1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5cr.define('print_preview', function() { 6 'use strict'; 7 8 /** 9 * Creates a PrintHeader object. This object encapsulates all the elements 10 * and logic related to the top part of the left pane in print_preview.html. 11 * @param {!print_preview.PrintTicketStore} printTicketStore Used to read 12 * information about the document. 13 * @param {!print_preview.DestinationStore} destinationStore Used to get the 14 * selected destination. 15 * @constructor 16 * @extends {print_preview.Component} 17 */ 18 function PrintHeader(printTicketStore, destinationStore) { 19 print_preview.Component.call(this); 20 21 /** 22 * Used to read information about the document. 23 * @type {!print_preview.PrintTicketStore} 24 * @private 25 */ 26 this.printTicketStore_ = printTicketStore; 27 28 /** 29 * Used to get the selected destination. 30 * @type {!print_preview.DestinationStore} 31 * @private 32 */ 33 this.destinationStore_ = destinationStore; 34 35 /** 36 * Whether the component is enabled. 37 * @type {boolean} 38 * @private 39 */ 40 this.isEnabled_ = true; 41 42 /** 43 * Whether the print button is enabled. 44 * @type {boolean} 45 * @private 46 */ 47 this.isPrintButtonEnabled_ = true; 48 }; 49 50 /** 51 * Event types dispatched by the print header. 52 * @enum {string} 53 */ 54 PrintHeader.EventType = { 55 PRINT_BUTTON_CLICK: 'print_preview.PrintHeader.PRINT_BUTTON_CLICK', 56 CANCEL_BUTTON_CLICK: 'print_preview.PrintHeader.CANCEL_BUTTON_CLICK' 57 }; 58 59 PrintHeader.prototype = { 60 __proto__: print_preview.Component.prototype, 61 62 set isEnabled(isEnabled) { 63 this.isEnabled_ = isEnabled; 64 this.updatePrintButtonEnabledState_(); 65 this.isCancelButtonEnabled = isEnabled; 66 }, 67 68 set isPrintButtonEnabled(isEnabled) { 69 this.isPrintButtonEnabled_ = isEnabled; 70 this.updatePrintButtonEnabledState_(); 71 }, 72 73 set isCancelButtonEnabled(isEnabled) { 74 this.getChildElement('button.cancel').disabled = !isEnabled; 75 }, 76 77 /** @param {string} message Error message to display in the print header. */ 78 setErrorMessage: function(message) { 79 var summaryEl = this.getChildElement('.summary'); 80 summaryEl.innerHTML = ''; 81 summaryEl.textContent = message; 82 }, 83 84 /** @override */ 85 enterDocument: function() { 86 print_preview.Component.prototype.enterDocument.call(this); 87 88 // User events 89 this.tracker.add( 90 this.getChildElement('button.cancel'), 91 'click', 92 this.onCancelButtonClick_.bind(this)); 93 this.tracker.add( 94 this.getChildElement('button.print'), 95 'click', 96 this.onPrintButtonClick_.bind(this)); 97 98 // Data events. 99 this.tracker.add( 100 this.printTicketStore_, 101 print_preview.PrintTicketStore.EventType.INITIALIZE, 102 this.onTicketChange_.bind(this)); 103 this.tracker.add( 104 this.printTicketStore_, 105 print_preview.PrintTicketStore.EventType.DOCUMENT_CHANGE, 106 this.onTicketChange_.bind(this)); 107 this.tracker.add( 108 this.printTicketStore_, 109 print_preview.PrintTicketStore.EventType.TICKET_CHANGE, 110 this.onTicketChange_.bind(this)); 111 this.tracker.add( 112 this.destinationStore_, 113 print_preview.DestinationStore.EventType.DESTINATION_SELECT, 114 this.onDestinationSelect_.bind(this)); 115 this.tracker.add( 116 this.printTicketStore_.copies, 117 print_preview.ticket_items.TicketItem.EventType.CHANGE, 118 this.onTicketChange_.bind(this)); 119 this.tracker.add( 120 this.printTicketStore_.duplex, 121 print_preview.ticket_items.TicketItem.EventType.CHANGE, 122 this.onTicketChange_.bind(this)); 123 this.tracker.add( 124 this.printTicketStore_.pageRange, 125 print_preview.ticket_items.TicketItem.EventType.CHANGE, 126 this.onTicketChange_.bind(this)); 127 }, 128 129 /** 130 * Updates Print Button state. 131 * @private 132 */ 133 updatePrintButtonEnabledState_: function() { 134 this.getChildElement('button.print').disabled = 135 !this.isEnabled_ || 136 !this.isPrintButtonEnabled_ || 137 !this.printTicketStore_.isTicketValid(); 138 }, 139 140 /** 141 * Updates the summary element based on the currently selected user options. 142 * @private 143 */ 144 updateSummary_: function() { 145 if (!this.printTicketStore_.isTicketValid()) { 146 this.getChildElement('.summary').innerHTML = ''; 147 return; 148 } 149 150 var summaryLabel = 151 localStrings.getString('printPreviewSheetsLabelSingular'); 152 var pagesLabel = localStrings.getString('printPreviewPageLabelPlural'); 153 154 var saveToPdf = this.destinationStore_.selectedDestination && 155 this.destinationStore_.selectedDestination.id == 156 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF; 157 if (saveToPdf) { 158 summaryLabel = localStrings.getString('printPreviewPageLabelSingular'); 159 } 160 161 var numPages = this.printTicketStore_.pageRange.getPageNumberSet().size; 162 var numSheets = numPages; 163 if (!saveToPdf && this.printTicketStore_.duplex.getValue()) { 164 numSheets = Math.ceil(numPages / 2); 165 } 166 167 var copies = this.printTicketStore_.copies.getValueAsNumber(); 168 numSheets *= copies; 169 numPages *= copies; 170 171 if (numSheets > 1) { 172 summaryLabel = saveToPdf ? pagesLabel : 173 localStrings.getString('printPreviewSheetsLabelPlural'); 174 } 175 176 var html; 177 if (numPages != numSheets) { 178 html = localStrings.getStringF('printPreviewSummaryFormatLong', 179 '<b>' + numSheets + '</b>', 180 '<b>' + summaryLabel + '</b>', 181 numPages, 182 pagesLabel); 183 } else { 184 html = localStrings.getStringF('printPreviewSummaryFormatShort', 185 '<b>' + numSheets + '</b>', 186 '<b>' + summaryLabel + '</b>'); 187 } 188 189 // Removing extra spaces from within the string. 190 html = html.replace(/\s{2,}/g, ' '); 191 this.getChildElement('.summary').innerHTML = html; 192 }, 193 194 /** 195 * Called when the print button is clicked. Dispatches a PRINT_DOCUMENT 196 * common event. 197 * @private 198 */ 199 onPrintButtonClick_: function() { 200 if (this.destinationStore_.selectedDestination.id != 201 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) { 202 this.getChildElement('button.print').classList.add('loading'); 203 this.getChildElement('button.cancel').classList.add('loading'); 204 this.getChildElement('.summary').innerHTML = 205 localStrings.getString('printing'); 206 } 207 cr.dispatchSimpleEvent(this, PrintHeader.EventType.PRINT_BUTTON_CLICK); 208 }, 209 210 /** 211 * Called when the cancel button is clicked. Dispatches a 212 * CLOSE_PRINT_PREVIEW event. 213 * @private 214 */ 215 onCancelButtonClick_: function() { 216 cr.dispatchSimpleEvent(this, PrintHeader.EventType.CANCEL_BUTTON_CLICK); 217 }, 218 219 /** 220 * Called when a new destination is selected. Updates the text on the print 221 * button. 222 * @private 223 */ 224 onDestinationSelect_: function() { 225 var isSaveLabel = this.destinationStore_.selectedDestination.id == 226 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF || 227 this.destinationStore_.selectedDestination.id == 228 print_preview.Destination.GooglePromotedId.DOCS; 229 this.getChildElement('button.print').textContent = isSaveLabel ? 230 localStrings.getString('saveButton') : 231 localStrings.getString('printButton'); 232 this.getChildElement('button.print').focus(); 233 }, 234 235 /** 236 * Called when the print ticket has changed. Disables the print button if 237 * any of the settings are invalid. 238 * @private 239 */ 240 onTicketChange_: function() { 241 this.updatePrintButtonEnabledState_(); 242 this.updateSummary_(); 243 if (document.activeElement == null || 244 document.activeElement == document.body) { 245 this.getChildElement('button.print').focus(); 246 } 247 } 248 }; 249 250 // Export 251 return { 252 PrintHeader: PrintHeader 253 }; 254}); 255