Implemented data-store using a casefile instead of an array of cases.
authorJohn Darrington <john@darrington.wattle.id.au>
Mon, 19 Jun 2006 10:16:51 +0000 (10:16 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Mon, 19 Jun 2006 10:16:51 +0000 (10:16 +0000)
27 files changed:
lib/gtksheet/ChangeLog
lib/gtksheet/gsheet-column-iface.c
lib/gtksheet/gsheet-column-iface.h
lib/gtksheet/gsheet-hetero-column.c
lib/gtksheet/gsheet-row-iface.c
lib/gtksheet/gsheet-row-iface.h
lib/gtksheet/gsheet-uniform-column.c
lib/gtksheet/gsheet-uniform-row.c
lib/gtksheet/gtksheet.c
lib/gtksheet/gtksheet.h
src/data/ChangeLog
src/data/casefile.c
src/data/format.c
src/ui/gui/ChangeLog
src/ui/gui/TODO [new file with mode: 0644]
src/ui/gui/automake.mk
src/ui/gui/data-sheet.c
src/ui/gui/data-sheet.h
src/ui/gui/menu-actions.c
src/ui/gui/psppire-case-file.c [new file with mode: 0644]
src/ui/gui/psppire-case-file.h [new file with mode: 0644]
src/ui/gui/psppire-data-store.c
src/ui/gui/psppire-data-store.h
src/ui/gui/psppire-dict.c
src/ui/gui/psppire-dict.h
src/ui/gui/psppire-var-store.c
src/ui/gui/psppire.c

index 0ccbb0e35135f8ea6009b61c97ffdb62823d77a5..f202b24c2a9ba7b7efdba7978b873e282740766d 100644 (file)
@@ -1,3 +1,11 @@
+Mon Jun 19 18:03:21 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * gsheet-column-iface.c gsheet-column-iface.h
+       gsheet-hetero-column.c gsheet-row-iface.c gsheet-row-iface.h
+       gsheet-uniform-column.c gsheet-uniform-row.c gtksheet.c
+       gtksheet.h:  Fixed some warnings.  Corrected errors updating
+               row/column titles
+       
 Di Mai 30 19:51:19 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
     * gtksheet.c gtksheet.h: constness. Removed dependence on glib2.10
index 5abd21bc2ab99669a1bc4cbf3bfc5811106210b9..df3c90658f03c92471dcd628845a4a36a64085eb 100644 (file)
@@ -99,61 +99,58 @@ g_sheet_column_base_init (gpointer g_class)
 
 
 inline void  
-g_sheet_column_set_width (GSheetColumn *column,
-                               gint col, gint size, const GtkSheet *sheet)
+g_sheet_column_set_width (GSheetColumn *column, gint col, gint size, 
+                         gpointer data)
 {
   g_return_if_fail (G_IS_SHEET_COLUMN (column));
 
   if ((G_SHEET_COLUMN_GET_IFACE (column)->set_width) ) 
-    (G_SHEET_COLUMN_GET_IFACE (column)->set_width) (column, col, 
-                                                       size, sheet);
+    (G_SHEET_COLUMN_GET_IFACE (column)->set_width) (column, col, size, data);
 }
 
 
 inline gint 
-g_sheet_column_get_width     (const GSheetColumn *column, 
-                                   gint col, const GtkSheet *sheet)
+g_sheet_column_get_width (const GSheetColumn *column, gint col, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_COLUMN (column), -1);
 
   g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_width);
   
-  return (G_SHEET_COLUMN_GET_IFACE (column)->get_width) (column, col, 
-                                                            sheet);
+  return (G_SHEET_COLUMN_GET_IFACE (column)->get_width) (column, col, data);
 }
 
 
 
 inline gboolean  
 g_sheet_column_get_visibility(const GSheetColumn *column,
-                                           gint col, const GtkSheet *sheet)
+                                           gint col, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE);
 
   g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_visibility);
   
   return (G_SHEET_COLUMN_GET_IFACE (column)->get_visibility) (column, 
-                                                                 col, sheet);
+                                                                 col, data);
 
 }
 
 inline gboolean  
 g_sheet_column_get_sensitivity(const GSheetColumn *column,
-                                            gint col, const GtkSheet *sheet)
+                                            gint col, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE);
 
   g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_sensitivity);
   
   return (G_SHEET_COLUMN_GET_IFACE (column)->get_sensitivity) (column, 
-                                                                  col, sheet);
+                                                                  col, data);
 
 }
 
 
 inline GtkSheetButton *
 g_sheet_column_get_button(const GSheetColumn *column,
-                             gint col, const GtkSheet *sheet)
+                             gint col, gpointer data)
 {
   GtkSheetButton *button = gtk_sheet_button_new();
 
@@ -162,20 +159,20 @@ g_sheet_column_get_button(const GSheetColumn *column,
   g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE);
 
   if ( iface->get_button_label)
-    button->label = iface->get_button_label(column, col, sheet);
+    button->label = iface->get_button_label(column, col, data);
 
   return button;
 }
 
 inline GtkJustification 
 g_sheet_column_get_justification(const GSheetColumn *column, 
-                                    gint col, const GtkSheet *sheet)
+                                    gint col, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE);
 
   g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_justification);
   
-  return (G_SHEET_COLUMN_GET_IFACE (column)->get_justification) (column, col, sheet);
+  return (G_SHEET_COLUMN_GET_IFACE (column)->get_justification) (column, col, data);
 }
 
 
@@ -183,76 +180,76 @@ g_sheet_column_get_justification(const GSheetColumn *column,
 
 inline gint  
 g_sheet_column_get_left_text_column (const GSheetColumn *column,
-                                        gint col, const GtkSheet *sheet)
+                                        gint col, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_COLUMN (column), -1);
 
   if  ( ! G_SHEET_COLUMN_GET_IFACE (column)->get_left_text_column)
     return col;
   
-  return (G_SHEET_COLUMN_GET_IFACE (column)->get_left_text_column) (column, col, sheet);
+  return (G_SHEET_COLUMN_GET_IFACE (column)->get_left_text_column) (column, col, data);
 
 }
 
 inline gint  
 g_sheet_column_get_right_text_column (const GSheetColumn *column,
-                                         gint col, const GtkSheet *sheet)
+                                         gint col, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_COLUMN (column), -1);
 
   if  ( ! G_SHEET_COLUMN_GET_IFACE (column)->get_right_text_column)
     return col;
   
-  return (G_SHEET_COLUMN_GET_IFACE (column)->get_right_text_column) (column, col, sheet);
+  return (G_SHEET_COLUMN_GET_IFACE (column)->get_right_text_column) (column, col, data);
 
 }
 
 inline void 
 g_sheet_column_set_left_text_column (const GSheetColumn *column,
-                                        gint col, gint i, const GtkSheet *sheet)
+                                        gint col, gint i, gpointer data)
 {
   g_return_if_fail (G_IS_SHEET_COLUMN (column));
 
   if  ( G_SHEET_COLUMN_GET_IFACE (column)->set_left_text_column)
-    (G_SHEET_COLUMN_GET_IFACE (column)->set_left_text_column) (column, col, i, sheet);
+    (G_SHEET_COLUMN_GET_IFACE (column)->set_left_text_column) (column, col, i, data);
 
 }
 
 
 inline void 
 g_sheet_column_set_right_text_column (const GSheetColumn *column,
-                                         gint col, gint i, const GtkSheet *sheet)
+                                         gint col, gint i, gpointer data)
 {
   g_return_if_fail (G_IS_SHEET_COLUMN (column));
 
   if  ( G_SHEET_COLUMN_GET_IFACE (column)->set_right_text_column)
-    (G_SHEET_COLUMN_GET_IFACE (column)->set_right_text_column) (column, col, i, sheet);
+    (G_SHEET_COLUMN_GET_IFACE (column)->set_right_text_column) (column, col, i, data);
 }
 
 inline gint  
-g_sheet_column_get_column_count(const GSheetColumn *geo, const GtkSheet *sheet)
+g_sheet_column_get_column_count(const GSheetColumn *geo, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_COLUMN (geo), -1);
 
   g_assert  ( G_SHEET_COLUMN_GET_IFACE (geo)->get_column_count);
 
-  return (G_SHEET_COLUMN_GET_IFACE (geo)->get_column_count) (geo, sheet);
+  return (G_SHEET_COLUMN_GET_IFACE (geo)->get_column_count) (geo, data);
 }
 
 inline gint  
-g_sheet_column_start_pixel(const GSheetColumn *geo, gint col, const GtkSheet *sheet)
+g_sheet_column_start_pixel(const GSheetColumn *geo, gint col, gpointer data)
 {
   gint i;
   gint start_pixel = 0;
 
   g_return_val_if_fail (G_IS_SHEET_COLUMN (geo), -1);
   g_return_val_if_fail (col < 
-                       g_sheet_column_get_column_count(geo, sheet),-1);
+                       g_sheet_column_get_column_count(geo, data),-1);
 
   for ( i = 0 ; i < col ; ++i ) 
     {
-      if ( g_sheet_column_get_visibility(geo, i, sheet))
-       start_pixel += g_sheet_column_get_width(geo, i, sheet);
+      if ( g_sheet_column_get_visibility(geo, i, data))
+       start_pixel += g_sheet_column_get_width(geo, i, data);
     }
   
   return start_pixel;
@@ -262,7 +259,7 @@ g_sheet_column_start_pixel(const GSheetColumn *geo, gint col, const GtkSheet *sh
 
 
 inline void
-g_sheet_column_columns_deleted(GSheetColumn *geo, 
+g_sheet_column_columns_changed(GSheetColumn *geo, 
                                 gint first, gint n_columns)
 {
   g_return_if_fail (G_IS_SHEET_COLUMN (geo));
@@ -270,3 +267,7 @@ g_sheet_column_columns_deleted(GSheetColumn *geo,
   g_signal_emit (geo, sheet_column_signals[COLUMNS_CHANGED], 0, 
                 first, n_columns);
 }
+
+
+
+
index 6c9970806b90561ee5196d67cde36ab68fc1cc9f..430814abc3768304a292fd3e8b0abec1662d53b1 100644 (file)
@@ -47,37 +47,37 @@ struct _GSheetColumnIface
                                      gint col, gint n_columns);
 
   /* Virtual Table */
-  gint (* get_width) (const GSheetColumn *gcolumn, gint col, const GtkSheet *);
-  void (* set_width) (GSheetColumn *gcolumn, gint col, gint width, const GtkSheet *);
+  gint (* get_width) (const GSheetColumn *gcolumn, gint col, gpointer data);
+  void (* set_width) (GSheetColumn *gcolumn, gint col, gint width, gpointer data);
 
-  gboolean (* get_visibility) (const GSheetColumn *gcolumn, gint col, const GtkSheet *);
-  gboolean (* get_sensitivity) (const GSheetColumn *gcolumn, gint col, const GtkSheet *);
-  const GtkSheetButton * (* get_button) (const GSheetColumn *gcolumn, gint col, const GtkSheet *);
-  GtkJustification (* get_justification) (const GSheetColumn *gcolumn, gint col, const GtkSheet *);
+  gboolean (* get_visibility) (const GSheetColumn *gcolumn, gint col, gpointer data);
+  gboolean (* get_sensitivity) (const GSheetColumn *gcolumn, gint col, gpointer data);
+  const GtkSheetButton * (* get_button) (const GSheetColumn *gcolumn, gint col, gpointer data);
+  GtkJustification (* get_justification) (const GSheetColumn *gcolumn, gint col, gpointer data);
 
   gint  (*get_left_text_column) (const GSheetColumn *gcolumn,
-                                gint col, const GtkSheet *);
+                                gint col, gpointer data);
 
   gint  (*get_right_text_column) (const GSheetColumn *gcolumn,
-                                 gint col, const GtkSheet *);
+                                 gint col, gpointer data);
 
   void (* set_left_text_column) (const GSheetColumn *gcolumn,
-                                gint col, gint i, const GtkSheet *);
+                                gint col, gint i, gpointer data);
 
   void (* set_right_text_column) (const GSheetColumn *gcolumn,
-                                 gint col, gint i, const GtkSheet *);
+                                 gint col, gint i, gpointer data);
 
-  gint  (* get_column_count) (const GSheetColumn *geo, const GtkSheet *);
+  gint  (* get_column_count) (const GSheetColumn *geo, gpointer data);
 
 
-  GtkStateType  (*get_button_state)(const GSheetColumn *geo, gint col, const GtkSheet *);
-  gchar * (*get_button_label)(const GSheetColumn *geo, gint col, const GtkSheet *);
+  GtkStateType  (*get_button_state)(const GSheetColumn *geo, gint col, gpointer data);
+  gchar * (*get_button_label)(const GSheetColumn *geo, gint col, gpointer data);
   gboolean      (*get_button_visibility)(const GSheetColumn *geo, 
-                                       gint col, const GtkSheet *);
+                                       gint col, gpointer data);
   const GtkSheetChild * (*get_button_child)(const GSheetColumn *geo, 
-                                          gint col, const GtkSheet *);
+                                          gint col, gpointer data);
   GtkJustification * (*get_button_justification)(const GSheetColumn *geo, 
-                                               gint col, const GtkSheet *);
+                                               gint col, gpointer data);
 };
 
 
@@ -85,47 +85,46 @@ inline GType g_sheet_column_get_type   (void) G_GNUC_CONST;
 
 
 inline gint  g_sheet_column_get_width (const GSheetColumn *gcolumn,
-                                       gint col, const GtkSheet *sheet);
+                                      gint col, gpointer data);
 
 
 inline void  g_sheet_column_set_width (GSheetColumn *gcolumn,
-                                       gint col, gint size, const GtkSheet *sheet);
+                                      gint col, gint size, gpointer data);
 
 
 inline gboolean  g_sheet_column_get_visibility(const GSheetColumn *gcolumn,
-                                           gint col, const GtkSheet *sheet);
+                                           gint col, gpointer data);
 
 inline gboolean  g_sheet_column_get_sensitivity(const GSheetColumn *gcolumn,
-                                            gint col, const GtkSheet *sheet);
+                                            gint col, gpointer data);
 
 
 inline GtkSheetButton *g_sheet_column_get_button(const GSheetColumn *gcolumn,
-                                            gint col, const GtkSheet *sheet);
+                                            gint col, gpointer data);
 
-inline GtkJustification g_sheet_column_get_justification(const GSheetColumn *gcolumn, gint col, const GtkSheet *sheet);
+inline GtkJustification g_sheet_column_get_justification(const GSheetColumn *gcolumn, gint col, gpointer data);
 
 
 inline gint  g_sheet_column_get_left_text_column (const GSheetColumn *gcolumn,
-                                       gint col, const GtkSheet *sheet);
+                                       gint col, gpointer data);
 
 inline gint  g_sheet_column_get_right_text_column (const GSheetColumn *gcolumn,
-                                       gint col, const GtkSheet *sheet);
+                                       gint col, gpointer data);
 
 inline void g_sheet_column_set_left_text_column (const GSheetColumn *gcolumn,
-                                       gint col, gint i, const GtkSheet *sheet);
+                                       gint col, gint i, gpointer data);
 
 
 inline void g_sheet_column_set_right_text_column (const GSheetColumn *gcolumn,
-                                       gint col, gint i, const GtkSheet *sheet);
+                                       gint col, gint i, gpointer data);
 
 
-inline gint  g_sheet_column_get_column_count(const GSheetColumn *geo, const GtkSheet *sheet);
+inline gint  g_sheet_column_get_column_count(const GSheetColumn *geo, gpointer data);
 
-inline gint  g_sheet_column_start_pixel(const GSheetColumn *geo, gint col, const GtkSheet *sheet);
-
-inline void g_sheet_column_columns_deleted(GSheetColumn *geo, 
-                                     gint first, gint n_columns);
+inline gint  g_sheet_column_start_pixel(const GSheetColumn *geo, gint col, gpointer data);
 
+inline void g_sheet_column_columns_changed(GSheetColumn *geo, 
+                                          gint first, gint n_columns);
 
 G_END_DECLS
 
index 1285e9f237c16be56d468754273e252c64e5fcbc..ebd67903335fe333fd70260389a4d19d134e65fc 100644 (file)
@@ -104,7 +104,7 @@ g_sheet_hetero_column_new (gint default_width, gint n_columns)
 }
 
 static gint 
-g_sheet_hetero_column_get_width(const GSheetColumn *geom, gint i)
+g_sheet_hetero_column_get_width(const GSheetColumn *geom, gint i, gpointer data)
 {
   GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN(geom);
 
@@ -114,14 +114,14 @@ g_sheet_hetero_column_get_width(const GSheetColumn *geom, gint i)
 }
 
 static gint 
-g_sheet_hetero_column_get_sensitivity(const GSheetColumn *geom, gint u)
+g_sheet_hetero_column_get_sensitivity(const GSheetColumn *geom, gint u, gpointer data)
 {
   return TRUE;
 }
 
 
 static gint 
-g_sheet_hetero_column_get_visibility(const GSheetColumn *geom, gint u)
+g_sheet_hetero_column_get_visibility(const GSheetColumn *geom, gint u, gpointer data)
 {
   return TRUE;
 }
@@ -129,7 +129,7 @@ g_sheet_hetero_column_get_visibility(const GSheetColumn *geom, gint u)
 
 
 static gchar *
-g_sheet_hetero_column_get_button_label(const GSheetColumn *geom, gint u)
+g_sheet_hetero_column_get_button_label(const GSheetColumn *geom, gint u, gpointer data)
 {
   GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN(geom);
 
@@ -138,7 +138,7 @@ g_sheet_hetero_column_get_button_label(const GSheetColumn *geom, gint u)
 
 
 static GtkJustification
-g_sheet_hetero_column_get_justification(const GSheetColumn *geom, gint u)
+g_sheet_hetero_column_get_justification(const GSheetColumn *geom, gint u, gpointer data)
 {
   return GTK_JUSTIFY_FILL;
 }
@@ -146,7 +146,7 @@ g_sheet_hetero_column_get_justification(const GSheetColumn *geom, gint u)
 
 
 static gint 
-g_sheet_hetero_column_get_column_count(const GSheetColumn *geom)
+g_sheet_hetero_column_get_column_count(const GSheetColumn *geom, gpointer data)
 {
   GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN(geom);
 
@@ -184,12 +184,24 @@ g_sheet_hetero_column_finalize (GObject           *object)
   g_free(hg->col);
 }
 
+static void 
+hetero_column_set_width(GSheetColumn *geo,
+                                     gint i, gint size, gpointer data)
+{
+  GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN(geo);
+
+  g_return_if_fail(i < hg->n_columns);
+
+  hg->col[i].width = size;
+}
+
+
 
 static void
 g_sheet_column_init (GSheetColumnIface *iface)
 {
   iface->get_width = g_sheet_hetero_column_get_width ;
-  iface->set_width = g_sheet_hetero_column_set_width ;
+  iface->set_width = hetero_column_set_width ;
   iface->get_sensitivity = g_sheet_hetero_column_get_sensitivity ;
   iface->get_visibility = g_sheet_hetero_column_get_visibility ;
   iface->get_justification = g_sheet_hetero_column_get_justification;
@@ -213,13 +225,15 @@ g_sheet_hetero_column_set_button_label(GSheetHeteroColumn *geo,
 
 
 
-void 
+
+inline void 
 g_sheet_hetero_column_set_width(GSheetHeteroColumn *geo,
-                                     gint i, gint size)
+                                            gint i, gint size)
 {
-  g_return_if_fail(i < geo->n_columns);
+  GSheetColumn *iface = G_SHEET_COLUMN(geo);
 
-  geo->col[i].width = size;
+  hetero_column_set_width(iface, i, size, 0);
 }
 
 
+
index 7c716d858810ce63109500200114065739fa5bb4..1136b9a5714b5aecef211d7ac7a3d44fa5118409 100644 (file)
@@ -103,60 +103,60 @@ g_sheet_row_base_init (gpointer g_class)
 
 void  
 g_sheet_row_set_height (GSheetRow *row_geo,
-                               gint row, gint size, const GtkSheet *sheet)
+                               gint row, gint size, gpointer data)
 {
   g_return_if_fail (G_IS_SHEET_ROW (row_geo));
 
   if ((G_SHEET_ROW_GET_IFACE (row_geo)->set_height) ) 
     (G_SHEET_ROW_GET_IFACE (row_geo)->set_height) (row_geo, row, 
-                                                       size, sheet);
+                                                       size, data);
 }
 
 
 gint 
 g_sheet_row_get_height     (const GSheetRow *row_geo, 
-                                   gint row, const GtkSheet *sheet)
+                                   gint row, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), -1);
 
   g_assert (G_SHEET_ROW_GET_IFACE (row_geo)->get_height);
   
   return (G_SHEET_ROW_GET_IFACE (row_geo)->get_height) (row_geo, row, 
-                                                            sheet);
+                                                            data);
 }
 
 
 
 gboolean  
 g_sheet_row_get_visibility(const GSheetRow *row_geo,
-                                           gint row, const GtkSheet *sheet)
+                                           gint row, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), FALSE);
 
   g_assert (G_SHEET_ROW_GET_IFACE (row_geo)->get_visibility);
   
   return (G_SHEET_ROW_GET_IFACE (row_geo)->get_visibility) (row_geo, 
-                                                                 row, sheet);
+                                                                 row, data);
 
 }
 
 gboolean  
 g_sheet_row_get_sensitivity(const GSheetRow *row_geo,
-                                            gint row, const GtkSheet *sheet)
+                                            gint row, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), FALSE);
 
   g_assert (G_SHEET_ROW_GET_IFACE (row_geo)->get_sensitivity);
   
   return (G_SHEET_ROW_GET_IFACE (row_geo)->get_sensitivity) (row_geo, 
-                                                                  row, sheet);
+                                                                  row, data);
 
 }
 
 
 GtkSheetButton *
 g_sheet_row_get_button(const GSheetRow *row_geo,
-                             gint row, const GtkSheet *sheet)
+                             gint row, gpointer data)
 {
   GtkSheetButton *button  = gtk_sheet_button_new();
 
@@ -165,20 +165,20 @@ g_sheet_row_get_button(const GSheetRow *row_geo,
   g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), FALSE);
 
   if ( iface->get_button_label)
