Commit f1ab3f8d authored by Almer. S. Tigelaar's avatar Almer. S. Tigelaar Committed by Almer S. Tigelaar

Fix column mangling in fixed width import.

2000-07-04  Almer. S. Tigelaar.  <almer1@dds.nl>

	* src/dialogs/dialog-stf.c, src/dialogs/dialog-stf-fixed-page.c :
	Fix column mangling in fixed width import.

	* src/dialogs/dialog-stf-format-page.c :
	Fix USB (==Ugly Selection Bug).

	* src/stf-parse.c, src/stf-parse.h :
	(stf_parse_options_fixed_autodiscover) : New!
	Column autodiscovery for fixed width.

	* src/dialogs/dialog-stf.glade :
	Add clear and autodiscovery buttons

	* src/dialogs/dialog-stf-fixed-page.c :
	(fixed_page_autodiscover) : Autodiscovery routine.
	(fixed_page_clear_clicked) : Clear click handler
	(fixed_page_auto_clicked) : Autodiscovery click handler
parent 435b0a66
......@@ -10,9 +10,6 @@ Release Critical
cells" undo record.
- Saving xml should not rely on changing the textdomain to disable translation
of TRUE/FALSE.
- Importing fixed-width text (try "ls -l" output) with space stripping
essentially requires columns to be selected right-to-left because
stripping is done too early and mangles columns.
Long term breakage
------------------
......
2000-07-04 Almer. S. Tigelaar. <almer1@dds.nl>
* src/dialogs/dialog-stf.c, src/dialogs/dialog-stf-fixed-page.c :
Fix column mangling in fixed width import.
* src/dialogs/dialog-stf-format-page.c :
Fix USB (==Ugly Selection Bug).
* src/stf-parse.c, src/stf-parse.h :
(stf_parse_options_fixed_autodiscover) : New!
Column autodiscovery for fixed width.
* src/dialogs/dialog-stf.glade :
Add clear and autodiscovery buttons
* src/dialogs/dialog-stf-fixed-page.c :
(fixed_page_autodiscover) : Autodiscovery routine.
(fixed_page_clear_clicked) : Clear click handler
(fixed_page_auto_clicked) : Autodiscovery click handler
2000-07-04 Jukka-Pekka Iivonen <iivonen@iki.fi>
* samples/excel/infofuns.xls: Changed the third test case of
......
2000-07-04 Almer. S. Tigelaar. <almer1@dds.nl>
* src/dialogs/dialog-stf.c, src/dialogs/dialog-stf-fixed-page.c :
Fix column mangling in fixed width import.
* src/dialogs/dialog-stf-format-page.c :
Fix USB (==Ugly Selection Bug).
* src/stf-parse.c, src/stf-parse.h :
(stf_parse_options_fixed_autodiscover) : New!
Column autodiscovery for fixed width.
* src/dialogs/dialog-stf.glade :
Add clear and autodiscovery buttons
* src/dialogs/dialog-stf-fixed-page.c :
(fixed_page_autodiscover) : Autodiscovery routine.
(fixed_page_clear_clicked) : Clear click handler
(fixed_page_auto_clicked) : Autodiscovery click handler
2000-07-04 Jukka-Pekka Iivonen <iivonen@iki.fi>
* samples/excel/infofuns.xls: Changed the third test case of
......
......@@ -14,6 +14,10 @@ Morten:
* Cleanup analysis tool code.
* Eliminate many fixed limits in the code. (Still some to go.)
Almer:
* Fix stf importer bugs
* Add "Autodiscovery" feature to stf fixed width importer.
Translations:
* Updated: de (Karl), no (Kjartan), maybe more.
* Update not new, but not mentioned the last time: pl (Zbigniew).
......
2000-07-04 Almer. S. Tigelaar. <almer1@dds.nl>
* src/dialogs/dialog-stf.c, src/dialogs/dialog-stf-fixed-page.c :
Fix column mangling in fixed width import.
* src/dialogs/dialog-stf-format-page.c :
Fix USB (==Ugly Selection Bug).
* src/stf-parse.c, src/stf-parse.h :
(stf_parse_options_fixed_autodiscover) : New!
Column autodiscovery for fixed width.
* src/dialogs/dialog-stf.glade :
Add clear and autodiscovery buttons
* src/dialogs/dialog-stf-fixed-page.c :
(fixed_page_autodiscover) : Autodiscovery routine.
(fixed_page_clear_clicked) : Clear click handler
(fixed_page_auto_clicked) : Autodiscovery click handler
2000-07-04 Jukka-Pekka Iivonen <iivonen@iki.fi>
* samples/excel/infofuns.xls: Changed the third test case of
......
2000-07-04 Almer. S. Tigelaar. <almer1@dds.nl>
* src/dialogs/dialog-stf.c, src/dialogs/dialog-stf-fixed-page.c :
Fix column mangling in fixed width import.
* src/dialogs/dialog-stf-format-page.c :
Fix USB (==Ugly Selection Bug).
* src/stf-parse.c, src/stf-parse.h :
(stf_parse_options_fixed_autodiscover) : New!
Column autodiscovery for fixed width.
* src/dialogs/dialog-stf.glade :
Add clear and autodiscovery buttons
* src/dialogs/dialog-stf-fixed-page.c :
(fixed_page_autodiscover) : Autodiscovery routine.
(fixed_page_clear_clicked) : Clear click handler
(fixed_page_auto_clicked) : Autodiscovery click handler
2000-07-04 Jukka-Pekka Iivonen <iivonen@iki.fi>
* samples/excel/infofuns.xls: Changed the third test case of
......
2000-07-04 Almer. S. Tigelaar. <almer1@dds.nl>
* src/dialogs/dialog-stf.c, src/dialogs/dialog-stf-fixed-page.c :
Fix column mangling in fixed width import.
* src/dialogs/dialog-stf-format-page.c :
Fix USB (==Ugly Selection Bug).
* src/stf-parse.c, src/stf-parse.h :
(stf_parse_options_fixed_autodiscover) : New!
Column autodiscovery for fixed width.
* src/dialogs/dialog-stf.glade :
Add clear and autodiscovery buttons
* src/dialogs/dialog-stf-fixed-page.c :
(fixed_page_autodiscover) : Autodiscovery routine.
(fixed_page_clear_clicked) : Clear click handler
(fixed_page_auto_clicked) : Autodiscovery click handler
2000-07-04 Jukka-Pekka Iivonen <iivonen@iki.fi>
* samples/excel/infofuns.xls: Changed the third test case of
......
2000-07-04 Almer. S. Tigelaar. <almer1@dds.nl>
* src/dialogs/dialog-stf.c, src/dialogs/dialog-stf-fixed-page.c :
Fix column mangling in fixed width import.
* src/dialogs/dialog-stf-format-page.c :
Fix USB (==Ugly Selection Bug).
* src/stf-parse.c, src/stf-parse.h :
(stf_parse_options_fixed_autodiscover) : New!
Column autodiscovery for fixed width.
* src/dialogs/dialog-stf.glade :
Add clear and autodiscovery buttons
* src/dialogs/dialog-stf-fixed-page.c :
(fixed_page_autodiscover) : Autodiscovery routine.
(fixed_page_clear_clicked) : Clear click handler
(fixed_page_auto_clicked) : Autodiscovery click handler
2000-07-04 Jukka-Pekka Iivonen <iivonen@iki.fi>
* samples/excel/infofuns.xls: Changed the third test case of
......
2000-07-04 Almer. S. Tigelaar. <almer1@dds.nl>
* src/dialogs/dialog-stf.c, src/dialogs/dialog-stf-fixed-page.c :
Fix column mangling in fixed width import.
* src/dialogs/dialog-stf-format-page.c :
Fix USB (==Ugly Selection Bug).
* src/stf-parse.c, src/stf-parse.h :
(stf_parse_options_fixed_autodiscover) : New!
Column autodiscovery for fixed width.
* src/dialogs/dialog-stf.glade :
Add clear and autodiscovery buttons
* src/dialogs/dialog-stf-fixed-page.c :
(fixed_page_autodiscover) : Autodiscovery routine.
(fixed_page_clear_clicked) : Clear click handler
(fixed_page_auto_clicked) : Autodiscovery click handler
2000-07-04 Jukka-Pekka Iivonen <iivonen@iki.fi>
* samples/excel/infofuns.xls: Changed the third test case of
......
......@@ -228,6 +228,13 @@ Almer. S. Tigelaar.
stf_parse_options_fixed_splitpositions_add (parseoptions, 20);
stf_parse_options_fixed_splitpositions_add (parseoptions, 24);
Alternatively you can also call the autodiscovery function :
stf_parse_options_fixed_autodiscover (parseoptions, lines, text);
This function will try to recognize columns in the text and adjust the
splitpositions accordingly.
after that we'll call a parsing routine (for the example I'll call the general one)
(normally you don't call the stf_parse_general and stf_parse_general_cached directly,
you create a separate function which parses the GSList returned by stf_parse_general or
......
......@@ -228,6 +228,13 @@ Almer. S. Tigelaar.
stf_parse_options_fixed_splitpositions_add (parseoptions, 20);
stf_parse_options_fixed_splitpositions_add (parseoptions, 24);
Alternatively you can also call the autodiscovery function :
stf_parse_options_fixed_autodiscover (parseoptions, lines, text);
This function will try to recognize columns in the text and adjust the
splitpositions accordingly.
after that we'll call a parsing routine (for the example I'll call the general one)
(normally you don't call the stf_parse_general and stf_parse_general_cached directly,
you create a separate function which parses the GSList returned by stf_parse_general or
......
......@@ -12,6 +12,62 @@
* MISC UTILITY FUNCTIONS
*************************************************************************************************/
/**
* fixed_page_autodiscover:
* @pagedata: a mother struct
*
* Use the STF's autodiscovery function and put the
* result in the fixed_collist
**/
static void
fixed_page_autodiscover (DruidPageData_t *pagedata)
{
FixedInfo_t *info = pagedata->fixed_info;
int i = 0;
char *tset[2];
stf_parse_options_fixed_autodiscover (info->fixed_run_parseoptions, pagedata->importlines, (char *) pagedata->cur);
gtk_clist_clear (info->fixed_collist);
while (i < info->fixed_run_parseoptions->splitpositions->len) {
tset[0] = g_strdup_printf ("%d", i);
tset[1] = g_strdup_printf ("%d", g_array_index (info->fixed_run_parseoptions->splitpositions,
int,
i));
gtk_clist_append (info->fixed_collist, tset);
g_free (tset[0]);
g_free (tset[1]);
i++;
}
tset[0] = g_strdup_printf ("%d", i);
tset[1] = g_strdup_printf ("%d", -1);
gtk_clist_append (info->fixed_collist, tset);
g_free (tset[0]);
g_free (tset[1]);
/*
* If there are no splitpositions than apparantly
* no columns where found
*/
if (info->fixed_run_parseoptions->splitpositions->len < 1) {
GtkWidget *dialog;
dialog = gnome_ok_dialog_parented (_("Autodiscovery did not find any columns in the text. Try manually"),
pagedata->window);
gnome_dialog_run (GNOME_DIALOG (dialog));
}
}
/**
* fixed_page_update_preview
* @pagedata : mother struct
......@@ -420,6 +476,48 @@ fixed_page_remove_clicked (GtkButton *button, DruidPageData_t *data)
fixed_page_update_preview (data);
}
/**
* fixed_page_clear_clicked:
* @button: GtkButton
* @data: mother struct
*
* Will clear all entries in fixed_collist
**/
static void
fixed_page_clear_clicked (GtkButton *button, DruidPageData_t *data)
{
FixedInfo_t *info = data->fixed_info;
char *tset[2];
gtk_clist_clear (info->fixed_collist);
tset[0] = g_strdup ("0");
tset[1] = g_strdup ("-1");
gtk_clist_append (info->fixed_collist, tset);
g_free (tset[0]);
g_free (tset[1]);
fixed_page_update_preview (data);
}
/**
* fixed_page_auto_clicked:
* @button: GtkButton
* @data: mother struct
*
* Will try to automatically recognize columns in the
* text.
**/
static void
fixed_page_auto_clicked (GtkButton *button, DruidPageData_t *data)
{
fixed_page_autodiscover (data);
fixed_page_update_preview (data);
}
/*************************************************************************************************
* FIXED EXPORTED FUNCTIONS
*************************************************************************************************/
......@@ -448,8 +546,8 @@ stf_dialog_fixed_page_prepare (GnomeDruidPage *page, GnomeDruid *druid, DruidPag
stf_cache_options_set_data (info->fixed_run_cacheoptions, info->fixed_run_parseoptions, pagedata->cur);
}
stf_parse_options_set_trim_spaces (info->fixed_run_parseoptions, pagedata->trim);
stf_parse_options_set_trim_spaces (info->fixed_run_parseoptions, TRIM_TYPE_NEVER);
stf_cache_options_invalidate (info->fixed_run_cacheoptions);
pagedata->colcount = stf_parse_get_colcount (info->fixed_run_parseoptions, pagedata->cur);
......@@ -462,7 +560,7 @@ stf_dialog_fixed_page_prepare (GnomeDruidPage *page, GnomeDruid *druid, DruidPag
spinadjust->lower = 1;
spinadjust->upper = stf_parse_get_longest_row_width (info->fixed_run_parseoptions, pagedata->cur);
gtk_spin_button_set_adjustment (info->fixed_colend, spinadjust);
fixed_page_update_preview (pagedata);
}
......@@ -517,6 +615,8 @@ stf_dialog_fixed_page_init (GladeXML *gui, DruidPageData_t *pagedata)
info->fixed_colend = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "fixed_colend"));
info->fixed_add = GTK_BUTTON (glade_xml_get_widget (gui, "fixed_add"));
info->fixed_remove = GTK_BUTTON (glade_xml_get_widget (gui, "fixed_remove"));
info->fixed_clear = GTK_BUTTON (glade_xml_get_widget (gui, "fixed_clear"));
info->fixed_auto = GTK_BUTTON (glade_xml_get_widget (gui, "fixed_auto"));
info->fixed_canvas = GNOME_CANVAS (glade_xml_get_widget (gui, "fixed_canvas"));
info->fixed_scroll = GTK_VSCROLLBAR (glade_xml_get_widget (gui, "fixed_scroll"));
......@@ -558,6 +658,14 @@ stf_dialog_fixed_page_init (GladeXML *gui, DruidPageData_t *pagedata)
"clicked",
GTK_SIGNAL_FUNC (fixed_page_remove_clicked),
pagedata);
gtk_signal_connect (GTK_OBJECT (info->fixed_clear),
"clicked",
GTK_SIGNAL_FUNC (fixed_page_clear_clicked),
pagedata);
gtk_signal_connect (GTK_OBJECT (info->fixed_auto),
"clicked",
GTK_SIGNAL_FUNC (fixed_page_auto_clicked),
pagedata);
gtk_signal_connect (GTK_OBJECT (info->fixed_canvas),
"motion_notify_event",
......
......@@ -164,8 +164,10 @@ format_page_sublist_select_row (GtkCList *clist, int row, int column, GdkEventBu
gtk_clist_get_text (clist, row, column, t);
info->format_run_sublist_select = FALSE;
if (strcmp (t[0], _("Custom")) != 0)
gtk_entry_set_text (info->format_format, t[0]);
info->format_run_sublist_select = TRUE;
}
/**
......@@ -207,20 +209,21 @@ format_page_format_changed (GtkEntry *entry, DruidPageData_t *data)
1,
gtk_clist_optimal_column_width (info->format_collist, 1));
found = 0;
for (i = 0; i < info->format_sublist->rows; i++) {
gtk_clist_get_text (info->format_sublist, i, 0, t);
if (strcmp (t[0], format) == 0) {
found = i;
break;
}
}
info->format_run_manual_change = TRUE;
gtk_clist_select_row (info->format_sublist, found, 0);
gnumeric_clist_moveto (info->format_sublist, found);
if (info->format_run_sublist_select) {
found = 0;
for (i = 0; i < info->format_sublist->rows; i++) {
gtk_clist_get_text (info->format_sublist, i, 0, t);
if (strcmp (t[0], format)==0) {
found = i;
break;
}
}
g_free (format);
info->format_run_manual_change = TRUE;
gtk_clist_select_row (info->format_sublist, found, 0);
gnumeric_clist_moveto (info->format_sublist, found);
}
}
format_page_update_preview (data);
......@@ -250,7 +253,7 @@ stf_dialog_format_page_prepare (GnomeDruidPage *page, GnomeDruid *druid, DruidPa
data->colcount = stf_parse_get_colcount (info->format_run_parseoptions, data->cur);
listcount = g_slist_length (info->format_run_list);
/* If necessary add new items (non-visual) */
while (listcount <= data->colcount) {
info->format_run_list = g_slist_append (info->format_run_list,
......@@ -359,6 +362,7 @@ stf_dialog_format_page_init (GladeXML *gui, DruidPageData_t *pagedata)
info->format_run_list = NULL;
info->format_run_index = -1;
info->format_run_manual_change = FALSE;
info->format_run_sublist_select = TRUE;
info->format_run_displayrows = stf_preview_get_displayed_rowcount (info->format_run_renderdata);
info->format_run_cacheoptions = stf_cache_options_new ();
info->format_run_parseoptions = NULL; /* stf_parse_options_new (); */
......
......@@ -17,7 +17,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Almer. S. Tigelaar <almer1@dds.nl>
*/
#include <config.h>
......@@ -214,8 +213,15 @@ stf_dialog_druid_page_next (GnomeDruidPage *page, GnomeDruid *druid, DruidPageDa
case DPG_FIXED : {
newpos = DPG_FORMAT;
if (data->format_info->format_run_parseoptions != data->fixed_info->fixed_run_parseoptions)
/*
* Set trim type here, we never want trimming on
* the fixed width page of the druid because of
* columns getting mangled
*/
stf_parse_options_set_trim_spaces (data->fixed_info->fixed_run_parseoptions, data->trim);
if (data->format_info->format_run_parseoptions != data->fixed_info->fixed_run_parseoptions) {
stf_cache_options_set_data (data->format_info->format_run_cacheoptions, data->fixed_info->fixed_run_parseoptions, data->cur);
}
else
stf_cache_options_invalidate (data->format_info->format_run_cacheoptions);
......
......@@ -984,7 +984,7 @@ On right side only
<class>GtkLabel</class>
<name>label16</name>
<width>505</width>
<label>Customize the columns using the add/remove buttons or the mouse : left click to create a new column, right click on a colum border to delete an existing column and hold the left mouse button on a column border and drag to resize a column.</label>
<label>Customize the columns using the add/remove buttons or the mouse : left click to create a new column, right click on a colum border to delete an existing column and hold the left mouse button on a column border and drag to resize a column. Auto column discovery will try to recognize columns in the text automatically.</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>True</wrap>
<xalign>7.45058e-09</xalign>
......@@ -1211,6 +1211,38 @@ On right side only
<can_focus>True</can_focus>
<label>_Remove</label>
</widget>
<widget>
<class>GtkButton</class>
<name>fixed_clear</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<label>_Clear</label>
</widget>
</widget>
</widget>
<widget>
<class>GtkHButtonBox</class>
<name>hbuttonbox2</name>
<layout_style>GTK_BUTTONBOX_START</layout_style>
<spacing>30</spacing>
<child_min_width>85</child_min_width>
<child_min_height>40</child_min_height>
<child_ipad_x>7</child_ipad_x>
<child_ipad_y>0</child_ipad_y>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkButton</class>
<name>fixed_auto</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<label>Auto Column _Discovery</label>
</widget>
</widget>
</widget>
......
......@@ -46,13 +46,15 @@ gchar *s = N_("\"\n"
gchar *s = N_("\"");
gchar *s = N_("Example");
gchar *s = N_("Fixed width customization");
gchar *s = N_("Customize the columns using the add/remove buttons or the mouse : left click to create a new column, right click on a colum border to delete an existing column and hold the left mouse button on a column border and drag to resize a column.");
gchar *s = N_("Customize the columns using the add/remove buttons or the mouse : left click to create a new column, right click on a colum border to delete an existing column and hold the left mouse button on a column border and drag to resize a column. Auto column discovery will try to recognize columns in the text automatically.");
gchar *s = N_("Columns");
gchar *s = N_("Column");
gchar *s = N_("End");
gchar *s = N_("Co_lumn end : ");
gchar *s = N_("_Add");
gchar *s = N_("_Remove");
gchar *s = N_("_Clear");
gchar *s = N_("Auto Column _Discovery");
gchar *s = N_("Example");
gchar *s = N_("Column formatting");
gchar *s = N_("Select the format for each column. You can click in the column list on the left to select a column, or you can click in the preview. You can then enter a custom format or select one from the list on the right.");
......
......@@ -63,7 +63,7 @@ typedef struct {
typedef struct {
GtkCList *fixed_collist;
GtkSpinButton *fixed_colend;
GtkButton *fixed_add, *fixed_remove;
GtkButton *fixed_add, *fixed_remove, *fixed_clear, *fixed_auto;
GnomeCanvas *fixed_canvas;
GtkVScrollbar *fixed_scroll;
......@@ -95,6 +95,7 @@ typedef struct {
GSList *format_run_list; /* List of StyleFormat * */
int format_run_index;
gboolean format_run_manual_change;
gboolean format_run_sublist_select;
int format_run_displayrows; /* Number of rows to display in the preview window */
} FormatInfo_t;
......
......@@ -47,6 +47,12 @@ typedef struct {
int linepos; /* Position on the current line */
} Source_t;
/* Struct used for autodiscovery */
typedef struct {
int start;
int stop;
} AutoDiscovery_t;
/*******************************************************************************************************
* STF PARSE OPTIONS : StfParseOptions related
*******************************************************************************************************/
......@@ -1410,6 +1416,176 @@ stf_parse_is_valid_data (const char *data)
return valid;
}
/**
* stf_parse_options_fixed_autodiscover:
* @parseoptions: a Parse options struct.
* @data_lines : The number of lines to look at in @data.
* @data : The actual data.
*
* Automatically try to discover columns in the text to be parsed.
* We ignore empty lines (only containing parseoptions->terminator)
*
**/
void
stf_parse_options_fixed_autodiscover (StfParseOptions_t *parseoptions, int data_lines, char *data)
{
char *iterator = data;
GSList *list = NULL;
GSList *list_start = NULL;
int lines = 0;
int effective_lines = 0;
int max_line_length = 0;
int *line_begin_hits = NULL;
int *line_end_hits = NULL;
int i;
stf_parse_options_fixed_splitpositions_clear (parseoptions);
/*
* First take a look at all possible white space combinations
*/
while (*iterator) {
gboolean begin_recorded = FALSE;
AutoDiscovery_t *disc = NULL;
int position = 0;
while (*iterator && *iterator != parseoptions->terminator) {
if (!begin_recorded && *iterator == ' ') {
disc = g_new0 (AutoDiscovery_t, 1);
disc->start = position;
begin_recorded = TRUE;
} else if (begin_recorded && *iterator != ' ') {
disc->stop = position;
list = g_slist_prepend (list, disc);
begin_recorded = FALSE;
disc = NULL;
}
position++;
iterator++;
}
if (position > max_line_length)
max_line_length = position;
/*
* If there are excess spaces at the end of
* the line : ignore them
*/
if (disc)
g_free (disc);
/*
* Hop over the terminator
*/
if (*iterator)
iterator++;
if (position != 0)
effective_lines++;
lines++;
if (lines >= data_lines)
break;
}
list = g_slist_reverse (list);
list_start = list;
/*
* Kewl stuff :
* Look at the number of hits at each line position
* if the number of hits equals the number of lines
* we can be pretty sure this is the start or end
* of a column, we filter out empty columns
* later
*/
line_begin_hits = g_new0 (int, max_line_length + 1);
line_end_hits = g_new0 (int, max_line_length + 1);
while (list) {