blob: 58b98b83b3081251b316d4afa473fb737fa41350 [file] [log] [blame]
[email protected]73852b8f2010-05-14 00:38:121// Copyright (c) 2010 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#include "chrome/browser/printing/print_dialog_cloud.h"
6#include "chrome/browser/printing/print_dialog_cloud_internal.h"
7
[email protected]73852b8f2010-05-14 00:38:128#include "base/base64.h"
[email protected]e39027a2011-01-24 21:41:549#include "base/command_line.h"
[email protected]73852b8f2010-05-14 00:38:1210#include "base/file_util.h"
11#include "base/json/json_reader.h"
[email protected]73852b8f2010-05-14 00:38:1212#include "base/values.h"
13#include "chrome/browser/browser_list.h"
[email protected]017a7a112010-10-12 16:38:2714#include "chrome/browser/browser_thread.h"
[email protected]37858e52010-08-26 00:22:0215#include "chrome/browser/debugger/devtools_manager.h"
[email protected]73852b8f2010-05-14 00:38:1216#include "chrome/browser/dom_ui/dom_ui.h"
17#include "chrome/browser/dom_ui/dom_ui_util.h"
[email protected]ea161da2010-11-02 21:57:3518#include "chrome/browser/prefs/pref_service.h"
[email protected]2283eead2010-09-29 23:17:3019#include "chrome/browser/printing/cloud_print/cloud_print_url.h"
[email protected]8ecad5e2010-12-02 21:18:3320#include "chrome/browser/profiles/profile.h"
[email protected]e39027a2011-01-24 21:41:5421#include "chrome/browser/profiles/profile_manager.h"
[email protected]73852b8f2010-05-14 00:38:1222#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]37858e52010-08-26 00:22:0223#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]ea161da2010-11-02 21:57:3524#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]e39027a2011-01-24 21:41:5425#if defined(TOOLKIT_GTK)
26#include "chrome/browser/ui/gtk/html_dialog_gtk.h"
27#endif // defined(TOOLKIT_GTK)
28#if defined(TOOLKIT_VIEWS)
29#include "chrome/browser/ui/views/browser_dialogs.h"
30#endif // defined(TOOLKIT_VIEWS)
31#include "chrome/common/chrome_switches.h"
[email protected]73852b8f2010-05-14 00:38:1232#include "chrome/common/notification_observer.h"
33#include "chrome/common/notification_registrar.h"
34#include "chrome/common/notification_source.h"
[email protected]939856a2010-08-24 20:29:0235#include "chrome/common/notification_type.h"
[email protected]ea161da2010-11-02 21:57:3536#include "chrome/common/pref_names.h"
[email protected]939856a2010-08-24 20:29:0237#include "chrome/common/render_messages_params.h"
[email protected]73852b8f2010-05-14 00:38:1238#include "chrome/common/url_constants.h"
[email protected]c051a1b2011-01-21 23:30:1739#include "ui/base/l10n/l10n_util.h"
[email protected]939856a2010-08-24 20:29:0240#include "webkit/glue/webpreferences.h"
[email protected]73852b8f2010-05-14 00:38:1241
42#include "grit/generated_resources.h"
43
44// This module implements the UI support in Chrome for cloud printing.
45// This means hosting a dialog containing HTML/JavaScript and using
46// the published cloud print user interface integration APIs to get
47// page setup settings from the dialog contents and provide the
48// generated print PDF to the dialog contents for uploading to the
49// cloud print service.
50
51// Currently, the flow between these classes is as follows:
52
53// PrintDialogCloud::CreatePrintDialogForPdf is called from
54// resource_message_filter_gtk.cc once the renderer has informed the
55// renderer host that PDF generation into the renderer host provided
[email protected]032682b2011-01-12 22:05:0256// temp file has been completed. That call is on the FILE thread.
[email protected]73852b8f2010-05-14 00:38:1257// That, in turn, hops over to the UI thread to create an instance of
58// PrintDialogCloud.
59
60// The constructor for PrintDialogCloud creates a
61// CloudPrintHtmlDialogDelegate and asks the current active browser to
62// show an HTML dialog using that class as the delegate. That class
63// hands in the kCloudPrintResourcesURL as the URL to visit. That is
64// recognized by the GetDOMUIFactoryFunction as a signal to create an
65// ExternalHtmlDialogUI.
66
67// CloudPrintHtmlDialogDelegate also temporarily owns a
68// CloudPrintFlowHandler, a class which is responsible for the actual
69// interactions with the dialog contents, including handing in the PDF
70// print data and getting any page setup parameters that the dialog
71// contents provides. As part of bringing up the dialog,
72// HtmlDialogUI::RenderViewCreated is called (an override of
73// DOMUI::RenderViewCreated). That routine, in turn, calls the
74// delegate's GetDOMMessageHandlers routine, at which point the
75// ownership of the CloudPrintFlowHandler is handed over. A pointer
76// to the flow handler is kept to facilitate communication back and
77// forth between the two classes.
78
79// The DOMUI continues dialog bring-up, calling
80// CloudPrintFlowHandler::RegisterMessages. This is where the
81// additional object model capabilities are registered for the dialog
82// contents to use. It is also at this time that capabilities for the
83// dialog contents are adjusted to allow the dialog contents to close
84// the window. In addition, the pending URL is redirected to the
85// actual cloud print service URL. The flow controller also registers
86// for notification of when the dialog contents finish loading, which
87// is currently used to send the PDF data to the dialog contents.
88
89// In order to send the PDF data to the dialog contents, the flow
90// handler uses a CloudPrintDataSender. It creates one, letting it
91// know the name of the temporary file containing the PDF data, and
92// posts the task of reading the file
93// (CloudPrintDataSender::ReadPrintDataFile) to the file thread. That
94// routine reads in the file, and then hops over to the IO thread to
95// send that data to the dialog contents.
96
97// When the dialog contents are finished (by either being cancelled or
98// hitting the print button), the delegate is notified, and responds
99// that the dialog should be closed, at which point things are torn
100// down and released.
101
102// TODO(scottbyer):
103// http://code.google.com/p/chromium/issues/detail?id=44093 The
104// high-level flow (where the PDF data is generated before even
105// bringing up the dialog) isn't what we want.
106
[email protected]73852b8f2010-05-14 00:38:12107namespace internal_cloud_print_helpers {
108
[email protected]73852b8f2010-05-14 00:38:12109bool GetRealOrInt(const DictionaryValue& dictionary,
[email protected]a65175d2010-08-17 04:00:57110 const std::string& path,
[email protected]73852b8f2010-05-14 00:38:12111 double* out_value) {
112 if (!dictionary.GetReal(path, out_value)) {
113 int int_value = 0;
114 if (!dictionary.GetInteger(path, &int_value))
115 return false;
116 *out_value = int_value;
117 }
118 return true;
119}
120
121// From the JSON parsed value, get the entries for the page setup
122// parameters.
123bool GetPageSetupParameters(const std::string& json,
124 ViewMsg_Print_Params& parameters) {
125 scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false));
126 DLOG_IF(ERROR, (!parsed_value.get() ||
127 !parsed_value->IsType(Value::TYPE_DICTIONARY)))
128 << "PageSetup call didn't have expected contents";
129 if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY))
130 return false;
131
132 bool result = true;
133 DictionaryValue* params = static_cast<DictionaryValue*>(parsed_value.get());
[email protected]a65175d2010-08-17 04:00:57134 result &= GetRealOrInt(*params, "dpi", &parameters.dpi);
135 result &= GetRealOrInt(*params, "min_shrink", &parameters.min_shrink);
136 result &= GetRealOrInt(*params, "max_shrink", &parameters.max_shrink);
137 result &= params->GetBoolean("selection_only", &parameters.selection_only);
[email protected]73852b8f2010-05-14 00:38:12138 return result;
139}
140
141void CloudPrintDataSenderHelper::CallJavascriptFunction(
142 const std::wstring& function_name) {
143 dom_ui_->CallJavascriptFunction(function_name);
144}
145
146void CloudPrintDataSenderHelper::CallJavascriptFunction(
147 const std::wstring& function_name, const Value& arg) {
148 dom_ui_->CallJavascriptFunction(function_name, arg);
149}
150
151void CloudPrintDataSenderHelper::CallJavascriptFunction(
152 const std::wstring& function_name, const Value& arg1, const Value& arg2) {
153 dom_ui_->CallJavascriptFunction(function_name, arg1, arg2);
154}
155
156// Clears out the pointer we're using to communicate. Either routine is
157// potentially expensive enough that stopping whatever is in progress
158// is worth it.
159void CloudPrintDataSender::CancelPrintDataFile() {
[email protected]20305ec2011-01-21 04:55:52160 base::AutoLock lock(lock_);
[email protected]73852b8f2010-05-14 00:38:12161 // We don't own helper, it was passed in to us, so no need to
162 // delete, just let it go.
163 helper_ = NULL;
164}
165
[email protected]38e08982010-10-22 17:28:43166CloudPrintDataSender::CloudPrintDataSender(CloudPrintDataSenderHelper* helper,
167 const string16& print_job_title)
168 : helper_(helper),
169 print_job_title_(print_job_title) {
170}
171
172CloudPrintDataSender::~CloudPrintDataSender() {}
173
[email protected]73852b8f2010-05-14 00:38:12174// Grab the raw PDF file contents and massage them into shape for
175// sending to the dialog contents (and up to the cloud print server)
176// by encoding it and prefixing it with the appropriate mime type.
177// Once that is done, kick off the next part of the task on the IO
178// thread.
179void CloudPrintDataSender::ReadPrintDataFile(const FilePath& path_to_pdf) {
[email protected]ba4f1132010-10-09 02:02:35180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]73852b8f2010-05-14 00:38:12181 int64 file_size = 0;
182 if (file_util::GetFileSize(path_to_pdf, &file_size) && file_size != 0) {
183 std::string file_data;
184 if (file_size < kuint32max) {
185 file_data.reserve(static_cast<unsigned int>(file_size));
186 } else {
187 DLOG(WARNING) << " print data file too large to reserve space";
188 }
189 if (helper_ && file_util::ReadFileToString(path_to_pdf, &file_data)) {
190 std::string base64_data;
191 base::Base64Encode(file_data, &base64_data);
192 std::string header("data:application/pdf;base64,");
193 base64_data.insert(0, header);
194 scoped_ptr<StringValue> new_data(new StringValue(base64_data));
195 print_data_.swap(new_data);
[email protected]ba4f1132010-10-09 02:02:35196 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
197 NewRunnableMethod(
198 this,
199 &CloudPrintDataSender::SendPrintDataFile));
[email protected]73852b8f2010-05-14 00:38:12200 }
201 }
202}
203
204// We have the data in hand that needs to be pushed into the dialog
205// contents; do so from the IO thread.
206
207// TODO(scottbyer): If the print data ends up being larger than the
208// upload limit (currently 10MB), what we need to do is upload that
209// large data to google docs and set the URL in the printing
210// JavaScript to that location, and make sure it gets deleted when not
211// needed. - 4/1/2010
212void CloudPrintDataSender::SendPrintDataFile() {
[email protected]ba4f1132010-10-09 02:02:35213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]20305ec2011-01-21 04:55:52214 base::AutoLock lock(lock_);
[email protected]73852b8f2010-05-14 00:38:12215 if (helper_ && print_data_.get()) {
[email protected]9848c7e2010-06-03 16:06:56216 StringValue title(print_job_title_);
[email protected]73852b8f2010-05-14 00:38:12217
218 // Send the print data to the dialog contents. The JavaScript
219 // function is a preliminary API for prototyping purposes and is
220 // subject to change.
221 const_cast<CloudPrintDataSenderHelper*>(helper_)->CallJavascriptFunction(
222 L"printApp._printDataUrl", *print_data_, title);
223 }
224}
225
226
[email protected]38e08982010-10-22 17:28:43227CloudPrintFlowHandler::CloudPrintFlowHandler(const FilePath& path_to_pdf,
228 const string16& print_job_title)
229 : path_to_pdf_(path_to_pdf),
230 print_job_title_(print_job_title) {
231}
232
233CloudPrintFlowHandler::~CloudPrintFlowHandler() {
234 // This will also cancel any task in flight.
235 CancelAnyRunningTask();
236}
237
238
[email protected]73852b8f2010-05-14 00:38:12239void CloudPrintFlowHandler::SetDialogDelegate(
240 CloudPrintHtmlDialogDelegate* delegate) {
241 // Even if setting a new dom_ui, it means any previous task needs
242 // to be cancelled, it's now invalid.
[email protected]ba4f1132010-10-09 02:02:35243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12244 CancelAnyRunningTask();
245 dialog_delegate_ = delegate;
246}
247
248// Cancels any print data sender we have in flight and removes our
249// reference to it, so when the task that is calling it finishes and
250// removes it's reference, it goes away.
251void CloudPrintFlowHandler::CancelAnyRunningTask() {
[email protected]ba4f1132010-10-09 02:02:35252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12253 if (print_data_sender_.get()) {
254 print_data_sender_->CancelPrintDataFile();
255 print_data_sender_ = NULL;
256 }
257}
258
[email protected]73852b8f2010-05-14 00:38:12259void CloudPrintFlowHandler::RegisterMessages() {
260 if (!dom_ui_)
261 return;
262
263 // TODO(scottbyer) - This is where we will register messages for the
264 // UI JS to use. Needed: Call to update page setup parameters.
265 dom_ui_->RegisterMessageCallback(
266 "ShowDebugger",
267 NewCallback(this, &CloudPrintFlowHandler::HandleShowDebugger));
268 dom_ui_->RegisterMessageCallback(
269 "SendPrintData",
270 NewCallback(this, &CloudPrintFlowHandler::HandleSendPrintData));
271 dom_ui_->RegisterMessageCallback(
272 "SetPageParameters",
273 NewCallback(this, &CloudPrintFlowHandler::HandleSetPageParameters));
274
275 if (dom_ui_->tab_contents()) {
276 // Also, take the opportunity to set some (minimal) additional
277 // script permissions required for the web UI.
278
279 // TODO(scottbyer): learn how to make sure we're talking to the
280 // right web site first.
281 RenderViewHost* rvh = dom_ui_->tab_contents()->render_view_host();
282 if (rvh && rvh->delegate()) {
283 WebPreferences webkit_prefs = rvh->delegate()->GetWebkitPrefs();
284 webkit_prefs.allow_scripts_to_close_windows = true;
285 rvh->UpdateWebPreferences(webkit_prefs);
286 }
287
288 // Register for appropriate notifications, and re-direct the URL
289 // to the real server URL, now that we've gotten an HTML dialog
290 // going.
291 NavigationController* controller = &dom_ui_->tab_contents()->controller();
292 NavigationEntry* pending_entry = controller->pending_entry();
293 if (pending_entry)
[email protected]2283eead2010-09-29 23:17:30294 pending_entry->set_url(CloudPrintURL(
[email protected]4baf1c42010-05-18 18:45:25295 dom_ui_->GetProfile()).GetCloudPrintServiceDialogURL());
[email protected]73852b8f2010-05-14 00:38:12296 registrar_.Add(this, NotificationType::LOAD_STOP,
297 Source<NavigationController>(controller));
298 }
299}
300
301void CloudPrintFlowHandler::Observe(NotificationType type,
302 const NotificationSource& source,
303 const NotificationDetails& details) {
304 if (type == NotificationType::LOAD_STOP) {
305 // Choose one or the other. If you need to debug, bring up the
306 // debugger. You can then use the various chrome.send()
307 // registrations above to kick of the various function calls,
308 // including chrome.send("SendPrintData") in the javaScript
309 // console and watch things happen with:
310 // HandleShowDebugger(NULL);
311 HandleSendPrintData(NULL);
312 }
313}
314
[email protected]88942a22010-08-19 20:34:43315void CloudPrintFlowHandler::HandleShowDebugger(const ListValue* args) {
[email protected]73852b8f2010-05-14 00:38:12316 ShowDebugger();
317}
318
319void CloudPrintFlowHandler::ShowDebugger() {
320 if (dom_ui_) {
321 RenderViewHost* rvh = dom_ui_->tab_contents()->render_view_host();
322 if (rvh)
323 DevToolsManager::GetInstance()->OpenDevToolsWindow(rvh);
324 }
325}
326
327scoped_refptr<CloudPrintDataSender>
328CloudPrintFlowHandler::CreateCloudPrintDataSender() {
329 DCHECK(dom_ui_);
330 print_data_helper_.reset(new CloudPrintDataSenderHelper(dom_ui_));
[email protected]9848c7e2010-06-03 16:06:56331 return new CloudPrintDataSender(print_data_helper_.get(), print_job_title_);
[email protected]73852b8f2010-05-14 00:38:12332}
333
[email protected]88942a22010-08-19 20:34:43334void CloudPrintFlowHandler::HandleSendPrintData(const ListValue* args) {
[email protected]ba4f1132010-10-09 02:02:35335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12336 // This will cancel any ReadPrintDataFile() or SendPrintDataFile()
337 // requests in flight (this is anticipation of when setting page
338 // setup parameters becomes asynchronous and may be set while some
339 // data is in flight). Then we can clear out the print data.
340 CancelAnyRunningTask();
341 if (dom_ui_) {
342 print_data_sender_ = CreateCloudPrintDataSender();
[email protected]ba4f1132010-10-09 02:02:35343 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
344 NewRunnableMethod(
345 print_data_sender_.get(),
346 &CloudPrintDataSender::ReadPrintDataFile,
347 path_to_pdf_));
[email protected]73852b8f2010-05-14 00:38:12348 }
349}
350
[email protected]88942a22010-08-19 20:34:43351void CloudPrintFlowHandler::HandleSetPageParameters(const ListValue* args) {
352 std::string json(dom_ui_util::GetJsonResponseFromFirstArgumentInList(args));
[email protected]73852b8f2010-05-14 00:38:12353 if (json.empty())
354 return;
355
356 // These are backstop default values - 72 dpi to match the screen,
357 // 8.5x11 inch paper with margins subtracted (1/4 inch top, left,
358 // right and 0.56 bottom), and the min page shrink and max page
359 // shrink values appear all over the place with no explanation.
360
361 // TODO(scottbyer): Get a Linux/ChromeOS edge for PrintSettings
362 // working so that we can get the default values from there. Fix up
363 // PrintWebViewHelper to do the same.
364 const int kDPI = 72;
365 const int kWidth = static_cast<int>((8.5-0.25-0.25)*kDPI);
366 const int kHeight = static_cast<int>((11-0.25-0.56)*kDPI);
367 const double kMinPageShrink = 1.25;
368 const double kMaxPageShrink = 2.0;
369
370 ViewMsg_Print_Params default_settings;
371 default_settings.printable_size = gfx::Size(kWidth, kHeight);
372 default_settings.dpi = kDPI;
373 default_settings.min_shrink = kMinPageShrink;
374 default_settings.max_shrink = kMaxPageShrink;
375 default_settings.desired_dpi = kDPI;
376 default_settings.document_cookie = 0;
377 default_settings.selection_only = false;
378
379 if (!GetPageSetupParameters(json, default_settings)) {
380 NOTREACHED();
381 return;
382 }
383
384 // TODO(scottbyer) - Here is where we would kick the originating
385 // renderer thread with these new parameters in order to get it to
386 // re-generate the PDF and hand it back to us. window.print() is
387 // currently synchronous, so there's a lot of work to do to get to
388 // that point.
389}
390
[email protected]ea161da2010-11-02 21:57:35391void CloudPrintFlowHandler::StoreDialogClientSize() const {
392 if (dom_ui_ && dom_ui_->tab_contents() && dom_ui_->tab_contents()->view()) {
393 gfx::Size size = dom_ui_->tab_contents()->view()->GetContainerSize();
394 dom_ui_->GetProfile()->GetPrefs()->SetInteger(
395 prefs::kCloudPrintDialogWidth, size.width());
396 dom_ui_->GetProfile()->GetPrefs()->SetInteger(
397 prefs::kCloudPrintDialogHeight, size.height());
398 }
399}
400
[email protected]73852b8f2010-05-14 00:38:12401CloudPrintHtmlDialogDelegate::CloudPrintHtmlDialogDelegate(
402 const FilePath& path_to_pdf,
403 int width, int height,
[email protected]9848c7e2010-06-03 16:06:56404 const std::string& json_arguments,
[email protected]e39027a2011-01-24 21:41:54405 const string16& print_job_title,
406 bool modal)
[email protected]9848c7e2010-06-03 16:06:56407 : flow_handler_(new CloudPrintFlowHandler(path_to_pdf, print_job_title)),
[email protected]e39027a2011-01-24 21:41:54408 modal_(modal),
[email protected]73852b8f2010-05-14 00:38:12409 owns_flow_handler_(true) {
410 Init(width, height, json_arguments);
411}
412
413CloudPrintHtmlDialogDelegate::CloudPrintHtmlDialogDelegate(
414 CloudPrintFlowHandler* flow_handler,
415 int width, int height,
[email protected]e39027a2011-01-24 21:41:54416 const std::string& json_arguments,
417 bool modal)
[email protected]73852b8f2010-05-14 00:38:12418 : flow_handler_(flow_handler),
[email protected]e39027a2011-01-24 21:41:54419 modal_(modal),
[email protected]18137e02010-05-25 21:10:35420 owns_flow_handler_(true) {
[email protected]73852b8f2010-05-14 00:38:12421 Init(width, height, json_arguments);
422}
423
424void CloudPrintHtmlDialogDelegate::Init(
[email protected]9848c7e2010-06-03 16:06:56425 int width, int height, const std::string& json_arguments) {
[email protected]73852b8f2010-05-14 00:38:12426 // This information is needed to show the dialog HTML content.
[email protected]ba4f1132010-10-09 02:02:35427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12428 std::string cloud_print_url(chrome::kCloudPrintResourcesURL);
429 params_.url = GURL(cloud_print_url);
430 params_.height = height;
431 params_.width = width;
432 params_.json_input = json_arguments;
433
434 flow_handler_->SetDialogDelegate(this);
[email protected]e39027a2011-01-24 21:41:54435 // If we're not modal we can show the dialog with no browser.
436 // We need this to keep Chrome alive while our dialog is up.
437 if (!modal_)
438 BrowserList::StartKeepAlive();
[email protected]73852b8f2010-05-14 00:38:12439}
440
441CloudPrintHtmlDialogDelegate::~CloudPrintHtmlDialogDelegate() {
442 // If the flow_handler_ is about to outlive us because we don't own
443 // it anymore, we need to have it remove it's reference to us.
[email protected]ba4f1132010-10-09 02:02:35444 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12445 flow_handler_->SetDialogDelegate(NULL);
446 if (owns_flow_handler_) {
447 delete flow_handler_;
448 }
449}
450
451bool CloudPrintHtmlDialogDelegate::IsDialogModal() const {
[email protected]e39027a2011-01-24 21:41:54452 return modal_;
[email protected]73852b8f2010-05-14 00:38:12453}
454
455std::wstring CloudPrintHtmlDialogDelegate::GetDialogTitle() const {
[email protected]be559e442010-11-02 20:37:32456 return std::wstring();
[email protected]73852b8f2010-05-14 00:38:12457}
458
459GURL CloudPrintHtmlDialogDelegate::GetDialogContentURL() const {
460 return params_.url;
461}
462
463void CloudPrintHtmlDialogDelegate::GetDOMMessageHandlers(
464 std::vector<DOMMessageHandler*>* handlers) const {
465 handlers->push_back(flow_handler_);
466 // We don't own flow_handler_ anymore, but it sticks around until at
467 // least right after OnDialogClosed() is called (and this object is
468 // destroyed).
469 owns_flow_handler_ = false;
470}
471
472void CloudPrintHtmlDialogDelegate::GetDialogSize(gfx::Size* size) const {
473 size->set_width(params_.width);
474 size->set_height(params_.height);
475}
476
477std::string CloudPrintHtmlDialogDelegate::GetDialogArgs() const {
478 return params_.json_input;
479}
480
481void CloudPrintHtmlDialogDelegate::OnDialogClosed(
482 const std::string& json_retval) {
[email protected]ea161da2010-11-02 21:57:35483 // Get the final dialog size and store it.
484 flow_handler_->StoreDialogClientSize();
[email protected]e39027a2011-01-24 21:41:54485 // If we're modal we can show the dialog with no browser.
486 // End the keep-alive so that Chrome can exit.
487 if (!modal_)
488 BrowserList::EndKeepAlive();
[email protected]73852b8f2010-05-14 00:38:12489 delete this;
490}
491
[email protected]18137e02010-05-25 21:10:35492void CloudPrintHtmlDialogDelegate::OnCloseContents(TabContents* source,
493 bool* out_close_dialog) {
494 if (out_close_dialog)
495 *out_close_dialog = true;
496}
497
[email protected]ea161da2010-11-02 21:57:35498bool CloudPrintHtmlDialogDelegate::ShouldShowDialogTitle() const {
499 return false;
500}
501
[email protected]73852b8f2010-05-14 00:38:12502} // end of namespace internal_cloud_print_helpers
503
504// static, called on the IO thread. This is the main entry point into
505// creating the dialog.
506
507// TODO(scottbyer): The signature here will need to change as the
508// workflow through the printing code changes to allow for dynamically
509// changing page setup parameters while the dialog is active.
[email protected]e39027a2011-01-24 21:41:54510void PrintDialogCloud::CreatePrintDialogForPdf(const FilePath& path_to_pdf,
511 const string16& print_job_title,
512 bool modal) {
513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE) ||
514 BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12515
[email protected]ba4f1132010-10-09 02:02:35516 BrowserThread::PostTask(
517 BrowserThread::UI, FROM_HERE,
[email protected]e39027a2011-01-24 21:41:54518 NewRunnableFunction(&PrintDialogCloud::CreateDialogImpl,
519 path_to_pdf,
520 print_job_title,
521 modal));
[email protected]73852b8f2010-05-14 00:38:12522}
523
524// static, called from the UI thread.
[email protected]e39027a2011-01-24 21:41:54525void PrintDialogCloud::CreateDialogImpl(const FilePath& path_to_pdf,
526 const string16& print_job_title,
527 bool modal) {
[email protected]ba4f1132010-10-09 02:02:35528 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]e39027a2011-01-24 21:41:54529 new PrintDialogCloud(path_to_pdf, print_job_title, modal);
[email protected]73852b8f2010-05-14 00:38:12530}
531
532// Initialize the print dialog. Called on the UI thread.
[email protected]e39027a2011-01-24 21:41:54533PrintDialogCloud::PrintDialogCloud(const FilePath& path_to_pdf,
534 const string16& print_job_title,
535 bool modal)
536 : browser_(BrowserList::GetLastActive()),
537 print_job_title_(print_job_title),
538 modal_(modal) {
[email protected]73852b8f2010-05-14 00:38:12539
540 // TODO(scottbyer): Verify GAIA login valid, execute GAIA login if not (should
541 // be distilled out of bookmark sync.)
[email protected]ea161da2010-11-02 21:57:35542 const int kDefaultWidth = 497;
543 const int kDefaultHeight = 332;
[email protected]e39027a2011-01-24 21:41:54544 Profile* profile = NULL;
545 PrefService* pref_service = NULL;
546 if (modal_) {
547 DCHECK(browser_);
548 if (print_job_title_.empty() && browser_->GetSelectedTabContents())
549 print_job_title_ = browser_->GetSelectedTabContents()->GetTitle();
550 profile = browser_->GetProfile();
551 } else {
552 profile = ProfileManager::GetDefaultProfile();
553 }
554 DCHECK(profile);
555 pref_service = profile->GetPrefs();
[email protected]ea161da2010-11-02 21:57:35556 DCHECK(pref_service);
557 if (!pref_service->FindPreference(prefs::kCloudPrintDialogWidth)) {
558 pref_service->RegisterIntegerPref(prefs::kCloudPrintDialogWidth,
559 kDefaultWidth);
560 }
561 if (!pref_service->FindPreference(prefs::kCloudPrintDialogHeight)) {
562 pref_service->RegisterIntegerPref(prefs::kCloudPrintDialogHeight,
563 kDefaultHeight);
564 }
565
566 int width = pref_service->GetInteger(prefs::kCloudPrintDialogWidth);
567 int height = pref_service->GetInteger(prefs::kCloudPrintDialogHeight);
[email protected]e39027a2011-01-24 21:41:54568
[email protected]73852b8f2010-05-14 00:38:12569 HtmlDialogUIDelegate* dialog_delegate =
570 new internal_cloud_print_helpers::CloudPrintHtmlDialogDelegate(
[email protected]e39027a2011-01-24 21:41:54571 path_to_pdf, width, height, std::string(), print_job_title_, modal_);
572 if (modal_) {
573 DCHECK(browser_);
574 browser_->BrowserShowHtmlDialog(dialog_delegate, NULL);
575 } else {
576#if defined(TOOLKIT_VIEWS)
577 browser::ShowHtmlDialogView(NULL, profile, dialog_delegate);
578#elif defined(TOOLKIT_GTK)
579 HtmlDialogGtk* html_dialog =
580 new HtmlDialogGtk(profile, dialog_delegate, NULL);
581 html_dialog->InitDialog();
582#endif // defined(TOOLKIT_VIEWS)
583 }
[email protected]73852b8f2010-05-14 00:38:12584}
585
586PrintDialogCloud::~PrintDialogCloud() {
587}