OLD | NEW |
---|---|
(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 cr.define('print_preview', function() { | |
6 'use strict'; | |
7 | |
8 // TODO Need to handle termination case--detach event listeners from native | |
9 // layer. | |
10 | |
11 /** | |
12 * Interface to the Chromium print preview generator. | |
13 * | |
14 * @param {!print_preview.DestinationStore} destinationStore Used to get the | |
15 * currently selected destination. | |
16 * @param {!print_preview.PrintTicketStore} printTicketStore Used to read the | |
17 * state of the ticket and write document information. | |
18 * @param {!print_preview.NativeLayer} nativeLayer Used to communicate to | |
19 * Chromium's preview rendering system. | |
20 * @constructor | |
21 * @extends {cr.EventTarget} | |
22 */ | |
23 function PreviewGenerator(destinationStore, printTicketStore, nativeLayer) { | |
24 cr.EventTarget.call(this); | |
25 | |
26 /** | |
27 * Used to get the currently selected destination. | |
28 * @type {!print_preview.DestinationStore} | |
29 * @private | |
30 */ | |
31 this.destinationStore_ = destinationStore; | |
32 | |
33 /** | |
34 * Used to read the state of the ticket and write document information. | |
35 * @type {!print_preview.PrintTicketStore} | |
36 * @private | |
37 */ | |
38 this.printTicketStore_ = printTicketStore; | |
39 | |
40 /** | |
41 * Interface to the Chromium native layer. | |
42 * @type {!print_preview.NativeLayer} | |
43 * @private | |
44 */ | |
45 this.nativeLayer_ = nativeLayer; | |
46 | |
47 /** | |
48 * ID of current in-flight request. Requests that do not share this ID will | |
49 * be ignored. | |
50 * @type {number} | |
51 * @private | |
52 */ | |
53 this.inFlightRequestId_ = -1; | |
54 | |
55 /** | |
56 * Whether the previews are being generated in landscape mode. | |
57 * @type {boolean} | |
58 * @private | |
59 */ | |
60 this.isLandscapeEnabled_ = false; | |
61 | |
62 /** | |
63 * Whether the previews are being generated with a header and footer. | |
64 * @type {boolean} | |
65 * @private | |
66 */ | |
67 this.isHeaderFooterEnabled_ = false; | |
68 | |
69 /** | |
70 * Whether the previews are being generated in color. | |
71 * @type {boolean} | |
72 * @private | |
73 */ | |
74 this.isColorEnabled_ = false; | |
75 | |
76 /** | |
77 * Page number set used to generate the last preview. | |
78 * @type {print_preview.PageNumberSet} | |
79 * @private | |
80 */ | |
81 this.pageNumberSet_ = null; | |
82 | |
83 /** | |
84 * Margins type used to generate the last preview. | |
85 * @type {print_preview.Margins.Type} | |
86 * @private | |
87 */ | |
88 this.marginsType_ = print_preview.Margins.Type.DEFAULT; | |
89 | |
90 /** | |
91 * Custom margins used to generate the last preview. | |
92 * @type {print_preview.Margins} | |
93 * @private | |
94 */ | |
95 this.customMargins_ = null; | |
96 | |
97 /** | |
98 * Event tracker used to keep track of native layer events. | |
99 * @type {!EventTracker} | |
100 * @private | |
101 */ | |
102 this.tracker_ = new EventTracker(); | |
103 | |
104 this.addEventListeners_(); | |
105 }; | |
106 | |
107 /** | |
108 * Events dispatched by the preview generator. | |
109 * @enum {string} | |
110 */ | |
111 PreviewGenerator.Event = { | |
112 // Dispatched when the document can be printed. | |
113 DOCUMENT_READY: 'print_preview.PreviewGenerator.DOCUMENT_READY', | |
114 | |
115 // Dispatched when a page preview is ready. The previewIndex field of the | |
116 // event is the index of the page in the modified document, not the | |
117 // original. So page 4 of the original document might be previewIndex = 0 of | |
118 // the modified document. | |
119 PAGE_READY: 'print_preview.PreviewGenerator.PAGE_READY', | |
120 | |
121 // Dispatched when the current print preview request fails. | |
122 FAIL: 'print_preview.PreviewGenerator.FAIL' | |
123 }; | |
124 | |
125 PreviewGenerator.prototype = { | |
126 __proto__: cr.EventTarget.prototype, | |
127 | |
128 /** @override */ | |
129 dispatchEvent: function(evt) { | |
130 // TODO REMOVE ME | |
131 log(evt.type); | |
132 cr.EventTarget.prototype.dispatchEvent.call(this, evt); | |
133 }, | |
134 | |
135 /** | |
136 * Request that new preview be generated. A preview request will not be | |
137 * generated if the print ticket has not changed sufficiently. | |
138 */ | |
139 requestPreview: function() { | |
140 if (this.hasPreviewChanged_()) { | |
141 log('print_preview.PreviewGenerator.requestPreview'); | |
142 this.isLandscapeEnabled_ = this.printTicketStore_.isLandscapeEnabled(); | |
143 this.isHeaderFooterEnabled_ = | |
144 this.printTicketStore_.isHeaderFooterEnabled(); | |
145 this.isColorEnabled_ = this.printTicketStore_.isColorEnabled(); | |
146 this.pageNumberSet_ = this.printTicketStore_.getPageNumberSet(); | |
147 this.marginsType_ = this.printTicketStore_.getMarginsType(); | |
148 this.customMargins_ = this.printTicketStore_.getCustomMargins(); | |
149 | |
150 this.inFlightRequestId_++; | |
151 this.nativeLayer_.startGetPreview( | |
152 this.destinationStore_.selectedDestination, | |
153 this.printTicketStore_, | |
154 this.inFlightRequestId_); | |
155 } | |
156 }, | |
157 | |
158 /** Removes all event listeners that the preview generator has attached. */ | |
159 removeEventListeners: function() { | |
160 this.tracker_.removeAll(); | |
161 }, | |
162 | |
163 /** | |
164 * Adds event listeners to the relevant native layer events. | |
165 * @private | |
166 */ | |
167 addEventListeners_: function() { | |
168 this.tracker_.add( | |
169 this.nativeLayer_, | |
170 print_preview.NativeLayer.Event.PAGE_LAYOUT_CHANGE, | |
171 this.onPageLayoutChange_.bind(this)); | |
172 this.tracker_.add( | |
173 this.nativeLayer_, | |
174 print_preview.NativeLayer.Event.PAGE_COUNT_CHANGE, | |
175 this.onPageCountChange_.bind(this)); | |
176 this.tracker_.add( | |
177 this.nativeLayer_, | |
178 print_preview.NativeLayer.Event.PREVIEW_RELOAD, | |
179 this.onPreviewReload_.bind(this)); | |
180 this.tracker_.add( | |
181 this.nativeLayer_, | |
182 print_preview.NativeLayer.Event.PAGE_PREVIEW_READY, | |
183 this.onPagePreviewReady_.bind(this)); | |
184 this.tracker_.add( | |
185 this.nativeLayer_, | |
186 print_preview.NativeLayer.Event.PREVIEW_GENERATION_DONE, | |
187 this.onPreviewGenerationDone_.bind(this)); | |
188 this.tracker_.add( | |
189 this.nativeLayer_, | |
190 print_preview.NativeLayer.Event.PREVIEW_GENERATION_FAIL, | |
191 this.onPreviewGenerationFail_.bind(this)); | |
192 }, | |
193 | |
194 /** | |
195 * Dispatches a PAGE_READY event to signal that a page preview is ready. | |
196 * @param {number} previewIndex Index of the page with respect to the pages | |
197 * shown in the preview. E.g an index of 0 might be the fifth page in | |
dpapad
2012/04/24 01:24:56
Took me a while to parse this comment. I think it
Robert Toscano
2012/04/24 22:29:56
Done.
| |
198 * in the document, but it will be the first page to be shown in the | |
199 * preview. | |
200 * @param {number} pageNumber Number of the page with respect to the | |
201 * document. A value of 3 means it's the third page of the document. | |
202 * @param {string} previewUid Unique identifier of the preview. | |
203 * @private | |
204 */ | |
205 dispatchPageReadyEvent_: function(previewIndex, pageNumber, previewUid) { | |
206 var pageGenEvt = new cr.Event(PreviewGenerator.Event.PAGE_READY); | |
207 pageGenEvt.previewIndex = previewIndex; | |
208 pageGenEvt.previewUrl = | |
209 'chrome://print/' + previewUid + '/' + (pageNumber - 1) + | |
210 '/print.pdf'; | |
211 this.dispatchEvent(pageGenEvt); | |
212 }, | |
213 | |
214 /** | |
215 * Called when the page layout of the document has changed. Always occurs | |
216 * as a result of a preview request. | |
217 * @param {cr.Event} evt Contains layout info about the document. | |
218 * @private | |
219 */ | |
220 onPageLayoutChange_: function(evt) { | |
221 // NOTE: A request ID is not specified, so assuming its for the current | |
222 // in-flight request. | |
223 | |
224 // TODO Do we need this? | |
225 //var hasCustomPageSizeStyle = evt.hasCustomPageSizeStyle; | |
226 | |
227 // Printable area info is unavailable on linux nor Google Chrome OS. | |
228 // TODO Maybe we can not have to have this if condition, and always set | |
229 // printable area? | |
230 log(JSON.stringify(evt.pageLayout)); | |
231 if (!cr.isLinux && !cr.isChromeOS) { | |
232 var origin = new print_preview.Coordinate2d( | |
233 evt.pageLayout.printableAreaX, | |
234 evt.pageLayout.printableAreaY); | |
235 var size = new print_preview.Size( | |
236 evt.pageLayout.printableAreaWidth, | |
237 evt.pageLayout.printableAreaHeight); | |
238 this.printTicketStore_.updatePrintableArea( | |
239 new print_preview.PrintableArea(origin, size)); | |
240 } // TODO else create a default printable area? | |
241 | |
242 var margins = new print_preview.Margins( | |
243 evt.pageLayout.marginTop, | |
244 evt.pageLayout.marginRight, | |
245 evt.pageLayout.marginBottom, | |
246 evt.pageLayout.marginLeft); | |
247 if (this.printTicketStore_.hasMarginsCapability()) { | |
248 this.printTicketStore_.updateCustomMargins(margins); | |
249 } | |
250 | |
251 var pageSize = new print_preview.Size( | |
252 evt.pageLayout.contentWidth + margins.left + margins.right, | |
253 evt.pageLayout.contentHeight + margins.top + margins.bottom); | |
254 this.printTicketStore_.updatePageSize(pageSize); | |
255 }, | |
256 | |
257 /** | |
258 * Called when the document page count is received from the native layer. | |
259 * Always occurs as a result of a preview request. | |
260 * @param {cr.Event} evt Contains the document's page count. | |
261 * @private | |
262 */ | |
263 onPageCountChange_: function(evt) { | |
264 if (this.inFlightRequestId_ != evt.previewResponseId) { | |
265 return; // Ignore old response. | |
266 } | |
267 this.printTicketStore_.updatePageCount(evt.pageCount); | |
268 }, | |
269 | |
270 /** | |
271 * Called when the print preview should be reloaded. | |
272 * @param {cr.Event} evt Contains the preview UID and request ID. | |
273 * @private | |
274 */ | |
275 onPreviewReload_: function(evt) { | |
276 if (this.inFlightRequestId_ != evt.previewResponseId) { | |
277 return; // Ignore old response. | |
278 } | |
279 var pageNumberSet = this.printTicketStore_.getPageNumberSet(); | |
280 for (var i = 0; i < pageNumberSet.size; i++) { | |
281 var pageNumber = pageNumberSet.getPageNumberAt(i); | |
282 this.dispatchPageReadyEvent_(i, pageNumber, evt.previewUid); | |
283 } | |
284 }, | |
285 | |
286 /** | |
287 * Called when a page's preview has been generated. Dispatches a | |
288 * PAGE_READY event. | |
289 * @param {cr.Event} evt Contains the page index and preview UID. | |
290 * @private | |
291 */ | |
292 onPagePreviewReady_: function(evt) { | |
293 if (this.inFlightRequestId_ != evt.previewResponseId) { | |
294 return; // Ignore old response. | |
295 } | |
296 var pageNumber = evt.pageIndex + 1; | |
297 if (this.printTicketStore_.getPageNumberSet().hasPageNumber(pageNumber)) { | |
298 var previewIndex = this.printTicketStore_.getPageNumberSet() | |
299 .getPageNumberIndex(pageNumber); | |
300 this.dispatchPageReadyEvent_(previewIndex, pageNumber, evt.previewUid); | |
301 } | |
302 }, | |
303 | |
304 /** | |
305 * Called when the preview generation is complete. Dispatches a | |
306 * DOCUMENT_READY event. | |
307 * @param {cr.Event} evt Contains the preview UID and response ID. | |
308 * @private | |
309 */ | |
310 onPreviewGenerationDone_: function(evt) { | |
311 if (this.inFlightRequestId_ != evt.previewResponseId) { | |
312 return; // Ignore old response. | |
313 } | |
314 }, | |
315 | |
316 /** | |
317 * Called when the preview generation fails. | |
318 * @private | |
319 */ | |
320 onPreviewGenerationFail_: function() { | |
321 // NOTE: No request ID is returned from Chromium so its assumed its the | |
322 // current one. | |
323 cr.dispatchSimpleEvent(this, PreviewGenerator.Event.FAIL); | |
324 }, | |
325 | |
326 /** | |
327 * @return {boolean} Whether the print ticket has changed sufficiently to | |
328 * determine whether a new preview request should be issued. | |
329 * @private | |
330 */ | |
331 hasPreviewChanged_: function() { | |
332 var ticketStore = this.printTicketStore_; | |
333 return this.inFlightRequestId_ == -1 || | |
334 ticketStore.isLandscapeEnabled() != this.isLandscapeEnabled_ || | |
335 ticketStore.isHeaderFooterEnabled() != this.isHeaderFooterEnabled_ || | |
336 ticketStore.isColorEnabled() != this.isColorEnabled_ || | |
337 !ticketStore.getPageNumberSet().equals(this.pageNumberSet_) || | |
338 ticketStore.getMarginsType() != this.marginsType_ || | |
339 (this.marginsType_ == print_preview.Margins.Type.CUSTOM && | |
340 !ticketStore.getCustomMargins().equals(this.customMargins_)); | |
341 } | |
342 }; | |
343 | |
344 // Export | |
345 return { | |
346 PreviewGenerator: PreviewGenerator | |
347 }; | |
348 }); | |
OLD | NEW |