Fixed some bad interaction between variable and data sheets.
authorJohn Darrington <john@darrington.wattle.id.au>
Sat, 20 May 2006 13:18:27 +0000 (13:18 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Sat, 20 May 2006 13:18:27 +0000 (13:18 +0000)
Allowed user to specify system file on command line.

12 files changed:
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/menu-actions.c
src/ui/gui/menu-actions.h
src/ui/gui/psppire-data-store.c
src/ui/gui/psppire-dict.c
src/ui/gui/psppire.c

index 596afc3db038a01843543e64d89e8d243408ba6e..b4a99709e52ad5e775315b3a20f4c429d7c8af14 100644 (file)
@@ -1,3 +1,11 @@
+Sat May 20 21:02:03 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * gsheetmodel.c gsheetmodel.h: Added columns-inserted and columns-deleted 
+    signals.  Added g_sheet_get_{row,column}_count functions.
+
+    * gtksheet.c gtksheet.h: Allowed -1 to be passed to
+    gtk_sheet_set_active_cell to indicate no active cell.
+
 Mon May 15 16:10:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
     * gtksheet.c: Removed code which rendered the title buttons a second 
index 3a447188b9b7c6912dcf2e7b6956d105fed7fa11..e6a60afc57539446bc67c40c009e7b7286066f89 100644 (file)
@@ -24,6 +24,8 @@ enum {
   RANGE_CHANGED,
   ROWS_INSERTED,
   ROWS_DELETED,
+  COLUMNS_INSERTED,
+  COLUMNS_DELETED,
   LAST_SIGNAL
 };
 
@@ -108,6 +110,29 @@ g_sheet_model_base_init (gpointer g_class)
                      G_TYPE_INT,
                      G_TYPE_INT);
 
+      sheet_model_signals[COLUMNS_INSERTED] =
+       g_signal_new ("columns_inserted",
+                     G_TYPE_SHEET_MODEL,
+                     G_SIGNAL_RUN_LAST,
+                     G_STRUCT_OFFSET (GSheetModelIface, columns_inserted),
+                     NULL, NULL,
+                     gtkextra_VOID__INT_INT,
+                     G_TYPE_NONE, 2,
+                     G_TYPE_INT,
+                     G_TYPE_INT);
+
+
+      sheet_model_signals[COLUMNS_DELETED] =
+       g_signal_new ("columns_deleted",
+                     G_TYPE_SHEET_MODEL,
+                     G_SIGNAL_RUN_LAST,
+                     G_STRUCT_OFFSET (GSheetModelIface, columns_deleted),
+                     NULL, NULL,
+                     gtkextra_VOID__INT_INT,
+                     G_TYPE_NONE, 2,
+                     G_TYPE_INT,
+                     G_TYPE_INT);
+
                    
       initialized = TRUE;
     }
@@ -237,6 +262,25 @@ g_sheet_model_rows_inserted (GSheetModel *sheet_model,
 }
 
 
