David PHAM-VAN

Improve Windows directPrint

@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 - Document.save() now returns a Future 6 - Document.save() now returns a Future
7 - Implement pan and zoom on PdfPreview widget 7 - Implement pan and zoom on PdfPreview widget
8 - Improve orientation handling 8 - Improve orientation handling
  9 +- Improve directPrint
9 10
10 ## 3.7.2 11 ## 3.7.2
11 12
@@ -165,6 +165,9 @@ class MethodChannelPrinting extends PrintingPlatform { @@ -165,6 +165,9 @@ class MethodChannelPrinting extends PrintingPlatform {
165 name: printer['name'], 165 name: printer['name'],
166 model: printer['model'], 166 model: printer['model'],
167 location: printer['location'], 167 location: printer['location'],
  168 + comment: printer['comment'],
  169 + isDefault: printer['default'],
  170 + available: printer['available'],
168 )); 171 ));
169 } 172 }
170 173
@@ -25,6 +25,9 @@ class Printer { @@ -25,6 +25,9 @@ class Printer {
25 this.name, 25 this.name,
26 this.model, 26 this.model,
27 this.location, 27 this.location,
  28 + this.comment,
  29 + this.isDefault = false,
  30 + this.available = true,
28 }) : assert(url != null); 31 }) : assert(url != null);
29 32
30 /// The platform specific printer identification 33 /// The platform specific printer identification
@@ -39,6 +42,15 @@ class Printer { @@ -39,6 +42,15 @@ class Printer {
39 /// The physical location of the printer 42 /// The physical location of the printer
40 final String location; 43 final String location;
41 44
  45 + /// A user comment about the printer
  46 + final String comment;
  47 +
  48 + /// Is this the default printer on the system
  49 + final bool isDefault;
  50 +
  51 + /// The printer is available for printing
  52 + final bool available;
  53 +
42 @override 54 @override
43 String toString() => name ?? url; 55 String toString() => name ?? url;
44 } 56 }
@@ -65,6 +65,7 @@ mixin Printing { @@ -65,6 +65,7 @@ mixin Printing {
65 static Future<Printer> pickPrinter({ 65 static Future<Printer> pickPrinter({
66 @required BuildContext context, 66 @required BuildContext context,
67 Rect bounds, 67 Rect bounds,
  68 + String title,
68 }) async { 69 }) async {
69 final _info = await info(); 70 final _info = await info();
70 71
@@ -74,17 +75,35 @@ mixin Printing { @@ -74,17 +75,35 @@ mixin Printing {
74 'Pass a BuildContext to pickPrinter to display a selection list', 75 'Pass a BuildContext to pickPrinter to display a selection list',
75 ); 76 );
76 final printers = await listPrinters(); 77 final printers = await listPrinters();
  78 + printers.sort((a, b) {
  79 + if (a.isDefault) {
  80 + return -1;
  81 + }
  82 + if (b.isDefault) {
  83 + return 1;
  84 + }
  85 + return a.name.compareTo(b.name);
  86 + });
  87 +
77 return await showDialog<Printer>( 88 return await showDialog<Printer>(
78 context: context, 89 context: context,
79 builder: (context) => SimpleDialog( 90 builder: (context) => SimpleDialog(
80 - children: printers  
81 - .map<Widget>(  
82 - (e) => SimpleDialogOption(  
83 - child: Text(e.name),  
84 - onPressed: () => Navigator.of(context).pop(e), 91 + title: Text(title ?? 'Select Printer'),
  92 + children: [
  93 + for (final printer in printers)
  94 + if (printer.available)
  95 + SimpleDialogOption(
  96 + child: Text(
  97 + printer.name,
  98 + style: TextStyle(
  99 + fontStyle: printer.isDefault
  100 + ? FontStyle.italic
  101 + : FontStyle.normal,
  102 + ),
  103 + ),
  104 + onPressed: () => Navigator.of(context).pop(printer),
85 ), 105 ),
86 - )  
87 - .toList(), 106 + ],
88 ), 107 ),
89 ); 108 );
90 } 109 }
@@ -134,6 +134,7 @@ bool PrintJob::printPdf(std::string name) { @@ -134,6 +134,7 @@ bool PrintJob::printPdf(std::string name) {
134 ZeroMemory(dm, sizeof(DEVMODE)); 134 ZeroMemory(dm, sizeof(DEVMODE));
135 dm->dmFields = DM_ORIENTATION; 135 dm->dmFields = DM_ORIENTATION;
136 dm->dmOrientation = 2; 136 dm->dmOrientation = 2;
  137 + printf("Printing ... \n");
137 138
138 // Initialize PRINTDLG 139 // Initialize PRINTDLG
139 ZeroMemory(&pd, sizeof(pd)); 140 ZeroMemory(&pd, sizeof(pd));
@@ -186,19 +187,28 @@ bool PrintJob::printPdf(std::string name) { @@ -186,19 +187,28 @@ bool PrintJob::printPdf(std::string name) {
186 } 187 }
187 188
188 std::vector<Printer> PrintJob::listPrinters() { 189 std::vector<Printer> PrintJob::listPrinters() {
  190 + LPTSTR defaultPrinter;
  191 + DWORD size = 0;
  192 + GetDefaultPrinter(nullptr, &size);
  193 +
  194 + defaultPrinter = static_cast<LPTSTR>(malloc(size * sizeof(TCHAR)));
  195 + if (!GetDefaultPrinter(defaultPrinter, &size)) {
  196 + size = 0;
  197 + }
  198 +
189 auto printers = std::vector<Printer>{}; 199 auto printers = std::vector<Printer>{};
190 DWORD needed = 0; 200 DWORD needed = 0;
191 DWORD returned = 0; 201 DWORD returned = 0;
192 const auto flags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS; 202 const auto flags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS;
193 203
194 - EnumPrinters(flags, nullptr, 1, nullptr, 0, &needed, &returned); 204 + EnumPrinters(flags, nullptr, 2, nullptr, 0, &needed, &returned);
195 205
196 - auto buffer = (PRINTER_INFO_1*)malloc(needed); 206 + auto buffer = (PRINTER_INFO_2*)malloc(needed);
197 if (!buffer) { 207 if (!buffer) {
198 return printers; 208 return printers;
199 } 209 }
200 210
201 - auto result = EnumPrinters(flags, nullptr, 1, (LPBYTE)buffer, needed, &needed, 211 + auto result = EnumPrinters(flags, nullptr, 2, (LPBYTE)buffer, needed, &needed,
202 &returned); 212 &returned);
203 213
204 if (result == 0) { 214 if (result == 0) {
@@ -208,14 +218,17 @@ std::vector<Printer> PrintJob::listPrinters() { @@ -208,14 +218,17 @@ std::vector<Printer> PrintJob::listPrinters() {
208 218
209 for (DWORD i = 0; i < returned; i++) { 219 for (DWORD i = 0; i < returned; i++) {
210 printers.push_back(Printer{ 220 printers.push_back(Printer{
211 - toUtf8(buffer[i].pName),  
212 - toUtf8(buffer[i].pName),  
213 - toUtf8(buffer[i].pDescription), 221 + toUtf8(buffer[i].pPrinterName), toUtf8(buffer[i].pPrinterName),
  222 + toUtf8(buffer[i].pDriverName), toUtf8(buffer[i].pLocation),
214 toUtf8(buffer[i].pComment), 223 toUtf8(buffer[i].pComment),
215 - }); 224 + size > 0 && _tcsncmp(buffer[i].pPrinterName, defaultPrinter, size) == 0,
  225 + (buffer[i].Status &
  226 + (PRINTER_STATUS_NOT_AVAILABLE | PRINTER_STATUS_ERROR |
  227 + PRINTER_STATUS_OFFLINE | PRINTER_STATUS_PAUSED)) == 0});
216 } 228 }
217 229
218 free(buffer); 230 free(buffer);
  231 + free(defaultPrinter);
219 return printers; 232 return printers;
220 } 233 }
221 234
@@ -34,13 +34,25 @@ struct Printer { @@ -34,13 +34,25 @@ struct Printer {
34 const std::string name; 34 const std::string name;
35 const std::string url; 35 const std::string url;
36 const std::string model; 36 const std::string model;
37 - const std::string description; 37 + const std::string location;
  38 + const std::string comment;
  39 + const bool default;
  40 + const bool available;
38 41
39 Printer(std::string name, 42 Printer(std::string name,
40 std::string url, 43 std::string url,
41 std::string model, 44 std::string model,
42 - std::string description)  
43 - : name(name), url(url), model(model), description(description) {} 45 + std::string location,
  46 + std::string comment,
  47 + bool default,
  48 + bool available)
  49 + : name(name),
  50 + url(url),
  51 + model(model),
  52 + location(location),
  53 + comment(comment),
  54 + default(default),
  55 + available(available) {}
44 }; 56 };
45 57
46 class PrintJob { 58 class PrintJob {
@@ -125,8 +125,14 @@ class PrintingPlugin : public flutter::Plugin { @@ -125,8 +125,14 @@ class PrintingPlugin : public flutter::Plugin {
125 flutter::EncodableValue(printer.url); 125 flutter::EncodableValue(printer.url);
126 mp[flutter::EncodableValue("model")] = 126 mp[flutter::EncodableValue("model")] =
127 flutter::EncodableValue(printer.model); 127 flutter::EncodableValue(printer.model);
128 - mp[flutter::EncodableValue("description")] =  
129 - flutter::EncodableValue(printer.description); 128 + mp[flutter::EncodableValue("location")] =
  129 + flutter::EncodableValue(printer.location);
  130 + mp[flutter::EncodableValue("comment")] =
  131 + flutter::EncodableValue(printer.comment);
  132 + mp[flutter::EncodableValue("default")] =
  133 + flutter::EncodableValue(printer.default);
  134 + mp[flutter::EncodableValue("available")] =
  135 + flutter::EncodableValue(printer.available);
130 pl.push_back(mp); 136 pl.push_back(mp);
131 } 137 }
132 result->Success(pl); 138 result->Success(pl);