src/ui/gui/page-first-line.c \
src/ui/gui/page-formats.c \
src/ui/gui/page-separators.c \
+ src/ui/gui/page-sheet-spec.c \
src/ui/gui/text-data-import-dialog.c \
src/ui/gui/text-data-import-dialog.h \
src/ui/gui/transpose-dialog.c \
#include "data/data-in.h"
#include "data/data-out.h"
#include "data/format-guesser.h"
+#include "data/gnumeric-reader.h"
+#include "data/spreadsheet-reader.h"
#include "data/value-labels.h"
#include "language/data-io/data-parser.h"
#include "language/lexer/lexer.h"
init_file (struct import_assistant *ia, GtkWindow *parent_window)
{
struct file *file = &ia->file;
- enum { MAX_PREVIEW_LINES = 1000 }; /* Max number of lines to read. */
- enum { MAX_LINE_LEN = 16384 }; /* Max length of an acceptable line. */
- struct line_reader *reader;
- struct string input;
-
file->file_name = choose_file (parent_window, &file->encoding);
if (file->file_name == NULL)
return false;
- reader = line_reader_for_file (file->encoding, file->file_name, O_RDONLY);
- if (reader == NULL)
- {
- msg (ME, _("Could not open `%s': %s"),
- file->file_name, strerror (errno));
- return false;
- }
-
- ds_init_empty (&input);
- file->lines = xnmalloc (MAX_PREVIEW_LINES, sizeof *file->lines);
- for (; file->line_cnt < MAX_PREVIEW_LINES; file->line_cnt++)
- {
- ds_clear (&input);
- if (!line_reader_read (reader, &input, MAX_LINE_LEN + 1)
- || ds_length (&input) > MAX_LINE_LEN)
- {
- if (line_reader_eof (reader))
- break;
- else if (line_reader_error (reader))
- msg (ME, _("Error reading `%s': %s"),
- file->file_name, strerror (line_reader_error (reader)));
- else
- msg (ME, _("Failed to read `%s', because it contains a line "
- "over %d bytes long and therefore appears not to be "
- "a text file."),
- file->file_name, MAX_LINE_LEN);
- line_reader_close (reader);
- destroy_file (ia);
- ds_destroy (&input);
- return false;
- }
-
- ds_init_cstr (&file->lines[file->line_cnt],
- recode_string ("UTF-8", line_reader_get_encoding (reader),
- ds_cstr (&input), ds_length (&input)));
- }
- ds_destroy (&input);
-
- if (file->line_cnt == 0)
- {
- msg (ME, _("`%s' is empty."), file->file_name);
- line_reader_close (reader);
- destroy_file (ia);
- return false;
- }
-
- /* Estimate the number of lines in the file. */
- if (file->line_cnt < MAX_PREVIEW_LINES)
- file->total_lines = file->line_cnt;
- else
- {
- struct stat s;
- off_t position = line_reader_tell (reader);
- if (fstat (line_reader_fileno (reader), &s) == 0 && position > 0)
- file->total_lines = (double) file->line_cnt / position * s.st_size;
- else
- file->total_lines = 0;
- }
-
- line_reader_close (reader);
+ struct dictionary *dict = NULL;
+ struct spreadsheet_read_info sri;
+
+ sri.sheet_name = NULL;
+ sri.file_name = file->file_name;
+ sri.cell_range = NULL;
+ sri.sheet_index = 1;
+ sri.read_names = true;
+ sri.asw = 0;
+
+ struct casereader *creader = gnumeric_open_reader (&sri, &dict);
+ printf ("%s:%d %s\n", __FILE__, __LINE__, sri.file_name);
+ ia->file.type = FTYPE_SPREADSHEET;
+
+ if (creader == NULL)
+ {
+ enum { MAX_PREVIEW_LINES = 1000 }; /* Max number of lines to read. */
+ enum { MAX_LINE_LEN = 16384 }; /* Max length of an acceptable line. */
+
+ struct string input;
+ struct line_reader *reader = line_reader_for_file (file->encoding, file->file_name, O_RDONLY);
+ if (reader == NULL)
+ {
+ msg (ME, _("Could not open `%s': %s"),
+ file->file_name, strerror (errno));
+ return false;
+ }
+
+ ds_init_empty (&input);
+ file->lines = xnmalloc (MAX_PREVIEW_LINES, sizeof *file->lines);
+ for (; file->line_cnt < MAX_PREVIEW_LINES; file->line_cnt++)
+ {
+ ds_clear (&input);
+ if (!line_reader_read (reader, &input, MAX_LINE_LEN + 1)
+ || ds_length (&input) > MAX_LINE_LEN)
+ {
+ if (line_reader_eof (reader))
+ break;
+ else if (line_reader_error (reader))
+ msg (ME, _("Error reading `%s': %s"),
+ file->file_name, strerror (line_reader_error (reader)));
+ else
+ msg (ME, _("Failed to read `%s', because it contains a line "
+ "over %d bytes long and therefore appears not to be "
+ "a text file."),
+ file->file_name, MAX_LINE_LEN);
+ line_reader_close (reader);
+ destroy_file (ia);
+ ds_destroy (&input);
+ return false;
+ }
+
+ ds_init_cstr (&file->lines[file->line_cnt],
+ recode_string ("UTF-8", line_reader_get_encoding (reader),
+ ds_cstr (&input), ds_length (&input)));
+ }
+ ds_destroy (&input);
+
+ if (file->line_cnt == 0)
+ {
+ msg (ME, _("`%s' is empty."), file->file_name);
+ line_reader_close (reader);
+ destroy_file (ia);
+ return false;
+ }
+
+ /* Estimate the number of lines in the file. */
+ if (file->line_cnt < MAX_PREVIEW_LINES)
+ file->total_lines = file->line_cnt;
+ else
+ {
+ struct stat s;
+ off_t position = line_reader_tell (reader);
+ if (fstat (line_reader_fileno (reader), &s) == 0 && position > 0)
+ file->total_lines = (double) file->line_cnt / position * s.st_size;
+ else
+ file->total_lines = 0;
+ }
+
+ line_reader_close (reader);
+ ia->file.type = FTYPE_TEXT;
+ }
return true;
}
GtkBin *vars_scroller;
GtkWidget *old_var_sheet;
PsppireVarSheet *var_sheet;
- struct separators_page *s = &ia->separators;
+ struct separators_page *seps = &ia->separators;
struct formats_page *p = &ia->formats;
struct fmt_guesser *fg;
unsigned long int number = 0;
dict = dict_create (get_default_encoding ());
fg = fmt_guesser_create ();
- for (column_idx = 0; column_idx < s->column_cnt; column_idx++)
+ printf ("%s:%d Column count %d\n", __FILE__, __LINE__, seps->column_cnt);
+ for (column_idx = 0; column_idx < seps->column_cnt; column_idx++)
{
struct variable *modified_var;
? p->modified_vars[column_idx] : NULL);
if (modified_var == NULL)
{
- struct column *column = &s->columns[column_idx];
+ struct column *column = &seps->columns[column_idx];
struct variable *var;
struct fmt_spec format;
char *name;
--- /dev/null
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2013 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "ui/gui/text-data-import-dialog.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <gtk-contrib/psppire-sheet.h>
+#include <gtk/gtk.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "data/data-in.h"
+#include "data/data-out.h"
+#include "data/format-guesser.h"
+#include "data/value-labels.h"
+#include "language/data-io/data-parser.h"
+#include "language/lexer/lexer.h"
+#include "libpspp/assertion.h"
+#include "libpspp/i18n.h"
+#include "libpspp/line-reader.h"
+#include "libpspp/message.h"
+#include "ui/gui/checkbox-treeview.h"
+#include "ui/gui/dialog-common.h"
+#include "ui/gui/executor.h"
+#include "ui/gui/helper.h"
+#include "ui/gui/builder-wrapper.h"
+#include "ui/gui/psppire-data-window.h"
+#include "ui/gui/psppire-dialog.h"
+#include "ui/gui/psppire-encoding-selector.h"
+#include "ui/gui/psppire-empty-list-store.h"
+#include "ui/gui/psppire-var-sheet.h"
+#include "ui/gui/psppire-var-store.h"
+#include "ui/gui/psppire-scanf.h"
+#include "ui/syntax-gen.h"
+
+#include "gl/error.h"
+#include "gl/intprops.h"
+#include "gl/xalloc.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+struct import_assistant;
+
+
+\f
+/* The "sheet-spec" page of the assistant. */
+
+
+/* Initializes IA's sheet_spec substructure. */
+void
+init_sheet_spec_page (struct import_assistant *ia)
+{
+ GtkBuilder *builder = ia->asst.builder;
+ struct sheet_spec_page *p = &ia->sheet_spec;
+
+ p->page = add_page_to_assistant (ia, get_widget_assert (builder, "Sheet"),
+ GTK_ASSISTANT_PAGE_INTRO);
+
+}
+
+/* Resets IA's sheet_spec page to its initial state. */
+void
+reset_sheet_spec_page (struct import_assistant *ia)
+{
+}
+
return;
}
+ printf ("%s:%d %s\n", __FILE__, __LINE__, ia->file.file_name);
+
init_assistant (ia, parent_window);
- init_intro_page (ia);
- init_first_line_page (ia);
- init_separators_page (ia);
+ if ( ia->file.type == FTYPE_TEXT)
+ {
+ init_intro_page (ia);
+ init_first_line_page (ia);
+ init_separators_page (ia);
+ }
+ else
+ {
+ init_sheet_spec_page (ia);
+ }
+
init_formats_page (ia);
gtk_widget_show_all (GTK_WIDGET (ia->asst.assistant));
break;
}
- destroy_formats_page (ia);
- destroy_separators_page (ia);
+ if ( ia->file.type == FTYPE_TEXT)
+ {
+ destroy_formats_page (ia);
+ destroy_separators_page (ia);
+ }
+
destroy_assistant (ia);
destroy_file (ia);
free (ia);
generate_syntax (const struct import_assistant *ia)
{
struct string s = DS_EMPTY_INITIALIZER;
- size_t var_cnt;
- size_t i;
- syntax_gen_pspp (&s,
- "GET DATA\n"
- " /TYPE=TXT\n"
- " /FILE=%sq\n",
- ia->file.file_name);
- if (ia->file.encoding && strcmp (ia->file.encoding, "Auto"))
- syntax_gen_pspp (&s, " /ENCODING=%sq\n", ia->file.encoding);
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
- ia->intro.n_cases_button)))
- ds_put_format (&s, " /IMPORTCASES=FIRST %d\n",
- gtk_spin_button_get_value_as_int (
- GTK_SPIN_BUTTON (ia->intro.n_cases_spin)));
- else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
- ia->intro.percent_button)))
- ds_put_format (&s, " /IMPORTCASES=PERCENT %d\n",
- gtk_spin_button_get_value_as_int (
- GTK_SPIN_BUTTON (ia->intro.percent_spin)));
+ if (ia->file.type == FTYPE_TEXT)
+ {
+ size_t var_cnt;
+ size_t i;
+ syntax_gen_pspp (&s,
+ "GET DATA\n"
+ " /TYPE=TXT\n"
+ " /FILE=%sq\n",
+ ia->file.file_name);
+ if (ia->file.encoding && strcmp (ia->file.encoding, "Auto"))
+ syntax_gen_pspp (&s, " /ENCODING=%sq\n", ia->file.encoding);
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
+ ia->intro.n_cases_button)))
+ ds_put_format (&s, " /IMPORTCASES=FIRST %d\n",
+ gtk_spin_button_get_value_as_int (
+ GTK_SPIN_BUTTON (ia->intro.n_cases_spin)));
+ else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
+ ia->intro.percent_button)))
+ ds_put_format (&s, " /IMPORTCASES=PERCENT %d\n",
+ gtk_spin_button_get_value_as_int (
+ GTK_SPIN_BUTTON (ia->intro.percent_spin)));
+ else
+ ds_put_cstr (&s, " /IMPORTCASES=ALL\n");
+ ds_put_cstr (&s,
+ " /ARRANGEMENT=DELIMITED\n"
+ " /DELCASE=LINE\n");
+ if (ia->first_line.skip_lines > 0)
+ ds_put_format (&s, " /FIRSTCASE=%d\n", ia->first_line.skip_lines + 1);
+ ds_put_cstr (&s, " /DELIMITERS=\"");
+ if (ds_find_byte (&ia->separators.separators, '\t') != SIZE_MAX)
+ ds_put_cstr (&s, "\\t");
+ if (ds_find_byte (&ia->separators.separators, '\\') != SIZE_MAX)
+ ds_put_cstr (&s, "\\\\");
+ for (i = 0; i < ds_length (&ia->separators.separators); i++)
+ {
+ char c = ds_at (&ia->separators.separators, i);
+ if (c == '"')
+ ds_put_cstr (&s, "\"\"");
+ else if (c != '\t' && c != '\\')
+ ds_put_byte (&s, c);
+ }
+ ds_put_cstr (&s, "\"\n");
+ if (!ds_is_empty (&ia->separators.quotes))
+ syntax_gen_pspp (&s, " /QUALIFIER=%sq\n", ds_cstr (&ia->separators.quotes));
+ if (!ds_is_empty (&ia->separators.quotes) && ia->separators.escape)
+ ds_put_cstr (&s, " /ESCAPE\n");
+ ds_put_cstr (&s, " /VARIABLES=\n");
+
+ var_cnt = dict_get_var_cnt (ia->formats.dict);
+ for (i = 0; i < var_cnt; i++)
+ {
+ struct variable *var = dict_get_var (ia->formats.dict, i);
+ char format_string[FMT_STRING_LEN_MAX + 1];
+ fmt_to_string (var_get_print_format (var), format_string);
+ ds_put_format (&s, " %s %s%s\n",
+ var_get_name (var), format_string,
+ i == var_cnt - 1 ? "." : "");
+ }
+
+ apply_dict (ia->formats.dict, &s);
+ }
else
- ds_put_cstr (&s, " /IMPORTCASES=ALL\n");
- ds_put_cstr (&s,
- " /ARRANGEMENT=DELIMITED\n"
- " /DELCASE=LINE\n");
- if (ia->first_line.skip_lines > 0)
- ds_put_format (&s, " /FIRSTCASE=%d\n", ia->first_line.skip_lines + 1);
- ds_put_cstr (&s, " /DELIMITERS=\"");
- if (ds_find_byte (&ia->separators.separators, '\t') != SIZE_MAX)
- ds_put_cstr (&s, "\\t");
- if (ds_find_byte (&ia->separators.separators, '\\') != SIZE_MAX)
- ds_put_cstr (&s, "\\\\");
- for (i = 0; i < ds_length (&ia->separators.separators); i++)
- {
- char c = ds_at (&ia->separators.separators, i);
- if (c == '"')
- ds_put_cstr (&s, "\"\"");
- else if (c != '\t' && c != '\\')
- ds_put_byte (&s, c);
- }
- ds_put_cstr (&s, "\"\n");
- if (!ds_is_empty (&ia->separators.quotes))
- syntax_gen_pspp (&s, " /QUALIFIER=%sq\n", ds_cstr (&ia->separators.quotes));
- if (!ds_is_empty (&ia->separators.quotes) && ia->separators.escape)
- ds_put_cstr (&s, " /ESCAPE\n");
- ds_put_cstr (&s, " /VARIABLES=\n");
-
- var_cnt = dict_get_var_cnt (ia->formats.dict);
- for (i = 0; i < var_cnt; i++)
{
- struct variable *var = dict_get_var (ia->formats.dict, i);
- char format_string[FMT_STRING_LEN_MAX + 1];
- fmt_to_string (var_get_print_format (var), format_string);
- ds_put_format (&s, " %s %s%s\n",
- var_get_name (var), format_string,
- i == var_cnt - 1 ? "." : "");
+ syntax_gen_pspp (&s,
+ "GET DATA\n"
+ " /TYPE=GNM\n"
+ " /FILE=%sq\n",
+ ia->file.file_name);
}
- apply_dict (ia->formats.dict, &s);
return ds_cstr (&s);
}
#include "libpspp/str.h"
+enum file_type
+ {
+ FTYPE_TEXT,
+ FTYPE_SPREADSHEET
+ };
+
/* The file to be imported. */
struct file
{
char *file_name; /* File name. */
+
+ enum file_type type;
+
+ /* Relevant only for text files */
+
gchar *encoding; /* Encoding. */
unsigned long int total_lines; /* Number of lines in file. */
bool total_is_exact; /* Is total_lines exact (or an estimate)? */
GtkCellRenderer *fixed_renderer;
};
+
+/* The sheet_spec page of the assistant (only relevant for spreadsheet imports). */
+struct sheet_spec_page
+ {
+ GtkWidget *page;
+ };
+
+
/* The introduction page of the assistant. */
struct intro_page
{
struct file file;
struct assistant asst;
struct intro_page intro;
+ struct sheet_spec_page sheet_spec;
struct first_line_page first_line;
struct separators_page separators;
struct formats_page formats;
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
+ <object class="GtkWindow" id="Sheet">
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">12</property>
+ <property name="title" translatable="yes">Importing Textual Data</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="intro-label1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Enter below the sheet number and the cell range which you wish to import.</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment4">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xscale">0</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment7">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkTable" id="table3">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <child>
+ <object class="GtkEntry" id="cell-range-entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="sheet-entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="cell-range-label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Cells: </property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">cell-range-entry</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="sheet-label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Sheet Index: </property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">sheet-entry</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes"><b>Cells to Import</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
</interface>