1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2020 Free Software Foundation
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 #include <ui/gui/psppire-marshal.h>
24 #include "psppire-spreadsheet-data-model.h"
25 #include "data/spreadsheet-reader.h"
28 static void psppire_spreadsheet_data_model_init (PsppireSpreadsheetDataModel *
30 static void psppire_spreadsheet_data_model_class_init (PsppireSpreadsheetDataModelClass
33 static void psppire_spreadsheet_data_model_finalize (GObject * object);
34 static void psppire_spreadsheet_data_model_dispose (GObject * object);
36 static GObjectClass *parent_class = NULL;
39 static void spreadsheet_tree_model_init (GtkTreeModelIface * iface);
47 static guint signals [n_SIGNALS];
49 G_DEFINE_TYPE_WITH_CODE (PsppireSpreadsheetDataModel,\
50 psppire_spreadsheet_data_model,\
52 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
53 spreadsheet_tree_model_init))
64 psppire_spreadsheet_data_model_get_property (GObject *object,
69 PsppireSpreadsheetDataModel *sp = PSPPIRE_SPREADSHEET_DATA_MODEL (object);
73 case PROP_SPREADSHEET:
74 g_value_set_pointer (value, sp->spreadsheet);
76 case PROP_SHEET_NUMBER:
77 g_value_set_int (value, sp->sheet_number);
80 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
87 psppire_spreadsheet_data_model_set_property (GObject * object,
92 PsppireSpreadsheetDataModel *sp = PSPPIRE_SPREADSHEET_DATA_MODEL (object);
96 case PROP_SPREADSHEET:
98 struct spreadsheet *old = sp->spreadsheet;
99 sp->spreadsheet = spreadsheet_ref (g_value_get_pointer (value));
101 spreadsheet_unref (old);
102 g_signal_emit (sp, signals[ITEMS_CHANGED], 0, 0, 0, 0);
105 case PROP_SHEET_NUMBER:
106 sp->sheet_number = g_value_get_int (value);
107 g_signal_emit (sp, signals[ITEMS_CHANGED], 0, 0, 0, 0);
110 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
117 psppire_spreadsheet_data_model_dispose (GObject * object)
119 PsppireSpreadsheetDataModel *spreadsheetModel = PSPPIRE_SPREADSHEET_DATA_MODEL (object);
121 if (spreadsheetModel->dispose_has_run)
124 spreadsheetModel->dispose_has_run = TRUE;
126 spreadsheet_unref (spreadsheetModel->spreadsheet);
127 /* Chain up to the parent class */
128 G_OBJECT_CLASS (parent_class)->dispose (object);
132 psppire_spreadsheet_data_model_finalize (GObject * object)
134 // PsppireSpreadsheetDataModel *spreadsheetModel = PSPPIRE_SPREADSHEET_DATA_MODEL (object);
138 psppire_spreadsheet_data_model_class_init (PsppireSpreadsheetDataModelClass * class)
140 GObjectClass *object_class;
142 GParamSpec *spreadsheet_spec = g_param_spec_pointer ("spreadsheet",
144 "The spreadsheet that this model represents",
145 G_PARAM_CONSTRUCT_ONLY
149 GParamSpec *sheet_number_spec = g_param_spec_int ("sheet-number",
151 "The number of the sheet",
154 G_PARAM_READABLE | G_PARAM_WRITABLE);
156 parent_class = g_type_class_peek_parent (class);
157 object_class = (GObjectClass *) class;
159 signals [ITEMS_CHANGED] =
160 g_signal_new ("items-changed",
161 G_TYPE_FROM_CLASS (class),
165 psppire_marshal_VOID__UINT_UINT_UINT,
168 G_TYPE_UINT, /* Index of the start of the change */
169 G_TYPE_UINT, /* The number of items deleted */
170 G_TYPE_UINT); /* The number of items inserted */
174 object_class->set_property = psppire_spreadsheet_data_model_set_property;
175 object_class->get_property = psppire_spreadsheet_data_model_get_property;
177 g_object_class_install_property (object_class,
178 PROP_SPREADSHEET, spreadsheet_spec);
180 g_object_class_install_property (object_class,
181 PROP_SHEET_NUMBER, sheet_number_spec);
183 object_class->finalize = psppire_spreadsheet_data_model_finalize;
184 object_class->dispose = psppire_spreadsheet_data_model_dispose;
189 psppire_spreadsheet_data_model_init (PsppireSpreadsheetDataModel * spreadsheetModel)
191 spreadsheetModel->dispose_has_run = FALSE;
192 spreadsheetModel->stamp = g_random_int ();
197 psppire_spreadsheet_data_model_new (struct spreadsheet *sp, gint sheet_number)
199 return g_object_new (psppire_spreadsheet_data_model_get_type (),
201 "sheet-number", sheet_number,
208 tree_model_n_columns (GtkTreeModel *model)
210 PsppireSpreadsheetDataModel *sp = PSPPIRE_SPREADSHEET_DATA_MODEL (model);
212 return spreadsheet_get_sheet_n_columns (sp->spreadsheet, sp->sheet_number);
215 static GtkTreeModelFlags
216 tree_model_get_flags (GtkTreeModel * model)
218 g_return_val_if_fail (PSPPIRE_IS_SPREADSHEET_DATA_MODEL (model),
219 (GtkTreeModelFlags) 0);
221 return GTK_TREE_MODEL_LIST_ONLY;
225 tree_model_column_type (GtkTreeModel * model, gint index)
227 g_print ("%s:%d %p\n", __FILE__, __LINE__, model);
228 g_return_val_if_fail (PSPPIRE_IS_SPREADSHEET_DATA_MODEL (model), (GType) 0);
230 return G_TYPE_STRING;
235 tree_model_get_iter (GtkTreeModel * model, GtkTreeIter * iter,
238 g_print ("%s:%d %p\n", __FILE__, __LINE__, model);
239 PsppireSpreadsheetDataModel *spreadsheetModel =
240 PSPPIRE_SPREADSHEET_DATA_MODEL (model);
241 gint *indices, depth;
244 g_return_val_if_fail (path, FALSE);
246 depth = gtk_tree_path_get_depth (path);
248 g_return_val_if_fail (depth == 1, FALSE);
250 indices = gtk_tree_path_get_indices (path);
254 iter->stamp = spreadsheetModel->stamp;
255 iter->user_data = (gpointer) (intptr_t) n;
261 tree_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter)
263 g_print ("%s:%d %p\n", __FILE__, __LINE__, model);
264 PsppireSpreadsheetDataModel *spreadsheetModel = PSPPIRE_SPREADSHEET_DATA_MODEL (model);
266 g_return_val_if_fail (iter->stamp == spreadsheetModel->stamp, FALSE);
269 iter->user_data = GINT_TO_POINTER (GPOINTER_TO_INT (iter->user_data) + 1);
275 tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter,
276 gint column, GValue *value)
278 PsppireSpreadsheetDataModel *sp = PSPPIRE_SPREADSHEET_DATA_MODEL (model);
279 g_return_if_fail (column >= 0);
280 g_return_if_fail (iter->stamp == sp->stamp);
282 gint row = GPOINTER_TO_INT (iter->user_data);
284 g_value_init (value, G_TYPE_STRING);
286 char *x = spreadsheet_get_cell (sp->spreadsheet, sp->sheet_number, row, column);
288 g_value_take_string (value, x);
292 tree_model_nth_child (GtkTreeModel *model, GtkTreeIter *iter,
293 GtkTreeIter *parent, gint n)
295 PsppireSpreadsheetDataModel *spreadsheetModel =
296 PSPPIRE_SPREADSHEET_DATA_MODEL (model);
301 iter->stamp = spreadsheetModel->stamp;
302 iter->user_data = GINT_TO_POINTER (n);
308 tree_model_n_children (GtkTreeModel *model, GtkTreeIter *iter)
310 PsppireSpreadsheetDataModel *sp = PSPPIRE_SPREADSHEET_DATA_MODEL (model);
314 return spreadsheet_get_sheet_n_rows (sp->spreadsheet, sp->sheet_number);
321 tree_model_iter_has_child (GtkTreeModel *model, GtkTreeIter *iter)
323 g_print ("%s:%d %p\n", __FILE__, __LINE__, model);
328 tree_model_get_path (GtkTreeModel * model, GtkTreeIter * iter)
330 g_print ("%s:%d %p\n", __FILE__, __LINE__, model);
331 PsppireSpreadsheetDataModel *spreadsheetModel =
332 PSPPIRE_SPREADSHEET_DATA_MODEL (model);
334 gint index = GPOINTER_TO_INT (iter->user_data);
336 g_return_val_if_fail (iter->stamp == spreadsheetModel->stamp, NULL);
338 path = gtk_tree_path_new ();
340 gtk_tree_path_append_index (path, index);
347 tree_model_children (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *parent)
349 g_print ("%s:%d %p\n", __FILE__, __LINE__, model);
350 PsppireSpreadsheetDataModel *spreadsheetModel = PSPPIRE_SPREADSHEET_DATA_MODEL (model);
355 iter->stamp = spreadsheetModel->stamp;
362 spreadsheet_tree_model_init (GtkTreeModelIface * iface)
364 iface->get_flags = tree_model_get_flags;
365 iface->get_n_columns = tree_model_n_columns;
366 iface->get_column_type = tree_model_column_type;
367 iface->get_iter = tree_model_get_iter;
368 iface->iter_next = tree_model_iter_next;
369 iface->get_value = tree_model_get_value;
371 iface->iter_children = tree_model_children;
372 iface->iter_parent = NULL;
374 iface->get_path = tree_model_get_path;
375 iface->iter_has_child = tree_model_iter_has_child;
376 iface->iter_n_children = tree_model_n_children;
377 iface->iter_nth_child = tree_model_nth_child;