Fix some runtime warnings
[pspp-builds.git] / lib / gtksheet / gtksheet.c
index d0873404fbeb28b3fe7eb493f85e2f912b8baf53..955e77e290b399b45954de63898c072fb90701c4 100644 (file)
@@ -91,11 +91,12 @@ static void set_entry_widget_font (GtkSheet *sheet);
 static void gtk_sheet_update_primary_selection (GtkSheet *sheet);
 static void draw_column_title_buttons_range (GtkSheet *sheet, gint first, gint n);
 static void draw_row_title_buttons_range (GtkSheet *sheet, gint first, gint n);
+static void redraw_range (GtkSheet *sheet, GtkSheetRange *range);
 
 
 static void set_row_height (GtkSheet *sheet,
                            gint row,
-                           guint height);
+                           gint height);
 
 static void destroy_hover_window (GtkSheetHoverTitle *);
 static GtkSheetHoverTitle *create_hover_window (void);
@@ -225,12 +226,20 @@ static gboolean
 on_column_boundary (const GtkSheet *sheet, gint x, gint *column)
 {
   gint col;
+  gint pixel;
 
   x += sheet->hadjustment->value;
 
+  if ( x < 0)
+    return FALSE;
+
   col = column_from_xpixel (sheet, x);
 
-  if ( column_from_xpixel (sheet, x - DRAG_WIDTH / 2) < col )
+  pixel = x - DRAG_WIDTH / 2;
+  if (pixel < 0)
+    pixel = 0;
+
+  if ( column_from_xpixel (sheet, pixel) < col )
     {
       *column = col - 1;
       return TRUE;
@@ -249,12 +258,20 @@ static gboolean
 on_row_boundary (const GtkSheet *sheet, gint y, gint *row)
 {
   gint r;
+  gint pixel;
 
   y += sheet->vadjustment->value;
 
+  if ( y < 0)
+    return FALSE;
+
   r = row_from_ypixel (sheet, y);
 
-  if ( row_from_ypixel (sheet, y - DRAG_WIDTH / 2) < r )
+  pixel = y - DRAG_WIDTH / 2;
+  if (pixel < 0)
+    pixel = 0;
+
+  if ( row_from_ypixel (sheet, pixel) < r )
     {
       *row = r - 1;
       return TRUE;
@@ -421,7 +438,7 @@ static void gtk_sheet_forall                         (GtkContainer *container,
                                                  GtkCallback callback,
                                                  gpointer callback_data);
 
-static void gtk_sheet_set_scroll_adjustments    (GtkSheet *sheet,
+static gboolean gtk_sheet_set_scroll_adjustments  (GtkSheet *sheet,
                                                  GtkAdjustment *hadjustment,
                                                  GtkAdjustment *vadjustment);
 
@@ -454,9 +471,9 @@ static gboolean gtk_sheet_cell_isvisible  (GtkSheet *sheet,
 static void gtk_sheet_cell_draw (GtkSheet *sheet, gint row, gint column);
 
 
-/* draw visible part of range. If range == NULL then draw the whole screen */
-static void gtk_sheet_range_draw (GtkSheet *sheet,
-                                 const GtkSheetRange *range);
+/* draw visible part of range. */
+static void draw_sheet_region (GtkSheet *sheet, GdkRegion *region);
+
 
 /* highlight the visible part of the selected range */
 static void gtk_sheet_range_draw_selection      (GtkSheet *sheet,
@@ -477,12 +494,9 @@ static void gtk_sheet_draw_border           (GtkSheet *sheet,
 
 /* Active Cell handling */
 
-static void gtk_sheet_entry_changed             (GtkWidget *widget,
-                                                 gpointer data);
 static void gtk_sheet_hide_entry_widget                 (GtkSheet *sheet);
-static void change_active_cell          (GtkSheet *sheet,
-                                         gint row, gint col);
-static gboolean gtk_sheet_draw_active_cell              (GtkSheet *sheet);
+static void change_active_cell  (GtkSheet *sheet, gint row, gint col);
+static gboolean gtk_sheet_draw_active_cell      (GtkSheet *sheet);
 static void gtk_sheet_show_entry_widget                 (GtkSheet *sheet);
 static gboolean gtk_sheet_click_cell            (GtkSheet *sheet,
                                                  gint row,
@@ -671,6 +685,21 @@ enum
     PROP_MODEL
   };
 
+static void
+resize_column (GtkSheet *sheet, gint unit, glong size)
+{
+  GtkSheetRange range;
+  range.col0 = unit;
+  range.coli = max_visible_column (sheet);
+  range.row0 = min_visible_row (sheet);
+  range.rowi = max_visible_row (sheet);
+
+  redraw_range (sheet, &range);
+
+  draw_column_title_buttons_range (sheet, range.col0, range.coli);
+}
+
+
 static void
 gtk_sheet_set_horizontal_axis (GtkSheet *sheet, PsppireAxis *a)
 {
@@ -678,11 +707,26 @@ gtk_sheet_set_horizontal_axis (GtkSheet *sheet, PsppireAxis *a)
     g_object_unref (sheet->haxis);
 
   sheet->haxis = a;
+  g_signal_connect_swapped (a, "resize-unit", G_CALLBACK (resize_column), sheet);
 
   if ( sheet->haxis )
     g_object_ref (sheet->haxis);
 }
 
+static void
+resize_row (GtkSheet *sheet, gint unit, glong size)
+{
+  GtkSheetRange range;
+  range.col0 = min_visible_column (sheet);
+  range.coli = max_visible_column (sheet);
+  range.row0 = unit;
+  range.rowi = max_visible_row (sheet);
+
+  redraw_range (sheet, &range);
+
+  draw_row_title_buttons_range (sheet, range.row0, range.rowi);
+}
+
 static void
 gtk_sheet_set_vertical_axis (GtkSheet *sheet, PsppireAxis *a)
 {
@@ -691,6 +735,8 @@ gtk_sheet_set_vertical_axis (GtkSheet *sheet, PsppireAxis *a)
 
   sheet->vaxis = a;
 
+  g_signal_connect_swapped (a, "resize-unit", G_CALLBACK (resize_row), sheet);
+
   if ( sheet->vaxis )
     g_object_ref (sheet->vaxis);
 }
@@ -1061,7 +1107,6 @@ gtk_sheet_init (GtkSheet *sheet)
 
   sheet->sheet_window = NULL;
   sheet->entry_widget = NULL;
-  sheet->entry_handler_id = 0;
   sheet->button = NULL;
 
   sheet->hadjustment = NULL;
@@ -1093,6 +1138,29 @@ gtk_sheet_init (GtkSheet *sheet)
 }
 
 
+/* Cause RANGE to be redrawn. If RANGE is null, then the
+   entire visible range will be redrawn.
+ */
+static void
+redraw_range (GtkSheet *sheet, GtkSheetRange *range)
+{
+  GdkRectangle rect;
+  if ( ! GTK_WIDGET_REALIZED (sheet))
+    return;
+
+  if ( NULL != range )
+    rectangle_from_range (sheet, range, &rect);
+  else
+    {
+      GdkRegion *r = gdk_drawable_get_visible_region (sheet->sheet_window);
+      gdk_region_get_clipbox (r, &rect);
+    }
+
+  gdk_window_invalidate_rect (sheet->sheet_window, &rect, FALSE);
+}
+
+
 /* Callback which occurs whenever columns are inserted / deleted in the model */
 static void
 columns_inserted_deleted_callback (GSheetModel *model, gint first_column,
@@ -1121,10 +1189,13 @@ columns_inserted_deleted_callback (GSheetModel *model, gint first_column,
   draw_column_title_buttons_range (sheet,
                                   first_column, max_visible_column (sheet));
 
-  gtk_sheet_range_draw (sheet, &range);
+
+  redraw_range (sheet, &range);
 }
 
 
+
+
 /* Callback which occurs whenever rows are inserted / deleted in the model */
 static void
 rows_inserted_deleted_callback (GSheetModel *model, gint first_row,
@@ -1151,7 +1222,7 @@ rows_inserted_deleted_callback (GSheetModel *model, gint first_row,
 
   draw_row_title_buttons_range (sheet, first_row, max_visible_row (sheet));
 
-  gtk_sheet_range_draw (sheet, &range);
+  redraw_range (sheet, &range);
 }
 
 /*
@@ -1176,7 +1247,7 @@ range_update_callback (GSheetModel *m, gint row0, gint col0,
 
   if ( ( row0 < 0 && col0 < 0 ) || ( rowi < 0 && coli < 0 ) )
     {
-      gtk_sheet_range_draw (sheet, NULL);
+      redraw_range (sheet, NULL);
       adjust_scrollbars (sheet);
 
       draw_row_title_buttons_range (sheet, min_visible_row (sheet),
@@ -1198,7 +1269,7 @@ range_update_callback (GSheetModel *m, gint row0, gint col0,
       range.coli = max_visible_column (sheet);
     }
 
-  gtk_sheet_range_draw (sheet, &range);
+  redraw_range (sheet, &range);
 }
 
 
@@ -1244,8 +1315,9 @@ gtk_sheet_set_model (GtkSheet *sheet, GSheetModel *model)
     {
       g_object_ref (model);
 
-      g_signal_connect (model, "range_changed",
-                       G_CALLBACK (range_update_callback), sheet);
+      sheet->update_handler_id = 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);
@@ -1296,7 +1368,7 @@ gtk_sheet_show_grid (GtkSheet *sheet, gboolean show)
 
   sheet->show_grid = show;
 
-  gtk_sheet_range_draw (sheet, NULL);
+  redraw_range (sheet, NULL);
 }
 
 gboolean
@@ -1319,7 +1391,7 @@ gtk_sheet_get_columns_count (GtkSheet *sheet)
 
 static void set_column_width (GtkSheet *sheet,
                              gint column,
-                             guint width);
+                             gint width);
 
 
 void
@@ -1485,7 +1557,6 @@ gtk_sheet_select_row (GtkSheet *sheet, gint row)
   sheet->range.rowi = row;
   sheet->range.coli = psppire_axis_unit_count (sheet->haxis) - 1;
   sheet->active_cell.row = row;
-  sheet->active_cell.col = 0;
 
   g_signal_emit (sheet, sheet_signals[SELECT_ROW], 0, row);
   gtk_sheet_real_select_range (sheet, NULL);
@@ -1509,7 +1580,6 @@ gtk_sheet_select_column (GtkSheet *sheet, gint column)
   sheet->range.col0 = column;
   sheet->range.rowi = psppire_axis_unit_count (sheet->vaxis) - 1;
   sheet->range.coli = column;
-  sheet->active_cell.row = 0;
   sheet->active_cell.col = column;
 
   g_signal_emit (sheet, sheet_signals[SELECT_COLUMN], 0, column);
@@ -1580,7 +1650,7 @@ gtk_sheet_get_visible_range (GtkSheet *sheet, GtkSheetRange *range)
 }
 
 
-static void
+static gboolean
 gtk_sheet_set_scroll_adjustments (GtkSheet *sheet,
                                  GtkAdjustment *hadjustment,
                                  GtkAdjustment *vadjustment)
@@ -1590,24 +1660,34 @@ gtk_sheet_set_scroll_adjustments (GtkSheet *sheet,
       if (sheet->vadjustment)
        g_object_unref (sheet->vadjustment);
       sheet->vadjustment = vadjustment;
-      g_object_ref (vadjustment);
 
-      g_signal_connect (sheet->vadjustment, "value_changed",
-                       G_CALLBACK (vadjustment_value_changed),
-                       sheet);
+      if ( vadjustment)
+       {
+         g_object_ref (vadjustment);
+
+         g_signal_connect (sheet->vadjustment, "value_changed",
+                           G_CALLBACK (vadjustment_value_changed),
+                           sheet);
+       }
     }
 
   if ( sheet->hadjustment != hadjustment )
     {
       if (sheet->hadjustment)
        g_object_unref (sheet->hadjustment);
+
       sheet->hadjustment = hadjustment;
-      g_object_ref (hadjustment);
 
-      g_signal_connect (sheet->hadjustment, "value_changed",
-                       G_CALLBACK (hadjustment_value_changed),
-                       sheet);
+      if ( hadjustment)
+       {
+         g_object_ref (hadjustment);
+
+         g_signal_connect (sheet->hadjustment, "value_changed",
+                           G_CALLBACK (hadjustment_value_changed),
+                           sheet);
+       }
     }
+  return TRUE;
 }
 
 static void
@@ -1713,8 +1793,6 @@ gtk_sheet_realize (GtkWidget *widget)
 
   sheet = GTK_SHEET (widget);
 
-  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
-
   colormap = gtk_widget_get_colormap (widget);
   display = gtk_widget_get_display (widget);
 
@@ -1835,6 +1913,9 @@ gtk_sheet_realize (GtkWidget *widget)
   draw_column_title_buttons (sheet);
 
   gtk_sheet_update_primary_selection (sheet);
+
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
 }
 
 static void
@@ -1956,7 +2037,7 @@ gtk_sheet_map (GtkWidget *widget)
            !GTK_WIDGET_MAPPED (GTK_BIN (sheet->button)->child))
          gtk_widget_map (GTK_BIN (sheet->button)->child);
 
-      gtk_sheet_range_draw (sheet, NULL);
+      redraw_range (sheet, NULL);
       change_active_cell (sheet,
                     sheet->active_cell.row,
                     sheet->active_cell.col);
@@ -2085,15 +2166,36 @@ gtk_sheet_cell_draw (GtkSheet *sheet, gint row, gint col)
 }
 
 
-
 static void
-gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range)
+draw_sheet_region (GtkSheet *sheet, GdkRegion *region)
 {
+  GtkSheetRange range;
+  GdkRectangle area;
+  gint y, x;
   gint i, j;
 
-  GdkRectangle area;
   GtkSheetRange drawing_range;
 
+  gdk_region_get_clipbox (region, &area);
+
+  y = area.y + sheet->vadjustment->value;
+  x = area.x + sheet->hadjustment->value;
+
+  if ( sheet->column_titles_visible)
+    y -= sheet->column_title_area.height;
+
+  if ( sheet->row_titles_visible)
+    x -= sheet->row_title_area.width;
+
+  maximize_int (&x, 0);
+  maximize_int (&y, 0);
+
+  range.row0 = row_from_ypixel (sheet, y);
+  range.rowi = row_from_ypixel (sheet, y + area.height);
+
+  range.col0 = column_from_xpixel (sheet, x);
+  range.coli = column_from_xpixel (sheet, x + area.width);
+
   g_return_if_fail (sheet != NULL);
   g_return_if_fail (GTK_SHEET (sheet));
 
@@ -2101,51 +2203,35 @@ gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range)
   if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return;
   if (!GTK_WIDGET_MAPPED (GTK_WIDGET (sheet))) return;
 
-  if (range == NULL)
-    {
-      drawing_range.row0 = min_visible_row (sheet);
-      drawing_range.col0 = min_visible_column (sheet);
-      drawing_range.rowi = MIN (max_visible_row (sheet),
-                               psppire_axis_unit_count (sheet->vaxis) - 1);
-      drawing_range.coli = max_visible_column (sheet);
-      gdk_drawable_get_size (sheet->sheet_window, &area.width, &area.height);
-      area.x = area.y = 0;
-    }
-  else
-    {
-      drawing_range.row0 = MAX (range->row0, min_visible_row (sheet));
-      drawing_range.col0 = MAX (range->col0, min_visible_column (sheet));
-      drawing_range.rowi = MIN (range->rowi, max_visible_row (sheet));
-      drawing_range.coli = MIN (range->coli, max_visible_column (sheet));
 
-      rectangle_from_range (sheet, &drawing_range, &area);
-    }
+  drawing_range.row0 = MAX (range.row0, min_visible_row (sheet));
+  drawing_range.col0 = MAX (range.col0, min_visible_column (sheet));
+  drawing_range.rowi = MIN (range.rowi, max_visible_row (sheet));
+  drawing_range.coli = MIN (range.coli, max_visible_column (sheet));
 
   g_return_if_fail (drawing_range.rowi >= drawing_range.row0);
   g_return_if_fail (drawing_range.coli >= drawing_range.col0);
 
-  gdk_window_begin_paint_rect (sheet->sheet_window, &area);
-
   for (i = drawing_range.row0; i <= drawing_range.rowi; i++)
-    for (j = drawing_range.col0; j <= drawing_range.coli; j++)
-      {
+    {
+      for (j = drawing_range.col0; j <= drawing_range.coli; j++)
        gtk_sheet_cell_draw (sheet, i, j);
-      }
+    }
 
   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 &&
       sheet->active_cell.row >= drawing_range.row0 &&
       sheet->active_cell.row <= drawing_range.rowi &&
       sheet->active_cell.col >= drawing_range.col0 &&
       sheet->active_cell.col <= drawing_range.coli)
     gtk_sheet_show_entry_widget (sheet);
-
-  gdk_window_end_paint (sheet->sheet_window);
 }
 
+
 static void
 gtk_sheet_range_draw_selection (GtkSheet *sheet, GtkSheetRange range)
 {
@@ -2240,7 +2326,11 @@ gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col,
   old_text = g_sheet_model_get_string (model, row, col);
 
   if (0 != safe_strcmp (old_text, text))
-    g_sheet_model_set_string (model, text, row, col);
+    {
+      g_signal_handler_block    (sheet->model, sheet->update_handler_id);
+      g_sheet_model_set_string (model, text, row, col);
+      g_signal_handler_unblock  (sheet->model, sheet->update_handler_id);
+    }
 
   if ( g_sheet_model_free_strings (model))
     g_free (old_text);
@@ -2266,7 +2356,7 @@ gtk_sheet_cell_clear (GtkSheet *sheet, gint row, gint column)
 
   gtk_sheet_real_cell_clear (sheet, row, column);
 
-  gtk_sheet_range_draw (sheet, &range);
+  redraw_range (sheet, &range);
 }
 
 static void
@@ -2442,9 +2532,6 @@ gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint col)
       col >= psppire_axis_unit_count (sheet->haxis))
     return;
 
-  sheet->active_cell.row = row;
-  sheet->active_cell.col = col;
-
   if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
     return;
 
@@ -2468,20 +2555,14 @@ gtk_sheet_get_active_cell (GtkSheet *sheet, gint *row, gint *column)
 }
 
 static void
-gtk_sheet_entry_changed (GtkWidget *widget, gpointer data)
+entry_load_text (GtkSheet *sheet)
 {
-  GtkSheet *sheet;
   gint row, col;
   const char *text;
   GtkJustification justification;
   GtkSheetCellAttr attributes;
 
-  g_return_if_fail (data != NULL);
-  g_return_if_fail (GTK_IS_SHEET (data));
-
-  sheet = GTK_SHEET (data);
-
-  if (!GTK_WIDGET_VISIBLE (widget)) return;
+  if (!GTK_WIDGET_VISIBLE (sheet->entry_widget)) return;
   if (sheet->state != GTK_STATE_NORMAL) return;
 
   row = sheet->active_cell.row;
@@ -2489,9 +2570,6 @@ gtk_sheet_entry_changed (GtkWidget *widget, gpointer data)
 
   if (row < 0 || col < 0) return;
 
-  sheet->active_cell.row = -1;
-  sheet->active_cell.col = -1;
-
   text = gtk_entry_get_text (gtk_sheet_get_entry (sheet));
 
   if (text && strlen (text) > 0)
@@ -2500,9 +2578,6 @@ gtk_sheet_entry_changed (GtkWidget *widget, gpointer data)
       justification = attributes.justification;
       gtk_sheet_set_cell (sheet, row, col, justification, text);
     }
-
-  sheet->active_cell.row = row;;
-  sheet->active_cell.col = col;
 }
 
 
@@ -2525,7 +2600,6 @@ static void
 change_active_cell (GtkSheet *sheet, gint row, gint col)
 {
   gint old_row, old_col;
-  glong old_handler_id = sheet->entry_handler_id;
 
   g_return_if_fail (GTK_IS_SHEET (sheet));
 
@@ -2542,29 +2616,13 @@ change_active_cell (GtkSheet *sheet, gint row, gint col)
       gtk_sheet_real_unselect_range (sheet, NULL);
     }
 
-
-  g_signal_handler_block   (sheet->entry_widget, sheet->entry_handler_id);
-
   old_row = sheet->active_cell.row;
   old_col = sheet->active_cell.col;
 
-  {
-    /* Redraw the neighbourhood of the old active cell */
-    GtkSheetRange r;
-    r.col0 = old_col - 1;
-    r.coli = old_col + 1;
-    r.row0 = old_row - 1;
-    r.rowi = old_row + 1;
-
-    maximize_int (&r.row0, 0);
-    maximize_int (&r.col0, 0);
-    minimize_int (&r.rowi, psppire_axis_unit_count (sheet->vaxis) - 1);
-    minimize_int (&r.coli, psppire_axis_unit_count (sheet->haxis) - 1);
-
+  /* Erase the old cell */
+  gtk_sheet_draw_active_cell (sheet);
 
-    if (  gtk_sheet_range_isvisible (sheet, &r))
-      gtk_sheet_range_draw (sheet, &r);
-  }
+  entry_load_text (sheet);
 
   sheet->range.row0 = row;
   sheet->range.col0 = col;
@@ -2577,15 +2635,16 @@ change_active_cell (GtkSheet *sheet, gint row, gint col)
 
   GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
 
+  GTK_WIDGET_UNSET_FLAGS (sheet->entry_widget, GTK_HAS_FOCUS);
+
   gtk_sheet_draw_active_cell (sheet);
   gtk_sheet_show_entry_widget (sheet);
 
+  GTK_WIDGET_SET_FLAGS (sheet->entry_widget, GTK_HAS_FOCUS);
 
   g_signal_emit (sheet, sheet_signals [ACTIVATE], 0,
                 row, col, old_row, old_col);
 
-  if ( old_handler_id == sheet->entry_handler_id)
-    g_signal_handler_unblock   (sheet->entry_widget, sheet->entry_handler_id);
 }
 
 static void
@@ -2593,10 +2652,9 @@ gtk_sheet_show_entry_widget (GtkSheet *sheet)
 {
   GtkEntry *sheet_entry;
   GtkSheetCellAttr attributes;
-  gchar *text = NULL;
+
   gint row, col;
 
-  g_return_if_fail (sheet != NULL);
   g_return_if_fail (GTK_IS_SHEET (sheet));
 
   row = sheet->active_cell.row;
@@ -2616,29 +2674,33 @@ gtk_sheet_show_entry_widget (GtkSheet *sheet)
 
   gtk_sheet_get_attributes (sheet, row, col, &attributes);
 
-
-  text = gtk_sheet_cell_get_text (sheet, row, col);
-  if ( ! text )
-    text = g_strdup ("");
-
-  if ( GTK_IS_ENTRY (sheet_entry))
+  if (GTK_IS_ENTRY (sheet_entry))
     {
+      gchar *text = gtk_sheet_cell_get_text (sheet, row, col);
       const gchar *old_text = gtk_entry_get_text (GTK_ENTRY (sheet_entry));
+
+      if ( ! text )
+       text = g_strdup ("");
+
       if (strcmp (old_text, text) != 0)
        gtk_entry_set_text (sheet_entry, text);
+      
+      dispose_string (sheet, text);
 
-      switch (attributes.justification)
        {
-       case GTK_JUSTIFY_RIGHT:
-         gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 1.0);
-         break;
-       case GTK_JUSTIFY_CENTER:
-         gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 0.5);
-         break;
-       case GTK_JUSTIFY_LEFT:
-       default:
-         gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 0.0);
-         break;
+         switch (attributes.justification)
+           {
+           case GTK_JUSTIFY_RIGHT:
+             gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 1.0);
+             break;
+           case GTK_JUSTIFY_CENTER:
+             gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 0.5);
+             break;
+           case GTK_JUSTIFY_LEFT:
+           default:
+             gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 0.0);
+             break;
+           }
        }
     }
 
@@ -2648,8 +2710,6 @@ gtk_sheet_show_entry_widget (GtkSheet *sheet)
                            g_sheet_model_is_editable (sheet->model,
                                                       row, col));
   gtk_widget_map (sheet->entry_widget);
-
-  dispose_string (sheet, text);
 }
 
 static gboolean
