]> git.evergreen-ils.org Git - working/Hatch.git/blob - src/org/evergreen_ils/hatch/PrintManager.java
hatch : create job settings from config hash cont.
[working/Hatch.git] / src / org / evergreen_ils / hatch / PrintManager.java
1 /* -----------------------------------------------------------------------
2  * Copyright 2014 Equinox Software, Inc.
3  * Bill Erickson <berick@esilibrary.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * -----------------------------------------------------------------------
15  */
16 package org.evergreen_ils.hatch;
17
18 // logging
19 import org.eclipse.jetty.util.log.Log;
20 import org.eclipse.jetty.util.log.Logger;
21
22 // printing
23 import javafx.print.*;
24 import javafx.scene.web.WebEngine;
25 import javafx.collections.ObservableSet;
26 import javafx.collections.SetChangeListener;
27
28 import javax.print.PrintService;
29 import javax.print.PrintServiceLookup;
30 import javax.print.attribute.Attribute;
31 import javax.print.attribute.AttributeSet;
32 import javax.print.attribute.PrintRequestAttributeSet;
33 import javax.print.attribute.standard.Media;
34 import javax.print.attribute.standard.OrientationRequested;
35
36 import java.lang.IllegalArgumentException;
37
38 // data structures
39 import java.util.Map;
40 import java.util.List;
41 import java.util.ArrayList;
42 import java.util.HashMap;
43 import java.util.LinkedList;
44 import java.util.Set;
45 import java.util.LinkedHashSet;
46
47 public class PrintManager {
48
49     static final Logger logger = Log.getLogger("PrintManager");
50
51     public Map<String,Object> configurePrinter(
52         Map<String,Object> params) throws IllegalArgumentException {
53
54         Map<String,Object> settings = 
55             (Map<String,Object>) params.get("config");
56
57         PrinterJob job = buildPrinterJob(settings);
58         
59         job.showPrintDialog(null);
60
61         // no printing needed
62         job.endJob(); 
63
64         // extract modifications to the settings applied within the dialog
65         return extractSettingsFromJob(job);
66     }
67
68     public PrinterJob buildPrinterJob(
69         Map<String,Object> settings) throws IllegalArgumentException {
70
71         String name = (String) settings.get("printer");
72         Printer printer = getPrinterByName(name);
73
74         if (printer == null) 
75             throw new IllegalArgumentException("No such printer: " + name);
76
77         PageLayout layout = buildPageLayout(settings, printer);
78         PrinterJob job = PrinterJob.createPrinterJob(printer);
79
80         if (layout != null) job.getJobSettings().setPageLayout(layout);
81
82         // apply any provided settings to the job
83         applySettingsToJob(settings, job);
84
85         return job;
86     }
87
88     protected PageLayout buildPageLayout(
89             Map<String,Object> settings, Printer printer) {
90
91         // modify the default page layout with our settings
92         Map<String,Object> layoutMap = 
93             (Map<String,Object>) settings.get("pageLayout");
94
95         if (layoutMap == null) {
96             // Start with a sane default.
97             // The Java default is wonky
98             return printer.createPageLayout(
99                 Paper.NA_LETTER,
100                 PageOrientation.PORTRAIT,
101                 Printer.MarginType.DEFAULT
102             );
103         }
104
105         PrinterAttributes printerAttrs = printer.getPrinterAttributes();
106
107         // find the paper by name
108         Paper paper = null;
109         String paperName = (String) layoutMap.get("paper");
110         Set<Paper> papers = printerAttrs.getSupportedPapers();
111         for (Paper source : papers) {
112             if (source.getName().equals(paperName)) {
113                 logger.info("Found matching paper for " + paperName);
114                 paper = source;
115                 break;
116             }
117         }
118
119         if (paper == null) 
120             paper = printerAttrs.getDefaultPaper();
121
122         return printer.createPageLayout(
123             paper,
124             PageOrientation.valueOf((String) layoutMap.get("pageOrientation")),
125             ((Number) layoutMap.get("leftMargin")).doubleValue(),
126             ((Number) layoutMap.get("rightMargin")).doubleValue(),
127             ((Number) layoutMap.get("topMargin")).doubleValue(),
128             ((Number) layoutMap.get("bottomMargin")).doubleValue()
129         );
130     }
131
132     // applies the settings in settings to the provided print job
133     protected void applySettingsToJob(
134             Map<String,Object> settings, PrinterJob job) {
135
136         JobSettings jobSettings = job.getJobSettings();
137
138         PrinterAttributes printerAttrs = 
139             job.getPrinter().getPrinterAttributes();
140
141         String collation = (String) settings.get("collation");
142         Long copies = (Long) settings.get("copies");
143         String printColor = (String) settings.get("printColor");
144         String printQuality = (String) settings.get("printQuality");
145         String printSides = (String) settings.get("printSides");
146         String paperSource = (String) settings.get("paperSource");
147         Object[] pageRanges = (Object[]) settings.get("pageRanges");
148
149         if (collation != null) 
150             jobSettings.setCollation(Collation.valueOf(collation));
151
152         if (copies != null) 
153             jobSettings.setCopies(((Long) settings.get("copies")).intValue());
154
155         if (printColor != null) 
156             jobSettings.setPrintColor(PrintColor.valueOf(printColor));
157
158         if (printQuality != null) 
159             jobSettings.setPrintQuality(PrintQuality.valueOf(printQuality));
160
161         if (printSides != null) 
162             jobSettings.setPrintSides(PrintSides.valueOf(printSides));
163
164         // find the paperSource by name
165         if (paperSource != null) {
166             Set<PaperSource> paperSources = 
167                 printerAttrs.getSupportedPaperSources();
168
169             // note: "Automatic" appears to be a virtual source,
170             // meaning no source.. meaning let the printer decide.
171             for (PaperSource source : paperSources) {
172                 if (source.getName().equals(paperSource)) {
173                     logger.info("matched paper source for " + paperSource);
174                     jobSettings.setPaperSource(source);
175                     break;
176                 }
177             }
178         }
179
180
181         if (pageRanges != null) {
182             logger.info("pageRanges = " + pageRanges.toString());
183             List<PageRange> builtRanges = new LinkedList<PageRange>();
184             int i = 0, start = 0, end = 0;
185             do {
186                 if (i % 2 == 0 && i > 0)
187                     builtRanges.add(new PageRange(start, end));
188
189                 if (i == pageRanges.length) break;
190
191                 int current = ((Long) pageRanges[i]).intValue();
192                 if (i % 2 == 0) start = current; else end = current;
193
194             } while (++i > 0);
195
196             jobSettings.setPageRanges(builtRanges.toArray(new PageRange[0]));
197         }
198     }
199
200
201     public void print(WebEngine engine, Map<String,Object>params) {
202         
203         //debugPrintService(null); // testing
204
205         /*
206         Map<String,String> attrs = 
207             (Map<String,String>) params.get("attributes");
208
209         String printerName = (String) attrs.get("printer-name");
210         PrintService service = getPrintServiceByName(printerName);
211
212         if (service == null) {
213             logger.warn("printer '" + printerName + "' not found!");
214             debugPrintService();
215             return;
216         }
217
218         PrinterJob job = PrinterJob.createPrinterJob();
219         Attribute mediaAttr = getAttribute(
220             service, Media.class, (String) attrs.get("media"));
221
222         Attribute orientationAttr = getAttribute(
223             service, RequestedOrientation.class, 
224             (String) attrs.get("orientation"));
225
226         PrintRequestAttributeSet attrSet = new PrintRequestAttributeSet();
227         if (mediaAttr != null) attrSet.add(mediaAttr);
228         if (orientationAttr != null) attrSet.add(orientationAttr);
229         */
230
231
232         //getPrinterByName(); ...
233         Printer printer = Printer.getDefaultPrinter(); // TODO
234         PageLayout firstLayout = printer.createPageLayout(
235             Paper.NA_LETTER,
236             PageOrientation.LANDSCAPE,
237             0.1 * 72, 0.2 * 72, 0.3 * 72, 0.4 * 72 
238         );
239
240         logger.info("orig job page layout " + firstLayout.toString());
241         PrinterJob job = PrinterJob.createPrinterJob(printer);
242
243         job.getJobSettings().setPageLayout(firstLayout);
244         if (!job.showPrintDialog(null)) return; // print canceled by user
245
246         Map<String,Object> settings = extractSettingsFromJob(job);
247         engine.print(job);
248         job.endJob();
249
250         HatchWebSocketHandler socket = 
251             (HatchWebSocketHandler) params.get("socket");
252
253         socket.reply(settings, (Long) params.get("msgid"));
254     }
255
256     protected Map<String,Object> extractSettingsFromJob(PrinterJob job) {
257         Map<String,Object> settings = new HashMap<String,Object>();
258         JobSettings jobSettings = job.getJobSettings();
259
260         settings.put(
261             jobSettings.collationProperty().getName(),
262             jobSettings.collationProperty().getValue()
263         );
264         settings.put(
265             jobSettings.copiesProperty().getName(),
266             jobSettings.copiesProperty().getValue()
267         );
268         settings.put(
269             "paperSource", 
270             jobSettings.getPaperSource().getName()
271         );
272         settings.put(
273             jobSettings.printColorProperty().getName(),
274             jobSettings.printColorProperty().getValue()
275         );
276         settings.put(
277             jobSettings.printQualityProperty().getName(),
278             jobSettings.printQualityProperty().getValue()
279         );
280         settings.put(
281             jobSettings.printSidesProperty().getName(),
282             jobSettings.printSidesProperty().getValue()
283         );
284
285         // nested properties...
286         
287         // page layout --------------
288         PageLayout layout = jobSettings.getPageLayout();
289         Map<String,Object> layoutMap = new HashMap<String,Object>();
290         layoutMap.put("bottomMargin", layout.getBottomMargin());
291         layoutMap.put("leftMargin", layout.getLeftMargin());
292         layoutMap.put("topMargin", layout.getTopMargin());
293         layoutMap.put("rightMargin", layout.getRightMargin());
294         layoutMap.put("pageOrientation", layout.getPageOrientation().toString());
295         layoutMap.put("printableHeight", layout.getPrintableHeight());
296         layoutMap.put("printableWidth", layout.getPrintableWidth());
297         layoutMap.put("paper", layout.getPaper().getName());
298
299         settings.put("pageLayout", layoutMap);
300
301         // page ranges --------------
302         PageRange[] ranges = jobSettings.getPageRanges();
303         if (ranges != null) {
304             List<Integer> pageRanges = new LinkedList<Integer>();
305
306             if (ranges.length == 1 &&
307                 ranges[0].getStartPage() == 1 && 
308                 ranges[0].getEndPage() == Integer.MAX_VALUE) {
309                 // full range -- no need to store
310
311             } else {
312                 for (PageRange range : ranges) {
313                     pageRanges.add(range.getStartPage());
314                     pageRanges.add(range.getEndPage());
315                 }
316                 settings.put("pageRanges", pageRanges);
317             }
318         }
319
320         logger.info("compiled printer properties: " + settings.toString());
321         return settings;
322     }
323
324     protected Printer[] getPrinters() {
325         ObservableSet<Printer> printerObserver = Printer.getAllPrinters();
326
327         if (printerObserver == null) return new Printer[0];
328
329         return (Printer[]) printerObserver.toArray(new Printer[0]);
330     }
331
332     protected List<Map<String,Object>> getPrintersAsMaps() {
333         Printer[] printers = getPrinters();
334
335         List<Map<String,Object>> printerMaps = 
336             new LinkedList<Map<String,Object>>();
337
338         Printer defaultPrinter = Printer.getDefaultPrinter();
339
340         for (Printer printer : printers) {
341             HashMap<String, Object> printerMap = new HashMap<String, Object>();
342             printerMaps.add(printerMap);
343             printerMap.put("name", printer.getName());
344             if (printer.getName().equals(defaultPrinter.getName())) {
345                 printerMap.put("is-default", new Boolean(true));
346             }
347             logger.info("found printer " + printer.getName());            
348         }
349
350         return printerMaps;
351     }
352
353
354     protected Printer getPrinterByName(String name) {
355         Printer[] printers = getPrinters();
356         for (Printer printer : printers) {
357             if (printer.getName().equals(name))
358                 return printer;
359         }
360         return null;
361     }
362
363
364     private void debugPrintService(PrintService printer) {
365
366         PrintService[] printServices;
367         String defaultPrinter = "";
368
369         if (printer != null) {
370             printServices = new PrintService[] {printer};
371         } else {
372             printServices = PrintServiceLookup.lookupPrintServices(null, null);
373             PrintService def = PrintServiceLookup.lookupDefaultPrintService();
374             if (def != null) defaultPrinter = def.getName();
375         }
376
377         for (PrintService service : printServices) {
378             logger.info("Printer Debug: found printer " + service.getName());
379             if (service.getName().equals(defaultPrinter)) {
380                 logger.info("    Printer Debug: Is Default");
381             }
382
383             AttributeSet attributes = service.getAttributes();
384             for (Attribute a : attributes.toArray()) {
385                 String name = a.getName();
386                 String value = attributes.get(a.getClass()).toString();
387                 logger.info("    Printer Debug: " + name + " => " + value);
388             }
389         }
390     }
391
392     public PrintService getPrintServiceByName(String name) {
393         PrintService[] printServices =
394             PrintServiceLookup.lookupPrintServices(null, null);
395         for (PrintService service : printServices) {
396             if (service.getName().equals(name))
397                 return service;
398         }
399         return null;
400     }
401
402     /*
403     public List<HashMap> getPrinters() {
404
405         List<HashMap> printers = new LinkedList<HashMap>();
406         PrintService[] printServices =
407             PrintServiceLookup.lookupPrintServices(null, null);
408
409         String defaultPrinter = "";
410         PrintService def = PrintServiceLookup.lookupDefaultPrintService();
411         if (def != null) defaultPrinter = def.getName();
412
413         for (PrintService service : printServices) {
414             HashMap<String, Object> printer = new HashMap<String, Object>();
415             printers.add(printer);
416
417             if (service.getName().equals(defaultPrinter))
418                 printer.put("is-default", new Boolean(true));
419
420             // collect information about the printer attributes we care about
421             Class[] attrClasses = {
422                 Media.class, 
423                 //OrientationRequested.class
424             };
425
426             for (Class c : attrClasses) {
427                 Attribute[] attrs = (Attribute[])
428                     service.getSupportedAttributeValues(c, null, null);
429
430                 if (attrs.length > 0) {
431                     ArrayList<String> values = new ArrayList<String>(attrs.length);
432                     for (Attribute a : attrs) {
433                         String s = a.toString();
434                         if (!values.contains(s)) values.add(s);
435                     }
436                     printer.put(attrs[0].getName(), values);
437                 }
438             }
439
440             AttributeSet attributes = service.getAttributes();
441             for (Attribute a : attributes.toArray()) {
442                 String name = a.getName();
443                 String value = attributes.get(a.getClass()).toString();
444                 printer.put(name, value);
445             }
446         }
447
448         return printers;
449     }
450     */
451 }
452