From 6bcf4f43a8f305732e0a5a3af16dbb802b7d7a71 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Sat, 24 Jun 2023 20:25:49 -0400 Subject: [PATCH 1/5] Initial page size support --- src/qz/printer/PrintServiceMatcher.java | 35 ++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/qz/printer/PrintServiceMatcher.java b/src/qz/printer/PrintServiceMatcher.java index b474af2ae..619fba620 100644 --- a/src/qz/printer/PrintServiceMatcher.java +++ b/src/qz/printer/PrintServiceMatcher.java @@ -22,10 +22,9 @@ import javax.print.PrintService; import javax.print.PrintServiceLookup; import javax.print.attribute.ResolutionSyntax; -import javax.print.attribute.standard.Media; -import javax.print.attribute.standard.MediaTray; -import javax.print.attribute.standard.PrinterName; -import javax.print.attribute.standard.PrinterResolution; +import javax.print.attribute.standard.*; +import java.awt.geom.Rectangle2D; +import java.util.HashMap; import java.util.Locale; public class PrintServiceMatcher { @@ -174,8 +173,36 @@ public static JSONArray getPrintersJSON(boolean includeDetails) throws JSONExcep log.info("Gathering printer MediaTray information..."); mediaTrayCrawled = true; } + + HashMap sizes = new HashMap<>(); + for(Media m : (Media[])ps.getSupportedAttributeValues(Media.class, null, null)) { if (m instanceof MediaTray) { jsonService.accumulate("trays", m.toString()); } + if (m instanceof MediaSizeName) { + MediaSize mediaSize = MediaSize.getMediaSizeForName((MediaSizeName)m); + if(mediaSize != null) { + // Collect into a HashMap to avoid duplicates + float widthIn = mediaSize.getX(MediaPrintableArea.INCH); + float heightIn = mediaSize.getY(MediaPrintableArea.INCH); + String keyIn = String.format("%sx%s in",widthIn, heightIn); + Rectangle2D valueIn = new Rectangle2D.Float(0, 0, widthIn, heightIn); + sizes.put(keyIn, valueIn); + + float widthMm = mediaSize.getX(MediaPrintableArea.MM); + float heightMm = mediaSize.getY(MediaPrintableArea.MM); + String keyMm = String.format("%sx%s mm", widthMm, heightMm); + Rectangle2D valueMm = new Rectangle2D.Float(0, 0, widthMm, heightMm); + sizes.put(keyMm, valueMm); + } + } + } + + for(String key : sizes.keySet()) { + JSONObject sizeEntry = new JSONObject(); + sizeEntry.put("units", key.endsWith("in") ? "in" : "mm"); + sizeEntry.put("width", sizes.get(key).getWidth()); + sizeEntry.put("height", sizes.get(key).getHeight()); + jsonService.accumulate("sizes", sizeEntry); } PrinterResolution res = printer.getResolution().value(); From a4edb74b243ed094308ac0fa69f7fd1b673eaa2c Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Mon, 26 Jun 2023 02:05:13 -0400 Subject: [PATCH 2/5] Refactor units handling, fix sorting --- src/qz/printer/PrintServiceMatcher.java | 48 +++++++------- src/qz/printer/info/MediaSizeHashSet.java | 78 +++++++++++++++++++++++ 2 files changed, 101 insertions(+), 25 deletions(-) create mode 100644 src/qz/printer/info/MediaSizeHashSet.java diff --git a/src/qz/printer/PrintServiceMatcher.java b/src/qz/printer/PrintServiceMatcher.java index 619fba620..ebf4cc807 100644 --- a/src/qz/printer/PrintServiceMatcher.java +++ b/src/qz/printer/PrintServiceMatcher.java @@ -15,6 +15,7 @@ import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; +import qz.printer.info.MediaSizeHashSet; import qz.printer.info.NativePrinter; import qz.printer.info.NativePrinterMap; import qz.utils.SystemUtilities; @@ -23,9 +24,7 @@ import javax.print.PrintServiceLookup; import javax.print.attribute.ResolutionSyntax; import javax.print.attribute.standard.*; -import java.awt.geom.Rectangle2D; -import java.util.HashMap; -import java.util.Locale; +import java.util.*; public class PrintServiceMatcher { private static final Logger log = LogManager.getLogger(PrintServiceMatcher.class); @@ -174,35 +173,34 @@ public static JSONArray getPrintersJSON(boolean includeDetails) throws JSONExcep mediaTrayCrawled = true; } - HashMap sizes = new HashMap<>(); + MediaSizeHashSet sizes = new MediaSizeHashSet(); for(Media m : (Media[])ps.getSupportedAttributeValues(Media.class, null, null)) { if (m instanceof MediaTray) { jsonService.accumulate("trays", m.toString()); } if (m instanceof MediaSizeName) { - MediaSize mediaSize = MediaSize.getMediaSizeForName((MediaSizeName)m); - if(mediaSize != null) { - // Collect into a HashMap to avoid duplicates - float widthIn = mediaSize.getX(MediaPrintableArea.INCH); - float heightIn = mediaSize.getY(MediaPrintableArea.INCH); - String keyIn = String.format("%sx%s in",widthIn, heightIn); - Rectangle2D valueIn = new Rectangle2D.Float(0, 0, widthIn, heightIn); - sizes.put(keyIn, valueIn); - - float widthMm = mediaSize.getX(MediaPrintableArea.MM); - float heightMm = mediaSize.getY(MediaPrintableArea.MM); - String keyMm = String.format("%sx%s mm", widthMm, heightMm); - Rectangle2D valueMm = new Rectangle2D.Float(0, 0, widthMm, heightMm); - sizes.put(keyMm, valueMm); - } + sizes.add((MediaSizeName)m); } } - for(String key : sizes.keySet()) { - JSONObject sizeEntry = new JSONObject(); - sizeEntry.put("units", key.endsWith("in") ? "in" : "mm"); - sizeEntry.put("width", sizes.get(key).getWidth()); - sizeEntry.put("height", sizes.get(key).getHeight()); - jsonService.accumulate("sizes", sizeEntry); + List sortedList = new ArrayList<>(sizes); + Collections.sort(sortedList); + + for(MediaSizeHashSet.Pair pair : sortedList) { + // Inches + JSONObject inches = new JSONObject(); + inches.put("units", "in"); + inches.put("width", pair.getInches().getWidth()); + inches.put("height", pair.getInches().getHeight()); + jsonService.accumulate("sizes", inches); + } + + for(MediaSizeHashSet.Pair pair : sortedList) { + // Millimeters + JSONObject mm = new JSONObject(); + mm.put("units", "mm"); + mm.put("width", pair.getMm().getWidth()); + mm.put("height", pair.getMm().getHeight()); + jsonService.accumulate("sizes", mm); } PrinterResolution res = printer.getResolution().value(); diff --git a/src/qz/printer/info/MediaSizeHashSet.java b/src/qz/printer/info/MediaSizeHashSet.java new file mode 100644 index 000000000..c2fc9a533 --- /dev/null +++ b/src/qz/printer/info/MediaSizeHashSet.java @@ -0,0 +1,78 @@ +package qz.printer.info; + +import javax.print.attribute.standard.MediaPrintableArea; +import javax.print.attribute.standard.MediaSize; +import javax.print.attribute.standard.MediaSizeName; +import java.util.*; + +/** + * A sortable HashMap for storing printer page sizes for both imperial (inches) and metric (millimeters) + */ +public class MediaSizeHashSet extends HashSet { + public class Pair implements Comparable { + private DimensionFloat inches; + private DimensionFloat mm; + + public Pair(MediaSize mediaSize) { + inches = new DimensionFloat(mediaSize.getX(MediaPrintableArea.INCH), mediaSize.getY(MediaPrintableArea.INCH)); + mm = new DimensionFloat(mediaSize.getX(MediaPrintableArea.MM), mediaSize.getY(MediaPrintableArea.MM)); + } + + @Override + public boolean equals(Object o) { + if (this == o) {return true;} + if (o == null || getClass() != o.getClass()) {return false;} + Pair that = (Pair)o; + return inches.width == that.inches.width && inches.height == that.inches.height; + } + + @Override + public int compareTo(Object o) { + if (this == o) {return 0;} + if (o == null || getClass() != o.getClass()) {return -1;} + return Comparator.comparing((Pair p)-> p.inches.width) + .thenComparing((Pair p)-> p.inches.height) + .compare(this, (Pair)o); + } + + public DimensionFloat getInches() { + return inches; + } + + public DimensionFloat getMm() { + return mm; + } + } + + /** + * Simple dimension container using floats + */ + public class DimensionFloat { + private float width; + private float height; + + public DimensionFloat(float width, float height) { + this.width = width; + this.height = height; + } + + public float getWidth() { + return width; + } + + public float getHeight() { + return height; + } + } + + /** + * Adds an imperial (in) and metric (mm) entry of the specified MediaSizeName + */ + public boolean add(MediaSizeName mediaSizeName) { + MediaSize mediaSize = MediaSize.getMediaSizeForName(mediaSizeName); + if(mediaSize != null) { + return add(new Pair(mediaSize)); + } + return false; + } +} From b8043044d46cc2e75facba0b49f4da71438ffa63 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Mon, 26 Jun 2023 02:12:31 -0400 Subject: [PATCH 3/5] Comments, cleanup --- src/qz/printer/PrintServiceMatcher.java | 20 +++++++------- src/qz/printer/info/MediaSizeHashSet.java | 32 ++++++++++++++--------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/qz/printer/PrintServiceMatcher.java b/src/qz/printer/PrintServiceMatcher.java index ebf4cc807..4b6fb3085 100644 --- a/src/qz/printer/PrintServiceMatcher.java +++ b/src/qz/printer/PrintServiceMatcher.java @@ -182,20 +182,20 @@ public static JSONArray getPrintersJSON(boolean includeDetails) throws JSONExcep } } - List sortedList = new ArrayList<>(sizes); + List sortedList = new ArrayList<>(sizes); Collections.sort(sortedList); - for(MediaSizeHashSet.Pair pair : sortedList) { - // Inches - JSONObject inches = new JSONObject(); - inches.put("units", "in"); - inches.put("width", pair.getInches().getWidth()); - inches.put("height", pair.getInches().getHeight()); - jsonService.accumulate("sizes", inches); + for(MediaSizeHashSet.UnitPair pair : sortedList) { + // First, list as inches + JSONObject in = new JSONObject(); + in.put("units", "in"); + in.put("width", pair.getIn().getWidth()); + in.put("height", pair.getIn().getHeight()); + jsonService.accumulate("sizes", in); } - for(MediaSizeHashSet.Pair pair : sortedList) { - // Millimeters + for(MediaSizeHashSet.UnitPair pair : sortedList) { + // Second, list as millimeters JSONObject mm = new JSONObject(); mm.put("units", "mm"); mm.put("width", pair.getMm().getWidth()); diff --git a/src/qz/printer/info/MediaSizeHashSet.java b/src/qz/printer/info/MediaSizeHashSet.java index c2fc9a533..38ebff339 100644 --- a/src/qz/printer/info/MediaSizeHashSet.java +++ b/src/qz/printer/info/MediaSizeHashSet.java @@ -8,13 +8,13 @@ /** * A sortable HashMap for storing printer page sizes for both imperial (inches) and metric (millimeters) */ -public class MediaSizeHashSet extends HashSet { - public class Pair implements Comparable { - private DimensionFloat inches; +public class MediaSizeHashSet extends HashSet { + public class UnitPair implements Comparable { + private DimensionFloat in; private DimensionFloat mm; - public Pair(MediaSize mediaSize) { - inches = new DimensionFloat(mediaSize.getX(MediaPrintableArea.INCH), mediaSize.getY(MediaPrintableArea.INCH)); + public UnitPair(MediaSize mediaSize) { + in = new DimensionFloat(mediaSize.getX(MediaPrintableArea.INCH), mediaSize.getY(MediaPrintableArea.INCH)); mm = new DimensionFloat(mediaSize.getX(MediaPrintableArea.MM), mediaSize.getY(MediaPrintableArea.MM)); } @@ -22,23 +22,29 @@ public Pair(MediaSize mediaSize) { public boolean equals(Object o) { if (this == o) {return true;} if (o == null || getClass() != o.getClass()) {return false;} - Pair that = (Pair)o; - return inches.width == that.inches.width && inches.height == that.inches.height; + UnitPair that = (UnitPair)o; + return in.width == that.in.width && in.height == that.in.height; } @Override public int compareTo(Object o) { if (this == o) {return 0;} if (o == null || getClass() != o.getClass()) {return -1;} - return Comparator.comparing((Pair p)-> p.inches.width) - .thenComparing((Pair p)-> p.inches.height) - .compare(this, (Pair)o); + return Comparator.comparing((UnitPair p)-> p.in.width) + .thenComparing((UnitPair p)-> p.in.height) + .compare(this, (UnitPair)o); } - public DimensionFloat getInches() { - return inches; + /** + * Get size as DimensionFloat in inches + */ + public DimensionFloat getIn() { + return in; } + /** + * Get size as DimensionFloat in millimeters + */ public DimensionFloat getMm() { return mm; } @@ -71,7 +77,7 @@ public float getHeight() { public boolean add(MediaSizeName mediaSizeName) { MediaSize mediaSize = MediaSize.getMediaSizeForName(mediaSizeName); if(mediaSize != null) { - return add(new Pair(mediaSize)); + return add(new UnitPair(mediaSize)); } return false; } From cd5781e5c95ddab770008def98a218e685e83743 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Wed, 28 Jun 2023 20:29:36 -0400 Subject: [PATCH 4/5] Refactor JSON, add name. --- src/qz/printer/PrintServiceMatcher.java | 43 ++++++------ src/qz/printer/info/MediaSizeHashSet.java | 84 ----------------------- 2 files changed, 21 insertions(+), 106 deletions(-) delete mode 100644 src/qz/printer/info/MediaSizeHashSet.java diff --git a/src/qz/printer/PrintServiceMatcher.java b/src/qz/printer/PrintServiceMatcher.java index 4b6fb3085..e77a29d42 100644 --- a/src/qz/printer/PrintServiceMatcher.java +++ b/src/qz/printer/PrintServiceMatcher.java @@ -15,7 +15,6 @@ import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; -import qz.printer.info.MediaSizeHashSet; import qz.printer.info.NativePrinter; import qz.printer.info.NativePrinterMap; import qz.utils.SystemUtilities; @@ -173,34 +172,34 @@ public static JSONArray getPrintersJSON(boolean includeDetails) throws JSONExcep mediaTrayCrawled = true; } - MediaSizeHashSet sizes = new MediaSizeHashSet(); + HashSet uniqueSizes = new HashSet<>(); for(Media m : (Media[])ps.getSupportedAttributeValues(Media.class, null, null)) { if (m instanceof MediaTray) { jsonService.accumulate("trays", m.toString()); } if (m instanceof MediaSizeName) { - sizes.add((MediaSizeName)m); - } - } + if(uniqueSizes.add(m.toString())) { + MediaSize mediaSize = MediaSize.getMediaSizeForName((MediaSizeName)m); + if(mediaSize == null) { + continue; + } - List sortedList = new ArrayList<>(sizes); - Collections.sort(sortedList); + JSONObject sizes = new JSONObject(); + sizes.put("name", m.toString()); - for(MediaSizeHashSet.UnitPair pair : sortedList) { - // First, list as inches - JSONObject in = new JSONObject(); - in.put("units", "in"); - in.put("width", pair.getIn().getWidth()); - in.put("height", pair.getIn().getHeight()); - jsonService.accumulate("sizes", in); - } + JSONObject in = new JSONObject(); + in.put("width", mediaSize.getX(MediaPrintableArea.INCH)); + in.put("height", mediaSize.getY(MediaPrintableArea.INCH)); + sizes.put("in", in); - for(MediaSizeHashSet.UnitPair pair : sortedList) { - // Second, list as millimeters - JSONObject mm = new JSONObject(); - mm.put("units", "mm"); - mm.put("width", pair.getMm().getWidth()); - mm.put("height", pair.getMm().getHeight()); - jsonService.accumulate("sizes", mm); + JSONObject mm = new JSONObject(); + mm.put("width", mediaSize.getX(MediaPrintableArea.MM)); + mm.put("height", mediaSize.getY(MediaPrintableArea.MM)); + sizes.put("mm", mm); + + jsonService.accumulate("sizes", sizes); + } + + } } PrinterResolution res = printer.getResolution().value(); diff --git a/src/qz/printer/info/MediaSizeHashSet.java b/src/qz/printer/info/MediaSizeHashSet.java deleted file mode 100644 index 38ebff339..000000000 --- a/src/qz/printer/info/MediaSizeHashSet.java +++ /dev/null @@ -1,84 +0,0 @@ -package qz.printer.info; - -import javax.print.attribute.standard.MediaPrintableArea; -import javax.print.attribute.standard.MediaSize; -import javax.print.attribute.standard.MediaSizeName; -import java.util.*; - -/** - * A sortable HashMap for storing printer page sizes for both imperial (inches) and metric (millimeters) - */ -public class MediaSizeHashSet extends HashSet { - public class UnitPair implements Comparable { - private DimensionFloat in; - private DimensionFloat mm; - - public UnitPair(MediaSize mediaSize) { - in = new DimensionFloat(mediaSize.getX(MediaPrintableArea.INCH), mediaSize.getY(MediaPrintableArea.INCH)); - mm = new DimensionFloat(mediaSize.getX(MediaPrintableArea.MM), mediaSize.getY(MediaPrintableArea.MM)); - } - - @Override - public boolean equals(Object o) { - if (this == o) {return true;} - if (o == null || getClass() != o.getClass()) {return false;} - UnitPair that = (UnitPair)o; - return in.width == that.in.width && in.height == that.in.height; - } - - @Override - public int compareTo(Object o) { - if (this == o) {return 0;} - if (o == null || getClass() != o.getClass()) {return -1;} - return Comparator.comparing((UnitPair p)-> p.in.width) - .thenComparing((UnitPair p)-> p.in.height) - .compare(this, (UnitPair)o); - } - - /** - * Get size as DimensionFloat in inches - */ - public DimensionFloat getIn() { - return in; - } - - /** - * Get size as DimensionFloat in millimeters - */ - public DimensionFloat getMm() { - return mm; - } - } - - /** - * Simple dimension container using floats - */ - public class DimensionFloat { - private float width; - private float height; - - public DimensionFloat(float width, float height) { - this.width = width; - this.height = height; - } - - public float getWidth() { - return width; - } - - public float getHeight() { - return height; - } - } - - /** - * Adds an imperial (in) and metric (mm) entry of the specified MediaSizeName - */ - public boolean add(MediaSizeName mediaSizeName) { - MediaSize mediaSize = MediaSize.getMediaSizeForName(mediaSizeName); - if(mediaSize != null) { - return add(new UnitPair(mediaSize)); - } - return false; - } -} From 3539299d8ecfce5b9170eeece525e55aa7be4169 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Sat, 22 Jul 2023 12:11:17 -0400 Subject: [PATCH 5/5] Add sizes to HTML --- css/style.css | 4 ++++ sample.html | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/css/style.css b/css/style.css index 98ebdedd2..b79e0f558 100644 --- a/css/style.css +++ b/css/style.css @@ -381,6 +381,10 @@ button > .fa-caret-down { border-bottom: 1px dashed; } +summary { + cursor: pointer; +} + code { color: #31708F; background-color: #D9EDF7; diff --git a/sample.html b/sample.html index 8b9ccedf3..5727b693b 100755 --- a/sample.html +++ b/sample.html @@ -1608,6 +1608,7 @@

Options

"
  • Density: " + data[i].density + "dpi
  • " + "
  • Connection: " + data[i].connection + "
  • " + (data[i].trays ? "
  • Trays: " + data[i].trays + "
  • " : "") + + accumulateSizes(data[i]) + ""; } @@ -1615,6 +1616,45 @@

    Options

    }).catch(displayError); } + function accumulateSizes(data) { + var html = ""; + if(data.sizes) { + var html = "
  • Sizes: (" + data.sizes.length + ") "; + var sizes = data.sizes; + html += "
      "; + for(var size in sizes) { + html += "
    • " + sizes[size].name + "
        "; + + var inch = sizes[size].in.width + " x " + sizes[size].in.height; + var mill = sizes[size].mm.width + " x " + sizes[size].mm.height; + + var inchTrunc = truncate(sizes[size].in.width, 3) + " x " + truncate(sizes[size].in.height, 3); + var millTrunc = truncate(sizes[size].mm.width, 3) + " x " + truncate(sizes[size].mm.height, 3); + + html += "
      • in: " + inchTrunc + "
      • "; + html += "
      • mm: " + millTrunc + "
      • "; + + html += "
    • "; + } + html += "
  • "; + } + return html; + } + + function truncate(val, length, ellipsis) { + var truncated; + if(isNaN(val)) { + truncated = val.substring(0, length); + } else { + var mult = Math.pow(10, length); + truncated = Math.floor(val * mult) / mult; + } + if(ellipsis === false) { + return truncated; + } + return val === truncated ? val : truncated + "…"; + } + /// Raw Printers /// function printCommand() {