Commit 649c54ea5388bca7a00984535fc2467d223d07fd

Authored by Perry Werneck
1 parent 67b9abff
Exists in master and in 1 other branch develop

Rewriting print dialog to use the new selection format.

src/dialogs/print/begin.c
@@ -33,8 +33,8 @@ @@ -33,8 +33,8 @@
33 33
34 void V3270PrintOperation_begin_print(GtkPrintOperation *prt, GtkPrintContext *context) 34 void V3270PrintOperation_begin_print(GtkPrintOperation *prt, GtkPrintContext *context)
35 { 35 {
36 - cairo_t * cr = gtk_print_context_get_cairo_context(context);  
37 V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(prt); 36 V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(prt);
  37 + cairo_t * cr = gtk_print_context_get_cairo_context(context);
38 38
39 trace("%s",__FUNCTION__); 39 trace("%s",__FUNCTION__);
40 40
@@ -78,9 +78,6 @@ @@ -78,9 +78,6 @@
78 78
79 operation->font.info.width++; 79 operation->font.info.width++;
80 80
81 - // Center text on page  
82 - // operation->font.info.left = 2;  
83 -  
84 operation->font.info.left = (gtk_print_context_get_width(context)- (operation->font.info.width * operation->contents.width))/2; 81 operation->font.info.left = (gtk_print_context_get_width(context)- (operation->font.info.width * operation->contents.width))/2;
85 if(operation->font.info.left < 2) 82 if(operation->font.info.left < 2)
86 operation->font.info.left = 2; 83 operation->font.info.left = 2;
src/dialogs/print/convenience.c 0 → 100644
@@ -0,0 +1,144 @@ @@ -0,0 +1,144 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 + #include "private.h"
  31 + #include <sys/param.h>
  32 + #include <terminal.h>
  33 + #include <lib3270/selection.h>
  34 +
  35 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  36 +
  37 + int v3270_print(GtkWidget *widget, LIB3270_CONTENT_OPTION mode, GError **error)
  38 + {
  39 + int rc;
  40 +
  41 + if(!(widget && GTK_IS_V3270(widget)))
  42 + {
  43 + return errno = EINVAL;
  44 + }
  45 +
  46 + /*
  47 + if(!v3270_is_connected(widget))
  48 + {
  49 + if(error)
  50 + {
  51 + *error = g_error_new(g_quark_from_static_string(PACKAGE_NAME),ENOTCONN,"%s",strerror(ENOTCONN));
  52 + }
  53 + else
  54 + {
  55 + GtkWidget *popup = gtk_message_dialog_new_with_markup(
  56 + GTK_WINDOW(gtk_widget_get_toplevel(widget)),
  57 + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
  58 + GTK_MESSAGE_ERROR,GTK_BUTTONS_CLOSE,
  59 + _("Can't print data")
  60 + );
  61 +
  62 + gtk_window_set_title(GTK_WINDOW(popup),_("Operation has failed"));
  63 +
  64 + gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(popup),"%s",strerror(ENOTCONN));
  65 +
  66 + gtk_dialog_run(GTK_DIALOG(popup));
  67 + gtk_widget_destroy(popup);
  68 + }
  69 +
  70 + return errno = ENOTCONN;
  71 + }
  72 + */
  73 +
  74 + lib3270_trace_event(v3270_get_session(widget),"print action activated (type=%d)",(int) mode);
  75 +
  76 + // Print operation.
  77 + V3270PrintOperation * operation = v3270_print_operation_new(widget, mode);
  78 +
  79 + if(error)
  80 + {
  81 + gtk_print_operation_run(
  82 + GTK_PRINT_OPERATION(operation),
  83 + GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
  84 + GTK_WINDOW(gtk_widget_get_toplevel(widget)),
  85 + error
  86 + );
  87 +
  88 + rc = (*error == NULL ? 0 : -1);
  89 +
  90 + }
  91 + else
  92 + {
  93 + GError *err = NULL;
  94 +
  95 + gtk_print_operation_run(
  96 + GTK_PRINT_OPERATION(operation),
  97 + GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
  98 + GTK_WINDOW(gtk_widget_get_toplevel(widget)),
  99 + &err
  100 + );
  101 +
  102 + if(err)
  103 + {
  104 + GtkWidget *popup = gtk_message_dialog_new_with_markup(
  105 + GTK_WINDOW(gtk_widget_get_toplevel(widget)),
  106 + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
  107 + GTK_MESSAGE_ERROR,GTK_BUTTONS_CLOSE,
  108 + _("Can't print data")
  109 + );
  110 +
  111 + gtk_window_set_title(GTK_WINDOW(popup),_("Operation has failed"));
  112 +
  113 + gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(popup),"%s",strerror(ENOTCONN));
  114 +
  115 + gtk_dialog_run(GTK_DIALOG(popup));
  116 + gtk_widget_destroy(popup);
  117 +
  118 + g_error_free(err);
  119 +
  120 + rc = -1;
  121 + }
  122 + }
  123 +
  124 + g_object_unref(operation);
  125 +
  126 + return rc;
  127 +
  128 + }
  129 +
  130 + int v3270_print_all(GtkWidget *widget, GError **error)
  131 + {
  132 + return v3270_print(widget,LIB3270_CONTENT_ALL,error);
  133 + }
  134 +
  135 + int v3270_print_selected(GtkWidget *widget, GError **error)
  136 + {
  137 + return v3270_print(widget,LIB3270_CONTENT_SELECTED,error);
  138 + }
  139 +
  140 + int v3270_print_copy(GtkWidget *widget, GError **error)
  141 + {
  142 + return v3270_print(widget,LIB3270_CONTENT_COPY,error);
  143 + }
  144 +
src/dialogs/print/custom.c 0 → 100644
@@ -0,0 +1,144 @@ @@ -0,0 +1,144 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 + #include "private.h"
  31 + #include <sys/param.h>
  32 + #include <terminal.h>
  33 + #include <v3270/colorscheme.h>
  34 + #include <lib3270/selection.h>
  35 +
  36 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  37 +
  38 +#ifndef _WIN32
  39 + static void color_scheme_changed(GtkWidget G_GNUC_UNUSED(*widget), const GdkRGBA *colors, V3270PrintOperation *operation) {
  40 +
  41 + debug("%s=%p",__FUNCTION__,colors);
  42 +
  43 + int f;
  44 + for(f=0;f<V3270_COLOR_COUNT;f++)
  45 + operation->colors[f] = colors[f];
  46 +
  47 + }
  48 +
  49 + static void font_name_changed(GtkComboBox *widget, V3270PrintOperation *operation)
  50 + {
  51 + GValue value = { 0, };
  52 + GtkTreeIter iter;
  53 +
  54 + if(!gtk_combo_box_get_active_iter(widget,&iter))
  55 + return;
  56 +
  57 + gtk_tree_model_get_value(gtk_combo_box_get_model(widget),&iter,0,&value);
  58 +
  59 + g_free(operation->font.name);
  60 + operation->font.name = g_value_dup_string(&value);
  61 +
  62 + debug("%s=%s",__FUNCTION__,operation->font.name);
  63 + }
  64 +
  65 + static void toggle_show_selection(GtkToggleButton *widget, V3270PrintOperation *operation)
  66 + {
  67 + operation->show_selection = gtk_toggle_button_get_active(widget);
  68 + }
  69 +
  70 + GtkWidget * V3270PrintOperation_custom_widget_new(GtkPrintOperation *prt)
  71 + {
  72 + static const gchar * text[] =
  73 + {
  74 + N_( "_Font:" ),
  75 + N_( "C_olor scheme:" )
  76 + };
  77 +
  78 + size_t f;
  79 +
  80 + V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(prt);
  81 +
  82 + if(operation->widget)
  83 + g_signal_emit(operation->widget, v3270_widget_signal[V3270_SIGNAL_PRINT_SETUP], 0, prt);
  84 +
  85 + // Create dialog
  86 +
  87 + GtkWidget * frame = gtk_frame_new("");
  88 + GtkGrid * grid = GTK_GRID(gtk_grid_new());
  89 + GtkWidget * font = v3270_font_selection_new(operation->font.name);
  90 + GtkWidget * color = v3270_color_scheme_new();
  91 + GtkWidget * selected = gtk_check_button_new_with_label( _("Print selection box") );
  92 +
  93 + // The print dialog doesn't follow the guidelines from https://developer.gnome.org/hig/stable/visual-layout.html.en )-:
  94 +
  95 + gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_NONE);
  96 +
  97 + GtkWidget *label = gtk_label_new(NULL);
  98 +
  99 + gtk_label_set_markup(GTK_LABEL(label),_("<b>Text options</b>"));
  100 + gtk_frame_set_label_widget(GTK_FRAME(frame),label);
  101 +
  102 + gtk_container_set_border_width(GTK_CONTAINER(frame),12);
  103 +
  104 + gtk_container_set_border_width(GTK_CONTAINER(grid),6);
  105 +
  106 + g_object_set(G_OBJECT(grid),"margin-start",8,NULL);
  107 +
  108 + gtk_grid_set_row_spacing(grid,6);
  109 + gtk_grid_set_column_spacing(grid,12);
  110 +
  111 + v3270_color_scheme_set_rgba(color,operation->colors);
  112 + g_signal_connect(G_OBJECT(color),"update-colors",G_CALLBACK(color_scheme_changed),operation);
  113 + g_signal_connect(G_OBJECT(font),"changed",G_CALLBACK(font_name_changed),operation);
  114 + g_signal_connect(G_OBJECT(selected),"toggled",G_CALLBACK(toggle_show_selection),operation);
  115 +
  116 + for(f=0;f<G_N_ELEMENTS(text);f++)
  117 + {
  118 + GtkWidget *label = gtk_label_new_with_mnemonic(gettext(text[f]));
  119 + gtk_widget_set_halign(label,GTK_ALIGN_START);
  120 + gtk_grid_attach(grid,label,0,f,1,1);
  121 + }
  122 +
  123 + gtk_grid_attach(grid,font,1,0,1,1);
  124 + gtk_grid_attach(grid,color,1,1,1,1);
  125 + gtk_grid_attach(grid,selected,1,2,1,1);
  126 +
  127 + gtk_container_add(GTK_CONTAINER(frame),GTK_WIDGET(grid));
  128 +
  129 + gtk_widget_show_all(GTK_WIDGET(frame));
  130 + return frame;
  131 + }
  132 +
  133 + void V3270PrintOperation_custom_widget_apply(GtkPrintOperation *prt, GtkWidget G_GNUC_UNUSED(*widget))
  134 + {
  135 + V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(prt);
  136 +
  137 + debug("%s",__FUNCTION__);
  138 +
  139 + if(operation->widget)
  140 + g_signal_emit(operation->widget, v3270_widget_signal[V3270_SIGNAL_PRINT_APPLY], 0, prt);
  141 +
  142 + }
  143 +
  144 +#endif // _WIN32
