Fixed bug where gui would crash when columns were resized.
[pspp-builds.git] / lib / gtksheet / gtksheet.c
index fbaa73c21c50a26bfe196d11e96f1aa8626b8ca6..7b5774ce7b8372dc2608e7e763159f1d2e032d3b 100644 (file)
@@ -1,4 +1,4 @@
-/* This version of GtkSheet has been heavily modified, for the specific 
+/* This version of GtkSheet has been *heavily* modified, for the specific 
    requirements of PSPPIRE. */
 
 /* GtkSheet widget for Gtk+.
@@ -60,7 +60,6 @@
 #include "gtkextra-marshal.h"
 #include "gsheetmodel.h"
 
-
 /* sheet flags */
 enum
 { 
@@ -79,6 +78,9 @@ enum
 #define GTK_SHEET_SET_FLAGS(sheet,flag)    (GTK_SHEET_FLAGS (sheet) |= (flag))
 #define GTK_SHEET_UNSET_FLAGS(sheet,flag)  (GTK_SHEET_FLAGS (sheet) &= ~(flag))
 
+#define GTK_SHEET_IS_LOCKED(sheet)   (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IS_LOCKED)
+
+
 #define GTK_SHEET_IS_FROZEN(sheet)   (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IS_FROZEN)
 #define GTK_SHEET_IN_XDRAG(sheet)    (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_XDRAG)
 #define GTK_SHEET_IN_YDRAG(sheet)    (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_YDRAG)
@@ -101,8 +103,24 @@ 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);
+
+static inline
+void dispose_string (const GtkSheet *sheet, gchar *text)
+{
+  GSheetModel *model  = gtk_sheet_get_model(sheet);
 
+  if ( ! model ) 
+    return;
 
+  if (g_sheet_model_free_strings(model))
+    g_free(text);
+}
 
 static inline 
 guint DEFAULT_ROW_HEIGHT(GtkWidget *widget) 
@@ -163,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);
 }
 
 
@@ -186,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
@@ -194,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;
@@ -213,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;
 
@@ -223,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));
 }
@@ -241,26 +258,27 @@ 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 const GtkSheetButton *
-xxx_column_button(GtkSheet *sheet, gint col)
+static inline GtkSheetButton *
+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);
 }
 
 
 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);
+  gint x = g_sheet_column_start_pixel(geo, col);
 
   if ( sheet->row_titles_visible ) 
     x += sheet->row_title_area.width;
@@ -273,7 +291,7 @@ xxx_column_width(const GtkSheet *sheet, gint col)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
 
-  return g_sheet_column_get_width(col_geo, col, sheet);
+  return g_sheet_column_get_width(col_geo, col);
 }
 
 
@@ -281,7 +299,7 @@ static inline void
 xxx_set_column_width(GtkSheet *sheet, gint col, gint width)
 {
   if ( sheet->column_geometry ) 
-    g_sheet_column_set_width(sheet->column_geometry, col, width, sheet);
+    g_sheet_column_set_width(sheet->column_geometry, col, width);
 }
 
 static inline void
@@ -289,7 +307,7 @@ xxx_column_set_left_column(GtkSheet *sheet, gint col, gint i)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
 
-  g_sheet_column_set_left_text_column(col_geo, col, i, sheet);
+  g_sheet_column_set_left_text_column(col_geo, col, i);
 }
 
 static inline gint
@@ -297,7 +315,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);
 }
 
 static inline void
@@ -305,7 +323,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);
 }
 
 static inline gint
@@ -313,7 +331,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);
 }
 
 static inline GtkJustification
@@ -321,31 +339,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);
 }
 
 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);
 }
 
 
 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);
 }
 
 
 /* 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));
 }
@@ -355,13 +373,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);
 }
 
 /* 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;
@@ -394,7 +412,7 @@ static inline gint SHEET_HEIGHT(GtkSheet *sheet)
 }
 
 
-static inline const GtkSheetButton *
+static inline GtkSheetButton *
 yyy_row_button(GtkSheet *sheet, gint row)
 {
   GSheetRow *row_geo = sheet->row_geometry;
@@ -433,15 +451,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;
@@ -455,11 +473,10 @@ 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;
-
  row=ROW_FROM_YPIXEL(sheet, y);
  *drag_row=row;
 
@@ -479,57 +496,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) 
@@ -622,7 +657,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, 
@@ -698,15 +733,13 @@ 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, 
                                                 GtkRequisition *requisition);
 
 /* Attributes routines */
-static void init_attributes                    (GtkSheet *sheet, gint col,  
+static void init_attributes                    (const GtkSheet *sheet, gint col,  
                                                 GtkSheetCellAttr *attributes);
 
 
@@ -1089,10 +1122,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;
 
@@ -1123,19 +1156,83 @@ gtk_sheet_init (GtkSheet *sheet)
 }
 
 
+/* Callback which occurs whenever columns are inserted/deleted in the model */
+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;
+  gint model_columns = g_sheet_model_get_column_count(model);
+
+
+  /* Need to update all the columns starting from the first column and onwards.
+   * Previous column are unchanged, so don't need to be updated.
+   */
+  range.col0 = first_column;
+  range.row0 = 0;
+  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);
+}
+
+
+/* Callback which occurs whenever rows are inserted/deleted in the model */
 static void 
-rows_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.
+   */
   range.row0 = first_row;
   range.col0 = 0;
   range.rowi = yyy_row_count(sheet) - 1;
   range.coli = xxx_column_count(sheet) - 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->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);
 }
 
@@ -1230,27 +1327,50 @@ gtk_sheet_set_model(GtkSheet *sheet, GSheetModel *model)
   g_signal_connect(model, "range_changed", 
                   G_CALLBACK(range_update_callback), sheet);
 
+  g_signal_connect(model, "rows_inserted",
+                  G_CALLBACK(rows_inserted_deleted_callback), sheet);
+
   g_signal_connect(model, "rows_deleted",
-                  G_CALLBACK(rows_deleted_callback), sheet);
+                  G_CALLBACK(rows_inserted_deleted_callback), sheet);
 
