Commit c228e99c authored by rbpotter's avatar rbpotter Committed by Commit Bot

Print Preview Componentization: Enable print button

Enable the print button in the new print preview UI.

Bug: 773928
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I27a8b99e3ce23ebe718214c4eee0ab92e6b48713
Reviewed-on: https://chromium-review.googlesource.com/892399Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#534814}
parent d012c58d
...@@ -54,6 +54,8 @@ Polymer({ ...@@ -54,6 +54,8 @@ Polymer({
invalidSettings: false, invalidSettings: false,
initialized: false, initialized: false,
cancelled: false, cancelled: false,
printRequested: false,
printFailed: false,
}, },
}, },
...@@ -65,6 +67,11 @@ Polymer({ ...@@ -65,6 +67,11 @@ Polymer({
}, },
}, },
observers: [
'onPreviewCancelled_(state_.cancelled)',
'onPrintRequested_(state_.printRequested, state_.previewLoading)',
],
/** @private {?WebUIListenerTracker} */ /** @private {?WebUIListenerTracker} */
listenerTracker_: null, listenerTracker_: null,
...@@ -157,4 +164,61 @@ Polymer({ ...@@ -157,4 +164,61 @@ Polymer({
onSaveStickySettings_: function(e) { onSaveStickySettings_: function(e) {
this.nativeLayer_.saveAppState(/** @type {string} */ (e.detail)); this.nativeLayer_.saveAppState(/** @type {string} */ (e.detail));
}, },
/** @private */
onPrintRequested_: function() {
if (this.state_.previewLoading || !this.state_.printRequested)
return;
assert(this.settings.scaling.valid);
assert(this.settings.pages.valid);
assert(this.settings.copies.valid);
const destination = assert(this.destinationStore_.selectedDestination);
const whenPrintDone =
this.nativeLayer_.print(this.$.model.createPrintTicket(destination));
if (destination.isLocal) {
const onError = destination.id ==
print_preview.Destination.GooglePromotedId.SAVE_AS_PDF ?
this.onFileSelectionCancel_.bind(this) :
this.onPrintFailed_.bind(this);
whenPrintDone.then(this.close_.bind(this), onError);
} else {
// Cloud print resolves when print data is returned to submit to cloud
// print, or if print ticket cannot be read, no PDF data is found, or
// PDF is oversized.
whenPrintDone.then(
this.onPrintToCloud_.bind(this), this.onPrintFailed_.bind(this));
}
},
/** @private */
onFileSelectionCancel_: function() {
this.set('state_.printRequested', false);
},
/** @private */
onPrintToCloud_: function() {
// TODO (rbpotter): Actually print to cloud print once cloud print
// interface is hooked up. Currently there are no cloud printers so
// this should never happen.
assertNotReached('Trying to print to cloud printer!');
},
/**
* Called when printing to a privet, cloud, or extension printer fails.
* @param {*} httpError The HTTP error code, or -1 or a string describing
* the error, if not an HTTP error.
* @private
*/
onPrintFailed_: function(httpError) {
console.error('Printing failed with error code ' + httpError);
this.set('state.printFailed', true);
},
/** @private */
close_: function() {
this.detached();
this.nativeLayer_.dialogClose(false);
},
}); });
...@@ -170,6 +170,7 @@ ...@@ -170,6 +170,7 @@
'../data/compiled_resources2.gyp:size', '../data/compiled_resources2.gyp:size',
'../data/compiled_resources2.gyp:margins', '../data/compiled_resources2.gyp:margins',
'../data/compiled_resources2.gyp:printable_area', '../data/compiled_resources2.gyp:printable_area',
'model',
'settings_behavior', 'settings_behavior',
'state', 'state',
], ],
......
...@@ -17,13 +17,6 @@ Polymer({ ...@@ -17,13 +17,6 @@ Polymer({
notify: true, notify: true,
}, },
/** @private {boolean} */
printInProgress_: {
type: Boolean,
notify: true,
value: false,
},
/** /**
* @private {?string} Null value indicates that there is no error or * @private {?string} Null value indicates that there is no error or
* state to display in the summary. * state to display in the summary.
...@@ -32,7 +25,7 @@ Polymer({ ...@@ -32,7 +25,7 @@ Polymer({
type: String, type: String,
computed: 'computeErrorOrStateString_(state.*, ' + computed: 'computeErrorOrStateString_(state.*, ' +
'settings.copies.valid, settings.scaling.valid, ' + 'settings.copies.valid, settings.scaling.valid, ' +
'settings.pages.valid, printInProgress_)' 'settings.pages.valid)'
}, },
/** /**
...@@ -51,7 +44,7 @@ Polymer({ ...@@ -51,7 +44,7 @@ Polymer({
/** @private */ /** @private */
onPrintButtonTap_: function() { onPrintButtonTap_: function() {
this.printInProgress_ = true; this.set('state.printRequested', true);
}, },
/** @private */ /** @private */
...@@ -85,6 +78,8 @@ Polymer({ ...@@ -85,6 +78,8 @@ Polymer({
* @private * @private
*/ */
computeErrorOrStateString_: function() { computeErrorOrStateString_: function() {
if (this.state.printFailed)
return loadTimeData.getString('couldNotPrint');
if (this.state.cloudPrintError != '') if (this.state.cloudPrintError != '')
return this.state.cloudPrintError; return this.state.cloudPrintError;
if (this.state.privetExtensionError != '') if (this.state.privetExtensionError != '')
...@@ -94,7 +89,7 @@ Polymer({ ...@@ -94,7 +89,7 @@ Polymer({
!this.getSetting('scaling').valid || !this.getSetting('pages').valid) { !this.getSetting('scaling').valid || !this.getSetting('pages').valid) {
return ''; return '';
} }
if (this.printInProgress_) { if (this.state.printRequested && !this.state.previewLoading) {
return loadTimeData.getString( return loadTimeData.getString(
this.isPdfOrDrive_() ? 'saving' : 'printing'); this.isPdfOrDrive_() ? 'saving' : 'printing');
} }
......
<link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="settings_behavior.html">
<link rel="import" href="../data/destination.html"> <link rel="import" href="../data/destination.html">
<link rel="import" href="../data/document_info.html"> <link rel="import" href="../data/document_info.html">
<link rel="import" href="../data/margins.html"> <link rel="import" href="../data/margins.html">
......
...@@ -33,6 +33,16 @@ cr.exportPath('print_preview_new'); ...@@ -33,6 +33,16 @@ cr.exportPath('print_preview_new');
*/ */
print_preview_new.SerializedSettings; print_preview_new.SerializedSettings;
/**
* Constant values matching printing::DuplexMode enum.
* @enum {number}
*/
print_preview_new.DuplexMode = {
SIMPLEX: 0,
LONG_EDGE: 1,
UNKNOWN_DUPLEX_MODE: -1
};
(function() { (function() {
'use strict'; 'use strict';
...@@ -52,6 +62,8 @@ const STICKY_SETTING_NAMES = [ ...@@ -52,6 +62,8 @@ const STICKY_SETTING_NAMES = [
Polymer({ Polymer({
is: 'print-preview-model', is: 'print-preview-model',
behaviors: [SettingsBehavior],
properties: { properties: {
/** /**
* Object containing current settings of Print Preview, for use by Polymer * Object containing current settings of Print Preview, for use by Polymer
...@@ -430,5 +442,162 @@ Polymer({ ...@@ -430,5 +442,162 @@ Polymer({
}); });
this.fire('save-sticky-settings', JSON.stringify(serialization)); this.fire('save-sticky-settings', JSON.stringify(serialization));
}, },
/**
* Creates a string that represents a print ticket.
* @param {!print_preview.Destination} destination Destination to print to.
* @return {string} Serialized print ticket.
*/
createPrintTicket: function(destination) {
const dpi = /** @type {{horizontal_dpi: (number | undefined),
vertical_dpi: (number | undefined),
vendor_id: (number | undefined)}} */ (
this.getSettingValue('dpi'));
const ticket = {
mediaSize: this.getSettingValue('mediaSize'),
pageCount: this.getSettingValue('pages').length,
landscape: this.getSettingValue('layout'),
color: destination.getNativeColorModel(
/** @type {boolean} */ (this.getSettingValue('color'))),
headerFooterEnabled: this.getSettingValue('headerFooter'),
marginsType: this.getSettingValue('margins'),
duplex: this.getSettingValue('duplex') ?
print_preview_new.DuplexMode.LONG_EDGE :
print_preview_new.DuplexMode.SIMPLEX,
copies: this.getSettingValue('copies'),
collate: this.getSettingValue('collate'),
shouldPrintBackgrounds: this.getSettingValue('cssBackground'),
shouldPrintSelectionOnly: this.getSettingValue('selectionOnly'),
previewModifiable: this.documentInfo.isModifiable,
printToPDF: destination.id ==
print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
printWithCloudPrint: !destination.isLocal,
printWithPrivet: destination.isPrivet,
printWithExtension: destination.isExtension,
rasterizePDF: this.getSettingValue('rasterize'),
scaleFactor: parseInt(this.getSettingValue('scaling'), 10),
dpiHorizontal: (dpi && 'horizontal_dpi' in dpi) ? dpi.horizontal_dpi : 0,
dpiVertical: (dpi && 'vertical_dpi' in dpi) ? dpi.vertical_dpi : 0,
deviceName: destination.id,
fitToPageEnabled: this.getSettingValue('fitToPage'),
pageWidth: this.documentInfo.pageSize.width,
pageHeight: this.documentInfo.pageSize.height,
showSystemDialog: false,
};
// Set 'cloudPrintID' only if the destination is not local.
if (!destination.isLocal)
ticket.cloudPrintID = destination.id;
if (this.getSettingValue('margins') ==
print_preview.ticket_items.MarginsTypeValue.CUSTOM) {
// TODO (rbpotter): Replace this with real values when custom margins are
// implemented.
ticket.marginsCustom = {
marginTop: 70,
marginRight: 70,
marginBottom: 70,
marginLeft: 70,
};
}
if (destination.isPrivet || destination.isExtension) {
// TODO (rbpotter): Get local and PDF printers to use the same ticket and
// send only this ticket instead of nesting it in a larger ticket.
ticket.ticket = this.createCloudJobTicket_(destination);
ticket.capabilities = JSON.stringify(destination.capabilities);
}
return JSON.stringify(ticket);
},
/**
* Creates an object that represents a Google Cloud Print print ticket.
* @param {!print_preview.Destination} destination Destination to print to.
* @return {string} Google Cloud Print print ticket.
* @private
*/
createCloudJobTicket_: function(destination) {
assert(
!destination.isLocal || destination.isPrivet || destination.isExtension,
'Trying to create a Google Cloud Print print ticket for a local ' +
' non-privet and non-extension destination');
assert(
destination.capabilities,
'Trying to create a Google Cloud Print print ticket for a ' +
'destination with no print capabilities');
// Create CJT (Cloud Job Ticket)
const cjt = {version: '1.0', print: {}};
if (this.settings.collate.available)
cjt.print.collate = {collate: this.settings.collate.value};
if (this.settings.color.available) {
const selectedOption = destination.getSelectedColorOption(
/** @type {boolean} */ (this.settings.color.value));
if (!selectedOption) {
console.error('Could not find correct color option');
} else {
cjt.print.color = {type: selectedOption.type};
if (selectedOption.hasOwnProperty('vendor_id')) {
cjt.print.color.vendor_id = selectedOption.vendor_id;
}
}
} else {
// Always try setting the color in the print ticket, otherwise a
// reasonable reader of the ticket will have to do more work, or process
// the ticket sub-optimally, in order to safely handle the lack of a
// color ticket item.
const defaultOption = destination.defaultColorOption;
if (defaultOption) {
cjt.print.color = {type: defaultOption.type};
if (defaultOption.hasOwnProperty('vendor_id')) {
cjt.print.color.vendor_id = defaultOption.vendor_id;
}
}
}
if (this.settings.copies.available)
cjt.print.copies = {copies: this.settings.copies.value};
if (this.settings.duplex.available) {
cjt.print.duplex = {
type: this.settings.duplex.value ? 'LONG_EDGE' : 'NO_DUPLEX'
};
}
if (this.settings.mediaSize.available) {
const mediaValue = this.settings.mediaSize.value;
cjt.print.media_size = {
width_microns: mediaValue.width_microns,
height_microns: mediaValue.height_microns,
is_continuous_feed: mediaValue.is_continuous_feed,
vendor_id: mediaValue.vendor_id
};
}
if (!this.settings.layout.available) {
// In this case "orientation" option is hidden from user, so user can't
// adjust it for page content, see Landscape.isCapabilityAvailable().
// We can improve results if we set AUTO here.
const capability = destination.capabilities.printer ?
destination.capabilities.printer.page_orientation :
null;
if (capability && capability.option &&
capability.option.some(option => option.type == 'AUTO')) {
cjt.print.page_orientation = {type: 'AUTO'};
}
} else {
cjt.print.page_orientation = {
type: this.settings.layout ? 'LANDSCAPE' : 'PORTRAIT'
};
}
if (this.settings.dpi.available) {
const dpiValue = this.settings.dpi.value;
cjt.print.dpi = {
horizontal_dpi: dpiValue.horizontal_dpi,
vertical_dpi: dpiValue.vertical_dpi,
vendor_id: dpiValue.vendor_id
};
}
// TODO (rbpotter): Deal with advanced settings (vendorItems).
return JSON.stringify(cjt);
},
}); });
})(); })();
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
<link rel="import" href="../data/margins.html"> <link rel="import" href="../data/margins.html">
<link rel="import" href="../data/printable_area.html"> <link rel="import" href="../data/printable_area.html">
<link rel="import" href="../data/size.html"> <link rel="import" href="../data/size.html">
<link rel="import" href="model.html">
<link rel="import" href="settings_behavior.html"> <link rel="import" href="settings_behavior.html">
<dom-module id="print-preview-preview-area"> <dom-module id="print-preview-preview-area">
......
...@@ -34,16 +34,6 @@ cr.exportPath('print_preview_new'); ...@@ -34,16 +34,6 @@ cr.exportPath('print_preview_new');
*/ */
print_preview_new.PDFPlugin; print_preview_new.PDFPlugin;
/**
* Constant values matching printing::DuplexMode enum.
* @enum {number}
*/
print_preview_new.DuplexMode = {
SIMPLEX: 0,
LONG_EDGE: 1,
UNKNOWN_DUPLEX_MODE: -1
};
Polymer({ Polymer({
is: 'print-preview-preview-area', is: 'print-preview-preview-area',
......
...@@ -13,6 +13,8 @@ cr.exportPath('print_preview_new'); ...@@ -13,6 +13,8 @@ cr.exportPath('print_preview_new');
* invalidSettings: boolean, * invalidSettings: boolean,
* initialized: boolean, * initialized: boolean,
* cancelled: boolean, * cancelled: boolean,
* printRequested: boolean,
* printFailed: boolean,
* }} * }}
*/ */
print_preview_new.State; print_preview_new.State;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment