summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/ui/webui/print_preview/print_preview_ui.h
blob: 2aca55e7bc1d73211ac5aedc9a6e4e727dd6bd9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_UI_H_
#define CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_UI_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"

struct PrintHostMsg_DidStartPreview_Params;
struct PrintHostMsg_PreviewIds;
struct PrintHostMsg_RequestPrintPreview_Params;
struct PrintHostMsg_SetOptionsFromDocument_Params;

namespace base {
class DictionaryValue;
class FilePath;
class RefCountedMemory;
}

namespace gfx {
class Rect;
}

namespace printing {

class PrintPreviewHandler;
struct PageSizeMargins;

class PrintPreviewUI : public ConstrainedWebDialogUI {
 public:
  explicit PrintPreviewUI(content::WebUI* web_ui);

  ~PrintPreviewUI() override;

  // Gets the print preview |data|. |index| is zero-based, and can be
  // |COMPLETE_PREVIEW_DOCUMENT_INDEX| to get the entire preview document.
  virtual void GetPrintPreviewDataForIndex(
      int index,
      scoped_refptr<base::RefCountedMemory>* data) const;

  // Setters
  void SetInitiatorTitle(const base::string16& initiator_title);

  const base::string16& initiator_title() const { return initiator_title_; }

  bool source_is_modifiable() const { return source_is_modifiable_; }

  bool source_has_selection() const { return source_has_selection_; }

  bool print_selection_only() const { return print_selection_only_; }

  int pages_per_sheet() const { return pages_per_sheet_; }

  const gfx::Rect& printable_area() const { return printable_area_; }

  const gfx::Size& page_size() const { return page_size_; }

  // Returns true if |page_number| is the last page in |pages_to_render_|.
  // |page_number| is a 0-based number.
  bool LastPageComposited(int page_number) const;

  // Get the 0-based index of the |page_number| in |pages_to_render_|.
  // Same as above, |page_number| is a 0-based number.
  int GetPageToNupConvertIndex(int page_number) const;

  std::vector<base::ReadOnlySharedMemoryRegion> TakePagesForNupConvert();

  // Save pdf pages temporarily before ready to do N-up conversion.
  void AddPdfPageForNupConversion(base::ReadOnlySharedMemoryRegion pdf_page);

  // PrintPreviewUI serves data for chrome://print requests.
  //
  // The format for requesting PDF data is as follows:
  //   chrome://print/<PrintPreviewUIID>/<PageIndex>/print.pdf
  //
  // Required parameters:
  //   <PrintPreviewUIID> = PrintPreview UI ID
  //   <PageIndex> = Page index is zero-based or
  //                 |COMPLETE_PREVIEW_DOCUMENT_INDEX| to represent
  //                 a print ready PDF.
  //
  // Example:
  //   chrome://print/123/10/print.pdf
  //
  // ParseDataPath() takes a path (i.e. what comes after chrome://print/) and
  // returns true if the path seems to be a valid data path. |ui_id| and
  // |page_index| are set to the parsed values if the provided pointers aren't
  // nullptr.
  static bool ParseDataPath(const std::string& path,
                            int* ui_id,
                            int* page_index);

  // Set initial settings for PrintPreviewUI.
  static void SetInitialParams(
      content::WebContents* print_preview_dialog,
      const PrintHostMsg_RequestPrintPreview_Params& params);

  // Determines whether to cancel a print preview request based on the request
  // and UI ids in |ids|.
  // Can be called from any thread.
  static bool ShouldCancelRequest(const PrintHostMsg_PreviewIds& ids);

  // Returns an id to uniquely identify this PrintPreviewUI.
  base::Optional<int32_t> GetIDForPrintPreviewUI() const;

  // Notifies the Web UI of a print preview request with |request_id|.
  virtual void OnPrintPreviewRequest(int request_id);

  // Notifies the Web UI about the properties of the request preview.
  void OnDidStartPreview(const PrintHostMsg_DidStartPreview_Params& params,
                         int request_id);

  // Notifies the Web UI of the default page layout according to the currently
  // selected printer and page size.
  void OnDidGetDefaultPageLayout(const PageSizeMargins& page_layout,
                                 const gfx::Rect& printable_area,
                                 bool has_custom_page_size_style,
                                 int request_id);

  // Notifies the Web UI that the 0-based page |page_number| rendering is being
  // processed and an OnPendingPreviewPage() call is imminent. Returns whether
  // |page_number| is the expected page.
  bool OnPendingPreviewPage(int page_number);

  // Notifies the Web UI that the 0-based page |page_number| has been rendered.
  // |preview_request_id| indicates which request resulted in this response.
  void OnDidPreviewPage(int page_number,
                        scoped_refptr<base::RefCountedMemory> data,
                        int preview_request_id);

  // Notifies the Web UI renderer that preview data is available.
  // |expected_pages_count| specifies the total number of pages.
  // |preview_request_id| indicates which request resulted in this response.
  void OnPreviewDataIsAvailable(int expected_pages_count,
                                scoped_refptr<base::RefCountedMemory> data,
                                int preview_request_id);

