Fixed some memory leaks in GUI.
authorJohn Darrington <john@darrington.wattle.id.au>
Sun, 14 May 2006 00:01:39 +0000 (00:01 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Sun, 14 May 2006 00:01:39 +0000 (00:01 +0000)
lib/gtksheet/ChangeLog
lib/gtksheet/gsheetmodel.c
lib/gtksheet/gsheetmodel.h
lib/gtksheet/gtksheet.c
lib/gtksheet/gtksheet.h
src/ui/gui/ChangeLog
src/ui/gui/data-sheet.c
src/ui/gui/helper.c
src/ui/gui/helper.h
src/ui/gui/psppire-data-store.c
src/ui/gui/psppire-var-store.c

index 2d2cfd043b6a114b6c7cf7a93e5cacb5faf4d232..32d1273602c68a383ca5d80e15f3c606e51e187f 100644 (file)
@@ -1,3 +1,9 @@
+Sat May 13 07:58:32 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+        * gsheetmodel.c gsheetmodel.h gtksheet.c gtksheeet.h: Added
+       free_strings flag to tell the sheet whether to free the string
+       data passed from the model.
+
 Thu May 11 22:20:04 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
     * gtksheet.c, gtksheet.h: Fixed broken deallocation of sheet->pixmap.
index 3f0665784a6a5a485d03e6765466b3c9b335307c..3a447188b9b7c6912dcf2e7b6956d105fed7fa11 100644 (file)
@@ -113,6 +113,23 @@ g_sheet_model_base_init (gpointer g_class)
     }
 }
 
+
+/**
+ * g_sheet_model_free_strings
+ * @sheet_model: A #GSheetModel
+ * 
+ * Returns: True if strings obtained with get_string should be freed by the 
+ * sheet when no longer required.
+ **/
+inline  gboolean 
+g_sheet_model_free_strings (const GSheetModel *sheet_model)
+{
+  g_return_val_if_fail (G_IS_SHEET_MODEL (sheet_model), FALSE);
+
+  return G_SHEET_MODEL_GET_IFACE (sheet_model)->free_strings;
+}
+
+
 /**
  * g_sheet_model_get_string:
  * @sheet_model: A #GSheetModel
@@ -122,7 +139,7 @@ g_sheet_model_base_init (gpointer g_class)
  * Retrieves the datum at location ROW, COLUMN in the form of a string.
  * Returns: The string representation of the datum, or NULL on error.
  **/
-inline const gchar *
+inline gchar *
 g_sheet_model_get_string (const GSheetModel *sheet_model, 
                          gint row, gint column)
 {
@@ -393,3 +410,6 @@ g_sheet_model_get_cell_border (const GSheetModel *model,
   return G_SHEET_MODEL_GET_IFACE (model)->get_cell_border (model, 
                                                           row, column);
 }
+
+
+
index 50746462b93db8a8efd647b92a9cb691e98933f4..4ee06836cc757fa541f6c87b2f9bf3a1611b92db 100644 (file)
@@ -15,6 +15,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
+
 #ifndef __G_SHEET_MODEL_H__
 #define __G_SHEET_MODEL_H__
 
@@ -70,6 +71,8 @@ struct _GSheetModelIface
 {
   GTypeInterface g_iface;
 
+  gboolean free_strings;
+
   /* Signals */
   void         (* range_changed)    (GSheetModel *sheet_model,
                                     gint row0, gint col0, 
@@ -82,9 +85,9 @@ struct _GSheetModelIface
                                     gint row, gint n_rows);
 
 
-
   /* Virtual Table */
-  const gchar *      (* get_string)      (const GSheetModel *sheet_model, 
+
+  gchar *      (* get_string)      (const GSheetModel *sheet_model, 
                                               gint row, gint column);
 
   gboolean  (* set_string) (GSheetModel *sheet_model, 
@@ -118,7 +121,7 @@ struct _GSheetModelIface
 GType              g_sheet_model_get_type   (void) G_GNUC_CONST;
 
 
-inline const gchar * g_sheet_model_get_string (const GSheetModel *sheet_model, 
+inline  gchar * g_sheet_model_get_string (const GSheetModel *sheet_model, 
                                               gint row, gint column);
 
 inline gboolean  g_sheet_model_set_string (GSheetModel *sheet_model, 
@@ -163,6 +166,7 @@ inline const PangoFontDescription *g_sheet_model_get_font_desc
 inline const GtkSheetCellBorder * g_sheet_model_get_cell_border 
                    (const GSheetModel *model, gint row, gint column);
 
+inline  gboolean g_sheet_model_free_strings (const GSheetModel *sheet_model);
 
 
 
index 2e9e416dc54cf7967085aab65a77bfcac4aed4d9..c7c3f7a86878d1833964183bd3fa6da5830b064b 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+.
@@ -101,8 +101,19 @@ enum
 #define DEFAULT_COLUMN_WIDTH 80
 
 
+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) 
@@ -1488,21 +1499,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;
 
-  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) )
     {
@@ -3054,7 +3067,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);
 
@@ -3091,6 +3104,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);
@@ -3130,7 +3144,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, 
@@ -3149,7 +3163,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, 
@@ -3158,7 +3172,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, 
@@ -3176,7 +3190,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, 
@@ -3506,7 +3520,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;
@@ -3530,14 +3544,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;
@@ -3609,7 +3628,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 )
     {
@@ -3620,6 +3639,7 @@ gtk_sheet_real_cell_clear (GtkSheet *sheet, gint row, gint column, gboolean dele
                        row, column);
     }  
 
+  dispose_string (sheet, old_text);
 }
     
 void