-}
+  g_signal_connect(model, "columns_inserted",
+                  G_CALLBACK(columns_inserted_deleted_callback), sheet);
+
+  g_signal_connect(model, "columns_deleted",
+                  G_CALLBACK(columns_inserted_deleted_callback), sheet);
 
+}
 
 
+/* 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
@@ -1275,7 +1395,6 @@ gtk_sheet_construct (GtkSheet *sheet,
   sheet->column_titles_visible = TRUE;
   sheet->autoscroll = TRUE;
   sheet->justify_entry = TRUE;
-  sheet->locked = FALSE;
 
 
   /* create sheet entry */
@@ -1347,10 +1466,7 @@ gtk_sheet_change_entry(GtkSheet *sheet, GtkType entry_type)
                         "changed",
                         G_CALLBACK(gtk_sheet_entry_changed),
                         sheet);
-
-
     }
 }
 
 void
@@ -1481,22 +1597,23 @@ gtk_sheet_autoresize_column (GtkSheet *sheet, gint column)
   g_return_if_fail (GTK_IS_SHEET (sheet));
   if (column >= xxx_column_count(sheet) || column < 0) return;
 
-  g_print("%s:%d Iterating rows\n",__FILE__, __LINE__);
-  for (row = 0; row < yyy_row_count(sheet); row++){
-    const gchar *text = gtk_sheet_cell_get_text(sheet, row, column);
-    if (text && strlen(text) > 0){
-      GtkSheetCellAttr attributes;
-
-      gtk_sheet_get_attributes(sheet, row, column, &attributes);
-      if(attributes.is_visible){
-        gint width = STRING_WIDTH(GTK_WIDGET(sheet),
-                                  attributes.font_desc,
-                                 text)
-                   + 2*CELLOFFSET + attributes.border.width;
-        text_width = MAX (text_width, width);
+  for (row = 0; row < yyy_row_count(sheet); row++)
+    {
+      gchar *text = gtk_sheet_cell_get_text(sheet, row, column);
+      if (text && strlen(text) > 0){
+       GtkSheetCellAttr attributes;
+
+       gtk_sheet_get_attributes(sheet, row, column, &attributes);
+       if(attributes.is_visible){
+         gint width = STRING_WIDTH(GTK_WIDGET(sheet),
+                                   attributes.font_desc,
+                                   text)
+           + 2*CELLOFFSET + attributes.border.width;
+         text_width = MAX (text_width, width);
+       }
       }
+      dispose_string(sheet, text);
     }
-  }
 
   if(text_width > xxx_column_width(sheet, column) )
     {
@@ -1566,16 +1683,33 @@ gtk_sheet_set_locked             (GtkSheet *sheet, gboolean locked)
   g_return_if_fail (sheet != NULL);
   g_return_if_fail (GTK_IS_SHEET (sheet));
 
-  sheet->locked = locked;
+  if ( locked ) 
+    {
+      GTK_SHEET_SET_FLAGS(sheet,GTK_SHEET_IS_LOCKED);
+      gtk_widget_hide(sheet->sheet_entry);
+      gtk_widget_unmap(sheet->sheet_entry);
+    }
+  else
+    {
+      GTK_SHEET_UNSET_FLAGS(sheet,GTK_SHEET_IS_LOCKED);
+      if (GTK_WIDGET_MAPPED(GTK_WIDGET(sheet)))
+       {
+         gtk_widget_show (sheet->sheet_entry);
+         gtk_widget_map (sheet->sheet_entry);
+       }
+    }
+
+  gtk_entry_set_editable(GTK_ENTRY(sheet->sheet_entry), locked);
+
 }
 
 gboolean
-gtk_sheet_locked                    (GtkSheet *sheet)
+gtk_sheet_locked                    (const GtkSheet *sheet)
 {
   g_return_val_if_fail (sheet != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
 
-  return sheet->locked;
+  return GTK_SHEET_IS_LOCKED(sheet);
 }
 
 /* This routine has problems with gtk+-1.2 related with the
@@ -1736,10 +1870,11 @@ gtk_sheet_show_column_titles(GtkSheet *sheet)
       col <= MAX_VISIBLE_COLUMN(sheet); 
       col++)
     {
-      const GtkSheetButton *button = xxx_column_button(sheet, col);
+      GtkSheetButton *button = xxx_column_button(sheet, col);
       GtkSheetChild *child = button->child;
       if(child)
         gtk_sheet_child_show(child);
+      gtk_sheet_button_free(button);
     }
   adjust_scrollbars(sheet);
  } 
@@ -1810,10 +1945,11 @@ gtk_sheet_hide_column_titles(GtkSheet *sheet)
       col <= MAX_VISIBLE_COLUMN(sheet); 
       col++)
     {
-      const GtkSheetButton *button = xxx_column_button(sheet, col);
+      GtkSheetButton *button = xxx_column_button(sheet, col);
       GtkSheetChild *child = button->child;
       if(child)
         gtk_sheet_child_hide(child);
+      gtk_sheet_button_free(button);
   }
   adjust_scrollbars(sheet);
  }
@@ -2043,24 +2179,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));
 
@@ -2077,16 +2210,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
@@ -2445,6 +2577,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);
 }
@@ -2776,7 +2909,7 @@ gtk_sheet_unrealize (GtkWidget * widget)
   gdk_window_destroy (sheet->row_title_window);
 
   if (sheet->pixmap){
-    g_free (sheet->pixmap);
+    g_object_unref(sheet->pixmap);
     sheet->pixmap = NULL;
   }
 
@@ -2822,10 +2955,14 @@ gtk_sheet_map (GtkWidget * widget)
            gdk_window_show (sheet->row_title_window);
       }
 
-      if(!GTK_WIDGET_MAPPED (sheet->sheet_entry)){
-                 gtk_widget_show (sheet->sheet_entry);
-                 gtk_widget_map (sheet->sheet_entry);
-      }
+      if(!GTK_WIDGET_MAPPED (sheet->sheet_entry)
+        && ! gtk_sheet_locked(sheet)
+        && sheet->active_cell.row  >=0
+        && sheet->active_cell.col  >=0 )
+       {
+         gtk_widget_show (sheet->sheet_entry);
+         gtk_widget_map (sheet->sheet_entry);
+       }
 
       if (GTK_WIDGET_VISIBLE (sheet->button) &&
          !GTK_WIDGET_MAPPED (sheet->button)){
@@ -3048,7 +3185,7 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col)
   PangoContext *context = gtk_widget_get_pango_context(GTK_WIDGET(sheet)); 
   gint ascent, descent, y_pos;
 
-  const gchar *label;
+  gchar *label;
 
   g_return_if_fail (sheet != NULL);
 
@@ -3085,6 +3222,7 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col)
   clip_area = area;
 
   layout = gtk_widget_create_pango_layout (GTK_WIDGET(sheet), label);
+  dispose_string(sheet, label);
   pango_layout_set_font_description (layout, attributes.font_desc);
 
   pango_layout_get_pixel_extents (layout, NULL, &rect);
@@ -3124,7 +3262,7 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col)
           area.x+=area.width;
           if(!gtk_sheet_clip_text(sheet)){          
            for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--){
-             if(gtk_sheet_cell_get_text(sheet, row, i)) break;
+             if( !gtk_sheet_cell_empty(sheet, row, i)) break;
              if(size>=text_width+CELLOFFSET) break;
              size+=xxx_column_width(sheet, i);
             xxx_column_set_right_column(sheet, i, 
@@ -3143,7 +3281,7 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col)
          area.x+=area.width/2;
           if(!gtk_sheet_clip_text(sheet)){          
            for(i=col+1; i<=MAX_VISIBLE_COLUMN(sheet); i++){
-             if(gtk_sheet_cell_get_text(sheet, row, i)) break;
+             if( ! gtk_sheet_cell_empty(sheet, row, i)) break;
              if(sizer>=text_width/2) break;
              sizer+= xxx_column_width(sheet, i);
             xxx_column_set_left_column(sheet, i, 
@@ -3152,7 +3290,7 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col)
                                            xxx_column_left_column(sheet, i)));
            }
            for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--){
-             if(gtk_sheet_cell_get_text(sheet, row, i)) break;
+             if( ! gtk_sheet_cell_empty(sheet, row, i)) break;
              if(sizel>=text_width/2) break;
              sizel+=xxx_column_width(sheet, i);
             xxx_column_set_right_column(sheet, i, 
@@ -3170,7 +3308,7 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col)
           size=area.width;
           if(!gtk_sheet_clip_text(sheet)){          
            for(i=col+1; i<=MAX_VISIBLE_COLUMN(sheet); i++){
-             if(gtk_sheet_cell_get_text(sheet, row, i)) break;
+             if(! gtk_sheet_cell_empty(sheet, row, i)) break;
              if(size>=text_width+CELLOFFSET) break;
              size+=xxx_column_width(sheet, i);
             xxx_column_set_left_column(sheet, i, 
@@ -3229,15 +3367,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
  {
@@ -3333,7 +3472,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 && 
@@ -3387,31 +3527,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
@@ -3428,20 +3570,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--;
@@ -3500,7 +3643,7 @@ gtk_sheet_set_cell(GtkSheet *sheet, gint row, gint col,
 {
   GSheetModel *model ;
   gboolean changed ;
-  const gchar *old_text ; 
+  gchar *old_text ; 
 
   GtkSheetRange range;
   gint text_width;
@@ -3524,14 +3667,19 @@ gtk_sheet_set_cell(GtkSheet *sheet, gint row, gint col,
   if (0 != safe_strcmp(old_text, text))
     changed = g_sheet_model_set_string(model, text, row, col);
 
+  if ( g_sheet_model_free_strings(model))
+    g_free(old_text);
+
+
   if(changed && attributes.is_visible)
     {
-      const gchar *s = gtk_sheet_cell_get_text(sheet, row, col);
+      gchar *s = gtk_sheet_cell_get_text(sheet, row, col);
       text_width = 0;
       if(s && strlen(s) > 0) {
        text_width = STRING_WIDTH(GTK_WIDGET(sheet), 
                                  attributes.font_desc, text);
       }
+      dispose_string(sheet, s);
 
     range.row0 = row;
     range.rowi = row;
@@ -3603,7 +3751,7 @@ gtk_sheet_real_cell_clear (GtkSheet *sheet, gint row, gint column, gboolean dele
 {
   GSheetModel *model =  gtk_sheet_get_model(sheet);
 
-  const gchar *old_text = gtk_sheet_cell_get_text(sheet, row, column); 
+  gchar *old_text = gtk_sheet_cell_get_text(sheet, row, column); 
  
   if (old_text && strlen(old_text) > 0 )
     {
@@ -3614,6 +3762,7 @@ gtk_sheet_real_cell_clear (GtkSheet *sheet, gint row, gint column, gboolean dele
                        row, column);
     }  
 
+  dispose_string (sheet, old_text);
 }
     
 void
@@ -3664,8 +3813,21 @@ gtk_sheet_real_range_clear (GtkSheet *sheet, const GtkSheetRange *range,
 }
 
 
-const gchar *     
-gtk_sheet_cell_get_text (GtkSheet *sheet, gint row, gint col)
+static gboolean
+gtk_sheet_cell_empty (const GtkSheet *sheet, gint row, gint col)
+{
+  gboolean empty;
+  char *text = gtk_sheet_cell_get_text(sheet, row, col);
+  empty = (text == NULL );
+  dispose_string(sheet, text);
+
+  return empty;
+}
+
+
+gchar *     
+gtk_sheet_cell_get_text (const GtkSheet *sheet, gint row, gint col)
 {
   GSheetModel *model;
   g_return_val_if_fail (sheet != NULL, NULL);
@@ -3797,7 +3959,7 @@ gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint column)
  g_return_val_if_fail (sheet != NULL, 0);
  g_return_val_if_fail (GTK_IS_SHEET (sheet), 0);
 
- if(row < 0 || column < 0) return FALSE;
+ if(row < -1 || column < -1) return FALSE;
  if(row >= yyy_row_count(sheet) || column >= xxx_column_count(sheet)) 
    return FALSE;
 
@@ -3806,9 +3968,15 @@ gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint column)
        if(!gtk_sheet_deactivate_cell(sheet)) return FALSE;
    }
 
- sheet->active_cell.row=row;
- sheet->active_cell.col=column;
+ sheet->active_cell.row = row;
+ sheet->active_cell.col = column;
  
+ if ( row == -1 || column == -1)
+   {
+     gtk_sheet_hide_active_cell(sheet);
+     return TRUE;
+   }
+
  if(!gtk_sheet_activate_cell(sheet, row, column)) return FALSE;
  
  if(gtk_sheet_autoscroll(sheet))
@@ -3856,11 +4024,12 @@ gtk_sheet_entry_changed(GtkWidget *widget, gpointer data)
 
  GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IS_FROZEN);
 
- if(text && strlen(text) > 0){
-      gtk_sheet_get_attributes(sheet, row, col, &attributes); 
-      justification=attributes.justification;
-      gtk_sheet_set_cell(sheet, row, col, justification, text);
- }
+ if(text && strlen(text) > 0)
+   {
+     gtk_sheet_get_attributes(sheet, row, col, &attributes); 
+     justification = attributes.justification;
+     gtk_sheet_set_cell(sheet, row, col, justification, text);
+   }
 
  if(sheet->freeze_count == 0)
         GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IS_FROZEN);
@@ -3887,13 +4056,16 @@ gtk_sheet_deactivate_cell(GtkSheet *sheet)
 
  if(!veto) return FALSE;
 
+ if ( sheet->active_cell.row == -1 || sheet->active_cell.col == -1 )
+   return TRUE;
+
  gtk_signal_disconnect_by_func(GTK_OBJECT(gtk_sheet_get_entry(sheet)),
                               (GtkSignalFunc) gtk_sheet_entry_changed,
                               GTK_OBJECT(GTK_WIDGET(sheet)));
 
  gtk_sheet_hide_active_cell(sheet);
- sheet->active_cell.row=-1;
- sheet->active_cell.col=-1;
+ sheet->active_cell.row = -1;
+ sheet->active_cell.col = -1;
  
  if(GTK_SHEET_REDRAW_PENDING(sheet)){
    GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_REDRAW_PENDING);
@@ -3926,7 +4098,8 @@ gtk_sheet_hide_active_cell(GtkSheet *sheet)
  gtk_sheet_get_attributes(sheet, row, col, &attributes); 
  justification=attributes.justification;
 
- if(text && strlen(text)!=0){
+ if(text && strlen(text) != 0) 
+ {
       gtk_sheet_set_cell(sheet, row, col, justification, text);
       gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[SET_CELL], row, col);
  }
@@ -3943,6 +4116,7 @@ gtk_sheet_hide_active_cell(GtkSheet *sheet)
  row_button_release(sheet, row);
 #endif
 
+ gtk_widget_hide(sheet->sheet_entry);
  gtk_widget_unmap(sheet->sheet_entry);
 
  if(row != -1 && col != -1)
@@ -3984,14 +4158,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); 
@@ -4029,7 +4203,7 @@ gtk_sheet_show_active_cell(GtkSheet *sheet)
  /* Don't show the active cell, if there is no active cell: */
  if(!(row >= 0 && col >= 0)) /* e.g row or coll == -1. */
    return;
-  
+
  if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return;
  if(sheet->state != GTK_SHEET_NORMAL) return;
  if(GTK_SHEET_IN_SELECTION(sheet)) return;
@@ -4045,17 +4219,16 @@ gtk_sheet_show_active_cell(GtkSheet *sheet)
  if(gtk_sheet_justify_entry(sheet))
       justification = attributes.justification;
 
- text = g_strdup(gtk_sheet_cell_get_text(sheet, row, col));
-
if(!text) text = g_strdup("");
+ text = gtk_sheet_cell_get_text(sheet, row, col);
+ if ( ! text ) 
       text = g_strdup("");
 
  gtk_entry_set_visibility(GTK_ENTRY(sheet_entry), attributes.is_visible);
 
- if(gtk_sheet_locked(sheet) || !attributes.is_editable){ 
-            gtk_entry_set_editable(GTK_ENTRY(sheet_entry), FALSE);
- }else{
-            gtk_entry_set_editable(GTK_ENTRY(sheet_entry), TRUE);
- }
+ if(gtk_sheet_locked(sheet) || !attributes.is_editable)
+   gtk_entry_set_editable(GTK_ENTRY(sheet_entry), FALSE);
+ else
+   gtk_entry_set_editable(GTK_ENTRY(sheet_entry), TRUE);
 
 /*** Added by John Gotts. Mar 25, 2005 *********/
  old_text = gtk_entry_get_text(GTK_ENTRY(sheet_entry));
@@ -4075,7 +4248,7 @@ gtk_sheet_show_active_cell(GtkSheet *sheet)
 
  gtk_widget_grab_focus(GTK_WIDGET(sheet_entry));
 
g_free(text);
dispose_string(sheet, text);
 }
 
 static void
@@ -4089,7 +4262,7 @@ gtk_sheet_draw_active_cell(GtkSheet *sheet)
     row = sheet->active_cell.row;
     col = sheet->active_cell.col;
  
-    if(row<0 || col<0) return;
+    if(row < 0 || col < 0) return;
 
     if(!gtk_sheet_cell_isvisible(sheet, row, col)) return;
 #if 0
@@ -4098,7 +4271,6 @@ gtk_sheet_draw_active_cell(GtkSheet *sheet)
 #endif
     gtk_sheet_draw_backing_pixmap(sheet, sheet->range);
     gtk_sheet_draw_border(sheet, sheet->range);
-
 }
 
 
@@ -4129,7 +4301,7 @@ gtk_sheet_make_backing_pixmap (GtkSheet *sheet, guint width, guint height)
                           &pixmap_width, &pixmap_height);
       if ((pixmap_width != width) || (pixmap_height != height))
        {
-          g_free(sheet->pixmap);
+         g_object_unref(sheet->pixmap);
          sheet->pixmap = gdk_pixmap_new (sheet->sheet_window,
                                               width, height,
                                               -1);
@@ -4550,52 +4722,25 @@ gtk_sheet_draw_corners(GtkSheet *sheet, GtkSheetRange range)
 
 static void
 gtk_sheet_real_select_range (GtkSheet * sheet,
-                            GtkSheetRange * range)
+                            const GtkSheetRange * range)
 {
   gint state;
 
   g_return_if_fail (sheet != NULL);
 
-  if(range==NULL) range=&sheet->range;
+  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;
-
-#if 0
-  if(state==GTK_SHEET_COLUMN_SELECTED || state==GTK_SHEET_RANGE_SELECTED){
-   for(i=sheet->range.col0; i< range->col0; i++)
-    column_button_release(sheet, i);
-   for(i=range->coli+1; i<= sheet->range.coli; i++)
-    column_button_release(sheet, i);
-   for(i=range->col0; i<=range->coli; i++){
-    column_button_set(sheet, i);
-   }
-  }
-  if(state==GTK_SHEET_ROW_SELECTED || state==GTK_SHEET_RANGE_SELECTED){
-   for(i=sheet->range.row0; i< range->row0; i++)
-    row_button_release(sheet, i);
-   for(i=range->rowi+1; i<= sheet->range.rowi; i++)
-    row_button_release(sheet, i);
-   for(i=range->row0; i<=range->rowi; i++){
-    row_button_set(sheet, i);
-   }
-  }
-#endif
+  state = sheet->state;
 
   if(range->coli != sheet->range.coli || range->col0 != sheet->range.col0 ||
      range->rowi != sheet->range.rowi || range->row0 != sheet->range.row0)
          {
-
-           gtk_sheet_new_selection(sheet, range);
-
-          sheet->range.col0=range->col0;
-          sheet->range.coli=range->coli;
-          sheet->range.row0=range->row0;
-          sheet->range.rowi=range->rowi;
-
+           gtk_sheet_new_selection(sheet, &sheet->range);
         }
   else
          {
@@ -4603,7 +4748,7 @@ gtk_sheet_real_select_range (GtkSheet * sheet,
            gtk_sheet_range_draw_selection(sheet, sheet->range);
          }
 
-  gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[SELECT_RANGE], range);
+  gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[SELECT_RANGE], &sheet->range);
 }
 
 void