+/**
+ * g_sheet_model_columns_inserted:
+ * @sheet_model: A #GSheetModel
+ * @column: The column before which the new columns should be inserted.
+ * @n_columns: The number of columns to insert.
+ * 
+ * Emits the "columns_inserted" signal on @sheet_model.
+ **/
+void
+g_sheet_model_columns_inserted (GSheetModel *sheet_model,
+                              gint column, gint n_columns)
+{
+  g_return_if_fail (G_IS_SHEET_MODEL (sheet_model));
+
+  g_signal_emit (sheet_model, sheet_model_signals[COLUMNS_INSERTED], 0, 
+                column, n_columns);
+}
+
+
 
 
 /**
@@ -259,6 +303,27 @@ g_sheet_model_rows_deleted (GSheetModel *sheet_model,
 
 
 
+/**
+ * g_sheet_model_columns_deleted:
+ * @sheet_model: A #GSheetModel
+ * @column: The first column to be deleted.
+ * @n_columns: The number of columns to delete.
+ * 
+ * Emits the "columns_deleted" signal on @sheet_model.
+ **/
+void
+g_sheet_model_columns_deleted (GSheetModel *sheet_model,
+                              gint column, gint n_columns)
+{
+  g_return_if_fail (G_IS_SHEET_MODEL (sheet_model));
+
+  g_signal_emit (sheet_model, sheet_model_signals[COLUMNS_DELETED], 0, 
+                column, n_columns);
+}
+
+
+
+
 
 /**
  * g_sheet_model_is_editable:
@@ -413,3 +478,31 @@ g_sheet_model_get_cell_border (const GSheetModel *model,
 
 
 
+/**
+ * g_sheet_model_get_column_count:
+ * @model: A #GSheetModel
+ *
+ * Returns the total number of columns represented by the model
+ **/
+inline gint 
+g_sheet_model_get_column_count(const GSheetModel *model)
+{
+  g_return_val_if_fail (G_IS_SHEET_MODEL (model), -1);
+
+  return G_SHEET_MODEL_GET_IFACE (model)->get_column_count (model);
+}
+
+/**
+ * g_sheet_model_get_row_count:
+ * @model: A #GSheetModel
+ *
+ * Returns the total number of rows represented by the model
+ **/
+inline gint 
+g_sheet_model_get_row_count(const GSheetModel *model)
+{
+  g_return_val_if_fail (G_IS_SHEET_MODEL (model), -1);
+
+
+  return G_SHEET_MODEL_GET_IFACE (model)->get_row_count (model);
+}
index 4ee06836cc757fa541f6c87b2f9bf3a1611b92db..39ab173f3593a3e4582b0e71ab0e7a4f7a858da0 100644 (file)
@@ -84,6 +84,14 @@ struct _GSheetModelIface
   void         (* rows_deleted)     (GSheetModel *sheet_model,
                                     gint row, gint n_rows);
 
+  void         (* columns_inserted)    (GSheetModel *sheet_model,
+                                    gint column, gint n_columns);
+
+  void         (* columns_deleted)     (GSheetModel *sheet_model,
+                                    gint column, gint n_columns);
+
+
+
 
   /* Virtual Table */
 
@@ -114,6 +122,11 @@ struct _GSheetModelIface
   const GtkSheetCellBorder *  (* get_cell_border) (const GSheetModel *sheet_model, 
                                                   gint row, gint column);
 
+
+  gint (*get_column_count) (const GSheetModel *model);
+
+  gint (*get_row_count) (const GSheetModel *model);
+
 };
 
 
@@ -142,6 +155,13 @@ inline void g_sheet_model_rows_deleted (GSheetModel *sheet_model,
 inline void g_sheet_model_rows_inserted (GSheetModel *sheet_model,
                                    gint row, gint n_rows);
 
+inline void g_sheet_model_columns_inserted (GSheetModel *sheet_model,
+                                           gint column, gint n_columns);
+
+inline void g_sheet_model_columns_deleted (GSheetModel *sheet_model,
+                                          gint column, gint n_columns);
+
+
 inline gboolean g_sheet_model_is_editable (const GSheetModel *model, 
                                      gint row, gint column);
 
@@ -168,7 +188,9 @@ inline const GtkSheetCellBorder * g_sheet_model_get_cell_border
 
 inline  gboolean g_sheet_model_free_strings (const GSheetModel *sheet_model);
 
+inline gint g_sheet_model_get_column_count(const GSheetModel *sheet_model);
 
+inline gint g_sheet_model_get_row_count(const GSheetModel *sheet_model);
 
 G_END_DECLS
 
index dd7d4190f0e4972f93d58df61c3d154667648bb6..caed10ba12c53e814a385a446cf0963cc3af93af 100644 (file)
@@ -79,6 +79,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)
@@ -1134,6 +1137,32 @@ 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)
+{
+  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;
+
+  if (sheet->active_cell.col >= model_columns)
+    gtk_sheet_activate_cell(sheet, sheet->active_cell.row, model_columns - 1);
+  
+  gtk_sheet_range_draw(sheet, &range);
+}
+
+
 /* Callback which occurs whenever rows are inserted/deleted in the model */
 static void 
 rows_inserted_deleted_callback (GSheetModel *m, gint first_row, gint n_rows,
@@ -1152,6 +1181,7 @@ rows_inserted_deleted_callback (GSheetModel *m, gint first_row, gint n_rows,
   range.coli = xxx_column_count(sheet) - 1;
   
   gtk_sheet_range_draw(sheet, &range);
+
 }
 
 /* 
@@ -1251,6 +1281,12 @@ gtk_sheet_set_model(GtkSheet *sheet, GSheetModel *model)
   g_signal_connect(model, "rows_deleted",
                   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);
+
 }
 
 
@@ -1293,7 +1329,6 @@ gtk_sheet_construct (GtkSheet *sheet,
   sheet->column_titles_visible = TRUE;
   sheet->autoscroll = TRUE;
   sheet->justify_entry = TRUE;
-  sheet->locked = FALSE;
 
 
   /* create sheet entry */
@@ -1585,16 +1620,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
@@ -2841,10 +2893,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)){
@@ -3836,7 +3892,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;
 
@@ -3845,9 +3901,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))
@@ -3926,13 +3988,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);
@@ -3968,6 +4033,7 @@ gtk_sheet_hide_active_cell(GtkSheet *sheet)
  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);
