Commit 65117ffa authored by Jody Goldberg's avatar Jody Goldberg Committed by Jody Goldberg

http://bugzilla.gnome.org/show_bug.cgi?id=127625 kludge around autofilters


2003-12-13  Jody Goldberg <jody@gnome.org>

	http://bugzilla.gnome.org/show_bug.cgi?id=127625
	* ms-excel-read.c (excel_sheet_destroy) : kludge around autofilters in
	 XL97 that have no related drop downs (eg guia.xls)
parent fca0a495
......@@ -9,13 +9,11 @@ Release Critical
----------------
http://bugzilla.gnome.org/show_bug.cgi?id=128524 [invalid xl export]
http://bugzilla.gnome.org/show_bug.cgi?id=128565 [comment renamed xml]
http://bugzilla.gnome.org/show_bug.cgi?id=127203 [x axis child pos]
: X axis label seperation
: warnings in billmrec.xls
: text in boxes for text-xls/pivot.xls is white [xl95 pallette id=9]
: box colors and warnings in christ95.xls
: guia.xls complains of problems importing autofilter
Worries
http://bugzilla.gnome.org/show_bug.cgi?id=123781
......
2003-12-13 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=127625
* ms-excel-read.c (excel_sheet_destroy) : kludge around autofilters in
XL97 that have no related drop downs (eg guia.xls)
2003-11-26 Jody Goldberg <jody@gnome.org>
* Release 1.2.2
......
......@@ -6,7 +6,7 @@
* Michael Meeks (michael@ximian.com)
* Jody Goldberg (jody@gnome.org)
*
* (C) 1998-2002 Michael Meeks
* (C) 1998-2003 Michael Meeks, Jody Goldberg
**/
#include <gnumeric-config.h>
#include <gnumeric-i18n.h>
......
......@@ -8,7 +8,8 @@
typedef struct _MSContainer MSContainer;
typedef struct _ExcelWorkbook ExcelWorkbook;
typedef struct _MSEscherBlip MSEscherBlip;
typedef struct _MSObj MSObj;
typedef struct _MSEscherShape MSEscherShape;
typedef struct _MSObj MSObj;
typedef struct {
gboolean (*realize_obj) (MSContainer *container, MSObj *obj);
......
......@@ -49,8 +49,7 @@
#endif
/* A storage accumulator for common state information */
typedef struct
{
typedef struct {
MSContainer *container;
BiffQuery *q;
......@@ -61,8 +60,7 @@ typedef struct
gint32 end_offset; /* 1st byte past end of current segment */
} MSEscherState;
typedef struct _MSEscherHeader
{
typedef struct _MSEscherHeader {
/* Read from the data stream */
guint ver;
guint instance;
......@@ -149,7 +147,7 @@ ms_escher_blip_free (MSEscherBlip *blip)
static guint8 const *
ms_escher_get_data (MSEscherState *state,
gint offset, /* bytes from logical start of the stream */
gint num_bytes, /* how many bytes we want, NOT incl prefix */
gint num_bytes, /*how many bytes we want, NOT incl prefix */
gboolean * needs_free)
{
BiffQuery *q = state->q;
......@@ -242,7 +240,7 @@ ms_escher_read_container (MSEscherState *state, MSEscherHeader *container,
/****************************************************************************/
static gboolean
ms_escher_read_CLSID (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_CLSID (MSEscherState *state, MSEscherHeader *h)
{
/* Holds a 'Class ID Record' ID record which is only included in the
* 'clipboard format'. It contains an OLE CLSID record from the source
......@@ -254,7 +252,7 @@ ms_escher_read_CLSID (MSEscherState * state, MSEscherHeader * h)
}
static gboolean
ms_escher_read_ColorMRU (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_ColorMRU (MSEscherState *state, MSEscherHeader *h)
{
d (3 , {
guint const num_Colours = h->instance;
......@@ -268,13 +266,13 @@ ms_escher_read_ColorMRU (MSEscherState * state, MSEscherHeader * h)
}
static gboolean
ms_escher_read_SplitMenuColors (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_SplitMenuColors (MSEscherState *state, MSEscherHeader *h)
{
gboolean needs_free;
guint8 const * data;
g_return_val_if_fail (h->instance == 4, TRUE);
g_return_val_if_fail (h->len == 24, TRUE); /* header + 4*4 */
g_return_val_if_fail (h->len == 24, TRUE); /*header + 4*4 */
if ((data = ms_escher_get_data (state, h->offset + COMMON_HEADER_LEN,
16, &needs_free))) {
......@@ -291,7 +289,7 @@ ms_escher_read_SplitMenuColors (MSEscherState * state, MSEscherHeader * h)
}
static gboolean
ms_escher_read_BStoreContainer (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_BStoreContainer (MSEscherState *state, MSEscherHeader *h)
{
return ms_escher_read_container (state, h, 0);
}
......@@ -311,7 +309,7 @@ bliptype_name (int const type)
}
static gboolean
ms_escher_read_BSE (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_BSE (MSEscherState *state, MSEscherHeader *h)
{
/* read the header */
gboolean needs_free;
......@@ -365,7 +363,7 @@ ms_escher_read_BSE (MSEscherState * state, MSEscherHeader * h)
}
static gboolean
ms_escher_read_Blip (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_Blip (MSEscherState *state, MSEscherHeader *h)
{
int offset = COMMON_HEADER_LEN + 16;
guint32 inst = h->instance;
......@@ -469,25 +467,25 @@ ms_escher_read_Blip (MSEscherState * state, MSEscherHeader * h)
}
static gboolean
ms_escher_read_RegroupItems (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_RegroupItems (MSEscherState *state, MSEscherHeader *h)
{
return FALSE;
}
static gboolean
ms_escher_read_ColorScheme (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_ColorScheme (MSEscherState *state, MSEscherHeader *h)
{
return FALSE;
}
static gboolean
ms_escher_read_SpContainer (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_SpContainer (MSEscherState *state, MSEscherHeader *h)
{
return ms_escher_read_container (state, h, 0);
}
static gboolean
ms_escher_read_Spgr (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_Spgr (MSEscherState *state, MSEscherHeader *h)
{
static char const * const shape_names[] = {
/* 0 */ "Not a primitive",
......@@ -635,7 +633,7 @@ ms_escher_read_Spgr (MSEscherState * state, MSEscherHeader * h)
}
static gboolean
ms_escher_read_Sp (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_Sp (MSEscherState *state, MSEscherHeader *h)
{
gboolean needs_free;
guint8 const *data = ms_escher_get_data (state,
......@@ -674,20 +672,51 @@ ms_escher_read_Sp (MSEscherState * state, MSEscherHeader * h)
}
static gboolean
ms_escher_read_Textbox (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_Textbox (MSEscherState *state, MSEscherHeader *h)
{
return FALSE;
}
static gboolean
ms_escher_read_Anchor (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_Anchor (MSEscherState *state, MSEscherHeader *h)
{
/* only needed for clipboard info, like child anchor with dim 100,000 */
return FALSE;
}
static gboolean
ms_escher_read_ChildAnchor (MSEscherState * state, MSEscherHeader * h)
ms_escher_read_ChildAnchor (MSEscherState *state, MSEscherHeader *h)
{
gboolean needs_free;
int len = h->len - COMMON_HEADER_LEN;
guint8 const *data = ms_escher_get_data (state,
h->offset + COMMON_HEADER_LEN, len, &needs_free);
#if 0
0 | 40 0 0 0 23 0 0 0 bd 0 0 0 44 0 0 0
0 | bd 0 0 0 44 0 0 0 3a 1 0 0 65 0 0 0
0 | 3a 1 0 0 66 0 0 0 b7 1 0 0 87 0 0 0
64 step 125
189 step 125
314 step 125
439
0 | 40 0 0 0 23 0 0 0 80 0 0 0 64 0 0 0
0 | 81 0 0 0 64 0 0 0 c1 0 0 0 a5 0 0 0
0 | c1 0 0 0 a6 0 0 0 1 1 0 0 e7 0 0 0
64 in steps of 64
0 | 1 0 0 0 32 0 0 0 40 0 0 0 66 0 0 0 | ....2...@...f...
0 | 41 0 0 0 66 0 0 0 80 0 0 0 9a 0 0 0 | A...f...........
0 | 80 0 0 0 99 0 0 0 bf 0 0 0 cd 0 0 0 | ................
gsf_mem_dump (data, len);
#endif
if (needs_free)
g_free ((guint8 *)data);
return FALSE;
}
......@@ -706,13 +735,15 @@ ms_escher_read_ClientAnchor (MSEscherState *state, MSEscherHeader *h)
data = ms_escher_get_data (state, h->offset + COMMON_HEADER_LEN,
MS_ANCHOR_SIZE, &needs_free);
#if 0
gsf_mem_dump (data, MS_ANCHOR_SIZE);
#endif
if (data) {
guint8 *anchor = g_malloc (MS_ANCHOR_SIZE);
memcpy (anchor, data, MS_ANCHOR_SIZE);
ms_escher_header_add_attr (h,
ms_obj_attr_new_ptr (MS_OBJ_ATTR_ANCHOR,
anchor));
ms_obj_attr_new_ptr (MS_OBJ_ATTR_ANCHOR, anchor));
if (needs_free)
g_free ((guint8 *)data);
......
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef GNUMERIC_MS_OFFICE_ESCHER_H
#define GNUMERIC_MS_OFFICE_ESCHER_H
......@@ -20,9 +21,12 @@ struct _MSEscherBlip {
guint32 data_len;
gboolean needs_free;
};
struct _MSEscherShape {
MSObjAttrBag *attrs;
};
MSObjAttrBag *ms_escher_parse (BiffQuery *q, MSContainer *container);
void ms_escher_blip_free (MSEscherBlip *blip);
MSObjAttrBag *ms_escher_parse (BiffQuery *q, MSContainer *container);
void ms_escher_blip_free (MSEscherBlip *blip);
#if 0
typedef struct _MSEscherWriter MSEscherWriter;
......
......@@ -335,7 +335,7 @@ ms_sheet_realize_obj (MSContainer *container, MSObj *obj)
anchor = ms_obj_attr_bag_lookup (obj->attrs, MS_OBJ_ATTR_ANCHOR);
if (anchor == NULL) {
fprintf (stderr,"MISSING anchor for obj %p\n", (void *)obj);
fprintf (stderr,"MISSING anchor for obj %p with id %d of type %s\n", (void *)obj, obj->id, obj->excel_type_name);
return TRUE;
}
......@@ -413,14 +413,14 @@ ms_sheet_create_obj (MSContainer *container, MSObj *obj)
{
SheetObject *so = NULL;
Workbook *wb;
ExcelReadSheet const *esheet;
ExcelReadSheet *esheet;
if (obj == NULL)
return NULL;
g_return_val_if_fail (container != NULL, NULL);
esheet = (ExcelReadSheet const *)container;
esheet = (ExcelReadSheet *)container;
wb = esheet->container.ewb->gnum_wb;
switch (obj->excel_type) {
......@@ -436,6 +436,7 @@ ms_sheet_create_obj (MSContainer *container, MSObj *obj)
gnm_so_graphic_set_fill_color (so, color);
break;
}
case 0x00: /* draw the group border */
case 0x02:
case 0x03: { /* Box or Oval */
GnmColor *fill_color = NULL;
......@@ -524,8 +525,12 @@ ms_sheet_create_obj (MSContainer *container, MSObj *obj)
/* ignore combos associateed with filters */
case 0x14:
if (!obj->ignore_combo_in_filter)
if (!obj->combo_in_autofilter)
so = g_object_new (sheet_widget_combo_get_type (), NULL);
/* ok, there are combos to go with the autofilter it can stay */
else if (esheet != NULL)
esheet->filter = NULL;
break;
case 0x19: so = g_object_new (cell_comment_get_type (), NULL);
......@@ -623,12 +628,12 @@ excel_sheet_new (ExcelWorkbook *ewb, char const *sheet_name)
workbook_sheet_attach (ewb->gnum_wb, sheet, NULL);
d (1, fprintf (stderr,"Adding sheet '%s'\n", sheet_name););
}
/* in case nothing forces a spanning flag it here so that spans will
* regenerater later.
*/
/* Flag a respan here in case nothing else does */
sheet_flag_recompute_spans (sheet);
esheet->sheet = sheet;
esheet->filter = NULL;
esheet->freeze_panes = FALSE;
esheet->shared_formulae = g_hash_table_new_full (
(GHashFunc)&cellpos_hash, (GCompareFunc)&cellpos_equal,
......@@ -2572,6 +2577,15 @@ excel_sheet_destroy (ExcelReadSheet *esheet)
esheet->tables = NULL;
}
/* There appear to be workbooks like guai.xls that have a filter NAME
* defined but no visible combos, so we remove a filter if it has no
* objects */
if (esheet->filter != NULL) {
gnm_filter_remove (esheet->filter);
gnm_filter_free (esheet->filter);
esheet->filter = NULL;
}
ms_container_finalize (&esheet->container);
g_free (esheet);
......@@ -2926,7 +2940,9 @@ excel_read_EXTERNNAME (BiffQuery *q, MSContainer *container)
}
/* Do some error checking to handle the magic name associated with an
* autofilter in a sheet */
* autofilter in a sheet. Do not make it an error.
* We have lots of examples of things that are not autofilters.
**/
static void
excel_prepare_autofilter (ExcelWorkbook *ewb, GnmNamedExpr *nexpr)
{
......@@ -2938,17 +2954,27 @@ excel_prepare_autofilter (ExcelWorkbook *ewb, GnmNamedExpr *nexpr)
value_release (v);
if (valid) {
(void) gnm_filter_new (r.sheet, &r.range);
unsigned i;
GnmFilter *filter;
ExcelReadSheet *esheet;
filter = gnm_filter_new (r.sheet, &r.range);
expr_name_remove (nexpr);
return;
for (i = 0 ; i < ewb->excel_sheets->len; i++) {
esheet = g_ptr_array_index (ewb->excel_sheets, i);
if (esheet->sheet == r.sheet) {
g_return_if_fail (esheet->filter == NULL);
esheet->filter = filter;
}
}
}
}
}
gnm_io_warning (ewb->context, _("Failure parsing AutoFilter."));
}
static void
excel_read_NAME (BiffQuery *q, ExcelWorkbook *ewb, gboolean global)
excel_read_NAME (BiffQuery *q, ExcelWorkbook *ewb, ExcelReadSheet *esheet)
{
GPtrArray *a;
GnmNamedExpr *nexpr = NULL;
......@@ -3048,7 +3074,7 @@ excel_read_NAME (BiffQuery *q, ExcelWorkbook *ewb, gboolean global)
excel_prepare_autofilter (ewb, nexpr);
/* g_warning ("flags = %hx, state = %s\n", flags, global ? "global" : "sheet"); */
if ((flags & 0xE) == 0xE) /* Function & VB-Proc & Proc */
else if ((flags & 0xE) == 0xE) /* Function & VB-Proc & Proc */
gnm_func_add_placeholder (ewb->gnum_wb,
nexpr->name->str, "VBA", TRUE);
}
......@@ -5082,7 +5108,7 @@ excel_read_sheet (BiffQuery *q, ExcelWorkbook *ewb,
case BIFF_XF_OLD:
excel_read_XF_OLD (q, ewb, esheet->container.ver);
break;
case BIFF_NAME: excel_read_NAME (q, ewb, FALSE); break;
case BIFF_NAME: excel_read_NAME (q, ewb, esheet); break;
case BIFF_FONT: excel_read_FONT (q, ewb); break;
case BIFF_FORMAT: excel_read_FORMAT (q, ewb); break;
case BIFF_STYLE: break;
......@@ -5498,7 +5524,7 @@ excel_read_workbook (IOContext *context, WorkbookView *wb_view,
break;
case BIFF_EXTERNNAME: excel_read_EXTERNNAME (q, &ewb->container); break;
case BIFF_NAME: excel_read_NAME (q, ewb, TRUE); break;
case BIFF_NAME: excel_read_NAME (q, ewb, NULL); break;
case BIFF_XCT: excel_read_XCT (q, ewb); break;
case BIFF_WRITEACCESS:
......
......@@ -38,7 +38,8 @@ typedef struct {
Sheet *sheet;
GHashTable *shared_formulae, *tables;
gboolean freeze_panes;
gboolean freeze_panes;
GnmFilter *filter;
} ExcelReadSheet;
typedef struct {
......
......@@ -42,7 +42,7 @@
#define GR_END 0x00
#define GR_MACRO 0x04
#define GR_COMMAND_BUTTON 0x05
#define GR_GROUP_BUTTON 0x06
#define GR_GROUP 0x06
#define GR_CLIPBOARD_FORMAT 0x07
#define GR_PICTURE_OPTIONS 0x08
#define GR_PICTURE_FORMULA 0x09
......@@ -275,7 +275,7 @@ ms_obj_new (MSObjAttrBag *attrs)
obj->id = -1;
obj->gnum_obj = NULL;
obj->attrs = (attrs != NULL) ? attrs : ms_obj_attr_bag_new ();
obj->ignore_combo_in_filter = FALSE;
obj->combo_in_autofilter = FALSE;
obj->is_linked = FALSE;
obj->comment_pos.col = obj->comment_pos.row = -1;
......@@ -567,7 +567,7 @@ ms_obj_read_pre_biff8_obj (BiffQuery *q, MSContainer *container, MSObj *obj)
case 0x13 : /* group box */
break;
case 0x14 : /* drop down */
obj->ignore_combo_in_filter =
obj->combo_in_autofilter =
(GSF_LE_GET_GUINT16 (q->data + 8) & 0x8000) ? TRUE : FALSE;
break;
default :
......@@ -615,7 +615,7 @@ ms_obj_read_biff8_obj (BiffQuery *q, MSContainer *container, MSObj *obj)
switch (record_type) {
case GR_END:
g_return_val_if_fail (len == 0, TRUE);
ms_obj_dump (data, len, data_len_left, "ObjEnd");
/* ms_obj_dump (data, len, data_len_left, "ObjEnd"); */
hit_end = TRUE;
break;
......@@ -627,8 +627,8 @@ ms_obj_read_biff8_obj (BiffQuery *q, MSContainer *container, MSObj *obj)
ms_obj_dump (data, len, data_len_left, "CommandButton");
break;
case GR_GROUP_BUTTON :
ms_obj_dump (data, len, data_len_left, "GroupButton");
case GR_GROUP :
ms_obj_dump (data, len, data_len_left, "Group");
break;
case GR_CLIPBOARD_FORMAT :
......@@ -750,7 +750,7 @@ ms_obj_read_biff8_obj (BiffQuery *q, MSContainer *container, MSObj *obj)
/* Undocumented. It appears that combos for filters are marked
* with flag 0x100
*/
obj->ignore_combo_in_filter =
obj->combo_in_autofilter =
(obj->excel_type == 0x14) && (options & 0x100);
#ifndef NO_DEBUG_EXCEL
......@@ -852,8 +852,7 @@ ms_obj_read_biff8_obj (BiffQuery *q, MSContainer *container, MSObj *obj)
void
ms_read_OBJ (BiffQuery *q, MSContainer *container, MSObjAttrBag *attrs)
{
static char const * const object_type_names[] =
{
static char const * const object_type_names[] = {
"Group", /* 0x00 */
"Line", /* 0x01 */
"Rectangle", /* 0x02 */
......
......@@ -108,9 +108,9 @@ struct _MSObj {
/* a kludge for now until the indicator and the box have distinct objects */
GnmCellPos comment_pos;
gboolean ignore_combo_in_filter;
gboolean combo_in_autofilter;
gboolean is_linked;
GHashTable *attrs;
MSObjAttrBag *attrs;
};
void ms_read_OBJ (BiffQuery *q, MSContainer *c, MSObjAttrBag *attrs);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment