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

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: 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 * @param {print_preview.DestinationStore!} destinationStore Destination store
18 * used to get the selected destination.
19 * @constructor
20 * @extends {cr.EventTarget}
21 */
22 function PrintTicketStore(destinationStore) {
23 cr.EventTarget.call(this);
24
25 /**
26 * Destination store used to get the selected destination.
27 * @type {print_preview.DestinationStore!}
28 * @private
29 */
30 this.destinationStore_ = destinationStore;
31
32 /**
33 * Information about the document to print.
34 * @type {DocumentInfo}
35 * @private
36 */
37 this.documentInfo_ = new DocumentInfo();
38
39 /**
40 * Cached page number set. Used to not have to parse page range string
41 * everytime its requested.
42 * @type {print_preview.PageNumberSet}
43 * @private
44 */
45 this.pageNumberSet_ = null;
46
47 /**
48 * Printing capabilities of Chromium and the currently selected destination.
49 * @type {print_preview.ChromiumCapabilities}
50 * @private
51 */
52 this.capabilities_ = null;
53
54 /**
55 * Print ticket information. Used to print and generate previews.
56 * @type {print_preview.ChromiumPrintTicket}
57 * @private
58 */
59 this.ticket_ = null;
60
61 /**
62 * Current measurement system. Used to work with margin measurements.
63 * @type {print_preview.MeasurementSystem}
64 * @private
65 */
66 this.measurementSystem_ = null;
67 };
68
69 /**
70 * Events dispatched by the print ticket store.
71 * @enum {string}
72 */
73 PrintTicketStore.Event = {
74 CAPABILITIES_CHANGE: 'print_preview.PrintTicketStore.CAPABILITIES_CHANGE',
75 DOCUMENT_CHANGE: 'print_preview.PrintTicketStore.DOCUMENT_CHANGE',
76 INITIALIZE: 'print_preview.PrintTicketStore.INITIALIZE',
77 TICKET_CHANGE: 'print_preview.PrintTicketStore.TICKET_CHANGE',
78 };
79
80 PrintTicketStore.prototype = {
81 __proto__: cr.EventTarget.prototype,
82
83 get isDocumentModifiable() {
84 return this.documentInfo_.isModifiable;
85 },
86
87 get pageCount() {
88 return this.documentInfo_.pageCount;
89 },
90
91 /** @override */
92 dispatchEvent: function(evt) {
93 // TODO REMOVE ME
94 log(evt.type);
95 cr.EventTarget.prototype.dispatchEvent.call(this, evt);
96 },
97
98 /**
99 * Initializes the print ticket store.
100 * @param {boolean} isDocumentModifiable Whether the document to print is
101 * modifiable (i.e. can be re-flowed by Chromium).
102 * @param {boolean} isDuplexEnabled Previous duplex setting.
103 * @param {boolean} isHeaderFooterEnabled Previous header-footer setting.
104 * @param {print_preview.MarginType} marginType Previous margin type.
105 */
106 initialize: function(
107 isDocumentModifiable,
108 isDuplexEnabled,
109 isHeaderFooterEnabled,
110 marginType,
111 customMarginsInfo,
112 numberFormat,
113 measurementSystem) {
114
115 this.documentInfo_.isModifiable = isDocumentModifiable;
116
117 // Create capabilities that can be handled by Chromium.
118 this.capabilities_ = new print_preview.ChromiumCapabilities();
119 this.capabilities_.hasPageRangeCapability = true;
120 this.capabilities_.hasColorCapability = true;
121 this.capabilities_.hasCopiesCapability = true;
122 this.capabilities_.hasCollateCapability = true;
123 this.capabilities_.hasDuplexCapability = true;
124 if (isDocumentModifiable) {
125 this.capabilities_.hasOrientationCapability = true;
126 this.capabilities_.hasMarginsCapability = true;
127 this.capabilities_.hasHeaderFooterCapability = true;
128 }
129
130 var numberFormatSymbols =
131 print_preview.MeasurementSystem.parseNumberFormat(numberFormat);
132 this.measurementSystem_ = new print_preview.MeasurementSystem(
133 numberFormatSymbols[0], numberFormatSymbols[1], measurementSystem);
134
135 marginType = marginType != null ?
136 marginType : print_preview.Margins.Type.DEFAULT;
137 var customMargins = null;
138 if (marginType == print_preview.Margins.Type.CUSTOM) {
139 if (customMarginsInfo != null) {
140 customMargins = new print_preview.Margins(
141 customMarginsInfo[0], customMarginsInfo[1],
142 customMarginsInfo[2], customMarginsInfo[3],
143 this.measurementSystem_);
144 } else {
145 marginType = print_preview.Margins.Type.DEFAULT;
146 }
147 }
148
149 this.ticket_ = new print_preview.ChromiumPrintTicket(this.capabilities_);
150 this.ticket_.isDuplexEnabled = isDuplexEnabled;
151 this.ticket_.marginType = marginType;
152 this.ticket_.pageRangeStr = '';
153 if (marginType == print_preview.Margins.Type.CUSTOM) {
154 // TODO this.ticket_.customMargins = customMargins;
155 }
156 this.ticket_.isHeaderFooterEnabled = isHeaderFooterEnabled;
157
158 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.INITIALIZE);
159 },
160
161 createTicketForPreviewGenerator: function() {
162 if (!this.isTicketValid()) {
163 throw Error(
164 'Requesting ticket for preview generator when ticket is not valid');
165 }
166
167 var settings = {
168 'pageRange': [], // TODO this.ticket_.pageRangeSequence,
169 'landscape': this.ticket_.isLandscapeEnabled,
170 'color': this.ticket_.colorMode,
171 'headerFooterEnabled': this.ticket_.isHeaderFooterEnabled,
172 'marginsType': this.ticket_.marginType,
173
174 // This field seems to issue a reloadPreviewPages call when true.
175 'generateDraftData': true, // TODO What should this value be?
176
177 // NOTE: Even though the following fields don't directly relate to the
178 // preview, they still need to be included.
179 'duplex': this.ticket_.duplexMode,
180 'copies': this.getCopies(),
181 'collate': this.ticket_.isCollateEnabled,
182 'previewModifiable': this.documentInfo_.isModifiable,
183 'printToPDF': false,
184 'printWithCloudPrint': false,
185 'deviceName': 'foo',
186 'cloudPrintID': 'foo'
187 };
188
189 if (this.ticket_.marginType == print_preview.Margins.Type.CUSTOM) {
190 // TODO settings['marginsCustom'] =
191 }
192
193 return settings;
194 },
195
196 updateDestinationCapabilities: function(caps) {
197 if (this.capabilities_.hasPageRangeCapability =
198 caps.hasPageRangeCapability) {
199 this.capabilities_.defaultPageRangeStr = caps.defaultPageRangeStr;
200 }
201 if (this.capabilities_.hasColorCapability = caps.hasColorCapability) {
202 this.capabilities_.defaultIsColorEnabled = caps.defaultIsColorEnabled;
203 }
204 if (this.capabilities_.hasCopiesCapability = caps.hasCopiesCapability) {
205 this.capabilities_.defaultCopiesStr = caps.defaultCopiesStr;
206 }
207 if (this.capabilities_.hasCollateCapability = caps.hasCollateCapability) {
208 this.capabilities_.defaultIsCollateEnabled =
209 caps.defaultIsCollateEnabled;
210 }
211 if (this.capabilities_.hasDuplexCapability = caps.hasDuplexCapability) {
212 this.capabilities_.defaultIsDuplexEnabled = caps.defaultIsDuplexEnabled;
213 }
214 if (this.documentInfo_.isModifiable) {
215 if (this.capabilities_.hasOrientationCapability =
216 caps.hasOrientationCapability) {
217 this.capabilities_.defaultIsLandscapeEnabled =
218 caps.defaultIsLandscapeEnabled;
219 }
220 if (this.capabilities_.hasMarginsCapability =
221 caps.hasMarginsCapability) {
222 this.capabilities_.defaultMarginType = caps.defaultMarginType;
223 }
224 if (this.capabilities_.hasHeaderFooterCapability =
225 caps.hasHeaderFooterCapability) {
226 this.capabilities_.defaultIsHeaderFooterEnabled =
227 caps.defaultIsHeaderFooterEnabled;
228 }
229 }
230 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.CAPABILITIES_CHANGE);
231 },
232
233 updatePageCount: function(pageCount) {
234 if (this.documentInfo_.pageCount != pageCount) {
235 log('print_preview.PrintTicketStore.updatePageCount -- updating count to ' + pageCount);
236 this.documentInfo_.pageCount = pageCount;
237 this.pageNumberSet_ = null;
238 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.DOCUMENT_CHANGE);
239 }
240 },
241
242 hasCopiesCapability: function() {
243 return this.capabilities_.hasCopiesCapability;
244 },
245
246 isCopiesValid: function() {
247 return this.isCopiesValidForValue(this.getCopiesStr());
248 },
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 getCopies: function() {
262 return parseInt(this.getCopiesStr());
263 },
264
265 getCopiesStr: function() {
266 return this.ticket_.copiesStr;
267 },
268
269 updateCopies: function(copies) {
270 if (!this.capabilities_.hasCopiesCapability) {
271 throw Error(
272 'Updating copies capability but destination does not have a ' +
273 'copies capability');
274 }
275 if (this.ticket_.copiesStr != copies) {
276 this.ticket_.copiesStr = copies;
277 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
278 }
279 },
280
281 hasCollateCapability: function() {
282 return this.capabilities_.hasCollateCapability;
283 },
284
285 isCollateEnabled: function() {
286 return this.ticket_.isCollateEnabled;
287 },
288
289 updateCollate: function(isCollate) {
290 if (!this.capabilities_.hasCollateCapability) {
291 throw Error(
292 'Updating collate capability but destination does not have a ' +
293 'collate capability');
294 }
295 if (this.ticket_.isCollateEnabled != isCollate) {
296 this.ticket_.isCollateEnabled = isCollate;
297 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
298 }
299 },
300
301 hasColorCapability: function() {
302 return this.capabilities_.hasColorCapability;
303 },
304
305 isColorEnabled: function() {
306 return this.ticket_.isColorEnabled;
307 },
308
309 /**
310 * @param {boolean} isColor Whether the color option is enabled.
311 */
312 updateColor: function(isColor) {
313 if (!this.capabilities_.hasColorCapability) {
314 throw Error(
315 'Updating color capability but destination does not have a color ' +
316 'capability');
317 }
318 if (this.ticket_.isColorEnabled != isColor) {
319 this.ticket_.isColorEnabled = isColor;
320 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
321 }
322 },
323
324 /** @return {boolean} Whether the header-footer capability is available. */
325 hasHeaderFooterCapability: function() {
326 if (!this.capabilities_.hasHeaderFooterCapability) {
327 return false;
328 }
329 // Checks the printable area and updates the visibility of header footer
330 // option based on the selected margins.
331 return true;
332 // TODO
333 // var headerFooterApplies = true;
334 // if (marginsType ==
335 // print_preview.MarginSettings.MARGINS_VALUE_NO_MARGINS ||
336 // !previewModifiable) {
337 // headerFooterApplies = false;
338 // } else if (marginsType !=
339 // print_preview.MarginSettings.MARGINS_VALUE_MINIMUM) {
340 // if (cr.isLinux || cr.isChromeOS) {
341 // headerFooterApplies = pageLayout.marginTop > 0 ||
342 // pageLayout.marginBottom > 0;
343 // } else {
344 // var pageHeight = pageLayout.marginTop + pageLayout.marginBottom +
345 // pageLayout.contentHeight;
346 // headerFooterApplies =
347 // (pageLayout.marginTop > pageLayout.printableAreaY) ||
348 // (pageLayout.marginBottom >
349 // (pageHeight - pageLayout.printableAreaY -
350 // pageLayout.printableAreaHeight));
351 // }
352 // }
353 // this.setVisible_(headerFooterApplies);
354 },
355
356 /** @return {boolean} Whether the header-footer setting is enabled. */
357 isHeaderFooterEnabled: function() {
358 return this.ticket_.isHeaderFooterEnabled;
359 },
360
361 updateHeaderFooter: function(isHeaderFooterEnabled) {
362 if (!this.capabilities_.hasHeaderFooterCapability) {
363 throw Error(
364 'Updating header-footer capability but destination does not have ' +
365 'a header-footer capability');
366 }
367 if (this.ticket_.isHeaderFooterEnabled != isHeaderFooterEnabled) {
368 this.ticket_.isHeaderFooterEnabled = isHeaderFooterEnabled;
369 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
370 }
371 },
372
373 hasOrientationCapability: function() {
374 // TODO Is this true? Maybe we can still rotate if the document is not
375 // modifiable. This is the old behavior.
376 return this.capabilities_.hasOrientationCapability;
377 },
378
379 isLandscapeEnabled: function() {
380 return this.ticket_.isLandscapeEnabled;
381 },
382
383 updateOrientation: function(isLandscape) {
384 if (!this.capabilities_.hasOrientationCapability) {
385 throw Error(
386 'Updating orientation capability but destination does not have ' +
387 'an orientation capability');
388 }
389 if (this.ticket_.isLandscapeEnabled != isLandscape) {
390 this.ticket_.isLandscapeEnabled = isLandscape;
391 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
392 }
393 },
394
395 hasDuplexCapability: function() {
396 return this.capabilities_.hasDuplexCapability;
397 },
398
399 isDuplexEnabled: function() {
400 return this.ticket_.isDuplexEnabled;
401 },
402
403 updateDuplex: function(isDuplex) {
404 if (!this.capabilities_.hasDuplexCapability) {
405 throw Error(
406 'Updating duplex capability but destination does not have a ' +
407 'duplex capability');
408 }
409 if (this.ticket_.isDuplexEnabled != isDuplex) {
410 this.ticket_.isDuplexEnabled = isDuplex;
411 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
412 }
413 },
414
415 hasMarginCapability: function() {
416 return this.capabilities_.hasMarginCapability;
417 },
418
419 getMarginType: function() {
420 return this.ticket_.marginType;
421 },
422
423 updateMarginType: function() {
424 if (!this.capabilities_.hasMarginsCapability) {
425 throw Error(
426 'Updating margins capability but destination does not have a ' +
427 'margin capability');
428 }
429 // TODO
430 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
431 },
432
433 hasPageRangeCapability: function() {
434 return this.capabilities_.hasPageRangeCapability;
435 },
436
437 isPageRangeValid: function() {
438 var pageRangeStr = this.ticket_.pageRangeStr;
439 return pageRangeStr == '' ||
440 isPageRangeTextValid(pageRangeStr, this.documentInfo_.pageCount);
441 },
442
443 getPageRangeStr: function() {
444 return this.ticket_.pageRangeStr;
445 },
446
447 getPageNumberSet: function() {
448 if (this.pageNumberSet_ == null) {
449 this.pageNumberSet_ = print_preview.PageNumberSet.parse(
450 this.ticket_.pageRangeStr, this.documentInfo_.pageCount);
451 }
452 return this.pageNumberSet_;
453 },
454
455 updatePageRange: function(pageRangeStr) {
456 if (!this.capabilities_.hasPageRangeCapability) {
457 throw Error(
458 'Updating page-range capability but destination does not have a ' +
459 'page-range capability');
460 }
461 log('print_preview.PrintTicketStore.updatePageRange -- trying update page range str to ' + pageRangeStr);
462 if (this.ticket_.pageRangeStr != pageRangeStr) {
463 this.ticket_.pageRangeStr = pageRangeStr;
464 this.pageNumberSet_ = null;
465 cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
466 } else {
467 log('print_preview.PrintTicketStore.updatePageRange -- ignoring because no change');
468 }
469 },
470
471 /**
472 * Checking if the stored print ticket is valid.
473 * @return {boolean} {@code true} if the stored print ticket is valid,
474 * {@code false} otherwise.
475 */
476 isTicketValid: function() {
477 // TODO Validate margins
478 return this.isCopiesValid() && this.isPageRangeValid();
479 },
480
481 serializeTicket: function() {
482 return 'persisted ticket';
483 },
484
485 /**
486 * Generates a print ticket suitable for sending to Google Cloud Print.
487 * @return {string} Serialized form of a Google Cloud Print print ticket.
488 */
489 createTicketForCloudPrint: function() {
490 // TODO
491 },
492
493 /**
494 * Generates a print ticket suitable for sending to Chromium.
495 * @return {Object} Object to send to Chromium.
496 */
497 createTicketForChromium: function() {
498 // TODO
499 }
500 };
501
502 /**
503 * Object which contains information related to the document to print.
504 * @constructor
505 */
506 function DocumentInfo() {
507 this.isModifiable = true;
508 this.pageCount = 1;
509 this.hasPageSizeStyle = false;
510 this.pageLayout = null;
511 };
512
513 // Export
514 return {
515 PrintTicketStore: PrintTicketStore
516 };
517 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698