From: John Darrington Date: Sun, 13 Jan 2013 09:27:28 +0000 (+0100) Subject: Made a start at canonicalising the interface X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f8a1592964567db640915d3019af0e25e30bbb6;p=pspp Made a start at canonicalising the interface --- diff --git a/src/data/gnumeric-reader.c b/src/data/gnumeric-reader.c index 6cc7b3e1c2..cfdd45424d 100644 --- a/src/data/gnumeric-reader.c +++ b/src/data/gnumeric-reader.c @@ -75,7 +75,9 @@ static const struct casereader_class gnm_file_casereader_class = enum reader_state { - STATE_INIT = 0, /* Initial state */ + STATE_PRE_INIT = 0, /* Initial state */ + STATE_SHEET_COUNT, /* Found the sheet index */ + STATE_INIT , /* Other Initial state */ STATE_SHEET_START, /* Found the start of a sheet */ STATE_SHEET_NAME, /* Found the sheet name */ STATE_MAXROW, @@ -87,9 +89,15 @@ enum reader_state struct gnumeric_reader { + struct spreadsheet spreadsheet; + xmlTextReaderPtr xtr; enum reader_state state; + + /* The total number of sheets in the "workbook" */ + int sheet_total ; + int row; int col; int min_col; @@ -144,6 +152,28 @@ process_node (struct gnumeric_reader *r) switch ( r->state) { + case STATE_PRE_INIT: + if (0 == xmlStrcasecmp (name, _xml("gnm:SheetNameIndex")) && + XML_READER_TYPE_ELEMENT == r->node_type) + { + r->state = STATE_SHEET_COUNT; + r->sheet_total = 0; + } + break; + + case STATE_SHEET_COUNT: + if (0 == xmlStrcasecmp (name, _xml("gnm:SheetName")) && + XML_READER_TYPE_ELEMENT == r->node_type) + { + r->sheet_total++; + } + else if (0 == xmlStrcasecmp (name, _xml("gnm:SheetNameIndex")) && + XML_READER_TYPE_END_ELEMENT == r->node_type) + { + r->state = STATE_INIT; + } + break; + case STATE_INIT: if (0 == xmlStrcasecmp (name, _xml("gnm:Sheet")) && XML_READER_TYPE_ELEMENT == r->node_type) @@ -275,6 +305,58 @@ struct var_spec xmlChar *first_value; }; +struct spreadsheet * +gnumeric_probe (const char *filename) +{ + int ret; + struct gnumeric_reader *r = NULL; + xmlTextReaderPtr xtr; + + gzFile gz = gzopen (filename, "r"); + + if (NULL == gz) + return NULL; + + xtr = xmlReaderForIO ((xmlInputReadCallback) gzread, + (xmlInputCloseCallback) gzclose, gz, + NULL, NULL, 0); + + if (xtr == NULL) + return NULL; + + r = xzalloc (sizeof *r); + + r->xtr = xtr; + r->sheet_total = -1; + r->state = STATE_PRE_INIT; + + + /* Advance to the start of the workbook. + This gives us some confidence that we are actually dealing with a gnumeric + spreadsheet. + */ + while ( (r->state != STATE_INIT ) + && 1 == (ret = xmlTextReaderRead (r->xtr))) + { + process_node (r); + } + + if (ret != 1) + { + /* Not a gnumeric spreadsheet */ + free (r); + gzclose (gz); + return NULL; + } + + r->spreadsheet.type = SPREADSHEET_GNUMERIC; + r->spreadsheet.sheets = r->sheet_total; + r->spreadsheet.make_reader = NULL; + + + return &r->spreadsheet; +} + struct casereader * gnumeric_open_reader (const struct spreadsheet_read_info *gri, struct spreadsheet_read_options *opts, @@ -287,27 +369,16 @@ gnumeric_open_reader (const struct spreadsheet_read_info *gri, struct var_spec *var_spec = NULL; int n_var_specs = 0; + struct spreadsheet * spreadsheet = NULL; struct gnumeric_reader *r = NULL; - gzFile gz = gzopen (gri->file_name, "r"); - - if ( NULL == gz) - { - msg (ME, _("Error opening `%s' for reading as a Gnumeric file: %s."), - gri->file_name, strerror (errno)); - - goto error; - } - - r = xzalloc (sizeof *r); + spreadsheet = gnumeric_probe (gri->file_name); - r->xtr = xmlReaderForIO ((xmlInputReadCallback) gzread, - (xmlInputCloseCallback) gzclose, gz, - NULL, NULL, 0); - - if ( r->xtr == NULL ) + if (spreadsheet == NULL) goto error; + r = (struct gnumeric_reader *) (spreadsheet); + if ( opts->cell_range ) { if ( ! convert_cell_ref (opts->cell_range, @@ -327,7 +398,7 @@ gnumeric_open_reader (const struct spreadsheet_read_info *gri, r->stop_row = -1; } - r->state = STATE_INIT; + r->target_sheet = BAD_CAST opts->sheet_name; r->target_sheet_index = opts->sheet_index; r->row = r->col = -1; diff --git a/src/data/gnumeric-reader.h b/src/data/gnumeric-reader.h index f1af5e56ee..529670e35c 100644 --- a/src/data/gnumeric-reader.h +++ b/src/data/gnumeric-reader.h @@ -24,6 +24,9 @@ struct dictionary; struct spreadsheet_read_info; struct spreadsheet_read_options; + +struct spreadsheet *gnumeric_probe (const char *filename); + struct casereader * gnumeric_open_reader (const struct spreadsheet_read_info *, struct spreadsheet_read_options *, struct dictionary **); diff --git a/src/data/ods-reader.c b/src/data/ods-reader.c index 097c245d17..85d3bc7dc1 100644 --- a/src/data/ods-reader.c +++ b/src/data/ods-reader.c @@ -88,6 +88,8 @@ enum reader_state struct ods_reader { + struct spreadsheet spreadsheet; + xmlTextReaderPtr xtr; enum reader_state state; diff --git a/src/data/spreadsheet-reader.c b/src/data/spreadsheet-reader.c index 11e8cf593a..3572a03ce4 100644 --- a/src/data/spreadsheet-reader.c +++ b/src/data/spreadsheet-reader.c @@ -22,6 +22,24 @@ #include #include + +struct spreadsheet * +spreadsheet_open (const char *filename) +{ + struct spreadsheet *ss = NULL; + + ss = gnumeric_probe (filename); + + return ss; +} + +void +spreadsheet_close (struct spreadsheet *spreadsheet) +{ +} + + + /* Convert a string, which is an integer encoded in base26 IE, A=0, B=1, ... Z=25 to the integer it represents. ... except that in this scheme, digits with an exponent diff --git a/src/data/spreadsheet-reader.h b/src/data/spreadsheet-reader.h index 6ea0bde4a4..d25aaf32f6 100644 --- a/src/data/spreadsheet-reader.h +++ b/src/data/spreadsheet-reader.h @@ -52,5 +52,39 @@ bool convert_cell_ref (const char *ref, #define _xmlchar_to_int(X) (atoi(CHAR_CAST (const char *, X))) +enum spreadsheet_type + { + SPREADSHEET_GNUMERIC, + SPREADSHEET_ODS + }; + +struct spreadsheet +{ + enum spreadsheet_type type; + + struct casereader * (*make_reader) (struct spreadsheet *); + + /* The total number of sheets in the "workbook" */ + int sheets; + + /* The dictionary */ + struct dictionary *dict; +}; + +/* + Attempt to open the file called FILENAME as a spreadsheet. + It is not known a priori, what type of spreadsheet FILENAME is, or + even if it is a spreadsheet at all. + If it fails to open, then it will return NULL without any error or + warning messages. + */ +struct spreadsheet * spreadsheet_open (const char *filename); +void spreadsheet_close (struct spreadsheet *); + +struct casereeader; +struct casereader * spreadsheet_make_reader (struct spreadsheet *s); + + +#define SPREADSHEET_CAST(X) ((struct spreadsheet *)(X)) #endif diff --git a/src/ui/gui/page-assistant.c b/src/ui/gui/page-assistant.c index 70c658d371..9ef5782a30 100644 --- a/src/ui/gui/page-assistant.c +++ b/src/ui/gui/page-assistant.c @@ -159,11 +159,17 @@ on_prepare (GtkAssistant *assistant, GtkWidget *page, else gtk_widget_grab_focus (assistant->forward); + + /* Prepare .... */ if (page == ia->separators.page) prepare_separators_page (ia); else if (page == ia->formats.page) prepare_formats_page (ia); + else if (page == ia->sheet_spec.page) + prepare_sheet_spec_page (ia); + + gtk_widget_show (ia->asst.reset_button); if (page == ia->formats.page) gtk_widget_show (ia->asst.paste_button); diff --git a/src/ui/gui/page-file.c b/src/ui/gui/page-file.c index a3aaf03749..ac751e8f97 100644 --- a/src/ui/gui/page-file.c +++ b/src/ui/gui/page-file.c @@ -137,8 +137,7 @@ init_file (struct import_assistant *ia, GtkWindow *parent_window) { enum { MAX_LINE_LEN = 16384 }; /* Max length of an acceptable line. */ struct file *file = &ia->file; - struct casereader *creader = NULL; - struct dictionary *dict = NULL; + struct sheet_spec_page *ssp = &ia->sheet_spec; struct spreadsheet_read_info sri; struct spreadsheet_read_options opts; @@ -155,25 +154,34 @@ init_file (struct import_assistant *ia, GtkWindow *parent_window) sri.read_names = true; sri.asw = -1; - if (!creader) - { - creader = gnumeric_open_reader (&sri, &opts, &dict); - ia->file.type = FTYPE_GNUMERIC; - } - - if (!creader) + ssp->spreadsheet = gnumeric_probe (sri.file_name); + + if (ssp->spreadsheet) { - creader = ods_open_reader (&sri, &opts, &dict); - ia->file.type = FTYPE_ODS; - } + struct casereader *creader = NULL; + struct dictionary *dict = NULL; + + if (ssp->spreadsheet->type == SPREADSHEET_GNUMERIC) + { + ia->file.type = FTYPE_GNUMERIC; + } + else if (ssp->spreadsheet->type == SPREADSHEET_ODS) + { + ia->file.type = FTYPE_ODS; + } + else + { + assert (0); + } - if (creader && dict) - { - struct sheet_spec_page *ssp = &ia->sheet_spec; - ssp->dict = dict; - ssp->reader = creader; + { + struct sheet_spec_page *ssp = &ia->sheet_spec; + ssp->dict = dict; + ssp->reader = creader; + + update_assistant (ia); + } - update_assistant (ia); } else { diff --git a/src/ui/gui/page-sheet-spec.c b/src/ui/gui/page-sheet-spec.c index 1c72e830e0..8f8bb381cc 100644 --- a/src/ui/gui/page-sheet-spec.c +++ b/src/ui/gui/page-sheet-spec.c @@ -80,6 +80,22 @@ init_sheet_spec_page (struct import_assistant *ia) } +/* Prepares IA's sheet_spec page. */ +void +prepare_sheet_spec_page (struct import_assistant *ia) +{ + struct sheet_spec_page *p = &ia->sheet_spec; + + GtkBuilder *builder = ia->asst.builder; + GtkWidget *sheet_entry = get_widget_assert (builder, "sheet-entry"); + + printf ("%s %d\n", __FUNCTION__, p->spreadsheet->sheets); + + gtk_spin_button_set_digits (GTK_SPIN_BUTTON (sheet_entry), 0); + gtk_spin_button_set_range (GTK_SPIN_BUTTON (sheet_entry), 1, p->spreadsheet->sheets); +} + + /* Resets IA's sheet_spec page to its initial state. */ void reset_sheet_spec_page (struct import_assistant *ia) @@ -109,16 +125,15 @@ post_sheet_spec_page (struct import_assistant *ia) GtkWidget *range_entry = get_widget_assert (builder, "cell-range-entry"); GtkWidget *readnames_checkbox = get_widget_assert (builder, "readnames-checkbox"); - gint num = atoi (gtk_entry_get_text (GTK_ENTRY (sheet_entry))); + gint num = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sheet_entry)); const gchar *range = gtk_entry_get_text (GTK_ENTRY (range_entry)); - if ( num < 1 ) num = 1; ssp->opts.sheet_name = NULL; - ssp->opts.cell_range = range; + ssp->opts.cell_range = NULL; ssp->opts.sheet_index = num; if ( convert_cell_ref (range, &col_start, &row_start, &col_stop, &row_stop)) diff --git a/src/ui/gui/text-data-import-dialog.h b/src/ui/gui/text-data-import-dialog.h index b465d04ddf..55064574f1 100644 --- a/src/ui/gui/text-data-import-dialog.h +++ b/src/ui/gui/text-data-import-dialog.h @@ -70,7 +70,8 @@ struct sheet_spec_page GtkWidget *page; struct casereader *reader; struct dictionary *dict; - + struct spreadsheet *spreadsheet; + struct spreadsheet_read_info sri; struct spreadsheet_read_options opts; }; @@ -213,6 +214,7 @@ void init_intro_page (struct import_assistant *); void reset_intro_page (struct import_assistant *); void init_sheet_spec_page (struct import_assistant *); +void prepare_sheet_spec_page (struct import_assistant *ia); void reset_sheet_spec_page (struct import_assistant *); void post_sheet_spec_page (struct import_assistant *ia); diff --git a/src/ui/gui/text-data-import.ui b/src/ui/gui/text-data-import.ui index d05296a7d7..62bdf94717 100644 --- a/src/ui/gui/text-data-import.ui +++ b/src/ui/gui/text-data-import.ui @@ -666,6 +666,12 @@ The selected file contains N lines of text. Only the first M of these will be s 1 10 + + 1 + 100 + 1 + 10 + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 @@ -721,10 +727,11 @@ The selected file contains N lines of text. Only the first M of these will be s - + True True + adjustment3 1