David PHAM-VAN

Improve Linux and Windows printing

@@ -27,6 +27,7 @@ class PdfPreview extends StatefulWidget { @@ -27,6 +27,7 @@ class PdfPreview extends StatefulWidget {
27 this.pageFormats, 27 this.pageFormats,
28 this.onError, 28 this.onError,
29 this.onPrinted, 29 this.onPrinted,
  30 + this.onPrintError,
30 this.onShared, 31 this.onShared,
31 this.scrollViewDecoration, 32 this.scrollViewDecoration,
32 this.pdfPreviewPageDecoration, 33 this.pdfPreviewPageDecoration,
@@ -65,12 +66,15 @@ class PdfPreview extends StatefulWidget { @@ -65,12 +66,15 @@ class PdfPreview extends StatefulWidget {
65 /// List of page formats the user can choose 66 /// List of page formats the user can choose
66 final Map<String, PdfPageFormat>? pageFormats; 67 final Map<String, PdfPageFormat>? pageFormats;
67 68
68 - /// Called if an error creating the Pdf occured 69 + /// Widget to display if the PDF document cannot be displayed
69 final Widget Function(BuildContext context)? onError; 70 final Widget Function(BuildContext context)? onError;
70 71
71 /// Called if the user prints the pdf document 72 /// Called if the user prints the pdf document
72 final void Function(BuildContext context)? onPrinted; 73 final void Function(BuildContext context)? onPrinted;
73 74
  75 + /// Called if an error creating the Pdf occured
  76 + final void Function(BuildContext context, dynamic error)? onPrintError;
  77 +
74 /// Called if the user shares the pdf document 78 /// Called if the user shares the pdf document
75 final void Function(BuildContext context)? onShared; 79 final void Function(BuildContext context)? onShared;
76 80
@@ -514,8 +518,8 @@ class _PdfPreviewState extends State<PdfPreview> { @@ -514,8 +518,8 @@ class _PdfPreviewState extends State<PdfPreview> {
514 widget.onPrinted!(context); 518 widget.onPrinted!(context);
515 } 519 }
516 } catch (e) { 520 } catch (e) {
517 - if (widget.onError != null) {  
518 - widget.onError!(context); 521 + if (widget.onPrintError != null) {
  522 + widget.onPrintError!(context, e);
519 } 523 }
520 } 524 }
521 } 525 }
@@ -138,29 +138,34 @@ bool print_job::print_pdf(const gchar* name, @@ -138,29 +138,34 @@ bool print_job::print_pdf(const gchar* name,
138 GTK_PRINT_UNIX_DIALOG(gtk_print_unix_dialog_new(name, nullptr)); 138 GTK_PRINT_UNIX_DIALOG(gtk_print_unix_dialog_new(name, nullptr));
139 gtk_print_unix_dialog_set_manual_capabilities( 139 gtk_print_unix_dialog_set_manual_capabilities(
140 dialog, (GtkPrintCapabilities)(GTK_PRINT_CAPABILITY_GENERATE_PDF)); 140 dialog, (GtkPrintCapabilities)(GTK_PRINT_CAPABILITY_GENERATE_PDF));
  141 + gtk_print_unix_dialog_set_embed_page_setup(dialog, true);
  142 + gtk_print_unix_dialog_set_support_selection(dialog, false);
141 143
142 gtk_widget_realize(GTK_WIDGET(dialog)); 144 gtk_widget_realize(GTK_WIDGET(dialog));
143 145
144 - auto response = gtk_dialog_run(GTK_DIALOG(dialog));  
145 - gtk_widget_hide(GTK_WIDGET(dialog));  
146 -  
147 - switch (response) {  
148 - case GTK_RESPONSE_OK: {  
149 - _printer = gtk_print_unix_dialog_get_selected_printer(  
150 - GTK_PRINT_UNIX_DIALOG(dialog));  
151 - settings =  
152 - gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dialog));  
153 - setup =  
154 - gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dialog));  
155 - gtk_widget_destroy(GTK_WIDGET(dialog));  
156 - } break;  
157 - case GTK_RESPONSE_DELETE_EVENT: // Fall through.  
158 - case GTK_RESPONSE_CANCEL: // Cancel  
159 - case GTK_RESPONSE_APPLY: // Preview  
160 - default:  
161 - gtk_widget_destroy(GTK_WIDGET(dialog));  
162 - on_completed(this, false, nullptr);  
163 - return true; 146 + auto loop = true;
  147 +
  148 + while (loop) {
  149 + auto response = gtk_dialog_run(GTK_DIALOG(dialog));
  150 +
  151 + switch (response) {
  152 + case GTK_RESPONSE_OK: {
  153 + _printer = gtk_print_unix_dialog_get_selected_printer(
  154 + GTK_PRINT_UNIX_DIALOG(dialog));
  155 + settings =
  156 + gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dialog));
  157 + setup = gtk_print_unix_dialog_get_page_setup(
  158 + GTK_PRINT_UNIX_DIALOG(dialog));
  159 + gtk_widget_destroy(GTK_WIDGET(dialog));
  160 + loop = false;
  161 + } break;
  162 + case GTK_RESPONSE_APPLY: // Preview
  163 + break;
  164 + default: // Cancel
  165 + gtk_widget_destroy(GTK_WIDGET(dialog));
  166 + on_completed(this, false, nullptr);
  167 + return true;
  168 + }
