--- old/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java 2016-03-22 16:38:08.000000000 +0530 +++ new/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java 2016-03-22 16:38:08.000000000 +0530 @@ -36,6 +36,7 @@ import javax.print.*; import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.Media; import javax.print.attribute.standard.MediaPrintableArea; import javax.print.attribute.standard.MediaSize; @@ -194,10 +195,39 @@ // setPageRange will set firstPage and lastPage as called in getFirstPage // and getLastPage setPageRange(range[0][0] - 1, range[0][1] - 1); + } else { + // if rangeSelect is SunPageSelection.ALL + // then setPageRange appropriately + setPageRange(-1, -1); } } } + private void setPageRangeAttribute(int from, int to, boolean isRangeSet) { + if (attributes != null) { + // since native Print use zero-based page indices, + // we need to store in 1-based format in attributes set + // but setPageRange again uses zero-based indices so it should be + // 1 less than pageRanges attribute + if (isRangeSet) { + attributes.add(new PageRanges(from+1, to+1)); + attributes.add(SunPageSelection.RANGE); + setPageRange(from, to); + } else { + attributes.add(SunPageSelection.ALL); + } + + } + } + + private void setCopiesAttribute(int copies) { + if (attributes != null) { + attributes.add(new Copies(copies)); + super.setCopies(copies); + } + } + + volatile boolean onEventThread; @Override @@ -606,7 +636,7 @@ page.getImageableHeight()); return pageFormatArea; } - + private boolean cancelCheck() { // This is called from the native side. @@ -653,7 +683,7 @@ Graphics2D delegate = new SunGraphics2D(sd, Color.black, Color.white, defaultFont); Graphics2D pathGraphics = new CPrinterGraphics(delegate, printerJob); // Just stores delegate into an ivar - Rectangle2D pageFormatArea = getPageFormatArea(page); + Rectangle2D pageFormatArea = getPageFormatArea(page); initPrinterGraphics(pathGraphics, pageFormatArea); painter.print(pathGraphics, page, pageIndex); delegate.dispose(); @@ -688,7 +718,7 @@ if (printable != null) { BufferedImage bimg = new BufferedImage((int)Math.round(pageFormat.getWidth()), (int)Math.round(pageFormat.getHeight()), BufferedImage.TYPE_INT_ARGB_PRE); PeekGraphics peekGraphics = createPeekGraphics(bimg.createGraphics(), printerJob); - Rectangle2D pageFormatArea = getPageFormatArea(pageFormat); + Rectangle2D pageFormatArea = getPageFormatArea(pageFormat); initPrinterGraphics(peekGraphics, pageFormatArea); // Do the assignment here! --- old/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m 2016-03-22 16:38:09.000000000 +0530 +++ new/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m 2016-03-22 16:38:09.000000000 +0530 @@ -312,9 +312,9 @@ static void nsPrintInfoToJavaPrinterJob(JNIEnv* env, NSPrintInfo* src, jobject dstPrinterJob, jobject dstPageable) { static JNF_MEMBER_CACHE(jm_setService, sjc_CPrinterJob, "setPrinterServiceFromNative", "(Ljava/lang/String;)V"); - static JNF_MEMBER_CACHE(jm_setCopies, sjc_CPrinterJob, "setCopies", "(I)V"); + static JNF_MEMBER_CACHE(jm_setCopiesAttribute, sjc_CPrinterJob, "setCopiesAttribute", "(I)V"); static JNF_MEMBER_CACHE(jm_setCollated, sjc_CPrinterJob, "setCollated", "(Z)V"); - static JNF_MEMBER_CACHE(jm_setPageRange, sjc_CPrinterJob, "setPageRange", "(II)V"); + static JNF_MEMBER_CACHE(jm_setPageRangeAttribute, sjc_CPrinterJob, "setPageRangeAttribute", "(IIZ)V"); // get the selected printer's name, and set the appropriate PrintService on the Java side NSString *name = [[src printer] name]; @@ -327,7 +327,7 @@ NSNumber* nsCopies = [printingDictionary objectForKey:NSPrintCopies]; if ([nsCopies respondsToSelector:@selector(integerValue)]) { - JNFCallVoidMethod(env, dstPrinterJob, jm_setCopies, [nsCopies integerValue]); // AWT_THREADING Safe (known object) + JNFCallVoidMethod(env, dstPrinterJob, jm_setCopiesAttribute, [nsCopies integerValue]); // AWT_THREADING Safe (known object) } NSNumber* nsCollated = [printingDictionary objectForKey:NSPrintMustCollate]; @@ -340,6 +340,7 @@ if ([nsPrintAllPages respondsToSelector:@selector(boolValue)]) { jint jFirstPage = 0, jLastPage = java_awt_print_Pageable_UNKNOWN_NUMBER_OF_PAGES; + jboolean isRangeSet = false; if (![nsPrintAllPages boolValue]) { NSNumber* nsFirstPage = [printingDictionary objectForKey:NSPrintFirstPage]; @@ -353,9 +354,12 @@ { jLastPage = [nsLastPage integerValue] - 1; } - } + isRangeSet = true; + } + JNFCallVoidMethod(env, dstPrinterJob, jm_setPageRangeAttribute, + jFirstPage, jLastPage, isRangeSet); + // AWT_THREADING Safe (known object) - JNFCallVoidMethod(env, dstPrinterJob, jm_setPageRange, jFirstPage, jLastPage); // AWT_THREADING Safe (known object) } } --- /dev/null 2016-03-22 16:38:10.000000000 +0530 +++ new/test/java/awt/print/PrinterJob/PrintAttributeUpdateTest.java 2016-03-22 16:38:10.000000000 +0530 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 8042713 + @summary Print Dialog does not update attribute set with page range + @run main/manual PrintAttributeUpdateTest + */ +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.print.PageFormat; +import java.awt.print.Pageable; +import java.awt.print.Paper; +import java.awt.print.Printable; +import java.awt.print.PrinterJob; +import javax.print.attribute.Attribute; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.standard.DialogTypeSelection; +import javax.print.attribute.standard.PageRanges; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +public class PrintAttributeUpdateTest implements Pageable, Printable { + + public static void main(String args[]) throws Exception { + String[] instructions = + { + "Select Pages Range From instead of All in print dialog. ", + "Then select Print", + }; + SwingUtilities.invokeAndWait(() -> { + JOptionPane.showMessageDialog((Component)null, + instructions, "Instructions", + JOptionPane.INFORMATION_MESSAGE); + }); + HashPrintRequestAttributeSet as = new HashPrintRequestAttributeSet(); + PrinterJob j = PrinterJob.getPrinterJob(); + j.setPageable(new PrintAttributeUpdateTest()); + as.add(DialogTypeSelection.NATIVE); + j.printDialog(as); + if (as.containsKey(PageRanges.class) == false) { + throw new RuntimeException("Print Dialog did not update attribute set with page range"); + } + Attribute attrs[] = as.toArray(); + for (int i = 0; i < attrs.length; i++) { + System.out.println("attr " + attrs[i]); + } + j.print(as); + } + + public int getNumberOfPages() { + return UNKNOWN_NUMBER_OF_PAGES; + } + + public PageFormat getPageFormat(int pageIndex) { + PageFormat pf = new PageFormat(); + return pf; + } + + public Printable getPrintable(int pageIndex) { + return this; + } + + public int print(Graphics g, PageFormat pgFmt, int pi) { + g.drawString("Page : " + (pi+1), 200, 200); + + return PAGE_EXISTS; + } + +}