[gnumeric] Improve the sc import.
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Improve the sc import.
- Date: Mon, 11 Oct 2010 17:40:33 +0000 (UTC)
commit 75c82a36274d532395d79c883676a6ffee9aa560
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date: Mon Oct 11 11:41:07 2010 -0600
Improve the sc import.
2010-10-11 Andreas J. Guelzow <aguelzow pyrshep ca>
* sc.c (sc_colname_to_coords): new
(sc_cellname_to_coords): use sc_colname_to_coords
(sc_parse_format_set_width): new
(sc_parse_format_free_precision): new
(sc_parse_format_get_precision): new
(sc_parse_format_save_precision): new
(sc_parse_format_apply_precision): new
(sc_parse_format_set_type): new
(sc_parse_format): implement
(sc_parse_fmt): apply precision
(sc_parse_line): use sc_warning
(sc_format_free): new
(sc_file_open): initialize and finalize new fields
2010-10-11 Andreas J. Guelzow <aguelzow pyrshep ca>
* src/undo.c (gnm_undo_colrow_set_sizes_undo): plug leak
ChangeLog | 4 +
plugins/sc/ChangeLog | 16 ++++
plugins/sc/sc.c | 227 +++++++++++++++++++++++++++++++++++++++++++++-----
src/undo.c | 6 +-
4 files changed, 230 insertions(+), 23 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 91cff0d..20d87ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-10-11 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * src/undo.c (gnm_undo_colrow_set_sizes_undo): plug leak
+
2010-10-07 Andreas J. Guelzow <aguelzow pyrshep ca>
* component/Gnumeric-embed.xml.in: add menu items
diff --git a/plugins/sc/ChangeLog b/plugins/sc/ChangeLog
index 6b39fbf..0e66666 100644
--- a/plugins/sc/ChangeLog
+++ b/plugins/sc/ChangeLog
@@ -1,3 +1,19 @@
+2010-10-11 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * sc.c (sc_colname_to_coords): new
+ (sc_cellname_to_coords): use sc_colname_to_coords
+ (sc_parse_format_set_width): new
+ (sc_parse_format_free_precision): new
+ (sc_parse_format_get_precision): new
+ (sc_parse_format_save_precision): new
+ (sc_parse_format_apply_precision): new
+ (sc_parse_format_set_type): new
+ (sc_parse_format): implement
+ (sc_parse_fmt): apply precision
+ (sc_parse_line): use sc_warning
+ (sc_format_free): new
+ (sc_file_open): initialize and finalize new fields
+
2010-10-08 Andreas J. Guelzow <aguelzow pyrshep ca>
* sc.c (sc_parse_set): new
diff --git a/plugins/sc/sc.c b/plugins/sc/sc.c
index b735128..084c483 100644
--- a/plugins/sc/sc.c
+++ b/plugins/sc/sc.c
@@ -34,6 +34,7 @@
#include "parse-util.h"
#include "value.h"
#include "cell.h"
+#include "ranges.h"
#include "style.h"
#include "sheet.h"
#include "expr.h"
@@ -41,6 +42,8 @@
#include "func.h"
#include "sheet-view.h"
#include "selection.h"
+#include "rendered-value.h"
+#include "gnm-style-impl.h"
#include <gsf/gsf-input.h>
#include <gsf/gsf-input-textline.h>
@@ -62,6 +65,8 @@ typedef struct {
GnmConventions *convs;
GOIOContext *context; /* The IOcontext managing things */
char *last_error;
+ GArray *precision;
+ GPtrArray *formats;
} ScParseState;
typedef enum {
@@ -157,36 +162,51 @@ sc_sheet_cell_fetch (ScParseState *state, int col, int row)
return sheet_cell_fetch (state->sheet, col, row);
}
-
-
-/* we can't use cellpos_parse b/c it doesn't support 0 bases (A0, B0, ...) */
-static gboolean
-sc_cellname_to_coords (char const *cellname, GnmCellPos *pos)
+static gint
+sc_colname_to_coords (char const *colname, gint *m)
{
int mult;
+ int digits = 1;
- g_return_val_if_fail (cellname, FALSE);
+ g_return_val_if_fail (colname, FALSE);
- if (!cellname || !*cellname || !g_ascii_isalpha (*cellname))
- goto err_out;
+ if (!colname || !*colname || !g_ascii_isalpha (*colname))
+ return 0;
- mult = g_ascii_toupper (*cellname) - 'A';
+ mult = g_ascii_toupper (*colname) - 'A';
if (mult < 0 || mult > 25)
- goto err_out;
+ return 0;
- cellname++;
+ colname++;
- if (g_ascii_isalpha (*cellname)) {
- int ofs = g_ascii_toupper (*cellname) - 'A';
+ if (g_ascii_isalpha (*colname)) {
+ int ofs = g_ascii_toupper (*colname) - 'A';
if (ofs < 0 || ofs > 25)
- goto err_out;
- pos->col = ((mult + 1) * 26) + ofs;
- cellname++;
+ return 0;
+ mult = ((mult + 1) * 26) + ofs;
+ digits++;
}
- else {
- pos->col = mult;
- }
+ *m = mult;
+
+ return digits;
+}
+
+
+/* we can't use cellpos_parse b/c it doesn't support 0 bases (A0, B0, ...) */
+static gboolean
+sc_cellname_to_coords (char const *cellname, GnmCellPos *pos)
+{
+ int mult, digits;
+
+ g_return_val_if_fail (cellname, FALSE);
+
+ digits = sc_colname_to_coords (cellname, &mult);
+ if (digits == 0)
+ goto err_out;
+
+ pos->col = mult;
+ cellname += digits;
/* XXX need to replace this block with strtol+error checking */
if (1) {
@@ -342,14 +362,159 @@ sc_parse_format_definition (ScParseState *state, char const *cmd, char const *st
return TRUE;
}
+static void
+sc_parse_format_set_width (ScParseState *state, int len, int col_from, int col_to)
+{
+ GnmFont *style_font;
+ int width;
+ int col;
+ GnmStyle *mstyle;
+
+ if (len < 1)
+ return;
+
+ mstyle = gnm_style_new_default ();
+ style_font = gnm_style_get_font
+ (mstyle, state->sheet->rendered_values->context);
+ width = PANGO_PIXELS (len * style_font->go.metrics->avg_digit_width) + 4;
+ gnm_style_unref (mstyle);
+
+ for (col = col_from; col <= col_to; col++)
+ sheet_col_set_size_pixels (state->sheet, col, width, TRUE);
+}
+
+static void
+sc_parse_format_free_precision (ScParseState *state)
+{
+ if (state->precision != NULL)
+ g_array_free (state->precision, TRUE);
+}
+
+static int
+sc_parse_format_get_precision (ScParseState *state, int col)
+{
+ if (state->precision != NULL &&
+ col < (int)state->precision->len) {
+ return (g_array_index(state->precision, int, col) - 1 );
+ } else return -1;
+}
+
+static void
+sc_parse_format_save_precision (ScParseState *state, int precision,
+ int col_from, int col_to)
+{
+ int col;
+
+ if (state->precision == NULL)
+ state->precision = g_array_new (FALSE, TRUE, sizeof (int));
+
+ if (!(col_to < (int)state->precision->len))
+ state->precision = g_array_set_size (state->precision, col_to + 1);
+
+ for (col = col_from; col <= col_to; col++)
+ g_array_index(state->precision, int, col) = precision + 1;
+}
+
+static char *
+sc_parse_format_apply_precision (ScParseState *state, char *format, int col)
+{
+ if (strchr (format, '&')) {
+ GString* str = g_string_new (format);
+ char *amp = str->str;
+ int off = 0;
+
+ g_free (format);
+ while (NULL != (amp = strchr (str->str + off, '&'))) {
+ off = amp - str->str + 1;
+ if (amp == str->str || *(amp - 1) != '\\') {
+ int p = sc_parse_format_get_precision (state, col);
+ int i;
+ if (p == -1) {
+ p = 0;
+ sc_warning (state, _("Encountered precision dependent format without set precision."));
+ }
+ off--;
+ g_string_erase (str, off, 1);
+ for (i = 0; i < p; i++)
+ g_string_insert_c (str, off, '0');
+ }
+
+ }
+ format = g_string_free (str, FALSE);
+ }
+ return format;
+}
+
+static void
+sc_parse_format_set_type (ScParseState *state, int type, int col_from, int col_to)
+{
+ char const *o_format = g_ptr_array_index(state->formats, type);
+ int col;
+
+ if (o_format == NULL) {
+ sc_warning (state, _("Column format %i is undefined."), type);
+ return;
+ }
+ for (col = col_from; col <= col_to; col++) {
+ char *fmt = g_strdup (o_format);
+ GOFormat *gfmt;
+ GnmStyle *style;
+ GnmRange range;
+ range_init_cols (&range, state->sheet, col, col);
+ fmt = sc_parse_format_apply_precision (state, fmt, col);
+ gfmt = go_format_new_from_XL (fmt);
+ style = gnm_style_new_default ();
+ gnm_style_set_format (style, gfmt);
+ sheet_style_apply_range (state->sheet, &range, style);
+ /* gnm_style_unref (style); reference has been absorbed */
+ go_format_unref (gfmt);
+ g_free (fmt);
+ }
+
+}
+
static gboolean
sc_parse_format (ScParseState *state, char const *cmd, char const *str,
GnmCellPos const *cpos)
{
+ char const *s = str;
+ int col_from = -1, col_to = -1, d;
+ int len = 0, precision = 0, format_type = 0;
+
if (g_ascii_isdigit ((gchar) *str))
return sc_parse_format_definition (state, cmd, str);
- sc_warning (state, "Ignoring column formatting: %s", str);
+
+ d = sc_colname_to_coords (s, &col_from);
+
+ if (d == 0)
+ goto cannotparse;
+
+ s += d;
+ if (*s == ':') {
+ s++;
+ d = sc_colname_to_coords (s, &col_to);
+ if (d == 0)
+ goto cannotparse;
+ s += d;
+ } else
+ col_to= col_from;
+ while (*s == ' ')
+ s++;
+
+ d = sscanf(s, "%i %i %i", &len, &precision, &format_type);
+
+ if (d != 3)
+ goto cannotparse;
+
+ if (len > 0)
+ sc_parse_format_set_width (state, len, col_from, col_to);
+ sc_parse_format_save_precision (state, precision, col_from, col_to);
+ sc_parse_format_set_type (state, format_type, col_from, col_to);
+
return TRUE;
+ cannotparse:
+ sc_warning (state, "Unable to parse: %s %s", cmd, str);
+ return FALSE;
}
static gboolean
@@ -376,6 +541,7 @@ sc_parse_fmt (ScParseState *state, char const *cmd, char const *str,
if (!space)
return FALSE;
fmt = g_strndup (s, space - s);
+ fmt = sc_parse_format_apply_precision (state, fmt, pos.col);
gfmt = go_format_new_from_XL (fmt);
style = gnm_style_new_default ();
gnm_style_set_format (style, gfmt);
@@ -714,7 +880,7 @@ sc_parse_line (ScParseState *state, char *buf)
if (cmd->have_coord) {
if (!sc_parse_coord (state, &strdata, &pos)) {
- g_printerr ("Cannot parse %s\n",
+ sc_warning (state, "Cannot parse %s\n",
buf);
return FALSE;
}
@@ -814,6 +980,11 @@ sc_conventions (void)
return conv;
}
+static void
+sc_format_free (gpointer data, gpointer user_data)
+{
+ g_free (data);
+}
void
sc_file_open (GOFileOpener const *fo, GOIOContext *io_context,
@@ -836,6 +1007,15 @@ sc_file_open (GOFileOpener const *fo, GOIOContext *io_context,
state.convs = sc_conventions ();
state.context = io_context;
state.last_error = NULL;
+ state.precision = NULL;
+ state.formats = g_ptr_array_sized_new (10);
+ g_ptr_array_add (state.formats, g_strdup ("#.&")); /* 0 */
+ g_ptr_array_add (state.formats, g_strdup ("0.&E+00")); /* 1 */
+ g_ptr_array_add (state.formats, g_strdup ("##0.&E+00")); /* 2 */
+ g_ptr_array_add (state.formats, g_strdup ("[$-f8f2]m/d/yy")); /* 3 */
+ g_ptr_array_add (state.formats, g_strdup ("[$-f800]dddd, mmmm dd, yyyy")); /* 4 */
+ g_ptr_array_set_size (state.formats, 10);
+
state.textline = (GsfInputTextline *) gsf_input_textline_new (input);
error = sc_parse_sheet (&state);
if (error != NULL) {
@@ -846,6 +1026,11 @@ sc_file_open (GOFileOpener const *fo, GOIOContext *io_context,
g_iconv_close (state.converter);
gnm_conventions_unref (state.convs);
g_free (state.last_error);
+ sc_parse_format_free_precision (&state);
+
+ /*In glib 2.22 or later we could use g_ptr_array_set_free_func */
+ g_ptr_array_foreach (state.formats, (GFunc) sc_format_free, NULL);
+ g_ptr_array_unref (state.formats);
}
diff --git a/src/undo.c b/src/undo.c
index cdcd1c9..c08304a 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -111,9 +111,11 @@ static void
gnm_undo_colrow_set_sizes_undo (GOUndo *u, gpointer data)
{
GNMUndoColrowSetSizes *ua = (GNMUndoColrowSetSizes *)u;
+ ColRowStateGroup *group;
- colrow_set_sizes (ua->sheet, ua->is_cols, ua->selection, ua->new_size,
- ua->from, ua->to);
+ group = colrow_set_sizes (ua->sheet, ua->is_cols, ua->selection, ua->new_size,
+ ua->from, ua->to);
+ colrow_state_group_destroy (group);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]