21#include <poppler/glib/poppler.h>
27#include <wx/filename.h>
28#include <wx/filesys.h>
30#include <wx/cmndata.h>
34#include <wx/gtk/print.h>
44 PrintData( PopplerDocument* d ) :
51void draw_page( GtkPrintOperation* operation, GtkPrintContext* context, gint page_nr, gpointer user_data )
53 PrintData* print_data =
static_cast<PrintData*
>( user_data );
55 if( !print_data || !print_data->doc )
58 PopplerPage* page = poppler_document_get_page( print_data->doc, page_nr );
62 auto cleanup_page = std::unique_ptr<PopplerPage, decltype( &g_object_unref )>( page, &g_object_unref );
64 cairo_t* cr = gtk_print_context_get_cairo_context( context );
69 double page_width, page_height;
70 poppler_page_get_size( page, &page_width, &page_height );
73 double print_width = gtk_print_context_get_width( context );
74 double print_height = gtk_print_context_get_height( context );
77 auto cleanup_cairo = std::unique_ptr<cairo_t, decltype( &cairo_restore )>( cr, &cairo_restore );
79 if( print_data->fit_to_page )
82 double scale_x = print_width / page_width;
83 double scale_y = print_height / page_height;
84 double scale = std::min( scale_x, scale_y );
87 double scaled_width = page_width *
scale;
88 double scaled_height = page_height *
scale;
89 double offset_x = ( print_width - scaled_width ) / 2.0;
90 double offset_y = ( print_height - scaled_height ) / 2.0;
93 cairo_translate( cr, offset_x, offset_y );
98 cairo_set_source_rgb( cr, 1.0, 1.0, 1.0 );
102 poppler_page_render( page, cr );
105void begin_print_callback( GtkPrintOperation* operation, GtkPrintContext* context, gpointer user_data )
107 PrintData* print_data =
static_cast<PrintData*
>( user_data );
108 if( !print_data || !print_data->doc )
110 gtk_print_operation_cancel( operation );
114 int num_pages = poppler_document_get_n_pages( print_data->doc );
117 gtk_print_operation_cancel( operation );
121 gtk_print_operation_set_n_pages( operation, num_pages );
124void request_page_setup_callback( GtkPrintOperation* operation, GtkPrintContext* context, gint page_nr,
125 GtkPageSetup* setup, gpointer user_data )
127 PrintData* print_data =
static_cast<PrintData*
>( user_data );
129 if( !print_data || !print_data->doc )
132 PopplerPage* page = poppler_document_get_page( print_data->doc, page_nr );
138 double page_width, page_height;
139 poppler_page_get_size( page, &page_width, &page_height );
142 GtkPageOrientation orientation =
143 ( page_width > page_height ) ? GTK_PAGE_ORIENTATION_LANDSCAPE : GTK_PAGE_ORIENTATION_PORTRAIT;
144 gtk_page_setup_set_orientation( setup, orientation );
146 g_object_unref( page );
157 if( access( aFile.c_str(), R_OK ) != 0 )
161 gchar* uri = g_filename_to_uri( aFile.c_str(), NULL, NULL );
166 GError* error = NULL;
167 PopplerDocument* doc = poppler_document_new_from_file( uri, NULL, &error );
172 g_error_free( error );
179 auto cleanup_doc = std::unique_ptr<PopplerDocument, decltype(&g_object_unref)>(doc, &g_object_unref);
182 int num_pages = poppler_document_get_n_pages( doc );
188 PrintData print_data( doc );
189 print_data.fit_to_page = fit_to_page;
192 GtkPrintOperation* op = gtk_print_operation_new();
197 auto cleanup_op = std::unique_ptr<GtkPrintOperation, decltype( &g_object_unref )>( op, &g_object_unref );
200 gtk_print_operation_set_use_full_page( op, FALSE );
201 gtk_print_operation_set_unit( op, GTK_UNIT_POINTS );
204 g_signal_connect( op,
"begin-print", G_CALLBACK( begin_print_callback ), &print_data );
205 g_signal_connect( op,
"draw-page", G_CALLBACK( draw_page ), &print_data );
206 g_signal_connect( op,
"request-page-setup", G_CALLBACK( request_page_setup_callback ), &print_data );
210 GtkPrintOperationResult
result =
211 gtk_print_operation_run( op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL, &error );
218 g_error_free( error );
225 case GTK_PRINT_OPERATION_RESULT_APPLY: return_result =
PRINT_RESULT::OK;
break;
227 case GTK_PRINT_OPERATION_RESULT_ERROR:
232 return return_result;
246 static wxRegEx spoolTemplate( wxS(
"^gtkprint_?[A-Z0-9]{6}$" ) );
248 return spoolTemplate.Matches( aFileName );
254 if(
isSpoolName( wxFileName( aData.GetFilename() ).GetFullName() ) )
255 aData.SetFilename( wxEmptyString );
258 wxGtkPrintNativeData* nativeData =
dynamic_cast<wxGtkPrintNativeData*
>( aData.GetNativeData() );
260 if( !nativeData || !nativeData->GetPrintConfig() )
263 const gchar* uri = gtk_print_settings_get( nativeData->GetPrintConfig(),
264 GTK_PRINT_SETTINGS_OUTPUT_URI );
269 wxFileName destination = wxFileSystem::URLToFileName( wxString::FromUTF8( uri ) );
272 gtk_print_settings_unset( nativeData->GetPrintConfig(), GTK_PRINT_SETTINGS_OUTPUT_URI );
wxString result
Test unit parsing edge cases and error handling.