src/dialogs/print/draw.c
@@ -29,29 +29,60 @@ @@ -29,29 +29,60 @@
29 29
30 #include "private.h" 30 #include "private.h"
31 #include <string.h> 31 #include <string.h>
  32 + #include <lib3270/selection.h>
32 33
33 /*--[ Implement ]------------------------------------------------------------------------------------*/ 34 /*--[ Implement ]------------------------------------------------------------------------------------*/
34 35
  36 + static gint get_row(const V3270PrintOperation * operation, gint row, const lib3270_selection **block)
  37 + {
  38 + const GList * element = NULL;
  39 + const lib3270_selection * selection = NULL;
  40 +
  41 + debug("Searching for row %u", row);
  42 +
  43 + for(element = operation->contents.selection; element; element = element->next)
  44 + {
  45 + selection = (const lib3270_selection *) element->data;
  46 +
  47 + if(((unsigned int) row) < selection->bounds.height)
  48 + {
  49 + // Found block.
  50 + debug("Found row %u",row);
  51 + *block = selection;
  52 + return row;
  53 + }
  54 +
  55 + debug("Skipping block with %u rows",selection->bounds.height);
  56 + row -= (int) selection->bounds.height;
  57 + }
  58 +
  59 + return -1;
  60 + }
  61 +