-    button->label = iface->get_button_label(row_geo, row, sheet);
+    button->label = iface->get_button_label(row_geo, row, data);
 
   return button;
 }
 
 
 gint  
-g_sheet_row_get_row_count(const GSheetRow *geo, const GtkSheet *sheet)
+g_sheet_row_get_row_count(const GSheetRow *geo, gpointer data)
 {
   g_return_val_if_fail (G_IS_SHEET_ROW (geo), -1);
 
   g_assert  ( G_SHEET_ROW_GET_IFACE (geo)->get_row_count);
 
-  return (G_SHEET_ROW_GET_IFACE (geo)->get_row_count) (geo, sheet);
+  return (G_SHEET_ROW_GET_IFACE (geo)->get_row_count) (geo, data);
 }
 
 /**
@@ -195,7 +195,7 @@ g_sheet_row_get_row_count(const GSheetRow *geo, const GtkSheet *sheet)
  */
 
 gint  
-g_sheet_row_start_pixel(const GSheetRow *geo, gint row, const GtkSheet *sheet)
+g_sheet_row_start_pixel(const GSheetRow *geo, gint row, gpointer data)
 {
   gint i;
   gint start_pixel = 0;
@@ -203,15 +203,15 @@ g_sheet_row_start_pixel(const GSheetRow *geo, gint row, const GtkSheet *sheet)
   g_return_val_if_fail (G_IS_SHEET_ROW (geo), -1);
   g_return_val_if_fail (row >= 0, -1);
   g_return_val_if_fail (row < 
-                       g_sheet_row_get_row_count(geo, sheet),-1);
+                       g_sheet_row_get_row_count(geo, data),-1);
 
   if ( G_SHEET_ROW_GET_IFACE(geo)->top_ypixel) 
-    return (G_SHEET_ROW_GET_IFACE(geo)->top_ypixel)(geo, row, sheet);
+    return (G_SHEET_ROW_GET_IFACE(geo)->top_ypixel)(geo, row, data);
 
   for ( i = 0 ; i < row ; ++i ) 
     {
-      if ( g_sheet_row_get_visibility(geo, i, sheet))
-       start_pixel += g_sheet_row_get_height(geo, i, sheet);
+      if ( g_sheet_row_get_visibility(geo, i, data))
+       start_pixel += g_sheet_row_get_height(geo, i, data);
     }
   
   return start_pixel;
@@ -220,29 +220,29 @@ g_sheet_row_start_pixel(const GSheetRow *geo, gint row, const GtkSheet *sheet)
 
 gint  
 g_sheet_row_pixel_to_row(const GSheetRow *geo, gint pixel, 
-                        const GtkSheet *s)
+                        gpointer data)
 {
   gint i, cy;
   g_return_val_if_fail (G_IS_SHEET_ROW (geo), -1);
   g_return_val_if_fail (pixel >= 0, -1) ;
 
   if ( G_SHEET_ROW_GET_IFACE(geo)->pixel_to_row) 
-    return (G_SHEET_ROW_GET_IFACE(geo)->pixel_to_row)(geo, pixel, s);
+    return (G_SHEET_ROW_GET_IFACE(geo)->pixel_to_row)(geo, pixel, data);
 
   cy = 0;
-  for (i = 0; i < g_sheet_row_get_row_count(geo, s); ++i ) 
+  for (i = 0; i < g_sheet_row_get_row_count(geo, data); ++i ) 
     {
       if (pixel >= cy  && 
-         pixel <= (cy + g_sheet_row_get_height(geo, i, s)) && 
-         g_sheet_row_get_visibility(geo, i, s))
+         pixel <= (cy + g_sheet_row_get_height(geo, i, data)) && 
+         g_sheet_row_get_visibility(geo, i, data))
        return i;
 
-      if(g_sheet_row_get_visibility(geo, i, s))
-       cy += g_sheet_row_get_height(geo, i, s);
+      if(g_sheet_row_get_visibility(geo, i, data))
+       cy += g_sheet_row_get_height(geo, i, data);
     }
 
   /* no match */
-  return g_sheet_row_get_row_count(geo, s) - 1;
+  return g_sheet_row_get_row_count(geo, data) - 1;
 }
 
 
index 8575620a9bc55721e484adcbe9c493d7f467bb07..9b75ba5509e531c74d99c051afb9443253ccc61e 100644 (file)
@@ -50,36 +50,36 @@ struct _GSheetRowIface
                                      gint row, gint n_rows);
 
   /* Virtual Table */
-  gint (* get_height) (const GSheetRow *grow, gint row, const GtkSheet *);
+  gint (* get_height) (const GSheetRow *grow, gint row, gpointer);
   void (* set_height) (GSheetRow *grow, gint row, gint height, 
-                      const GtkSheet *);
+                      gpointer);
 
   gboolean (* get_visibility) (const GSheetRow *grow, gint row, 
-                              const GtkSheet *);
+                              gpointer);
 
   gboolean (* get_sensitivity) (const GSheetRow *grow, gint row, 
-                               const GtkSheet *);
+                               gpointer);
 
   const GtkSheetButton * (* get_button) (const GSheetRow *grow, gint row, 
-                                        const GtkSheet *);
+                                        gpointer);
 
-  gint  (* get_row_count) (const GSheetRow *geo, const GtkSheet *);
+  gint  (* get_row_count) (const GSheetRow *geo, gpointer);
 
 
   GtkStateType  (*get_button_state)(const GSheetRow *geo, gint row, 
-                                   const GtkSheet *);
+                                   gpointer);
 
   gchar * (*get_button_label)(const GSheetRow *geo, gint row, 
-                             const GtkSheet *);
+                             gpointer);
 
   gboolean      (*get_button_visibility)(const GSheetRow *geo, 
-                                       gint row, const GtkSheet *);
+                                       gint row, gpointer);
 
   const GtkSheetChild * (*get_button_child)(const GSheetRow *geo, 
-                                          gint row, const GtkSheet *);
+                                          gint row, gpointer);
 
-  guint (*top_ypixel)(const GSheetRow *geo, gint row, const GtkSheet *);
-  gint (*pixel_to_row)(const GSheetRow *geo, guint pixel, const GtkSheet *);
+  guint (*top_ypixel)(const GSheetRow *geo, gint row, gpointer);
+  gint (*pixel_to_row)(const GSheetRow *geo, guint pixel, gpointer);
 };
 
 
@@ -87,33 +87,33 @@ GType g_sheet_row_get_type   (void) G_GNUC_CONST;
 
 
 gint  g_sheet_row_get_height (const GSheetRow *grow,
-                                       gint row, const GtkSheet *sheet);
+                                       gint row, gpointer);
 
 
 void  g_sheet_row_set_height (GSheetRow *grow,
-                                       gint row, gint size, const GtkSheet *sheet);
+                                       gint row, gint size, gpointer);
 
 
 gboolean  g_sheet_row_get_visibility(const GSheetRow *grow,
-                                           gint row, const GtkSheet *sheet);
+                                           gint row, gpointer);
 
 gboolean  g_sheet_row_get_sensitivity(const GSheetRow *grow,
-                                            gint row, const GtkSheet *sheet);
+                                            gint row, gpointer);
 
 
 GtkSheetButton *g_sheet_row_get_button(const GSheetRow *grow,
-                                            gint row, const GtkSheet *sheet);
+                                            gint row, gpointer);
 
 
-gint  g_sheet_row_get_row_count(const GSheetRow *geo, const GtkSheet *sheet);
+gint  g_sheet_row_get_row_count(const GSheetRow *geo, gpointer);
 
 /* Return the top pixel of row ROW */
 gint  g_sheet_row_start_pixel(const GSheetRow *geo, gint row, 
-                             const GtkSheet *sheet);
+                             gpointer);
 
 /* Return the row contained by pixel PIXEL */
 gint  g_sheet_row_pixel_to_row(const GSheetRow *geo, gint pixel, 
-                              const GtkSheet *sheet);
+                              gpointer);
 
 
 void g_sheet_row_rows_deleted(GSheetRow *geo, 
index 0c1573b5d5717c4ba4fd46c2a24564fcda00d3bc..6822fa3606b684cf00a371c53853317c383a9cba 100644 (file)
@@ -96,7 +96,7 @@ g_sheet_uniform_column_new (gint width, gint n_columns)
 }
 
 static gint 
-g_sheet_uniform_column_get_width(const GSheetColumn *geom, gint u)
+g_sheet_uniform_column_get_width(const GSheetColumn *geom, gint u, gpointer data)
 {
   GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN(geom);
   
@@ -104,7 +104,7 @@ g_sheet_uniform_column_get_width(const GSheetColumn *geom, gint u)
 }
 
 static gint 
-g_sheet_uniform_column_get_sensitivity(const GSheetColumn *geom, gint u)
+g_sheet_uniform_column_get_sensitivity(const GSheetColumn *geom, gint u, gpointer data)
 {
   GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN(geom);
   
@@ -113,7 +113,7 @@ g_sheet_uniform_column_get_sensitivity(const GSheetColumn *geom, gint u)
 
 
 static gint 
-g_sheet_uniform_column_get_visibility(const GSheetColumn *geom, gint u)
+g_sheet_uniform_column_get_visibility(const GSheetColumn *geom, gint u, gpointer data)
 {
   GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN(geom);
   
@@ -121,32 +121,25 @@ g_sheet_uniform_column_get_visibility(const GSheetColumn *geom, gint u)
 }
 
 
-static const gchar *
-g_sheet_uniform_column_get_button_label(const GSheetColumn *geom, gint u)
+static gchar *
+g_sheet_uniform_column_get_button_label(const GSheetColumn *geom, gint u, gpointer data)
 {
-  static gchar *label; 
-
-  g_free(label);
-  label = g_strdup_printf("%d", u);
+  gchar *label = g_strdup_printf("%d", u);
 
   return label;
 }
 
 
 static GtkJustification
-g_sheet_uniform_column_get_justification(const GSheetColumn *geom, gint u)
+g_sheet_uniform_column_get_justification(const GSheetColumn *geom, gint u, gpointer data)
 {
-       /* 
-  GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN(geom);
-  */
-  
   return GTK_JUSTIFY_FILL;
 }
 
 
 
 static gint 
-g_sheet_uniform_column_get_column_count(const GSheetColumn *geom)
+g_sheet_uniform_column_get_column_count(const GSheetColumn *geom, gpointer data)
 {
   GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN(geom);
 
index f25480fbed733ed396ff3947df89e05171999b11..08397c30b02be011f00880bfe9ef55f1f9f5b22c 100644 (file)
@@ -95,7 +95,7 @@ g_sheet_uniform_row_new (gint height, gint n_rows)
 }
 
 static gint 
-g_sheet_uniform_row_get_height(const GSheetRow *geom, gint u)
+g_sheet_uniform_row_get_height(const GSheetRow *geom, gint u, gpointer data)
 {
   GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geom);
   
@@ -103,7 +103,7 @@ g_sheet_uniform_row_get_height(const GSheetRow *geom, gint u)
 }
 
 static gboolean
-g_sheet_uniform_row_get_sensitivity(const GSheetRow *geom, gint u)
+g_sheet_uniform_row_get_sensitivity(const GSheetRow *geom, gint u, gpointer data)
 {
   GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geom);
   
@@ -112,7 +112,7 @@ g_sheet_uniform_row_get_sensitivity(const GSheetRow *geom, gint u)
 
 
 static gboolean
-g_sheet_uniform_row_get_visibility(const GSheetRow *geom, gint u)
+g_sheet_uniform_row_get_visibility(const GSheetRow *geom, gint u, gpointer data)
 {
   GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geom);
   
@@ -120,8 +120,8 @@ g_sheet_uniform_row_get_visibility(const GSheetRow *geom, gint u)
 }
 
 
-static const gchar *
-g_sheet_uniform_row_get_button_label(const GSheetRow *geom, gint u)
+static gchar *
+g_sheet_uniform_row_get_button_label(const GSheetRow *geom, gint u, gpointer data)
 {
   gchar *label = g_strdup_printf("%d", u);
 
@@ -131,7 +131,7 @@ g_sheet_uniform_row_get_button_label(const GSheetRow *geom, gint u)
 
 
 static gint 
-g_sheet_uniform_row_get_row_count(const GSheetRow *geom)
+g_sheet_uniform_row_get_row_count(const GSheetRow *geom, gpointer data)
 {
   GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geom);
 
@@ -164,23 +164,23 @@ g_sheet_uniform_row_finalize (GObject           *object)
 
 
 static guint
-g_sheet_uniform_row_top_ypixel(GSheetRow *geo, gint row, const GtkSheet *sheet)
+g_sheet_uniform_row_top_ypixel(const GSheetRow *geo, gint row, gpointer data)
 {
   GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geo);
 
   return row * ug->height;
 }
 
-static guint
-g_sheet_uniform_row_pixel_to_row(GSheetRow *geo
-                                gint pixel, const GtkSheet *sheet)
+static gint
+g_sheet_uniform_row_pixel_to_row(const GSheetRow *geo, guint pixel
+                                gpointer data)
 {
   GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geo);
 
   gint row = pixel / ug->height;
 
-  if (row >= g_sheet_uniform_row_get_row_count(geo))
-    row = g_sheet_uniform_row_get_row_count(geo) -1;
+  if (row >= g_sheet_uniform_row_get_row_count(geo, data))
+    row = g_sheet_uniform_row_get_row_count(geo, data) -1;
 
   return row;
 }
index 6d47cfb9943ce05bf23f9841cf3146a258b4a2b1..7435b8e27979c6012f46411e3779cc61354817e3 100644 (file)
@@ -60,7 +60,6 @@
 #include "gtkextra-marshal.h"
 #include "gsheetmodel.h"
 
-
 /* sheet flags */
 enum
 { 
@@ -104,6 +103,10 @@ enum
 #define DEFAULT_COLUMN_WIDTH 80
 
 
+static void gtk_sheet_column_title_button_draw(GtkSheet *sheet, gint column);
+
+static void gtk_sheet_row_title_button_draw(GtkSheet *sheet, gint row);
+
 
 static gboolean gtk_sheet_cell_empty (const GtkSheet *sheet, gint row, gint col);
 
@@ -178,20 +181,20 @@ static inline guint DEFAULT_FONT_DESCENT(GtkWidget *widget)
 
 
 static gint
-yyy_row_is_visible(GtkSheet *sheet, gint row)
+yyy_row_is_visible(const GtkSheet *sheet, gint row)
 {
   GSheetRow *row_geo = sheet->row_geometry;
 
-  return g_sheet_row_get_visibility(row_geo, row, sheet);
+  return g_sheet_row_get_visibility(row_geo, row, 0);
 }
 
 
 static gint
-yyy_row_is_sensitive(GtkSheet *sheet, gint row)
+yyy_row_is_sensitive(const GtkSheet *sheet, gint row)
 {
   GSheetRow *row_geo = sheet->row_geometry;
 
-  return g_sheet_row_get_sensitivity(row_geo, row, sheet);
+  return g_sheet_row_get_sensitivity(row_geo, row, 0);
 }
 
 
@@ -201,7 +204,7 @@ yyy_row_count(const GtkSheet *sheet)
 {
   GSheetRow *row_geo = sheet->row_geometry;
 
-  return g_sheet_row_get_row_count(row_geo, sheet);
+  return g_sheet_row_get_row_count(row_geo, 0);
 }
 
 static inline gint
@@ -209,15 +212,15 @@ yyy_row_height(const GtkSheet *sheet, gint row)
 {
   GSheetRow *row_geo = sheet->row_geometry;
 
-  return g_sheet_row_get_height(row_geo, row, sheet);
+  return g_sheet_row_get_height(row_geo, row, 0);
 }
 
 static gint
-yyy_row_top_ypixel(GtkSheet *sheet, gint row)
+yyy_row_top_ypixel(const GtkSheet *sheet, gint row)
 {
   GSheetRow *geo = sheet->row_geometry;
 
-  gint y = g_sheet_row_start_pixel(geo, row, sheet);
+  gint y = g_sheet_row_start_pixel(geo, row, 0);
 
   if ( sheet->column_titles_visible ) 
     y += sheet->column_title_area.height;
@@ -228,7 +231,7 @@ yyy_row_top_ypixel(GtkSheet *sheet, gint row)
 
 /* Return the row containing pixel Y */
 static gint
-yyy_row_ypixel_to_row(GtkSheet *sheet, gint y)
+yyy_row_ypixel_to_row(const GtkSheet *sheet, gint y)
 {
   GSheetRow *geo = sheet->row_geometry;
 
@@ -238,16 +241,15 @@ yyy_row_ypixel_to_row(GtkSheet *sheet, gint y)
     cy += sheet->column_title_area.height;
   
   if(y < cy) return 0;
-
-
-  return g_sheet_row_pixel_to_row(geo, y - cy, sheet);
+  
+  return  g_sheet_row_pixel_to_row(geo, y - cy, 0);
 }
 
 
 /* gives the top pixel of the given row in context of
  * the sheet's voffset */
 static inline gint
-ROW_TOP_YPIXEL(GtkSheet *sheet, gint row)
+ROW_TOP_YPIXEL(const GtkSheet *sheet, gint row)
 {
   return (sheet->voffset + yyy_row_top_ypixel(sheet, row));
 }
@@ -256,26 +258,29 @@ ROW_TOP_YPIXEL(GtkSheet *sheet, gint row)
 /* returns the row index from a y pixel location in the 
  * context of the sheet's voffset */
 static inline gint 
-ROW_FROM_YPIXEL(GtkSheet *sheet, gint y)
+ROW_FROM_YPIXEL(const GtkSheet *sheet, gint y)
 {
   return (yyy_row_ypixel_to_row(sheet, y));
 }
 
 static inline GtkSheetButton *
-xxx_column_button(GtkSheet *sheet, gint col)
+xxx_column_button(const GtkSheet *sheet, gint col)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
+  if ( col < 0 ) return NULL ; 
 
-  return g_sheet_column_get_button(col_geo, col, sheet);
+  return g_sheet_column_get_button(col_geo, col, 0);
 }
 
 
 static inline gint
-xxx_column_left_xpixel(GtkSheet *sheet, gint col)
+xxx_column_left_xpixel(const GtkSheet *sheet, gint col)
 {
   GSheetColumn *geo = sheet->column_geometry;
 
-  gint x = g_sheet_column_start_pixel(geo, col, sheet);
+  /* FIXME: Get rid of this nasty cast.
+     In fact, get rid of this entire variable */
+  gint x = g_sheet_column_start_pixel(geo, col, (GtkSheet *) sheet);
 
   if ( sheet->row_titles_visible ) 
     x += sheet->row_title_area.width;
@@ -288,7 +293,9 @@ xxx_column_width(const GtkSheet *sheet, gint col)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
 
-  return g_sheet_column_get_width(col_geo, col, sheet);
+  /* FIXME: Get rid of this nasty cast.
+     In fact, get rid of this entire variable */
+  return g_sheet_column_get_width(col_geo, col, (GtkSheet *)sheet);
 }
 
 
@@ -312,7 +319,7 @@ xxx_column_left_column(const GtkSheet *sheet, gint col)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
 
-  return g_sheet_column_get_left_text_column(col_geo, col, sheet);
+  return g_sheet_column_get_left_text_column(col_geo, col, 0);
 }
 
 static inline void
