diff --git a/src/dialogs/print/begin.c b/src/dialogs/print/begin.c index 0e21498..29d4073 100644 --- a/src/dialogs/print/begin.c +++ b/src/dialogs/print/begin.c @@ -49,10 +49,9 @@ ); // Set font size based on text and context. - cairo_font_extents_t extents; double width = gtk_print_context_get_width(context); - double cols = (double) operation->text.width; + double cols = (double) operation->contents.width; double current = width / cols; double valid = current; @@ -68,7 +67,27 @@ trace("Font size: %d",(int) valid); cairo_set_font_size(cr,valid); - // Set view size + // Store font data. + operation->font.info.scaled = cairo_get_scaled_font(cr); + cairo_scaled_font_reference(operation->font.info.scaled); + cairo_scaled_font_extents(operation->font.info.scaled,&extents); + + operation->font.info.height = extents.height; + operation->font.info.descent = extents.descent; + operation->font.info.width = extents.max_x_advance; + + // Center text on page + operation->font.info.left = (gtk_print_context_get_width(context)-operation->font.info.width)/2; + if(operation->font.info.left < 2) + operation->font.info.left = 2; + + // Setup page size + operation->lpp = (gtk_print_context_get_height(context) / (extents.height + extents.descent)); + operation->pages = (operation->contents.height / operation->lpp)+1; + + trace("%d lines per page, %d pages to print",operation->lpp,operation->pages); + + gtk_print_operation_set_n_pages(prt,operation->pages); } diff --git a/src/dialogs/print/print.c b/src/dialogs/print/print.c index 290a0ba..6cb8a80 100644 --- a/src/dialogs/print/print.c +++ b/src/dialogs/print/print.c @@ -28,6 +28,7 @@ */ #include "private.h" + #include #include "../../v3270/private.h" // Required for v3270 signal. #include #include @@ -117,7 +118,7 @@ return GTK_WIDGET(grid); } - static void custom_widget_apply(GtkPrintOperation *prt, GtkWidget *widget) + static void custom_widget_apply(GtkPrintOperation *prt, GtkWidget G_GNUC_UNUSED(*widget)) { V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(prt); @@ -135,6 +136,12 @@ V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(object); + if(operation->contents.text) + g_strfreev(operation->contents.text); + + if(operation->font.info.scaled) + cairo_scaled_font_destroy(operation->font.info.scaled); + g_free(operation->font.name); } @@ -168,8 +175,7 @@ widget->mode = LIB3270_PRINT_ALL; widget->show_selection = FALSE; widget->font.name = g_strdup(v3270_default_font); - - widget->text.width = 80; + widget->contents.width = 80; v3270_set_mono_color_table(widget->colors,"#000000","#FFFFFF"); @@ -185,6 +191,8 @@ V3270PrintOperation * v3270_print_operation_new(GtkWidget *widget, LIB3270_PRINT operation->widget = GTK_V3270(widget); operation->session = v3270_get_session(widget); + V3270PrintOperation_set_mode(operation, mode); + return operation; } @@ -214,3 +222,72 @@ V3270PrintOperation * v3270_print_operation_new(GtkWidget *widget, LIB3270_PRINT { v3270_print(widget,LIB3270_PRINT_COPY); } + + void V3270PrintOperation_set_mode(V3270PrintOperation * operation, LIB3270_PRINT_MODE mode) + { + operation->mode = mode; + + // Text rectangle (in characters). + switch(mode) + { + case LIB3270_PRINT_ALL: + operation->contents.height = lib3270_get_height(operation->session); + operation->contents.width = lib3270_get_width(operation->session); + break; + + case LIB3270_PRINT_SELECTED: + { + int row, col; + + GdkRectangle rect; + memset(&rect,0,sizeof(rect)); + rect.x = lib3270_get_width(operation->session); + rect.y = lib3270_get_height(operation->session); + + int baddr = 0; + for(row = 0; row < lib3270_get_height(operation->session); row++) + { + for(col = 0; col < lib3270_get_width(operation->session); col++) + { + if(lib3270_is_selected(operation->session,baddr)) + { + rect.x = MIN(rect.x,col); + rect.width = MAX(rect.width,col); + + rect.y = MIN(rect.y,row); + rect.height = MAX(rect.height,row); + } + } + } + + operation->contents.height = rect.height; + operation->contents.width = rect.width; + + } + break; + + case LIB3270_PRINT_COPY: + { + lib3270_autoptr(char) text = v3270_get_copy(GTK_WIDGET(operation->widget)); + if(text) + { + size_t r; + + operation->contents.text = g_strsplit(text,"\n",-1); + operation->contents.height = g_strv_length(operation->contents.text); + operation->contents.width = 0; + + for(r=0;r < operation->contents.height;r++) + { + operation->contents.width = MAX(operation->contents.width,strlen(operation->contents.text[r])); + } + + } + } + break; + + } + + debug("%s: width=%u height=%u",__FUNCTION__,(unsigned int) operation->contents.width, (unsigned int) operation->contents.height); + + } diff --git a/src/dialogs/print/private.h b/src/dialogs/print/private.h index 8440a61..bc6b55c 100644 --- a/src/dialogs/print/private.h +++ b/src/dialogs/print/private.h @@ -48,12 +48,15 @@ v3270 * widget; H3270 * session; + size_t lpp; ///< @brief Lines per page (in rows). + size_t pages; ///< @brief Number of pages. + struct { - size_t width; ///< @brief Maximun text width (in characters) - size_t rows; ///< @brief Number of text rows. - size_t pages; ///< @brief Number of pages. - } text; + size_t width; ///< @brief Width of the contents (in columns); + size_t height; ///< @brief Height of the contents (in rows); + gchar **text; ///< @brief Text contents; + } contents; struct { diff --git a/src/include/v3270/print.h b/src/include/v3270/print.h index 2377a0c..54512e4 100644 --- a/src/include/v3270/print.h +++ b/src/include/v3270/print.h @@ -52,8 +52,11 @@ /*--[ Prototipes ]-----------------------------------------------------------------------------------*/ LIB3270_EXPORT V3270PrintOperation * v3270_print_operation_new(GtkWidget *widget, LIB3270_PRINT_MODE mode); + LIB3270_EXPORT void V3270PrintOperation_set_mode(V3270PrintOperation * operation, LIB3270_PRINT_MODE mode); + LIB3270_EXPORT GtkWidget * v3270_font_selection_new(const gchar *fontname); + LIB3270_EXPORT GType V3270PrintOperation_get_type(void); G_END_DECLS diff --git a/src/testprogram/testprogram.c b/src/testprogram/testprogram.c index adcfa6b..0a15f68 100644 --- a/src/testprogram/testprogram.c +++ b/src/testprogram/testprogram.c @@ -201,6 +201,7 @@ static void activate(GtkApplication* app, G_GNUC_UNUSED gpointer user_data) { GtkWidget *grid = gtk_grid_new(); GtkWidget *color = v3270_color_scheme_new(); GtkWidget *print = gtk_button_new_with_label("Print"); + gtk_widget_set_focus_on_click(print,FALSE); g_signal_connect(G_OBJECT(print),"clicked",G_CALLBACK(print_clicked),terminal); -- libgit2 0.21.2