Definition in file fileout.c.
#include "config.h"
#include <string.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <gtkextra/gtksheet.h>
#include "types.h"
#include "dialog_initial.h"
#include "dim_list_menu.h"
#include "edit.h"
#include "filein.h"
#include "main.h"
#include "report.h"
Go to the source code of this file.
Enumerations | |
enum | QlCloseMode { QL_CLOSE, QL_QUIT } |
enum | QlPrintType { QL_PRINT_NONE, QL_PRINT_ALL, QL_PRINT_LIT, QL_PRINT_FILTER } |
Functions | |
static void | all_data_clicked (GtkWidget G_GNUC_UNUSED *w, gpointer G_GNUC_UNUSED data) |
static void | filter_data_clicked (GtkWidget G_GNUC_UNUSED *w, gpointer G_GNUC_UNUSED data) |
static void | highlighted_data_clicked (GtkWidget G_GNUC_UNUSED *w, gpointer G_GNUC_UNUSED data) |
static void | ask_about_all (QlTabData *tab, GtkWidget *chooser) |
static void | remove_ql_chars (gchar *text) |
static void | print_field_cb (gpointer G_GNUC_UNUSED field_index, gpointer field_ptr, gpointer user_data) |
static void | write_ql_file (QlTabData *tab, FILE *f) |
static void | write_html (QlTabData *tab, FILE *f) |
static void | write_delimited (QlTabData *tab, FILE *f, gchar separator) |
static void | write_all_types (QlTabData *tab, gchar *name) |
static void | update_title (gchar G_GNUC_UNUSED *filename, QlTabData *tab) |
static void | any_save (QlTabData *tab) |
gboolean | ask_about_save (QlTabData *tab) |
void | close_file (GtkAction G_GNUC_UNUSED *w, gpointer data) |
gboolean | exit_action (GtkAction G_GNUC_UNUSED *a, gpointer data) |
gboolean | file_exit (GtkWidget *w, GdkEvent G_GNUC_UNUSED *event, gpointer G_GNUC_UNUSED data) |
void | file_export (GtkAction G_GNUC_UNUSED *w, gpointer data) |
void | save_as (GtkAction G_GNUC_UNUSED *w, gpointer data) |
void | save_file (GtkAction G_GNUC_UNUSED *w, gpointer data) |
Variables | |
QlCloseMode | close_mode |
GtkSheetRange | write_range |
static QlPrintType | print_all = QL_PRINT_NONE |
enum QlCloseMode |
enum QlPrintType |
QL_PRINT_NONE | default |
QL_PRINT_ALL | print the entire sheet |
QL_PRINT_LIT | print only those cells that are selected. |
QL_PRINT_FILTER | print cells that match the active filter. |
Definition at line 56 of file fileout.c.
00057 { 00059 QL_PRINT_NONE, 00061 QL_PRINT_ALL, 00063 QL_PRINT_LIT, 00065 QL_PRINT_FILTER 00066 } QlPrintType;
static void ask_about_all | ( | QlTabData * | tab, | |
GtkWidget * | chooser | |||
) | [static] |
These buttons offer to export less than the whole file
Definition at line 90 of file fileout.c.
00091 { 00092 GtkWidget *all_data; 00093 GtkWidget *filter_data; 00094 GtkWidget *highlighted_data; 00095 GtkWidget *hbox; 00096 00097 print_all = QL_PRINT_ALL; 00098 hbox = gtk_hbox_new (FALSE, 5); 00099 all_data = gtk_radio_button_new_with_label (NULL, _("Entire file")); 00100 gtk_box_pack_start (GTK_BOX (hbox), all_data, FALSE, FALSE, 0); 00101 g_signal_connect (all_data, "clicked", 00102 G_CALLBACK (all_data_clicked), NULL); 00103 00104 filter_data = gtk_radio_button_new_with_label 00105 (gtk_radio_button_get_group (GTK_RADIO_BUTTON (all_data)), 00106 _("Allowed by filter")); 00107 if (!tab->file->filter_ptr) 00108 gtk_widget_set_sensitive (filter_data, FALSE); 00109 gtk_box_pack_start (GTK_BOX (hbox), filter_data, FALSE, FALSE, 0); 00110 g_signal_connect (filter_data, "clicked", 00111 G_CALLBACK (filter_data_clicked), NULL); 00112 00113 highlighted_data = gtk_radio_button_new_with_label 00114 (gtk_radio_button_get_group (GTK_RADIO_BUTTON (all_data)), 00115 _("Highlighted cells")); 00116 gtk_box_pack_start (GTK_BOX (hbox), highlighted_data, FALSE, FALSE, 0); 00117 g_signal_connect (highlighted_data, "clicked", 00118 G_CALLBACK (highlighted_data_clicked), NULL); 00119 00120 /* there can only be a selection if some cells are selected, more than one */ 00121 if (tab->view->dialog_mode == MODE_SAVE || 00122 (tab->view->sel_type == SELECT_ENTRY || 00123 tab->view->sel_type != SELECT_COLUMN)) 00124 gtk_widget_set_sensitive (highlighted_data, FALSE); 00125 gtk_widget_show_all (hbox); 00126 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(chooser), hbox); 00127 } /* end of ask_about_all */
gboolean ask_about_save | ( | QlTabData * | tab | ) |
This dialogue box is called by the close and quit routines to just ask if the front file should be saved onto disk before the window is closed.
Definition at line 597 of file fileout.c.
00598 { 00599 GtkWidget * ask_dlg; 00600 gboolean ret; 00601 gint result; 00602 00603 ret = FALSE; 00604 /* no tabs, no data to save */ 00605 if (!tab) 00606 return FALSE; 00607 if (gtk_notebook_get_current_page (tab->qlc->notebook) < 0) 00608 return FALSE; 00609 if (!check_if_changed(tab)) 00610 return FALSE; 00611 ask_dlg = gtk_message_dialog_new (GTK_WINDOW(tab->qlc->parent), 00612 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, 00613 GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, 00614 "%s", _("This file has been changed. " 00615 "Do you want to save it to disk?")); 00616 gtk_dialog_add_buttons (GTK_DIALOG(ask_dlg), 00617 GTK_STOCK_YES, GTK_RESPONSE_YES, 00618 GTK_STOCK_NO, GTK_RESPONSE_NO, 00619 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); 00620 00621 result = gtk_dialog_run (GTK_DIALOG (ask_dlg)); 00622 switch (result) 00623 { 00624 case GTK_RESPONSE_YES: 00625 { 00626 /* if user said Yes, save the file */ 00627 any_save (tab); 00628 break; 00629 } 00630 case GTK_RESPONSE_NO: 00631 { 00632 gint tab_index; 00633 tab_index = gtk_notebook_get_current_page (tab->qlc->notebook); 00634 gtk_notebook_remove_page (tab->qlc->notebook, tab_index); 00635 if (tab->file->file_path) 00636 g_free (tab->file->file_path); 00637 tab->file->file_path = NULL; 00638 break; 00639 } 00640 case GTK_RESPONSE_CANCEL : 00641 ret = TRUE; 00642 break; 00643 } 00644 gtk_widget_destroy (ask_dlg); 00645 return ret; 00646 } /* End of ask_about_save */
static void print_field_cb | ( | gpointer G_GNUC_UNUSED | field_index, | |
gpointer | field_ptr, | |||
gpointer | user_data | |||
) | [static] |
<
Definition at line 149 of file fileout.c.
00150 { 00151 QlFieldInfo * field = (QlFieldInfo*)field_ptr; 00152 FILE * f; 00153 f = (FILE*)user_data; 00154 00155 remove_ql_chars (field->name); 00156 fprintf (f, "FIELD %u %u %u %u %u %u %u %u %s\n", 00157 field->type, 00158 field->formatting, 00159 field->decimal_places, 00160 field->justification, 00161 field->sheet_column, 00162 field->width, 00163 field->unused1, 00164 field->unused2, 00165 field->name); 00166 }
static void remove_ql_chars | ( | gchar * | text | ) | [static] |
Routine removes backslash and trailing blanks, which are of no value.
Definition at line 135 of file fileout.c.
00136 { 00137 gchar *linebufp = text; 00138 while (*linebufp) 00139 { 00140 if (*linebufp == '\\') 00141 *linebufp = '/'; 00142 linebufp++; 00143 } 00144 linebufp--; /* skip back over ending zero */ 00145 linebufp = g_strstrip (linebufp); /* removes trailing blanks */ 00146 } /* end of remove_ql_chars */
void save_file | ( | GtkAction G_GNUC_UNUSED * | w, | |
gpointer | data | |||
) |
Write the file onto disk with its present file path
Definition at line 732 of file fileout.c.
00733 { 00734 QlContext * qlc; 00735 QlTabData * tab; 00736 00737 qlc = ql_get_context (GTK_WIDGET(data)); 00738 tab = ql_get_tabdata (qlc); 00739 print_all = QL_PRINT_ALL; 00740 if ((tab->file->current_file == QL_NO_FILE) || 00741 (tab->view->dialog_mode == MODE_NEW)) 00742 { 00743 tab->file->current_file = tab->file->file_type = QL_OLD_QLF; 00744 tab->view->dialog_mode = MODE_NEW; 00745 any_save (tab); 00746 } 00747 else 00748 { 00749 tab->file->file_type = QL_OLD_QLF; 00750 tab->view->dialog_mode = MODE_SAVE; 00751 save_as (NULL, data); 00752 } 00753 }
static void write_all_types | ( | QlTabData * | tab, | |
gchar * | name | |||
) | [static] |
This puts all file types onto disk
Definition at line 411 of file fileout.c.
00412 { 00413 FILE * f; 00414 gchar * backup_name; 00415 gchar * fullpath; 00416 00417 g_return_if_fail (tab); 00418 g_return_if_fail (tab->file->file_type > QL_NO_FILE); 00419 00420 tab->file->file_name = name; 00421 fullpath = tab->file->file_path; 00422 00423 backup_name = g_strconcat (fullpath, "~", NULL); 00424 rename (fullpath, backup_name); 00425 00426 /* determine if whole file is to be written */ 00427 write_range.row0 = write_range.col0 = 0; 00428 write_range.rowi = tab->file->last_row - 1; 00429 write_range.coli = tab->file->last_field; 00430 if (print_all == QL_PRINT_LIT) /* highlighted */ 00431 write_range = tab->view->sel_range; 00432 00433 f = NULL; 00434 switch (tab->file->file_type) 00435 { 00436 case QL_OLD_QLF: 00437 { 00438 if (!g_str_has_suffix(fullpath, "qlf")) 00439 { 00440 fullpath = g_strconcat (fullpath, ".qlf", NULL); 00441 } 00442 if (!(f = fopen (fullpath, "w"))) 00443 { 00444 level1_error (tab, _("Can't write the file. Strange.")); 00445 return; 00446 } 00448 write_ql_file (tab, f); 00449 tab->file->file_name = g_path_get_basename (fullpath); 00450 tab->file->file_path = fullpath; 00451 tab->file->changed = FALSE; 00452 break; 00453 } 00454 case QL_EXPORT_HTML: 00455 { 00456 if (!g_str_has_suffix(name, "html")) 00457 { 00458 name = g_strconcat (name, ".html", NULL); 00459 } 00460 if (!(f = fopen (name, "w"))) 00461 { 00462 level1_error (tab, _("Can't write the file. Strange.")); 00463 return; 00464 } 00466 write_html (tab, f); 00467 tab->file->file_name = name; 00468 break; 00469 } 00470 case QL_CSV: 00471 { 00472 if (!g_str_has_suffix(name, "csv")) 00473 { 00474 name = g_strconcat (name, ".csv", NULL); 00475 } 00476 if (!(f = fopen (name, "w"))) 00477 { 00478 level1_error (tab, _("Can't write the file. Strange.")); 00479 return; 00480 } 00482 write_delimited (tab, f, ','); 00483 tab->file->file_name = name; 00484 break; 00485 } 00486 case QL_TSV: 00487 { 00488 if (!g_str_has_suffix(name, "tsv")) 00489 { 00490 name = g_strconcat (name, ".tsv", NULL); 00491 } 00492 if (!(f = fopen (name, "w"))) 00493 { 00494 level1_error (tab, _("Can't write the file. Strange.")); 00495 return; 00496 } 00498 write_delimited (tab, f, '\t'); 00499 tab->file->file_name = name; 00500 break; 00501 } 00502 default: 00503 break; 00504 } 00505 fclose (f); 00506 dim_all_menus (tab->qlc); 00507 } /* end of write_all_types */
static void write_delimited | ( | QlTabData * | tab, | |
FILE * | f, | |||
gchar | separator | |||
) | [static] |
Write the file onto disk with called char as a separator.
Definition at line 371 of file fileout.c.
00372 { 00374 gchar linebuf[4096]; 00375 gchar *text; 00376 gint32 rowx; 00377 gint16 colx; /* indexes into array */ 00378 gint x, y; 00379 gboolean first_in_row; 00380 00381 /* NOW WRITE THE DATA RECORDS. Last row is always empty. */ 00382 for (rowx = write_range.row0; rowx < write_range.rowi; rowx++) 00383 { 00384 if (print_all != QL_PRINT_ALL && !row_is_visible (tab, rowx)) 00385 continue; 00386 first_in_row = TRUE; 00387 for (colx = write_range.col0; colx <= write_range.coli; colx++) 00388 { 00389 text = gtk_sheet_cell_get_text (tab->view->sheet, rowx, colx); 00390 if (!first_in_row) 00391 fprintf (f, "%c", separator); 00392 first_in_row = FALSE; 00393 if (text) 00394 { 00395 x = y = 0; /* remove separator characters from data */ 00396 do 00397 { 00398 if (text[x] != separator) 00399 linebuf[y++] = text[x]; 00400 } 00401 while (text[x++]); /* stop at end of string */ 00402 fprintf (f, "%s", linebuf); 00403 } 00404 } 00405 fprintf (f, "\n"); /* write nothing if nothing there */ 00406 } 00407 } /* end of write_delimited */
static void write_html | ( | QlTabData * | tab, | |
FILE * | f | |||
) | [static] |
Definition at line 311 of file fileout.c.
00312 { 00313 gchar *text; 00314 gint32 rowx; 00315 gint16 fieldx; 00316 gint16 justification; 00317 QlFieldInfo * field; 00318 gint16 colx = 0; /* indexes into array */ 00319 00320 /* Output Head Info Stuff */ 00321 fprintf (f, 00322 "<html>\n" 00323 "<head>\n" 00324 "<title>%s</title>\n" 00325 "<meta name=\"Generator\" content=\"QUICKLIST %s\">\n" 00326 "</head>\n\n" 00327 "<body bgcolor=\"#ffffff\">\n" 00328 "<table width=\"2\">\n" " <tr>\n", 00329 tab->file->file_path, VERSION); 00330 for (colx = write_range.col0; colx <= write_range.coli; colx++) 00331 { 00332 fieldx = tab->file->col_to_field[colx]; 00333 field = ql_get_fieldinfo (tab, fieldx); 00334 fprintf (f, " <th>%s</th>\n", field->name); 00335 } 00336 fprintf (f, " </tr>\n"); 00337 00338 for (rowx = write_range.row0; rowx <= write_range.rowi; rowx++) 00339 { 00340 if (print_all != 'A' && !row_is_visible (tab, rowx)) 00341 continue; 00342 fprintf (f, " <tr>\n"); 00343 for (colx = write_range.col0; colx <= write_range.coli; colx++) 00344 { 00345 text = gtk_sheet_cell_get_text (tab->view->sheet, rowx, colx); 00346 fputs ("<td>", f); 00347 if (text) 00348 { 00349 fieldx = tab->file->col_to_field[colx]; 00350 field = ql_get_fieldinfo (tab, fieldx); 00351 justification = field->justification; 00352 if (justification == GTK_JUSTIFY_CENTER) 00353 fputs ("<center>", f); 00354 else if (justification == GTK_JUSTIFY_RIGHT) 00355 fputs ("<right>", f); 00356 fprintf (f, "%s", text); 00357 if (justification == GTK_JUSTIFY_CENTER) 00358 fputs ("</center>", f); 00359 else if (justification == GTK_JUSTIFY_RIGHT) 00360 fputs ("</right>", f); 00361 } 00362 fputs ("</td>\n", f); 00363 } 00364 fprintf (f, " </tr>\n"); 00365 } 00366 fprintf (f, "</table>\n</body>\n</html>\n"); 00367 } /* end of html output */
static void write_ql_file | ( | QlTabData * | tab, | |
FILE * | f | |||
) | [static] |
Write the file onto disk. Called by save, save_as, close, quit
indexes into array
try to not write trailing slashes
try to not write blank records
Definition at line 171 of file fileout.c.
00172 { 00173 gchar *text; 00174 gint32 rowx; 00175 gint16 fieldx = 0; 00176 gint16 sortx = 0; 00177 gint16 filterx = 0; 00178 gint16 subx = 0; 00179 gint16 reportx = 0; 00181 gint16 colx = 0; 00183 gint16 blank_fields; 00185 gboolean got_data; 00186 00187 g_return_if_fail (tab); 00188 get_window_size_loc (GTK_WIDGET (tab->qlc->parent)); 00189 00190 fprintf (f, "QUICKLIST %s 06/10/99 %u %u %u %u %u %u %u %u\n", 00191 VERSION, 00192 tab->file->last_field + 1, 00193 tab->file->sort_ct, 00194 tab->file->filter_ct, 00195 tab->file->report_ct, tab->view->width, tab->view->height, 00196 tab->view->x, tab->view->y); 00197 ql_fieldinfo_foreach (tab, print_field_cb, f); 00198 /* 00199 for (fieldx = 0; fieldx <= tab->file->last_field; fieldx++) 00200 { 00201 remove_ql_chars (tab->file->fields[fieldx]->name); 00202 fprintf (f, "FIELD %u %u %u %u %u %u %u %u %s\n", 00203 tab->file->fields[fieldx]->type, 00204 tab->file->fields[fieldx]->formatting, 00205 tab->file->fields[fieldx]->decimal_places, 00206 tab->file->fields[fieldx]->justification, 00207 tab->file->fields[fieldx]->sheet_column, 00208 tab->file->fields[fieldx]->width, 00209 tab->file->fields[fieldx]->unused1, 00210 tab->file->fields[fieldx]->unused2, 00211 tab->file->fields[fieldx]->name); 00212 } 00213 */ 00214 for (sortx = 0; sortx < tab->file->sort_ct; sortx++) 00215 { 00216 remove_ql_chars (tab->file->sorts[sortx].name); 00217 fprintf (f, "SORT %u %u %s\\", 00218 tab->file->sorts[sortx].unused1, 00219 tab->file->sorts[sortx].unused2, 00220 tab->file->sorts[sortx].name); 00221 for (subx = 0; subx < tab->file->sorts[sortx].line_ct; subx++) 00222 fprintf (f, " %u %u", 00223 tab->file->sorts[sortx].line[subx].field, 00224 tab->file->sorts[sortx].line[subx].ascending); 00225 fprintf (f, "\n"); 00226 } /* end of printing one sort record */ 00227 00228 /* Here we need to write a filter. */ 00229 for (filterx = 0; filterx < tab->file->filter_ct; filterx++) 00230 { 00231 remove_ql_chars (tab->file->filters[filterx].name); 00232 fprintf (f, "FILTER %d %d %s", 00233 tab->file->filters[filterx].by_and, 00234 tab->file->filters[filterx].use_nocase, 00235 tab->file->filters[filterx].name); 00236 for (subx = 0; subx < tab->file->filters[filterx].line_ct; subx++) 00237 { 00238 fprintf (f, "\\%u %u", 00239 tab->file->filters[filterx].line[subx].field, 00240 tab->file->filters[filterx].line[subx].type); 00241 remove_ql_chars (tab->file->filters[filterx].line[subx].compare); 00242 fprintf (f, " %s", tab->file->filters[filterx].line[subx].compare); 00243 } 00244 fprintf (f, "\n"); /* Finish off the filter */ 00245 } 00246 00247 /* Now a report column */ 00248 for (reportx = 0; reportx < tab->file->report_ct; reportx++) 00249 { 00250 for (colx = 0; colx <= tab->file->reports[reportx].last_column; colx++) 00251 fprintf (f, "COLUMN %u %u %u %u %u %u\n", 00252 tab->file->reports[reportx].column[colx].field, 00253 tab->file->reports[reportx].column[colx].width, 00254 tab->file->reports[reportx].column[colx].group, 00255 tab->file->reports[reportx].column[colx].total, 00256 tab->file->reports[reportx].column[colx].unused1, 00257 tab->file->reports[reportx].column[colx].unused2); 00258 00259 remove_ql_chars (tab->file->reports[reportx].name); 00260 fprintf (f, "REPORT %i %i %u %u %s\\\\\n", 00261 tab->file->reports[reportx].sort, 00262 tab->file->reports[reportx].filter, 00263 tab->file->reports[reportx].width, 00264 tab->file->reports[reportx].height, 00265 tab->file->reports[reportx].name); 00266 00267 } /* end of writing report columns and report records */ 00268 fprintf (f, "DATA 0 0\n"); 00269 00270 /* NOW WRITE THE DATA RECORDS. Last row is always empty. 00271 The logic is difficult enough that I use an intermediate variable */ 00272 for (rowx = 0; rowx < tab->file->last_row; rowx++) 00273 { 00274 gint last_field; 00275 got_data = FALSE; /* to not write empty records */ 00276 blank_fields = 0; /* to not write trailing \\\\\ */ 00277 last_field = ql_get_last_field (tab); 00278 for (fieldx = 0; fieldx <= last_field; fieldx++) 00279 { 00280 QlFieldInfo * field; 00281 field = ql_get_fieldinfo (tab, fieldx); 00282 colx = field->sheet_column; 00283 text = gtk_sheet_cell_get_text (tab->view->sheet, rowx, colx); 00284 if (text) 00285 { 00286 while (blank_fields) 00287 { /* write the skipped blank fields */ 00288 fprintf (f, "\\"); 00289 blank_fields--; 00290 } 00291 00292 remove_ql_chars (text); 00293 fprintf (f, "%s\\", text); 00294 got_data = TRUE; 00295 } 00296 else 00297 blank_fields++; 00298 } 00299 if (got_data) 00300 fprintf (f, "\n"); /* write nothing if nothing there */ 00301 } 00302 fprintf (f, "\n"); /* write nothing if nothing there */ 00303 tab->file->changed = FALSE; 00304 }
GtkSheetRange write_range |