  // Notifies the Web UI that the print preview failed to render for the request
  // with id = |request_id|.
  void OnPrintPreviewFailed(int request_id);

  // Notified the Web UI that this print preview dialog's RenderProcess has been
  // closed, which may occur for several reasons, e.g. tab closure or crash.
  void OnPrintPreviewDialogClosed();

  // Notifies the Web UI that the preview request identified by |request_id|
  // was cancelled.
  void OnPrintPreviewCancelled(int request_id);

  // Notifies the Web UI that initiator is closed, so we can disable all the
  // controls that need the initiator for generating the preview data.
  void OnInitiatorClosed();

  // Notifies the Web UI that the printer is unavailable or its settings are
  // invalid. |request_id| is the preview request id with the invalid printer.
  void OnInvalidPrinterSettings(int request_id);

  // Notifies the Web UI to cancel the pending preview request.
  virtual void OnCancelPendingPreviewRequest();

  // Hides the print preview dialog.
  virtual void OnHidePreviewDialog();

  // Closes the print preview dialog.
  virtual void OnClosePrintPreviewDialog();

  // Notifies the WebUI to set print preset options from source PDF.
  void OnSetOptionsFromDocument(
      const PrintHostMsg_SetOptionsFromDocument_Params& params,
      int request_id);

  // Allows tests to wait until the print preview dialog is loaded.
  class TestDelegate {
   public:
    virtual void DidGetPreviewPageCount(int page_count) = 0;
    virtual void DidRenderPreviewPage(content::WebContents* preview_dialog) = 0;

   protected:
    virtual ~TestDelegate() = default;
  };

  static void SetDelegateForTesting(TestDelegate* delegate);

  // Allows for tests to set a file path to print a PDF to. This also initiates
  // the printing without having to click a button on the print preview dialog.
  void SetSelectedFileForTesting(const base::FilePath& path);

  // Passes |closure| to PrintPreviewHandler::SetPdfSavedClosureForTesting().
  void SetPdfSavedClosureForTesting(base::OnceClosure closure);

  // Tell the handler to send the enable-manipulate-settings-for-test WebUI
  // event.
  void SendEnableManipulateSettingsForTest();

  // Tell the handler to send the manipulate-settings-for-test WebUI event
  // to set the print preview settings contained in |settings|.
  void SendManipulateSettingsForTest(const base::DictionaryValue& settings);

  // See SetPrintPreviewDataForIndex().
  void SetPrintPreviewDataForIndexForTest(
      int index,
      scoped_refptr<base::RefCountedMemory> data);

  // See ClearAllPreviewData().
  void ClearAllPreviewDataForTest();

  // Sets a new valid Print Preview UI ID for this instance. Called by
  // PrintPreviewHandler in OnJavascriptAllowed().
  void SetPreviewUIId();

  // Clears the UI ID. Called by PrintPreviewHandler in
  // OnJavascriptDisallowed().
  void ClearPreviewUIId();

 protected:
  // Alternate constructor for tests
  PrintPreviewUI(content::WebUI* web_ui,
                 std::unique_ptr<PrintPreviewHandler> handler);

 private:
  FRIEND_TEST_ALL_PREFIXES(PrintPreviewDialogControllerUnitTest,
                           TitleAfterReload);

  // Sets the print preview |data|. |index| is zero-based, and can be
  // |COMPLETE_PREVIEW_DOCUMENT_INDEX| to set the entire preview document.
  void SetPrintPreviewDataForIndex(int index,
                                   scoped_refptr<base::RefCountedMemory> data);

  // Clear the existing print preview data.
  void ClearAllPreviewData();

  base::TimeTicks initial_preview_start_time_;

  // The unique ID for this class instance. Stored here to avoid calling
  // GetIDForPrintPreviewUI() everywhere.
  base::Optional<int32_t> id_;

  // Weak pointer to the WebUI handler.
  PrintPreviewHandler* const handler_;

  // Indicates whether the source document can be modified.
  bool source_is_modifiable_ = true;

  // Indicates whether the source document has selection.
  bool source_has_selection_ = false;

  // Indicates whether only the selection should be printed.
  bool print_selection_only_ = false;

  // Keeps track of whether OnClosePrintPreviewDialog() has been called or not.
  bool dialog_closed_ = false;

  // Store the initiator title, used for populating the print preview dialog
  // title.
  base::string16 initiator_title_;

  // The list of 0-based page numbers that will be rendered.
  std::vector<int> pages_to_render_;

  // The list of pages to be converted.
  std::vector<base::ReadOnlySharedMemoryRegion> pages_for_nup_convert_;

  // Index into |pages_to_render_| for the page number to expect.
  size_t pages_to_render_index_ = 0;

  // number of pages per sheet and should be greater or equal to 1.
  int pages_per_sheet_ = 1;

  // Physical size of the page, including non-printable margins.
  gfx::Size page_size_;

  // The printable area of the printed document pages.
  gfx::Rect printable_area_;

  DISALLOW_COPY_AND_ASSIGN(PrintPreviewUI);
};

}  // namespace printing

#endif  // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_UI_H_