@@ -320,7 +327,7 @@ xxx_column_set_right_column(GtkSheet *sheet, gint col, gint i)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
 
-  g_sheet_column_set_right_text_column(col_geo, col, i, sheet);
+  g_sheet_column_set_right_text_column(col_geo, col, i, 0);
 }
 
 static inline gint
@@ -328,7 +335,7 @@ xxx_column_right_column(const GtkSheet *sheet, gint col)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
 
-  return g_sheet_column_get_right_text_column(col_geo, col, sheet);
+  return g_sheet_column_get_right_text_column(col_geo, col, 0);
 }
 
 static inline GtkJustification
@@ -336,31 +343,31 @@ xxx_column_justification(const GtkSheet *sheet, gint col)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
 
-  return g_sheet_column_get_justification(col_geo, col, sheet);
+  return g_sheet_column_get_justification(col_geo, col, 0);
 }
 
 static inline gint
-xxx_column_is_visible(GtkSheet *sheet, gint col)
+xxx_column_is_visible(const GtkSheet *sheet, gint col)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
 
-  return g_sheet_column_get_visibility(col_geo, col, sheet);
+  return g_sheet_column_get_visibility(col_geo, col, 0);
 }
 
 
 static inline gint
-xxx_column_is_sensitive(GtkSheet *sheet, gint col)
+xxx_column_is_sensitive(const GtkSheet *sheet, gint col)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
 
-  return g_sheet_column_get_sensitivity(col_geo, col, sheet);
+  return g_sheet_column_get_sensitivity(col_geo, col, 0);
 }
 
 
 /* gives the left pixel of the given column in context of
  * the sheet's hoffset */
 static inline gint
-COLUMN_LEFT_XPIXEL(GtkSheet *sheet, gint ncol)
+COLUMN_LEFT_XPIXEL(const GtkSheet *sheet, gint ncol)
 {
   return (sheet->hoffset + xxx_column_left_xpixel(sheet, ncol));
 }
@@ -370,13 +377,13 @@ xxx_column_count(const GtkSheet *sheet)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
 
-  return g_sheet_column_get_column_count(col_geo, sheet);
+  return g_sheet_column_get_column_count(col_geo, 0);
 }
 
 /* returns the column index from a x pixel location in the 
  * context of the sheet's hoffset */
 static inline gint