@@ -3670,8 +3690,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);
@@ -4051,9 +4084,9 @@ 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);
 
@@ -4081,7 +4114,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
@@ -6431,10 +6464,10 @@ gtk_sheet_button_draw (GtkSheet *sheet, gint row, gint column)
      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);
+    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){
 
index 3fecbc926267849a813d4960d6f9ed05c698614b..18c39f250c9af8a120652808d16fb39f53884f49 100644 (file)
@@ -540,8 +540,8 @@ gtk_sheet_set_cell_text                     (GtkSheet *sheet,
                                        gint row, gint col,
                                        const gchar *text);
 /* get cell contents */
-const gchar *     
-gtk_sheet_cell_get_text                (GtkSheet *sheet, gint row, gint col);
+gchar *     
+gtk_sheet_cell_get_text                (const GtkSheet *sheet, gint row, gint col);
 
 /* clear cell contents */
 void 
index 6aba2cf8d67d9e2b924a684a4538e48d582fe249..c5311eded30b1201c09120e725805e65f2fd31ff 100644 (file)
@@ -1,3 +1,11 @@
+Sat May 13 08:00:50 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * data-sheet.c, helper.c, helper.h, psppire-data-store.c, 
+          psppire-var-store.c:
+         
+         Set free_strings flag so that the gtksheet frees the string data 
+         when it's done with them.
+
 Thu May 11 22:25:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
        * data-sheet.c helper.c helper.h psppire-data-store.c psppire-var-store.c 
index 20869dcb0b0939466fdb16e3847779a83c8ca547..a9d980ded2e74a584dd9d34d0f5ed9601f44d772 100644 (file)
@@ -85,7 +85,7 @@ click2column(GtkWidget *w, gint col, gpointer data)
 
 /* Update the data_ref_entry with the reference of the active cell */
 static gint 
-update_data_ref_entry(GtkSheet *sheet, gint row, gint col)
+update_data_ref_entry(const GtkSheet *sheet, gint row, gint col)
 {
 
   /* The entry where the reference to the current cell is displayed */
index e3c4ee081a911cb4d70d81d14517cf0005b25ee3..d2defd69933a85a4063d1673b8e61c8d0f7b3462 100644 (file)
@@ -77,12 +77,12 @@ get_widget_assert(GladeXML *xml, const gchar *name)
 }
 
 /* Converts a string in the pspp locale to utf-8 */
-const char *
+char *
 pspp_locale_to_utf8(const gchar *text, gssize len, GError **err)
 {
   GError *tmp_error = 0;
 
-  const gchar *s;
+  gchar *s;
 
   if ( ! text ) 
     return 0;
index 3ec352d945f490705e6cce4b8cf01d6a22758b97..5776c2b54714ee17aaec15bf5a28af845bc6ffe5 100644 (file)
@@ -39,7 +39,7 @@ gboolean text_to_value(const gchar *text, union value *v,
 GtkWidget * get_widget_assert(GladeXML *xml, const gchar *name);
 
 /* Converts a string in the pspp locale to utf-8 */
-const char * pspp_locale_to_utf8(const gchar *text, gssize len, GError **err);
+char * pspp_locale_to_utf8(const gchar *text, gssize len, GError **err);
 
 
 #endif
index 4a517db1872e616e94a6ed13a01a22a57fcbb6f6..53aa827d256c7edd821cafedfc264e17e413a366 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "psppire-variable.h"
 #include "psppire-data-store.h"
+#include "helper.h"
 
 #include <data/dictionary.h>
 #include <data/missing-values.h>
@@ -147,6 +148,7 @@ psppire_data_store_get_font_desc(GSheetModel *model,
 static void
 psppire_data_store_sheet_model_init (GSheetModelIface *iface)
 {
+  iface->free_strings = TRUE;
   iface->get_string = psppire_data_store_get_string;
   iface->set_string = psppire_data_store_set_string;
   iface->clear_datum = psppire_data_store_clear_datum;
index 77ea7343636244c1c2cfc0403f7116ea1f7b339d..09e1e716c82a37c0f29b9410998f643460f53541 100644 (file)
@@ -199,6 +199,7 @@ psppire_var_store_get_font_desc(GSheetModel *model,
 static void
 psppire_var_store_sheet_model_init (GSheetModelIface *iface)
 {
+  iface->free_strings = TRUE;
   iface->get_string = psppire_var_store_get_string;
   iface->set_string = psppire_var_store_set_string;
   iface->clear_datum = psppire_var_store_clear;