fixed scrolling of edited cell - fixes bug #45113
[pspp] / src / ui / gui / pspp-sheet-view.c
index ccdbd10e9919b5d61cbc059bd6d4c7284c66e277..138f86fd4213df848fec6491d71e2238aef1e39e 100644 (file)
@@ -93,10 +93,8 @@ typedef struct _PsppSheetViewChild PsppSheetViewChild;
 struct _PsppSheetViewChild
 {
   GtkWidget *widget;
-  gint x;
-  gint y;
-  gint width;
-  gint height;
+  PsppSheetViewColumn *column;
+  int node;
 };
 
 
@@ -199,8 +197,7 @@ static gint     pspp_sheet_view_focus_out            (GtkWidget        *widget,
 static gint     pspp_sheet_view_focus                (GtkWidget        *widget,
                                                    GtkDirectionType  direction);
 static void     pspp_sheet_view_grab_focus           (GtkWidget        *widget);
-static void     pspp_sheet_view_style_set            (GtkWidget        *widget,
-                                                   GtkStyle         *previous_style);
+static void     pspp_sheet_view_style_updated        (GtkWidget        *widget);
 static void     pspp_sheet_view_grab_notify          (GtkWidget        *widget,
                                                    gboolean          was_grabbed);
 static void     pspp_sheet_view_state_changed        (GtkWidget        *widget,
@@ -403,10 +400,8 @@ static void     pspp_sheet_view_search_init               (GtkWidget        *ent
                                                         PsppSheetView      *tree_view);
 static void     pspp_sheet_view_put                       (PsppSheetView      *tree_view,
                                                         GtkWidget        *child_widget,
-                                                        gint              x,
-                                                        gint              y,
-                                                        gint              width,
-                                                        gint              height);
+                                                        GtkTreePath *path,
+                                                        PsppSheetViewColumn *column);
 static gboolean pspp_sheet_view_start_editing             (PsppSheetView      *tree_view,
                                                         GtkTreePath      *cursor_path);
 static gboolean pspp_sheet_view_editable_button_press_event (GtkWidget *,
@@ -538,7 +533,7 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class)
   widget_class->drag_data_received = pspp_sheet_view_drag_data_received;
   widget_class->focus = pspp_sheet_view_focus;
   widget_class->grab_focus = pspp_sheet_view_grab_focus;
-  widget_class->style_set = pspp_sheet_view_style_set;
+  widget_class->style_updated = pspp_sheet_view_style_updated;
   widget_class->grab_notify = pspp_sheet_view_grab_notify;
   widget_class->state_changed = pspp_sheet_view_state_changed;
 
@@ -1122,6 +1117,8 @@ pspp_sheet_view_init (PsppSheetView *tree_view)
 
   pspp_sheet_view_do_set_vadjustment (tree_view, NULL);
   pspp_sheet_view_do_set_hadjustment (tree_view, NULL);
+  gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (tree_view)),
+                               GTK_STYLE_CLASS_VIEW);
 }
 
 \f