-COLUMN_FROM_XPIXEL (GtkSheet * sheet,
+COLUMN_FROM_XPIXEL (const GtkSheet * sheet,
                    gint x)
 {
   gint i, cx;
@@ -448,15 +455,15 @@ static inline gint SHEET_WIDTH(GtkSheet *sheet)
 #define MAX_VISIBLE_COLUMN(sheet) sheet->view.coli
 
 
-static inline gint
-POSSIBLE_XDRAG(GtkSheet *sheet, gint x, gint *drag_column)
+static inline gboolean
+POSSIBLE_XDRAG(const GtkSheet *sheet, gint x, gint *drag_column)
 {
  gint column, xdrag;
 
  column=COLUMN_FROM_XPIXEL(sheet, x);
  *drag_column=column;
 
- xdrag=COLUMN_LEFT_XPIXEL(sheet,column)+CELL_SPACING;
+ xdrag = COLUMN_LEFT_XPIXEL(sheet, column)+CELL_SPACING;
  if(x <= xdrag+DRAG_WIDTH/2 && column != 0){
    while(! xxx_column_is_visible(sheet, column-1) && column>0) column--;
    *drag_column=column-1;
@@ -470,8 +477,8 @@ POSSIBLE_XDRAG(GtkSheet *sheet, gint x, gint *drag_column)
  return FALSE;
 } 
 
-static inline gint
-POSSIBLE_YDRAG(GtkSheet *sheet, gint y, gint *drag_row)
+static inline gboolean
+POSSIBLE_YDRAG(const GtkSheet *sheet, gint y, gint *drag_row)
 {
  gint row, ydrag;
 
@@ -494,57 +501,75 @@ POSSIBLE_YDRAG(GtkSheet *sheet, gint y, gint *drag_row)
  return FALSE;
 }        
 
-static inline gint POSSIBLE_DRAG(GtkSheet *sheet, gint x, gint y,
-                            gint *drag_row, gint *drag_column)
+static inline gboolean
+POSSIBLE_DRAG(const GtkSheet *sheet, gint x, gint y,
+             gint *drag_row, gint *drag_column)
 {
   gint ydrag, xdrag;
 
-  *drag_column=COLUMN_FROM_XPIXEL(sheet,x);
-  *drag_row=ROW_FROM_YPIXEL(sheet,y);
+  /* Can't drag if nothing is selected */
+  if ( sheet->range.row0 < 0 || sheet->range.rowi < 0 || 
+       sheet->range.col0 < 0 || sheet->range.coli < 0 )
+    return FALSE;
 
-  if(x>=COLUMN_LEFT_XPIXEL(sheet,sheet->range.col0)-DRAG_WIDTH/2 &&
-     x<=COLUMN_LEFT_XPIXEL(sheet,sheet->range.coli)+
-     xxx_column_width(sheet, sheet->range.coli) + DRAG_WIDTH/2){
-    ydrag=ROW_TOP_YPIXEL(sheet,sheet->range.row0);
-     if(y>=ydrag-DRAG_WIDTH/2 && y<=ydrag+DRAG_WIDTH/2){
-        *drag_row=sheet->range.row0;
-        return TRUE;
-     }
-     ydrag=ROW_TOP_YPIXEL(sheet,sheet->range.rowi)+
-           yyy_row_height(sheet, sheet->range.rowi);
-     if(y>=ydrag-DRAG_WIDTH/2 && y<=ydrag+DRAG_WIDTH/2){
-        *drag_row=sheet->range.rowi;
-        return TRUE;
-     }
-  }
+  *drag_column = COLUMN_FROM_XPIXEL(sheet, x);
+  *drag_row = ROW_FROM_YPIXEL(sheet, y);
 
-  if(y>=ROW_TOP_YPIXEL(sheet,sheet->range.row0)-DRAG_WIDTH/2 &&
-     y<=ROW_TOP_YPIXEL(sheet,sheet->range.rowi)+
-        yyy_row_height(sheet, sheet->range.rowi)+DRAG_WIDTH/2){
-     xdrag=COLUMN_LEFT_XPIXEL(sheet,sheet->range.col0);
-     if(x>=xdrag-DRAG_WIDTH/2 && x<=xdrag+DRAG_WIDTH/2){
-        *drag_column=sheet->range.col0;
-        return TRUE;
-     }
-     xdrag=COLUMN_LEFT_XPIXEL(sheet,sheet->range.coli)+
-           xxx_column_width(sheet, sheet->range.coli);
-     if(x>=xdrag-DRAG_WIDTH/2 && x<=xdrag+DRAG_WIDTH/2){
-        *drag_column=sheet->range.coli;
-        return TRUE;
-     }
-  }
+  if(x >= COLUMN_LEFT_XPIXEL(sheet, sheet->range.col0) - DRAG_WIDTH/2 &&
+     x <= COLUMN_LEFT_XPIXEL(sheet, sheet->range.coli) +
+     xxx_column_width(sheet, sheet->range.coli) + DRAG_WIDTH/2)
+    {
+      ydrag=ROW_TOP_YPIXEL(sheet,sheet->range.row0);
+      if(y >= ydrag - DRAG_WIDTH/2 && y <= ydrag + DRAG_WIDTH/2)
+       {
+         *drag_row = sheet->range.row0;
+         return TRUE;
+       }
+      ydrag = ROW_TOP_YPIXEL(sheet, sheet->range.rowi) +
+       yyy_row_height(sheet, sheet->range.rowi);
+      if(y >= ydrag - DRAG_WIDTH/2 && y <= ydrag+DRAG_WIDTH/2)
+       {
+         *drag_row = sheet->range.rowi;
+         return TRUE;
+       }
+    }
+
+  if(y >= ROW_TOP_YPIXEL(sheet, sheet->range.row0) - DRAG_WIDTH/2 &&
+     y <= ROW_TOP_YPIXEL(sheet, sheet->range.rowi) +
+     yyy_row_height(sheet, sheet->range.rowi) + DRAG_WIDTH/2)
+    {
+      xdrag = COLUMN_LEFT_XPIXEL(sheet, sheet->range.col0);
+      if(x >= xdrag-DRAG_WIDTH/2 && x <= xdrag + DRAG_WIDTH/2)
+       {
+         *drag_column = sheet->range.col0;
+         return TRUE;
+       }
+      xdrag = COLUMN_LEFT_XPIXEL(sheet, sheet->range.coli) +
+       xxx_column_width(sheet, sheet->range.coli);
+      if(x >= xdrag - DRAG_WIDTH/2 && x <= xdrag + DRAG_WIDTH/2)
+       {
+         *drag_column = sheet->range.coli;
+         return TRUE;
+       }
+    }
   return FALSE;
 }
 
-static inline gint POSSIBLE_RESIZE(GtkSheet *sheet, gint x, gint y,
+static inline gboolean
+POSSIBLE_RESIZE(const GtkSheet *sheet, gint x, gint y,
                             gint *drag_row, gint *drag_column)
 {
   gint xdrag, ydrag;
   
-  xdrag=COLUMN_LEFT_XPIXEL(sheet,sheet->range.coli)+
+  /* Can't drag if nothing is selected */
+  if ( sheet->range.row0 < 0 || sheet->range.rowi < 0 || 
+       sheet->range.col0 < 0 || sheet->range.coli < 0 )
+    return FALSE;
+
+  xdrag = COLUMN_LEFT_XPIXEL(sheet,sheet->range.coli)+
     xxx_column_width(sheet, sheet->range.coli);
 
-  ydrag=ROW_TOP_YPIXEL(sheet,sheet->range.rowi)+
+  ydrag = ROW_TOP_YPIXEL(sheet,sheet->range.rowi)+
            yyy_row_height(sheet, sheet->range.rowi);
 
   if(sheet->state == GTK_SHEET_COLUMN_SELECTED) 
@@ -637,7 +662,7 @@ static void gtk_sheet_range_draw_selection  (GtkSheet *sheet,
 static gint gtk_sheet_move_query               (GtkSheet *sheet, 
                                                 gint row, gint column);
 static void gtk_sheet_real_select_range        (GtkSheet * sheet,
-                                                GtkSheetRange * range);
+                                                const GtkSheetRange * range);
 static void gtk_sheet_real_unselect_range      (GtkSheet * sheet,
                                                 const GtkSheetRange * range);
 static void gtk_sheet_extend_selection         (GtkSheet *sheet, 
@@ -713,8 +738,6 @@ static void size_allocate_column_title_buttons      (GtkSheet * sheet);
 static void size_allocate_row_title_buttons    (GtkSheet * sheet);
 
 
-static void gtk_sheet_button_draw              (GtkSheet *sheet, 
-                                                gint row, gint column);
 static void size_allocate_global_button        (GtkSheet *sheet);
 static void gtk_sheet_button_size_request      (GtkSheet *sheet,
                                                 const GtkSheetButton *button, 
@@ -1104,10 +1127,10 @@ gtk_sheet_init (GtkSheet *sheet)
   sheet->sheet_entry=NULL;
   sheet->pixmap=NULL;
 
-  sheet->range.row0=0;
-  sheet->range.rowi=0;
-  sheet->range.col0=0;
-  sheet->range.coli=0;
+  sheet->range.row0 = 0;
+  sheet->range.rowi = 0;
+  sheet->range.col0 = 0;
+  sheet->range.coli = 0;
 
   sheet->state=GTK_SHEET_NORMAL;
 
@@ -1143,6 +1166,7 @@ static void
 columns_inserted_deleted_callback (GSheetModel *model, gint first_column, gint n_columns,
                      gpointer data)
 {
+  gint i;
   GtkSheet *sheet = GTK_SHEET(data);
 
   GtkSheetRange range;
@@ -1157,8 +1181,22 @@ columns_inserted_deleted_callback (GSheetModel *model, gint first_column, gint n
   range.coli = xxx_column_count(sheet) - 1;
   range.rowi = yyy_row_count(sheet) - 1;
 
+  sheet->view.col0 = 
+    COLUMN_FROM_XPIXEL(sheet, sheet->row_title_area.width + 1);
+  
+  sheet->view.coli = 
+    COLUMN_FROM_XPIXEL(sheet, sheet->sheet_window_width);
+
+  if ( sheet->view.coli > range.coli) 
+    sheet->view.coli = range.coli;
+
+  adjust_scrollbars(sheet);
+
   if (sheet->active_cell.col >= model_columns)
     gtk_sheet_activate_cell(sheet, sheet->active_cell.row, model_columns - 1);
+
+  for(i = first_column; i <= MAX_VISIBLE_COLUMN(sheet); i++)
+    gtk_sheet_column_title_button_draw(sheet, i);
   
   gtk_sheet_range_draw(sheet, &range);
 }
@@ -1166,13 +1204,16 @@ columns_inserted_deleted_callback (GSheetModel *model, gint first_column, gint n
 
 /* Callback which occurs whenever rows are inserted/deleted in the model */
 static void 
-rows_inserted_deleted_callback (GSheetModel *m, gint first_row, gint n_rows,
+rows_inserted_deleted_callback (GSheetModel *model, gint first_row, gint n_rows,
                      gpointer data)
 {
+  gint i;
   GtkSheet *sheet = GTK_SHEET(data);
 
   GtkSheetRange range;
 
+  gint model_rows = g_sheet_model_get_row_count(model);
+
   /* Need to update all the rows starting from the first row and onwards.
    * Previous rows are unchanged, so don't need to be updated.
    */
@@ -1180,9 +1221,24 @@ rows_inserted_deleted_callback (GSheetModel *m, gint first_row, gint n_rows,
   range.col0 = 0;
   range.rowi = yyy_row_count(sheet) - 1;
   range.coli = xxx_column_count(sheet) - 1;
-  
-  gtk_sheet_range_draw(sheet, &range);
 
+  sheet->view.row0 = 
+    ROW_FROM_YPIXEL(sheet, sheet->column_title_area.height + 1);
+  sheet->view.rowi = 
+    ROW_FROM_YPIXEL(sheet, sheet->sheet_window_height - 1);
+
+  if ( sheet->view.rowi > range.rowi) 
+    sheet->view.rowi = range.rowi;
+
+  adjust_scrollbars(sheet);
+  if (sheet->active_cell.row >= model_rows)
+    gtk_sheet_activate_cell(sheet, model_rows - 1, sheet->active_cell.col);
+
+  for(i = first_row; i <= MAX_VISIBLE_ROW(sheet); i++)
+    gtk_sheet_row_title_button_draw(sheet, i);
+
+  gtk_sheet_range_draw(sheet, &range);
 }
 
 /* 
@@ -1291,21 +1347,35 @@ gtk_sheet_set_model(GtkSheet *sheet, GSheetModel *model)
 }
 
 
-
+/* Call back for when the column titles have changed.
+   FIRST is the first column changed.
+   N_COLUMNS is the number of columns which have changed, or -1, which 
+   indicates that the column has changed to its right-most extremity 
+ */
 static void
 column_titles_changed(GtkWidget *w, gint first, gint n_columns, gpointer data)
 {
   GtkSheet *sheet = GTK_SHEET(data);
+  gboolean extremity = FALSE;
 
-
-  if(!GTK_SHEET_IS_FROZEN(sheet)){  
-    gint i;
-    for ( i = first ; i <= MAX_VISIBLE_COLUMN(sheet) ; ++i ) 
-      {
-       gtk_sheet_button_draw(sheet, -1, i);
-       gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[CHANGED], -1, i);
-      }
-  }
+  if ( n_columns == -1 ) 
+    {
+      extremity = TRUE;
+      n_columns = xxx_column_count(sheet) - 1 ;
+    }
+  
+  if(!GTK_SHEET_IS_FROZEN(sheet))
+    {  
+      gint i;
+      for ( i = first ; i <= first + n_columns ; ++i ) 
+       {
+         gtk_sheet_column_title_button_draw(sheet, i);
+         gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[CHANGED], -1, i);
+       }
+    }
+  if ( extremity) 
+    gtk_sheet_column_title_button_draw(sheet, -1);
+    
 }
 
 static void
@@ -1401,10 +1471,7 @@ gtk_sheet_change_entry(GtkSheet *sheet, GtkType entry_type)
                         "changed",
                         G_CALLBACK(gtk_sheet_entry_changed),
                         sheet);
-
-
     }
 }
 
 void
@@ -2117,24 +2184,21 @@ gtk_sheet_select_row (GtkSheet * sheet,
   }
 
   sheet->state=GTK_SHEET_ROW_SELECTED;                     
-  sheet->range.row0=row;
-  sheet->range.col0=0;
-  sheet->range.rowi=row;
+  sheet->range.row0 = row;
+  sheet->range.col0 = 0;
+  sheet->range.rowi = row;
   sheet->range.coli = xxx_column_count(sheet) - 1;
-  sheet->active_cell.row=row;
-  sheet->active_cell.col=0;
+  sheet->active_cell.row = row;
+  sheet->active_cell.col = 0;
 
   gtk_signal_emit (GTK_OBJECT (sheet), sheet_signals[SELECT_ROW], row);
   gtk_sheet_real_select_range(sheet, NULL);
-
 }
 
 
 void
-gtk_sheet_select_column (GtkSheet * sheet,
-                        gint column)
+gtk_sheet_select_column (GtkSheet * sheet, gint column)
 {
-  
   g_return_if_fail (sheet != NULL);
   g_return_if_fail (GTK_IS_SHEET (sheet));
 
@@ -2151,16 +2215,15 @@ gtk_sheet_select_column (GtkSheet * sheet,
   }
 
   sheet->state=GTK_SHEET_COLUMN_SELECTED;                     
-  sheet->range.row0=0;
-  sheet->range.col0=column;
-  sheet->range.rowi= yyy_row_count(sheet) - 1;
-  sheet->range.coli=column;
-  sheet->active_cell.row=0;
-  sheet->active_cell.col=column;
+  sheet->range.row0 = 0;
+  sheet->range.col0 = column;
+  sheet->range.rowi = yyy_row_count(sheet) - 1;
+  sheet->range.coli = column;
+  sheet->active_cell.row = 0;
+  sheet->active_cell.col = column;
 
   gtk_signal_emit (GTK_OBJECT (sheet), sheet_signals[SELECT_COLUMN], column);
   gtk_sheet_real_select_range(sheet, NULL);
-
 }
 
 void
@@ -2519,6 +2582,7 @@ gtk_sheet_set_scroll_adjustments (GtkSheet *sheet,
 {
    if(sheet->hadjustment != hadjustment)
          gtk_sheet_set_hadjustment (sheet, hadjustment);
+
    if(sheet->vadjustment != vadjustment)
          gtk_sheet_set_vadjustment (sheet, vadjustment);
 }
@@ -3308,15 +3372,16 @@ gtk_sheet_range_draw(GtkSheet *sheet, const GtkSheetRange *range)
  {
    drawing_range.row0=MIN_VISIBLE_ROW(sheet);
    drawing_range.col0=MIN_VISIBLE_COLUMN(sheet);
-   drawing_range.rowi=MAX_VISIBLE_ROW(sheet);
+   drawing_range.rowi=MIN(MAX_VISIBLE_ROW(sheet), yyy_row_count(sheet) - 1);
    drawing_range.coli=MAX_VISIBLE_COLUMN(sheet);
-/*
+   
+
    gdk_draw_rectangle (sheet->pixmap,
                       GTK_WIDGET(sheet)->style->white_gc,
                       TRUE,
                       0,0,
                       sheet->sheet_window_width,sheet->sheet_window_height);
-*/
+
  }
  else
  {
@@ -3412,7 +3477,8 @@ gtk_sheet_range_draw(GtkSheet *sheet, const GtkSheetRange *range)
 
   gtk_sheet_draw_backing_pixmap(sheet, drawing_range);
 
-  if(sheet->state != GTK_SHEET_NORMAL && gtk_sheet_range_isvisible(sheet, sheet->range))
+  if(sheet->state != GTK_SHEET_NORMAL && 
+     gtk_sheet_range_isvisible(sheet, sheet->range))
        gtk_sheet_range_draw_selection(sheet, drawing_range);
   
   if(sheet->state == GTK_STATE_NORMAL && 
@@ -3466,31 +3532,33 @@ gtk_sheet_range_draw_selection(GtkSheet *sheet, GtkSheetRange range)
       area.width= xxx_column_width(sheet, j);
       area.height=yyy_row_height(sheet, i);
 
-      if(i==sheet->range.row0){
-            area.y=area.y+2;
-            area.height=area.height-2;
-      }
+      if(i==sheet->range.row0)
+       {
+         area.y=area.y+2;
+         area.height=area.height-2;
+       }
       if(i==sheet->range.rowi) area.height=area.height-3;
-      if(j==sheet->range.col0){
-            area.x=area.x+2;
-            area.width=area.width-2;
-      }
+      if(j==sheet->range.col0)
+       {
+         area.x=area.x+2;
+         area.width=area.width-2;
+       }
       if(j==sheet->range.coli) area.width=area.width-3;
 
-      if(i!=sheet->active_cell.row || j!=sheet->active_cell.col){
-       gdk_draw_rectangle (sheet->sheet_window,
-                          sheet->xor_gc,
-                          TRUE,
-                          area.x+1,area.y+1,
-                          area.width,area.height);
-      }
+      if(i!=sheet->active_cell.row || j!=sheet->active_cell.col)
+       {
+         gdk_draw_rectangle (sheet->sheet_window,
+                             sheet->xor_gc,
+                             TRUE,
+                             area.x+1,area.y+1,
+                             area.width,area.height);
+       }
     }
 
    }
   }
 
   gtk_sheet_draw_border(sheet, sheet->range);
-
 }
 
 static void
@@ -3507,20 +3575,21 @@ gtk_sheet_draw_backing_pixmap(GtkSheet *sheet, GtkSheetRange range)
 
   height=ROW_TOP_YPIXEL(sheet, range.rowi)-y+yyy_row_height(sheet, range.rowi);
 
-  if(range.row0==sheet->range.row0){
-          y=y-5;
-          height=height+5;
-  }
-  if(range.rowi==sheet->range.rowi) height=height+5;
-  if(range.col0==sheet->range.col0){
-            x=x-5;
-            width=width+5;
-  }
-  if(range.coli==sheet->range.coli) width=width+5;
-
+  if(range.row0 == sheet->range.row0) 
+    {
+      y=y-5;
+      height=height+5;
+    }
+  if(range.rowi==sheet->range.rowi) height = height + 5;
+  if(range.col0==sheet->range.col0)
+    {
+      x = x-5;
+      width = width+5;
+    }
+  if(range.coli == sheet->range.coli) width = width + 5;
   
-  width=MIN(width, sheet->sheet_window_width-x);
-  height=MIN(height, sheet->sheet_window_height-y);
+  width = MIN(width, sheet->sheet_window_width - x);
+  height = MIN(height, sheet->sheet_window_height - y);
 
   x--; 
   y--;
@@ -4094,14 +4163,14 @@ gtk_sheet_activate_cell(GtkSheet *sheet, gint row, gint col)
         gtk_sheet_real_unselect_range(sheet, NULL);
  }
 
- sheet->range.row0=row;
- sheet->range.col0=col;
- sheet->range.rowi=row;
- sheet->range.coli=col;
- sheet->active_cell.row=row;
- sheet->active_cell.col=col;
- sheet->selection_cell.row=row;
- sheet->selection_cell.col=col;
+ sheet->range.row0 = row;
+ sheet->range.col0 = col;
+ sheet->range.rowi = row;
+ sheet->range.coli = col;
+ sheet->active_cell.row = row;
+ sheet->active_cell.col = col;
+ sheet->selection_cell.row = row;
+ sheet->selection_cell.col = col;
 #if 0
  row_button_set(sheet, row);
  column_button_set(sheet, col); 
@@ -4658,7 +4727,7 @@ gtk_sheet_draw_corners(GtkSheet *sheet, GtkSheetRange range)
 
 static void
 gtk_sheet_real_select_range (GtkSheet * sheet,
-                            GtkSheetRange * range)
+                            const GtkSheetRange * range)
 {
   gint state;
 
@@ -4666,10 +4735,12 @@ gtk_sheet_real_select_range (GtkSheet * sheet,
 
   if(range==NULL) range=&sheet->range;
 
+  memcpy(&sheet->range, range, sizeof(*range));
+
   if(range->row0 < 0 || range->rowi < 0) return;
   if(range->col0 < 0 || range->coli < 0) return;
 
-  state=sheet->state;
+  state = sheet->state;
 
 #if 0
   if(state==GTK_SHEET_COLUMN_SELECTED || state==GTK_SHEET_RANGE_SELECTED){
@@ -4755,7 +4826,8 @@ gtk_sheet_unselect_range (GtkSheet * sheet)
 {
   gtk_sheet_real_unselect_range(sheet, NULL);
   sheet->state = GTK_STATE_NORMAL;
-  gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col);
+  gtk_sheet_activate_cell(sheet, 
+                         sheet->active_cell.row, sheet->active_cell.col);
 }
 
 
@@ -4766,16 +4838,14 @@ gtk_sheet_real_unselect_range (GtkSheet * sheet,
   g_return_if_fail (sheet != NULL);
   g_return_if_fail (GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)));
 
-  if(range==NULL){
-     range=&sheet->range;
-  }
+  if( range == NULL)
+    range = &sheet->range;
 
   if(range->row0 < 0 || range->rowi < 0) return;
   if(range->col0 < 0 || range->coli < 0) return;
 
-  if (gtk_sheet_range_isvisible (sheet, *range)){
+  if (gtk_sheet_range_isvisible (sheet, *range))
     gtk_sheet_draw_backing_pixmap(sheet, *range);
-  }
 
 #if 0
   for(i=range->col0; i<=range->coli; i++){
@@ -4787,6 +4857,11 @@ gtk_sheet_real_unselect_range (GtkSheet * sheet,
   }
 #endif
 
+  sheet->range.row0 = -1;
+  sheet->range.rowi = -1;
+  sheet->range.col0 = -1;
+  sheet->range.coli = -1;
+
   gtk_sheet_position_children(sheet);
 }
 
@@ -4806,55 +4881,58 @@ gtk_sheet_expose (GtkWidget * widget,
 
   if (GTK_WIDGET_DRAWABLE (widget))
   {
-      range.row0=ROW_FROM_YPIXEL(sheet,event->area.y);
-      range.col0=COLUMN_FROM_XPIXEL(sheet,event->area.x);
-      range.rowi=ROW_FROM_YPIXEL(sheet,event->area.y+event->area.height);
-      range.coli=COLUMN_FROM_XPIXEL(sheet,event->area.x+event->area.width);
+      range.row0 = ROW_FROM_YPIXEL(sheet, event->area.y);
+      range.col0 = COLUMN_FROM_XPIXEL(sheet, event->area.x);
+      range.rowi = ROW_FROM_YPIXEL(sheet, event->area.y + event->area.height);
+      range.coli = COLUMN_FROM_XPIXEL(sheet, event->area.x + event->area.width);
 
       /* exposure events on the sheet */
-      if(event->window == sheet->row_title_window && sheet->row_titles_visible){
-         gint i;
-         for(i = MIN_VISIBLE_ROW(sheet); i <= MAX_VISIBLE_ROW(sheet); i++)
-           gtk_sheet_button_draw(sheet,i,-1);
-      }
+      if(event->window == sheet->row_title_window && 
+        sheet->row_titles_visible)
+       {
+         gint i;
+         for(i = MIN_VISIBLE_ROW(sheet); i <= MAX_VISIBLE_ROW(sheet); i++)
+           gtk_sheet_row_title_button_draw(sheet, i);
+       }
 
-      if(event->window == sheet->column_title_window && sheet->column_titles_visible){
-         gint i;
-         for(i = MIN_VISIBLE_COLUMN(sheet); i <= MAX_VISIBLE_COLUMN(sheet); i++)
-           gtk_sheet_button_draw(sheet,-1,i);
-      }
+      if(event->window == sheet->column_title_window && 
+        sheet->column_titles_visible)
+       {
+         gint i;
+         for(i = MIN_VISIBLE_COLUMN(sheet); i <= MAX_VISIBLE_COLUMN(sheet); i++)
+           gtk_sheet_column_title_button_draw(sheet, i);
+       }
 
-      if (event->window == sheet->sheet_window){
-        gtk_sheet_draw_backing_pixmap(sheet, range);
+      if (event->window == sheet->sheet_window)
+       {
+         gtk_sheet_draw_backing_pixmap(sheet, range);
               
-        if(sheet->state != GTK_SHEET_NORMAL){
-                if(gtk_sheet_range_isvisible(sheet, sheet->range))          
-                   gtk_sheet_draw_backing_pixmap(sheet, sheet->range);
-                if(GTK_SHEET_IN_RESIZE(sheet) || GTK_SHEET_IN_DRAG(sheet))
-                   gtk_sheet_draw_backing_pixmap(sheet, sheet->drag_range);
-
-                if(gtk_sheet_range_isvisible(sheet, sheet->range))          
-                   gtk_sheet_range_draw_selection(sheet, sheet->range);
-                if(GTK_SHEET_IN_RESIZE(sheet) || GTK_SHEET_IN_DRAG(sheet))
-                   draw_xor_rectangle(sheet, sheet->drag_range);
-        }
-
-        if((!GTK_SHEET_IN_XDRAG(sheet)) && (!GTK_SHEET_IN_YDRAG(sheet))){
-             if(sheet->state == GTK_SHEET_NORMAL){ 
-                 gtk_sheet_draw_active_cell(sheet);
-                 if(!GTK_SHEET_IN_SELECTION(sheet))
-                         gtk_widget_queue_draw(sheet->sheet_entry);
-             }
-        }
-
-
-      }
+         if(sheet->state != GTK_SHEET_NORMAL)
+           {
+             if(gtk_sheet_range_isvisible(sheet, sheet->range))          
+               gtk_sheet_draw_backing_pixmap(sheet, sheet->range);
+             if(GTK_SHEET_IN_RESIZE(sheet) || GTK_SHEET_IN_DRAG(sheet))
+               gtk_sheet_draw_backing_pixmap(sheet, sheet->drag_range);
+
+             if(gtk_sheet_range_isvisible(sheet, sheet->range))          
+               gtk_sheet_range_draw_selection(sheet, sheet->range);
+             if(GTK_SHEET_IN_RESIZE(sheet) || GTK_SHEET_IN_DRAG(sheet))
+               draw_xor_rectangle(sheet, sheet->drag_range);
+           }
 
+         if((!GTK_SHEET_IN_XDRAG(sheet)) && (!GTK_SHEET_IN_YDRAG(sheet)))
+           {
+             if(sheet->state == GTK_SHEET_NORMAL){ 
+               gtk_sheet_draw_active_cell(sheet);
+               if(!GTK_SHEET_IN_SELECTION(sheet))
+                 gtk_widget_queue_draw(sheet->sheet_entry);
+             }
+           }
+       }
   }
 
   if(sheet->state != GTK_SHEET_NORMAL && GTK_SHEET_IN_SELECTION(sheet))
-     gtk_widget_grab_focus(GTK_WIDGET(sheet));
+    gtk_widget_grab_focus(GTK_WIDGET(sheet));
 
   (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
 
@@ -5285,179 +5363,214 @@ gtk_sheet_motion (GtkWidget * widget,
   GtkSheet *sheet;
   GdkModifierType mods;
   GdkCursorType new_cursor;
-  gint x, y, row, column;
+  gint x, y;
+  gint row, column;
 
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
-
   sheet = GTK_SHEET (widget);
 
   /* selections on the sheet */
   x = event->x;
   y = event->y;
 
-  if(event->window == sheet->column_title_window && gtk_sheet_columns_resizable(sheet)){
-    gtk_widget_get_pointer(widget, &x, &y);
-    if(!GTK_SHEET_IN_SELECTION(sheet) && POSSIBLE_XDRAG(sheet, x, &column)){
-      new_cursor=GDK_SB_H_DOUBLE_ARROW;
-      if(new_cursor != sheet->cursor_drag->type){
-        gdk_cursor_destroy(sheet->cursor_drag);
-        sheet->cursor_drag=gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW);
-        gdk_window_set_cursor(sheet->column_title_window,sheet->cursor_drag);
-      }
-    }else{
-      new_cursor=GDK_TOP_LEFT_ARROW;
-      if(!GTK_SHEET_IN_XDRAG(sheet) && new_cursor != sheet->cursor_drag->type){
-        gdk_cursor_destroy(sheet->cursor_drag);
-        sheet->cursor_drag=gdk_cursor_new(GDK_TOP_LEFT_ARROW);
-        gdk_window_set_cursor(sheet->column_title_window,sheet->cursor_drag);
-      }
-    }
-  }      
-
-  if(event->window == sheet->row_title_window && gtk_sheet_rows_resizable(sheet)){
-    gtk_widget_get_pointer(widget, &x, &y);
-    if(!GTK_SHEET_IN_SELECTION(sheet) && POSSIBLE_YDRAG(sheet,y, &column)){
-      new_cursor=GDK_SB_V_DOUBLE_ARROW;
-      if(new_cursor != sheet->cursor_drag->type){
-        gdk_cursor_destroy(sheet->cursor_drag);
-        sheet->cursor_drag=gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW);
-        gdk_window_set_cursor(sheet->row_title_window,sheet->cursor_drag);
-      }
-    }else{
-      new_cursor=GDK_TOP_LEFT_ARROW;
-      if(!GTK_SHEET_IN_YDRAG(sheet) && new_cursor != sheet->cursor_drag->type){
-        gdk_cursor_destroy(sheet->cursor_drag);
-        sheet->cursor_drag=gdk_cursor_new(GDK_TOP_LEFT_ARROW);
-        gdk_window_set_cursor(sheet->row_title_window,sheet->cursor_drag);
-      }
+  if(event->window == sheet->column_title_window && 
+     gtk_sheet_columns_resizable(sheet))
+    {
+      gtk_widget_get_pointer(widget, &x, &y);
+      if(!GTK_SHEET_IN_SELECTION(sheet) && 
+        POSSIBLE_XDRAG(sheet, x, &column))
+       {
+         new_cursor = GDK_SB_H_DOUBLE_ARROW;
+         if(new_cursor != sheet->cursor_drag->type)
+           {
+             gdk_cursor_destroy(sheet->cursor_drag);
+             sheet->cursor_drag = gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW);
+             gdk_window_set_cursor(sheet->column_title_window,
+                                   sheet->cursor_drag);
+           }
+       }
+      else
+       {
+         new_cursor = GDK_TOP_LEFT_ARROW;
+         if(!GTK_SHEET_IN_XDRAG(sheet) && 
+            new_cursor != sheet->cursor_drag->type)
+           {
+             gdk_cursor_destroy(sheet->cursor_drag);
+             sheet->cursor_drag = gdk_cursor_new(GDK_TOP_LEFT_ARROW);
+             gdk_window_set_cursor(sheet->column_title_window,
+                                   sheet->cursor_drag);
+           }
+       }
+    }      
+
+  if(event->window == sheet->row_title_window && 
+     gtk_sheet_rows_resizable(sheet))
+    {
+      gtk_widget_get_pointer(widget, &x, &y);
+      if(!GTK_SHEET_IN_SELECTION(sheet) && POSSIBLE_YDRAG(sheet,y, &column))
+       {
+         new_cursor = GDK_SB_V_DOUBLE_ARROW;
+         if(new_cursor != sheet->cursor_drag->type){
+           gdk_cursor_destroy(sheet->cursor_drag);
+           sheet->cursor_drag = gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW);
+           gdk_window_set_cursor(sheet->row_title_window, sheet->cursor_drag);
+         }
+       }
+      else
+       {
+         new_cursor = GDK_TOP_LEFT_ARROW;
+         if(!GTK_SHEET_IN_YDRAG(sheet) && 
+            new_cursor != sheet->cursor_drag->type)
+           {
+             gdk_cursor_destroy(sheet->cursor_drag);
+             sheet->cursor_drag = gdk_cursor_new(GDK_TOP_LEFT_ARROW);
+             gdk_window_set_cursor(sheet->row_title_window, sheet->cursor_drag);
+           }
+       }
+    }      
+
+  new_cursor = GDK_PLUS;
+  if( event->window == sheet->sheet_window && 
+     !POSSIBLE_DRAG(sheet, x, y, &row, &column) && 
+     !GTK_SHEET_IN_DRAG(sheet) &&
+     !POSSIBLE_RESIZE(sheet, x, y, &row, &column) && 
+     !GTK_SHEET_IN_RESIZE(sheet) &&
+     new_cursor != sheet->cursor_drag->type)
+    {
+      gdk_cursor_destroy(sheet->cursor_drag);
+      sheet->cursor_drag = gdk_cursor_new(GDK_PLUS);
+      gdk_window_set_cursor(sheet->sheet_window, sheet->cursor_drag);
     }
-  }      
-
-  new_cursor=GDK_PLUS;
-  if(!POSSIBLE_DRAG(sheet,x,y,&row,&column) && !GTK_SHEET_IN_DRAG(sheet) &&
-     !POSSIBLE_RESIZE(sheet,x,y,&row,&column) && !GTK_SHEET_IN_RESIZE(sheet) &&
-     event->window == sheet->sheet_window && 
-     new_cursor != sheet->cursor_drag->type){
-         gdk_cursor_destroy(sheet->cursor_drag);
-         sheet->cursor_drag=gdk_cursor_new(GDK_PLUS);
-         gdk_window_set_cursor(sheet->sheet_window,sheet->cursor_drag);
-  }
 
-  new_cursor=GDK_TOP_LEFT_ARROW;
-  if(!(POSSIBLE_RESIZE(sheet,x,y,&row,&column) || GTK_SHEET_IN_RESIZE(sheet)) &&
-     (POSSIBLE_DRAG(sheet, x,y,&row,&column) || GTK_SHEET_IN_DRAG(sheet)) && 
-     event->window == sheet->sheet_window && 
-     new_cursor != sheet->cursor_drag->type){
-         gdk_cursor_destroy(sheet->cursor_drag);
-         sheet->cursor_drag=gdk_cursor_new(GDK_TOP_LEFT_ARROW);
-         gdk_window_set_cursor(sheet->sheet_window,sheet->cursor_drag);
-  }
+  new_cursor = GDK_TOP_LEFT_ARROW;
+  if( event->window == sheet->sheet_window && 
+      !(POSSIBLE_RESIZE(sheet,x,y,&row,&column) || GTK_SHEET_IN_RESIZE(sheet)) &&     (POSSIBLE_DRAG(sheet, x,y,&row,&column) || GTK_SHEET_IN_DRAG(sheet)) && 
+
+      new_cursor != sheet->cursor_drag->type)
+    {
+      gdk_cursor_destroy(sheet->cursor_drag);
+      sheet->cursor_drag=gdk_cursor_new(GDK_TOP_LEFT_ARROW);
+      gdk_window_set_cursor(sheet->sheet_window,sheet->cursor_drag);
+    }
 
   new_cursor=GDK_SIZING;
-  if(!GTK_SHEET_IN_DRAG(sheet) &&
-     (POSSIBLE_RESIZE(sheet,x,y,&row,&column) || GTK_SHEET_IN_RESIZE(sheet)) &&
-     event->window == sheet->sheet_window && 
-     new_cursor != sheet->cursor_drag->type){
-         gdk_cursor_destroy(sheet->cursor_drag);
-         sheet->cursor_drag=gdk_cursor_new(GDK_SIZING);
-         gdk_window_set_cursor(sheet->sheet_window,sheet->cursor_drag);
-  }
+  if( event->window == sheet->sheet_window && 
+      !GTK_SHEET_IN_DRAG(sheet) &&
+      (POSSIBLE_RESIZE(sheet, x, y, &row, &column) || 
+       GTK_SHEET_IN_RESIZE(sheet)) &&
+      new_cursor != sheet->cursor_drag->type)
+    {
+      gdk_cursor_destroy(sheet->cursor_drag);
+      sheet->cursor_drag=gdk_cursor_new(GDK_SIZING);
+      gdk_window_set_cursor(sheet->sheet_window,sheet->cursor_drag);
+    }
 
   gdk_window_get_pointer (widget->window, &x, &y, &mods);
   if(!(mods & GDK_BUTTON1_MASK)) return FALSE;
 
-  if (GTK_SHEET_IN_XDRAG (sheet)){
-       if (event->is_hint || event->window != widget->window)
-           gtk_widget_get_pointer (widget, &x, NULL);
-         else
-           x = event->x;
+  if (GTK_SHEET_IN_XDRAG (sheet))
+    {
+      if (event->is_hint || event->window != widget->window)
+       gtk_widget_get_pointer (widget, &x, NULL);
+      else
+       x = event->x;
 
-         new_column_width (sheet, sheet->drag_cell.col, &x);
-         if (x != sheet->x_drag)
-           {
-             draw_xor_vline (sheet);
-             sheet->x_drag = x;
-             draw_xor_vline (sheet);
-           }
-          return TRUE;
-  }
+      new_column_width (sheet, sheet->drag_cell.col, &x);
+      if (x != sheet->x_drag)
+       {
+         draw_xor_vline (sheet);
+         sheet->x_drag = x;
+         draw_xor_vline (sheet);
+       }
+      return TRUE;
+    }
 
-  if (GTK_SHEET_IN_YDRAG (sheet)){
-         if (event->is_hint || event->window != widget->window)
-           gtk_widget_get_pointer (widget, NULL, &y);
-         else
-           y = event->y;
+  if (GTK_SHEET_IN_YDRAG (sheet))
+    {
+      if (event->is_hint || event->window != widget->window)
+       gtk_widget_get_pointer (widget, NULL, &y);
+      else
+       y = event->y;
+
+      new_row_height (sheet, sheet->drag_cell.row, &y);
+      if (y != sheet->y_drag)
+       {
+         draw_xor_hline (sheet);
+         sheet->y_drag = y;
+         draw_xor_hline (sheet);
+       }
+      return TRUE;
+    }
 
-         new_row_height (sheet, sheet->drag_cell.row, &y);
-         if (y != sheet->y_drag)
+  if (GTK_SHEET_IN_DRAG(sheet))
+    {
+      GtkSheetRange aux;
+      column=COLUMN_FROM_XPIXEL(sheet,x)-sheet->drag_cell.col;
+      row=ROW_FROM_YPIXEL(sheet,y)-sheet->drag_cell.row;
+      if(sheet->state==GTK_SHEET_COLUMN_SELECTED) row=0;
+      if(sheet->state==GTK_SHEET_ROW_SELECTED) column=0;
+      sheet->x_drag=x;
+      sheet->y_drag=y;
+      aux=sheet->range;
+      if(aux.row0+row >= 0 && aux.rowi+row < yyy_row_count(sheet) &&
+        aux.col0+column >= 0 && aux.coli+column < xxx_column_count(sheet))
+       {
+         aux=sheet->drag_range;
+         sheet->drag_range.row0 = sheet->range.row0 + row;
+         sheet->drag_range.col0 = sheet->range.col0 + column;
+         sheet->drag_range.rowi = sheet->range.rowi + row;
+         sheet->drag_range.coli = sheet->range.coli + column;
+         if(aux.row0 != sheet->drag_range.row0 ||
+            aux.col0 != sheet->drag_range.col0)
            {
-             draw_xor_hline (sheet);
-             sheet->y_drag = y;
-             draw_xor_hline (sheet);
+             draw_xor_rectangle (sheet, aux);
+             draw_xor_rectangle (sheet, sheet->drag_range);
            }
-          return TRUE;
-  }
-
-  if (GTK_SHEET_IN_DRAG(sheet)){
-       GtkSheetRange aux;
-       column=COLUMN_FROM_XPIXEL(sheet,x)-sheet->drag_cell.col;
-       row=ROW_FROM_YPIXEL(sheet,y)-sheet->drag_cell.row;
-       if(sheet->state==GTK_SHEET_COLUMN_SELECTED) row=0;
-       if(sheet->state==GTK_SHEET_ROW_SELECTED) column=0;
-       sheet->x_drag=x;
-       sheet->y_drag=y;
-       aux=sheet->range;
-       if(aux.row0+row >= 0 && aux.rowi+row < yyy_row_count(sheet) &&
-          aux.col0+column >= 0 && aux.coli+column < xxx_column_count(sheet)){
-             aux=sheet->drag_range;
-             sheet->drag_range.row0=sheet->range.row0+row;
-             sheet->drag_range.col0=sheet->range.col0+column;
-             sheet->drag_range.rowi=sheet->range.rowi+row;
-             sheet->drag_range.coli=sheet->range.coli+column;
-             if(aux.row0 != sheet->drag_range.row0 ||
-                aux.col0 != sheet->drag_range.col0){
-                draw_xor_rectangle (sheet, aux);
-                draw_xor_rectangle (sheet, sheet->drag_range);
-             }
-       }
-       return TRUE;
-  }
+       }
+      return TRUE;
+    }
 
-  if (GTK_SHEET_IN_RESIZE(sheet)){
-       GtkSheetRange aux;
-       gint v_h, current_col, current_row, col_threshold, row_threshold;
-       v_h=1;
+  if (GTK_SHEET_IN_RESIZE(sheet))
+    {
+      GtkSheetRange aux;
+      gint v_h, current_col, current_row, col_threshold, row_threshold;
+      v_h=1;
 
-       if(abs(x-COLUMN_LEFT_XPIXEL(sheet,sheet->drag_cell.col)) >
-          abs(y-ROW_TOP_YPIXEL(sheet,sheet->drag_cell.row))) v_h=2;
+      if(abs(x-COLUMN_LEFT_XPIXEL(sheet,sheet->drag_cell.col)) >
+        abs(y-ROW_TOP_YPIXEL(sheet,sheet->drag_cell.row))) v_h=2;
         
-       current_col = COLUMN_FROM_XPIXEL(sheet,x);
-       current_row = ROW_FROM_YPIXEL(sheet,y);
-       column = current_col-sheet->drag_cell.col;
-       row    = current_row-sheet->drag_cell.row;
-
-       /*use half of column width resp. row height as threshold to expand selection*/
-       col_threshold = COLUMN_LEFT_XPIXEL(sheet,current_col)+xxx_column_width (sheet,current_col)/2;
-       if (column > 0){
-         if (x < col_threshold)
-           column-=1;
-       }
-       else if (column < 0){
-         if (x > col_threshold) 
-          column+=1;
-       }
-       row_threshold = ROW_TOP_YPIXEL(sheet,current_row)+yyy_row_height (sheet, current_row)/2;
-       if (row > 0){
-         if(y < row_threshold)
-           row-=1;
-       }
-       else if (row < 0){
-         if(y > row_threshold)
-           row+=1;       
-       }
+      current_col = COLUMN_FROM_XPIXEL(sheet,x);
+      current_row = ROW_FROM_YPIXEL(sheet,y);
+      column = current_col-sheet->drag_cell.col;
+      row    = current_row-sheet->drag_cell.row;
+
+      /*use half of column width resp. row height as threshold to expand selection*/
+      col_threshold = COLUMN_LEFT_XPIXEL(sheet,current_col)+xxx_column_width (sheet,current_col)/2;
+      if (column > 0)
+       {
+         if (x < col_threshold)
+           column-=1;
+       }
+      else if (column < 0)
+       {
+         if (x > col_threshold) 
+           column+=1;
+       }
+       row_threshold = ROW_TOP_YPIXEL(sheet,current_row) + 
+        yyy_row_height (sheet, current_row)/2;
+       if (row > 0)
+        {
+          if(y < row_threshold)
+            row-=1;
+        }
+       else if (row < 0)
+        {
+          if(y > row_threshold)
+            row+=1;       
+        }
 
        if(sheet->state==GTK_SHEET_COLUMN_SELECTED) row=0;
        if(sheet->state==GTK_SHEET_ROW_SELECTED) column=0;
@@ -6088,7 +6201,7 @@ size_allocate_column_title_buttons (GtkSheet * sheet)
   if(!GTK_WIDGET_DRAWABLE(sheet)) return;
 
   for (i = MIN_VISIBLE_COLUMN(sheet); i <= MAX_VISIBLE_COLUMN(sheet); i++)
-      gtk_sheet_button_draw(sheet,-1,i);
+    gtk_sheet_column_title_button_draw(sheet, i);
 }
        
 static void
@@ -6129,7 +6242,11 @@ size_allocate_row_title_buttons (GtkSheet * sheet)
   if(!GTK_WIDGET_DRAWABLE(sheet)) return;
 
   for(i = MIN_VISIBLE_ROW(sheet); i <= MAX_VISIBLE_ROW(sheet); i++)
-      gtk_sheet_button_draw(sheet,i,-1);
+    {
+      if ( i >= yyy_row_count(sheet))
+       break;
+      gtk_sheet_row_title_button_draw(sheet, i);
+    }
 }
          
 
@@ -6325,51 +6442,47 @@ create_sheet_entry(GtkSheet *sheet)
 
  widget = GTK_WIDGET(sheet);
 
- if(sheet->sheet_entry){
-    /* avoids warnings */
-    gtk_widget_ref(sheet->sheet_entry);
-    gtk_widget_unparent(sheet->sheet_entry);
-    gtk_widget_destroy(sheet->sheet_entry);
- }
-
- if(sheet->entry_type){
-
-   if(!g_type_is_a (sheet->entry_type, GTK_TYPE_ENTRY)){
-
-     parent = GTK_WIDGET(gtk_type_new(sheet->entry_type));
-
-     sheet->sheet_entry = parent;
-
-     entry = gtk_sheet_get_entry (sheet);
-     if(GTK_IS_ENTRY(entry)) found_entry = TRUE;
+ if(sheet->sheet_entry)
+   {
+     /* avoids warnings */
+     gtk_widget_ref(sheet->sheet_entry);
+     gtk_widget_unparent(sheet->sheet_entry);
+     gtk_widget_destroy(sheet->sheet_entry);
+   }
 
-   } else {
+ if(sheet->entry_type)
+   {
+     if(!g_type_is_a (sheet->entry_type, GTK_TYPE_ENTRY))
+       {
+       parent = GTK_WIDGET(gtk_type_new(sheet->entry_type));
 
-     parent = GTK_WIDGET(gtk_type_new(sheet->entry_type));
-     entry = parent;
-     found_entry = TRUE;
+       sheet->sheet_entry = parent;
 
-   }             
+       entry = gtk_sheet_get_entry (sheet);
+       if(GTK_IS_ENTRY(entry)) 
+        found_entry = TRUE;
+       } 
+     else 
+       {
+        parent = GTK_WIDGET(gtk_type_new(sheet->entry_type));
+        entry = parent;
+        found_entry = TRUE;
+       }             
                                     
-   if(!found_entry){
-
-     g_warning ("Entry type must be GtkEntry subclass, using default");
-     entry = gtk_item_entry_new();
-     sheet->sheet_entry = entry;
-
-   } else {
-
+   if(!found_entry)
+     {
+       g_warning ("Entry type must be GtkEntry subclass, using default");
+       entry = gtk_item_entry_new();
+       sheet->sheet_entry = entry;
+     } 
+   else
      sheet->sheet_entry = parent;
-
-   }
-
-
- } else {
-
+ } 
+ else 
+   {
      entry = gtk_item_entry_new();
      sheet->sheet_entry = entry;
-
- }
+   }
  
  gtk_widget_size_request(sheet->sheet_entry, NULL);
  
@@ -6461,217 +6574,239 @@ gtk_sheet_get_entry_widget(GtkSheet *sheet)
  return (sheet->sheet_entry);
 }
 
-#if 0
-/* BUTTONS */
-static void
-row_button_set (GtkSheet *sheet, gint row)
-{
-  if(sheet->row[row].button.state == GTK_STATE_ACTIVE) return;
-
-  sheet->row[row].button.state = GTK_STATE_ACTIVE;
-  gtk_sheet_button_draw(sheet, row, -1);
-}
-
-static void
-row_button_release (GtkSheet *sheet, gint row)
-{
-  if(sheet->row[row].button.state == GTK_STATE_NORMAL) return;
-
-  sheet->row[row].button.state = GTK_STATE_NORMAL;
-  gtk_sheet_button_draw(sheet, row, -1);
-}
-#endif
 
 static void
-gtk_sheet_button_draw (GtkSheet *sheet, gint row, gint column)
+gtk_sheet_button_draw(GtkSheet *sheet, GdkWindow *window, 
+                     GtkSheetButton *button, gboolean is_sensitive,
+                     GdkRectangle allocation)
 {
-  GdkWindow *window = NULL;
   GtkShadowType shadow_type;
-  guint width = 0, height = 0;
-  gint x = 0, y = 0;
-  gint index = 0;
   gint text_width = 0, text_height = 0;
-  GtkSheetButton *button = NULL;
   GtkSheetChild *child = NULL;
-  GdkRectangle allocation;
-  gboolean is_sensitive = FALSE;
+  PangoAlignment align = PANGO_ALIGN_LEFT; 
+
+  gboolean rtl ;
+
   gint state = 0;
   gint len = 0;
   gchar *line = 0;
 
-  PangoAlignment align = PANGO_ALIGN_LEFT; 
-  gboolean rtl;
+  g_return_if_fail(sheet != NULL);
+  g_return_if_fail(button != NULL);
 
   rtl = gtk_widget_get_direction(GTK_WIDGET(sheet)) == GTK_TEXT_DIR_RTL;
-
-  if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return;
-
-  if(row >= 0 && !yyy_row_is_visible(sheet, row)) return;
-  if(column >= 0 && ! xxx_column_is_visible(sheet, column)) return;
-  if(row >= 0 && !sheet->row_titles_visible) return;
-  if(column >= 0 && !sheet->column_titles_visible) return;
-  if(column>=0 && column < MIN_VISIBLE_COLUMN(sheet)) return;
-  if(column>=0 && column > MAX_VISIBLE_COLUMN(sheet)) return;
-  if(row>=0 && row < MIN_VISIBLE_ROW(sheet)) return;
-  if(row>=0 && row > MAX_VISIBLE_ROW(sheet)) return;
-  if( (row == -1) && (column == -1) ) return; 
-
-  if(row==-1){
-     window=sheet->column_title_window;
-     button= xxx_column_button(sheet, column);
-     index=column;
-     x = COLUMN_LEFT_XPIXEL(sheet, column)+CELL_SPACING;
-     if(sheet->row_titles_visible) x -= sheet->row_title_area.width;
-     y = 0;
-     width = xxx_column_width(sheet, column);
-     height = sheet->column_title_area.height;
-     is_sensitive=xxx_column_is_sensitive(sheet, column);
-  }
-  if(column==-1){
-     window=sheet->row_title_window;
-     button = yyy_row_button(sheet, row);
-     index=row;
-     x = 0;
-     y = ROW_TOP_YPIXEL(sheet, row)+CELL_SPACING;
-     if(sheet->column_titles_visible) y-=sheet->column_title_area.height;
-     width = sheet->row_title_area.width;
-     height = yyy_row_height(sheet, row);
-     is_sensitive=yyy_row_is_sensitive(sheet, row);
-  }
-
-  allocation.x = x;
-  allocation.y = y;
-  allocation.width = width;
-  allocation.height = height;
+  
   gdk_window_clear_area (window,
-                         x, y,
-                        width, height);
+                         allocation.x, allocation.y,
+                        allocation.width, allocation.height);
 
   gtk_paint_box (sheet->button->style, window,
                  GTK_STATE_NORMAL, GTK_SHADOW_OUT, 
                  &allocation, GTK_WIDGET(sheet->button),
-                 "buttondefault", x, y, width, height);
-
+                 "buttondefault", 
+                allocation.x, allocation.y, 
+                allocation.width, allocation.height);
+  
   state = button->state;
-  if(!is_sensitive) state=GTK_STATE_INSENSITIVE;
+  if(!is_sensitive) state = GTK_STATE_INSENSITIVE;
 
   if (state == GTK_STATE_ACTIVE)
-     shadow_type = GTK_SHADOW_IN;
+    shadow_type = GTK_SHADOW_IN;
   else
-     shadow_type = GTK_SHADOW_OUT;
+    shadow_type = GTK_SHADOW_OUT;
 
   if(state != GTK_STATE_NORMAL && state != GTK_STATE_INSENSITIVE)
     gtk_paint_box (sheet->button->style, window,
                   button->state, shadow_type, 
                   &allocation, GTK_WIDGET(sheet->button),
-                  "button", x, y, width, height);
+                  "button", 
+                  allocation.x, allocation.y, 
+                  allocation.width, allocation.height);
 