@@ -4616,6 +4761,9 @@ gtk_sheet_select_range(GtkSheet * sheet, const GtkSheetRange *range)
   if(range->row0 < 0 || range->rowi < 0) return;
   if(range->col0 < 0 || range->coli < 0) return;
 
+
+  if ( gtk_sheet_locked(sheet)) return ;
+
   if(sheet->state != GTK_SHEET_NORMAL) 
        gtk_sheet_real_unselect_range(sheet, NULL);
   else
@@ -4644,7 +4792,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);
 }
 
 
@@ -4655,16 +4804,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++){
@@ -4676,6 +4823,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);
 }
 
@@ -4695,55 +4847,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);
 
@@ -4876,35 +5031,40 @@ gtk_sheet_button_press (GtkWidget * widget,
         GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_RESIZE);
      }
      else if(sheet->cursor_drag->type==GDK_TOP_LEFT_ARROW &&
-            !GTK_SHEET_IN_SELECTION(sheet) && !GTK_SHEET_IN_DRAG(sheet)) {
-            if(sheet->state==GTK_STATE_NORMAL) {
-              row=sheet->active_cell.row;
-              column=sheet->active_cell.col;
-              if(!gtk_sheet_deactivate_cell(sheet)) return FALSE;
-              sheet->active_cell.row=row;
-              sheet->active_cell.col=column;
-              sheet->drag_range=sheet->range;
-              sheet->state=GTK_SHEET_RANGE_SELECTED;
-              gtk_sheet_select_range(sheet, &sheet->drag_range);
-            }
-            sheet->x_drag=x;
-            sheet->y_drag=y;
-            if(row < sheet->range.row0) row++;
-            if(row > sheet->range.rowi) row--;
-            if(column < sheet->range.col0) column++;
-            if(column > sheet->range.coli) column--;
-            sheet->drag_cell.row=row;
-            sheet->drag_cell.col=column;
-            sheet->drag_range=sheet->range;
-            draw_xor_rectangle(sheet, sheet->drag_range);
-            GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_DRAG);
-          }
-          else 
-          {
-           gtk_sheet_click_cell(sheet, row, column, &veto);
-           if(veto) GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_SELECTION);
-          }
-
+            !GTK_SHEET_IN_SELECTION(sheet) 
+            && ! GTK_SHEET_IN_DRAG(sheet)
+            && ! gtk_sheet_locked(sheet)
+            && sheet->active_cell.row >= 0
+            && sheet->active_cell.col >= 0
+            ) 
+       {
+        if(sheet->state==GTK_STATE_NORMAL) {
+          row=sheet->active_cell.row;
+          column=sheet->active_cell.col;
+          if(!gtk_sheet_deactivate_cell(sheet)) return FALSE;
+          sheet->active_cell.row=row;
+          sheet->active_cell.col=column;
+          sheet->drag_range=sheet->range;
+          sheet->state=GTK_SHEET_RANGE_SELECTED;
+          gtk_sheet_select_range(sheet, &sheet->drag_range);
+        }
+        sheet->x_drag=x;
+        sheet->y_drag=y;
+        if(row < sheet->range.row0) row++;
+        if(row > sheet->range.rowi) row--;
+        if(column < sheet->range.col0) column++;
+        if(column > sheet->range.coli) column--;
+        sheet->drag_cell.row=row;
+        sheet->drag_cell.col=column;
+        sheet->drag_range=sheet->range;
+        draw_xor_rectangle(sheet, sheet->drag_range);
+        GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_DRAG);
+       }
+     else 
+       {
+        gtk_sheet_click_cell(sheet, row, column, &veto);
+        if(veto) GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_SELECTION);
+       }
     }
 
     if(event->window == sheet->column_title_window){
@@ -5063,18 +5223,20 @@ gtk_sheet_button_release (GtkWidget * widget,
   sheet=GTK_SHEET(widget);
 
   /* release on resize windows */
-  if (GTK_SHEET_IN_XDRAG (sheet)){
-         GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_XDRAG);
-          GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
-         gtk_widget_get_pointer (widget, &x, NULL);
-         gdk_pointer_ungrab (event->time);
-         draw_xor_vline (sheet);
+  if (GTK_SHEET_IN_XDRAG (sheet))
+    {
+      GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_XDRAG);
+      GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+      gtk_widget_get_pointer (widget, &x, NULL);
+      gdk_pointer_ungrab (event->time);
+      draw_xor_vline (sheet);
          
-         gtk_sheet_set_column_width (sheet, sheet->drag_cell.col, new_column_width (sheet, sheet->drag_cell.col, &x));
-          sheet->old_hadjustment = -1.;
-          gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed");
-         return TRUE;
-  }
+      gtk_sheet_set_column_width (sheet, sheet->drag_cell.col, 
+                                 new_column_width (sheet, sheet->drag_cell.col, &x));
+      sheet->old_hadjustment = -1.;
+      gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed");
+      return TRUE;
+    }
 
   if (GTK_SHEET_IN_YDRAG (sheet)){
          GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_YDRAG);