164 } 169 }
165 } 170 }
166 171
@@ -172,8 +177,8 @@ bool print_job::print_pdf(const gchar* name, @@ -172,8 +177,8 @@ bool print_job::print_pdf(const gchar* name,
172 return false; 177 return false;
173 } 178 }
174 179
175 - auto _width = gtk_page_setup_get_page_width(setup, GTK_UNIT_POINTS);  
176 - auto _height = gtk_page_setup_get_page_height(setup, GTK_UNIT_POINTS); 180 + auto _width = gtk_page_setup_get_paper_width(setup, GTK_UNIT_POINTS);
  181 + auto _height = gtk_page_setup_get_paper_height(setup, GTK_UNIT_POINTS);
177 auto _marginLeft = gtk_page_setup_get_left_margin(setup, GTK_UNIT_POINTS); 182 auto _marginLeft = gtk_page_setup_get_left_margin(setup, GTK_UNIT_POINTS);
178 auto _marginTop = gtk_page_setup_get_top_margin(setup, GTK_UNIT_POINTS); 183 auto _marginTop = gtk_page_setup_get_top_margin(setup, GTK_UNIT_POINTS);
179 auto _marginRight = gtk_page_setup_get_right_margin(setup, GTK_UNIT_POINTS); 184 auto _marginRight = gtk_page_setup_get_right_margin(setup, GTK_UNIT_POINTS);
@@ -71,7 +71,7 @@ std::wstring fromUtf8(std::string str) { @@ -71,7 +71,7 @@ std::wstring fromUtf8(std::string str) {
71 } 71 }
72 72
73 PrintJob::PrintJob(Printing* printing, int index) 73 PrintJob::PrintJob(Printing* printing, int index)
74 - : printing(printing), index(index) {} 74 + : printing{printing}, index{index} {}
75 75
76 bool PrintJob::printPdf(std::string name, std::string printer) { 76 bool PrintJob::printPdf(std::string name, std::string printer) {
77 documentName = name; 77 documentName = name;
@@ -102,11 +102,18 @@ bool PrintJob::printPdf(std::string name, std::string printer) { @@ -102,11 +102,18 @@ bool PrintJob::printPdf(std::string name, std::string printer) {
102 102
103 auto r = PrintDlg(&pd); 103 auto r = PrintDlg(&pd);
104 104
105 - if (r == 1) { 105 + if (r != 1) {
  106 + printing->onCompleted(this, false, "");
  107 + DeleteDC(hDC);
  108 + GlobalFree(hDevNames);
  109 + ClosePrinter(hDevMode);
  110 + return true;
  111 + }
  112 +
106 hDC = pd.hDC; 113 hDC = pd.hDC;
107 hDevMode = pd.hDevMode; 114 hDevMode = pd.hDevMode;
108 hDevNames = pd.hDevNames; 115 hDevNames = pd.hDevNames;
109 - } 116 +
110 } else { 117 } else {
111 hDC = CreateDC(TEXT("WINSPOOL"), fromUtf8(printer).c_str(), NULL, NULL); 118 hDC = CreateDC(TEXT("WINSPOOL"), fromUtf8(printer).c_str(), NULL, NULL);
112 if (!hDC) { 119 if (!hDC) {
@@ -235,6 +242,8 @@ void PrintJob::writeJob(std::vector<uint8_t> data) { @@ -235,6 +242,8 @@ void PrintJob::writeJob(std::vector<uint8_t> data) {
235 DeleteDC(hDC); 242 DeleteDC(hDC);
236 GlobalFree(hDevNames); 243 GlobalFree(hDevNames);
237 ClosePrinter(hDevMode); 244 ClosePrinter(hDevMode);
  245 +
  246 + printing->onCompleted(this, true, "");
238 } 247 }
239 248
240 void PrintJob::cancelJob(std::string error) {} 249 void PrintJob::cancelJob(std::string error) {}
@@ -55,7 +55,7 @@ void Printing::onPageRasterEnd(PrintJob* job) { @@ -55,7 +55,7 @@ void Printing::onPageRasterEnd(PrintJob* job) {
55 55
56 class OnLayoutResult : public flutter::MethodResult<flutter::EncodableValue> { 56 class OnLayoutResult : public flutter::MethodResult<flutter::EncodableValue> {
57 public: 57 public:
58 - OnLayoutResult(PrintJob* job) : job(job) {} 58 + OnLayoutResult(PrintJob* job) : job{job} {}
59 59
60 private: 60 private:
61 PrintJob* job; 61 PrintJob* job;