diff options
| author | 2013-08-28 00:07:08 +0000 | |
|---|---|---|
| committer | 2013-08-28 00:07:09 +0000 | |
| commit | ca09dbc67b28d5d1d16b7966b855229697c6c549 (patch) | |
| tree | 0ca07ec7add60de57f04f43cb2cfcd9c39d035ac | |
| parent | bbbc8660cdbfb033291f1911742a942a42c85af0 (diff) | |
| parent | aec1417ca9eb63209668ac17da90cf8a07c6076c (diff) | |
Merge "Print APIs update." into klp-dev
| -rw-r--r-- | api/current.txt | 34 | ||||
| -rw-r--r-- | core/java/android/print/PageRange.java | 2 | ||||
| -rw-r--r-- | core/java/android/print/PrintAttributes.java | 60 | ||||
| -rw-r--r-- | core/java/android/print/PrintDocumentAdapter.java | 22 | ||||
| -rw-r--r-- | core/java/android/print/PrintDocumentInfo.java | 255 | ||||
| -rw-r--r-- | core/java/android/print/PrinterCapabilitiesInfo.java | 4 | ||||
| -rw-r--r-- | core/java/android/print/PrinterInfo.java | 29 | ||||
| -rw-r--r-- | core/java/android/print/pdf/PdfDocument.java | 43 | ||||
| -rw-r--r-- | core/java/android/print/pdf/PrintedPdfDocument.java | 162 | ||||
| -rw-r--r-- | packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java | 188 |
10 files changed, 671 insertions, 128 deletions
diff --git a/api/current.txt b/api/current.txt index ca8a7dd2092f..4b66d086b2cb 100644 --- a/api/current.txt +++ b/api/current.txt @@ -19017,6 +19017,7 @@ package android.preference { package android.print { public final class PageRange implements android.os.Parcelable { + ctor public PageRange(int, int); method public int describeContents(); method public int getEnd(); method public int getStart(); @@ -19044,8 +19045,9 @@ package android.print { field public static final int DUPLEX_MODE_LONG_EDGE = 2; // 0x2 field public static final int DUPLEX_MODE_NONE = 1; // 0x1 field public static final int DUPLEX_MODE_SHORT_EDGE = 4; // 0x4 - field public static final int FITTING_MODE_FIT_TO_PAGE = 2; // 0x2 field public static final int FITTING_MODE_NONE = 1; // 0x1 + field public static final int FITTING_MODE_SCALE_TO_FILL = 4; // 0x4 + field public static final int FITTING_MODE_SCALE_TO_FIT = 2; // 0x2 field public static final int ORIENTATION_LANDSCAPE = 2; // 0x2 field public static final int ORIENTATION_PORTRAIT = 1; // 0x1 } @@ -19070,6 +19072,7 @@ package android.print { method public int getLeftMils(); method public int getRightMils(); method public int getTopMils(); + field public static final android.print.PrintAttributes.Margins NO_MARGINS; } public static final class PrintAttributes.MediaSize { @@ -19157,21 +19160,33 @@ package android.print { public final class PrintDocumentInfo implements android.os.Parcelable { method public int describeContents(); + method public int getColorMode(); method public int getContentType(); + method public int getFittingMode(); + method public android.print.PrintAttributes.Margins getMargins(); + method public android.print.PrintAttributes.MediaSize getMediaSize(); method public java.lang.String getName(); + method public int getOrientation(); method public int getPageCount(); method public void writeToParcel(android.os.Parcel, int); field public static final int CONTENT_TYPE_DOCUMENT = 0; // 0x0 field public static final int CONTENT_TYPE_PHOTO = 1; // 0x1 field public static final int CONTENT_TYPE_UNKNOWN = -1; // 0xffffffff field public static final android.os.Parcelable.Creator CREATOR; + field public static final android.print.PrintAttributes.MediaSize MEDIA_SIZE_UNKNOWN; field public static final int PAGE_COUNT_UNKNOWN = -1; // 0xffffffff } public static final class PrintDocumentInfo.Builder { + ctor public PrintDocumentInfo.Builder(java.lang.String, android.print.PrintAttributes); ctor public PrintDocumentInfo.Builder(java.lang.String); method public android.print.PrintDocumentInfo create(); + method public android.print.PrintDocumentInfo.Builder setColorMode(int); method public android.print.PrintDocumentInfo.Builder setContentType(int); + method public android.print.PrintDocumentInfo.Builder setFittingMode(int); + method public android.print.PrintDocumentInfo.Builder setMargins(android.print.PrintAttributes.Margins); + method public android.print.PrintDocumentInfo.Builder setMediaSize(android.print.PrintAttributes.MediaSize); + method public android.print.PrintDocumentInfo.Builder setOrientation(int); method public android.print.PrintDocumentInfo.Builder setPageCount(int); } @@ -19259,7 +19274,9 @@ package android.print { method public int getStatus(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; - field public static final int STATUS_READY = 1; // 0x1 + field public static final int STATUS_BUSY = 2; // 0x2 + field public static final int STATUS_IDLE = 1; // 0x1 + field public static final int STATUS_UNAVAILABLE = 3; // 0x3 } public static final class PrinterInfo.Builder { @@ -19269,6 +19286,7 @@ package android.print { method public android.print.PrinterInfo.Builder setCapabilities(android.print.PrinterCapabilitiesInfo); method public android.print.PrinterInfo.Builder setDescription(java.lang.String); method public android.print.PrinterInfo.Builder setName(java.lang.String); + method public android.print.PrinterInfo.Builder setStatus(int); } } @@ -19291,19 +19309,27 @@ package android.print.pdf { public static final class PdfDocument.PageInfo { method public android.graphics.Rect getContentSize(); - method public int getDesity(); method public android.graphics.Matrix getInitialTransform(); method public int getPageNumber(); method public android.graphics.Rect getPageSize(); } public static final class PdfDocument.PageInfo.Builder { - ctor public PdfDocument.PageInfo.Builder(android.graphics.Rect, int, int); + ctor public PdfDocument.PageInfo.Builder(android.graphics.Rect, int); method public android.print.pdf.PdfDocument.PageInfo create(); method public android.print.pdf.PdfDocument.PageInfo.Builder setContentSize(android.graphics.Rect); method public android.print.pdf.PdfDocument.PageInfo.Builder setInitialTransform(android.graphics.Matrix); } + public final class PrintedPdfDocument { + method public void close(); + method public void finishPage(android.print.pdf.PdfDocument.Page); + method public java.util.List<android.print.pdf.PdfDocument.PageInfo> getPages(); + method public static android.print.pdf.PrintedPdfDocument open(android.content.Context, android.print.PrintAttributes); + method public android.print.pdf.PdfDocument.Page startPage(int); + method public void writeTo(java.io.OutputStream); + } + } package android.printservice { diff --git a/core/java/android/print/PageRange.java b/core/java/android/print/PageRange.java index ba455f622810..cdcd0c7d2e6a 100644 --- a/core/java/android/print/PageRange.java +++ b/core/java/android/print/PageRange.java @@ -42,8 +42,6 @@ public final class PageRange implements Parcelable { * @throws IllegalArgumentException If start is less than zero. * @throws IllegalArgumentException If end is less than zero. * @throws IllegalArgumentException If start greater than end. - * - * @hide */ public PageRange(int start, int end) { if (start < 0) { diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java index a902c7204bbd..caa10aee03b0 100644 --- a/core/java/android/print/PrintAttributes.java +++ b/core/java/android/print/PrintAttributes.java @@ -50,9 +50,15 @@ public final class PrintAttributes implements Parcelable { /** Fitting mode: No fitting. */ - public static final int FITTING_MODE_NONE = 0x00000001; - /** Fitting mode: Fit the content to the page. */ - public static final int FITTING_MODE_FIT_TO_PAGE = 0x00000002; + public static final int FITTING_MODE_NONE = 1 << 0; + /** Fitting mode: Scale the content to fit in the page + * without cropping it in any dimension. */ + public static final int FITTING_MODE_SCALE_TO_FIT = 1 << 1; + /** + * Fitting mode: Uniformly scale the content to fill the entire page + * potentially cropping the content if it overflows in one dimension. + */ + public static final int FITTING_MODE_SCALE_TO_FILL = 1 << 2; private static final int VALID_DUPLEX_MODES = @@ -62,7 +68,7 @@ public final class PrintAttributes implements Parcelable { COLOR_MODE_MONOCHROME | COLOR_MODE_COLOR; private static final int VALID_FITTING_MODES = - FITTING_MODE_NONE | FITTING_MODE_FIT_TO_PAGE; + FITTING_MODE_NONE | FITTING_MODE_SCALE_TO_FIT | FITTING_MODE_SCALE_TO_FILL; private static final int VALID_ORIENTATIONS = ORIENTATION_PORTRAIT | ORIENTATION_LANDSCAPE; @@ -252,7 +258,8 @@ public final class PrintAttributes implements Parcelable { * @return The fitting mode or zero if not set. * * @see #FITTING_MODE_NONE - * @see #FITTING_MODE_FIT_TO_PAGE + * @see #FITTING_MODE_SCALE_TO_FILL + * @see #FITTING_MODE_SCALE_TO_FIT */ public int getFittingMode() { return mFittingMode; @@ -264,12 +271,13 @@ public final class PrintAttributes implements Parcelable { * @param The fitting mode. * * @see #FITTING_MODE_NONE - * @see #FITTING_MODE_FIT_TO_PAGE + * @see #FITTING_MODE_SCALE_TO_FILL + * @see #FITTING_MODE_SCALE_TO_FIT * * @hide */ public void setFittingMode(int fittingMode) { - enfoceValidFittingMode(fittingMode); + enforceValidFittingMode(fittingMode); mFittingMode = fittingMode; } @@ -1220,6 +1228,8 @@ public final class PrintAttributes implements Parcelable { * This class specifies content margins. */ public static final class Margins { + public static final Margins NO_MARGINS = new Margins(0, 0, 0, 0); + private final int mLeftMils; private final int mTopMils; private final int mRightMils; @@ -1232,24 +1242,13 @@ public final class PrintAttributes implements Parcelable { * @param topMils The top margin in mils (thousands of an inch). * @param rightMils The right margin in mils (thousands of an inch). * @param bottomMils The bottom margin in mils (thousands of an inch). - * - * @throws IllegalArgumentException If the leftMils is less than zero. - * @throws IllegalArgumentException If the topMils is less than zero. - * @throws IllegalArgumentException If the rightMils is less than zero. - * @throws IllegalArgumentException If the bottomMils is less than zero. */ public Margins(int leftMils, int topMils, int rightMils, int bottomMils) { - if (leftMils < 0) { - throw new IllegalArgumentException("leftMils cannot be less than zero."); + if (leftMils > rightMils) { + throw new IllegalArgumentException("leftMils cannot be less than rightMils."); } - if (topMils < 0) { - throw new IllegalArgumentException("topMils cannot be less than zero."); - } - if (rightMils < 0) { - throw new IllegalArgumentException("rightMils cannot be less than zero."); - } - if (bottomMils < 0) { - throw new IllegalArgumentException("bottomMils cannot be less than zero."); + if (topMils > bottomMils) { + throw new IllegalArgumentException("topMils cannot be less than bottomMils."); } mTopMils = topMils; mLeftMils = leftMils; @@ -1504,8 +1503,11 @@ public final class PrintAttributes implements Parcelable { case FITTING_MODE_NONE: { return "FITTING_MODE_NONE"; } - case FITTING_MODE_FIT_TO_PAGE: { - return "FITTING_MODE_FIT_TO_PAGE"; + case FITTING_MODE_SCALE_TO_FIT: { + return "FITTING_MODE_SCALE_TO_FIT"; + } + case FITTING_MODE_SCALE_TO_FILL: { + return "FITTING_MODE_SCALE_TO_FILL"; } default: return "FITTING_MODE_UNKNOWN"; @@ -1513,25 +1515,25 @@ public final class PrintAttributes implements Parcelable { } static void enforceValidDuplexMode(int duplexMode) { - if ((duplexMode & VALID_DUPLEX_MODES) == 0) { + if ((duplexMode & VALID_DUPLEX_MODES) == 0 && Integer.bitCount(duplexMode) == 1) { throw new IllegalArgumentException("invalid duplex mode: " + duplexMode); } } static void enforceValidColorMode(int colorMode) { - if ((colorMode & VALID_COLOR_MODES) == 0) { + if ((colorMode & VALID_COLOR_MODES) == 0 && Integer.bitCount(colorMode) == 1) { throw new IllegalArgumentException("invalid color mode: " + colorMode); } } - static void enfoceValidFittingMode(int fittingMode) { - if ((fittingMode & VALID_FITTING_MODES) == 0) { + static void enforceValidFittingMode(int fittingMode) { + if ((fittingMode & VALID_FITTING_MODES) == 0 && Integer.bitCount(fittingMode) == 1) { throw new IllegalArgumentException("invalid fitting mode: " + fittingMode); } } static void enforceValidOrientation(int orientation) { - if ((orientation & VALID_ORIENTATIONS) == 0) { + if ((orientation & VALID_ORIENTATIONS) == 0 && Integer.bitCount(orientation) == 1) { throw new IllegalArgumentException("invalid orientation: " + orientation); } } diff --git a/core/java/android/print/PrintDocumentAdapter.java b/core/java/android/print/PrintDocumentAdapter.java index d3202262bbd5..8a64e85cd07d 100644 --- a/core/java/android/print/PrintDocumentAdapter.java +++ b/core/java/android/print/PrintDocumentAdapter.java @@ -101,6 +101,28 @@ public abstract class PrintDocumentAdapter { * LayoutResultCallback#onLayoutFailed(CharSequence)}, if an error occurred. * </p> * <p> + * When doing a layout you may satisfy some of the constraints in the print + * attributes such as applying the appropriate fitting, emitting content in the + * requested orientation, using the specified margins, generating content with + * the desired color mode, producing output with the given media size. Ideally, + * you will satisfy all of these constraints. It is important that if you + * satisfy a given constraint, you update the {@link PrintDocumentInfo} that + * is returned in the given {@link LayoutResultCallback}. This way the printer + * will have more accurate information about the content, thus producing a + * better output. For example, assume that your application is printing + * an image and the print attributes request landscape and fitting mode scale + * to fill. The result of this operation should be the entire media is filled + * and the content is rotated ninety degrees. In this case it is beneficial + * you do the rotation and select a higher resolution image to utilize + * the wider media (the height is now the width), rather to use a lower + * resolution image that is later stretched by the printer. If you applied + * the rotation you have to update the returned print document info to + * reflect that the content is already in landscape by calling + * {@link PrintDocumentInfo.Builder#setOrientation(int)} with {@link + * PrintAttributes#ORIENTATION_LANDSCAPE}. In this case the printer does not + * have to rotate the content. + * </p> + * <p> * <strong>Note:</strong> If the content is large and a layout will be * performed, it is a good practice to schedule the work on a dedicated * thread and register an observer in the provided {@link diff --git a/core/java/android/print/PrintDocumentInfo.java b/core/java/android/print/PrintDocumentInfo.java index 653ad4bfc4e4..b32961b641cf 100644 --- a/core/java/android/print/PrintDocumentInfo.java +++ b/core/java/android/print/PrintDocumentInfo.java @@ -18,6 +18,8 @@ package android.print; import android.os.Parcel; import android.os.Parcelable; +import android.print.PrintAttributes.Margins; +import android.print.PrintAttributes.MediaSize; import android.text.TextUtils; /** @@ -26,12 +28,17 @@ import android.text.TextUtils; public final class PrintDocumentInfo implements Parcelable { /** - * Constant for unknown page count (default). + * Constant for an unknown media size. + */ + public static final MediaSize MEDIA_SIZE_UNKNOWN = new MediaSize("Unknown", "Unknown", 1, 1); + + /** + * Constant for unknown page count.. */ public static final int PAGE_COUNT_UNKNOWN = -1; /** - * Content type: unknown (default). + * Content type: unknown. */ public static final int CONTENT_TYPE_UNKNOWN = -1; @@ -48,13 +55,17 @@ public final class PrintDocumentInfo implements Parcelable { private String mName; private int mPageCount; private int mContentType; + private int mOrientation; + private int mFittingMode; + private int mColorMode; + private Margins mMargins; + private MediaSize mMediaSize; /** * Creates a new instance. */ private PrintDocumentInfo() { - mPageCount = PAGE_COUNT_UNKNOWN; - mContentType = CONTENT_TYPE_UNKNOWN; + /* do nothing */ } /** @@ -66,6 +77,11 @@ public final class PrintDocumentInfo implements Parcelable { mName = prototype.mName; mPageCount = prototype.mPageCount; mContentType = prototype.mContentType; + mOrientation = prototype.mOrientation; + mFittingMode = prototype.mFittingMode; + mColorMode = prototype.mColorMode; + mMargins = prototype.mMargins; + mMediaSize = prototype.mMediaSize; } /** @@ -77,6 +93,11 @@ public final class PrintDocumentInfo implements Parcelable { mName = parcel.readString(); mPageCount = parcel.readInt(); mContentType = parcel.readInt(); + mOrientation = parcel.readInt(); + mFittingMode = parcel.readInt(); + mColorMode = parcel.readInt(); + mMargins = Margins.createFromParcel(parcel); + mMediaSize = MediaSize.createFromParcel(parcel); } /** @@ -112,6 +133,61 @@ public final class PrintDocumentInfo implements Parcelable { return mContentType; } + /** + * Gets the document orientation. + * + * @return The orientation. + * + * @see PrintAttributes#ORIENTATION_PORTRAIT PrintAttributes.ORIENTATION_PORTRAIT + * @see PrintAttributes#ORIENTATION_LANDSCAPE PrintAttributes.ORIENTATION_LANDSCAPE + */ + public int getOrientation() { + return mOrientation; + } + + /** + * Gets the document fitting mode. + * + * @return The fitting mode. + * + * @see PrintAttributes#FITTING_MODE_NONE PrintAttributes.FITTING_MODE_NONE + * @see PrintAttributes#FITTING_MODE_SCALE_TO_FILL PrintAttributes.FITTING_MODE_SCALE_TO_FILL + * @see PrintAttributes#FITTING_MODE_SCALE_TO_FIT PrintAttributes.FITTING_MODE_SCALE_TO_FIT + */ + public int getFittingMode() { + return mFittingMode; + } + + /** + * Gets document color mode. + * + * @return The color mode. + * + * @see PrintAttributes#COLOR_MODE_COLOR PrintAttributes.COLOR_MODE_COLOR + * @see PrintAttributes#COLOR_MODE_MONOCHROME PrintAttributes.COLOR_MODE_MONOCHROME + */ + public int getColorMode() { + return mColorMode; + } + + /** + * Gets the document margins. + * + * @return The margins. + */ + public Margins getMargins() { + return mMargins; + } + + /** + * Gets the media size. + * + * @return The media size. + */ + public MediaSize getMediaSize() { + return mMediaSize; + } + @Override public int describeContents() { return 0; @@ -122,6 +198,11 @@ public final class PrintDocumentInfo implements Parcelable { parcel.writeString(mName); parcel.writeInt(mPageCount); parcel.writeInt(mContentType); + parcel.writeInt(mOrientation); + parcel.writeInt(mFittingMode); + parcel.writeInt(mColorMode); + mMargins.writeToParcel(parcel); + mMediaSize.writeToParcel(parcel); } @Override @@ -131,6 +212,11 @@ public final class PrintDocumentInfo implements Parcelable { result = prime * result + ((mName != null) ? mName.hashCode() : 0); result = prime * result + mContentType; result = prime * result + mPageCount; + result = prime * result + mOrientation; + result = prime * result + mFittingMode; + result = prime * result + mColorMode; + result = prime * result + (mMargins != null ? mMargins.hashCode() : 0); + result = prime * result + (mMediaSize != null ? mMediaSize.hashCode() : 0); return result; } @@ -155,6 +241,29 @@ public final class PrintDocumentInfo implements Parcelable { if (mPageCount != other.mPageCount) { return false; } + if (mOrientation != other.mOrientation) { + return false; + } + if (mFittingMode != other.mFittingMode) { + return false; + } + if (mColorMode != other.mColorMode) { + return false; + } + if (mMargins == null) { + if (other.mMargins != null) { + return false; + } + } else if (!mMargins.equals(other.mMargins)) { + return false; + } + if (mMediaSize == null) { + if (other.mMediaSize != null) { + return false; + } + } else if (!mMediaSize.equals(other.mMediaSize)) { + return false; + } return true; } @@ -165,6 +274,11 @@ public final class PrintDocumentInfo implements Parcelable { builder.append("name=").append(mName); builder.append(", pageCount=").append(mPageCount); builder.append(", contentType=").append(contentTyepToString(mContentType)); + builder.append(", orientation=").append(PrintAttributes.orientationToString(mOrientation)); + builder.append(", fittingMode=").append(PrintAttributes.fittingModeToString(mFittingMode)); + builder.append(", colorMode=").append(PrintAttributes.colorModeToString(mColorMode)); + builder.append(", margins=").append(mMargins); + builder.append(", mediaSize=").append(mMediaSize); builder.append("}"); return builder.toString(); } @@ -191,21 +305,62 @@ public final class PrintDocumentInfo implements Parcelable { /** * Constructor. + * <p> + * The values of the relevant properties are initialized from the + * provided print attributes. For example, the orientation is set + * to be the same as the orientation returned by calling {@link + * PrintAttributes#getOrientation() PrintAttributes.getOrientation()}. + * </p> * * @param name The document name. Cannot be empty. + * @param attributes Print attributes. Cannot be null. * * @throws IllegalArgumentException If the name is empty. */ + public Builder(String name, PrintAttributes attributes) { + if (TextUtils.isEmpty(name)) { + throw new IllegalArgumentException("name cannot be empty"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes cannot be null"); + } + mPrototype = new PrintDocumentInfo(); + mPrototype.mName = name; + mPrototype.mOrientation = attributes.getOrientation(); + mPrototype.mFittingMode = attributes.getFittingMode(); + mPrototype.mColorMode = attributes.getColorMode(); + mPrototype.mMargins = attributes.getMargins(); + mPrototype.mMediaSize = attributes.getMediaSize(); + } + + /** + * Constructor. + * <p> + * The values of the relevant properties are initialized with default + * values. Please refer to the documentation of the individual setters + * for information about the default values. + * </p> + * + * @param name The document name. Cannot be empty. + */ public Builder(String name) { if (TextUtils.isEmpty(name)) { throw new IllegalArgumentException("name cannot be empty"); } mPrototype = new PrintDocumentInfo(); mPrototype.mName = name; + mPrototype.mOrientation = PrintAttributes.ORIENTATION_PORTRAIT; + mPrototype.mFittingMode = PrintAttributes.FITTING_MODE_NONE; + mPrototype.mColorMode = PrintAttributes.COLOR_MODE_COLOR; + mPrototype.mMargins = Margins.NO_MARGINS; + mPrototype.mMediaSize = MEDIA_SIZE_UNKNOWN; } /** * Sets the total number of pages. + * <p> + * <strong>Default: </strong> {@link #PAGE_COUNT_UNKNOWN} + * </p> * * @param pageCount The number of pages. Must be greater than * or equal to zero or {@link PrintDocumentInfo#PAGE_COUNT_UNKNOWN}. @@ -222,6 +377,9 @@ public final class PrintDocumentInfo implements Parcelable { /** * Sets the content type. + * <p> + * <strong>Default: </strong> {@link #CONTENT_TYPE_UNKNOWN} + * </p> * * @param type The content type. * @@ -235,6 +393,95 @@ public final class PrintDocumentInfo implements Parcelable { } /** + * Sets the orientation. + * <p> + * <strong>Default: </strong> {@link PrintAttributes#ORIENTATION_PORTRAIT + * PrintAttributes.ORIENTATION_PORTRAIT} + * </p> + * + * @param orientation The orientation. + * + * @see PrintAttributes#ORIENTATION_PORTRAIT PrintAttributes.ORIENTATION_PORTRAIT + * @see PrintAttributes#ORIENTATION_LANDSCAPE PrintAttributes.ORIENTATION_LANDSCAPE + */ + public Builder setOrientation(int orientation) { + PrintAttributes.enforceValidOrientation(orientation); + mPrototype.mOrientation = orientation; + return this; + } + + /** + * Sets the content fitting mode. + * <p> + * <strong>Default: </strong> {@link PrintAttributes#FITTING_MODE_NONE + * PrintAttributes.FITTING_MODE_NONE} + * </p> + * + * @param fittingMode The fitting mode. + * + * @see PrintAttributes#FITTING_MODE_NONE PrintAttributes.FITTING_MODE_NONE + * @see PrintAttributes#FITTING_MODE_SCALE_TO_FILL PrintAttributes.FITTING_MODE_SCALE_TO_FILL + * @see PrintAttributes#FITTING_MODE_SCALE_TO_FIT PrintAttributes.FITTING_MODE_SCALE_TO_FIT + */ + public Builder setFittingMode(int fittingMode) { + PrintAttributes.enforceValidFittingMode(fittingMode); + mPrototype.mFittingMode = fittingMode; + return this; + } + + /** + * Sets the content color mode. + * <p> + * <strong>Default: </strong> {@link PrintAttributes#COLOR_MODE_COLOR + * PrintAttributes.COLOR_MODE_COLOR} + * </p> + * + * @param colorMode The color mode. + * + * @see PrintAttributes#COLOR_MODE_COLOR PrintAttributes.COLOR_MODE_COLOR + * @see PrintAttributes#COLOR_MODE_MONOCHROME PrintAttributes.COLOR_MODE_MONOCHROME + */ + public Builder setColorMode(int colorMode) { + PrintAttributes.enforceValidColorMode(colorMode); + mPrototype.mColorMode = colorMode; + return this; + } + + /** + * Sets the document margins. + * <p> + * <strong>Default: </strong> {@link PrintAttributes.Margins#NO_MARGINS Margins.NO_MARGINS} + * </p> + * + * @param margins The margins. Cannot be null. + */ + public Builder setMargins(Margins margins) { + if (margins == null) { + throw new IllegalArgumentException("margins cannot be null"); + } + mPrototype.mMargins = margins; + return this; + } + + /** + * Sets the document media size. + * <p> + * <strong>Default: </strong>#MEDIA_SIZE_UNKNOWN + * </p> + * + * @param mediaSize The media size. Cannot be null. + * + * @see #MEDIA_SIZE_UNKNOWN + */ + public Builder setMediaSize(MediaSize mediaSize) { + if (mediaSize == null) { + throw new IllegalArgumentException("media size cannot be null"); + } + mPrototype.mMediaSize = mediaSize; + return this; + } + + /** * Creates a new {@link PrintDocumentInfo} instance. * * @return The new instance. diff --git a/core/java/android/print/PrinterCapabilitiesInfo.java b/core/java/android/print/PrinterCapabilitiesInfo.java index 70b418c2a145..941e6e1f7d2c 100644 --- a/core/java/android/print/PrinterCapabilitiesInfo.java +++ b/core/java/android/print/PrinterCapabilitiesInfo.java @@ -863,12 +863,12 @@ public final class PrinterCapabilitiesInfo implements Parcelable { while (currentModes > 0) { final int currentMode = (1 << Integer.numberOfTrailingZeros(currentModes)); currentModes &= ~currentMode; - PrintAttributes.enfoceValidFittingMode(currentMode); + PrintAttributes.enforceValidFittingMode(currentMode); } if ((fittingModes & defaultFittingMode) == 0) { throw new IllegalArgumentException("Default fitting mode not in fiting modes."); } - PrintAttributes.enfoceValidFittingMode(defaultFittingMode); + PrintAttributes.enforceValidFittingMode(defaultFittingMode); mPrototype.mFittingModes = fittingModes; mPrototype.mDefaults[PROPERTY_FITTING_MODE] = defaultFittingMode; return this; diff --git a/core/java/android/print/PrinterInfo.java b/core/java/android/print/PrinterInfo.java index 6f567a64d709..0ea319be8b1d 100644 --- a/core/java/android/print/PrinterInfo.java +++ b/core/java/android/print/PrinterInfo.java @@ -25,10 +25,14 @@ import android.text.TextUtils; */ public final class PrinterInfo implements Parcelable { - /** Printer status: the printer is ready to print. */ - public static final int STATUS_READY = 1; + /** Printer status: the printer is idle and ready to print. */ + public static final int STATUS_IDLE = 1; - // TODO: Add printer status constants. + /** Printer status: the printer is busy printing. */ + public static final int STATUS_BUSY = 2; + + /** Printer status: the printer is not available. */ + public static final int STATUS_UNAVAILABLE = 3; private PrinterId mId; @@ -237,6 +241,21 @@ public final class PrinterInfo implements Parcelable { } /** + * Sets the printer status. + * + * @param status The status. + * @return This builder. + * + * @see PrinterInfo#STATUS_IDLE + * @see PrinterInfo#STATUS_BUSY + * @see PrinterInfo#STATUS_UNAVAILABLE + */ + public Builder setStatus(int status) { + mPrototype.mStatus = status; + return this; + } + + /** * Sets the printer name. * * @param name The name. @@ -279,7 +298,9 @@ public final class PrinterInfo implements Parcelable { } private boolean isValidStatus(int status) { - return (status == PrinterInfo.STATUS_READY); + return (status == STATUS_IDLE + || status == STATUS_IDLE + || status == STATUS_UNAVAILABLE); } } diff --git a/core/java/android/print/pdf/PdfDocument.java b/core/java/android/print/pdf/PdfDocument.java index dbd7dd1448c5..a2883cf83e3a 100644 --- a/core/java/android/print/pdf/PdfDocument.java +++ b/core/java/android/print/pdf/PdfDocument.java @@ -44,7 +44,7 @@ import java.util.List; * PdfDocument document = PdfDocument.open(); * * // crate a page description - * PageInfo pageInfo = new PageInfo.Builder(new Rect(0, 0, 100, 100), 1, 300).create(); + * PageInfo pageInfo = new PageInfo.Builder(new Rect(0, 0, 100, 100), 1).create(); * * // start a page * Page page = document.startPage(pageInfo); @@ -125,8 +125,7 @@ public final class PdfDocument { throw new IllegalStateException("Previous page not finished!"); } Canvas canvas = new PdfCanvas(nativeCreatePage(pageInfo.mPageSize, - pageInfo.mContentSize, pageInfo.mInitialTransform.native_instance), - pageInfo.mDensity); + pageInfo.mContentSize, pageInfo.mInitialTransform.native_instance)); mCurrentPage = new Page(canvas, pageInfo); return mCurrentPage; } @@ -230,25 +229,14 @@ public final class PdfDocument { private final class PdfCanvas extends Canvas { - public PdfCanvas(int nativeCanvas, int density) { + public PdfCanvas(int nativeCanvas) { super(nativeCanvas); - super.setDensity(density); } @Override public void setBitmap(Bitmap bitmap) { throw new UnsupportedOperationException(); } - - @Override - public void setDensity(int density) { - throw new UnsupportedOperationException(); - } - - @Override - public void setScreenDensity(int density) { - throw new UnsupportedOperationException(); - } } /** @@ -259,7 +247,6 @@ public final class PdfDocument { private Rect mContentSize; private Matrix mInitialTransform; private int mPageNumber; - private int mDensity; /** * Creates a new instance. @@ -269,7 +256,7 @@ public final class PdfDocument { } /** - * Gets the page size in pixels. + * Gets the page size in PostScript points (1/72th of an inch). * * @return The page size. */ @@ -278,7 +265,7 @@ public final class PdfDocument { } /** - * Get the content size in pixels. + * Get the content size in PostScript points (1/72th of an inch). * * @return The content size. */ @@ -307,15 +294,6 @@ public final class PdfDocument { } /** - * Gets the density of the page in DPI. - * - * @return The density. - */ - public int getDesity() { - return mDensity; - } - - /** * Builder for creating a {@link PageInfo}. */ public static final class Builder { @@ -324,11 +302,10 @@ public final class PdfDocument { /** * Creates a new builder with the mandatory page info attributes. * - * @param pageSize The page size in points, <strong>not</strong> dips. + * @param pageSize The page size in PostScript (1/72th of an inch). * @param pageNumber The page number. - * @param density The page density in DPI. */ - public Builder(Rect pageSize, int pageNumber, int density) { + public Builder(Rect pageSize, int pageNumber) { if (pageSize.width() == 0 || pageSize.height() == 0) { throw new IllegalArgumentException("page width and height" + " must be greater than zero!"); @@ -336,16 +313,12 @@ public final class PdfDocument { if (pageNumber < 0) { throw new IllegalArgumentException("pageNumber cannot be less than zero!"); } - if (density <= 0) { - throw new IllegalArgumentException("density must be greater than zero!"); - } mPageInfo.mPageSize = pageSize; mPageInfo.mPageNumber = pageNumber; - mPageInfo.mDensity = density; } /** - * Sets the content size in pixels. + * Sets the content size in PostScript point (1/72th of an inch). * * @param contentSize The content size. */ diff --git a/core/java/android/print/pdf/PrintedPdfDocument.java b/core/java/android/print/pdf/PrintedPdfDocument.java new file mode 100644 index 000000000000..a3be38bb1f71 --- /dev/null +++ b/core/java/android/print/pdf/PrintedPdfDocument.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.print.pdf; + +import android.content.Context; +import android.graphics.Rect; +import android.print.PrintAttributes; +import android.print.PrintAttributes.Margins; +import android.print.PrintAttributes.MediaSize; +import android.print.pdf.PdfDocument; +import android.print.pdf.PdfDocument.Page; +import android.print.pdf.PdfDocument.PageInfo; + +import java.io.OutputStream; +import java.util.List; + +/** + * This class is a helper for printing content to a different media + * size. This class is responsible for computing a correct page size + * given some print constraints, i.e. {@link PrintAttributes}. It is + * an adapter around a {@link PdfDocument}. + */ +public final class PrintedPdfDocument { + private static final int MILS_PER_INCH = 1000; + private static final int POINTS_IN_INCH = 72; + + private final PdfDocument mDocument = PdfDocument.open(); + private final Rect mPageSize = new Rect(); + private final Rect mContentSize = new Rect(); + + /** + * Opens a new document. The document pages are computed based on + * the passes in {@link PrintAttributes}. + * <p> + * <strong>Note:</strong> You must close the document after you are + * done by calling {@link #close()} + * </p> + * + * @param context Context instance for accessing resources. + * @param attributes The print attributes. + * @return The document. + * + * @see #close() + */ + public static PrintedPdfDocument open(Context context, PrintAttributes attributes) { + return new PrintedPdfDocument(context, attributes); + } + + /** + * Creates a new instance. + * + * @param context Context instance for accessing resources and services. + * @param attributes The {@link PrintAttributes} to user. + */ + private PrintedPdfDocument(Context context, PrintAttributes attributes) { + MediaSize mediaSize = attributes.getMediaSize(); + + // Compute the size of the target canvas from the attributes. + final int pageWidth = (int) (((float) mediaSize.getWidthMils() / MILS_PER_INCH) + * POINTS_IN_INCH); + final int pageHeight = (int) (((float) mediaSize.getHeightMils() / MILS_PER_INCH) + * POINTS_IN_INCH); + mPageSize.set(0, 0, pageWidth, pageHeight); + + // Compute the content size from the attributes. + Margins margins = attributes.getMargins(); + final int marginLeft = (int) (((float) margins.getLeftMils() /MILS_PER_INCH) + * POINTS_IN_INCH); + final int marginTop = (int) (((float) margins.getTopMils() / MILS_PER_INCH) + * POINTS_IN_INCH); + final int marginRight = (int) (((float) margins.getRightMils() / MILS_PER_INCH) + * POINTS_IN_INCH); + final int marginBottom = (int) (((float) margins.getBottomMils() / MILS_PER_INCH) + * POINTS_IN_INCH); + mContentSize.set(mPageSize.left + marginLeft, mPageSize.top + marginTop, + mPageSize.right - marginRight, mPageSize.bottom - marginBottom); + } + + /** + * Starts a page using a page size computed from the print attributes + * passed in {@link #open(Context, PrintAttributes)} and the given page + * number to create appropriate {@link PageInfo}. + * <p> + * After the page is created you can draw arbitrary content on the page's + * canvas which you can get by calling {@link Page#getCanvas() Page.getCanvas()}. + * After you are done drawing the content you should finish the page by calling + * {@link #finishPage(Page)}. After the page is finished you should no longer + * access the page or its canvas. + * </p> + * <p> + * <strong>Note:</strong> Do not call this method after {@link #close()}. + * </p> + * + * @param pageNumber The page number. + * @return A blank page. + * + * @see #finishPage(Page) + */ + public Page startPage(int pageNumber) { + PageInfo pageInfo = new PageInfo.Builder(mPageSize, 0).create(); + Page page = mDocument.startPage(pageInfo); + return page; + } + + /** + * Finishes a started page. You should always finish the last started page. + * <p> + * <strong>Note:</strong> Do not call this method after {@link #close()}. + * </p> + * + * @param page The page. + * + * @see #startPage(int) + */ + public void finishPage(Page page) { + mDocument.finishPage(page); + } + + /** + * Writes the document to an output stream. + * <p> + * <strong>Note:</strong> Do not call this method after {@link #close()}. + * </p> + * + * @param out The output stream. + */ + public void writeTo(OutputStream out) { + mDocument.writeTo(out); + } + + /** + * Gets the pages of the document. + * + * @return The pages. + */ + public List<PageInfo> getPages() { + return mDocument.getPages(); + } + + /** + * Closes this document. This method should be called after you + * are done working with the document. After this call the document + * is considered closed and none of its methods should be called. + */ + public void close() { + mDocument.close(); + } +} diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java index c01d8f83190f..607be9050bbd 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java @@ -42,6 +42,7 @@ import android.print.IPrintDocumentAdapter; import android.print.IWriteResultCallback; import android.print.PageRange; import android.print.PrintAttributes; +import android.print.PrintAttributes.Margins; import android.print.PrintAttributes.MediaSize; import android.print.PrintAttributes.Resolution; import android.print.PrintDocumentAdapter; @@ -388,14 +389,20 @@ public class PrintJobConfigActivity extends Activity { final boolean infoChanged = !info.equals(mDocument.info); if (infoChanged) { mDocument.info = info; + // Set the info. PrintSpoolerService.peekInstance().setPrintJobPrintDocumentInfoNoPersistence( mPrintJobId, info); } + // Update the fitting mode based on the document type. + updateCurrentFittingMode(info); + // If the document info or the layout changed, then // drop the pages since we have to fetch them again. if (infoChanged || layoutChanged) { mDocument.pages = null; + PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence( + mPrintJobId, null); } // No pages means that the user selected an invalid range while we @@ -489,7 +496,7 @@ public class PrintJobConfigActivity extends Activity { } else if (PageRangeUtils.contains(mDocument.pages, mRequestedPages)) { // We requested specific pages and got more but not all pages. // Hence, we have to offset appropriately the printed pages to - // excle the pages we did not request. Note that pages is + // exclude the pages we did not request. Note that pages is // guaranteed to be not null and not empty. final int offset = mDocument.pages[0].getStart() - pages[0].getStart(); PageRange[] offsetPages = Arrays.copyOf(mDocument.pages, mDocument.pages.length); @@ -514,6 +521,10 @@ public class PrintJobConfigActivity extends Activity { } if (mEditor.isDone()) { + // Update the print attributes based on whether the application + // handled some of the print attribute constraints, e.g. rotation. + updateAndSaveCurrentPrintAttributes(mDocument.info); + if (mEditor.isPrintingToPdf()) { PrintJobInfo printJob = PrintSpoolerService.peekInstance() .getPrintJobInfo(mPrintJobId, PrintManager.APP_ID_ANY); @@ -536,6 +547,58 @@ public class PrintJobConfigActivity extends Activity { PrintJobConfigActivity.this.finish(); } + private void updateCurrentFittingMode(PrintDocumentInfo document) { + // Update the fitting mode based on content type. + switch (document.getContentType()) { + case PrintDocumentInfo.CONTENT_TYPE_DOCUMENT: { + mCurrPrintAttributes.setFittingMode( + PrintAttributes.FITTING_MODE_SCALE_TO_FIT); + } break; + + case PrintDocumentInfo.CONTENT_TYPE_PHOTO: { + mCurrPrintAttributes.setFittingMode( + PrintAttributes.FITTING_MODE_SCALE_TO_FILL); + } + } + } + + private void updateAndSaveCurrentPrintAttributes(PrintDocumentInfo document) { + PrintAttributes attributes = mTempPrintAttributes; + attributes.copyFrom(mCurrPrintAttributes); + + // Update the orientation + if (document.getOrientation() == PrintAttributes.ORIENTATION_LANDSCAPE) { + if (attributes.getOrientation() == PrintAttributes.ORIENTATION_LANDSCAPE) { + // If the document is in landscape and we want to print it in + // landscape, then we do not need to rotate, so portrait. + attributes.setOrientation(PrintAttributes.ORIENTATION_PORTRAIT); + } else { + // If the document is in landscape and we want to print it in + // portrait, then we have to rotate the content, so landscape. + attributes.setOrientation(PrintAttributes.ORIENTATION_LANDSCAPE); + } + } + + // Update margins. + Margins documentMargins = document.getMargins(); + if (documentMargins.getLeftMils() != 0 + || documentMargins.getTopMils() != 0 + || documentMargins.getRightMils() != 0 + || documentMargins.getBottomMils() != 0) { + // If the application has applied some of the margins, then + // the printer should only apply the difference. + Margins oldMargins = attributes.getMargins(); + attributes.setMargins(new Margins( + oldMargins.getLeftMils() - documentMargins.getLeftMils(), + oldMargins.getTopMils() - documentMargins.getTopMils(), + oldMargins.getRightMils() - documentMargins.getRightMils(), + oldMargins.getBottomMils() - documentMargins.getBottomMils())); + } + + PrintSpoolerService.peekInstance().setPrintJobAttributesNoPersistence( + mPrintJobId, attributes); + } + private final class ControllerHandler extends Handler { public static final int MSG_ON_LAYOUT_FINISHED = 1; public static final int MSG_ON_LAYOUT_FAILED = 2; @@ -1409,8 +1472,6 @@ public class PrintJobConfigActivity extends Activity { mOrientationSpinner.setEnabled(false); mRangeOptionsSpinner.setEnabled(false); mPageRangeEditText.setEnabled(false); - // TODO: Remove entirely or implement print preview. -// mPrintPreviewButton.setEnabled(false); mPrintButton.setEnabled(false); return false; } @@ -1474,10 +1535,6 @@ public class PrintJobConfigActivity extends Activity { mPageRangeEditText.setVisibility(View.INVISIBLE); mPageRangeTitle.setVisibility(View.INVISIBLE); -// // Print preview -// mPrintPreviewButton.setEnabled(false); -// mPrintPreviewButton.setText(getString(R.string.print_preview)); - // Print mPrintButton.setEnabled(false); @@ -1548,6 +1605,8 @@ public class PrintJobConfigActivity extends Activity { // Color mode. final int colorModes = capabilities.getColorModes(); + + // If the color modes changed, we update the adapter and the spinner. boolean colorModesChanged = false; if (Integer.bitCount(colorModes) != mColorModeSpinnerAdapter.getCount()) { colorModesChanged = true; @@ -1567,6 +1626,11 @@ public class PrintJobConfigActivity extends Activity { } } if (colorModesChanged) { + // Remember the old color mode to try selecting it again. + int oldColorModeNewIndex = AdapterView.INVALID_POSITION; + final int oldColorMode = mCurrPrintAttributes.getColorMode(); + + // Rebuild the adapter data. mColorModeSpinnerAdapter.clear(); String[] colorModeLabels = getResources().getStringArray( R.array.color_mode_labels); @@ -1575,6 +1639,10 @@ public class PrintJobConfigActivity extends Activity { final int colorBitOffset = Integer.numberOfTrailingZeros( remainingColorModes); final int colorMode = 1 << colorBitOffset; + if (colorMode == oldColorMode) { + // Update the index of the old selection. + oldColorModeNewIndex = colorBitOffset; + } remainingColorModes &= ~colorMode; mColorModeSpinnerAdapter.add(new SpinnerItem<Integer>(colorMode, colorModeLabels[colorBitOffset])); @@ -1585,11 +1653,14 @@ public class PrintJobConfigActivity extends Activity { mColorModeSpinner.setSelection(AdapterView.INVALID_POSITION); } else { mColorModeSpinner.setEnabled(true); - final int selectedColorModeIndex = Integer.numberOfTrailingZeros( - (colorModes & defaultAttributes.getColorMode())); - if (mColorModeSpinner.getSelectedItemPosition() != selectedColorModeIndex) { - mIgnoreNextColorModeChange = true; - mColorModeSpinner.setSelection(selectedColorModeIndex); + if (oldColorModeNewIndex != AdapterView.INVALID_POSITION) { + // Select the old color mode - nothing really changed. + setColorModeSpinnerSelectionNoCallback(oldColorModeNewIndex); + } else { + final int selectedColorModeIndex = Integer.numberOfTrailingZeros( + (colorModes & defaultAttributes.getColorMode())); + someAttributeSelectionChanged = setColorModeSpinnerSelectionNoCallback( + selectedColorModeIndex); } } } @@ -1597,6 +1668,8 @@ public class PrintJobConfigActivity extends Activity { // Orientation. final int orientations = capabilities.getOrientations(); + + // If the orientations changed, we update the adapter and the spinner. boolean orientationsChanged = false; if (Integer.bitCount(orientations) != mOrientationSpinnerAdapter.getCount()) { orientationsChanged = true; @@ -1617,6 +1690,10 @@ public class PrintJobConfigActivity extends Activity { } } if (orientationsChanged) { + // Remember the old orientation to try selecting it again. + int oldOrientationNewIndex = AdapterView.INVALID_POSITION; + final int oldOrientation = mCurrPrintAttributes.getOrientation(); + mOrientationSpinnerAdapter.clear(); String[] orientationLabels = getResources().getStringArray( R.array.orientation_labels); @@ -1625,6 +1702,10 @@ public class PrintJobConfigActivity extends Activity { final int orientationBitOffset = Integer.numberOfTrailingZeros( remainingOrientations); final int orientation = 1 << orientationBitOffset; + if (orientation == oldOrientation) { + // Update the index of the old selection. + oldOrientationNewIndex = orientationBitOffset; + } remainingOrientations &= ~orientation; mOrientationSpinnerAdapter.add(new SpinnerItem<Integer>(orientation, orientationLabels[orientationBitOffset])); @@ -1635,12 +1716,15 @@ public class PrintJobConfigActivity extends Activity { mOrientationSpinner.setSelection(AdapterView.INVALID_POSITION); } else { mOrientationSpinner.setEnabled(true); - final int selectedOrientationIndex = Integer.numberOfTrailingZeros( - (orientations & defaultAttributes.getOrientation())); - if (mOrientationSpinner.getSelectedItemPosition() - != selectedOrientationIndex) { - mIgnoreNextOrientationChange = true; - mOrientationSpinner.setSelection(selectedOrientationIndex); + if (oldOrientationNewIndex != AdapterView.INVALID_POSITION) { + // Select the old orientation - nothing really changed. + setOrientationSpinnerSelectionNoCallback(oldOrientationNewIndex); + } else { + final int selectedOrientationIndex = Integer.numberOfTrailingZeros( + (orientations & defaultAttributes.getOrientation())); + someAttributeSelectionChanged = + setOrientationSpinnerSelectionNoCallback( + selectedOrientationIndex); } } } @@ -1648,23 +1732,27 @@ public class PrintJobConfigActivity extends Activity { // Range options PrintDocumentInfo info = mDocument.info; - if (info != null && (info.getPageCount() > 1 + if (info != null && (info.getPageCount() > 0 || info.getPageCount() == PrintDocumentInfo.PAGE_COUNT_UNKNOWN)) { - mRangeOptionsSpinner.setEnabled(true); - if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) { - if (!mPageRangeEditText.isEnabled()) { - mPageRangeEditText.setEnabled(true); - mPageRangeEditText.setVisibility(View.VISIBLE); - mPageRangeTitle.setVisibility(View.VISIBLE); - mPageRangeEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) - getSystemService(INPUT_METHOD_SERVICE); - imm.showSoftInput(mPageRangeEditText, 0); - } + if (info.getPageCount() == 1) { + mRangeOptionsSpinner.setEnabled(false); } else { - mPageRangeEditText.setEnabled(false); - mPageRangeEditText.setVisibility(View.INVISIBLE); - mPageRangeTitle.setVisibility(View.INVISIBLE); + mRangeOptionsSpinner.setEnabled(true); + if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) { + if (!mPageRangeEditText.isEnabled()) { + mPageRangeEditText.setEnabled(true); + mPageRangeEditText.setVisibility(View.VISIBLE); + mPageRangeTitle.setVisibility(View.VISIBLE); + mPageRangeEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) + getSystemService(INPUT_METHOD_SERVICE); + imm.showSoftInput(mPageRangeEditText, 0); + } + } else { + mPageRangeEditText.setEnabled(false); + mPageRangeEditText.setVisibility(View.INVISIBLE); + mPageRangeTitle.setVisibility(View.INVISIBLE); + } } final int pageCount = mDocument.info.getPageCount(); mRangeOptionsTitle.setText(getString(R.string.label_pages, @@ -1702,15 +1790,8 @@ public class PrintJobConfigActivity extends Activity { && (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors())) || (mRangeOptionsSpinner.getSelectedItemPosition() == 0 && (!mController.hasPerformedLayout() || hasErrors()))) { -// mPrintPreviewButton.setEnabled(false); mPrintButton.setEnabled(false); } else { -// mPrintPreviewButton.setEnabled(true); -// if (hasPdfViewer()) { -// mPrintPreviewButton.setText(getString(R.string.print_preview)); -// } else { -// mPrintPreviewButton.setText(getString(R.string.install_for_print_preview)); -// } mPrintButton.setEnabled(true); } @@ -1742,6 +1823,24 @@ public class PrintJobConfigActivity extends Activity { return false; } + private boolean setColorModeSpinnerSelectionNoCallback(int position) { + if (mColorModeSpinner.getSelectedItemPosition() != position) { + mIgnoreNextColorModeChange = true; + mColorModeSpinner.setSelection(position); + return true; + } + return false; + } + + private boolean setOrientationSpinnerSelectionNoCallback(int position) { + if (mOrientationSpinner.getSelectedItemPosition() != position) { + mIgnoreNextOrientationChange = true; + mOrientationSpinner.setSelection(position); + return true; + } + return false; + } + private void updateUiForNewPrinterCapabilities() { // The printer changed so we want to start with a clean slate // for the print options and let them be populated from the @@ -1786,13 +1885,6 @@ public class PrintJobConfigActivity extends Activity { && mPageRangeEditText.getError() != null; } -// private boolean hasPdfViewer() { -// Intent intent = new Intent(Intent.ACTION_VIEW); -// intent.setType("application/pdf"); -// return !getPackageManager().queryIntentActivities(intent, -// PackageManager.MATCH_DEFAULT_ONLY).isEmpty(); -// } - private final class SpinnerItem<T> { final T value; CharSequence label; @@ -1998,7 +2090,7 @@ public class PrintJobConfigActivity extends Activity { .create(); return new PrinterInfo.Builder(printerId, getString(R.string.save_as_pdf), - PrinterInfo.STATUS_READY) + PrinterInfo.STATUS_IDLE) .setCapabilities(capabilities) .create(); } |