-  if(button->label_visible){
+  if(button->label_visible)
+    {
 
-    text_height=DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet))-2*CELLOFFSET;
+      text_height=DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet))-2*CELLOFFSET;
 
-    gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->fg_gc[button->state], 
-                              &allocation);
-    gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->white_gc, &allocation);
+      gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->fg_gc[button->state], 
+                               &allocation);
+      gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->white_gc, &allocation);
 
-    y += 2*sheet->button->style->ythickness;
+      allocation.y += 2*sheet->button->style->ythickness;
 
 
-    if(button->label && strlen(button->label)>0){
-           gchar *words = 0;
-           PangoLayout *layout = NULL;
-           gint real_x = x, real_y = y;
+      if(button->label && strlen(button->label)>0){
+       gchar *words = 0;
+       PangoLayout *layout = NULL;
+       gint real_x = allocation.x, real_y = allocation.y;
 
-           words=button->label;
-           line = g_new(gchar, 1);
-           line[0]='\0';
+       words=button->label;
+       line = g_new(gchar, 1);
+       line[0]='\0';
 
-           while(words && *words != '\0'){
-             if(*words != '\n'){
-                len=strlen(line);
-                line=g_realloc(line, len+2);
-                line[len]=*words;
-                line[len+1]='\0';
-             }
-             if(*words == '\n' || *(words+1) == '\0'){
-               text_width = STRING_WIDTH(GTK_WIDGET(sheet), GTK_WIDGET(sheet)->style->font_desc, line);
-
-               layout = gtk_widget_create_pango_layout (GTK_WIDGET(sheet), line);
-               switch(button->justification){
-                 case GTK_JUSTIFY_LEFT:
-                   real_x = x + CELLOFFSET;
-                   align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT;
-                   break;
-                 case GTK_JUSTIFY_RIGHT:
-                   real_x = x + width - text_width - CELLOFFSET;
-                   align = rtl ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT;
-                   break;
-                 case GTK_JUSTIFY_CENTER:
-                 default:
-                   real_x = x + (width - text_width)/2;
-                   align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT;
-                   pango_layout_set_justify (layout, TRUE);
-               }
-               pango_layout_set_alignment (layout, align);
-               gtk_paint_layout (GTK_WIDGET(sheet)->style,
-                                 window,
-                                 state,
-                                 FALSE,
-                                 &allocation,
-                                 GTK_WIDGET(sheet),
-                                 "label",
-                                 real_x, real_y,
-                                 layout);
-               g_object_unref(G_OBJECT(layout));
-
-               real_y += text_height + 2;
-
-               g_free(line);
-               line = g_new(gchar, 1);
-               line[0]='\0';
-             }
-             words++;
-           }
-           g_free(line);
-    }
+       while(words && *words != '\0'){
+         if(*words != '\n'){
+           len=strlen(line);
+           line=g_realloc(line, len+2);
+           line[len]=*words;
+           line[len+1]='\0';
+         }
+         if(*words == '\n' || *(words+1) == '\0'){
+           text_width = STRING_WIDTH(GTK_WIDGET(sheet), GTK_WIDGET(sheet)->style->font_desc, line);
+
+           layout = gtk_widget_create_pango_layout (GTK_WIDGET(sheet), line);
+           switch(button->justification){
+           case GTK_JUSTIFY_LEFT:
+             real_x = allocation.x + CELLOFFSET;
+             align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT;
+             break;
+           case GTK_JUSTIFY_RIGHT:
+             real_x = allocation.x + allocation.width - text_width - CELLOFFSET;
+             align = rtl ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT;
+             break;
+           case GTK_JUSTIFY_CENTER:
+           default:
+             real_x = allocation.x + (allocation.width - text_width)/2;
+             align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT;
+             pango_layout_set_justify (layout, TRUE);
+           }
+           pango_layout_set_alignment (layout, align);
+           gtk_paint_layout (GTK_WIDGET(sheet)->style,
+                             window,
+                             state,
+                             FALSE,
+                             &allocation,
+                             GTK_WIDGET(sheet),
+                             "label",
+                             real_x, real_y,
+                             layout);
+           g_object_unref(G_OBJECT(layout));
+
+           real_y += text_height + 2;
+
+           g_free(line);
+           line = g_new(gchar, 1);
+           line[0]='\0';
+         }
+         words++;
+       }
+       g_free(line);
+      }
 