@@ -1501,15 +1498,14 @@ pspp_sheet_view_realize (GtkWidget *widget)
 {
   PsppSheetView *tree_view = PSPP_SHEET_VIEW (widget);
   GList *tmp_list;
+  GdkWindow *window;
   GdkWindowAttr attributes;
   gint attributes_mask;
   GtkAllocation allocation;
-  GtkAllocation old_allocation;
 
   gtk_widget_set_realized (widget, TRUE);
 
   gtk_widget_get_allocation (widget, &allocation);
-  gtk_widget_get_allocation (widget, &old_allocation);
 
   /* Make the main, clipping window */
   attributes.window_type = GDK_WINDOW_CHILD;
@@ -1523,16 +1519,22 @@ pspp_sheet_view_realize (GtkWidget *widget)
 
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 
-  gtk_widget_set_window (widget,
-                        gdk_window_new (gtk_widget_get_parent_window (widget),
-                                        &attributes, attributes_mask));
-  gdk_window_set_user_data (gtk_widget_get_window (widget), widget);
+  window = gdk_window_new (gtk_widget_get_parent_window (widget),
+                           &attributes, attributes_mask);
+  gtk_widget_set_window (widget, window);
+
+#if GTK_CHECK_VERSION(3,8,0)
+  gtk_widget_register_window (widget, window);
+#else
+  gdk_window_set_user_data (window, widget);
+#endif
+  gtk_widget_get_allocation (widget, &allocation);
 
   /* Make the window for the tree */
   attributes.x = 0;
   attributes.y = TREE_VIEW_HEADER_HEIGHT (tree_view);
-  attributes.width = MAX (tree_view->priv->width, old_allocation.width);
-  attributes.height = old_allocation.height;
+  attributes.width = MAX (tree_view->priv->width, allocation.width);
+  attributes.height = allocation.height;
   attributes.event_mask = (GDK_EXPOSURE_MASK |
                            GDK_SCROLL_MASK |
                            GDK_POINTER_MOTION_MASK |
@@ -1542,14 +1544,19 @@ pspp_sheet_view_realize (GtkWidget *widget)
                            GDK_BUTTON_RELEASE_MASK |
                            gtk_widget_get_events (widget));
 
-  tree_view->priv->bin_window = gdk_window_new (gtk_widget_get_window (widget),
+  tree_view->priv->bin_window = gdk_window_new (window,
                                                &attributes, attributes_mask);
+#if GTK_CHECK_VERSION(3,8,0)
+  gtk_widget_register_window (widget, tree_view->priv->bin_window);
+#else
   gdk_window_set_user_data (tree_view->priv->bin_window, widget);
+#endif
+  gtk_widget_get_allocation (widget, &allocation);
 
   /* Make the column header window */
   attributes.x = 0;
   attributes.y = 0;
-  attributes.width = MAX (tree_view->priv->width, old_allocation.width);
+  attributes.width = MAX (tree_view->priv->width, allocation.width);
   attributes.height = tree_view->priv->header_height;
   attributes.event_mask = (GDK_EXPOSURE_MASK |
                            GDK_SCROLL_MASK |
@@ -1559,15 +1566,22 @@ pspp_sheet_view_realize (GtkWidget *widget)
                            GDK_KEY_RELEASE_MASK |
                            gtk_widget_get_events (widget));
 
-  tree_view->priv->header_window = gdk_window_new (gtk_widget_get_window (widget),
+  tree_view->priv->header_window = gdk_window_new (window,
                                                   &attributes, attributes_mask);
+#if GTK_CHECK_VERSION(3,8,0)
+  gtk_widget_register_window (widget, tree_view->priv->header_window);
+#else
   gdk_window_set_user_data (tree_view->priv->header_window, widget);
+#endif
+
+  { /* Ensure Background */
+    GtkStyleContext *context;
 
-  /* Add them all up. */
-  gtk_widget_set_style (widget,
-                      gtk_style_attach (gtk_widget_get_style (widget), gtk_widget_get_window (widget)));
-  gdk_window_set_background (tree_view->priv->bin_window, &gtk_widget_get_style (widget)->base[gtk_widget_get_state (widget)]);
-  gtk_style_set_background (gtk_widget_get_style (widget), tree_view->priv->header_window, GTK_STATE_NORMAL);
+    context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
+
+    gtk_style_context_set_background (context, gtk_widget_get_window (GTK_WIDGET (tree_view)));
+    gtk_style_context_set_background (context, tree_view->priv->header_window);
+  }
 
   tmp_list = tree_view->priv->children;
   while (tmp_list)
@@ -1979,12 +1993,6 @@ pspp_sheet_view_size_allocate_columns (GtkWidget *widget,
 
       pspp_sheet_view_column_size_allocate (column, &col_allocation);
 
-      if (span_intersects (col_allocation.x, col_allocation.width,
-                           gtk_adjustment_get_value (tree_view->priv->hadjustment),
-                           allocation.width)
-          && gtk_widget_get_realized (widget))
-        pspp_sheet_view_column_set_need_button (column, TRUE);
-
       if (column->window)
        gdk_window_move_resize (column->window,
                                 col_allocation.x + (rtl ? 0 : col_allocation.width) - TREE_VIEW_DRAG_WIDTH/2,
@@ -2003,6 +2011,24 @@ pspp_sheet_view_size_allocate_columns (GtkWidget *widget,
     gtk_widget_queue_draw (GTK_WIDGET (tree_view));
 }
 
+static void
+update_childrens_allocation (PsppSheetView *tree_view)
+{
+  GList *tmp_list;
+  for (tmp_list = tree_view->priv->children; tmp_list; tmp_list = tmp_list->next)
+    {
+      PsppSheetViewChild *child = tmp_list->data;
+      GtkAllocation allocation;
+      GtkTreePath *path;
+
+      /* totally ignore our child's requisition */
+      path = _pspp_sheet_view_find_path (tree_view, child->node);
+      pspp_sheet_view_get_cell_area (tree_view, path, child->column, &allocation);
+      gtk_tree_path_free (path);
+      gtk_widget_size_allocate (child->widget, &allocation);
+    }
+}
+
 static void
 pspp_sheet_view_size_allocate (GtkWidget     *widget,
                             GtkAllocation *allocation)
@@ -2016,26 +2042,8 @@ pspp_sheet_view_size_allocate (GtkWidget     *widget,
   if (allocation->width != old_allocation.width)
     width_changed = TRUE;
 
-
   gtk_widget_set_allocation (widget, allocation);
 
-  tmp_list = tree_view->priv->children;
-
-  while (tmp_list)
-    {
-      GtkAllocation allocation;
-
-      PsppSheetViewChild *child = tmp_list->data;
-      tmp_list = tmp_list->next;
-
-      /* totally ignore our child's requisition */
-      allocation.x = child->x;
-      allocation.y = child->y;
-      allocation.width = child->width;
-      allocation.height = child->height;
-      gtk_widget_size_allocate (child->widget, &allocation);
-    }
-
   /* We size-allocate the columns first because the width of the
    * tree view (used in updating the adjustments below) might change.
    */
@@ -2135,6 +2143,7 @@ pspp_sheet_view_size_allocate (GtkWidget     *widget,
          else
            gtk_widget_queue_draw (widget);
        }
+      update_childrens_allocation(tree_view);
     }
 }
 
@@ -3862,9 +3871,9 @@ pspp_sheet_view_draw_vertical_grid_lines (PsppSheetView    *tree_view,
  * KEEP IN SYNC WITH pspp_sheet_view_create_row_drag_icon()!
  * FIXME: It's not...
  */
-static gboolean
-pspp_sheet_view_bin_expose (GtkWidget      *widget,
-                           cairo_t *cr)
+static void
+pspp_sheet_view_draw_bin (GtkWidget      *widget,
+                         cairo_t *cr)
 {
   PsppSheetView *tree_view = PSPP_SHEET_VIEW (widget);
   GtkTreePath *path;
@@ -3895,11 +3904,16 @@ pspp_sheet_view_bin_expose (GtkWidget      *widget,
   gboolean row_ending_details;
   gboolean draw_vgrid_lines, draw_hgrid_lines;
   gint min_y, max_y;
+  GtkStyleContext *context;
+  context = gtk_widget_get_style_context (widget);
 
   GdkRectangle Zarea;
   GtkAllocation allocation;
   gtk_widget_get_allocation (widget, &allocation);
 
+  GdkRectangle exposed_rect;
+  gdk_cairo_get_clip_rectangle (cr, &exposed_rect);
+  
   Zarea.x =      0;
   Zarea.y =      0;
   Zarea.height = allocation.height;
@@ -3917,13 +3931,13 @@ pspp_sheet_view_bin_expose (GtkWidget      *widget,
   if (tree_view->priv->row_count == 0)
     {
       draw_empty_focus (tree_view);
-      return TRUE;
+      return;
     }
 
 #if GTK3_TRANSITION
   /* clip event->area to the visible area */
   if (Zarea.height < 0.5)
-    return TRUE;
+    return;
 #endif
 
   validate_visible_area (tree_view);
@@ -3954,7 +3968,7 @@ pspp_sheet_view_bin_expose (GtkWidget      *widget,
     }
 
   if (node < 0)
-    return TRUE;
+    return;
 
   /* find the path for the node */
   path = _pspp_sheet_view_find_path ((PsppSheetView *)widget, node);
@@ -4137,11 +4151,14 @@ pspp_sheet_view_bin_expose (GtkWidget      *widget,
 
 #if GTK3_TRANSITION
          if (gdk_region_rect_in (event->region, &background_area) == GDK_OVERLAP_RECTANGLE_OUT)
+#else
+         if (!gdk_rectangle_intersect (&background_area, &exposed_rect, NULL))
+#endif
            {
              cell_offset += column->width;
              continue;
            }
-#endif
+
 
          pspp_sheet_view_column_cell_set_cell_data (column,
                                                      tree_view->priv->model,
@@ -4190,57 +4207,24 @@ pspp_sheet_view_bin_expose (GtkWidget      *widget,
 
           g_assert (detail);
 
-         if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE)
-           state = GTK_STATE_INSENSITIVE;          
-         else if (flags & GTK_CELL_RENDERER_SELECTED)
-           state = GTK_STATE_SELECTED;
-         else
-           state = GTK_STATE_NORMAL;
+         gtk_style_context_save (context);
+         state = gtk_cell_renderer_get_state (NULL, widget, flags);
+          gtk_style_context_set_state (context, state);
+          gtk_style_context_add_class (context, GTK_STYLE_CLASS_CELL);
 
          /* Draw background */
-         if (row_ending_details)
-           {
-             char new_detail[128];
-
-             is_first = (rtl ? !list->next : !list->prev);
-             is_last = (rtl ? !list->prev : !list->next);
-
-             /* (I don't like the snprintfs either, but couldn't find a
-              * less messy way).
-              */
-             if (is_first && is_last)
-               g_snprintf (new_detail, 127, "%s", detail);
-             else if (is_first)
-               g_snprintf (new_detail, 127, "%s_start", detail);
-             else if (is_last)
-               g_snprintf (new_detail, 127, "%s_end", detail);
-             else
-               g_snprintf (new_detail, 128, "%s_middle", detail);
-
-             gtk_paint_flat_box (gtk_widget_get_style (widget),
-                                 cr,
-                                 state,
-                                 GTK_SHADOW_NONE,
-                                 widget,
-                                 new_detail,
-                                 background_area.x,
-                                 background_area.y,
-                                 background_area.width,
-                                 background_area.height);
-           }
-         else
-           {
-             gtk_paint_flat_box (gtk_widget_get_style (widget),
-                                 cr,
-                                 state,
-                                 GTK_SHADOW_NONE,
-                                 widget,
-                                 detail,
-                                 background_area.x,
-                                 background_area.y,
-                                 background_area.width,
-                                 background_area.height);
-           }
+          gtk_render_background (context, cr,
+                                 background_area.x,
+                                 background_area.y,
+                                 background_area.width,
+                                 background_area.height);
+
+          /* Draw frame */
+          gtk_render_frame (context, cr,
+                            background_area.x,
+                            background_area.y,
+                            background_area.width,
+                            background_area.height);
 
          if (draw_hgrid_lines)
            {
@@ -4286,36 +4270,11 @@ pspp_sheet_view_bin_expose (GtkWidget      *widget,
                                                &cell_area,
                                                flags);
 
-          if (node == cursor && has_special_cell &&
-             ((column == tree_view->priv->focus_column &&
-               PSPP_SHEET_VIEW_FLAG_SET (tree_view, PSPP_SHEET_VIEW_DRAW_KEYFOCUS) &&
-               gtk_widget_has_focus (widget)) ||
-              (column == tree_view->priv->edited_column)))
-           {
-             _pspp_sheet_view_column_cell_draw_focus (column,
-                                                      cr,
-                                                    &background_area,
-                                                    &cell_area,
-                                                    flags);
-           }
 
          cell_offset += column->width;
+         gtk_style_context_restore (context);
        }
 
-      if (cell_offset < Zarea.x)
-        {
-          gtk_paint_flat_box (gtk_widget_get_style (widget),
-                              cr,
-                              GTK_STATE_NORMAL,
-                              GTK_SHADOW_NONE,
-                              widget,
-                              "base",
-                              cell_offset,
-                              background_area.y,
-                              Zarea.x - cell_offset,
-                              background_area.height);
-        }
-
       if (node == drag_highlight)
         {
           /* Draw indicator for the drop
@@ -4382,54 +4341,6 @@ pspp_sheet_view_bin_expose (GtkWidget      *widget,
 #endif
         }
 
-      /* draw the big row-spanning focus rectangle, if needed */
-      if (!has_special_cell && node == cursor &&
-         PSPP_SHEET_VIEW_FLAG_SET (tree_view, PSPP_SHEET_VIEW_DRAW_KEYFOCUS) &&
-         gtk_widget_has_focus (widget))
-        {
-         gint tmp_y, tmp_height;
-         gint width;
-         GtkStateType focus_rect_state;
-
-         focus_rect_state =
-           flags & GTK_CELL_RENDERER_SELECTED ? GTK_STATE_SELECTED :
-           (flags & GTK_CELL_RENDERER_PRELIT ? GTK_STATE_PRELIGHT :
-            (flags & GTK_CELL_RENDERER_INSENSITIVE ? GTK_STATE_INSENSITIVE :
-             GTK_STATE_NORMAL));
-
-         width = gdk_window_get_width (tree_view->priv->bin_window);
-         
-         if (draw_hgrid_lines)
-           {
-             tmp_y = BACKGROUND_FIRST_PIXEL (tree_view, node) + grid_line_width / 2;
-             tmp_height = ROW_HEIGHT (tree_view) - grid_line_width;
-           }
-         else
-           {
-             tmp_y = BACKGROUND_FIRST_PIXEL (tree_view, node);
-             tmp_height = ROW_HEIGHT (tree_view);
-           }
-
-         if (row_ending_details)
-           gtk_paint_focus (gtk_widget_get_style (widget),
-                            cr,
-                            focus_rect_state,
-                            widget,
-                            (is_first
-                             ? (is_last ? "treeview" : "treeview-left" )
-                             : (is_last ? "treeview-right" : "treeview-middle" )),
-                            0, tmp_y,
-                            width, tmp_height);
-         else
-           gtk_paint_focus (gtk_widget_get_style (widget),
-                            cr,
-                            focus_rect_state,
-                            widget,
-                            "treeview",
-                            0, tmp_y,
-                            width, tmp_height);
-       }
-
       y_offset += max_height;
 
       do
@@ -4441,7 +4352,7 @@ pspp_sheet_view_bin_expose (GtkWidget      *widget,
               done = TRUE;
 
               /* Sanity Check! */
-              TREE_VIEW_INTERNAL_ASSERT (has_next, FALSE);
+              TREE_VIEW_INTERNAL_ASSERT_VOID (has_next);
             }
           else
             goto done;
@@ -4477,7 +4388,7 @@ done:
   if (drag_dest_path)
     gtk_tree_path_free (drag_dest_path);
 
-  return FALSE;
+  return;
 }
 
 
@@ -4486,17 +4397,17 @@ pspp_sheet_view_draw (GtkWidget      *widget,
                      cairo_t *cr)
 {
   PsppSheetView *tree_view = PSPP_SHEET_VIEW (widget);
-  GtkAllocation allocation;
-  gtk_widget_get_allocation (widget, &allocation);
-  
+  GtkStyleContext *context;
+
+  context = gtk_widget_get_style_context (widget);
+
   if (gtk_cairo_should_draw_window (cr, tree_view->priv->bin_window))
     {
-      gboolean retval;
       GList *tmp_list;
 
       cairo_save (cr);
-      cairo_translate (cr, 0, gdk_window_get_height (tree_view->priv->header_window));
-      retval = pspp_sheet_view_bin_expose (widget, cr);
+      gtk_cairo_transform_to_window(cr,widget,tree_view->priv->bin_window);
+      pspp_sheet_view_draw_bin (widget, cr);
       cairo_restore (cr);
 
       /* We can't just chain up to Container::expose as it will try to send the
@@ -4510,27 +4421,24 @@ pspp_sheet_view_draw (GtkWidget      *widget,
          tmp_list = tmp_list->next;
 
          gtk_container_propagate_draw (GTK_CONTAINER (tree_view), child->widget, cr);
-       }
-
-      return retval;
+        }
     }
-  else if (gtk_cairo_should_draw_window (cr, tree_view->priv->header_window))
+  else
+    {
+      gtk_render_background (context, cr,
+                             0, 0,
+                             gtk_widget_get_allocated_width (widget),
+                             gtk_widget_get_allocated_height (widget));
+    }
+
+  gtk_style_context_save (context);
+  gtk_style_context_remove_class (context, GTK_STYLE_CLASS_VIEW);
+
+  if (gtk_cairo_should_draw_window (cr, tree_view->priv->header_window))
     {
       gint n_visible_columns;
       GList *list;
 
-      gtk_paint_flat_box (gtk_widget_get_style (widget),
-                          cr,
-                          GTK_STATE_NORMAL,
-                          GTK_SHADOW_NONE,
-                          widget,
-                          "cell_odd",
-                         allocation.x,
-                         allocation.y,
-                         allocation.width,
-                         allocation.height
-                         );
-
       for (list = tree_view->priv->columns; list != NULL; list = list->next)
        {
          PsppSheetViewColumn *column = list->data;
@@ -4539,7 +4447,8 @@ pspp_sheet_view_draw (GtkWidget      *widget,
            continue;
 
           if (span_intersects (column->allocation.x, column->allocation.width,
-                              allocation.x, allocation.width)
+                               (int) gtk_adjustment_get_value (tree_view->priv->hadjustment),
+                               (int) gtk_widget_get_allocated_width (widget))
               && column->button != NULL)
             gtk_container_propagate_draw (GTK_CONTAINER (tree_view),
                                          column->button, cr);
@@ -4552,23 +4461,24 @@ pspp_sheet_view_draw (GtkWidget      *widget,
             continue;
           n_visible_columns ++;
         }
+      cairo_save (cr);
+      gtk_cairo_transform_to_window(cr,widget,tree_view->priv->header_window);
       pspp_sheet_view_draw_vertical_grid_lines (tree_view,
                                                cr,
                                                n_visible_columns,
-                                               allocation.y,
-                                               allocation.height);
-
-      return TRUE;
+                                               0,
+                                               TREE_VIEW_HEADER_HEIGHT (tree_view));
+      cairo_restore (cr);
     }
-  else if (gtk_cairo_should_draw_window (cr, tree_view->priv->drag_window))
+  if (tree_view->priv->drag_window &&
+      gtk_cairo_should_draw_window (cr, tree_view->priv->drag_window))
     {
       gtk_container_propagate_draw (GTK_CONTAINER (tree_view),
                                    tree_view->priv->drag_column->button,
                                    cr);
-     
-      return TRUE;
     }
 
+  gtk_style_context_restore (context);
   return FALSE;
 }
 
@@ -6723,13 +6633,6 @@ pspp_sheet_view_focus_column (PsppSheetView *tree_view,
   g_return_if_fail (focus_column != NULL);
 
   tree_view->priv->focus_column = focus_column;
-  if (!focus_column->button)
-    {
-      pspp_sheet_view_column_set_need_button (focus_column, TRUE);
-      //      g_return_if_fail (focus_column->button != NULL);
-      if (focus_column->button == NULL)
-       return;
-    }
 
   if (gtk_container_get_focus_child (GTK_CONTAINER (tree_view)) != focus_column->button)
     gtk_widget_grab_focus (focus_column->button);
@@ -6860,7 +6763,6 @@ pspp_sheet_view_header_focus (PsppSheetView      *tree_view,
           if (column->visible &&
              pspp_sheet_view_column_can_focus (column))
             {
-              pspp_sheet_view_column_set_need_button (column, TRUE);
               if (column->button)
                 {
                   pspp_sheet_view_focus_column (tree_view, column,
@@ -6971,17 +6873,20 @@ pspp_sheet_view_grab_focus (GtkWidget *widget)
 }
 
 static void
-pspp_sheet_view_style_set (GtkWidget *widget,
-                        GtkStyle *previous_style)
+pspp_sheet_view_style_updated (GtkWidget *widget)
 {
   PsppSheetView *tree_view = PSPP_SHEET_VIEW (widget);
   GList *list;
   PsppSheetViewColumn *column;
+  GtkStyleContext *context;
+
+  GTK_WIDGET_CLASS (pspp_sheet_view_parent_class)->style_updated (widget);
 
   if (gtk_widget_get_realized (widget))
     {
-      gdk_window_set_background (tree_view->priv->bin_window, &gtk_widget_get_style (widget)->base[gtk_widget_get_state (widget)]);
-      gtk_style_set_background (gtk_widget_get_style (widget), tree_view->priv->header_window, GTK_STATE_NORMAL);
+      context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
+      gtk_style_context_set_background (context, gtk_widget_get_window (GTK_WIDGET (tree_view)));
+      gtk_style_context_set_background (context, tree_view->priv->header_window);
       pspp_sheet_view_set_grid_lines (tree_view, tree_view->priv->grid_lines);
     }
 
@@ -7153,12 +7058,9 @@ pspp_sheet_view_real_move_cursor (PsppSheetView       *tree_view,
 
 static void
 pspp_sheet_view_put (PsppSheetView *tree_view,
-                  GtkWidget   *child_widget,
-                  /* in bin_window coordinates */
-                  gint         x,
-                  gint         y,
-                  gint         width,
-                  gint         height)
+                    GtkWidget   *child_widget,
+                    GtkTreePath *path,
+                    PsppSheetViewColumn *column)
 {
   PsppSheetViewChild *child;
   
@@ -7168,10 +7070,12 @@ pspp_sheet_view_put (PsppSheetView *tree_view,
   child = g_slice_new (PsppSheetViewChild);
 
   child->widget = child_widget;
-  child->x = x;
-  child->y = y;
-  child->width = width;
-  child->height = height;
+  _pspp_sheet_view_find_node (tree_view, path, &child->node);
+  if (child->node < 0)
+    {
+      g_assert_not_reached ();
+    }
+  child->column = column;
 
   tree_view->priv->children = g_list_append (tree_view->priv->children, child);
 
@@ -7181,43 +7085,6 @@ pspp_sheet_view_put (PsppSheetView *tree_view,
   gtk_widget_set_parent (child_widget, GTK_WIDGET (tree_view));
 }
 
-void
-_pspp_sheet_view_child_move_resize (PsppSheetView *tree_view,
-                                 GtkWidget   *widget,
-                                 /* in tree coordinates */
-                                 gint         x,
-                                 gint         y,
-                                 gint         width,
-                                 gint         height)
-{
-  PsppSheetViewChild *child = NULL;
-  GList *list;
-  GdkRectangle allocation;
-
-  g_return_if_fail (PSPP_IS_SHEET_VIEW (tree_view));
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-
-  for (list = tree_view->priv->children; list; list = list->next)
-    {
-      if (((PsppSheetViewChild *)list->data)->widget == widget)
-       {
-         child = list->data;
-         break;
-       }
-    }
-  if (child == NULL)
-    return;
-
-  allocation.x = child->x = x;
-  allocation.y = child->y = y;
-  allocation.width = child->width = width;
-  allocation.height = child->height = height;
-
-  if (gtk_widget_get_realized (widget))
-    gtk_widget_size_allocate (widget, &allocation);
-}
-
-
 /* TreeModel Callbacks
  */
 
@@ -8873,79 +8740,6 @@ pspp_sheet_view_new_column_width (PsppSheetView *tree_view,
   return width;
 }
 
-
-/* FIXME this adjust_allocation is a big cut-and-paste from
- * GtkCList, needs to be some "official" way to do this
- * factored out.
- */
-typedef struct
-{
-  GdkWindow *window;
-  int dx;
-  int dy;
-} ScrollData;
-
-/* The window to which gtk_widget_get_window (widget) is relative */
-#define ALLOCATION_WINDOW(widget)              \
-   (!gtk_widget_get_has_window (widget) ?              \
-    gtk_widget_get_window (widget) :                          \
-    gdk_window_get_parent (gtk_widget_get_window (widget)))
-
-static void
-adjust_allocation_recurse (GtkWidget *widget,
-                          gpointer   data)
-{
-  ScrollData *scroll_data = data;
-  GtkAllocation allocation;
-  gtk_widget_get_allocation (widget, &allocation);
-  /* Need to really size allocate instead of just poking
-   * into widget->allocation if the widget is not realized.
-   * FIXME someone figure out why this was.
-   */
-  if (!gtk_widget_get_realized (widget))
-    {
-      if (gtk_widget_get_visible (widget))
-       {
-         GdkRectangle tmp_rectangle = allocation;
-         tmp_rectangle.x += scroll_data->dx;
-          tmp_rectangle.y += scroll_data->dy;
-          
-         gtk_widget_size_allocate (widget, &tmp_rectangle);
-       }
-    }
-  else
-    {
-      if (ALLOCATION_WINDOW (widget) == scroll_data->window)
-       {
-         allocation.x += scroll_data->dx;
-          allocation.y += scroll_data->dy;
-          
-         if (GTK_IS_CONTAINER (widget))
-           gtk_container_forall (GTK_CONTAINER (widget),
-                                 adjust_allocation_recurse,
-                                 data);
-       }
-    }
-}
-
-static void
-adjust_allocation (GtkWidget *widget,
-                  int        dx,
-                   int        dy)
-{
-  ScrollData scroll_data;
-
-  if (gtk_widget_get_realized (widget))
-    scroll_data.window = ALLOCATION_WINDOW (widget);
-  else
-    scroll_data.window = NULL;
-    
-  scroll_data.dx = dx;
-  scroll_data.dy = dy;
-  
-  adjust_allocation_recurse (widget, &scroll_data);
-}
-
 void 
 pspp_sheet_view_column_update_button (PsppSheetViewColumn *tree_column);
 
@@ -8956,9 +8750,8 @@ pspp_sheet_view_adjustment_changed (GtkAdjustment *adjustment,
 {
   if (gtk_widget_get_realized (GTK_WIDGET (tree_view)))
     {
-      GList *list;
       gint dy;
-       
+
       gdk_window_move (tree_view->priv->bin_window,
                       - gtk_adjustment_get_value (tree_view->priv->hadjustment),
                       TREE_VIEW_HEADER_HEIGHT (tree_view));
@@ -8966,65 +8759,26 @@ pspp_sheet_view_adjustment_changed (GtkAdjustment *adjustment,
                       - gtk_adjustment_get_value (tree_view->priv->hadjustment),
                       0);
       dy = tree_view->priv->dy - (int) gtk_adjustment_get_value (tree_view->priv->vadjustment);
-      if (dy)
-       {
-          update_prelight (tree_view,
-                           tree_view->priv->event_last_x,
-                           tree_view->priv->event_last_y - dy);
-
-         if (tree_view->priv->edited_column &&
-              GTK_IS_WIDGET (tree_view->priv->edited_column->editable_widget))
-           {
-             GList *list;
-             GtkWidget *widget;
-             PsppSheetViewChild *child = NULL;
 
-             widget = GTK_WIDGET (tree_view->priv->edited_column->editable_widget);
-             adjust_allocation (widget, 0, dy); 
-             
-             for (list = tree_view->priv->children; list; list = list->next)
-               {
-                 child = (PsppSheetViewChild *)list->data;
-                 if (child->widget == widget)
-                   {
-                     child->y += dy;
-                     break;
-                   }
-               }
-           }
-       }
       gdk_window_scroll (tree_view->priv->bin_window, 0, dy);
 
-      if (tree_view->priv->dy != (int) gtk_adjustment_get_value (tree_view->priv->vadjustment))
+      if (dy != 0)
         {
           /* update our dy and top_row */
           tree_view->priv->dy = (int) gtk_adjustment_get_value (tree_view->priv->vadjustment);
 
+         update_prelight (tree_view,
+                           tree_view->priv->event_last_x,
+                           tree_view->priv->event_last_y);
+
           if (!tree_view->priv->in_top_row_to_dy)
             pspp_sheet_view_dy_to_top_row (tree_view);
        }
 
-      for (list = tree_view->priv->columns; list; list = list->next)
-        {
-          PsppSheetViewColumn *column = list->data;
-          GtkAllocation *col_allocation = &column->allocation;
-         GtkAllocation widget_allocation;
-         gtk_widget_get_allocation (GTK_WIDGET (tree_view), &widget_allocation);
-
-          if (span_intersects (col_allocation->x, col_allocation->width,
-                               gtk_adjustment_get_value (tree_view->priv->hadjustment),
-                               widget_allocation.width))
-            {
-              pspp_sheet_view_column_set_need_button (column, TRUE);
-              if (!column->button)
-                pspp_sheet_view_column_update_button (column);
-            }
-        }
+      update_childrens_allocation(tree_view);
     }
 }
 
-\f
-
 /* Public methods
  */
 
@@ -12707,25 +12461,12 @@ pspp_sheet_view_real_start_editing (PsppSheetView       *tree_view,
   pspp_sheet_selection_select_column (tree_view->priv->selection, column);
   tree_view->priv->anchor_column = column;
 
-  gtk_widget_size_request (GTK_WIDGET (cell_editable), &requisition);
-
   PSPP_SHEET_VIEW_SET_FLAG (tree_view, PSPP_SHEET_VIEW_DRAW_KEYFOCUS);
 
-  if (requisition.height < cell_area->height)
-    {
-      gint diff = cell_area->height - requisition.height;
-      pspp_sheet_view_put (tree_view,
-                        GTK_WIDGET (cell_editable),
-                        cell_area->x, cell_area->y + diff/2,
-                        cell_area->width, requisition.height);
-    }
-  else
-    {
-      pspp_sheet_view_put (tree_view,
-                        GTK_WIDGET (cell_editable),
-                        cell_area->x, cell_area->y,
-                        cell_area->width, cell_area->height);
-    }
+  pspp_sheet_view_put (tree_view,
+                      GTK_WIDGET (cell_editable),
+                      path,
+                      column);
 
   gtk_cell_editable_start_editing (GTK_CELL_EDITABLE (cell_editable),
                                   (GdkEvent *)event);