35 void V3270PrintOperation_draw_page(GtkPrintOperation *prt, GtkPrintContext *context, gint page) 62 void V3270PrintOperation_draw_page(GtkPrintOperation *prt, GtkPrintContext *context, gint page)
36 { 63 {
37 - cairo_t * cr = gtk_print_context_get_cairo_context(context);  
38 V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(prt); 64 V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(prt);
  65 + cairo_t * cr = gtk_print_context_get_cairo_context(context);
39 66
40 - size_t from = page * operation->lpp;  
41 -  
42 - if(from > operation->contents.height) 67 + // Convert page number in rows.
  68 + gint row = page * operation->lpp;
  69 + if(((unsigned int) row) > operation->contents.height)
43 return; 70 return;
44 71
45 - // Create a rectangle with the size of 1 character. 72 + debug("%s: page=%d skip_rows=%d",__FUNCTION__,page,row);
  73 +
  74 + // Get block
  75 + const lib3270_selection * selection = NULL;
  76 + row = get_row(operation,row,&selection);
  77 +
  78 + // Setup a rectangle with the size of 1 character.
46 GdkRectangle rect; 79 GdkRectangle rect;
47 memset(&rect,0,sizeof(rect)); 80 memset(&rect,0,sizeof(rect));
48 rect.y = 2; 81 rect.y = 2;
49 rect.height = operation->font.info.height + operation->font.info.descent; 82 rect.height = operation->font.info.height + operation->font.info.descent;
50 rect.width = operation->font.info.width; 83 rect.width = operation->font.info.width;
51 84
52 - // Draw "operation->lpp" lines starting from "from"  
53 -  
54 - // Clear contents. 85 + // Clear drawing area.
55 gdk_cairo_set_source_rgba(cr,operation->colors + V3270_COLOR_BACKGROUND); 86 gdk_cairo_set_source_rgba(cr,operation->colors + V3270_COLOR_BACKGROUND);
56 cairo_rectangle( 87 cairo_rectangle(
57 cr, 88 cr,
@@ -63,6 +94,70 @@ @@ -63,6 +94,70 @@
63 cairo_fill(cr); 94 cairo_fill(cr);
64 cairo_stroke(cr); 95 cairo_stroke(cr);
65 96
  97 + // Draw LPP lines
  98 + size_t drawing;
  99 +
  100 + for(drawing = 0; drawing < operation->lpp; drawing++)
  101 + {
  102 + size_t pos = (row * selection->bounds.width);
  103 + debug("Drawing: %u row=%u selection=%p pos=%u", (unsigned int) drawing, row, selection, (unsigned int) pos);
  104 +
  105 + if(((unsigned int) ++row) > selection->bounds.height)
  106 + {
  107 + debug("Searching for next block (first line=%u)",(unsigned int) (page * operation->lpp) + drawing);
  108 + row = get_row(operation,(page * operation->lpp) + drawing, &selection);
  109 + if(row < 0)
  110 + {
  111 + break;
  112 + }
  113 + }
  114 +
  115 + // Draw columns
  116 + size_t col;
  117 + rect.x = operation->font.info.left;
  118 +
  119 + for(col = 0; col < selection->bounds.width;col++)
  120 + {
  121 + if(selection->contents[pos].chr)
  122 + {
  123 + // Draw character.
  124 + unsigned short attr = selection->contents[pos].attribute.visual;
  125 +
  126 + if(!operation->show_selection)
  127 + attr &= ~LIB3270_ATTR_SELECTED;
  128 +
  129 + v3270_draw_element(
  130 + cr,
  131 + selection->contents[pos].chr,
  132 + attr,
  133 + operation->session,
  134 + &operation->font.info,
  135 + &rect,
  136 + operation->colors
  137 + );
  138 +
  139 + }
  140 + pos++;
  141 +
  142 + // Advance to the next char
  143 + rect.x += (rect.width-1);
  144 +
  145 + }
  146 +
  147 + // Advance to the next row
  148 + rect.y += (rect.height-1);
  149 +
  150 + }
  151 +
  152 + /*
  153 +
  154 +
  155 + // Create a rectangle with the size of 1 character.
  156 +
  157 + // Draw "operation->lpp" lines starting from "from"
  158 +
  159 + // Clear contents.
  160 +
66 // draw "lpp" lines starting from "from" 161 // draw "lpp" lines starting from "from"
67 size_t r; 162 size_t r;
68 163
@@ -107,5 +202,6 @@ @@ -107,5 +202,6 @@
107 rect.y += (rect.height-1); 202 rect.y += (rect.height-1);
108 203
109 } 204 }
  205 + */
110 206
111 } 207 }
src/dialogs/print/print.c
@@ -30,7 +30,6 @@ @@ -30,7 +30,6 @@
30 #include "private.h" 30 #include "private.h"
31 #include <sys/param.h> 31 #include <sys/param.h>
32 #include <terminal.h> 32 #include <terminal.h>
33 - #include <v3270/colorscheme.h>  
34 #include <lib3270/selection.h> 33 #include <lib3270/selection.h>
35 34
36 G_DEFINE_TYPE(V3270PrintOperation, V3270PrintOperation, GTK_TYPE_PRINT_OPERATION); 35 G_DEFINE_TYPE(V3270PrintOperation, V3270PrintOperation, GTK_TYPE_PRINT_OPERATION);
@@ -48,115 +47,6 @@ @@ -48,115 +47,6 @@
48 47
49 } 48 }
50 49
51 -#ifndef _WIN32  
52 - static void color_scheme_changed(GtkWidget G_GNUC_UNUSED(*widget), const GdkRGBA *colors, V3270PrintOperation *operation) {  
53 -  
54 - debug("%s=%p",__FUNCTION__,colors);  
55 -  
56 - int f;  
57 - for(f=0;f<V3270_COLOR_COUNT;f++)  
58 - operation->colors[f] = colors[f];  
59 -  
60 - }  
61 -  
62 - static void font_name_changed(GtkComboBox *widget, V3270PrintOperation *operation)  
63 - {  
64 - GValue value = { 0, };  
65 - GtkTreeIter iter;  
66 -  
67 - if(!gtk_combo_box_get_active_iter(widget,&iter))  
68 - return;  
69 -  
70 - gtk_tree_model_get_value(gtk_combo_box_get_model(widget),&iter,0,&value);  
71 -  
72 - g_free(operation->font.name);  
73 - operation->font.name = g_value_dup_string(&value);  
74 -  
75 - debug("%s=%s",__FUNCTION__,operation->font.name);  
76 - }  
77 -  
78 - static void toggle_show_selection(GtkToggleButton *widget, V3270PrintOperation *operation)  
79 - {  
80 - operation->show_selection = gtk_toggle_button_get_active(widget);  
81 - }  
82 -  
83 - static GtkWidget * create_custom_widget(GtkPrintOperation *prt)  
84 - {  
85 - static const gchar * text[] =  
86 - {  
87 - N_( "_Font:" ),  
88 - N_( "C_olor scheme:" )  
89 - };  
90 -  
91 - size_t f;  
92 -  
93 - V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(prt);  
94 -  
95 - if(operation->widget)  
96 - g_signal_emit(operation->widget, v3270_widget_signal[V3270_SIGNAL_PRINT_SETUP], 0, prt);  
97 -  
98 - // Create dialog  
99 -  
100 - GtkWidget * frame = gtk_frame_new("");  
101 - GtkGrid * grid = GTK_GRID(gtk_grid_new());  
102 - GtkWidget * font = v3270_font_selection_new(operation->font.name);  
103 - GtkWidget * color = v3270_color_scheme_new();  
104 - GtkWidget * selected = gtk_check_button_new_with_label( _("Print selection box") );  
105 -  
106 - // The print dialog doesn't follow the guidelines from https://developer.gnome.org/hig/stable/visual-layout.html.en )-:  
107 -  
108 - gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_NONE);  
109 -  
110 - GtkWidget *label = gtk_label_new(NULL);  
111 -  
112 - gtk_label_set_markup(GTK_LABEL(label),_("<b>Text options</b>"));  
113 - gtk_frame_set_label_widget(GTK_FRAME(frame),label);  
114 -  
115 - gtk_container_set_border_width(GTK_CONTAINER(frame),12);  
116 -  
117 - gtk_container_set_border_width(GTK_CONTAINER(grid),6);  
118 -  
119 - g_object_set(G_OBJECT(grid),"margin-start",8,NULL);  
120 -  
121 - gtk_grid_set_row_spacing(grid,6);  
122 - gtk_grid_set_column_spacing(grid,12);  
123 -  
124 - v3270_color_scheme_set_rgba(color,operation->colors);  
125 - g_signal_connect(G_OBJECT(color),"update-colors",G_CALLBACK(color_scheme_changed),operation);  
126 - g_signal_connect(G_OBJECT(font),"changed",G_CALLBACK(font_name_changed),operation);  
127 - g_signal_connect(G_OBJECT(selected),"toggled",G_CALLBACK(toggle_show_selection),operation);  
128 -  
129 -  
130 - for(f=0;f<G_N_ELEMENTS(text);f++)  
131 - {  
132 - GtkWidget *label = gtk_label_new_with_mnemonic(gettext(text[f]));  
133 - gtk_widget_set_halign(label,GTK_ALIGN_START);  
134 - gtk_grid_attach(grid,label,0,f,1,1);  
135 - }  
136 -  
137 - gtk_grid_attach(grid,font,1,0,1,1);  
138 - gtk_grid_attach(grid,color,1,1,1,1);  
139 - gtk_grid_attach(grid,selected,1,2,1,1);  
140 -  
141 - gtk_container_add(GTK_CONTAINER(frame),GTK_WIDGET(grid));  
142 -  
143 - gtk_widget_show_all(GTK_WIDGET(frame));  
144 - return frame;  
145 - }  
146 -  
147 - static void custom_widget_apply(GtkPrintOperation *prt, GtkWidget G_GNUC_UNUSED(*widget))  
148 - {  
149 - V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(prt);  
150 -  
151 - debug("%s",__FUNCTION__);  
152 -  
153 - if(operation->widget)  
154 - g_signal_emit(operation->widget, v3270_widget_signal[V3270_SIGNAL_PRINT_APPLY], 0, prt);  
155 -  
156 - }  
157 -  
158 -#endif // _WIN32  
159 -  
160 static void dispose(GObject *object) 50 static void dispose(GObject *object)
161 { 51 {
162 debug("%s",__FUNCTION__); 52 debug("%s",__FUNCTION__);
@@ -168,17 +58,12 @@ @@ -168,17 +58,12 @@
168 58
169 g_free(operation->font.name); 59 g_free(operation->font.name);
170 60
171 - if(operation->contents.text) 61 + if(operation->contents.dynamic)
172 { 62 {
173 - size_t row;  
174 -  
175 - for(row = 0; operation->contents.text[row]; row++)  
176 - {  
177 - g_free(operation->contents.text[row]);  
178 - }  
179 - g_free(operation->contents.text);  
180 - 63 + g_list_free_full(operation->contents.dynamic,(GDestroyNotify) lib3270_free);
  64 + operation->contents.dynamic = NULL;
181 } 65 }
  66 + operation->contents.selection = NULL;
182 67
183 G_OBJECT_CLASS(V3270PrintOperation_parent_class)->dispose(object); 68 G_OBJECT_CLASS(V3270PrintOperation_parent_class)->dispose(object);
184 69
@@ -194,8 +79,8 @@ @@ -194,8 +79,8 @@
194 operation->draw_page = V3270PrintOperation_draw_page; 79 operation->draw_page = V3270PrintOperation_draw_page;
195 80
196 #ifndef _WIN32 81 #ifndef _WIN32
197 - operation->create_custom_widget = create_custom_widget;  
198 - operation->custom_widget_apply = custom_widget_apply; 82 + operation->create_custom_widget = V3270PrintOperation_custom_widget_new;
  83 + operation->custom_widget_apply = V3270PrintOperation_custom_widget_apply;
199 #endif // _WIN32 84 #endif // _WIN32
200 85
201 } 86 }
@@ -208,13 +93,10 @@ @@ -208,13 +93,10 @@
208 gtk_print_operation_set_print_settings(GTK_PRINT_OPERATION(widget),gtk_print_settings_new()); 93 gtk_print_operation_set_print_settings(GTK_PRINT_OPERATION(widget),gtk_print_settings_new());
209 gtk_print_operation_set_default_page_setup(GTK_PRINT_OPERATION(widget),gtk_page_setup_new()); 94 gtk_print_operation_set_default_page_setup(GTK_PRINT_OPERATION(widget),gtk_page_setup_new());
210 95
211 -  
212 // Setup defaults 96 // Setup defaults
213 widget->mode = LIB3270_CONTENT_ALL; 97 widget->mode = LIB3270_CONTENT_ALL;
214 widget->show_selection = FALSE; 98 widget->show_selection = FALSE;
215 widget->font.name = NULL; // g_strdup(v3270_default_font); 99 widget->font.name = NULL; // g_strdup(v3270_default_font);
216 - widget->contents.width = 80;  
217 -  
218 v3270_set_mono_color_table(widget->colors,"#000000","#FFFFFF"); 100 v3270_set_mono_color_table(widget->colors,"#000000","#FFFFFF");
219 101
220 } 102 }
@@ -225,165 +107,46 @@ V3270PrintOperation * v3270_print_operation_new(GtkWidget *widget, LIB3270_CONTE @@ -225,165 +107,46 @@ V3270PrintOperation * v3270_print_operation_new(GtkWidget *widget, LIB3270_CONTE
225 107
226 V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(g_object_new(GTK_TYPE_V3270_PRINT_OPERATION, NULL)); 108 V3270PrintOperation * operation = GTK_V3270_PRINT_OPERATION(g_object_new(GTK_TYPE_V3270_PRINT_OPERATION, NULL));
227 109
228 - operation->mode = mode;  
229 - operation->widget = GTK_V3270(widget);  
230 - operation->session = v3270_get_session(widget);  
231 - operation->font.name = g_strdup(v3270_get_font_family(widget));  
232 -  
233 - V3270PrintOperation_set_text_by_mode(operation, mode);  
234 -  
235 - return operation;  
236 -}  
237 -  
238 -/*--[ Convenience ]----------------------------------------------------------------------------------*/  
239 -  
240 - int v3270_print(GtkWidget *widget, LIB3270_CONTENT_OPTION mode, GError **error)  
241 - {  
242 - if(*error)  
243 - {  
244 - return -1;  
245 - }  
246 -  
247 - lib3270_trace_event(v3270_get_session(widget),"print action activated (type=%d)",(int) mode);  
248 -  
249 - if(v3270_is_connected(widget))  
250 - {  
251 - V3270PrintOperation * operation = v3270_print_operation_new(widget, mode);  
252 - gtk_print_operation_run(GTK_PRINT_OPERATION(operation),GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,GTK_WINDOW(gtk_widget_get_toplevel(widget)),error);  
253 - g_object_unref(operation);  
254 - return (*error != NULL);  
255 - }  
256 -  
257 - *error = g_error_new(g_quark_from_static_string(PACKAGE_NAME),ENOTCONN,"%s",strerror(ENOTCONN));  
258 -  
259 - return -1; 110 + operation->mode = mode;
  111 + operation->widget = GTK_V3270(widget);
  112 + operation->session = v3270_get_session(widget);
  113 + operation->font.name = g_strdup(v3270_get_font_family(widget));
260 114
261 - }  
262 -  
263 - int v3270_print_all(GtkWidget *widget, GError **error)  
264 - {  
265 - return v3270_print(widget,LIB3270_CONTENT_ALL,error);  
266 - }  
267 -  
268 - int v3270_print_selected(GtkWidget *widget, GError **error)  
269 - {  
270 - return v3270_print(widget,LIB3270_CONTENT_SELECTED,error);  
271 - }  
272 -  
273 - int v3270_print_copy(GtkWidget *widget, GError **error)  
274 - {  
275 - return v3270_print(widget,LIB3270_CONTENT_COPY,error);  
276 - }  
277 -  
278 - void V3270PrintOperation_set_text_by_mode(V3270PrintOperation * operation, LIB3270_CONTENT_OPTION mode)  
279 - {  
280 - operation->mode = mode;  
281 -  
282 - switch(mode) 115 + // Get contents.
  116 + switch(operation->mode)
283 { 117 {
284 case LIB3270_CONTENT_ALL: 118 case LIB3270_CONTENT_ALL:
285 - {  
286 - size_t row, col;  
287 - int baddr = 0;  
288 - column * text;  
289 -  
290 - operation->contents.height = lib3270_get_height(operation->session);  
291 - operation->contents.width = lib3270_get_width(operation->session);  
292 -  
293 - operation->contents.text = g_new0(column *, operation->contents.height+1);  
294 -  
295 - for(row = 0; row < operation->contents.height; row++)  
296 - {  
297 - operation->contents.text[row] = text = g_new0(column, operation->contents.width);  
298 - for(col = 0; col < operation->contents.width; col++)  
299 - {  
300 - lib3270_get_element(operation->session,baddr++,&text[col].c,&text[col].attr);  
301 - }  
302 - }  
303 -  
304 - } 119 + debug("%s","LIB3270_CONTENT_ALL");
  120 + operation->contents.dynamic = g_new0(GList,1);
  121 + operation->contents.dynamic->data = (gpointer) lib3270_get_selection(operation->session,0,1);
  122 + operation->contents.selection = operation->contents.dynamic;
305 break; 123 break;
306 124
307 - case LIB3270_CONTENT_SELECTED:  
308 - {  
309 - unsigned int row, col;  
310 - unsigned int baddr = 0;  
311 -  
312 - GdkRectangle rect;  
313 - memset(&rect,0,sizeof(rect));  
314 - rect.x = lib3270_get_width(operation->session);  
315 - rect.y = lib3270_get_height(operation->session);  
316 -  
317 - // Get regions  
318 -  
319 - for(row = 0; row < lib3270_get_height(operation->session); row++)  
320 - {  
321 - for(col = 0; col < lib3270_get_width(operation->session); col++)  
322 - {  
323 - if(lib3270_is_selected(operation->session,baddr++))  
324 - {  
325 - rect.x = MIN( ((unsigned int) rect.x),col);  
326 - rect.width = MAX( ((unsigned int) rect.width),col);  
327 -  
328 - rect.y = MIN( ((unsigned int) rect.y),row);  
329 - rect.height = MAX( ((unsigned int) rect.height),row);  
330 - }  
331 - }  
332 - }  
333 -  
334 - operation->contents.height = rect.height - rect.y;  
335 - operation->contents.width = rect.width - rect.x;  
336 -  
337 - // Get contents  
338 - int r = 0;  
339 - column * text;  
340 -  
341 - operation->contents.text = g_new0(column *, operation->contents.height+1);  
342 -  
343 - for(row = rect.y; ((int) row) < rect.width; row++)  
344 - {  
345 - int c = 0;  
346 - operation->contents.text[r++] = text = g_new0(column, operation->contents.width);  
347 -  
348 - for(col = rect.x; ((int) col) < rect.height; col++)  
349 - {  
350 - lib3270_get_element(operation->session,lib3270_translate_to_address(operation->session,row,col),&text[c].c,&text[c].attr);  
351 - if(!(text[c].attr & LIB3270_ATTR_SELECTED))  
352 - {  
353 - text[c].c = 0;  
354 - text[c].attr = 0;  
355 - }  
356 - c++;  
357 - }  
358 -  
359 - }  
360 -  
361 - } 125 + case LIB3270_CONTENT_COPY:
  126 + debug("%s","LIB3270_CONTENT_COPY");
  127 + operation->contents.selection = v3270_get_selection_blocks(operation->widget);
362 break; 128 break;
363 129
364 - case LIB3270_CONTENT_COPY:  
365 - {  
366 - lib3270_autoptr(char) copy = v3270_get_copy(GTK_WIDGET(operation->widget));  
367 - if(copy)  
368 - {  
369 - size_t r;  
370 - gchar ** text = g_strsplit(copy,"\n",-1);  
371 - operation->contents.height = g_strv_length(text);  
372 - operation->contents.width = 0;  
373 -  
374 - for(r=0;r < operation->contents.height;r++)  
375 - {  
376 - operation->contents.width = MAX(operation->contents.width,strlen(text[r]));  
377 - }  
378 -  
379 - g_strfreev(text);  
380 -  
381 - }  
382 - } 130 + case LIB3270_CONTENT_SELECTED:
  131 + debug("%s","LIB3270_CONTENT_SELECTED");
  132 + operation->contents.dynamic = g_new0(GList,1);
  133 + operation->contents.dynamic->data = (gpointer) lib3270_get_selection(operation->session,0,0);
  134 + operation->contents.selection = operation->contents.dynamic;
383 break; 135 break;
  136 + }
384 137
  138 + // Get metrics
  139 + const GList * element;
  140 + for(element = operation->contents.selection; element; element = element->next)
  141 + {
  142 + const lib3270_selection * selection = (const lib3270_selection *) element->data;
  143 +
  144 + if(selection->bounds.width > operation->contents.width)
  145 + operation->contents.width = selection->bounds.width;
  146 +
  147 + operation->contents.height += selection->bounds.height;
385 } 148 }
386 149
387 - debug("%s: width=%u height=%u",__FUNCTION__,(unsigned int) operation->contents.width, (unsigned int) operation->contents.height); 150 + return operation;
  151 +}
388 152
389 - }  
src/dialogs/print/private.h
@@ -58,11 +58,12 @@ @@ -58,11 +58,12 @@
58 size_t pages; ///< @brief Number of pages. 58 size_t pages; ///< @brief Number of pages.
59 gboolean show_selection; ///< @brief Print selection box? 59 gboolean show_selection; ///< @brief Print selection box?
60 60
61 - struct 61 + struct
62 { 62 {
63 - size_t width; ///< @brief Width of the contents (in columns);  
64 - size_t height; ///< @brief Height of the contents (in rows);  
65 - column **text; ///< @brief Report contents. 63 + unsigned int width; ///< @brief Max line width.
  64 + unsigned int height; ///< @brief Number of lines to print.
  65 + GList * dynamic;
  66 + const GList * selection;
66 } contents; 67 } contents;
67 68
68 struct 69 struct
@@ -75,7 +76,9 @@ @@ -75,7 +76,9 @@
75 76
76 /*--[ Prototypes ]-----------------------------------------------------------------------------------*/ 77 /*--[ Prototypes ]-----------------------------------------------------------------------------------*/
77 78
78 - G_GNUC_INTERNAL void V3270PrintOperation_begin_print(GtkPrintOperation *prt, GtkPrintContext *context);  
79 - G_GNUC_INTERNAL void V3270PrintOperation_draw_page(GtkPrintOperation *prt, GtkPrintContext *context, gint page); 79 + G_GNUC_INTERNAL void V3270PrintOperation_begin_print(GtkPrintOperation *prt, GtkPrintContext *context);
  80 + G_GNUC_INTERNAL void V3270PrintOperation_draw_page(GtkPrintOperation *prt, GtkPrintContext *context, gint page);
  81 + G_GNUC_INTERNAL GtkWidget * V3270PrintOperation_custom_widget_new(GtkPrintOperation *prt);
  82 + G_GNUC_INTERNAL void V3270PrintOperation_custom_widget_apply(GtkPrintOperation *prt, GtkWidget *widget);