-    gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->fg_gc[button->state],
-                            NULL);
-    gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->white_gc, NULL);
+      gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->fg_gc[button->state],
+                               NULL);
+      gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->white_gc, NULL);
 
-  }
+    }
 
-  if((child = button->child) && (child->widget)){
+  if((child = button->child) && (child->widget))
+    {
       child->x = allocation.x;
       child->y = allocation.y;
 
-      child->x += (width - child->widget->requisition.width) / 2; 
-      child->y += (height - child->widget->requisition.height) / 2;
+      child->x += (allocation.width - child->widget->requisition.width) / 2; 
+      child->y += (allocation.height - child->widget->requisition.height) / 2;
       allocation.x = child->x;
       allocation.y = child->y;
       allocation.width = child->widget->requisition.width;
       allocation.height = child->widget->requisition.height;
 
-      x = child->x;
-      y = child->y;
+      allocation.x = child->x;
+      allocation.y = child->y;
 
       gtk_widget_set_state(child->widget, button->state);
 
       if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)) &&
-         GTK_WIDGET_MAPPED(child->widget))
-            {
-              gtk_widget_size_allocate(child->widget, 
-                                       &allocation);
-              gtk_widget_queue_draw(child->widget);
-            }
-  }
+        GTK_WIDGET_MAPPED(child->widget))
+       {
+         gtk_widget_size_allocate(child->widget, 
+                                  &allocation);
+         gtk_widget_queue_draw(child->widget);
+       }
+    }
 
   gtk_sheet_button_free(button);
+}
    
+
+/* COLUMN value of -1 indicates that the area to the right of the rightmost 
+   button should be redrawn */
+static void
+gtk_sheet_column_title_button_draw(GtkSheet *sheet, gint column)
+{
+  GdkWindow *window = NULL;
+  GdkRectangle allocation;
+  GtkSheetButton *button = NULL;
+  gboolean is_sensitive = FALSE;
+
+  if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return;
+
+  if(column >= 0 && ! xxx_column_is_visible(sheet, column)) return;
+  if(column >= 0 && !sheet->column_titles_visible) return;
+  if(column>=0 && column < MIN_VISIBLE_COLUMN(sheet)) return;
+  if(column>=0 && column > MAX_VISIBLE_COLUMN(sheet)) return;
+
+  window = sheet->column_title_window;
+  allocation.y = 0;
+  allocation.height = sheet->column_title_area.height;
+
+  if ( column == -1 ) 
+    {
+      const gint cols = xxx_column_count(sheet) ;
+      allocation.x = COLUMN_LEFT_XPIXEL(sheet, cols - 1) 
+       ;
+      allocation.width = sheet->column_title_area.width 
+       + sheet->column_title_area.x 
+       - allocation.x;
+
+      gdk_window_clear_area (window,
+                            allocation.x, allocation.y,
+                            allocation.width, allocation.height);
+    }
+  else 
+    {
+      button = xxx_column_button(sheet, column);
+      allocation.x = COLUMN_LEFT_XPIXEL(sheet, column) + CELL_SPACING;
+      if(sheet->row_titles_visible) 
+       allocation.x -= sheet->row_title_area.width;
+
+      allocation.width = xxx_column_width(sheet, column);
+
+      is_sensitive = xxx_column_is_sensitive(sheet, column);
+      gtk_sheet_button_draw(sheet, window, button, 
+                           is_sensitive, allocation);
+    }
 }
 
+static void
+gtk_sheet_row_title_button_draw(GtkSheet *sheet, gint row)
+{
+  GdkWindow *window = NULL;
+  GdkRectangle allocation;
+  GtkSheetButton *button = NULL;
+  gboolean is_sensitive = FALSE;
+
+
+  if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return;
+
+  if(row >= 0 && !yyy_row_is_visible(sheet, row)) return;
+  if(row >= 0 && !sheet->row_titles_visible) return;
+  if(row>=0 && row < MIN_VISIBLE_ROW(sheet)) return;
+  if(row>=0 && row > MAX_VISIBLE_ROW(sheet)) return;
+
+
+  window=sheet->row_title_window;
+  button = yyy_row_button(sheet, row);
+  allocation.x = 0;
+  allocation.y = ROW_TOP_YPIXEL(sheet, row) + CELL_SPACING;
+  if(sheet->column_titles_visible) 
+    allocation.y -= sheet->column_title_area.height;
+  allocation.width = sheet->row_title_area.width;
+  allocation.height = yyy_row_height(sheet, row);
+  is_sensitive = yyy_row_is_sensitive(sheet, row);
+
+  gtk_sheet_button_draw(sheet, window, button, is_sensitive, allocation);
+}
 
 /* SCROLLBARS
  *
@@ -6785,9 +6920,9 @@ vadjustment_value_changed (GtkAdjustment * adjustment,
 
   if(GTK_SHEET_IS_FROZEN(sheet)) return;
 
-  row=ROW_FROM_YPIXEL(sheet,sheet->column_title_area.height + CELL_SPACING);
+  row = ROW_FROM_YPIXEL(sheet,sheet->column_title_area.height + CELL_SPACING);
   if(!sheet->column_titles_visible)
-     row=ROW_FROM_YPIXEL(sheet,CELL_SPACING);
+     row=ROW_FROM_YPIXEL(sheet, CELL_SPACING);
     
   old_value = -sheet->voffset;
 
@@ -6797,71 +6932,77 @@ vadjustment_value_changed (GtkAdjustment * adjustment,
   y = g_sheet_row_start_pixel(sheet->row_geometry, new_row, sheet);
 
   if (adjustment->value > sheet->old_vadjustment && sheet->old_vadjustment > 0. &&
-      yyy_row_height(sheet, row) > sheet->vadjustment->step_increment){
-/* This avoids embarrassing twitching */
-          if(row == new_row && row != yyy_row_count(sheet) - 1 &&
-             adjustment->value - sheet->old_vadjustment >= 
-                          sheet->vadjustment->step_increment &&
-             new_row + 1 != MIN_VISIBLE_ROW(sheet)){
-                new_row+=1;
-                y=y+yyy_row_height(sheet, row);
-          }
-  }
+      yyy_row_height(sheet, row) > sheet->vadjustment->step_increment)
+    {
+      /* This avoids embarrassing twitching */
+      if(row == new_row && row != yyy_row_count(sheet) - 1 &&
+        adjustment->value - sheet->old_vadjustment >= 
+        sheet->vadjustment->step_increment &&
+        new_row + 1 != MIN_VISIBLE_ROW(sheet)){
+       new_row+=1;
+       y=y+yyy_row_height(sheet, row);
+      }
+    }
 
-/* Negative old_adjustment enforces the redraw, otherwise avoid spureous redraw */
-  if(sheet->old_vadjustment >= 0. && row == new_row){
+  /* Negative old_adjustment enforces the redraw, otherwise avoid 
+     spureous redraw */
+  if(sheet->old_vadjustment >= 0. && row == new_row)
+    {
       sheet->old_vadjustment = sheet->vadjustment->value;
       return;
-  }
+    }
 
   sheet->old_vadjustment = sheet->vadjustment->value;
   adjustment->value=y;
 
  
-  if(new_row == 0){
-   sheet->vadjustment->step_increment=  yyy_row_height(sheet, 0);
-  }else{
-   sheet->vadjustment->step_increment=
-   MIN(yyy_row_height(sheet, new_row), yyy_row_height(sheet, new_row-1));
-  }
+  if(new_row == 0)
+    {
+      sheet->vadjustment->step_increment =  yyy_row_height(sheet, 0);
+    }
+  else
+    {
+      sheet->vadjustment->step_increment =
+       MIN(yyy_row_height(sheet, new_row), yyy_row_height(sheet, new_row-1));
+    }
 
-  sheet->vadjustment->value=adjustment->value;
+  sheet->vadjustment->value = adjustment->value;
 
   value = adjustment->value;
 
   if (value >= -sheet->voffset)
-       {
-         /* scroll down */
-         diff = value + sheet->voffset;
-       }
+    {
+      /* scroll down */
+      diff = value + sheet->voffset;
+    }
   else
-       {
-         /* scroll up */
-         diff = -sheet->voffset - value;
-       }
+    {
+      /* scroll up */
+      diff = -sheet->voffset - value;
+    }
 
-      sheet->voffset = -value;
+  sheet->voffset = -value;
  
-  sheet->view.row0=ROW_FROM_YPIXEL(sheet, sheet->column_title_area.height+1);
-  sheet->view.rowi=ROW_FROM_YPIXEL(sheet, sheet->sheet_window_height-1);
+  sheet->view.row0=ROW_FROM_YPIXEL(sheet, sheet->column_title_area.height + 1);
+  sheet->view.rowi=ROW_FROM_YPIXEL(sheet, sheet->sheet_window_height - 1);
   if(!sheet->column_titles_visible)
-     sheet->view.row0=ROW_FROM_YPIXEL(sheet, 1);
+    sheet->view.row0=ROW_FROM_YPIXEL(sheet, 1);
 
   if(GTK_WIDGET_REALIZED(sheet->sheet_entry) &&
      sheet->state == GTK_SHEET_NORMAL && 
      sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0 &&
      !gtk_sheet_cell_isvisible(sheet, sheet->active_cell.row,
-                                      sheet->active_cell.col))
+                              sheet->active_cell.col))
     {
       const gchar *text;
 
       text = gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet)));
 
       if(!text || strlen(text)==0) 
-             gtk_sheet_cell_clear(sheet,
-                                  sheet->active_cell.row,
-                                  sheet->active_cell.col);
-       gtk_widget_unmap(sheet->sheet_entry);
+       gtk_sheet_cell_clear(sheet,
+                            sheet->active_cell.row,
+                            sheet->active_cell.col);
+      gtk_widget_unmap(sheet->sheet_entry);
     }
 
   gtk_sheet_position_children(sheet);
@@ -7106,7 +7247,7 @@ new_column_width (GtkSheet * sheet,
     width = min_width;
 
   xxx_set_column_width(sheet, column, width);
-  sheet->view.coli=COLUMN_FROM_XPIXEL(sheet, sheet->sheet_window_width);
+  sheet->view.coli = COLUMN_FROM_XPIXEL(sheet, sheet->sheet_window_width);
   size_allocate_column_title_buttons (sheet);
   
   return width;
@@ -7931,6 +8072,8 @@ gtk_sheet_button_new(void)
 inline void
 gtk_sheet_button_free(GtkSheetButton *button)
 {
+  if (!button) return ;
+   
   g_free(button->label);
   g_free(button);
 }
index d8db6c40e39098ff2dd5138e45aae06ae5588138..1b87be408bdebbff9c35d8bcc6352bd300510327 100644 (file)
@@ -437,7 +437,7 @@ gtk_sheet_row_button_justify                (GtkSheet *sheet,
 
 /* scroll the viewing area of the sheet to the given column
  * and row; row_align and col_align are between 0-1 representing the
- * location the row should appear on the screnn, 0.0 being top or left,
+ * location the row should appear on the screen, 0.0 being top or left,
  * 1.0 being bottom or right; if row or column is negative then there
  * is no change */
 void
index 238601c6d9bd838d6e8076580fb20dcd5c7a9c1e..0faa3504583841524a1e282c5217f0f116d63ce3 100644 (file)
@@ -1,3 +1,10 @@
+Mon Jun 19 18:05:42 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * casefile.c (casefile_get_random_reader): Nasty hack to get around 
+       the mode assertion.
+
+       * format.c: Removed tortological assertion.
+
 Fri Jun  9 12:20:09 2006  Ben Pfaff  <blp@gnu.org>
 
        Reform string library.
index 453fbf09da4a5af8f6a9effe85aeb3fe9d4fbad2..7681a65f9d4e3e33b1c272760ed33ea0bc78e621 100644 (file)
@@ -545,8 +545,14 @@ casefile_get_reader (const struct casefile *cf_)
 struct casereader *
 casefile_get_random_reader (const struct casefile *cf) 
 {
-  struct casereader *reader = casefile_get_reader (cf);
+  struct casefile  *mutable_casefile = (struct casefile*) cf;
+  struct casereader *reader;
+
+  enum { WRITE, READ } mode = cf->mode ;
+  reader = casefile_get_reader (cf);
   reader->random = true;
+  mutable_casefile->mode = mode;
+  
   return reader;
 }
 
index 88b613748c42e871733751a81b2ced6223e75d95..a552f867cf338ce941a3759d5610be685c2ae676 100644 (file)
@@ -385,7 +385,6 @@ measure_is_valid(enum measure m)
 bool 
 alignment_is_valid(enum alignment a)
 {
-  if ( a < 0 ) return false;
   if ( a >= n_ALIGN) return false;
   return true;
 }
index 9cf8b0ed7d67df9c119f1ca4f38ff4b2136d4ff5..3b32eda1dd468711037fff29be1c50c19b58acb6 100644 (file)
@@ -1,3 +1,14 @@
+Mon Jun 19 18:10:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * psppire-case-file.c psppire-case-file.h (new files)
+   
+   * automake.mk data-sheet.c data-sheet.h menu-actions.c
+   psppire-data-store.c psppire-data-store.h psppire-dict.c
+   psppire-dict.h psppire-var-store.c psppire.c
+   
+     Replaced psppire-case-array.c  with psppire-case-file.c, so as to
+     allow an arbitrary number of cases to be represented.
+   
 Sun Jun  4 15:50:28 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
    * psppire-var-store.c, psppire.c, var-sheet.c :  Unlimited the number of 
diff --git a/src/ui/gui/TODO b/src/ui/gui/TODO
new file mode 100644 (file)
index 0000000..bced1fb
--- /dev/null
@@ -0,0 +1,23 @@
+* Crashes when resizing rows/columns when no cell is selected.
+
+* Blank cell reference when deselecting cells. (Eg New command).
+
+* Strip leading/trailing whitespace on data in cells.
+
+* Cell Ref Entry populate/depopulate.
+
+* Case weights.
+
+* Resizing of string variables.
+
+* Goto Variable / Goto Case.
+
+* Widen columns in var sheet as necessary to accomodate non-english translations.
+
+Wishlist
+========
+
+* Cut/Paste Buffer.  Cut and paste: a) Between psppire instances. b) From other applications.
+
+* In datasheet, add tooltips to column buttons, so that hovering over a column button displays 
+  the label for that variable.
index 6eba71890368ef2838d4b05990968bcd9965c8ac..247548153cbe4dbccb3197387e717673997615d7 100644 (file)
@@ -38,8 +38,8 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/helper.h \
        src/ui/gui/missing-val-dialog.c \
        src/ui/gui/missing-val-dialog.h \
-       src/ui/gui/psppire-case-array.c \
-       src/ui/gui/psppire-case-array.h \
+       src/ui/gui/psppire-case-file.c \
+       src/ui/gui/psppire-case-file.h \
        src/ui/gui/psppire-data-store.c \
        src/ui/gui/psppire-data-store.h \
        src/ui/gui/psppire-dict.c \
