Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Side by Side Diff: chrome/browser/resources/print_preview/data/print_ticket_store.js

Issue 10108001: Refactor print preview web ui (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review feedback Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
5 // TODO Optimize this to not dispatch CHANGE events when nothing really changed.
6
7 cr.define('print_preview', function() {
8 'use strict';
9
10 /**
11 * Storage of the print ticket and document statistics.
12 *
13 * Dispatches events when the contents of the print ticket or document
14 * statistics change. Also handles validation of the print ticket against
15 * destination capabilities and against the document.
16 *
17 * @constructor
18 * @extends {cr.EventTarget}
19 */
20 function PrintTicketStore() {
21 cr.EventTarget.call(this);
22
23 /**
24 * Information about the document to print.
25 * @type {DocumentInfo}
26 * @private
27 */
28 this.documentInfo_ = new DocumentInfo();
29
30 /**
31 * Printing capabilities of Chromium and the currently selected destination.
32 * @type {print_preview.ChromiumCapabilities}
33 * @private
34 */
35 this.capabilities_ = null;
36
37 /**
38 * Print ticket information. Used to print and generate previews.
39 * @type {print_preview.ChromiumPrintTicket}
40 * @private
41 */
42 this.ticket_ = null;
43
44 /**
45 * Current measurement system. Used to work with margin measurements.
46 * @type {print_preview.MeasurementSystem}
47 * @private
48 */
49 this.measurementSystem_ = null;
50
51 /**
52 * Cached page number set. Used to not have to parse page range string
53 * everytime its requested.
54 * @type {print_preview.PageNumberSet}
55 * @private
56 */
57 this.pageNumberSet_ = null;
58 };
59
60 /**
61 * Events dispatched by the print ticket store.
62 * @enum {string}
63 */
64 PrintTicketStore.Event = {
65 CAPABILITIES_CHANGE: 'print_preview.PrintTicketStore.CAPABILITIES_CHANGE',
66 DOCUMENT_CHANGE: 'print_preview.PrintTicketStore.DOCUMENT_CHANGE',
67 INITIALIZE: 'print_preview.PrintTicketStore.INITIALIZE',
68 TICKET_CHANGE: 'print_preview.PrintTicketStore.TICKET_CHANGE'
69 };
70
71 /**
72 * Minimum size in points the margins need to be to fit a header or footer.
73 * TODO: Figure out someway to actually calculate this value.
74 * @type {number}
75 * @const
76 * @private
77 */
78 PrintTicketStore.MINIMUM_HEADER_FOOTER_HEIGHT_ = 0;
79
80 PrintTicketStore.prototype = {
81 __proto__: cr.EventTarget.prototype,
82
83 /** @override */
84 dispatchEvent: function(evt) {
85 // TODO REMOVE ME
86 log(evt.type);
87 cr.EventTarget.prototype.dispatchEvent.call(this, evt);
88 },
89
90 /**
91 * @return {boolean} Whether the print ticket store has been initialized.
92 */
93 get isInitialized() {
94 return !!this.ticket_;
95 },
96
97 /** @return {boolean} Whether the document is modifiable. */
98 get isDocumentModifiable() {
99 return this.documentInfo_.isModifiable;
100 },
101
102 /** @return {number} Number of pages in the document. */
103 get pageCount() {
104 return this.documentInfo_.pageCount;
105 },
106
107 /**
108 * @param {number} pageCount New number of pages in the document.
109 * Dispatches a DOCUMENT_CHANGE event if the value changes.
110 */
111 updatePageCount: function(pageCount) {
112 if (this.documentInfo_.pageCount != pageCount) {
113 this.documentInfo_.pageCount = pageCount;
114 this.pageNumberSet_ = null;
115 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.DOCUMENT_CHANGE);
116 }
117 },
118
119 /**
120 * @return {!print_preview.PrintableArea} Printable area of the document in
121 * points.
122 */
123 get printableArea() {
124 return this.documentInfo_.printableArea;
125 },
126
127 /**
128 * @param {!print_preview.PrintableArea} printableArea New printable area of
129 * the document in points. Dispatches a DOCUMENT_CHANGE event if the
130 * value changes.
131 */
132 updatePrintableArea: function(printableArea) {
133 if (!this.documentInfo_.printableArea.equals(printableArea)) {
134 log('PrintableArea: ' + printableArea.origin.x + ' ' +
135 printableArea.origin.y + ' ' + printableArea.size.width + ' ' +
136 printableArea.size.height);
137 this.documentInfo_.printableArea = printableArea;
138 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.DOCUMENT_CHANGE);
139 }
140 },
141
142 /** @return {!print_preview.Size} Size of the document in points. */
143 get pageSize() {
144 return this.documentInfo_.pageSize;
145 },
146
147 /**
148 * @param {!print_preview.Size} pageSize New size of the document.
149 * Dispatches a DOCUMENT_CHANGE event if the value changes.
150 */
151 updatePageSize: function(pageSize) {
152 if (!this.documentInfo_.pageSize.equals(pageSize)) {
153 log('Updating page size to: ' + pageSize.width + ' ' + pageSize.height);
154 this.documentInfo_.pageSize = pageSize;
155 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.DOCUMENT_CHANGE);
156 }
157 },
158
159 /**
160 * @return {!print_preview.MeasurementSystem} Measurement system of the
161 * local system.
162 */
163 get measurementSystem() {
164 if (!this.isInitialized) {
165 throw Error(
166 'Trying to get measurement system before ticket is initialized');
167 }
168 return /** @type {!print_preview.MeasurementSystem} */ (this.
169 measurementSystem_);
170 },
171
172 /**
173 * Initializes the print ticket store. Dispatches an INITIALIZE event.
174 * @param {boolean} isDocumentModifiable Whether the document to print is
175 * modifiable (i.e. can be re-flowed by Chromium).
176 * @param {boolean} isDuplexEnabled Previous duplex setting.
177 * @param {boolean} isHeaderFooterEnabled Previous header-footer setting.
178 * @param {print_preview.Margins.Type} marginsType Previous margins type.
179 * @param {print_preview.Margins} customMargins Initial custom margins.
180 * @param {!print_preview.MeasurementSystem} measurementSystem Measurement
181 * system of the local system.
182 */
183 initialize: function(
184 isDocumentModifiable,
185 isDuplexEnabled,
186 isHeaderFooterEnabled,
187 marginsType,
188 customMargins,
189 measurementSystem) {
190
191 this.documentInfo_.isModifiable = isDocumentModifiable;
192
193 // Create capabilities that can be handled by Chromium before any
194 // particular print destination is selected.
195 this.capabilities_ = new print_preview.ChromiumCapabilities(
196 true /*hasCopiesCapability*/,
197 '1' /*defaultCopiesStr*/,
198 true /*hasCollateCapability*/,
199 true /*defaultIsCollateEnabled*/,
200 true /*hasDuplexCapability*/,
201 true /*defaultIsDuplexEnabled*/,
202 true /*hasOrientationCapability*/,
203 false /*defaultIsLandscapeEnabled*/,
204 true /*hasColorCapability*/,
205 true /*defaultIsColorEnabled*/);
206
207 // Initialize ticket with user's previous values.
208 this.ticket_ = new print_preview.ChromiumPrintTicket(this.capabilities_);
209 this.ticket_.isDuplexEnabled = isDuplexEnabled;
210 this.ticket_.marginsType = marginsType;
211 this.ticket_.customMargins = customMargins;
212 this.ticket_.isHeaderFooterEnabled = isHeaderFooterEnabled;
213
214 // Initialize measurement system.
215 this.measurementSystem_ = measurementSystem;
216
217 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.INITIALIZE);
218 },
219
220 /**
221 * Updates the capabilities of the destination the print ticket is for.
222 * Dispatches a CAPABILITIES_CHANGE event.
223 * @param {!print_preview.ChromiumCapabilities} caps New capabilities.
224 */
225 updateDestinationCapabilities: function(caps) {
226 this.capabilities_ = caps;
227 this.ticket_.capabilities = caps;
228 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.CAPABILITIES_CHANGE);
229 },
230
231 /** @return {boolean} Whether the ticket store has the copies capability. */
232 hasCopiesCapability: function() {
233 return this.capabilities_.hasCopiesCapability;
234 },
235
236 /**
237 * @return {boolean} Whether the string representation of the copies value
238 * currently in the ticket store is valid.
239 */
240 isCopiesValid: function() {
241 return this.isCopiesValidForValue(this.ticket_.copiesStr);
242 },
243
244 /**
245 * @param {string} value String representation of the number of print
246 * copies.
247 * @return {boolean} Whether the given value is valid--an integer in the
248 * range [1, 999].
249 */
250 isCopiesValidForValue: function(value) {
251 if (/[^\d]+/.test(value)) {
252 return false;
253 }
254 var copies = parseInt(value);
255 if (copies > 999 || copies < 1) {
256 return false;
257 }
258 return true;
259 },
260
261 /** @return {number} Number of copies to print. */
262 getCopies: function() {
263 return parseInt(this.ticket_.copiesStr);
264 },
265
266 /**
267 * @return {string} String representation of the number of copies to print.
268 */
269 getCopiesStr: function() {
270 return this.ticket_.copiesStr;
271 },
272
273 /**
274 * Updates the string representation of the number of copies to print.
275 * Dispatches a TICKET_CHANGE event if the string value has changed.
276 * @param {string} New string representation of the number of copies to
277 * print.
278 */
279 updateCopies: function(copies) {
280 if (!this.hasCopiesCapability()) {
281 throw Error(
282 'Updating copies capability but destination does not have a ' +
283 'copies capability');
284 }
285 if (this.ticket_.copiesStr != copies) {
286 this.ticket_.copiesStr = copies;
287 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
288 }
289 },
290
291 /** @return {boolean} Whether the ticket store has a collate capability. */
292 hasCollateCapability: function() {
293 return this.capabilities_.hasCollateCapability;
294 },
295
296 /** @return {boolean} Whether collate is enabled. */
297 isCollateEnabled: function() {
298 return this.ticket_.isCollateEnabled;
299 },
300
301 /**
302 * Updates whether collate is enabled. Dispatches a TICKET_CHANGE event if
303 * collate has changed.
304 * @param {boolean} isCollate Whether collate is enabled.
305 */
306 updateCollate: function(isCollate) {
307 if (!this.hasCollateCapability()) {
308 throw Error(
309 'Updating collate capability but destination does not have a ' +
310 'collate capability');
311 }
312 if (this.ticket_.isCollateEnabled != isCollate) {
313 this.ticket_.isCollateEnabled = isCollate;
314 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
315 }
316 },
317
318 /**
319 * @return {boolean} Whether the ticket store has color printing capability.
320 */
321 hasColorCapability: function() {
322 return this.capabilities_.hasColorCapability;
323 },
324
325 /**
326 * @return {boolean} Whether color printing is enabled.
327 */
328 isColorEnabled: function() {
329 return this.ticket_.isColorEnabled;
330 },
331
332 /**
333 * Updates whether color printing is enabled. Dispatches a TICKET_CHANGE if
334 * color has changed.
335 * @param {boolean} isColor Whether the color printing is enabled.
336 */
337 updateColor: function(isColor) {
338 if (!this.hasColorCapability()) {
339 throw Error(
340 'Updating color capability but destination does not have a color ' +
341 'capability');
342 }
343 if (this.ticket_.isColorEnabled != isColor) {
344 this.ticket_.isColorEnabled = isColor;
345 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
346 }
347 },
348
349 /** @return {boolean} Whether the header-footer capability is available. */
350 hasHeaderFooterCapability: function() {
351 // Checks the printable area and updates the visibility of header footer
352 // option based on the selected margins.
353 if (!this.documentInfo_.isModifiable ||
354 this.ticket_.marginsType == print_preview.Margins.Type.NO_MARGINS) {
355 return false;
356 }
357 if (this.ticket_.marginsType == print_preview.Margins.Type.CUSTOM) {
358 var margins = this.ticket_.customMargins;
359 // TODO This condition only checks if the margin is non-zero. It should
360 // check whether the margin is large enough to render the header-footer.
361 var availableTopMargin = this.documentInfo_.printableArea.origin.y -
362 PrintTicketStore.MINIMUM_HEADER_FOOTER_HEIGHT_;
363 var availbleBottomMargin = this.documentInfo_.pageSize.height -
364 this.documentInfo_.printableArea.origin.y -
365 this.documentInfo_.printableArea.size.height -
366 PrintTicketStore.MINIMUM_HEADER_FOOTER_HEIGHT_;
367 if (margins.top < availableTopMargin ||
368 margins.bottom < availbleBottomMargin) {
369 return false;
370 }
371 }
372 return true;
373 },
374
375 /** @return {boolean} Whether the header-footer setting is enabled. */
376 isHeaderFooterEnabled: function() {
377 return this.ticket_.isHeaderFooterEnabled;
378 },
379
380 /**
381 * Updates the whether the header-footer setting is enabled. Dispatches a
382 * TICKET_CHANGE event if the setting changed.
383 * @param {boolean} isHeaderFooterEnabled Whether the header-footer setting
384 * is enabled.
385 */
386 updateHeaderFooter: function(isHeaderFooterEnabled) {
387 if (!this.hasHeaderFooterCapability()) {
388 throw Error(
389 'Updating header-footer capability but destination does not have ' +
390 'a header-footer capability');
391 }
392 if (this.ticket_.isHeaderFooterEnabled != isHeaderFooterEnabled) {
393 this.ticket_.isHeaderFooterEnabled = isHeaderFooterEnabled;
394 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
395 }
396 },
397
398 /**
399 * @return {boolean} Whether the page orientation capability is available.
400 */
401 hasOrientationCapability: function() {
402 // TODO Technically, the print destination can still change the
403 // orientation of the print out (at least for cloud printers). But the
404 // preview wouldn't update in the case where the document is not
405 // modifiable so this is a bad user experience.
406 return this.documentInfo_.isModifiable;
407 },
408
409 /**
410 * @return {boolean} Whether the document should be printed in landscape.
411 */
412 isLandscapeEnabled: function() {
413 return this.ticket_.isLandscapeEnabled;
414 },
415
416 /**
417 * Updates whether the document should be printed in landscape. Dispatches
418 * a TICKET_CHANGE event if the setting changes.
419 * @param {boolean} isLandscape Whether the document should be printed in
420 * landscape.
421 */
422 updateOrientation: function(isLandscape) {
423 if (!this.hasOrientationCapability()) {
424 throw Error(
425 'Updating orientation capability but destination does not have ' +
426 'an orientation capability');
427 }
428 if (this.ticket_.isLandscapeEnabled != isLandscape) {
429 this.ticket_.isLandscapeEnabled = isLandscape;
430 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
431 }
432 },
433
434 /** @return {boolean} Whether the duplexing capability is available. */
435 hasDuplexCapability: function() {
436 return this.capabilities_.hasDuplexCapability;
437 },
438
439 /** @return {boolean} Whether the document should be printed in duplex. */
440 isDuplexEnabled: function() {
441 return this.ticket_.isDuplexEnabled;
442 },
443
444 /**
445 * Updates the duplexing setting. Dispatches a TICKET_CHANGE event if the
446 * value changes.
447 * @param {boolean} isDuplex Whether the document should be printed in
448 * duplex.
449 */
450 updateDuplex: function(isDuplex) {
451 if (!this.hasDuplexCapability()) {
452 throw Error(
453 'Updating duplex capability but destination does not have a ' +
454 'duplex capability');
455 }
456 if (this.ticket_.isDuplexEnabled != isDuplex) {
457 this.ticket_.isDuplexEnabled = isDuplex;
458 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
459 }
460 },
461
462 /** @return {boolean} Whether the margins capability is available. */
463 hasMarginsCapability: function() {
464 return this.documentInfo_.isModifiable;
465 },
466
467 /** @return {print_preview.Margins.Type} Type of predefined margins. */
468 getMarginsType: function() {
469 return this.ticket_.marginsType;
470 },
471
472 /**
473 * Updates the type of predefined margins. Dispatches a TICKET_CHANGE event
474 * if the margins type changes.
475 * @param {print_preview.Margins.Type} marginsType Type of predefined
476 * margins.
477 */
478 updateMarginsType: function(marginsType) {
479 if (!this.hasMarginsCapability()) {
480 throw Error(
481 'Updating margins capability but destination does not have a ' +
482 'margin capability');
483 }
484 if (this.ticket_.marginsType != marginsType) {
485 this.ticket_.marginsType = marginsType;
486 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
487 }
488 },
489
490 /** @return {print_preview.Margins} Custom margins of the document. */
491 getCustomMargins: function() {
492 return this.ticket_.customMargins;
493 },
494
495 // TODO Store the custom margins as a string so that validation can be done
496 // in the PrintTicketStore.
497
498 /**
499 * Updates the custom margins of the document. Dispatches a TICKET_CHANGE
500 * event if the margins have changed.
501 * @param {print_preview.Margins} margins New document page margins.
502 */
503 updateCustomMargins: function(margins) {
504 if (!this.hasMarginsCapability()) {
505 throw Error(
506 'Updating margins capability but destination does not have a ' +
507 'margin capability');
508 }
509 if (!margins.equals(this.ticket_.customMargins)) {
510 this.ticket_.customMargins = margins;
511 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
512 }
513 },
514
515 /** @return {boolean} Whether the page range capability is available. */
516 hasPageRangeCapability: function() {
517 // Page range can always be manipulated by Chromium.
518 return true;
519 },
520
521 /**
522 * @return {boolean} Whether the current page range string is defines a
523 * valid page number set.
524 */
525 isPageRangeValid: function() {
526 var pageRangeStr = this.ticket_.pageRangeStr;
527 return pageRangeStr == '' ||
528 isPageRangeTextValid(pageRangeStr, this.documentInfo_.pageCount);
529 },
530
531 /** @return {string} String representation of the page range. */
532 getPageRangeStr: function() {
533 return this.ticket_.pageRangeStr;
534 },
535
536 /**
537 * @return {!print_preview.PageNumberSet} Page number set specified by the
538 * string representation of the page range string.
539 */
540 getPageNumberSet: function() {
541 if (this.pageNumberSet_ == null) {
542 this.pageNumberSet_ = print_preview.PageNumberSet.parse(
543 this.ticket_.pageRangeStr, this.documentInfo_.pageCount);
544 }
545 return this.pageNumberSet_;
546 },
547
548 /**
549 * Updates the page range string. Dispatches a TICKET_CHANGE if the string
550 * changed.
551 * @param {string} pageRangeStr New page range string.
552 */
553 updatePageRange: function(pageRangeStr) {
554 if (this.ticket_.pageRangeStr != pageRangeStr) {
555 this.ticket_.pageRangeStr = pageRangeStr;
556 this.pageNumberSet_ = null;
557 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
558 }
559 },
560
561 /**
562 * @return {boolean} {@code true} if the stored print ticket is valid,
563 * {@code false} otherwise.
564 */
565 isTicketValid: function() {
566 // TODO Validate custom margins
567 return this.isCopiesValid() && this.isPageRangeValid();
568 }
569 };
570
571 /**
572 * Object which contains information related to the document to print.
573 *
574 * @constructor
575 */
576 function DocumentInfo() {
577 /**
578 * Whether the document to print is modifiable (i.e. can be reflowed).
579 * @type {boolean}
580 */
581 this.isModifiable = true;
582
583 /**
584 * Number of pages in the document to print.
585 * @type {number}
586 */
587 this.pageCount = 1;
588
589 /**
590 * Size of the pages of the document.
591 * @type {!print_preview.Size}
592 */
593 this.pageSize = new print_preview.Size(612, 792);
dpapad 2012/04/24 01:24:56 Where do these values come from?
Robert Toscano 2012/04/24 22:29:56 8.5"x11" paper size. I've move the initialization
594
595 /**
596 * Printable area of the document.
597 * @type {!print_preview.PrintableArea}
598 */
599 this.printableArea = new print_preview.PrintableArea(
600 new print_preview.Coordinate2d(0, 0),
601 this.pageSize);
602 };
603
604 // Export
605 return {
606 PrintTicketStore: PrintTicketStore
607 };
608 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698