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.destinationStore_.selectedDestination == null || 136 !this.isEnabled_ || 137 !this.isPrintButtonEnabled_ || 138 !this.printTicketStore_.isTicketValid(); 139 }, 140 141 /** 142 * Updates the summary element based on the currently selected user options. 143 * @private 144 */ 145 updateSummary_: function() { 146 if (!this.printTicketStore_.isTicketValid()) { 147 this.getChildElement('.summary').innerHTML = ''; 148 return; 149 } 150 151 var summaryLabel = 152 loadTimeData.getString('printPreviewSheetsLabelSingular'); 153 var pagesLabel = loadTimeData.getString('printPreviewPageLabelPlural'); 154 155 var saveToPdf = this.destinationStore_.selectedDestination && 156 this.destinationStore_.selectedDestination.id == 157 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF; 158 if (saveToPdf) { 159 summaryLabel = loadTimeData.getString('printPreviewPageLabelSingular'); 160 } 161 162 var numPages = this.printTicketStore_.pageRange.getPageNumberSet().size; 163 var numSheets = numPages; 164 if (!saveToPdf && this.printTicketStore_.duplex.getValue()) { 165 numSheets = Math.ceil(numPages / 2); 166 } 167 168 var copies = this.printTicketStore_.copies.getValueAsNumber(); 169 numSheets *= copies; 170 numPages *= copies; 171 172 if (numSheets > 1) { 173 summaryLabel = saveToPdf ? pagesLabel : 174 loadTimeData.getString('printPreviewSheetsLabelPlural'); 175 } 176 177 var html; 178 if (numPages != numSheets) { 179 html = loadTimeData.getStringF('printPreviewSummaryFormatLong', 180 '<b>' + numSheets + '</b>', 181 '<b>' + summaryLabel + '</b>', 182 numPages, 183 pagesLabel); 184 } else { 185 html = loadTimeData.getStringF('printPreviewSummaryFormatShort', 186 '<b>' + numSheets + '</b>', 187 '<b>' + summaryLabel + '</b>'); 188 } 189 190 // Removing extra spaces from within the string. 191 html = html.replace(/\s{2,}/g, ' '); 192 this.getChildElement('.summary').innerHTML = html; 193 }, 194 195 /** 196 * Called when the print button is clicked. Dispatches a PRINT_DOCUMENT 197 * common event. 198 * @private 199 */ 200 onPrintButtonClick_: function() { 201 if (this.destinationStore_.selectedDestination.id != 202 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) { 203 this.getChildElement('button.print').classList.add('loading'); 204 this.getChildElement('button.cancel').classList.add('loading'); 205 this.getChildElement('.summary').innerHTML = 206 loadTimeData.getString('printing'); 207 } 208 cr.dispatchSimpleEvent(this, PrintHeader.EventType.PRINT_BUTTON_CLICK); 209 }, 210 211 /** 212 * Called when the cancel button is clicked. Dispatches a 213 * CLOSE_PRINT_PREVIEW event. 214 * @private 215 */ 216 onCancelButtonClick_: function() { 217 cr.dispatchSimpleEvent(this, PrintHeader.EventType.CANCEL_BUTTON_CLICK); 218 }, 219 220 /** 221 * Called when a new destination is selected. Updates the text on the print 222 * button. 223 * @private 224 */ 225 onDestinationSelect_: function() { 226 var isSaveLabel = this.destinationStore_.selectedDestination && 227 (this.destinationStore_.selectedDestination.id == 228 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF || 229 this.destinationStore_.selectedDestination.id == 230 print_preview.Destination.GooglePromotedId.DOCS); 231 this.getChildElement('button.print').textContent = 232 loadTimeData.getString(isSaveLabel ? 'saveButton' : 'printButton'); 233 if (this.destinationStore_.selectedDestination) { 234 this.getChildElement('button.print').focus(); 235 } 236 }, 237 238 /** 239 * Called when the print ticket has changed. Disables the print button if 240 * any of the settings are invalid. 241 * @private 242 */ 243 onTicketChange_: function() { 244 this.updatePrintButtonEnabledState_(); 245 this.updateSummary_(); 246 if (document.activeElement == null || 247 document.activeElement == document.body) { 248 this.getChildElement('button.print').focus(); 249 } 250 } 251 }; 252 253 // Export 254 return { 255 PrintHeader: PrintHeader 256 }; 257}); 258