filein.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *            filein.c
00003  *
00004  *  Tue Sep 26 13:42:04 2006
00005  *  Copyright  2006-2007  Neil Williams
00006  *  linux@codehelp.co.uk
00007  ****************************************************************************/
00013 /*
00014     This package is free software; you can redistribute it and/or modify
00015     it under the terms of the GNU General Public License as published by
00016     the Free Software Foundation; either version 3 of the License, or
00017     (at your option) any later version.
00018 
00019     This program is distributed in the hope that it will be useful,
00020     but WITHOUT ANY WARRANTY; without even the implied warranty of
00021     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022     GNU General Public License for more details.
00023 
00024     You should have received a copy of the GNU General Public License
00025     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00026 */
00027 
00028 #include "config.h"
00029 
00030 #include <string.h>
00031 #include <glib.h>
00032 #include <gtk/gtk.h>
00033 #include <glib/gi18n.h>
00034 #include <gtkextra/gtksheet.h>
00035 #include <libgnomevfs/gnome-vfs.h>
00036 #include "types.h"
00037 #include "dialog_initial.h"
00038 #include "dim_list_menu.h"
00039 #include "filein.h"
00040 #include "main.h"
00041 #include "report.h"
00042 
00043 #ifndef QOF_UTIL_H
00044 
00045 #define ENUM_BODY(name, value)           \
00046     name value,
00047 
00048 #define DEFINE_ENUM_NON_TYPEDEF(name, list)   \
00049     enum name {                               \
00050         list(ENUM_BODY)                       \
00051     };
00052 
00053 #define FROM_STRING_DEC_NON_TYPEDEF(name, list)   \
00054     void name##fromString                          \
00055     (const gchar* str, enum name *type);
00056 
00057 #define FROM_STRING_CASE_NON_TYPEDEF(name, value) \
00058     if (strcmp(str, #name) == 0) { *type = name; }
00059 
00060 #define FROM_STRING_FUNC_NON_TYPEDEF(name, list)  \
00061     void name##fromString                          \
00062     (const gchar* str, enum name *type) {          \
00063     if(str == NULL) { return; }                    \
00064     list(FROM_STRING_CASE_NON_TYPEDEF) }
00065 
00066 #define AS_STRING_DEC_NON_TYPEDEF(name, list)     \
00067     const gchar* name##asString(enum name n);
00068 
00069 #define AS_STRING_FUNC_NON_TYPEDEF(name, list)    \
00070     const gchar* name##asString(enum name n) {     \
00071        switch (n) {                               \
00072            list(AS_STRING_CASE_NON_TYPEDEF)       \
00073            default: return ""; } }
00074 
00075 #define AS_STRING_CASE_NON_TYPEDEF(name, value)   \
00076     case name: { return #name; }
00077 
00078 #endif
00079 
00088 #define QL_ERRORS(_) \
00089     _(QL_SUCCESS, =0) \
00090     _(QL_CANNOT_OPEN_FILE, ) \
00091     _(QL_NO_CONTENT_FOUND, ) \
00092     _(QL_BAD_QUICKLIST_DATA, ) \
00093     _(QL_BAD_FIELD_DATA, ) \
00094     _(QL_NO_FIELD_TYPE, ) \
00095     _(QL_UNABLE_TO_PARSE_FIELD_TYPE, ) \
00096     _(QL_UNABLE_TO_PARSE_FIELD, ) \
00097     _(QL_FIELD_NAME_IS_TOO_LONG, ) \
00098     _(QL_BAD_SORT_VALUE, ) \
00099     _(QL_TOO_FEW_SORT_LEVELS, ) \
00100     _(QL_INVALID_FIELD_NAME, ) \
00101     _(QL_SORT_NESTING_TOO_DEEP, ) \
00102     _(QL_BAD_FILTER_VALUE, ) \
00103     _(QL_CANNOT_PARSE_FILTER_DATA, ) \
00104     _(QL_INVALID_FILTER_NAME, ) \
00105     _(QL_TOO_FEW_FILTER_FIELDS, ) \
00106     _(QL_INVALID_FIELD_TYPE, ) \
00107     _(QL_TOO_MANY_FILTER_COMPARISONS, =19) \
00108     _(QL_INVALID_CHAR_IN_FILTER, ) \
00109     _(QL_FILTER_NESTING_TOO_DEEP, ) \
00110     _(QL_TOO_MANY_COLUMNS, ) \
00111     _(QL_INVALID_COLUMN_DATA, ) \
00112     _(QL_UNRECOGNISED_COLUMN_TYPE, ) \
00113     _(QL_NO_COLUMNS_IN_REPORT, ) \
00114     _(QL_INVALID_REPORT_DATA, ) \
00115     _(QL_REPORT_FIELD_NAME_TOO_LONG, ) \
00116     _(QL_INVALID_DATA, ) \
00117     _(QL_TOO_MANY_FIELDS, =30) \
00118     _(QL_LINE_IS_TOO_BIG, =45)
00119 
00120 DEFINE_ENUM_NON_TYPEDEF (QlErrorVal, QL_ERRORS)
00121 
00122 AS_STRING_FUNC_NON_TYPEDEF (QlErrorVal, QL_ERRORS)
00123 
00125 static void
00126 define_last_field (QlTabData * tab)
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 }
00140 
00145 static void
00146 add1field (QlTabData * tab)
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 */
00159 
00160 
00163 static enum QlErrorVal
00164 read_comma_file (QlTabData * tab)
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 */
00231 
00239 static enum QlErrorVal
00240 read_ql_file (QlTabData * tab)
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 */
00558 
00560 static enum QlErrorVal
00561 read_tab_file (QlTabData * tab)
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 */
00624 
00625 static void
00626 report_error (QlTabData * tab, enum QlErrorVal err_number)
00627 {
00628     gchar * tmp;
00629 
00630     tmp = g_strconcat (_("Error: "), QlErrorValasString(err_number),
00631         ". ", _("This file is apparently not the type that you selected."),
00632         NULL);
00633     level1_error (tab, tmp);
00634     g_free (tmp);
00635 }
00636 
00639 void
00640 actually_open (const gchar * filename, QlDialogMode G_GNUC_UNUSED open_mode,
00641                QlFileType file_type, QlContext * qlc)
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 */
00672 
00675 static gchar *
00676 check_last_path (QlContext * qlc)
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 }
00685 
00687 static void
00688 any_open (QlDialogMode open_mode, QlFileType file_type, QlContext * qlc)
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 */
00737 
00738 static void
00739 set_sheet_column_cb (gpointer G_GNUC_UNUSED field_index, gpointer field_ptr, gpointer user_data)
00740 {
00741     GtkSheet * sheet;
00742     gint colx;
00743     QlFieldInfo * field = (QlFieldInfo*)field_ptr;
00744     sheet = (GtkSheet*) user_data;
00745     colx = field->sheet_column;
00746     gtk_sheet_set_column_width (sheet, colx, field->width * 8);
00747     gtk_sheet_column_button_add_label (sheet, colx, field->name);
00748     gtk_sheet_column_set_justification (sheet, colx, field->justification);
00749 }
00750 
00752 void
00753 build_basic_list_mode (QlTabData * tab)
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 */
00808 
00809 void
00810 file_import (GtkAction G_GNUC_UNUSED * action, gpointer data)
00811 {
00812     QlContext * qlc;
00813 
00814     qlc = ql_get_context (GTK_WIDGET(data));
00815     g_return_if_fail (qlc);
00816     any_open (MODE_IMPORT, QL_CSV, NULL);
00817 }
00818 
00821 void
00822 file_type_menu (QlTabData * tab, GtkWidget * chooser)
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 }
00842 
00844 void
00845 open_file (GtkAction G_GNUC_UNUSED * action, gpointer data)
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 }
00853 
00854 void
00855 open_recent (GtkRecentChooser * c, gpointer data)
00856 {
00857     QlContext * qlc;
00858     GnomeVFSFileInfo * vfsinfo;
00859     GnomeVFSResult vfsresult;
00860     gchar * filename;
00861 
00862     g_return_if_fail (data);
00863     qlc = (QlContext*)data;
00864     g_return_if_fail (qlc);
00865     filename = gtk_recent_chooser_get_current_uri (c);
00866     if (!filename)
00867         return;
00868     vfsinfo = gnome_vfs_file_info_new ();
00869     vfsresult = gnome_vfs_get_file_info (filename, vfsinfo,
00870         GNOME_VFS_FILE_INFO_DEFAULT);
00871     if ((vfsinfo->type == GNOME_VFS_FILE_TYPE_REGULAR) || (vfsinfo->size > 0))
00872         actually_open (filename, MODE_OPEN, QL_OLD_QLF, qlc);
00873     g_free (filename);
00874 }

Generated on Mon Jan 28 22:02:10 2008 for quicklist by  doxygen 1.5.4