80 83
81 84
src/include/v3270/print.h
@@ -52,12 +52,8 @@ @@ -52,12 +52,8 @@
52 /*--[ Prototipes ]-----------------------------------------------------------------------------------*/ 52 /*--[ Prototipes ]-----------------------------------------------------------------------------------*/
53 53
54 LIB3270_EXPORT V3270PrintOperation * v3270_print_operation_new(GtkWidget *widget, LIB3270_CONTENT_OPTION mode); 54 LIB3270_EXPORT V3270PrintOperation * v3270_print_operation_new(GtkWidget *widget, LIB3270_CONTENT_OPTION mode);
55 - LIB3270_EXPORT void V3270PrintOperation_set_text_by_mode(V3270PrintOperation * operation, LIB3270_CONTENT_OPTION mode);  
56 -  
57 - LIB3270_EXPORT GtkTreeModel * v3270_font_family_model_new(GtkWidget *widget, const gchar *selected, GtkTreeIter * active);  
58 - LIB3270_EXPORT GtkWidget * v3270_font_selection_new(const gchar *fontname);  
59 -  
60 - 55 + LIB3270_EXPORT GtkTreeModel * v3270_font_family_model_new(GtkWidget *widget, const gchar *selected, GtkTreeIter * active);
  56 + LIB3270_EXPORT GtkWidget * v3270_font_selection_new(const gchar *fontname);
