8061258: [macosx] PrinterJob's native Print Dialog does not reflect specified Copies or Page Ranges
Reviewed-by: prr, jdv
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m Wed Mar 30 15:26:10 2016 +0530
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m Wed Mar 30 16:00:43 2016 +0530
@@ -368,6 +368,8 @@
static JNF_MEMBER_CACHE(jm_isCollated, sjc_CPrinterJob, "isCollated", "()Z");
static JNF_MEMBER_CACHE(jm_getFromPage, sjc_CPrinterJob, "getFromPageAttrib", "()I");
static JNF_MEMBER_CACHE(jm_getToPage, sjc_CPrinterJob, "getToPageAttrib", "()I");
+ static JNF_MEMBER_CACHE(jm_getMinPage, sjc_CPrinterJob, "getMinPageAttrib", "()I");
+ static JNF_MEMBER_CACHE(jm_getMaxPage, sjc_CPrinterJob, "getMaxPageAttrib", "()I");
static JNF_MEMBER_CACHE(jm_getSelectAttrib, sjc_CPrinterJob, "getSelectAttrib", "()I");
static JNF_MEMBER_CACHE(jm_getNumberOfPages, jc_Pageable, "getNumberOfPages", "()I");
static JNF_MEMBER_CACHE(jm_getPageFormat, sjc_CPrinterJob, "getPageFormatFromAttributes", "()Ljava/awt/print/PageFormat;");
@@ -379,31 +381,33 @@
jboolean collated = JNFCallBooleanMethod(env, srcPrinterJob, jm_isCollated); // AWT_THREADING Safe (known object)
[printingDictionary setObject:[NSNumber numberWithBool:collated ? YES : NO] forKey:NSPrintMustCollate];
- jint jNumPages = JNFCallIntMethod(env, srcPageable, jm_getNumberOfPages); // AWT_THREADING Safe (!appKit)
- if (jNumPages != java_awt_print_Pageable_UNKNOWN_NUMBER_OF_PAGES)
- {
- jint selectID = JNFCallIntMethod(env, srcPrinterJob, jm_getSelectAttrib);
- if (selectID ==0) {
- [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
- } else if (selectID == 2) {
- // In Mac 10.7, Print ALL is deselected if PrintSelection is YES whether
- // NSPrintAllPages is YES or NO
- [printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];
- [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintSelectionOnly];
- } else {
+ jint selectID = JNFCallIntMethod(env, srcPrinterJob, jm_getSelectAttrib);
+ jint fromPage = JNFCallIntMethod(env, srcPrinterJob, jm_getFromPage);
+ jint toPage = JNFCallIntMethod(env, srcPrinterJob, jm_getToPage);
+ if (selectID ==0) {
+ [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
+ } else if (selectID == 2) {
+ // In Mac 10.7, Print ALL is deselected if PrintSelection is YES whether
+ // NSPrintAllPages is YES or NO
+ [printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];
+ [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintSelectionOnly];
+ } else {
+ jint minPage = JNFCallIntMethod(env, srcPrinterJob, jm_getMinPage);
+ jint maxPage = JNFCallIntMethod(env, srcPrinterJob, jm_getMaxPage);
+
+ // for PD_SELECTION or PD_NOSELECTION, check from/to page
+ // to determine which radio button to select
+ if (fromPage > minPage || toPage < maxPage) {
[printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];
+ } else {
+ [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
}
+ }
- jint fromPage = JNFCallIntMethod(env, srcPrinterJob, jm_getFromPage);
- jint toPage = JNFCallIntMethod(env, srcPrinterJob, jm_getToPage);
- // setting fromPage and toPage will not be shown in the dialog if printing All pages
- [printingDictionary setObject:[NSNumber numberWithInteger:fromPage] forKey:NSPrintFirstPage];
- [printingDictionary setObject:[NSNumber numberWithInteger:toPage] forKey:NSPrintLastPage];
- }
- else
- {
- [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
- }
+ // setting fromPage and toPage will not be shown in the dialog if printing All pages
+ [printingDictionary setObject:[NSNumber numberWithInteger:fromPage] forKey:NSPrintFirstPage];
+ [printingDictionary setObject:[NSNumber numberWithInteger:toPage] forKey:NSPrintLastPage];
+
jobject page = JNFCallObjectMethod(env, srcPrinterJob, jm_getPageFormat);
if (page != NULL) {
javaPageFormatToNSPrintInfo(env, NULL, page, dst);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/DlgAttrsBug.java Wed Mar 30 16:00:43 2016 +0530
@@ -0,0 +1,152 @@
+/*
+ * 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 8061258
+ * @summary PrinterJob's native Print Dialog does not reflect
+ * specified Copies or Page Ranges
+ * @run main/manual DlgAttrsBug
+ */
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Graphics;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.standard.Copies;
+import javax.print.attribute.standard.PageRanges;
+import javax.print.attribute.standard.DialogTypeSelection;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+
+public class DlgAttrsBug implements Printable {
+ private static Thread mainThread;
+ private static boolean testPassed;
+ private static boolean testGeneratedInterrupt;
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ doTest(DlgAttrsBug::printTest);
+ });
+ mainThread = Thread.currentThread();
+ try {
+ Thread.sleep(30000);
+ } catch (InterruptedException e) {
+ if (!testPassed && testGeneratedInterrupt) {
+ throw new RuntimeException("Print Dialog does not " +
+ "reflect Copies or Page Ranges");
+ }
+ }
+ if (!testGeneratedInterrupt) {
+ throw new RuntimeException("user has not executed the test");
+ }
+ }
+
+ private static void printTest() {
+ PrinterJob job = PrinterJob.getPrinterJob();
+ if (job.getPrintService() == null) {
+ System.out.println("No printers. Test cannot continue");
+ return;
+ }
+ job.setPrintable(new DlgAttrsBug());
+ PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
+ aset.add(new Copies(5));
+ aset.add(new PageRanges(3,4));
+ aset.add(DialogTypeSelection.NATIVE);
+ job.printDialog(aset);
+ }
+
+ public static synchronized void pass() {
+ testPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ public static synchronized void fail() {
+ testPassed = false;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ private static void doTest(Runnable action) {
+ String description
+ = " Visual inspection of print dialog is required.\n"
+ + " A print dialog will be shown.\n "
+ + " Please verify Copies 5 is selected.\n"
+ + " Also verify, Page Range is selected with "
+ + " from page 3 and to Page 4.\n"
+ + " If ok, press PASS else press FAIL";
+
+ final JDialog dialog = new JDialog();
+ dialog.setTitle("printSelectionTest");
+ JTextArea textArea = new JTextArea(description);
+ textArea.setEditable(false);
+ final JButton testButton = new JButton("Start Test");
+ final JButton passButton = new JButton("PASS");
+ passButton.setEnabled(false);
+ passButton.addActionListener((e) -> {
+ dialog.dispose();
+ pass();
+ });
+ final JButton failButton = new JButton("FAIL");
+ failButton.setEnabled(false);
+ failButton.addActionListener((e) -> {
+ dialog.dispose();
+ fail();
+ });
+ testButton.addActionListener((e) -> {
+ testButton.setEnabled(false);
+ action.run();
+ passButton.setEnabled(true);
+ failButton.setEnabled(true);
+ });
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(textArea, BorderLayout.CENTER);
+ JPanel buttonPanel = new JPanel(new FlowLayout());
+ buttonPanel.add(testButton);
+ buttonPanel.add(passButton);
+ buttonPanel.add(failButton);
+ mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+ dialog.add(mainPanel);
+ dialog.pack();
+ dialog.setVisible(true);
+ }
+
+ public int print(Graphics g, PageFormat pf, int pi)
+ throws PrinterException {
+ System.out.println("pi = " + pi);
+ if (pi >= 5) {
+ return NO_SUCH_PAGE;
+ }
+ g.drawString("Page : " + (pi+1), 200, 200);
+ return PAGE_EXISTS;
+ }
+
+}