index a2a420dc62e91f3fb3064e8e830ca631fbfe60b5..87dcc5006531b6cddfbad2ee6f0046eab35ea01e 100644 (file)
@@ -128,11 +128,7 @@ psppire_data_sheet_create (gchar *widget_name, gchar *string1, gchar *string2,
 {
   GtkWidget *sheet;
 
-  const gint rows = 10046;
-
-  GObject *row_geometry = g_sheet_uniform_row_new(25, rows); 
-
-  sheet = gtk_sheet_new(G_SHEET_ROW(row_geometry), 
+  sheet = gtk_sheet_new(G_SHEET_ROW(data_store), 
                        G_SHEET_COLUMN(data_store), "data sheet", 0); 
 
 
index 9189edddda78aec229603c6d42e4a97a086c7600..1fa579ffe31301aa1587710460eda0bebb2f8083 100644 (file)
@@ -23,7 +23,6 @@
 #define DATA_SHEET_H
 
 #include <gtksheet/gtksheet.h>
-#include "psppire-case-array.h"
 #include "psppire-dict.h"
 
 void psppire_data_sheet_clear(GtkSheet *sheet);
index c23beb49a872c5d02c55ec007384a4fd038045ed..0dc03658c0c93f6222100d13c5be3c1066658a31 100644 (file)
@@ -25,6 +25,7 @@
 #define N_(msgid) msgid
 
 
+#include <data/casefile.h>
 #include <data/file-handle-def.h>
 #include <data/sys-file-reader.h>
 #include <data/case.h>
@@ -50,8 +51,6 @@ extern GladeXML *xml;
 
 
 extern PsppireDict *the_dictionary ;
-extern PsppireCaseArray *the_cases ;
-
 
 static struct file_handle *psppire_handle = 0;
 
@@ -75,20 +74,32 @@ psppire_set_window_title(const gchar *text)
   g_free(title);
 }
 
-
+/* Clear the active file and set the data and var sheets to 
+   reflect this.
+ */
 gboolean
 clear_file(void)
 {
-  GtkWidget *data_sheet = get_widget_assert(xml, "data_sheet");
-  GtkWidget *var_sheet = get_widget_assert(xml, "variable_sheet");
-  gtk_sheet_set_active_cell(GTK_SHEET(data_sheet), -1, -1);
+  PsppireDataStore *data_store ;
+  GtkSheet *data_sheet = GTK_SHEET(get_widget_assert(xml, "data_sheet"));
+  GtkSheet *var_sheet = GTK_SHEET(get_widget_assert(xml, "variable_sheet"));
 
-  gtk_sheet_set_active_cell(GTK_SHEET(var_sheet), 0, 0);
+  gtk_sheet_set_active_cell(data_sheet, -1, -1);
+  gtk_sheet_set_active_cell(var_sheet, 0, 0);
+
+  if ( GTK_WIDGET_REALIZED(GTK_WIDGET(data_sheet)))
+    gtk_sheet_unselect_range(data_sheet);
+
+  if ( GTK_WIDGET_REALIZED(GTK_WIDGET(var_sheet)))
+    gtk_sheet_unselect_range(var_sheet);
+
+  gtk_sheet_moveto(data_sheet, 0, 0, 0.0, 0.0);
+  gtk_sheet_moveto(var_sheet,  0, 0, 0.0, 0.0);
+
+  data_store = PSPPIRE_DATA_STORE(gtk_sheet_get_model(data_sheet));
+
+  psppire_data_store_clear(data_store);
 
-  psppire_dict_clear(the_dictionary);
-  psppire_case_array_clear(the_cases);
-  
   psppire_set_window_title(gettext(untitled));
 
   if (psppire_handle)
@@ -107,23 +118,13 @@ on_new1_activate                       (GtkMenuItem     *menuitem,
 
 
 
-static gboolean
-populate_case_from_reader(struct ccase *c, gpointer aux)
-{
-  struct sfm_reader *reader = aux;
-
-  return sfm_read_case(reader, c);
-}
-
-
 /* Load a system file.
    Return TRUE if successfull
 */
 gboolean
 load_system_file(const gchar *file_name)
 {
-  int ni ;
-  gint case_num;
+  int var_cnt ;
 
   PsppireVarStore *var_store ;
   PsppireDataStore *data_store ;
@@ -134,12 +135,10 @@ load_system_file(const gchar *file_name)
   GtkWidget *data_sheet = get_widget_assert(xml, "data_sheet");
   GtkWidget *var_sheet = get_widget_assert(xml, "variable_sheet");
 
-
   g_assert(data_sheet);
   g_assert(var_sheet);
 
-  if ( psppire_handle ) 
-    fh_free(psppire_handle);
+  clear_file();
 
   psppire_handle = 
     fh_create_file (handle_name, file_name, fh_default_properties());
@@ -151,7 +150,6 @@ load_system_file(const gchar *file_name)
       return FALSE;
     }
 
-
   reader = sfm_open_reader (psppire_handle, &new_dict, &ri);
       
   if ( ! reader ) 
@@ -172,25 +170,36 @@ load_system_file(const gchar *file_name)
   psppire_data_store_set_dictionary(data_store,
                                    the_dictionary);
 
-  psppire_case_array_clear(data_store->cases);
-
-
   psppire_set_window_title(basename(file_name));
 
-  ni = dict_get_next_value_idx(the_dictionary->dict);
-  if ( ni == 0 ) 
+  var_cnt = dict_get_next_value_idx(the_dictionary->dict);
+  if ( var_cnt == 0 ) 
     return FALSE;
 
-  for(case_num=0;;case_num++)
+
+  for(;;)
     {
-      if (!psppire_case_array_append_case(the_cases, 
-                                         populate_case_from_reader, 
-                                         reader))
-       break;
-    }
+      struct ccase c;
+      case_create(&c, var_cnt);
+      if ( 0 == sfm_read_case (reader, &c) )
+       {
+         case_destroy(&c);
+         break;
+       }
+
+      if ( !psppire_case_file_append_case(data_store->case_file, &c) ) 
+       {
+         g_warning("Cannot write case to casefile\n");
+         break;
+       }
+
+      case_destroy(&c);
 
+    }
+  
+  sfm_close_reader(reader);      
 
-  sfm_close_reader(reader);
+  psppire_case_file_get_case_count(data_store->case_file);
 
   return TRUE;
 }
@@ -396,6 +405,7 @@ on_insert1_activate                    (GtkMenuItem     *menuitem,
   switch (page) 
     {
     case PAGE_DATA_SHEET:
+#if 0
       {
        GtkSheet *data_sheet = GTK_SHEET(get_widget_assert(xml, "data_sheet"));
        PsppireDataStore *data_store = 
@@ -406,6 +416,7 @@ on_insert1_activate                    (GtkMenuItem     *menuitem,
                                       blank_case, the_dictionary);
       }
       break;
+#endif
     case PAGE_VAR_SHEET:
       {
        GtkSheet *var_sheet = 
@@ -430,6 +441,7 @@ on_delete1_activate                    (GtkMenuItem     *menuitem,
   page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
   switch ( page) 
     {
+#if 0
     case PAGE_DATA_SHEET:
       {
        GtkSheet *data_sheet = GTK_SHEET(get_widget_assert(xml, "data_sheet"));
@@ -442,6 +454,7 @@ on_delete1_activate                    (GtkMenuItem     *menuitem,
                                    - data_sheet->range.row0  );
       }
       break;
+#endif
     case PAGE_VAR_SHEET:
       {
        GtkSheet *var_sheet = 
diff --git a/src/ui/gui/psppire-case-file.c b/src/ui/gui/psppire-case-file.c
new file mode 100644 (file)
index 0000000..374105b
--- /dev/null
@@ -0,0 +1,248 @@
+/* 
+    PSPPIRE --- A Graphical User Interface for PSPP
+    Copyright (C) 2006  Free Software Foundation
+    Written by John Darrington
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA. */
+
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "psppire-object.h"
+#include "psppire-case-file.h"
+
+#include <gtksheet/gtkextra-marshal.h>
+
+#include <data/case.h>
+#include <data/casefile.h>
+#include <data/data-in.h>
+
+/* --- prototypes --- */
+static void psppire_case_file_class_init       (PsppireCaseFileClass   *class);
+static void psppire_case_file_init     (PsppireCaseFile        *case_file);
+static void psppire_case_file_finalize (GObject                *object);
+
+
+/* --- variables --- */
+static GObjectClass     *parent_class = NULL;
+
+enum  {CASE_CHANGED, 
+       CASE_INSERTED,
+       CASES_DELETED,
+       n_SIGNALS};
+
+static guint signal[n_SIGNALS];
+
+
+/* --- functions --- */
+/**
+ * psppire_case_file_get_type:
+ * @returns: the type ID for accelerator groups.
+ */
+GType
+psppire_case_file_get_type (void)
+{
+  static GType object_type = 0;
+
+  if (!object_type)
+    {
+      static const GTypeInfo object_info = {
+       sizeof (PsppireCaseFileClass),
+       (GBaseInitFunc) NULL,
+       (GBaseFinalizeFunc) NULL,
+       (GClassInitFunc) psppire_case_file_class_init,
+       NULL,   /* class_finalize */
+       NULL,   /* class_data */
+       sizeof (PsppireCaseFile),
+       0,      /* n_preallocs */
+       (GInstanceInitFunc) psppire_case_file_init,
+      };
+
+      object_type = g_type_register_static (G_TYPE_PSPPIRE_OBJECT, "PsppireCaseFile",
+                                           &object_info, 0);
+    }
+
+  return object_type;
+}
+
+
+static void
+psppire_case_file_class_init (PsppireCaseFileClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  parent_class = g_type_class_peek_parent (class);
+
+  object_class->finalize = psppire_case_file_finalize;
+
+  signal[CASE_CHANGED] =
+    g_signal_new ("case_changed",
+                 G_TYPE_FROM_CLASS(class),
+                 G_SIGNAL_RUN_FIRST,
+                 0,
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__INT,
+                 G_TYPE_NONE, 
+                 1,
+                 G_TYPE_INT);
+
+
+  signal[CASE_INSERTED] =
+    g_signal_new ("case_inserted",
+                 G_TYPE_FROM_CLASS(class),
+                 G_SIGNAL_RUN_FIRST,
+                 0,
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__INT,
+                 G_TYPE_NONE, 
+                 1,
+                 G_TYPE_INT);
+
+
+  signal[CASES_DELETED] =
+    g_signal_new ("cases_deleted",
+                 G_TYPE_FROM_CLASS(class),
+                 G_SIGNAL_RUN_FIRST,
+                 0,
+                 NULL, NULL,
+                 gtkextra_VOID__INT_INT,
+                 G_TYPE_NONE, 
+                 2,
+                 G_TYPE_INT, G_TYPE_INT);
+}
+
+static void
+psppire_case_file_finalize (GObject *object)
+{
+  PsppireCaseFile *cf = PSPPIRE_CASE_FILE (object);
+  
+  if ( cf->casefile) 
+    casefile_destroy(cf->casefile);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+psppire_case_file_init (PsppireCaseFile *cf)
+{
+  cf->casefile = 0;
+}
+
+/**
+ * psppire_case_file_new:
+ * @returns: a new #PsppireCaseFile object
+ * 
+ * Creates a new #PsppireCaseFile. 
+ */
+PsppireCaseFile*
+psppire_case_file_new (gint var_cnt)
+{
+  PsppireCaseFile *cf = g_object_new (G_TYPE_PSPPIRE_CASE_FILE, NULL);
+
+  cf->casefile = casefile_create(var_cnt);
+
+  return cf;
+}
+
+
+
+/* Append a case to the case file */
+gboolean
+psppire_case_file_append_case(PsppireCaseFile *cf, 
+                             struct ccase *c)
+{
+  bool result ;
+  gint posn ;
+
+  g_return_val_if_fail(cf, FALSE);
+  g_return_val_if_fail(cf->casefile, FALSE);
+
+  posn = casefile_get_case_cnt(cf->casefile);
+
+  result = casefile_append(cf->casefile, c);
+  
+  g_signal_emit(cf, signal[CASE_INSERTED], 0, posn);
+               
+  return result;
+}
+
+
+inline gint
+psppire_case_file_get_case_count(const PsppireCaseFile *cf)
+{
+  g_return_val_if_fail(cf, FALSE);
+  
+  if ( ! cf->casefile) 
+    return 0;
+
+  return casefile_get_case_cnt(cf->casefile);
+}
+
+/* Return the IDXth value from case CASENUM.
+   The return value must not be freed or written to
+ */
+const union value *
+psppire_case_file_get_value(const PsppireCaseFile *cf, gint casenum, gint idx)
+{
+  const union value *v; 
+  struct ccase c;
+  struct casereader *reader =  casefile_get_random_reader (cf->casefile);
+
+  casereader_seek(reader, casenum);
+
+  casereader_read(reader, &c);
+
+  v = case_data(&c, idx);
+  casereader_destroy(reader);
+  case_destroy(&c);
+
+  return v;
+}
+
+void
+psppire_case_file_clear(PsppireCaseFile *cf)
+{
+  casefile_destroy(cf->casefile);
+  cf->casefile = 0;
+  g_signal_emit(cf, signal[CASES_DELETED], 0, 0, -1);
+}
+
+/* Set the IDXth value of case C using FF and DATA */
+gboolean
+psppire_case_file_set_value(PsppireCaseFile *cf, gint casenum, gint idx,
+                           struct data_in *d_in)
+{
+  struct ccase cc ;
+
+  struct casereader *reader =  casefile_get_random_reader (cf->casefile);
+
+  casereader_seek(reader, casenum);
+  casereader_read(reader, &cc);
+
+  /* Cast away const in flagrant abuse of the casefile */
+  d_in->v = (union value *) case_data(&cc, idx);
+
+  if ( ! data_in(d_in) ) 
+    g_warning("Cant set value\n");
+
+  case_destroy(&cc);
+  casereader_destroy(reader);
+
+  g_signal_emit(cf, signal[CASE_CHANGED], 0, casenum);
+
+  return TRUE;
+}
diff --git a/src/ui/gui/psppire-case-file.h b/src/ui/gui/psppire-case-file.h
new file mode 100644 (file)
index 0000000..0aa44aa
--- /dev/null
@@ -0,0 +1,90 @@
+/* 
+    PSPPIRE --- A Graphical User Interface for PSPP
+    Copyright (C) 2006  Free Software Foundation
+    Written by John Darrington
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA. */
+
+
+#ifndef __CASE_FILE_H__
+#define __CASE_FILE_H__
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+
+
+G_BEGIN_DECLS
+
+
+/* --- type macros --- */
+#define G_TYPE_PSPPIRE_CASE_FILE              (psppire_case_file_get_type ())
+#define PSPPIRE_CASE_FILE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_CASE_FILE, PsppireCaseFile))
+#define PSPPIRE_CASE_FILE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_CASE_FILE, PsppireCaseFileClass))
+#define G_IS_PSPPIRE_CASE_FILE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_CASE_FILE))
+#define G_IS_PSPPIRE_CASE_FILE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_CASE_FILE))
+#define PSPPIRE_CASE_FILE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_CASE_FILE, PsppireCaseFileClass))
+
+
+
+
+/* --- typedefs & structures --- */
+typedef struct _PsppireCaseFile           PsppireCaseFile;
+typedef struct _PsppireCaseFileClass PsppireCaseFileClass;
+
+struct ccase;
+struct casefile;
+
+struct _PsppireCaseFile
+{
+  GObject             parent;
+
+  struct casefile *casefile;
+};
+
+
+struct _PsppireCaseFileClass
+{
+  GObjectClass parent_class;
+};
+
+
+/* -- PsppireCaseFile --- */
+GType          psppire_case_file_get_type (void);
+
+PsppireCaseFile *psppire_case_file_new (gint var_cnt);
+
+gboolean psppire_case_file_append_case(PsppireCaseFile *cf, 
+                                            struct ccase *c);
+
+gint psppire_case_file_get_case_count(const PsppireCaseFile *cf);
+
+
+const union value * psppire_case_file_get_value(const PsppireCaseFile *cf, 
+                                             gint c, gint idx);
+
+struct data_in;
+
+gboolean psppire_case_file_set_value(PsppireCaseFile *cf, gint c, gint idx,
+                                struct data_in *d_in);
+
+void psppire_case_file_clear(PsppireCaseFile *cf);
+
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_CASE_FILE_H__ */
index df36d0832e41ff600b966ae76186d86b192fdf4e..4471a866ca0374d5f4491a1d73e520a5a087b21c 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <gettext.h>
-#define _(msgid) gettext (msgid)
+#define _(msgid) gettext(msgid)
 #define N_(msgid) msgid
 
-
+#include <data/casefile.h>
+#include <data/case.h>
 
 #include <gtksheet/gtksheet.h>
 #include <gtksheet/gsheetmodel.h>
@@ -50,9 +51,11 @@ static void psppire_data_store_init            (PsppireDataStore      *data_stor
 static void psppire_data_store_class_init      (PsppireDataStoreClass *class);
 static void psppire_data_store_sheet_model_init (GSheetModelIface *iface);
 static void psppire_data_store_sheet_column_init (GSheetColumnIface *iface);
+static void psppire_data_store_sheet_row_init (GSheetRowIface *iface);
+
 static void psppire_data_store_finalize        (GObject           *object);
 
-static const gchar *psppire_data_store_get_string(GSheetModel *sheet_model, gint row, gint column);
+static gchar *psppire_data_store_get_string(const GSheetModel *sheet_model, gint row, gint column);
 
 static gboolean psppire_data_store_set_string(GSheetModel *model, 
                                          const gchar *text, gint row, gint column);
@@ -63,6 +66,7 @@ static gboolean psppire_data_store_clear_datum(GSheetModel *model,
 
 #define MIN_COLUMNS 10
 
+#define TRAILING_ROWS 10
 
 static GObjectClass *parent_class = NULL;
 
@@ -100,6 +104,12 @@ psppire_data_store_get_type (void)
        NULL
       };
 
+      static const GInterfaceInfo sheet_row_info =
+      {
+       (GInterfaceInitFunc) psppire_data_store_sheet_row_init,
+       NULL,
+       NULL
+      };
 
 
       data_store_type = g_type_register_static (G_TYPE_OBJECT, "PsppireDataStore",
@@ -113,6 +123,9 @@ psppire_data_store_get_type (void)
                                   G_TYPE_SHEET_COLUMN,
                                   &sheet_column_info);
 
+      g_type_add_interface_static (data_store_type,
+                                  G_TYPE_SHEET_ROW,
+                                  &sheet_row_info);
     }
 
   return data_store_type;
@@ -144,7 +157,7 @@ psppire_data_store_get_case_count (const GSheetModel *model)
 {
   const PsppireDataStore *store = PSPPIRE_DATA_STORE(model);
 
-  return psppire_case_array_get_n_cases(store->cases);
+  return psppire_case_file_get_case_count(store->case_file);
 }
 
 
@@ -152,11 +165,11 @@ static void
 psppire_data_store_init (PsppireDataStore *data_store)
 {
   data_store->dict = 0;
-  data_store->cases = 0;
+  data_store->case_file = 0;
 }
 
 const PangoFontDescription *
-psppire_data_store_get_font_desc(GSheetModel *model,
+psppire_data_store_get_font_desc(const GSheetModel *model,
                              gint row, gint column)
 {
   PsppireDataStore *store = PSPPIRE_DATA_STORE(model);
@@ -215,8 +228,10 @@ insert_case_callback(GtkWidget *w, gint casenum, gpointer data)
   
   g_sheet_model_range_changed (G_SHEET_MODEL(store),
                               casenum, -1,
-                              psppire_case_array_get_n_cases(store->cases),
+                              psppire_case_file_get_case_count(store->case_file),
                               -1);
+
+  g_sheet_model_rows_inserted (G_SHEET_MODEL(store), casenum, 1);
 }
 
 
@@ -231,7 +246,6 @@ changed_case_callback(GtkWidget *w, gint casenum, gpointer data)
   g_sheet_model_range_changed (G_SHEET_MODEL(store),
                                 casenum, -1,
                                 casenum, -1);
-
 }
 
 
@@ -244,12 +258,11 @@ delete_variables_callback(GObject *obj, gint var_num, gint n_vars, gpointer data
 
   store  = PSPPIRE_DATA_STORE(data);
 
-  g_sheet_column_columns_deleted(G_SHEET_COLUMN(store),
-                                  var_num, n_vars);
-
   g_sheet_model_columns_deleted (G_SHEET_MODEL(store), var_num, n_vars);
-}
 
+  g_sheet_column_columns_changed(G_SHEET_COLUMN(store),
+                                  var_num, -1);
+}
 
 static void
 insert_variable_callback(GObject *obj, gint var_num, gpointer data)
@@ -267,8 +280,14 @@ insert_variable_callback(GObject *obj, gint var_num, gpointer data)
                                 -1);
   */
 
+#if 0
   psppire_case_array_resize(store->cases, 
                         dict_get_next_value_idx (store->dict->dict));
+#endif
+
+  g_sheet_column_columns_changed(G_SHEET_COLUMN(store),
+                                 var_num, 1);
+
 
   g_sheet_model_columns_inserted (G_SHEET_MODEL(store), var_num, 1);
 }
@@ -284,23 +303,12 @@ insert_variable_callback(GObject *obj, gint var_num, gpointer data)
  * Return value: a new #PsppireDataStore
  **/
 PsppireDataStore *
-psppire_data_store_new (PsppireDict *dict, PsppireCaseArray *cases)
+psppire_data_store_new (PsppireDict *dict)
 {
   PsppireDataStore *retval;
 
   retval = g_object_new (GTK_TYPE_DATA_STORE, NULL);
 
-  retval->cases = cases;
-  g_signal_connect(cases, "cases-deleted", G_CALLBACK(delete_cases_callback), 
-                  retval);
-
-  g_signal_connect(cases, "case-inserted", G_CALLBACK(insert_case_callback), 
-                  retval);
-
-
-  g_signal_connect(cases, "case-changed", G_CALLBACK(changed_case_callback), 
-                  retval);
-
   psppire_data_store_set_dictionary(retval, dict);
 
 
@@ -320,14 +328,33 @@ psppire_data_store_new (PsppireDict *dict, PsppireCaseArray *cases)
 void
 psppire_data_store_set_dictionary(PsppireDataStore *data_store, PsppireDict *dict)
 {
+  gint var_cnt = psppire_dict_get_next_value_idx(dict);
 #if 0
   if ( data_store->dict ) g_object_unref(data_store->dict);
 #endif
 
   data_store->dict = dict;
 
-  psppire_case_array_resize(data_store->cases, 
-                        dict_get_next_value_idx (data_store->dict->dict));
+  if ( data_store->case_file)
+    {
+      g_object_unref(data_store->case_file);
+      data_store->case_file = 0;
+    }
+
+  data_store->case_file = psppire_case_file_new(var_cnt);
+
+  g_signal_connect(data_store->case_file, "cases-deleted", 
+                  G_CALLBACK(delete_cases_callback), 
+                  data_store);
+
+  g_signal_connect(data_store->case_file, "case-inserted", 
+                  G_CALLBACK(insert_case_callback), 
+                  data_store);
+
+
+  g_signal_connect(data_store->case_file, "case-changed", 
+                  G_CALLBACK(changed_case_callback), 
+                  data_store);
 
 
   g_signal_connect(dict, "variable-inserted", 
@@ -340,6 +367,8 @@ psppire_data_store_set_dictionary(PsppireDataStore *data_store, PsppireDict *dic
 
   /* The entire model has changed */
   g_sheet_model_range_changed (G_SHEET_MODEL(data_store), -1, -1, -1, -1);
+  
+  g_sheet_column_columns_changed(G_SHEET_COLUMN(data_store), 0, -1);
 }
 
 static void
@@ -351,10 +380,11 @@ psppire_data_store_finalize (GObject *object)
 }
 
 
-static const gchar *
-psppire_data_store_get_string(GSheetModel *model, gint row, gint column)
+static gchar *
+psppire_data_store_get_string(const GSheetModel *model, gint row, gint column)
 {
-  const char *text;
+  gint idx;
+  char *text;
   const struct fmt_spec *fp ;
   const struct PsppireVariable *pv ;
   const union value *v ;
@@ -362,19 +392,19 @@ psppire_data_store_get_string(GSheetModel *model, gint row, gint column)
   PsppireDataStore *store = PSPPIRE_DATA_STORE(model);
 
   g_return_val_if_fail(store->dict, NULL);
-  g_return_val_if_fail(store->cases, NULL);
+  g_return_val_if_fail(store->case_file, NULL);
 
   if (column >= psppire_dict_get_var_cnt(store->dict))
     return NULL;
 
-  if ( row >= psppire_case_array_get_n_cases(store->cases))
+  if ( row >= psppire_case_file_get_case_count(store->case_file))
     return NULL;
 
-
   pv = psppire_dict_get_variable(store->dict, column);
 
-  v =  psppire_case_array_get_value(store->cases, row, 
-                             psppire_variable_get_index(pv));
+  idx = psppire_variable_get_index(pv);
+
+  v = psppire_case_file_get_value(store->case_file, row, idx);
 
   if ( store->show_labels) 
     {
@@ -408,21 +438,6 @@ psppire_data_store_get_string(GSheetModel *model, gint row, gint column)
 }
 
 
-static gboolean
-set_null_string_value(union value *val, gpointer data)
-{
-  strcpy(val->s, "");
-  return TRUE;
-}
-
-static gboolean
-set_sysmis_value(union value *val, gpointer data)
-{
-  val->f = SYSMIS;
-  return TRUE;
-}
-
-
 static gboolean 
 psppire_data_store_clear_datum(GSheetModel *model, 
                                          gint row, gint col)
@@ -430,30 +445,17 @@ psppire_data_store_clear_datum(GSheetModel *model,
 {
   PsppireDataStore *store = PSPPIRE_DATA_STORE(model);
 
+  union value v;
   const struct PsppireVariable *pv = psppire_dict_get_variable(store->dict, col);
 
   const gint index = psppire_variable_get_index(pv) ;
 
   if ( psppire_variable_get_type(pv) == NUMERIC) 
-    psppire_case_array_set_value(store->cases, row, index, set_sysmis_value,0);
+    v.f = SYSMIS;
   else
-    psppire_case_array_set_value(store->cases, row, index, set_null_string_value,0);
-  return TRUE;
-}
-
-
-static gboolean
-fillit(union value *val, gpointer data)
-{
-  struct data_in *d_in = data;
+    memcpy(v.s, "", MAX_SHORT_STRING);
 
-  d_in->v = val;
-
-  if ( ! data_in(d_in) ) 
-    {
-      g_warning("Cant encode string\n");
-      return FALSE;
-    }
+  psppire_case_file_set_value(store->case_file, row, index, &v);
 
   return TRUE;
 }
@@ -467,20 +469,25 @@ static gboolean
 psppire_data_store_set_string(GSheetModel *model, 
                          const gchar *text, gint row, gint col)
 {
-  gint r;
   PsppireDataStore *store = PSPPIRE_DATA_STORE(model);
 
   const struct PsppireVariable *pv = psppire_dict_get_variable(store->dict, col);
   g_return_val_if_fail(pv, FALSE);
 
-  for(r = psppire_case_array_get_n_cases(store->cases) ; r <= row ; ++r ) 
+#if 0
+  /* Allow the user to insert a lot of blank cases, simply by skipping rows */
+  for(r = psppire_case_file_get_case_count(store->case_file); r <= row ; ++r) 
     {
+
       gint c;
+
       psppire_case_array_insert_case(store->cases, r, 0, 0);
 
+
       for (c = 0 ; c < psppire_dict_get_var_cnt(store->dict); ++c ) 
        psppire_data_store_clear_datum(model, r, c);
     }
+#endif
 
   {
     const gint index = psppire_variable_get_index(pv);
@@ -493,7 +500,15 @@ psppire_data_store_set_string(GSheetModel *model,
     d_in.format = * psppire_variable_get_write_spec(pv);
     d_in.flags = 0;
 
-    psppire_case_array_set_value(store->cases, row, index, fillit, &d_in);
+    /* 
+    if ( ! data_in(&d_in) ) 
+      {
+       g_warning("Cannot encode string");
+       return FALSE;
+      }
+    */
+
+    psppire_case_file_set_value(store->case_file, row, index, &d_in) ;
   }
 
   return TRUE;
@@ -558,17 +573,30 @@ psppire_data_store_create_system_file(PsppireDataStore *store,
   if ( ! writer) 
     return;
 
+#if 0
   psppire_case_array_iterate_case(store->cases, write_case, writer);
+#endif
 
   sfm_close_writer(writer);
 }
 
 
 
+void 
+psppire_data_store_clear(PsppireDataStore *data_store)
+{
+  psppire_case_file_clear(data_store->case_file);
+
+  psppire_dict_clear(data_store->dict);
+}
+
+
+
+
 /* Column related funcs */
 
 static gint
-geometry_get_column_count(const GSheetColumn *geom)
+geometry_get_column_count(const GSheetColumn *geom, gpointer data)
 {
   PsppireDataStore *ds = PSPPIRE_DATA_STORE(geom);
 
@@ -645,7 +673,7 @@ geometry_set_width(GSheetColumn *geom, gint unit, gint width, GtkSheet *sheet)
 
 
 static GtkJustification
-geometry_get_justification(const GSheetColumn *geom, gint unit)
+geometry_get_justification(const GSheetColumn *geom, gint unit, gpointer data)
 {
   PsppireDataStore *ds = PSPPIRE_DATA_STORE(geom);
   const struct PsppireVariable *pv ;
@@ -664,10 +692,11 @@ geometry_get_justification(const GSheetColumn *geom, gint unit)
 
 static const gchar null_var_name[]=N_("var");
  
-static const gchar *
-geometry_get_button_label(const GSheetColumn *geom, gint unit)
+static gchar *
+geometry_get_column_button_label(const GSheetColumn *geom, gint unit, 
+                                gpointer data)
 {
-  const gchar *text;
+  gchar *text;
   struct PsppireVariable *pv ;
   PsppireDataStore *ds = PSPPIRE_DATA_STORE(geom);
 
@@ -683,7 +712,7 @@ geometry_get_button_label(const GSheetColumn *geom, gint unit)
 
 
 static gboolean
-geometry_get_sensitivity(const GSheetColumn *geom, gint unit)
+geometry_get_sensitivity(const GSheetColumn *geom, gint unit, gpointer data)
 {
   PsppireDataStore *ds = PSPPIRE_DATA_STORE(geom);
 
@@ -702,5 +731,72 @@ psppire_data_store_sheet_column_init (GSheetColumnIface *iface)
   iface->get_sensitivity = geometry_get_sensitivity;
   iface->get_justification = geometry_get_justification;
 
-  iface->get_button_label = geometry_get_button_label;
+  iface->get_button_label = geometry_get_column_button_label;
+}
+
+
+/* Row related funcs */
+
+static gint
+geometry_get_row_count(const GSheetRow *geom, gpointer data)
+{
+  PsppireDataStore *ds = PSPPIRE_DATA_STORE(geom);
+
+  return TRAILING_ROWS + psppire_case_file_get_case_count(ds->case_file);
+}
+
+
+static gint
+geometry_get_height(const GSheetRow *geom, gint unit, gpointer data)
+{
+  return 25;
+}
+
+
+static gboolean
+geometry_get_row_sensitivity(const GSheetRow *geom, gint unit, gpointer data)
+{
+  PsppireDataStore *ds = PSPPIRE_DATA_STORE(geom);
+
+  
+  return (unit < psppire_case_file_get_case_count(ds->case_file));
+}
+
+
+static gchar *
+geometry_get_row_button_label(const GSheetRow *geom, gint unit, gpointer data)
+{
+  gchar *text;
+  gchar *s;
+  PsppireDataStore *ds = PSPPIRE_DATA_STORE(geom);
+
+  if ( unit > 
+       TRAILING_ROWS + psppire_case_file_get_case_count(ds->case_file))
+    return 0;
+
+  s = g_strdup_printf(_("%d"), unit);
+
+  text =  pspp_locale_to_utf8(s, -1, 0);
+  
+  g_free(s);
+  
+  return text;
+}
+
+
+static void
+psppire_data_store_sheet_row_init (GSheetRowIface *iface)
+{
+  iface->get_row_count = geometry_get_row_count;
+
+  iface->get_height = geometry_get_height;
+  iface->set_height = 0;
+  iface->get_visibility = always_true;
+  iface->get_sensitivity = geometry_get_row_sensitivity;
+
+  iface->get_button_label = geometry_get_row_button_label;
 }
+
+
+
+
index 2f0d42ca102c8f93b17922d385c562451bbbb6ac..d9b058432bdcc9f4f4f284b28278401b2b761985 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <gtksheet/gsheetmodel.h>
 #include "psppire-dict.h"
-#include "psppire-case-array.h"
+#include "psppire-case-file.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -58,7 +58,7 @@ struct _PsppireDataStore
 
   /*< private >*/
   PsppireDict *dict;
-  PsppireCaseArray *cases;
+  PsppireCaseFile *case_file;
   PangoFontDescription *font_desc;
   gboolean show_labels;
 
@@ -79,13 +79,18 @@ struct _PsppireDataStoreClass
 
 
 inline GType psppire_data_store_get_type (void) G_GNUC_CONST;
-PsppireDataStore *psppire_data_store_new     (PsppireDict *dict, PsppireCaseArray *cases);
+PsppireDataStore *psppire_data_store_new     (PsppireDict *dict);
 
 void psppire_data_store_set_dictionary(PsppireDataStore *data_store, PsppireDict *dict);
 void psppire_data_store_set_font(PsppireDataStore *store, PangoFontDescription *fd);
 
 void psppire_data_store_show_labels(PsppireDataStore *store, gboolean show_labels);
 
+  
+void psppire_data_store_clear(PsppireDataStore *data_store);
+
+
+
 
 struct file_handle;
 
index 0927f9c99e7e58b53b1370673e62acea5a285c01..2cb6894ce957d508a739ca86070c35704689f092 100644 (file)
@@ -306,7 +306,6 @@ psppire_dict_set_name(PsppireDict* d, gint idx, const gchar *name)
     {
       /* new variable */
       dict_create_var(d->dict, name, 0);
-      g_print("Emitting variable-inserted signal\n");
       g_signal_emit(d, signal[VARIABLE_INSERTED], 0, idx);
     }
 }
@@ -421,3 +420,10 @@ psppire_dict_check_name(const PsppireDict *dict,
 
   return TRUE;
 }
+
+
+inline gint 
+psppire_dict_get_next_value_idx (const PsppireDict *dict)
+{
+  return dict_get_next_value_idx(dict->dict);
+}
index 96753ab5dcd7bc0d6a91237bcfb84e1751066471..385d0671b42239c85a94244400c68fabfad2f201 100644 (file)
@@ -100,6 +100,8 @@ void psppire_dict_insert_variable(PsppireDict *d, gint idx, const gchar *name);
 gboolean psppire_dict_check_name(const PsppireDict *dict, 
                              const gchar *name, gboolean report);
 
+gint psppire_dict_get_next_value_idx (const PsppireDict *dict);
+
 
 G_END_DECLS
 
index 1435a4a24500e44c64dd6e3f7bf666896169a752..cf38b60dbdb7565b4b3baf58b9f5c30d9e4779ab 100644 (file)
 #include <data/value-labels.h>
 
 
+#define TRAILING_ROWS 40
 
 static void         psppire_var_store_init            (PsppireVarStore      *var_store);
 static void         psppire_var_store_class_init      (PsppireVarStoreClass *class);
 static void         psppire_var_store_sheet_model_init (GSheetModelIface *iface);
 static void         psppire_var_store_finalize        (GObject           *object);
 
-static gchar *psppire_var_store_get_string(GSheetModel *sheet_model, gint row, gint column);
+static gchar *psppire_var_store_get_string(const GSheetModel *sheet_model, gint row, gint column);
 
 static gboolean  psppire_var_store_clear(GSheetModel *model,  gint row, gint col);
 
@@ -60,6 +61,7 @@ static gboolean  psppire_var_store_clear(GSheetModel *model,  gint row, gint col
 static gboolean psppire_var_store_set_string(GSheetModel *model, 
                                          const gchar *text, gint row, gint column);
 
+static gint psppire_var_store_get_row_count(const GSheetModel * model);
 
 static gchar *text_for_column(const struct PsppireVariable *pv, gint c, GError **err);
 
@@ -185,7 +187,7 @@ psppire_var_store_item_editable(PsppireVarStore *var_store, gint row, gint colum
 }
 
 static gboolean
-psppire_var_store_is_editable(GSheetModel *model, gint row, gint column)
+psppire_var_store_is_editable(const GSheetModel *model, gint row, gint column)
 {
   PsppireVarStore *store = PSPPIRE_VAR_STORE(model);
   return psppire_var_store_item_editable(store, row, column);
@@ -193,7 +195,7 @@ psppire_var_store_is_editable(GSheetModel *model, gint row, gint column)
 
 
 static const GdkColor *
-psppire_var_store_get_foreground(GSheetModel *model, gint row, gint column)
+psppire_var_store_get_foreground(const GSheetModel *model, gint row, gint column)
 {
   PsppireVarStore *store = PSPPIRE_VAR_STORE(model);
 
@@ -205,7 +207,7 @@ psppire_var_store_get_foreground(GSheetModel *model, gint row, gint column)
 
 
 const PangoFontDescription *
-psppire_var_store_get_font_desc(GSheetModel *model,
+psppire_var_store_get_font_desc(const GSheetModel *model,
                              gint row, gint column)
 {
   PsppireVarStore *store = PSPPIRE_VAR_STORE(model);
@@ -218,6 +220,7 @@ psppire_var_store_get_font_desc(GSheetModel *model,
 static void
 psppire_var_store_sheet_model_init (GSheetModelIface *iface)
 {
+  iface->get_row_count = psppire_var_store_get_row_count;
   iface->free_strings = TRUE;
   iface->get_string = psppire_var_store_get_string;
   iface->set_string = psppire_var_store_set_string;
@@ -317,7 +320,7 @@ psppire_var_store_finalize (GObject *object)
 }
 
 static gchar *
-psppire_var_store_get_string(GSheetModel *model, gint row, gint column)
+psppire_var_store_get_string(const GSheetModel *model, gint row, gint column)
 {
   PsppireVarStore *store = PSPPIRE_VAR_STORE(model);
 
@@ -674,25 +677,51 @@ psppire_var_store_set_font(PsppireVarStore *store, const PangoFontDescription *f
 }
 
 
+static gint
+psppire_var_store_get_row_count(const GSheetModel * model)
+{
+  gint rows = 0;
+  PsppireVarStore *vs = PSPPIRE_VAR_STORE(model);
+
+  if (vs->dict) 
+    rows =  psppire_dict_get_var_cnt(vs->dict); 
+
+  return rows ;
+}
 
 /* Row related funcs */
 
 static gint
-geometry_get_row_count(const GSheetRow *geom)
+geometry_get_row_count(const GSheetRow *geom, gpointer data)
 {
+  gint rows = 0;
   PsppireVarStore *vs = PSPPIRE_VAR_STORE(geom);
 
-  return psppire_dict_get_var_cnt(vs->dict)+ 40;
+  if (vs->dict) 
+    rows =  psppire_dict_get_var_cnt(vs->dict); 
+
+  return rows + TRAILING_ROWS;
 }
 
 
 static gint
-geometry_get_height(const GSheetRow *geom)
+geometry_get_height(const GSheetRow *geom, gint row, gpointer data)
 {
   return 25;
 }
 
 
+static gboolean
+geometry_is_sensitive(const GSheetRow *geom, gint row, gpointer data)
+{
+  PsppireVarStore *vs = PSPPIRE_VAR_STORE(geom);
+  
+  if ( ! vs->dict) 
+    return FALSE;
+
+  return  row < psppire_dict_get_var_cnt(vs->dict); 
+}
+
 static
 gboolean always_true()
 {
@@ -700,8 +729,8 @@ gboolean always_true()
 }
 
 
-static const gchar *
-geometry_get_button_label(const GSheetRow *geom, gint unit)
+static gchar *
+geometry_get_button_label(const GSheetRow *geom, gint unit, gpointer data)
 {
   gchar *label = g_strdup_printf(_("%d"), unit);
   
@@ -716,7 +745,7 @@ psppire_var_store_sheet_row_init (GSheetRowIface *iface)
   iface->get_height =        geometry_get_height;
   iface->set_height =        0;
   iface->get_visibility =    always_true;
-  iface->get_sensitivity =   always_true;
+  iface->get_sensitivity =   geometry_is_sensitive;
 
   iface->get_button_label = geometry_get_button_label;
 }
index 9a341ec424da1922d5246d2b9e1042f86c1c290a..21ba79b11400e2efd231437efc9a461ec78b2e43 100644 (file)
 #include "helper.h"
 #include "data-sheet.h"
 #include "var-sheet.h"
-#include "psppire-case-array.h"
 #include "message-dialog.h"
 
 GladeXML *xml;
 
 
 PsppireDict *the_dictionary = 0;
-PsppireCaseArray *the_cases = 0;
-
 
 PsppireDataStore *data_store = 0;
 
@@ -120,10 +117,7 @@ main(int argc, char *argv[])
   /* Create the model for the var_sheet */
   var_store = psppire_var_store_new(the_dictionary);
 
-  /* Create the model for the data sheet */
-  the_cases = psppire_case_array_new(100000, 20);
-
-  data_store = psppire_data_store_new(the_dictionary, the_cases);
+  data_store = psppire_data_store_new(the_dictionary);
 
   /* load the interface */
   xml = glade_xml_new(PKGDATADIR "/psppire.glade", NULL, NULL);