Fixed bug which manifested itself in the text import dialog
[pspp-builds.git] / lib / gtksheet / gtksheet.c
index 7569eefe728d3b901d626a857fd713b3be2bbc64..658061510a7b4757891a28c65b3239e72c0a4eda 100644 (file)
@@ -91,6 +91,7 @@ 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,
@@ -421,7 +422,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);
 
@@ -477,12 +478,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 +669,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 +691,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 +719,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);
 }
@@ -1099,6 +1129,10 @@ 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
@@ -1265,8 +1299,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);
@@ -1601,7 +1636,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)
@@ -1611,24 +1646,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
@@ -1734,8 +1779,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);
 
@@ -1856,6 +1899,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
@@ -2162,6 +2208,7 @@ draw_sheet_region (GtkSheet *sheet, GdkRegion *region)
       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 &&
@@ -2265,7 +2312,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);
@@ -2493,20 +2544,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;
@@ -2514,9 +2559,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)
@@ -2525,9 +2567,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;
 }
 
 
@@ -2572,6 +2611,8 @@ change_active_cell (GtkSheet *sheet, gint row, gint col)
   /* Erase the old cell */
   gtk_sheet_draw_active_cell (sheet);
 
+  entry_load_text (sheet);
+
   sheet->range.row0 = row;
   sheet->range.col0 = col;
   sheet->range.rowi = row;
@@ -2583,9 +2624,12 @@ 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);
@@ -2597,10 +2641,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;
@@ -2620,29 +2663,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;
+           }
        }
     }
 
@@ -2652,8 +2699,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
@@ -4539,11 +4584,6 @@ create_sheet_entry (GtkSheet *sheet)
                            G_CALLBACK (gtk_sheet_entry_key_press),
                            sheet);
 
-  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);