@@ -5169,179 +5331,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);
-      }
-    }
-  }      
-
-  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);
-  }
+  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_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;
@@ -5972,7 +6169,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
@@ -6013,7 +6210,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);
+    }
 }
          
 
@@ -6021,7 +6222,7 @@ static void
 gtk_sheet_size_allocate_entry(GtkSheet *sheet)
 {
  GtkAllocation shentry_allocation;
- GtkSheetCellAttr attributes;
+ GtkSheetCellAttr attributes = { 0 };
  GtkEntry *sheet_entry;
  GtkStyle *style = NULL, *previous_style = NULL;
  gint row, col;
@@ -6033,51 +6234,54 @@ gtk_sheet_size_allocate_entry(GtkSheet *sheet)
 
  sheet_entry = GTK_ENTRY(gtk_sheet_get_entry(sheet));
 
- gtk_sheet_get_attributes(sheet, sheet->active_cell.row, sheet->active_cell.col, &attributes); 
-
- if(GTK_WIDGET_REALIZED(sheet->sheet_entry)){
-
-  if(!GTK_WIDGET(sheet_entry)->style) 
-        gtk_widget_ensure_style(GTK_WIDGET(sheet_entry));
+ if ( ! gtk_sheet_get_attributes(sheet, sheet->active_cell.row, 
+                                sheet->active_cell.col,
+                                &attributes) ) 
+   return ;
 
-  previous_style = GTK_WIDGET(sheet_entry)->style;
-
-  style = gtk_style_copy(previous_style);
-  style->bg[GTK_STATE_NORMAL] = attributes.background;
-  style->fg[GTK_STATE_NORMAL] = attributes.foreground;
-  style->text[GTK_STATE_NORMAL] = attributes.foreground;
-  style->bg[GTK_STATE_ACTIVE] = attributes.background;
-  style->fg[GTK_STATE_ACTIVE] = attributes.foreground;
-  style->text[GTK_STATE_ACTIVE] = attributes.foreground;
-
-  pango_font_description_free(style->font_desc);
-  style->font_desc = pango_font_description_copy(attributes.font_desc);
-
-  GTK_WIDGET(sheet_entry)->style = style;
-  gtk_widget_size_request(sheet->sheet_entry, NULL);
-  GTK_WIDGET(sheet_entry)->style = previous_style;
-
-  if(style != previous_style){
-    if(!GTK_IS_ITEM_ENTRY(sheet->sheet_entry)){
-      style->bg[GTK_STATE_NORMAL] = previous_style->bg[GTK_STATE_NORMAL];
-      style->fg[GTK_STATE_NORMAL] = previous_style->fg[GTK_STATE_NORMAL];
-      style->bg[GTK_STATE_ACTIVE] = previous_style->bg[GTK_STATE_ACTIVE];
-      style->fg[GTK_STATE_ACTIVE] = previous_style->fg[GTK_STATE_ACTIVE];
-    }
-    gtk_widget_set_style(GTK_WIDGET(sheet_entry), style);
-  }
- }
+ if ( GTK_WIDGET_REALIZED(sheet->sheet_entry) )
+   {
+     if(!GTK_WIDGET(sheet_entry)->style) 
+       gtk_widget_ensure_style(GTK_WIDGET(sheet_entry));
+
+     previous_style = GTK_WIDGET(sheet_entry)->style;
+
+     style = gtk_style_copy(previous_style);
+     style->bg[GTK_STATE_NORMAL] = attributes.background;
+     style->fg[GTK_STATE_NORMAL] = attributes.foreground;
+     style->text[GTK_STATE_NORMAL] = attributes.foreground;
+     style->bg[GTK_STATE_ACTIVE] = attributes.background;
+     style->fg[GTK_STATE_ACTIVE] = attributes.foreground;
+     style->text[GTK_STATE_ACTIVE] = attributes.foreground;
+
+     pango_font_description_free(style->font_desc);
+     g_assert(attributes.font_desc);
+     style->font_desc = pango_font_description_copy(attributes.font_desc);
+
+     GTK_WIDGET(sheet_entry)->style = style;
+     gtk_widget_size_request(sheet->sheet_entry, NULL);
+     GTK_WIDGET(sheet_entry)->style = previous_style;
+
+     if(style != previous_style){
+       if(!GTK_IS_ITEM_ENTRY(sheet->sheet_entry)){
+        style->bg[GTK_STATE_NORMAL] = previous_style->bg[GTK_STATE_NORMAL];
+        style->fg[GTK_STATE_NORMAL] = previous_style->fg[GTK_STATE_NORMAL];
+        style->bg[GTK_STATE_ACTIVE] = previous_style->bg[GTK_STATE_ACTIVE];
+        style->fg[GTK_STATE_ACTIVE] = previous_style->fg[GTK_STATE_ACTIVE];
+       }
+       gtk_widget_set_style(GTK_WIDGET(sheet_entry), style);
+     }
+   }
 
  if(GTK_IS_ITEM_ENTRY(sheet_entry))
-    max_size = GTK_ITEM_ENTRY(sheet_entry)->text_max_size;
+   max_size = GTK_ITEM_ENTRY(sheet_entry)->text_max_size;
  else
-    max_size = 0;
+   max_size = 0;
 
  text_size = 0;
  text = gtk_entry_get_text(GTK_ENTRY(sheet_entry));
- if(text && strlen(text) > 0){ 
-     text_size = STRING_WIDTH(GTK_WIDGET(sheet), attributes.font_desc, text);
- }
+ if(text && strlen(text) > 0)
+   text_size = STRING_WIDTH(GTK_WIDGET(sheet), attributes.font_desc, text);
 
  column_width=xxx_column_width(sheet, sheet->active_cell.col);
 
@@ -6092,16 +6296,16 @@ gtk_sheet_size_allocate_entry(GtkSheet *sheet)
  shentry_allocation.width = column_width;
  shentry_allocation.height = yyy_row_height(sheet, sheet->active_cell.row);
 
- if(GTK_IS_ITEM_ENTRY(sheet->sheet_entry)){
-
-   shentry_allocation.height -= 2*CELLOFFSET;
-   shentry_allocation.y += CELLOFFSET;
-   if(gtk_sheet_clip_text(sheet))
-     shentry_allocation.width = column_width - 2*CELLOFFSET;
-   else
-     shentry_allocation.width = size;
-
-   switch(GTK_ITEM_ENTRY(sheet_entry)->justification){
+ if(GTK_IS_ITEM_ENTRY(sheet->sheet_entry))
+   {
+     shentry_allocation.height -= 2*CELLOFFSET;
+     shentry_allocation.y += CELLOFFSET;
+     if(gtk_sheet_clip_text(sheet))
+       shentry_allocation.width = column_width - 2*CELLOFFSET;
+     else
+       shentry_allocation.width = size;
+
+     switch(GTK_ITEM_ENTRY(sheet_entry)->justification){
      case GTK_JUSTIFY_CENTER:
        shentry_allocation.x += (column_width)/2 - size/2;
        break;
@@ -6112,16 +6316,16 @@ gtk_sheet_size_allocate_entry(GtkSheet *sheet)
      case GTK_JUSTIFY_FILL:
        shentry_allocation.x += CELLOFFSET;
        break;
-    }
-
- }
+     }
+   }
 
- if(!GTK_IS_ITEM_ENTRY(sheet->sheet_entry)){
-   shentry_allocation.x += 2;
-   shentry_allocation.y += 2;
-   shentry_allocation.width -= MIN(shentry_allocation.width, 3);
-   shentry_allocation.height -= MIN(shentry_allocation.height, 3);
- }
+ if(!GTK_IS_ITEM_ENTRY(sheet->sheet_entry))
+   {
+     shentry_allocation.x += 2;
+     shentry_allocation.y += 2;
+     shentry_allocation.width -= MIN(shentry_allocation.width, 3);
+     shentry_allocation.height -= MIN(shentry_allocation.height, 3);
+   }
 
  gtk_widget_size_allocate(sheet->sheet_entry, &shentry_allocation);
 
@@ -6136,11 +6340,13 @@ gtk_sheet_entry_set_max_size(GtkSheet *sheet)
  gint sizel=0, sizer=0;
  gint row,col;
  GtkJustification justification;
+ gchar *s = NULL;
 
  row=sheet->active_cell.row;
  col=sheet->active_cell.col;
 
- if(!GTK_IS_ITEM_ENTRY(sheet->sheet_entry) || gtk_sheet_clip_text(sheet)) return;
+ if( ! GTK_IS_ITEM_ENTRY(sheet->sheet_entry) || gtk_sheet_clip_text(sheet)) 
+   return;
 
  justification = GTK_ITEM_ENTRY(sheet->sheet_entry)->justification;
 
@@ -6148,34 +6354,52 @@ gtk_sheet_entry_set_max_size(GtkSheet *sheet)
   case GTK_JUSTIFY_FILL:
   case GTK_JUSTIFY_LEFT:
     for(i=col+1; i<=MAX_VISIBLE_COLUMN(sheet); i++){
-     if(gtk_sheet_cell_get_text(sheet, row, i)) break;
+      if((s = gtk_sheet_cell_get_text(sheet, row, i)))
+       {
+         g_free(s);
+         break;
+       }
      size+=xxx_column_width(sheet, i);
     }
     size = MIN(size, sheet->sheet_window_width - COLUMN_LEFT_XPIXEL(sheet, col));
     break;
-  case GTK_JUSTIFY_RIGHT:
-    for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--){
-     if(gtk_sheet_cell_get_text(sheet, row, i)) break;
-     size+=xxx_column_width(sheet, i);
-    }
+ case GTK_JUSTIFY_RIGHT:
+   for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--)
+     {
+       if((s = gtk_sheet_cell_get_text(sheet, row, i)))
+        {
+          g_free(s);
+          break;
+        }
+       size+=xxx_column_width(sheet, i);
+     }
     break;
   case GTK_JUSTIFY_CENTER:
     for(i=col+1; i<=MAX_VISIBLE_COLUMN(sheet); i++){
-/*     if(gtk_sheet_cell_get_text(sheet, row, i)) break;
+/*     if((s = gtk_sheet_cell_get_text(sheet, row, i)))
+            {
+            g_free(s);
+            break;
+            }
 */
      sizer+=xxx_column_width(sheet, i);
     }
