summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Svetoslav Ganov <svetoslavganov@google.com> 2013-08-28 00:07:08 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2013-08-28 00:07:09 +0000
commitca09dbc67b28d5d1d16b7966b855229697c6c549 (patch)
tree0ca07ec7add60de57f04f43cb2cfcd9c39d035ac
parentbbbc8660cdbfb033291f1911742a942a42c85af0 (diff)
parentaec1417ca9eb63209668ac17da90cf8a07c6076c (diff)
Merge "Print APIs update." into klp-dev
-rw-r--r--api/current.txt34
-rw-r--r--core/java/android/print/PageRange.java2
-rw-r--r--core/java/android/print/PrintAttributes.java60
-rw-r--r--core/java/android/print/PrintDocumentAdapter.java22
-rw-r--r--core/java/android/print/PrintDocumentInfo.java255
-rw-r--r--core/java/android/print/PrinterCapabilitiesInfo.java4
-rw-r--r--core/java/android/print/PrinterInfo.java29
-rw-r--r--core/java/android/print/pdf/PdfDocument.java43
-rw-r--r--core/java/android/print/pdf/PrintedPdfDocument.java162
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java188
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();
}