61 LIB3270_EXPORT GType V3270PrintOperation_get_type(void); 57 LIB3270_EXPORT GType V3270PrintOperation_get_type(void);
62 58
63 G_END_DECLS 59 G_END_DECLS
src/selection/table.c
@@ -34,7 +34,7 @@ @@ -34,7 +34,7 @@
34 /*--[ Implement ]------------------------------------------------------------------------------------*/ 34 /*--[ Implement ]------------------------------------------------------------------------------------*/
35 35
36 /// @brief Check if column has data. 36 /// @brief Check if column has data.
37 -static gboolean hasDataOnColumn(v3270 * terminal, unsigned int col, const GList *selection, gboolean all) 37 +static gboolean hasDataOnColumn(v3270 * G_GNUC_UNUSED(terminal), unsigned int col, const GList *selection, gboolean all)
38 { 38 {
39 while(selection) 39 while(selection)
40 { 40 {
@@ -118,7 +118,7 @@ gchar * v3270_get_selection_as_table(v3270 * terminal, const GList *selection, c @@ -118,7 +118,7 @@ gchar * v3270_get_selection_as_table(v3270 * terminal, const GList *selection, c
118 } 118 }
119 #endif // DEBUG 119 #endif // DEBUG
120 120
121 - GList * element = selection; 121 + const GList * element = selection;
122 unsigned int width = lib3270_get_width(terminal->host); 122 unsigned int width = lib3270_get_width(terminal->host);
123 g_autofree gchar * line = g_malloc0(width+1); 123 g_autofree gchar * line = g_malloc0(width+1);
124 GList * column; 124 GList * column;
src/terminal/callbacks.c
@@ -329,32 +329,7 @@ static void message(H3270 *session, LIB3270_NOTIFY id , const char *title, const @@ -329,32 +329,7 @@ static void message(H3270 *session, LIB3270_NOTIFY id , const char *title, const
329 329
330 static int print(H3270 *session, LIB3270_CONTENT_OPTION mode) 330 static int print(H3270 *session, LIB3270_CONTENT_OPTION mode)
331 { 331 {
332 - GtkWidget * widget = GTK_WIDGET(lib3270_get_user_data(session));  
333 - GError * error = NULL;  
334 -  
335 - v3270_print(widget, mode, &error);  
336 -  
337 - if(error)  
338 - {  
339 - GtkWidget *dialog =  
340 - gtk_message_dialog_new_with_markup(  
341 - GTK_WINDOW(gtk_widget_get_toplevel(widget)),  
342 - GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,GTK_MESSAGE_ERROR,GTK_BUTTONS_CLOSE,  
343 - _( "Operation has failed" ));  
344 -  
345 - gtk_window_set_title(GTK_WINDOW(dialog),_("Can't print"));  
346 -  
347 - gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(dialog),"%s",error->message);  
348 -  
349 - gtk_dialog_run(GTK_DIALOG(dialog));  
350 - gtk_widget_destroy(dialog);  
351 -  
352 - g_error_free(error);  
353 - return -1;  
354 -  
355 - }  
356 -  
357 - return 0; 332 + return v3270_print(GTK_WIDGET(lib3270_get_user_data(session)), mode, NULL);
358 } 333 }
359 334
360 static int save(H3270 *session, LIB3270_CONTENT_OPTION mode, const char *filename) 335 static int save(H3270 *session, LIB3270_CONTENT_OPTION mode, const char *filename)
@@ -63,6 +63,12 @@ @@ -63,6 +63,12 @@
63 <Unit filename="src/dialogs/print/begin.c"> 63 <Unit filename="src/dialogs/print/begin.c">
64 <Option compilerVar="CC" /> 64 <Option compilerVar="CC" />
65 </Unit> 65 </Unit>
  66 + <Unit filename="src/dialogs/print/convenience.c">
  67 + <Option compilerVar="CC" />
  68 + </Unit>
  69 + <Unit filename="src/dialogs/print/custom.c">
  70 + <Option compilerVar="CC" />
  71 + </Unit>
66 <Unit filename="src/dialogs/print/draw.c"> 72 <Unit filename="src/dialogs/print/draw.c">
67 <Option compilerVar="CC" /> 73 <Option compilerVar="CC" />
68 </Unit> 74 </Unit>