X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-spreadsheet-model.c;h=26c803f3a670a90d3923db358422e3a78c209634;hb=refs%2Fheads%2Fctables7;hp=d5915a3db5206fdd15541734b661b2e18e956765;hpb=eec708fba0cef3b9274fcd201d14c97f67c0d52f;p=pspp diff --git a/src/ui/gui/psppire-spreadsheet-model.c b/src/ui/gui/psppire-spreadsheet-model.c index d5915a3db5..26c803f3a6 100644 --- a/src/ui/gui/psppire-spreadsheet-model.c +++ b/src/ui/gui/psppire-spreadsheet-model.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2013 Free Software Foundation + Copyright (C) 2013, 2014 Free Software Foundation This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,81 +14,109 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +/* This file implements a GtkTreeModel. It allows GtkComboBox and + GtkTreeView to display the names and non-empty cell ranges of the + sheets aka "Tables" of spreadsheet files. + It doesn't take any notice of the spreadsheet data itself. +*/ #include #include -#include "psppire-spreadsheet-model.h" +#include + +#include +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid -static void psppire_spreadsheet_model_init (PsppireSpreadsheetModel *spreadsheetModel); -static void psppire_spreadsheet_model_class_init (PsppireSpreadsheetModelClass *class); -static void psppire_spreadsheet_model_finalize (GObject *object); -static void psppire_spreadsheet_model_dispose (GObject *object); +#include "psppire-spreadsheet-model.h" +#include "data/spreadsheet-reader.h" + +static void psppire_spreadsheet_model_finalize (GObject * object); +static void psppire_spreadsheet_model_dispose (GObject * object); static GObjectClass *parent_class = NULL; +static void spreadsheet_tree_model_init (GtkTreeModelIface * iface); + +G_DEFINE_TYPE_WITH_CODE (PsppireSpreadsheetModel,\ + psppire_spreadsheet_model,\ + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, + spreadsheet_tree_model_init)) -static void spreadsheet_tree_model_init (GtkTreeModelIface *iface); +/* Properties */ +enum +{ + PROP_0, + PROP_SPREADSHEET +}; -GType -psppire_spreadsheet_model_get_type (void) +static void +psppire_spreadsheet_model_set_property (GObject * object, + guint prop_id, + const GValue * value, + GParamSpec * pspec) { - static GType object_type = 0; + PsppireSpreadsheetModel *spreadsheetModel = + PSPPIRE_SPREADSHEET_MODEL (object); - if (!object_type) + switch (prop_id) { - static const GTypeInfo spreadsheet_model_info = + case PROP_SPREADSHEET: { - sizeof (PsppireSpreadsheetModelClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) psppire_spreadsheet_model_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PsppireSpreadsheetModel), - 0, - (GInstanceInitFunc) psppire_spreadsheet_model_init, - }; - - static const GInterfaceInfo tree_model_info = { - (GInterfaceInitFunc) spreadsheet_tree_model_init, - NULL, - NULL - }; - - object_type = g_type_register_static (G_TYPE_OBJECT, - "PsppireSpreadsheetModel", - &spreadsheet_model_info, 0); - - g_type_add_interface_static (object_type, GTK_TYPE_TREE_MODEL, - &tree_model_info); - - } - - return object_type; + struct spreadsheet *old = spreadsheetModel->spreadsheet; + spreadsheetModel->spreadsheet = spreadsheet_ref (g_value_get_pointer (value)); + if (old) + spreadsheet_unref (old); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + }; } static void -psppire_spreadsheet_model_dispose (GObject *object) +psppire_spreadsheet_model_dispose (GObject * object) { + PsppireSpreadsheetModel *spreadsheetModel = PSPPIRE_SPREADSHEET_MODEL (object); + + if (!spreadsheetModel->dispose_has_run) + { + spreadsheet_unref (spreadsheetModel->spreadsheet); + + spreadsheetModel->dispose_has_run = TRUE; + } } static void -psppire_spreadsheet_model_finalize (GObject *object) +psppire_spreadsheet_model_finalize (GObject * object) { // PsppireSpreadsheetModel *spreadsheetModel = PSPPIRE_SPREADSHEET_MODEL (object); } static void -psppire_spreadsheet_model_class_init (PsppireSpreadsheetModelClass *class) +psppire_spreadsheet_model_class_init (PsppireSpreadsheetModelClass * class) { - GObjectClass *object_class; + GObjectClass *object_class = G_OBJECT_CLASS (class); + + GParamSpec *spreadsheet_spec = g_param_spec_pointer ("spreadsheet", + "Spreadsheet", + "The spreadsheet that this model represents", + G_PARAM_CONSTRUCT_ONLY + | G_PARAM_WRITABLE); parent_class = g_type_class_peek_parent (class); - object_class = (GObjectClass*) class; + + + object_class->set_property = psppire_spreadsheet_model_set_property; + + g_object_class_install_property (object_class, + PROP_SPREADSHEET, spreadsheet_spec); object_class->finalize = psppire_spreadsheet_model_finalize; object_class->dispose = psppire_spreadsheet_model_dispose; @@ -96,72 +124,72 @@ psppire_spreadsheet_model_class_init (PsppireSpreadsheetModelClass *class) static void -psppire_spreadsheet_model_init (PsppireSpreadsheetModel *spreadsheetModel) +psppire_spreadsheet_model_init (PsppireSpreadsheetModel * spreadsheetModel) { spreadsheetModel->dispose_has_run = FALSE; spreadsheetModel->stamp = g_random_int (); } -GtkTreeModel* -psppire_spreadsheet_model_new (void) +GtkTreeModel * +psppire_spreadsheet_model_new (struct spreadsheet *sp) { - return g_object_new (psppire_spreadsheet_model_get_type (), NULL); + return g_object_new (psppire_spreadsheet_model_get_type (), + "spreadsheet", sp, NULL); } - - -static const gint N_COLS = 2; - -static gint -tree_model_n_columns (GtkTreeModel *model) +static gint +tree_model_n_columns (GtkTreeModel * model) { - g_print ("%s\n", __FUNCTION__); - return N_COLS; + return PSPPIRE_SPREADSHEET_MODEL_N_COLS; } static GtkTreeModelFlags -tree_model_get_flags (GtkTreeModel *model) +tree_model_get_flags (GtkTreeModel * model) { - g_print ("%s\n", __FUNCTION__); - g_return_val_if_fail (PSPPIRE_IS_SPREADSHEET_MODEL (model), (GtkTreeModelFlags) 0); + g_return_val_if_fail (PSPPIRE_IS_SPREADSHEET_MODEL (model), + (GtkTreeModelFlags) 0); return GTK_TREE_MODEL_LIST_ONLY; } static GType -tree_model_column_type (GtkTreeModel *model, gint index) +tree_model_column_type (GtkTreeModel * model, gint index) { - g_print ("%s %d\n", __FUNCTION__, index); g_return_val_if_fail (PSPPIRE_IS_SPREADSHEET_MODEL (model), (GType) 0); - g_return_val_if_fail (index < N_COLS, (GType) 0); - + g_return_val_if_fail (index < PSPPIRE_SPREADSHEET_MODEL_N_COLS, (GType) 0); + + if (index == PSPPIRE_SPREADSHEET_MODEL_COL_SHEET_ROWS) + return G_TYPE_UINT; + return G_TYPE_STRING; } static gboolean -tree_model_get_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path) +tree_model_get_iter (GtkTreeModel * model, GtkTreeIter * iter, + GtkTreePath * path) { + PsppireSpreadsheetModel *spreadsheetModel = + PSPPIRE_SPREADSHEET_MODEL (model); gint *indices, depth; - - PsppireSpreadsheetModel *spreadsheetModel = PSPPIRE_SPREADSHEET_MODEL (model); + gint n; g_return_val_if_fail (path, FALSE); - indices = gtk_tree_path_get_indices (path); - depth = gtk_tree_path_get_depth (path); g_return_val_if_fail (depth == 1, FALSE); - g_print ("%s %d\n", __FUNCTION__, *indices); + indices = gtk_tree_path_get_indices (path); + + n = indices[0]; iter->stamp = spreadsheetModel->stamp; - iter->user_data = *indices; // kludge + iter->user_data = (gpointer) (intptr_t) n; return TRUE; } @@ -170,79 +198,168 @@ static gboolean tree_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter) { PsppireSpreadsheetModel *spreadsheetModel = PSPPIRE_SPREADSHEET_MODEL (model); + g_assert (iter); g_return_val_if_fail (iter->stamp == spreadsheetModel->stamp, FALSE); - g_print ("%s %d\n", __FUNCTION__, iter->user_data); - - if ( iter->user_data >= 5 - 1) - return FALSE; + if ((intptr_t) iter->user_data >= + spreadsheet_get_sheet_n_sheets (spreadsheetModel->spreadsheet) - 1) + { + iter->user_data = NULL; + iter->stamp = 0; + return FALSE; + } - iter->user_data++; + iter->user_data = GINT_TO_POINTER (GPOINTER_TO_INT (iter->user_data) + 1); return TRUE; } static void -tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter, - gint column, GValue *value) +tree_model_get_value (GtkTreeModel * model, GtkTreeIter * iter, + gint column, GValue * value) { - PsppireSpreadsheetModel *spreadsheetModel = PSPPIRE_SPREADSHEET_MODEL (model); - g_return_if_fail (column < N_COLS); + PsppireSpreadsheetModel *spreadsheetModel = + PSPPIRE_SPREADSHEET_MODEL (model); + g_return_if_fail (column < PSPPIRE_SPREADSHEET_MODEL_N_COLS); g_return_if_fail (iter->stamp == spreadsheetModel->stamp); - g_print ("%s col %d\n", __FUNCTION__, column); - g_value_init (value, G_TYPE_STRING); - if ( column > 0) - g_value_set_string (value, "foo"); - else - g_value_set_string (value, "bar"); + switch (column) + { + case PSPPIRE_SPREADSHEET_MODEL_COL_NAME: + { + g_value_init (value, G_TYPE_STRING); + const char *x = + spreadsheet_get_sheet_name (spreadsheetModel->spreadsheet, + (intptr_t) iter->user_data); + + g_value_set_string (value, x); + } + break; + case PSPPIRE_SPREADSHEET_MODEL_COL_RANGE: + { + g_value_init (value, G_TYPE_STRING); + char *x = + spreadsheet_get_sheet_range (spreadsheetModel->spreadsheet, + (intptr_t) iter->user_data); + + g_value_set_string (value, x ? x : _("(empty)")); + g_free (x); + } + break; + case PSPPIRE_SPREADSHEET_MODEL_COL_SHEET_ROWS: + { + g_value_init (value, G_TYPE_UINT); + unsigned int rows = + spreadsheet_get_sheet_n_rows (spreadsheetModel->spreadsheet, + (intptr_t) iter->user_data); + + g_value_set_uint (value, rows); + } + break; + case PSPPIRE_SPREADSHEET_MODEL_COL_SHEET_COLUMNS: + { + g_value_init (value, G_TYPE_UINT); + unsigned int columns = + spreadsheet_get_sheet_n_columns (spreadsheetModel->spreadsheet, + (intptr_t) iter->user_data); + + g_value_set_uint (value, columns); + } + break; + default: + g_error ("%s:%d Invalid column in spreadsheet model", + __FILE__, __LINE__); + break; + } } - static gboolean -tree_model_nth_child (GtkTreeModel *model, GtkTreeIter *iter, - GtkTreeIter *parent, gint n) +tree_model_nth_child (GtkTreeModel * model, GtkTreeIter * iter, + GtkTreeIter * parent, gint n) { - PsppireSpreadsheetModel *spreadsheetModel = PSPPIRE_SPREADSHEET_MODEL (model); + PsppireSpreadsheetModel *spreadsheetModel = + PSPPIRE_SPREADSHEET_MODEL (model); - if ( parent ) + if (parent) return FALSE; - if ( n >= 5) + if (n >= spreadsheet_get_sheet_n_sheets (spreadsheetModel->spreadsheet)) return FALSE; iter->stamp = spreadsheetModel->stamp; - /* - iter->user_data = psppire_dict_get_variable (dict, n); + iter->user_data = (gpointer) (intptr_t) n; + + return TRUE; +} + +static gint +tree_model_n_children (GtkTreeModel * model, GtkTreeIter * iter) +{ + PsppireSpreadsheetModel *spreadsheetModel = + PSPPIRE_SPREADSHEET_MODEL (model); + + if (iter == NULL) + return spreadsheet_get_sheet_n_sheets (spreadsheetModel->spreadsheet); + + return 0; +} + +static gboolean +tree_model_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter) +{ + return FALSE; +} + +static GtkTreePath * +tree_model_get_path (GtkTreeModel * model, GtkTreeIter * iter) +{ + PsppireSpreadsheetModel *spreadsheetModel = + PSPPIRE_SPREADSHEET_MODEL (model); + GtkTreePath *path; + gint index = (intptr_t) iter->user_data; + + g_return_val_if_fail (iter->stamp == spreadsheetModel->stamp, NULL); + + path = gtk_tree_path_new (); + + gtk_tree_path_append_index (path, index); + + return path; +} + + +static gboolean +tree_model_children (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *parent) +{ + PsppireSpreadsheetModel *spreadsheetModel = PSPPIRE_SPREADSHEET_MODEL (model); - if ( !iter->user_data) + if (parent != NULL) return FALSE; - */ + + iter->stamp = spreadsheetModel->stamp; + iter->user_data = 0; return TRUE; } + static void -spreadsheet_tree_model_init (GtkTreeModelIface *iface) +spreadsheet_tree_model_init (GtkTreeModelIface * iface) { iface->get_flags = tree_model_get_flags; iface->get_n_columns = tree_model_n_columns; iface->get_column_type = tree_model_column_type; iface->get_iter = tree_model_get_iter; iface->iter_next = tree_model_iter_next; - iface->get_value = tree_model_get_value; -#if 0 - iface->get_path = tree_model_get_path; - iface->iter_children = tree_model_iter_children ; - iface->iter_has_child = tree_model_iter_has_child ; - iface->iter_n_children = tree_model_n_children ; - - iface->iter_parent = tree_model_iter_parent ; -#endif + iface->iter_children = tree_model_children; + iface->iter_parent = NULL; - iface->iter_nth_child = tree_model_nth_child ; + iface->get_path = tree_model_get_path; + iface->iter_has_child = tree_model_iter_has_child; + iface->iter_n_children = tree_model_n_children; + iface->iter_nth_child = tree_model_nth_child; }