Definition in file filein.c.
#include "config.h"
#include <string.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <gtkextra/gtksheet.h>
#include <libgnomevfs/gnome-vfs.h>
#include "types.h"
#include "dialog_initial.h"
#include "dim_list_menu.h"
#include "filein.h"
#include "main.h"
#include "report.h"
Go to the source code of this file.
Defines | |
#define | ENUM_BODY(name, value) name value, |
#define | DEFINE_ENUM_NON_TYPEDEF(name, list) |
#define | FROM_STRING_DEC_NON_TYPEDEF(name, list) |
#define | FROM_STRING_CASE_NON_TYPEDEF(name, value) if (strcmp(str, #name) == 0) { *type = name; } |
#define | FROM_STRING_FUNC_NON_TYPEDEF(name, list) |
#define | AS_STRING_DEC_NON_TYPEDEF(name, list) const gchar* name##asString(enum name n); |
#define | AS_STRING_FUNC_NON_TYPEDEF(name, list) |
#define | AS_STRING_CASE_NON_TYPEDEF(name, value) case name: { return #name; } |
#define | QL_ERRORS(_) |
Inherited error codes. | |
Functions | |
static void | define_last_field (QlTabData *tab) |
static void | add1field (QlTabData *tab) |
Add 1 column to sheet. | |
static enum QlErrorVal | read_comma_file (QlTabData *tab) |
static enum QlErrorVal | read_ql_file (QlTabData *tab) |
static enum QlErrorVal | read_tab_file (QlTabData *tab) |
static void | report_error (QlTabData *tab, enum QlErrorVal err_number) |
void | actually_open (const gchar *filename, QlDialogMode G_GNUC_UNUSED open_mode, QlFileType file_type, QlContext *qlc) |
static gchar * | check_last_path (QlContext *qlc) |
static void | any_open (QlDialogMode open_mode, QlFileType file_type, QlContext *qlc) |
static void | set_sheet_column_cb (gpointer G_GNUC_UNUSED field_index, gpointer field_ptr, gpointer user_data) |
void | build_basic_list_mode (QlTabData *tab) |
void | file_import (GtkAction G_GNUC_UNUSED *action, gpointer data) |
void | file_type_menu (QlTabData *tab, GtkWidget *chooser) |
void | open_file (GtkAction G_GNUC_UNUSED *action, gpointer data) |
void | open_recent (GtkRecentChooser *c, gpointer data) |
#define AS_STRING_FUNC_NON_TYPEDEF | ( | name, | |||
list | ) |
#define DEFINE_ENUM_NON_TYPEDEF | ( | name, | |||
list | ) |
#define ENUM_BODY | ( | name, | |||
value | ) | name value, |
#define FROM_STRING_DEC_NON_TYPEDEF | ( | name, | |||
list | ) |
#define FROM_STRING_FUNC_NON_TYPEDEF | ( | name, | |||
list | ) |
#define QL_ERRORS | ( | _ | ) |
Value:
_(QL_SUCCESS, =0) \ _(QL_CANNOT_OPEN_FILE, ) \ _(QL_NO_CONTENT_FOUND, ) \ _(QL_BAD_QUICKLIST_DATA, ) \ _(QL_BAD_FIELD_DATA, ) \ _(QL_NO_FIELD_TYPE, ) \ _(QL_UNABLE_TO_PARSE_FIELD_TYPE, ) \ _(QL_UNABLE_TO_PARSE_FIELD, ) \ _(QL_FIELD_NAME_IS_TOO_LONG, ) \ _(QL_BAD_SORT_VALUE, ) \ _(QL_TOO_FEW_SORT_LEVELS, ) \ _(QL_INVALID_FIELD_NAME, ) \ _(QL_SORT_NESTING_TOO_DEEP, ) \ _(QL_BAD_FILTER_VALUE, ) \ _(QL_CANNOT_PARSE_FILTER_DATA, ) \ _(QL_INVALID_FILTER_NAME, ) \ _(QL_TOO_FEW_FILTER_FIELDS, ) \ _(QL_INVALID_FIELD_TYPE, ) \ _(QL_TOO_MANY_FILTER_COMPARISONS, =19) \ _(QL_INVALID_CHAR_IN_FILTER, ) \ _(QL_FILTER_NESTING_TOO_DEEP, ) \ _(QL_TOO_MANY_COLUMNS, ) \ _(QL_INVALID_COLUMN_DATA, ) \ _(QL_UNRECOGNISED_COLUMN_TYPE, ) \ _(QL_NO_COLUMNS_IN_REPORT, ) \ _(QL_INVALID_REPORT_DATA, ) \ _(QL_REPORT_FIELD_NAME_TOO_LONG, ) \ _(QL_INVALID_DATA, ) \ _(QL_TOO_MANY_FIELDS, =30) \ _(QL_LINE_IS_TOO_BIG, =45)
Previous error codes have been expanded into more descriptive enum values that are then mapped as strings.
void actually_open | ( | const gchar * | filename, | |
QlDialogMode G_GNUC_UNUSED | open_mode, | |||
QlFileType | file_type, | |||
QlContext * | qlc | |||
) |
This callback is when someone clicks OK on a file selection dialog box
Definition at line 640 of file filein.c.
00642 { 00643 QlTabData * tab; 00644 enum QlErrorVal temp; 00645 00646 tab = ql_new_tabdata(qlc); 00647 /* 0,0 is valid, so can't use initial values. */ 00648 tab->view->activate_row = tab->view->activate_col = -5; 00649 tab->file->file_path = g_strdup (filename); 00650 tab->file->file_name = g_path_get_basename (filename); 00651 00652 temp = -1; /* default error */ 00653 if (file_type == QL_OLD_QLF) /* .qlf */ 00654 temp = read_ql_file (tab); 00655 else if (file_type == QL_CSV) /* .csv */ 00656 temp = read_comma_file (tab); 00657 else 00658 temp = read_tab_file (tab); 00659 if (temp) 00660 { 00661 report_error (tab, temp); 00662 return; 00663 } 00664 tab->view->display_mode = DISPLAY_LIST; 00665 tab->file->changed = FALSE; 00666 gtk_recent_manager_add_item (qlc->recent_manager, filename); 00667 dim_all_menus (qlc); 00668 gtk_widget_show_all (qlc->parent); 00669 connect_signals (tab); 00670 tab->view->dialog_mode = MODE_SAVE; 00671 } /* end of actual open */
static void add1field | ( | QlTabData * | tab | ) | [static] |
Add 1 column to sheet.
This is necessary for reading unspecified input files such as comma, html and tab
Definition at line 146 of file filein.c.
00147 { 00148 QlFieldInfo * field; 00149 gint fieldx = ++tab->file->last_field; 00150 define_last_field (tab); 00151 gtk_sheet_add_column (tab->view->sheet, 1); 00152 gtk_sheet_set_column_width (tab->view->sheet, fieldx, 80); 00153 field = ql_get_fieldinfo (tab, fieldx); 00154 gtk_sheet_column_button_add_label (tab->view->sheet, fieldx, 00155 field->name); 00156 gtk_sheet_set_column_title (tab->view->sheet, 00157 fieldx, field->name); 00158 } /* end of add1field */
static void any_open | ( | QlDialogMode | open_mode, | |
QlFileType | file_type, | |||
QlContext * | qlc | |||
) | [static] |
allow the user to choose the file to open.
Definition at line 688 of file filein.c.
00689 { 00690 GtkWidget * chooser; 00691 GtkFileFilter * filter; 00692 gchar * filename, * last_path; 00693 QlTabData * tab; 00694 00695 tab = ql_get_tabdata (qlc); 00696 filename = NULL; 00697 last_path = check_last_path (qlc); 00698 filter = gtk_file_filter_new (); 00699 if (open_mode == MODE_OPEN) 00700 { 00701 gtk_file_filter_set_name (filter, _("QuickList files *.qlf")); 00702 gtk_file_filter_add_mime_type (filter, "application-x-quicklist"); 00703 gtk_file_filter_add_pattern (filter, "*.qlf"); 00704 chooser = gtk_file_chooser_dialog_new 00705 ((_("Open a list")), 00706 NULL, GTK_FILE_CHOOSER_ACTION_OPEN, 00707 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 00708 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); 00709 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(chooser), 00710 filter); 00711 } 00712 else 00713 { 00714 chooser = gtk_file_chooser_dialog_new 00715 ((_("Import a file")), 00716 NULL, GTK_FILE_CHOOSER_ACTION_OPEN, 00717 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 00718 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); 00719 file_type_menu (tab, chooser); 00720 } 00721 filter = gtk_file_filter_new (); 00722 gtk_file_filter_set_name (filter, _("All files *")); 00723 gtk_file_filter_add_pattern (filter, "*"); 00724 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(chooser), 00725 filter); 00726 /* need tab index */ 00727 if (last_path) 00728 gtk_file_chooser_set_current_folder ( 00729 GTK_FILE_CHOOSER(chooser), last_path); 00730 if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT) 00731 filename = gtk_file_chooser_get_filename 00732 (GTK_FILE_CHOOSER (chooser)); 00733 gtk_widget_destroy (chooser); 00734 if (filename) 00735 actually_open (filename, open_mode, file_type, qlc); 00736 } /* end of any_open callback */
void build_basic_list_mode | ( | QlTabData * | tab | ) |
window initialiser
Definition at line 753 of file filein.c.
00754 { 00755 GtkSheet *sheet; 00756 GtkWidget *scrolled_window; 00757 gint colx, fieldx, tbindex; 00758 00759 colx = 0; 00760 fieldx = 0; 00761 tab->view->sheet = GTK_SHEET (gtk_sheet_new (1, tab->file->last_field + 1, 00762 tab->file->file_name)); 00763 sheet = (tab->view->sheet); 00764 gtk_sheet_row_button_add_label (sheet, 0, " "); 00765 gtk_sheet_set_autoscroll (sheet, TRUE); 00766 gtk_sheet_set_autoresize (sheet, TRUE); 00767 00768 gtk_sheet_set_row_titles_width (sheet, 20); 00769 tab->file->last_row = 0; 00770 gtk_container_set_border_width (GTK_CONTAINER (sheet), 4); 00771 00772 /* set sensitivity for all column and row buttons */ 00773 gtk_sheet_columns_set_sensitivity (sheet, TRUE); 00774 gtk_sheet_show_row_titles (sheet); 00775 gtk_sheet_show_column_titles (sheet); 00776 gtk_sheet_rows_set_sensitivity (sheet, TRUE); 00777 ql_fieldinfo_foreach (tab, set_sheet_column_cb, sheet); 00778 /* for (fieldx = 0; fieldx <= tab->file->last_field; fieldx++) 00779 { 00780 colx = tab->file->fields[fieldx]->sheet_column; 00781 gtk_sheet_set_column_width (sheet, colx, 00782 tab->file->fields[fieldx]->width * 8); 00783 gtk_sheet_column_button_add_label (sheet, colx, 00784 tab->file->fields[fieldx]->name); 00785 gtk_sheet_column_set_justification (sheet, colx, 00786 tab->file->fields[fieldx]->justification); 00787 }*/ 00788 gtk_sheet_show_column_titles (sheet); 00789 00790 /* create a new scrolled window. */ 00791 scrolled_window = gtk_scrolled_window_new (NULL, NULL); 00792 00793 gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 3); 00794 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW 00795 (scrolled_window), GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS); 00796 00797 gtk_container_add (GTK_CONTAINER (scrolled_window), 00798 GTK_WIDGET (sheet)); 00799 gtk_notebook_append_page(tab->qlc->notebook, 00800 GTK_WIDGET(scrolled_window), 00801 tab_label_box (tab, tab->file->file_name)); 00802 gtk_widget_show (scrolled_window); 00803 tbindex = gtk_notebook_get_current_page (tab->qlc->notebook); 00804 tbindex++; 00805 gtk_notebook_set_tab_reorderable (tab->qlc->notebook, scrolled_window, TRUE); 00806 gtk_notebook_set_current_page (tab->qlc->notebook, tbindex); 00807 } /* end of build_basic_list_mode */
static gchar* check_last_path | ( | QlContext * | qlc | ) | [static] |
retrieve path from the filename of the current tab, if any.
Definition at line 676 of file filein.c.
00677 { 00678 QlFileData * file; 00679 00680 file = ql_get_filedata (qlc); 00681 if (!file) 00682 return NULL; 00683 return g_path_get_dirname (file->file_path); 00684 }
static void define_last_field | ( | QlTabData * | tab | ) | [static] |
setup a new text field as a standard text field.
Definition at line 126 of file filein.c.
00127 { 00128 QlFieldInfo * field; 00129 gint temp = tab->file->last_field; 00130 field = ql_get_fieldinfo (tab, tab->file->last_field); 00131 field->name = g_strdup_printf ("Column %u", temp + 1); 00132 field->sheet_column = temp; 00133 field->type = FIELD_TYPE_TEXT; 00134 field->formatting = 0; 00135 field->decimal_places = 0; 00136 field->justification = GTK_JUSTIFY_LEFT; 00137 field->width = 10; 00138 tab->file->col_to_field[temp] = temp; 00139 }
void file_type_menu | ( | QlTabData * | tab, | |
GtkWidget * | chooser | |||
) |
Build the menu button for the file selection box, allowing choice of file types. Works for input and output
Definition at line 822 of file filein.c.
00823 { 00824 GtkFileFilter * filter; 00825 00826 if (tab->view->dialog_mode == MODE_EXPORT) 00827 { 00828 filter = gtk_file_filter_new (); 00829 gtk_file_filter_set_name (filter, _("HTML document, *.html")); 00830 gtk_file_filter_add_pattern (filter, "*.html"); 00831 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(chooser), filter); 00832 } 00833 filter = gtk_file_filter_new (); 00834 gtk_file_filter_set_name (filter, _("Comma delimited, *.csv")); 00835 gtk_file_filter_add_pattern (filter, "*.csv"); 00836 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(chooser), filter); 00837 filter = gtk_file_filter_new (); 00838 gtk_file_filter_set_name (filter, _("Tab delimited, *.tsv")); 00839 gtk_file_filter_add_pattern (filter, "*.csv"); 00840 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(chooser), filter); 00841 }
void open_file | ( | GtkAction G_GNUC_UNUSED * | action, | |
gpointer | data | |||
) |
This is a callback that handles open file from various places
Definition at line 845 of file filein.c.
00846 { 00847 QlContext * qlc; 00848 00849 qlc = ql_get_context (GTK_WIDGET(data)); 00850 g_return_if_fail (qlc); 00851 any_open (MODE_OPEN, QL_OLD_QLF, qlc); 00852 }
static enum QlErrorVal read_comma_file | ( | QlTabData * | tab | ) | [static] |
The file selection dialog box has returned a file name. It is supposed to be a comma delimited file (CSV)
Definition at line 164 of file filein.c.
00165 { 00169 gchar linebuf[256]; 00170 gchar *linebufp; 00171 gchar *beginp; 00172 gchar *endp; 00173 gint16 fieldx = 0; 00174 gint rowx, c; 00175 gboolean got_data; 00176 FILE * f; 00177 00178 /* Make Column 1 in field [0] */ 00179 if (!(f = fopen (tab->file->file_path, "r"))) 00180 return QL_CANNOT_OPEN_FILE; 00181 build_basic_list_mode (tab); 00182 define_last_field (tab); 00183 linebufp = beginp = linebuf; 00184 rowx = fieldx = 0; 00185 endp = linebufp + 253;; 00186 got_data = FALSE; 00187 00188 while ((c = getc (f)) != EOF) 00189 { 00190 if (c >= ' ' && c != ',') 00191 { 00192 *linebufp++ = c; 00193 if (linebufp >= endp) 00194 return QL_LINE_IS_TOO_BIG; 00195 } 00196 else if (c == '\n' || c == '\r' || c == ',') 00197 { 00198 if (linebufp != beginp) 00199 { 00200 got_data = TRUE; 00201 *linebufp = '\0'; 00202 while (fieldx > tab->file->last_field) 00203 { 00204 if (fieldx >= MAX_FIELDS - 1) 00205 return QL_TOO_MANY_FIELDS; 00206 else 00207 add1field (tab); 00208 } 00209 gtk_sheet_set_cell_text 00210 (tab->view->sheet, rowx, 00211 fieldx, linebuf); 00212 linebufp = beginp; 00213 } 00214 00215 fieldx++; 00216 if (c != ',') 00217 { 00218 if (got_data) 00219 { 00220 rowx++; 00221 add1row (tab); 00222 } 00223 fieldx = 0; 00224 got_data = FALSE; 00225 } 00226 } 00227 } 00228 fclose (f); 00229 return QL_SUCCESS; 00230 } /* end of read_comma_file */
static enum QlErrorVal read_ql_file | ( | QlTabData * | tab | ) | [static] |
The file selection dialog box has returned a file name. Get it, open it, open the window. Build all window window components, but do not assemble them. That is done by build_file_win ()
storing width, height, x and y in the file is outmoded but needs to be retained for compatibility.
remove leading spaces
remove leading spaces
Definition at line 240 of file filein.c.
00241 { 00242 gchar linebuf[4096]; 00243 gchar tokbuf[256]; 00244 gchar *tokbufp; 00245 gchar *linebufp; 00246 gchar *prevbufp; 00247 gint16 fieldx = 0; 00248 gint16 sortx = 0; 00249 gint16 filterx = 0; 00250 gint16 subx = 0; 00251 gint rowx; 00252 gboolean got_data; 00253 gint16 reportx = 0; 00254 gint16 colx = 0; /* indexes into array */ 00255 gint16 thislen, i, count; 00256 FILE * f; 00257 gchar singlechar; 00258 gint16 temp_field, temp_type; 00259 00260 if (!(f = fopen (tab->file->file_path, "r"))) 00261 return QL_CANNOT_OPEN_FILE; 00262 while (fgets (linebuf, sizeof (linebuf), f)) 00263 { 00264 linebufp = linebuf; 00265 if (sscanf (linebuf, "%s", tokbuf) != 1) 00266 return QL_NO_CONTENT_FOUND; 00267 00268 /* process QUICKLIST header record */ 00269 if (g_ascii_strcasecmp (tokbuf, "QUICKLIST") == 0) 00270 { 00273 if (sscanf (linebuf, "%*s%*s%*s%hu%hu%hu%hu%hu%hu%hu%hu", 00274 &tab->file->last_field, 00275 &tab->file->sort_ct, 00276 &tab->file->filter_ct, 00277 &tab->file->report_ct, 00278 &tab->view->width, 00279 &tab->view->height, 00280 &tab->view->x, 00281 &tab->view->y) < 6) 00282 return QL_BAD_QUICKLIST_DATA; 00283 tab->file->last_field--; 00284 if (tab->file->last_field < 0 00285 || tab->file->last_field >= MAX_FIELDS 00286 || tab->file->sort_ct > MAX_SORTS 00287 || tab->file->filter_ct > MAX_FILTERS 00288 || tab->file->report_ct > MAX_REPORTS) 00289 return QL_BAD_FIELD_DATA; 00290 } 00291 /* process FIELD input header record */ 00292 else if (g_ascii_strcasecmp (tokbuf, "FIELD") == 0) 00293 { 00294 QlFieldInfo * field; 00295 guint16 field_type; 00296 if (fieldx > tab->file->last_field) 00297 return QL_NO_FIELD_TYPE; 00298 field = g_new0(QlFieldInfo, 1); 00299 if (sscanf (linebuf, "%*s%hu%hu%hu%hu%hu%hu%hu%hu%40[^\n\\]", 00300 &field_type, 00301 &field->formatting, 00302 &field->decimal_places, 00303 &field->justification, 00304 &field->sheet_column, 00305 &field->width, 00306 &field->unused1, 00307 &field->unused2, tokbuf) != 9) 00308 return QL_UNABLE_TO_PARSE_FIELD_TYPE; 00309 else 00310 field->type = field_type; 00311 ql_add_fieldinfo (tab, field); 00312 tokbufp = tokbuf; 00317 while (*tokbufp == ' ') 00318 tokbufp++; 00319 if (field->type < FIELD_TYPE_TEXT 00320 || field->type > FIELD_TYPE_TIME 00321 || field->formatting > 12 00322 || field->decimal_places > 6 00323 || field->justification > GTK_JUSTIFY_CENTER 00324 || field->sheet_column > tab->file->last_field 00325 || field->width > 80) 00326 return QL_UNABLE_TO_PARSE_FIELD; 00327 00328 thislen = strlen (tokbufp); 00329 if (thislen < 1 || thislen > MAX_FIELD_NAME) 00330 return QL_FIELD_NAME_IS_TOO_LONG; 00331 field->name = g_strdup(tokbufp); 00332 fieldx++; 00333 } 00334 /* convert the SORT record to memory */ 00335 00336 else if (g_ascii_strcasecmp (tokbuf, "SORT") == 0) 00337 { 00338 if (sortx >= tab->file->sort_ct) 00339 return QL_BAD_SORT_VALUE; 00340 count = sscanf (linebuf, 00341 "%*s%hu%hu%40[^\n\\]%c%hu%u%hu%u%hu%u%hu%u%hu%u%hu%u", 00342 &tab->file->sorts[sortx].unused1, 00343 &tab->file->sorts[sortx].unused2, 00344 tokbuf, 00345 &singlechar, 00346 &tab->file->sorts[sortx].line[0].field, 00347 &tab->file->sorts[sortx].line[0].ascending, 00348 &tab->file->sorts[sortx].line[1].field, 00349 &tab->file->sorts[sortx].line[1].ascending, 00350 &tab->file->sorts[sortx].line[2].field, 00351 &tab->file->sorts[sortx].line[2].ascending, 00352 &tab->file->sorts[sortx].line[3].field, 00353 &tab->file->sorts[sortx].line[3].ascending, 00354 &tab->file->sorts[sortx].line[4].field, 00355 &tab->file->sorts[sortx].line[4].ascending, 00356 &tab->file->sorts[sortx].line[5].field, 00357 &tab->file->sorts[sortx].line[5].ascending); 00358 if (count < 6) 00359 return QL_TOO_FEW_SORT_LEVELS; 00360 tab->file->sorts[sortx].line_ct = (count - 4) / 2; 00361 /* number of sort lines read */ 00362 tokbufp = tokbuf; 00367 while (*tokbufp == ' ') 00368 tokbufp++; 00369 thislen = strlen (tokbufp); 00370 if (thislen < 1 00371 || thislen > MAX_FIELD_NAME || singlechar != '\\') 00372 return QL_INVALID_FIELD_NAME; 00373 tab->file->sorts[sortx].name = g_strdup(tokbufp); 00374 for (i = 0; i < MAX_SORT_NESTING; i++) 00375 if (tab->file->sorts[sortx].line[i].field >= 00376 tab->file->last_field + 1) 00377 return QL_SORT_NESTING_TOO_DEEP; 00378 sortx++; 00379 } 00380 /* now store a FILTER record, the most complicated record */ 00381 else if (strcmp (tokbuf, "FILTER") == 0) 00382 { 00383 if (filterx >= tab->file->filter_ct) 00384 return QL_BAD_FILTER_VALUE; 00385 if (sscanf (linebuf, "%*s%d%d%40[^\n\\]%c%hn", 00386 &tab->file->filters[filterx].by_and, 00387 &tab->file->filters[filterx].use_nocase, 00388 tokbuf, &singlechar, &count) != 4) 00389 { 00390 return QL_CANNOT_PARSE_FILTER_DATA; 00391 } 00392 tokbufp = tokbuf; 00396 while (*tokbufp == ' ') 00397 tokbufp++; 00398 thislen = strlen (tokbufp); 00399 if (thislen < 1 00400 || thislen > MAX_FIELD_NAME || singlechar != '\\') 00401 return QL_INVALID_FILTER_NAME; 00402 strcpy (tab->file->filters[filterx].name, tokbufp); 00403 subx = 0; 00404 00405 /* now loop through the lines of the filter */ 00406 linebufp = linebuf + count; 00407 while (TRUE) 00408 { 00409 if (sscanf (linebufp, "%hu%hu%hn", &temp_field, 00410 &temp_type, &count) < 2) 00411 return QL_TOO_FEW_FILTER_FIELDS; 00412 linebufp += count; 00413 tokbuf[0] = '\0'; 00414 00415 while (*linebufp == ' ') 00416 linebufp++; 00417 if (*linebufp != '\n' && *linebufp != '\\' && 00418 *linebufp != '\0') 00419 { 00420 sscanf (linebufp, "%40[^\\\n]%hn", tokbuf, &count); 00421 linebufp += count; 00422 } 00423 00424 if (temp_field > tab->file->last_field || temp_type < 0 || temp_type > 7) /* read and verify field and type */ 00425 return QL_INVALID_FIELD_TYPE; 00426 tab->file->filters[filterx].line[subx].field = temp_field; 00427 tab->file->filters[filterx].line[subx].type = temp_type; 00428 /* what happened to 18 ? */ 00429 tokbufp = tokbuf; 00430 if (strlen (tokbufp) > MAX_FILTER_COMPARE) 00431 return QL_TOO_MANY_FILTER_COMPARISONS; 00432 strcpy (tab->file->filters[filterx].line[subx].compare, 00433 tokbufp); 00434 subx++; 00435 00436 /* now look for \ before next rule, or \n to end it */ 00437 sscanf (linebufp, "%c", &singlechar); 00438 if (singlechar == '\n' || !singlechar) 00439 break; /* no more data */ 00440 if (singlechar != '\\') 00441 return QL_INVALID_CHAR_IN_FILTER; 00442 linebufp++; 00443 if (subx >= MAX_FILTER_NESTING) 00444 return QL_FILTER_NESTING_TOO_DEEP; 00445 00446 } /* End of loop that scans filter lines */ 00447 00448 /* Break comes here */ 00449 tab->file->filters[filterx].line_ct = subx; 00450 filterx++; 00451 } 00452 00453 /* store a report column */ 00454 else if (strcmp (tokbuf, "COLUMN") == 0) 00455 { 00456 if (colx >= tab->file->last_field + 1) 00457 return QL_TOO_MANY_COLUMNS; 00458 if (sscanf (linebuf, 00459 "%*s%hu%hu%hu%hu%hu%hu", 00460 &tab->file->reports[reportx].column[colx].field, 00461 &tab->file->reports[reportx].column[colx].width, 00462 &tab->file->reports[reportx].column[colx].group, 00463 &tab->file->reports[reportx].column[colx].total, 00464 &tab->file->reports[reportx].column[colx].unused1, 00465 &tab->file->reports[reportx].column[colx].unused2) < 6) 00466 return QL_INVALID_COLUMN_DATA; 00467 if (tab->file->reports[reportx].column[colx].field >= 00468 tab->file->last_field + 1) 00469 return QL_UNRECOGNISED_COLUMN_TYPE; 00470 colx++; 00471 } 00472 /* store a report record */ 00473 else if (strcmp (tokbuf, "REPORT") == 0) 00474 { 00475 if (reportx >= tab->file->report_ct || colx == 0) /* never got any column records */ 00476 return QL_NO_COLUMNS_IN_REPORT; 00477 if (sscanf (linebuf, 00478 "%*s%hd%hd%hd%hd%40[^\n\\]%c", 00479 &tab->file->reports[reportx].sort, 00480 &tab->file->reports[reportx].filter, 00481 &tab->file->reports[reportx].width, 00482 &tab->file->reports[reportx].height, 00483 tokbuf, &singlechar) < 6) 00484 return QL_INVALID_REPORT_DATA; 00485 tokbufp = tokbuf; 00486 while (*tokbufp == ' ') /* remove leading spaces */ 00487 tokbufp++; 00488 thislen = strlen (tokbufp); 00489 if (thislen < 1 || thislen > MAX_FIELD_NAME) 00490 return QL_REPORT_FIELD_NAME_TOO_LONG; 00491 tab->file->reports[reportx].name = g_strdup(tokbufp); 00492 tab->file->reports[reportx].last_column = colx - 1; 00493 reportx++; 00494 colx = 0; /* reset the report column indicator */ 00495 } 00496 00497 else if (strcmp (tokbuf, "DATA") == 0) 00498 break; 00499 else 00500 return QL_LINE_IS_TOO_BIG; 00501 } 00502 00504 if (colx != 0 00505 || fieldx != tab->file->last_field + 1 00506 || sortx != tab->file->sort_ct 00507 || filterx != tab->file->filter_ct || reportx != tab->file->report_ct) 00508 return QL_INVALID_DATA; 00509 00510 /* fields are all OK so go build the basic window and sheet */ 00511 reset_col_to_field (tab); 00512 build_basic_list_mode (tab); 00513 tab->file->last_field = fieldx; 00514 00515 /* The file is already open, now read it in. 00516 Make some effort to not load entirely blank records */ 00517 while (fgets (linebuf, sizeof (linebuf), f)) 00518 { 00519 fieldx = 0; 00520 got_data = FALSE; 00521 linebufp = linebuf; 00522 prevbufp = linebuf; 00523 rowx = tab->file->last_row; 00524 singlechar = ' '; 00525 00526 while (singlechar != '\n') 00527 { 00528 while (*linebufp != '\n' && *linebufp != '\\') 00529 linebufp++; 00530 00531 singlechar = *linebufp; 00532 if (linebufp != prevbufp) 00533 { /* ie, not a zero length field */ 00534 QlFieldInfo * field; 00535 if (fieldx > tab->file->last_field) 00536 return QL_TOO_MANY_FIELDS; 00537 field = ql_get_fieldinfo (tab, fieldx); 00538 if (!field) 00539 { 00540 fieldx++; 00541 continue; 00542 } 00543 *linebufp = '\0'; /* to terminate string move */ 00544 got_data = TRUE; 00545 gtk_sheet_set_cell_text (tab->view->sheet, rowx, 00546 field->sheet_column, prevbufp); 00547 } 00548 prevbufp = ++linebufp; 00549 fieldx++; 00550 } 00551 if (got_data) 00552 add1row (tab); 00553 } 00554 fclose (f); 00555 tab->file->current_file = QL_OLD_QLF; 00556 return QL_SUCCESS; 00557 } /* end of read_ql_file */
static enum QlErrorVal read_tab_file | ( | QlTabData * | tab | ) | [static] |
Read tab delimited files
Definition at line 561 of file filein.c.
00562 { 00563 gchar linebuf[256]; 00564 gchar *linebufp; 00565 gchar *beginp; 00566 gchar *endp; 00567 gint16 fieldx = 0; 00568 gint rowx, c; 00569 gboolean got_data; 00570 FILE * f; 00571 00572 /* Make Column 1 in field [0] */ 00573 if (!(f = fopen (tab->file->file_path, "r"))) 00574 return QL_CANNOT_OPEN_FILE; 00575 define_last_field (tab); 00576 build_basic_list_mode (tab); 00577 linebufp = beginp = linebuf; 00578 rowx = fieldx = 0; 00579 endp = linebufp + 253;; 00580 got_data = FALSE; 00581 00582 while ((c = getc (f)) != EOF) 00583 { 00584 if (c >= ' ') 00585 { 00586 *linebufp++ = c; 00587 if (linebufp >= endp) /* line is too big */ 00588 return QL_LINE_IS_TOO_BIG; 00589 } 00590 else if (c == '\n' || c == '\r' || c == '\t') 00591 { 00592 if (linebufp != beginp) 00593 { /* ie, there was data */ 00594 got_data = TRUE; 00595 *linebufp = '\0'; 00596 while (fieldx > tab->file->last_field) 00597 { 00598 if (fieldx >= MAX_FIELDS - 1) 00599 return QL_TOO_MANY_FIELDS; 00600 else 00601 add1field (tab); 00602 } 00603 gtk_sheet_set_cell_text (tab->view->sheet, rowx, 00604 fieldx, linebuf); 00605 linebufp = beginp; 00606 } /* end of storing data */ 00607 00608 fieldx++; 00609 if (c != '\t') 00610 { /* process end of line or return */ 00611 if (got_data) 00612 { 00613 rowx++; 00614 add1row (tab); 00615 } 00616 fieldx = 0; 00617 got_data = FALSE; 00618 } 00619 } 00620 } 00621 fclose (f); 00622 return QL_SUCCESS; 00623 } /* end of read_tab_file */