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