Index: ChangeLog =================================================================== RCS file: /cvs/gnome/ghex/ChangeLog,v retrieving revision 1.134 diff -u -5 -r1.134 ChangeLog --- ChangeLog 2001/04/14 15:18:11 1.134 +++ ChangeLog 2001/04/15 18:22:27 @@ -1,5 +1,34 @@ +2001-04-15 Nathan Cullen + + * src/ghex.h broke up print_document into smaller functions + (print_document): deleted declaration + (ghex_print_job_info_new): added delcaration + (ghex_print_job_info_destroy): added declaration + (ghex_print_job_execute): added declaration + (GHexPrintJobInfo): added printing range, preview flag, printer + * src/print.c refactored print_document, merged changes with AleX's + patch. + (preview_destroy_cb): deleted, functionality moved to ui.c + (print_document): deleted, refactored + (start_job): delted empty function + (end_job): delted empty function + (print_header): replaced spaces with tabs + (ghex_print_job_info_new): creates a new GHexPrintJobInfo object + (ghex_print_job_info_destroy): deallocates a GHexPrintJobInfo object + (ghex_print_job_execute): executes the job described by a GHexPrintJob + Info object + * src/ui.c added print range and preview button to print dialog + (print_dialog_clicked_cb): deleted, functionality in + ghex_print_run_dialog + (print_cb): modified to call ghex_print + (print_preview_cb): modified to call ghex_print + (ghex_print): added function. prints or previews current document + (ghex_print_run_dialog): added function. runs the print dialog with + a new preview button and a print range + (ghex_print_preview_real): added function. previews a print job + 2001-04-14 Jaka Mocnik * src/gtkhex.c (scroll_timeout_handler): return TRUE. (*_motion_cb): simplify scrolling logic. (display_scrolled): removed hide_cursor()/show_cursor() pair. Index: src/ghex.h =================================================================== RCS file: /cvs/gnome/ghex/src/ghex.h,v retrieving revision 1.44 diff -u -5 -r1.44 ghex.h --- src/ghex.h 2001/03/18 18:44:14 1.44 +++ src/ghex.h 2001/04/15 18:22:27 @@ -105,14 +105,18 @@ } Converter; typedef struct { GnomePrintMaster *master; GnomePrintContext *pc; + GnomePrinter *printer; GnomeFont *d_font, *h_font; HexDocument *doc; int pages; + gint range; + gint page_first; + gint page_last; float page_width, page_height; float margin_top, margin_bottom, margin_left, margin_right; float printable_width, printable_height; float header_height; @@ -122,10 +126,11 @@ int bytes_per_row, rows_per_page; float pad_size; int offset_chars ; /* How many chars are used in the offset window */ int gt; /* group_type */ + gboolean preview; } GHexPrintJobInfo; extern int restarted; extern const struct poptOption options[]; extern GSList *cl_files; @@ -174,12 +179,13 @@ void create_dialog_title (GtkWidget *, gchar *); gint ask_user (GnomeMessageBox *); GtkWidget *create_button (GtkWidget *, const gchar *, gchar *); /* printing */ -void print_document (HexDocument *doc, guint group_type, - GnomePrinter *printer); +void ghex_print_job_execute(GHexPrintJobInfo *pji); +GHexPrintJobInfo *ghex_print_job_info_new(HexDocument *doc, guint group_type); +void ghex_print_job_info_destroy(GHexPrintJobInfo *pji); /* config stuff */ void save_configuration (void); void load_configuration (void); Index: src/print.c =================================================================== RCS file: /cvs/gnome/ghex/src/print.c,v retrieving revision 1.13 diff -u -5 -r1.13 print.c --- src/print.c 2001/04/14 13:44:19 1.13 +++ src/print.c 2001/04/15 18:22:27 @@ -22,200 +22,48 @@ Printing module by: Chema Celorio */ #include "ghex.h" #include "gtkhex.h" -#include #define is_printable(c) (((((guchar)c)>=0x20) && (((guchar)c)<=0x7F))?1:0) const GnomePaper *def_paper; gchar *data_font_name, *header_font_name; gdouble data_font_size, header_font_size; gint shaded_box_size; -static void preview_destroy_cb(GtkObject *obj, GHexPrintJobInfo *job); -static void start_job(GnomePrintContext *pc); static void print_header(GHexPrintJobInfo *pji, unsigned int page); static void end_page(GnomePrintContext *pc); static void print_row(GHexPrintJobInfo *pji, unsigned int offset, unsigned int bytes, int row); -static void end_job(GnomePrintContext *pc); static void format_hex(HexDocument *doc, guint gt, gchar *out, guint start, guint end); static void format_ascii(HexDocument *doc, gchar *out, guint start, guint end); static void print_shaded_boxes( GHexPrintJobInfo *pji, guint page, guint max_row); static void print_shaded_box( GHexPrintJobInfo *pji, guint row, guint rows); static gboolean print_verify_fonts (void); -static void preview_destroy_cb(GtkObject *obj, GHexPrintJobInfo *job) -{ - gtk_object_unref(GTK_OBJECT(job->master)); - g_free(job); -} - -/** - * print_document: - * - * The main printing function. - **/ -void print_document(HexDocument *doc, guint gt, GnomePrinter *printer) -{ - gint i, j; - GHexPrintJobInfo *pji; - GnomeFont *d_font, *h_font; - guint32 glyph; - ArtPoint point; - - /* -- Added to verify fonts (Extract from Gedit) --*/ - if(!print_verify_fonts ()) - return; - - d_font = gnome_font_new(data_font_name, data_font_size); - if(!d_font) - return; - - h_font = gnome_font_new(header_font_name, header_font_size); - if(!h_font){ - gtk_object_unref(GTK_OBJECT(d_font)); - return; - } - - /* Create Printing Job */ - pji = g_new0(GHexPrintJobInfo, 1); - pji->h_font = h_font; - pji->d_font = d_font; - - pji->gt = gt; - pji->master = gnome_print_master_new(); - gnome_print_master_set_paper(pji->master, def_paper); - - if(printer) { - gnome_print_master_set_printer(pji->master, printer); - } - - pji->pc = gnome_print_master_get_context(pji->master); - pji->doc = doc; - - g_return_if_fail(pji->pc != NULL); - - pji->page_width = gnome_paper_pswidth(def_paper); - pji->page_height = gnome_paper_psheight(def_paper); - - /* I've taken the liberty to convert inches to ps points */ - pji->margin_top = .75 * 72; /* Printer margins, not page margins */ - pji->margin_bottom = .75 * 72; - pji->margin_left = .75 * 72; - pji->margin_right = .75 * 72; - pji->header_height = 2.2 * (gnome_font_get_ascender(GNOME_FONT(h_font)) + - gnome_font_get_descender(GNOME_FONT(h_font))); - - /* Get font_char_width */ - glyph = ' '; - gnome_font_get_glyph_stdadvance (GNOME_FONT (d_font), glyph, &point); - pji->font_char_width = point.x; - - pji->font_char_height = gnome_font_get_ascender(GNOME_FONT(d_font)) + - gnome_font_get_descender(GNOME_FONT(d_font)); - /* add 10% for spacing between lines */ - pji->font_char_height *= 1.1; - pji->pad_size = .5 * 72; - pji->offset_chars = 8; - - pji->printable_width = pji->page_width - - pji->margin_left - - pji->margin_right; - pji->printable_height = pji->page_height - - pji->margin_top - - pji->margin_bottom; - pji->bytes_per_row = (pji->printable_width - pji->pad_size*2 - - (pji->offset_chars * pji->font_char_width))/ - ((3 + (1/((float)pji->gt)))*pji->font_char_width); - pji->bytes_per_row -= pji->bytes_per_row % pji->gt; - pji->rows_per_page = (pji->printable_height - - pji->header_height)/pji->font_char_height - - 1 ; - pji->pages = (((doc->file_size/pji->bytes_per_row) + 1)/ - pji->rows_per_page) + 1; - - start_job(pji->pc); - for(i = 1; i <= pji->pages; i++) - { - int max_row; - print_header(pji, i); - gnome_print_setfont(pji->pc, d_font); - max_row = ( pji->bytes_per_row*pji->rows_per_page*(i) > - doc->file_size ? - (int)((doc->file_size-1)-(pji->bytes_per_row*pji->rows_per_page*(i-1)))/ - pji->bytes_per_row+1: - pji->rows_per_page); - print_shaded_boxes(pji, i, max_row); - for(j = 1; j <= pji->rows_per_page; j++) - { - int file_offset = pji->bytes_per_row*(j - 1) + - pji->bytes_per_row*pji->rows_per_page*(i - 1); - int length; - length = (file_offset + pji->bytes_per_row > - doc->file_size ? - doc->file_size - file_offset : - pji->bytes_per_row); - if(file_offset >= doc->file_size) - break; - print_row(pji, file_offset, length, j); - } - end_page(pji->pc); - } - end_job(pji->pc); - - gnome_print_context_close(pji->pc); - - gnome_print_master_close(pji->master); - - gtk_object_unref(GTK_OBJECT(d_font)); - gtk_object_unref(GTK_OBJECT(h_font)); - - if(printer) { - gnome_print_master_print(pji->master); - gtk_object_unref(GTK_OBJECT(pji->master)); - g_free(pji); - } - else { - GnomePrintMasterPreview *preview; - gchar *title; - - title = g_strdup_printf(_("GHex (%s): Print Preview"), doc->file_name); - preview = gnome_print_master_preview_new(pji->master, title); - g_free(title); - gtk_signal_connect(GTK_OBJECT(preview), "destroy", - GTK_SIGNAL_FUNC(preview_destroy_cb), pji); - gtk_widget_show(GTK_WIDGET(preview)); - } -} - -static void start_job(GnomePrintContext *pc) -{ -} - static void print_header(GHexPrintJobInfo *pji, unsigned int page) { - guchar* text1 = g_strdup(pji->doc->file_name); - guchar* text2 = g_strdup_printf(_("Page: %i/%i"),page,pji->pages); + guchar* text1 = g_strdup(pji->doc->file_name); + guchar* text2 = g_strdup_printf(_("Page: %i/%i"),page,pji->pages); gfloat x, y, len; gnome_print_setfont(pji->pc, pji->h_font); /* Print the file name */ y = pji->page_height - pji->margin_top - 2.1*gnome_font_get_ascender(pji->h_font) - 1.1*gnome_font_get_descender(pji->h_font); - len = gnome_font_get_width_string (pji->h_font, text1); + len = gnome_font_get_width_string (pji->h_font, text1); x = pji->page_width/2 - len/2; gnome_print_moveto(pji->pc, x, y); gnome_print_show(pji->pc, text1); gnome_print_stroke(pji->pc); /* Print the page/pages */ y = pji->page_height - pji->margin_top - gnome_font_get_ascender(pji->h_font); - len = gnome_font_get_width_string (pji->h_font, text2); + len = gnome_font_get_width_string (pji->h_font, text2); x = pji->page_width - len - 36; gnome_print_moveto(pji->pc, x, y); gnome_print_show(pji->pc, text2); gnome_print_stroke(pji->pc); } @@ -259,14 +107,10 @@ static void end_page(GnomePrintContext *pc) { gnome_print_showpage(pc); } -static void end_job(GnomePrintContext *pc) -{ -} - static void format_hex(HexDocument *doc, guint gt, gchar *out, guint start, guint end) { gint i, j, low, high; guchar c; @@ -297,12 +141,11 @@ out[j] = '.'; } out[j++] = 0; } -static void print_shaded_boxes(GHexPrintJobInfo *pji, guint page, - guint max_row) +static void print_shaded_boxes(GHexPrintJobInfo *pji, guint page, guint max_row) { gint i; gint box_size = shaded_box_size; if(box_size == 0) @@ -340,11 +183,11 @@ gnome_print_closepath(pji->pc); gnome_print_fill(pji->pc); gnome_print_setrgbcolor(pji->pc, 0.0, 0.0, 0.0); } -gboolean print_verify_fonts() +static gboolean print_verify_fonts() { GnomeFont *test_font; guchar *test_font_name; test_font_name = g_strdup(data_font_name); @@ -376,7 +219,161 @@ g_free(test_font_name); return TRUE; } +/** + * ghex_print_job_info_new: + * @doc: Pointer to the HexDocument to be printed. + * @group_type: How to group bytes. GROUP_BYTE, GROUP_WORD, or GROUP_LONG. + * + * Return value: A pointer to a newly-created GHexPrintJobInfo object. NULL if +unable to create. + * + * Creates a new GHexPrintJobInfo object. + **/ +GHexPrintJobInfo * +ghex_print_job_info_new(HexDocument *doc, guint group_type) +{ + GHexPrintJobInfo *pji; + GnomeFont *d_font; + GnomeFont *h_font; + guint32 glyph; + ArtPoint point; + + if (!doc || !print_verify_fonts()) + return NULL; + + /* Create the header and data fonts */ + d_font = gnome_font_new(data_font_name, data_font_size); + if (!d_font) + return NULL; + + h_font = gnome_font_new(header_font_name, header_font_size); + if (!h_font) { + gnome_font_unref(d_font); + return NULL; + } + + pji = g_new0(GHexPrintJobInfo, 1); + pji->h_font = h_font; + pji->d_font = d_font; + pji->gt = group_type; + + pji->master = gnome_print_master_new(); + + gnome_print_master_set_paper(pji->master, def_paper); + + pji->doc = doc; + + pji->page_width = gnome_paper_pswidth(def_paper); + pji->page_height = gnome_paper_psheight(def_paper); + + /* Convert inches to ps points */ + pji->margin_top = .75 * 72; /* Printer margins, not page margins */ + pji->margin_bottom = .75 * 72; + pji->margin_left = .75 * 72; + pji->margin_right = .75 * 72; + pji->header_height = 2.2*(gnome_font_get_ascender(GNOME_FONT(h_font)) + + gnome_font_get_descender(GNOME_FONT(h_font))); + + /* Get font character width */ + glyph = ' '; + gnome_font_get_glyph_stdadvance(GNOME_FONT(d_font), glyph, &point); + pji->font_char_width = point.x; + + pji->font_char_height = gnome_font_get_ascender(GNOME_FONT(d_font)) + + gnome_font_get_descender(GNOME_FONT(d_font)); + + /* Add 10% spacing between lines */ + pji->font_char_height *= 1.1; + pji->pad_size = .5 * 72; + pji->offset_chars = 8; + + pji->printable_width = pji->page_width - + pji->margin_left - + pji->margin_right; + pji->printable_height = pji->page_height - + pji->margin_top - + pji->margin_bottom; + pji->bytes_per_row = (pji->printable_width - pji->pad_size*2 - + (pji->offset_chars * + pji->font_char_width))/ + ((3 + (1/((float)pji->gt))) * + pji->font_char_width); + pji->bytes_per_row -= pji->bytes_per_row % pji->gt; + pji->rows_per_page = (pji->printable_height - pji->header_height) / + pji->font_char_height - 1; + pji->pages = (((doc->file_size/pji->bytes_per_row) + 1)/ + pji->rows_per_page) + 1; + pji->page_first = 1; + pji->page_last = pji->pages; + pji->preview = FALSE; + pji->printer = NULL; + pji->range = GNOME_PRINT_RANGE_ALL; + + return pji; +} + +/** + * ghex_print_job_info_destroy: + * @pji: Pointer to the GHexPrintJobInfo to be destroyed. + * + * Destroys the GHexPrintJobInfo object pointed to by pji. + **/ +void +ghex_print_job_info_destroy(GHexPrintJobInfo *pji) +{ + gnome_print_master_close(pji->master); + gnome_font_unref(pji->h_font); + gnome_font_unref(pji->d_font); + g_free(pji); +} + +/** + * ghex_print_job_execute: + * @pji: Pointer to the GHexPrintJobInfo object. + * + * Performs the printing job described by the GHexPrintJobInfo object. + **/ +void +ghex_print_job_execute(GHexPrintJobInfo *pji) +{ + gint i; + gint j; + + g_return_if_fail(pji != NULL); + + pji->pc = gnome_print_master_get_context(pji->master); + + g_return_if_fail(pji->pc != NULL); + + for(i = pji->page_first; i <= pji->page_last; i++) { + int max_row; + print_header(pji, i); + gnome_print_setfont(pji->pc, pji->d_font); + max_row = (pji->bytes_per_row*pji->rows_per_page*(i) > + pji->doc->file_size ? + (int)((pji->doc->file_size-1)- + (pji->bytes_per_row * + pji->rows_per_page*(i-1))) / + pji->bytes_per_row + 1: + pji->rows_per_page); + print_shaded_boxes(pji, i, max_row); + for(j = 1; j <= pji->rows_per_page; j++) { + int file_offset = pji->bytes_per_row*(j - 1) + + pji->bytes_per_row*pji->rows_per_page*(i - 1); + int length; + length = (file_offset + pji->bytes_per_row > + pji->doc->file_size ? + pji->doc->file_size - file_offset : + pji->bytes_per_row); + if(file_offset >= pji->doc->file_size) + break; + print_row(pji, file_offset, length, j); + } + end_page(pji->pc); + } + gnome_print_context_close(pji->pc); +} Index: src/ui.c =================================================================== RCS file: /cvs/gnome/ghex/src/ui.c,v retrieving revision 1.53 diff -u -5 -r1.53 ui.c --- src/ui.c 2001/04/12 20:34:09 1.53 +++ src/ui.c 2001/04/15 18:22:27 @@ -22,16 +22,20 @@ */ #include #include #include -#include +#include +#include #include "ghex.h" static void open_selected_file(GtkWidget *); static void save_selected_file(GtkWidget *, GtkWidget *view); static void export_html_selected_file(GtkWidget *w, GtkHex *view); +static void ghex_print(gboolean preview); +static gboolean ghex_print_run_dialog(GHexPrintJobInfo *pji); +static void ghex_print_preview_real(GHexPrintJobInfo *pji); /* callbacks to nullify widget pointer after a delete event */ static void about_destroy_cb(GtkObject *, GtkWidget **); /* callbacks for global menus */ @@ -297,66 +301,18 @@ gtk_window_set_modal(GTK_WINDOW(file_sel), TRUE); gtk_widget_show (file_sel); } -static void print_dialog_clicked_cb(GtkWidget *widget, gint button, gpointer data) -{ - if(button == 0) { - GnomePrinter *printer; - GnomePrinterDialog *dialog = GNOME_PRINTER_DIALOG(widget); - HexDocument *doc = (HexDocument *)data; - - printer = gnome_printer_dialog_get_printer(dialog); - - if(printer) { - GtkWidget *active_view; - guint group_type = 1; - - active_view = gnome_mdi_get_active_view(mdi); - if(active_view) - group_type = GTK_HEX(active_view)->group_type; - - print_document(doc, group_type, printer); - } - } - - gnome_dialog_close(GNOME_DIALOG(widget)); -} - static void print_cb(GtkWidget *w) { - HexDocument *doc; - GtkWidget *dialog; - - if(gnome_mdi_get_active_child(mdi) == NULL) - return; - - doc = HEX_DOCUMENT(gnome_mdi_get_active_child(mdi)); - - dialog = gnome_printer_dialog_new (); - - gnome_dialog_set_parent(GNOME_DIALOG(dialog), - GTK_WINDOW(mdi->active_window)); - gtk_signal_connect(GTK_OBJECT(dialog), "clicked", - (GtkSignalFunc)print_dialog_clicked_cb, doc); - gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); - gtk_widget_show_all(dialog); + ghex_print(FALSE); } static void print_preview_cb(GtkWidget *w) { - GtkWidget *active_view; - HexDocument *doc; - - active_view = gnome_mdi_get_active_view(mdi); - if(!active_view) - return; - - doc = HEX_DOCUMENT(gnome_mdi_get_child_from_view(active_view)); - - print_document(doc, GTK_HEX(active_view)->group_type, NULL); + ghex_print(TRUE); } static void export_html_cb(GtkWidget *w) { HexDocument *doc; @@ -554,5 +510,123 @@ gnome_app_error(mdi->active_window, _("Can't open file for writing!")); gtk_widget_destroy(GTK_WIDGET(file_sel)); file_sel = NULL; } + +/** + * ghex_print + * @preview: Indicates whether to show only a print preview (TRUE) or +to display the print dialog. + * + * Prints or previews the current document. + **/ +static void +ghex_print(gboolean preview) +{ + GHexPrintJobInfo *pji; + HexDocument *doc; + GtkWidget *active_view; + gboolean cancel = FALSE; + + if (!gnome_mdi_get_active_child(mdi)) + return; + + doc = HEX_DOCUMENT(gnome_mdi_get_active_child(mdi)); + active_view = gnome_mdi_get_active_view(mdi); + if (!active_view || !doc) + return; + + pji = ghex_print_job_info_new(doc, GTK_HEX(active_view)->group_type); + + if (!pji) + return; + + pji->preview = preview; + + if (!pji->preview) + cancel = ghex_print_run_dialog(pji); + + /* Cancel clicked */ + if (cancel) { + ghex_print_job_info_destroy(pji); + return; + } + + ghex_print_job_execute(pji); + + if (pji->preview) + ghex_print_preview_real(pji); + else + gnome_print_master_print(pji->master); + + ghex_print_job_info_destroy(pji); +} + +/** + * ghex_print_run_dialog + * @pji: Pointer to a GHexPrintJobInfo object. + * + * Return value: TRUE if cancel was clicked, FALSE otherwise. + * + * Runs the GHex print dialog. + **/ +static gboolean +ghex_print_run_dialog(GHexPrintJobInfo *pji) +{ + GnomeDialog *dialog; + + dialog = (GnomeDialog *) gnome_print_dialog_new( + (const char *) _("Print Hex Document"), + GNOME_PRINT_DIALOG_RANGE); + + gnome_print_dialog_construct_range_page((GnomePrintDialog *)dialog, + GNOME_PRINT_RANGE_ALL | GNOME_PRINT_RANGE_RANGE, + 1, pji->pages, "A", _("Pages")); + + switch(gnome_dialog_run(GNOME_DIALOG(dialog))) { + case GNOME_PRINT_PRINT: + break; + case GNOME_PRINT_PREVIEW: + pji->preview = TRUE; + break; + case -1: + return TRUE; + default: + gnome_dialog_close(GNOME_DIALOG(dialog)); + return TRUE; + }; + + pji->printer = gnome_print_dialog_get_printer( + GNOME_PRINT_DIALOG(dialog)); + + if (pji->printer && !pji->preview) + gnome_print_master_set_printer(pji->master, pji->printer); + + pji->range = gnome_print_dialog_get_range_page( + GNOME_PRINT_DIALOG(dialog), + &pji->page_first, &pji->page_last); + + gnome_dialog_close(GNOME_DIALOG(dialog)); + return FALSE; +} + +/** + * ghex_print_preview_real: + * @pji: Pointer to a GHexPrintJobInfo object. + * + * Previews the print job. + **/ +static void +ghex_print_preview_real(GHexPrintJobInfo *pji) +{ + GnomePrintMasterPreview *preview; + gchar *title; + + title = g_strdup_printf(_("GHex (%s): Print Preview"), + pji->doc->file_name); + preview = gnome_print_master_preview_new(pji->master, title); + g_free(title); + + gtk_widget_show(GTK_WIDGET(preview)); +} +