am f22a767e: Merge "Added UI for errors during layout and write." into klp-dev
* commit 'f22a767e872ec8f5c2531a88819e0f4574c78fe3':
Added UI for errors during layout and write.
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 7eea3e9..48564911 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -41,8 +41,6 @@
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"/>
- <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="18"/>
-
<application
android:allowClearUserData="true"
android:label="@string/app_label"
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_content_error.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_content_error.xml
new file mode 100644
index 0000000..222b5b6
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/print_job_config_activity_content_error.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/content_generating"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@color/editable_background"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dip"
+ android:layout_marginEnd="16dip"
+ android:layout_marginTop="32dip"
+ android:layout_marginBottom="32dip"
+ android:layout_gravity="center"
+ style="?android:attr/buttonBarButtonStyle"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:text="@string/print_error_default_message"
+ android:textColor="@color/important_text"
+ android:textSize="16sp">
+ </TextView>
+
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="@color/separator">
+ </View>
+
+ </LinearLayout>
+
+ <Button
+ android:id="@+id/ok_button"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="fill_horizontal"
+ style="?android:attr/buttonBarButtonStyle"
+ android:text="@android:string/ok"
+ android:textSize="16sp"
+ android:textColor="@color/important_text">
+ </Button>
+
+</LinearLayout>
diff --git a/packages/PrintSpooler/res/values/strings.xml b/packages/PrintSpooler/res/values/strings.xml
index 67c455d..d74b414 100644
--- a/packages/PrintSpooler/res/values/strings.xml
+++ b/packages/PrintSpooler/res/values/strings.xml
@@ -44,7 +44,7 @@
<string name="label_pages">Pages (<xliff:g id="page_count" example="5">%1$s</xliff:g>)</string>
<!-- Page range exmple used as a hint of how to specify such. [CHAR LIMIT=20] -->
- <string name="pages_range_example">e.g. 1–5, 8, 11–13</string>
+ <string name="pages_range_example">e.g. 1—5,8,11—13</string>
<!-- Title for the pring preview button .[CHAR LIMIT=30] -->
<string name="print_preview">Print preview</string>
@@ -142,6 +142,9 @@
<!-- Label for a printer that is not available. [CHAR LIMIT=25] -->
<string name="printer_unavailable"><xliff:g id="print_job_name" example="Canon-123GHT">%1$s</xliff:g> – unavailable</string>
+ <!-- Default message of an alert dialog for app error while generating a print job. [CHAR LIMIT=50] -->
+ <string name="print_error_default_message">Couldn\'t generate print job</string>
+
<!-- Arrays -->
<!-- Color mode labels. -->
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index 007d9c0..3ba7369 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -89,6 +89,8 @@
import libcore.io.IoUtils;
+import libcore.io.IoUtils;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -357,6 +359,10 @@
return mControllerState >= CONTROLLER_STATE_LAYOUT_COMPLETED;
}
+ public boolean isPerformingLayout() {
+ return mControllerState == CONTROLLER_STATE_LAYOUT_STARTED;
+ }
+
public boolean isWorking() {
return mControllerState == CONTROLLER_STATE_LAYOUT_STARTED
|| mControllerState == CONTROLLER_STATE_WRITE_STARTED;
@@ -372,9 +378,18 @@
if (!mController.hasStarted()) {
mController.start();
}
+
+ // If the print attributes are the same and we are performing
+ // a layout, then we have to wait for it to completed which will
+ // trigger writing of the necessary pages.
+ final boolean printAttributesChanged = printAttributesChanged();
+ if (!printAttributesChanged && isPerformingLayout()) {
+ return;
+ }
+
// If print is confirmed we always do a layout since the previous
// ones were for preview and this one is for printing.
- if (!printAttributesChanged() && !mEditor.isPrintConfirmed()) {
+ if (!printAttributesChanged && !mEditor.isPrintConfirmed()) {
if (mDocument.info == null) {
// We are waiting for the result of a layout, so do nothing.
return;
@@ -492,14 +507,20 @@
mRequestCounter.incrementAndGet());
}
- private void handleOnLayoutFailed(CharSequence error, int sequence) {
+ private void handleOnLayoutFailed(final CharSequence error, int sequence) {
if (mRequestCounter.get() != sequence) {
return;
}
mControllerState = CONTROLLER_STATE_FAILED;
- // TODO: We need some UI for announcing an error.
- Log.e(LOG_TAG, "Error during layout: " + error);
- PrintJobConfigActivity.this.finish();
+ mEditor.showUi(Editor.UI_ERROR, new Runnable() {
+ @Override
+ public void run() {
+ if (!TextUtils.isEmpty(error)) {
+ TextView messageView = (TextView) findViewById(R.id.message);
+ messageView.setText(error);
+ }
+ }
+ });
}
private void handleOnWriteFinished(PageRange[] pages, int sequence) {
@@ -596,13 +617,20 @@
}
}
- private void handleOnWriteFailed(CharSequence error, int sequence) {
+ private void handleOnWriteFailed(final CharSequence error, int sequence) {
if (mRequestCounter.get() != sequence) {
return;
}
mControllerState = CONTROLLER_STATE_FAILED;
- Log.e(LOG_TAG, "Error during write: " + error);
- PrintJobConfigActivity.this.finish();
+ mEditor.showUi(Editor.UI_ERROR, new Runnable() {
+ @Override
+ public void run() {
+ if (!TextUtils.isEmpty(error)) {
+ TextView messageView = (TextView) findViewById(R.id.message);
+ messageView.setText(error);
+ }
+ }
+ });
}
private boolean equalsIgnoreSize(PrintDocumentInfo lhs, PrintDocumentInfo rhs) {
@@ -800,6 +828,7 @@
private static final int UI_NONE = 0;
private static final int UI_EDITING_PRINT_JOB = 1;
private static final int UI_GENERATING_PRINT_JOB = 2;
+ private static final int UI_ERROR = 3;
private EditText mCopiesEditText;
@@ -1310,6 +1339,21 @@
updateUi();
}
+ public void reselectCurrentPrinter() {
+ if (mCurrentPrinter != null) {
+ // TODO: While the data did not change and we set the adapter
+ // to a newly inflated spinner, the latter does not show the
+ // current item unless we poke the adapter. This requires more
+ // investigation. Maybe an optimization in AdapterView does not
+ // call into the adapter if the view is not visible which is the
+ // case when we set the adapter.
+ mDestinationSpinnerAdapter.notifyDataSetChanged();
+ final int position = mDestinationSpinnerAdapter.getPrinterIndex(
+ mCurrentPrinter.getId());
+ mDestinationSpinner.setSelection(position);
+ }
+ }
+
public void refreshCurrentPrinter() {
PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
if (printer != null) {
@@ -1407,7 +1451,10 @@
return;
}
- switch (mCurrentUi) {
+ final int oldUi = mCurrentUi;
+ mCurrentUi = ui;
+
+ switch (oldUi) {
case UI_NONE: {
switch (ui) {
case UI_EDITING_PRINT_JOB: {
@@ -1444,6 +1491,21 @@
new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
} break;
+
+ case UI_ERROR: {
+ animateUiSwitch(R.layout.print_job_config_activity_content_error,
+ new Runnable() {
+ @Override
+ public void run() {
+ registerOkButtonClickListener();
+ if (postSwitchCallback != null) {
+ postSwitchCallback.run();
+ }
+ }
+ },
+ new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
+ } break;
}
} break;
@@ -1463,11 +1525,43 @@
new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
} break;
+
+ case UI_ERROR: {
+ animateUiSwitch(R.layout.print_job_config_activity_content_error,
+ new Runnable() {
+ @Override
+ public void run() {
+ registerOkButtonClickListener();
+ if (postSwitchCallback != null) {
+ postSwitchCallback.run();
+ }
+ }
+ },
+ new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
+ } break;
+ }
+ } break;
+
+ case UI_ERROR: {
+ switch (ui) {
+ case UI_EDITING_PRINT_JOB: {
+ animateUiSwitch(R.layout.print_job_config_activity_content_editing,
+ new Runnable() {
+ @Override
+ public void run() {
+ registerPrintButtonClickListener();
+ if (postSwitchCallback != null) {
+ postSwitchCallback.run();
+ }
+ }
+ },
+ new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
+ } break;
}
} break;
}
-
- mCurrentUi = ui;
}
private void registerPrintButtonClickListener() {
@@ -1503,13 +1597,33 @@
});
}
+ private void registerOkButtonClickListener() {
+ Button okButton = (Button) findViewById(R.id.ok_button);
+ okButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mEditor.showUi(Editor.UI_EDITING_PRINT_JOB, new Runnable() {
+ @Override
+ public void run() {
+ // Start over with a clean slate.
+ mOldPrintAttributes.clear();
+ mController.initialize();
+ mEditor.initialize();
+ mEditor.bindUi();
+ mEditor.reselectCurrentPrinter();
+ }
+ });
+ }
+ });
+ }
+
private void doUiSwitch(int showLayoutId) {
ViewGroup contentContainer = (ViewGroup) findViewById(R.id.content_container);
contentContainer.removeAllViews();
getLayoutInflater().inflate(showLayoutId, contentContainer, true);
}
- private void animateUiSwitch(int showLayoutId, final Runnable postAnimateCommand,
+ private void animateUiSwitch(int showLayoutId, final Runnable beforeShowNewUiAction,
final LayoutParams containerParams) {
// Find everything we will shuffle around.
final ViewGroup contentContainer = (ViewGroup) findViewById(R.id.content_container);
@@ -1538,7 +1652,7 @@
/ (float) contentContainer.getHeight();
// Second animation - resize the container.
- AutoCancellingAnimator.animate(contentContainer).scaleY(scaleY).withLayer()
+ AutoCancellingAnimator.animate(contentContainer).scaleY(scaleY)
.withEndAction(new Runnable() {
@Override
public void run() {
@@ -1549,14 +1663,10 @@
contentContainer.setLayoutParams(containerParams);
+ beforeShowNewUiAction.run();
+
// Third animation - show the new content.
- AutoCancellingAnimator.animate(showingView).withLayer().alpha(1.0f)
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- postAnimateCommand.run();
- }
- });
+ AutoCancellingAnimator.animate(showingView).alpha(1.0f);
}
});
}