+      gtk_entry_set_text(GTK_ENTRY(sheet->sheet_entry), "");
  }
  else
  {
@@ -3982,6 +4048,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)
@@ -4068,7 +4135,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;
@@ -4090,11 +4157,10 @@ gtk_sheet_show_active_cell(GtkSheet *sheet)
 
  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));
@@ -4128,7 +4194,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
@@ -4654,6 +4720,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
@@ -4914,35 +4983,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){
index 18c39f250c9af8a120652808d16fb39f53884f49..ed6cd31ee43a10409ba634bd7dd85318ca7745d1 100644 (file)
@@ -71,7 +71,6 @@ enum
 
 /* Public flags, for compatibility */
 
-#define GTK_SHEET_IS_LOCKED(sheet)       gtk_sheet_locked(sheet)
 #define GTK_SHEET_ROW_FROZEN(sheet)      !gtk_sheet_rows_resizable(sheet)
 #define GTK_SHEET_COLUMN_FROZEN(sheet)   !gtk_sheet_columns_resizable(sheet)
 #define GTK_SHEET_AUTORESIZE(sheet)      gtk_sheet_autoresize(sheet)
@@ -120,7 +119,6 @@ struct _GtkSheet{
   gboolean autoscroll;
   gboolean clip_text;
   gboolean justify_entry;
-  gboolean locked;
 
   guint freeze_count;
 
@@ -377,7 +375,7 @@ void
 gtk_sheet_set_locked                   (GtkSheet *sheet, gboolean lock);
 
 gboolean
-gtk_sheet_locked                       (GtkSheet *sheet);
+gtk_sheet_locked                       (const GtkSheet *sheet);
 
 /* set sheet title */
 void
index 3d1b900e5d9ae973c1f9a49beffb6c1635ee3d55..4fe6e3f37cafd113a93351a8d1d5e9224f05b83a 100644 (file)
@@ -1,3 +1,15 @@
+Sat May 20 21:08:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * data-sheet.c, menu-actions.c menu-actions: Fixed data sheet so that
+   active cell is never on a deleted variable.
+
+   * psppire-data-store.c psppire-data-store.h:  Added get_var_count and
+   get_case_count functions.
+
+   * psppire-dict.c: removed VARIABLE_DELETED (singular) signal.
+
+   * psppire.c: Allowed user to specify *.sav file on command line.
+
 Mon May 15 20:01:25 WST 2006 John Darrington <john@darrington.wattle.id.au>
        
        * menu-actions.c psppire-case-array.c psppire-case-array.h
index a9d980ded2e74a584dd9d34d0f5ed9601f44d772..af32f80119db78e2923e08d1c4f8a74180837bd1 100644 (file)
@@ -84,7 +84,7 @@ click2column(GtkWidget *w, gint col, gpointer data)
 
 
 /* Update the data_ref_entry with the reference of the active cell */
-static gint 
+gint 
 update_data_ref_entry(const GtkSheet *sheet, gint row, gint col)
 {
 
@@ -150,6 +150,7 @@ psppire_data_sheet_create (gchar *widget_name, gchar *string1, gchar *string2,
                    GTK_SIGNAL_FUNC (click2column),
                    0);
 
+  gtk_sheet_set_active_cell(GTK_SHEET(sheet), -1, -1);
   gtk_widget_show(sheet);
 
   return sheet;
index 38f73ebe55839804f89e4281d29dbd045355a2dc..d1165f38b6ae8117f8d7efea4c7816dd5ff8b489 100644 (file)
@@ -76,9 +76,16 @@ void
 on_new1_activate                       (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  GtkWidget *data_sheet = get_widget_assert(xml, "data_sheet");
+  GtkWidget *var_sheet = get_widget_assert(xml, "variable_sheet");
+  gtk_sheet_set_active_cell(GTK_SHEET(data_sheet), -1, -1);
+
+  gtk_sheet_set_active_cell(GTK_SHEET(var_sheet), 0, 0);
+
   psppire_dict_clear(the_dictionary);
   psppire_case_array_clear(the_cases);
-
+  
   psppire_set_window_title(untitled);
 
   if (psppire_handle)
@@ -86,6 +93,7 @@ on_new1_activate                       (GtkMenuItem     *menuitem,
   psppire_handle = 0 ;
 }
 
+
 static gboolean
 populate_case_from_reader(struct ccase *c, gpointer aux)
 {
@@ -95,6 +103,86 @@ populate_case_from_reader(struct ccase *c, gpointer aux)
 }
 
 
+/* Load a system file.
+   Return TRUE if successfull
+*/
+gboolean
+load_system_file(const gchar *file_name)
+{
+  int ni ;
+  gint case_num;
+
+  PsppireVarStore *var_store ;
+  PsppireDataStore *data_store ;
+  struct dictionary *new_dict;
+  struct sfm_read_info ri;
+  struct sfm_reader *reader ; 
+
+  GtkWidget *data_sheet = get_widget_assert(xml, "data_sheet");
+  GtkWidget *var_sheet = get_widget_assert(xml, "variable_sheet");
+
+
+  g_assert(data_sheet);
+  g_assert(var_sheet);
+
+  if ( psppire_handle ) 
+    fh_free(psppire_handle);
+
+  psppire_handle = 
+    fh_create_file (handle_name, file_name, fh_default_properties());
+
+  if ( !psppire_handle ) 
+    {
+      g_warning("Cannot read handle for reading system file \"%s\"\n", 
+               file_name);
+      return FALSE;
+    }
+
+
+  reader = sfm_open_reader (psppire_handle, &new_dict, &ri);
+      
+  if ( ! reader ) 
+    return FALSE;
+
+  /* FIXME: We need a better way of updating a dictionary than this */
+  the_dictionary = psppire_dict_new_from_dict(new_dict);
+
+  var_store = 
+    PSPPIRE_VAR_STORE(gtk_sheet_get_model(GTK_SHEET(var_sheet)));
+       
+  psppire_var_store_set_dictionary(var_store, the_dictionary);
+
+
+  data_store = 
+    PSPPIRE_DATA_STORE(gtk_sheet_get_model(GTK_SHEET(data_sheet)));
+       
+  psppire_data_store_set_dictionary(data_store,
+                                   the_dictionary);
+
+  psppire_case_array_clear(data_store->cases);
+
+
+  psppire_set_window_title(basename(file_name));
+
+  ni = dict_get_next_value_idx(the_dictionary->dict);
+  if ( ni == 0 ) 
+    return FALSE;
+
+  for(case_num=0;;case_num++)
+    {
+      if (!psppire_case_array_append_case(the_cases, 
+                                         populate_case_from_reader, 
+                                         reader))
+       break;
+    }
+
+
+  sfm_close_reader(reader);
+
+  return TRUE;
+}
+
+
 void
 on_open1_activate                      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
@@ -129,94 +217,22 @@ on_open1_activate                      (GtkMenuItem     *menuitem,
   gtk_file_filter_add_pattern(filter, "*");
   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
 
-
   do {
 
     if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
       {
-       PsppireVarStore *var_store ;
-       PsppireDataStore *data_store ;
-       struct dictionary *new_dict;
-       struct sfm_read_info ri;
-       struct sfm_reader *reader ; 
-
-       GtkWidget *data_sheet = get_widget_assert(xml, "data_sheet");
-       GtkWidget *var_sheet = get_widget_assert(xml, "variable_sheet");
-       gchar *file_name;
-
-       g_assert(data_sheet);
-       g_assert(var_sheet);
-
-       file_name = gtk_file_chooser_get_filename
-         (GTK_FILE_CHOOSER (dialog));
-
-       if ( psppire_handle ) 
-         fh_free(psppire_handle);
-
-       psppire_handle = 
-         fh_create_file (handle_name, file_name, fh_default_properties());
-
-       if ( !psppire_handle ) 
-         {
-           g_warning("Cannot read handle for reading system file \"%s\"\n", 
-                     file_name);
-           continue;
-         }
-
-
-       reader = sfm_open_reader (psppire_handle, &new_dict, &ri);
-      
-       if ( ! reader ) 
-         continue;
-
-       the_dictionary = psppire_dict_new_from_dict(new_dict);
-
-       var_store = 
-         PSPPIRE_VAR_STORE(gtk_sheet_get_model(GTK_SHEET(var_sheet)));
+       gchar *file_name = 
+         gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (dialog));
        
-       psppire_var_store_set_dictionary(var_store, the_dictionary);
-
-
-       data_store = 
-         PSPPIRE_DATA_STORE(gtk_sheet_get_model(GTK_SHEET(data_sheet)));
-       
-
-       psppire_data_store_set_dictionary(data_store,
-                                         the_dictionary);
-
-       psppire_case_array_clear(data_store->cases);
+       finished =  load_system_file(file_name) ;
 
-
-       psppire_set_window_title(basename(file_name));
-
-       g_free (file_name);
-
-       {
-         const int ni = dict_get_next_value_idx(the_dictionary->dict);
-         gint case_num;
-         if ( ni == 0 ) 
-           goto done;
-      
-
-         for(case_num=0;;case_num++)
-           {
-             if (!psppire_case_array_append_case(the_cases, 
-                                                 populate_case_from_reader, 
-                                                 reader))
-               break;
-           }
-       }
-
-       sfm_close_reader(reader);
-       finished = TRUE;
+       g_free(file_name);
       }
     else
-      {
-       finished = TRUE;
-      }
+      finished = TRUE;
+
   } while ( ! finished ) ;
 
- done:
   gtk_widget_destroy (dialog);
 }
 
index 2e4e86ea974941b02718fd5143336ea6d016c98d..f4ed5c006d643db0582a19eec6870dd7e0aab7d9 100644 (file)
@@ -83,7 +83,11 @@ gboolean callbacks_on_init(gpointer data) ;
 /* Switch between the VAR SHEET and the DATA SHEET */
 enum {PAGE_DATA_SHEET = 0, PAGE_VAR_SHEET};
 
+gboolean load_system_file(const gchar *file_name);
+
+void select_sheet(gint page);
 
 #endif
 
-void select_sheet(gint page);
+
+
index 116092fd77a139193f10e5f3d9b7b76b63d4d3cb..5b40635b66606553f6545f342f56b5c67b6b63d8 100644 (file)
@@ -22,6 +22,7 @@
 #include <config.h>
 #include <string.h>
 #include <stdlib.h>
+#include <minmax.h>
 
 #include <gtksheet/gtksheet.h>
 #include <gtksheet/gsheetmodel.h>
@@ -60,7 +61,6 @@ static gboolean psppire_data_store_clear_datum(GSheetModel *model,
 
 #define MIN_COLUMNS 10
 
-#define max(A,B) ((A>B)?A:B)
 
 static GObjectClass *parent_class = NULL;
 
@@ -128,6 +128,24 @@ psppire_data_store_class_init (PsppireDataStoreClass *class)
 }
 
 
+
+static gint
+psppire_data_store_get_var_count (const GSheetModel *model)
+{
+  const PsppireDataStore *store = PSPPIRE_DATA_STORE(model);
+  
+  return psppire_dict_get_var_cnt(store->dict);
+}
+
+static gint
+psppire_data_store_get_case_count (const GSheetModel *model)
+{
+  const PsppireDataStore *store = PSPPIRE_DATA_STORE(model);
+
+  return psppire_case_array_get_n_cases(store->cases);
+}
+
+
 static void
 psppire_data_store_init (PsppireDataStore *data_store)
 {
@@ -158,6 +176,8 @@ psppire_data_store_sheet_model_init (GSheetModelIface *iface)
   iface->get_background = NULL;
   iface->get_font_desc = psppire_data_store_get_font_desc;
   iface->get_cell_border = NULL;
+  iface->get_column_count = psppire_data_store_get_var_count;
+  iface->get_row_count = psppire_data_store_get_case_count;
 }
 
 static
@@ -167,7 +187,6 @@ gboolean always_true()
 }
 
 
-
 static void
 delete_cases_callback(GtkWidget *w, gint first, gint n_cases, gpointer data)
 {
@@ -215,7 +234,7 @@ changed_case_callback(GtkWidget *w, gint casenum, gpointer data)
 
 
 static void
-delete_variables_callback(GtkWidget *w, gint var_num, gint n_vars, gpointer data)
+delete_variables_callback(GObject *obj, gint var_num, gint n_vars, gpointer data)
 {
   PsppireDataStore *store ;
 
@@ -225,11 +244,13 @@ delete_variables_callback(GtkWidget *w, gint var_num, gint n_vars, gpointer data
 
   g_sheet_column_columns_deleted(G_SHEET_COLUMN(store),
                                   var_num, n_vars);
+
+  g_sheet_model_columns_deleted (G_SHEET_MODEL(store), var_num, n_vars);
 }
 
 
 static void
-insert_variable_callback(GtkWidget *w, gint var_num, gpointer data)
+insert_variable_callback(GObject *obj, gint var_num, gpointer data)
 {
   PsppireDataStore *store;
 
@@ -247,6 +268,7 @@ insert_variable_callback(GtkWidget *w, gint var_num, gpointer data)
   psppire_case_array_resize(store->cases, 
                         dict_get_next_value_idx (store->dict->dict));
 
+  g_sheet_model_columns_inserted (G_SHEET_MODEL(store), var_num, 1);
 }
 
 
@@ -277,7 +299,6 @@ psppire_data_store_new (PsppireDict *dict, PsppireCaseArray *cases)
   g_signal_connect(cases, "case-changed", G_CALLBACK(changed_case_callback), 
                   retval);
 
-
   psppire_data_store_set_dictionary(retval, dict);
 
 
@@ -315,7 +336,6 @@ psppire_data_store_set_dictionary(PsppireDataStore *data_store, PsppireDict *dic
                   G_CALLBACK(delete_variables_callback), 
                   data_store);
 
-
   /* The entire model has changed */
   g_sheet_model_range_changed (G_SHEET_MODEL(data_store), -1, -1, -1, -1);
 }
@@ -450,6 +470,7 @@ psppire_data_store_set_string(GSheetModel *model,
   PsppireDataStore *store = PSPPIRE_DATA_STORE(model);
 
   const struct PsppireVariable *pv = psppire_dict_get_variable(store->dict, col);
+  g_return_val_if_fail(pv, FALSE);
 
   for(r = psppire_case_array_get_n_cases(store->cases) ; r <= row ; ++r ) 
     {
@@ -550,7 +571,7 @@ geometry_get_column_count(const GSheetColumn *geom)
 {
   PsppireDataStore *ds = PSPPIRE_DATA_STORE(geom);
 
-  return max(MIN_COLUMNS, psppire_dict_get_var_cnt(ds->dict));
+  return MAX(MIN_COLUMNS, psppire_dict_get_var_cnt(ds->dict));
 }
 
 /* Return the width that an  'M' character would occupy when typeset at
index a8a8f63640cbc7ec41bed73759aa49e171006422..0927f9c99e7e58b53b1370673e62acea5a285c01 100644 (file)
@@ -46,7 +46,6 @@ static GObjectClass     *parent_class = NULL;
 
 enum  {VARIABLE_CHANGED, 
        VARIABLE_INSERTED,
-       VARIABLE_DELETED, 
        VARIABLES_DELETED, 
        n_SIGNALS};
 
@@ -119,17 +118,6 @@ psppire_dict_class_init (PsppireDictClass *class)
                  1,
                  G_TYPE_INT);
 
-  signal[VARIABLE_DELETED] =
-    g_signal_new ("variable_deleted",
-                 G_TYPE_FROM_CLASS(class),
-                 G_SIGNAL_RUN_FIRST,
-                 0,
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__INT,
-                 G_TYPE_NONE, 
-                 1,
-                 G_TYPE_INT);
-
 
   signal[VARIABLES_DELETED] =
     g_signal_new ("variables_deleted",
@@ -332,7 +320,9 @@ psppire_dict_get_variable(PsppireDict *d, gint idx)
   struct PsppireVariable *var ;
   g_return_val_if_fail(d, NULL);
   g_return_val_if_fail(d->dict, NULL);
-  g_return_val_if_fail(d->variables, NULL);
+
+  if ( ! d->variables) 
+    return NULL;
   
   if (idx < 0 || idx >= psppire_dict_get_var_cnt(d))
     return NULL;
index 9d01f9f76a4f8bbe9b4edfce3e81c51278b0715a..e252acdefb84f69cb6b9ba96db26574a36c7c8ed 100644 (file)
@@ -51,7 +51,8 @@ PsppireCaseArray *the_cases = 0;
 PsppireDataStore *data_store = 0;
 
 
-static bool parse_command_line (int *argc, char ***argv);
+static bool parse_command_line (int *argc, char ***argv, 
+                               gchar **filename, GError **err);
 
 
 int 
@@ -62,10 +63,16 @@ main(int argc, char *argv[])
   GtkSheet *var_sheet ; 
   GtkSheet *data_sheet ;
 
+  gchar *filename=0;
+  GError *err = 0;
+
   gtk_init(&argc, &argv);
 
-  if ( ! parse_command_line(&argc, &argv) ) 
-    return 0;
+  if ( ! parse_command_line(&argc, &argv, &filename, &err) ) 
+    {
+      g_clear_error(&err);
+      return 1;
+    }
 
 
   glade_init();
@@ -101,9 +108,11 @@ main(int argc, char *argv[])
   
   gtk_sheet_set_model(data_sheet, G_SHEET_MODEL(data_store));
 
-
   gtk_init_add(callbacks_on_init, 0);
 
+  if (filename)
+    gtk_init_add((GtkFunction)load_system_file, filename);
+
   /* start the event loop */
   gtk_main();
 
@@ -117,7 +126,7 @@ main(int argc, char *argv[])
    main().  Returns true if normal execution should proceed,
    false if the command-line indicates that PSPP should exit. */
 static bool
-parse_command_line (int *argc, char ***argv)
+parse_command_line (int *argc, char ***argv, gchar **filename, GError **err)
 {
   static struct option long_options[] =
     {
@@ -137,7 +146,7 @@ parse_command_line (int *argc, char ***argv)
       switch (c)
        {
        case 'h':
-         g_print("Usage: psppire {|--help|--version}\n");
+         g_printerr("Usage: psppire {|--help|--version}\n");
           return false;
        case 'V':
          g_print(version);
@@ -149,5 +158,10 @@ parse_command_line (int *argc, char ***argv)
        }
     }
 
+  if ( optind < *argc) 
+    {
+      *filename = (*argv)[optind];
+    }
+
   return true;
 }