@@ -3046,15 +3106,10 @@ static gint
 gtk_sheet_expose (GtkWidget *widget,
                  GdkEventExpose *event)
 {
-  GtkSheet *sheet;
-  GtkSheetRange range;
+  GtkSheet *sheet = GTK_SHEET (widget);
 
-  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);
-
   if (!GTK_WIDGET_DRAWABLE (widget))
     return FALSE;
 
@@ -3075,33 +3130,11 @@ gtk_sheet_expose (GtkWidget *widget,
                                       max_visible_column (sheet));
     }
 
-
-  {
-    gint y = event->area.y + sheet->vadjustment->value;
-    gint x = event->area.x + sheet->hadjustment->value;
-
-    if ( sheet->column_titles_visible)
-      y -= sheet->column_title_area.height;
-
-    if ( sheet->row_titles_visible)
-      x -= sheet->row_title_area.width;
-
-    maximize_int (&x, 0);
-    maximize_int (&y, 0);
-
-    range.row0 = row_from_ypixel (sheet, y);
-
-    range.rowi = row_from_ypixel (sheet, y + event->area.height);
-
-    range.col0 = column_from_xpixel (sheet, x);
-
-    range.coli = column_from_xpixel (sheet, x + event->area.width);
-  }
-
   if (event->window == sheet->sheet_window)
     {
-      gtk_sheet_range_draw (sheet, &range);
+      draw_sheet_region (sheet, event->region);
 
+#if 0
       if (sheet->state != GTK_SHEET_NORMAL)
        {
          if (gtk_sheet_range_isvisible (sheet, &sheet->range))
@@ -3115,12 +3148,24 @@ gtk_sheet_expose (GtkWidget *widget,
          if (GTK_SHEET_IN_RESIZE (sheet) || GTK_SHEET_IN_DRAG (sheet))
            draw_xor_rectangle (sheet, sheet->drag_range);
        }
+#endif
 
       if ((!GTK_SHEET_IN_XDRAG (sheet)) && (!GTK_SHEET_IN_YDRAG (sheet)))
        {
-         if (sheet->state == GTK_SHEET_NORMAL)
-           g_idle_add (gtk_sheet_draw_active_cell, sheet);
+         GdkRectangle rect;
+         GtkSheetRange range;
+         range.row0 = range.rowi =  sheet->active_cell.row;
+         range.col0 = range.coli =  sheet->active_cell.col;
+
+         rectangle_from_range (sheet, &range, &rect);
+
+         if (GDK_OVERLAP_RECTANGLE_OUT !=
+             gdk_region_rect_in (event->region, &rect))
+           {
+             gtk_sheet_draw_active_cell (sheet);
+           }
        }
+
     }
 
   (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
@@ -3418,8 +3463,6 @@ gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column)
   sheet->state = GTK_SHEET_NORMAL;
   GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
 
-  gtk_sheet_draw_active_cell (sheet);
-
   gtk_widget_grab_focus (GTK_WIDGET (sheet->entry_widget));
 
   return TRUE;
@@ -3443,9 +3486,9 @@ gtk_sheet_button_release (GtkWidget *widget,
       gdk_display_pointer_ungrab (display, event->time);
       draw_xor_vline (sheet);
 
-      width = event->x - 
-       psppire_axis_start_pixel (sheet->haxis, sheet->drag_cell.col) -
-       sheet->hadjustment->value;
+      width = event->x -
+       psppire_axis_start_pixel (sheet->haxis, sheet->drag_cell.col)
+       sheet->hadjustment->value;
 
       set_column_width (sheet, sheet->drag_cell.col, width);
 
@@ -3462,7 +3505,7 @@ gtk_sheet_button_release (GtkWidget *widget,
       draw_xor_hline (sheet);
 
       height = event->y -
-       psppire_axis_start_pixel (sheet->vaxis, sheet->drag_cell.row) -
+       psppire_axis_start_pixel (sheet->vaxis, sheet->drag_cell.row) +
        sheet->vadjustment->value;
 
       set_row_height (sheet, sheet->drag_cell.row, height);
@@ -4552,12 +4595,6 @@ create_sheet_entry (GtkSheet *sheet)
                            G_CALLBACK (gtk_sheet_entry_key_press),
                            sheet);
 
-  sheet->entry_handler_id =
-    g_signal_connect (sheet->entry_widget,
-                     "changed",
-                     G_CALLBACK (gtk_sheet_entry_changed),
-                     sheet);
-
   set_entry_widget_font (sheet);
 
   gtk_widget_show (sheet->entry_widget);
@@ -4913,7 +4950,6 @@ vadjustment_value_changed (GtkAdjustment *adjustment,
 
   if ( ! GTK_WIDGET_REALIZED (sheet)) return;
 
-
   gtk_widget_hide (sheet->entry_widget);
 
   region =
@@ -4921,13 +4957,14 @@ vadjustment_value_changed (GtkAdjustment *adjustment,
 
   gdk_window_begin_paint_region (sheet->sheet_window, region);
 
+  draw_sheet_region (sheet, region);
 
-  gtk_sheet_range_draw (sheet, NULL);
   draw_row_title_buttons (sheet);
   //  size_allocate_global_button (sheet);
   gtk_sheet_draw_active_cell (sheet);
 
   gdk_window_end_paint (sheet->sheet_window);
+  gdk_region_destroy (region);
 }
 
 
@@ -4950,13 +4987,16 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
 
   gdk_window_begin_paint_region (sheet->sheet_window, region);
 
-  gtk_sheet_range_draw (sheet, NULL);
+  draw_sheet_region (sheet, region);
+
   draw_column_title_buttons (sheet);
   //  size_allocate_global_button (sheet);
 
   gtk_sheet_draw_active_cell (sheet);
 
   gdk_window_end_paint (sheet->sheet_window);
+
+  gdk_region_destroy (region);
 }
 
 
@@ -5063,7 +5103,7 @@ draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range)
 static void
 set_column_width (GtkSheet *sheet,
                  gint column,
-                 guint width)
+                 gint width)
 {
   g_return_if_fail (sheet != NULL);
   g_return_if_fail (GTK_IS_SHEET (sheet));
@@ -5071,6 +5111,9 @@ set_column_width (GtkSheet *sheet,
   if (column < 0 || column >= psppire_axis_unit_count (sheet->haxis))
     return;
 
+  if ( width <= 0)
+    return;
+
   psppire_axis_resize (sheet->haxis, column, width);
 
   if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
@@ -5078,14 +5121,14 @@ set_column_width (GtkSheet *sheet,
       draw_column_title_buttons (sheet);
       adjust_scrollbars (sheet);
       gtk_sheet_size_allocate_entry (sheet);
-      gtk_sheet_range_draw (sheet, NULL);
+      redraw_range (sheet, NULL);
     }
 }
 
 static void
 set_row_height (GtkSheet *sheet,
                gint row,
-               guint height)
+               gint height)
 {
   g_return_if_fail (sheet != NULL);
   g_return_if_fail (GTK_IS_SHEET (sheet));
@@ -5093,6 +5136,9 @@ set_row_height (GtkSheet *sheet,
   if (row < 0 || row >= psppire_axis_unit_count (sheet->vaxis))
     return;
 
+  if (height <= 0)
+    return;
+
   psppire_axis_resize (sheet->vaxis, row, height);
 
   if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) )
@@ -5100,7 +5146,7 @@ set_row_height (GtkSheet *sheet,
       draw_row_title_buttons (sheet);
       adjust_scrollbars (sheet);
       gtk_sheet_size_allocate_entry (sheet);
-      gtk_sheet_range_draw (sheet, NULL);
+      redraw_range (sheet, NULL);
     }
 }