-    for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--){
-     if(gtk_sheet_cell_get_text(sheet, row, i)) break;
-     sizel+=xxx_column_width(sheet, i);
-    }
+    for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--)
+      {
+       if((s = gtk_sheet_cell_get_text(sheet, row, i)))
+         {
+           g_free(s);
+           break;
+         }
+       sizel+=xxx_column_width(sheet, i);
+      }
     size=2*MIN(sizel, sizer);
     break;
  }
 
- if(size!=0) size+=xxx_column_width(sheet, col);
GTK_ITEM_ENTRY(sheet->sheet_entry)->text_max_size=size;
-
+ if(size != 0) 
  size += xxx_column_width(sheet, col);
+ GTK_ITEM_ENTRY(sheet->sheet_entry)->text_max_size = size;
 }
 
 static void
@@ -6188,51 +6412,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;
-
-   } else {
-
-     parent = GTK_WIDGET(gtk_type_new(sheet->entry_type));
-     entry = parent;
-     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);
+   }
 
-   }             
+ 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;
+       } 
+     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);
  
@@ -6324,249 +6544,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)
+gtk_sheet_button_draw(GtkSheet *sheet, GdkWindow *window, 
+                     GtkSheetButton *button, gboolean is_sensitive,
+                     GdkRectangle allocation)
 {
-  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)
-{
-  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;
-  const 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);
-
-  if(button->label_visible){
-
-    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);
+    gtk_paint_box (sheet->button->style, window,
+                  button->state, shadow_type, 
+                  &allocation, GTK_WIDGET(sheet->button),
+                  "button", 
+                  allocation.x, allocation.y, 
+                  allocation.width, allocation.height);
+
+  if(button->label_visible)
+    {
 
-    y += 2*sheet->button->style->ythickness;
+      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);
 
-    if(button->label && strlen(button->label)>0){
-           gchar *words = 0;
-           PangoLayout *layout = NULL;
-           gint real_x = x, real_y = y;
+      allocation.y += 2*sheet->button->style->ythickness;
 
-           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);
-    }
-    if(button->label && strlen(button->label) > 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;
 
-      text_width = STRING_WIDTH(GTK_WIDGET(sheet), GTK_WIDGET(sheet)->style->font_desc, button->label);
+       words=button->label;
+       line = g_new(gchar, 1);
+       line[0]='\0';
 
-      layout = gtk_widget_create_pango_layout (GTK_WIDGET(sheet), button->label);
-      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);
+       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);
       }
-      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));
-    }
 
-    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
  *
@@ -6680,9 +6890,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;
 
@@ -6692,71 +6902,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);
@@ -7001,9 +7217,9 @@ 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;
 }
 
@@ -7066,16 +7282,17 @@ gtk_sheet_set_column_width (GtkSheet * sheet,
 
   xxx_set_column_width(sheet, column, width);
 
-  if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)) && !GTK_SHEET_IS_FROZEN(sheet)){
-    size_allocate_column_title_buttons (sheet);
-    adjust_scrollbars (sheet);
-    gtk_sheet_size_allocate_entry(sheet);
-    gtk_sheet_range_draw (sheet, NULL);
-  } else
-
+  if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)) && !GTK_SHEET_IS_FROZEN(sheet))
+    {
+      size_allocate_column_title_buttons (sheet);
+      adjust_scrollbars (sheet);
+      gtk_sheet_size_allocate_entry(sheet);
+      gtk_sheet_range_draw (sheet, NULL);
+    } 
+  
   gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[CHANGED], -1, column);
-  gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[NEW_COL_WIDTH], column, width);
-
+  gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[NEW_COL_WIDTH], 
+                 column, width);
 }
 
 
@@ -7112,7 +7329,8 @@ gtk_sheet_set_row_height (GtkSheet * sheet,
 
 
 gboolean
-gtk_sheet_get_attributes(GtkSheet *sheet, gint row, gint col, GtkSheetCellAttr *attributes)
+gtk_sheet_get_attributes(const GtkSheet *sheet, gint row, gint col, 
+                        GtkSheetCellAttr *attributes)
 {
  const GdkColor *fg, *bg; 
  const GtkJustification *j ; 
@@ -7127,7 +7345,7 @@ gtk_sheet_get_attributes(GtkSheet *sheet, gint row, gint col, GtkSheetCellAttr *
  init_attributes(sheet, col, attributes);
 
  if ( !sheet->model) 
-        return FALSE;
+   return FALSE;
 
  attributes->is_editable = g_sheet_model_is_editable(sheet->model, row, col);
  attributes->is_visible = g_sheet_model_is_visible(sheet->model, row, col);
@@ -7154,7 +7372,7 @@ gtk_sheet_get_attributes(GtkSheet *sheet, gint row, gint col, GtkSheetCellAttr *
 }
 
 static void
-init_attributes(GtkSheet *sheet, gint col, GtkSheetCellAttr *attributes)
+init_attributes(const GtkSheet *sheet, gint col, GtkSheetCellAttr *attributes)
 {
  /* DEFAULT VALUES */    
  attributes->foreground = GTK_WIDGET(sheet)->style->black;
@@ -7175,9 +7393,7 @@ init_attributes(GtkSheet *sheet, gint col, GtkSheetCellAttr *attributes)
  attributes->is_editable = TRUE;
  attributes->is_visible = TRUE;
  attributes->font_desc = GTK_WIDGET(sheet)->style->font_desc;
-
 }       
 
 
 /********************************************************************
@@ -7808,3 +8024,27 @@ gtk_sheet_get_model(const GtkSheet *sheet)
   return sheet->model;
 }
 
+
+GtkSheetButton *
+gtk_sheet_button_new(void)
+{
+  GtkSheetButton *button = g_malloc(sizeof(GtkSheetButton));
+  
+  button->state = GTK_STATE_NORMAL;
+  button->label = NULL;
+  button->label_visible = TRUE;
+  button->child = NULL;
+  button->justification = GTK_JUSTIFY_FILL;
+
+  return button;
+}
+
+
+inline void
+gtk_sheet_button_free(GtkSheetButton *button)
+{
+  if (!button) return ;
+   
+  g_free(button->label);
+  g_free(button);
+}