12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/printing/print_preview_dialog_controller.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/auto_reset.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/printing/print_view_manager.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_content_client.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_paths.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/url_constants.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/navigation_controller.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/navigation_details.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/navigation_entry.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_details.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_source.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/plugin_service.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_process_host.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_view_host.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_view.h"
43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/public/common/webplugininfo.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/web_dialogs/web_dialog_delegate.h"
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/web_dialogs/web_dialog_web_contents_delegate.h"
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::NativeWebKeyboardEvent;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::NavigationController;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::WebContents;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::WebUIMessageHandler;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ui::WebDialogDelegate;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ui::WebDialogWebContentsDelegate;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void EnableInternalPDFPluginForContents(WebContents* preview_dialog) {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Always enable the internal PDF plugin for the print preview page.
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath pdf_plugin_path;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_plugin_path))
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  content::WebPluginInfo pdf_plugin;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!content::PluginService::GetInstance()->GetPluginInfoByPath(
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pdf_plugin_path, &pdf_plugin))
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ChromePluginServiceFilter::GetInstance()->OverridePluginForTab(
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      preview_dialog->GetRenderProcessHost()->GetID(),
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      preview_dialog->GetRenderViewHost()->GetRoutingID(),
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL(), pdf_plugin);
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WebDialogDelegate that specifies what the print preview dialog
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// will look like.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PrintPreviewDialogDelegate : public WebDialogDelegate {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  explicit PrintPreviewDialogDelegate(WebContents* initiator);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~PrintPreviewDialogDelegate();
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ui::ModalType GetDialogModalType() const OVERRIDE;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual string16 GetDialogTitle() const OVERRIDE;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual GURL GetDialogContentURL() const OVERRIDE;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetWebUIMessageHandlers(
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::vector<WebUIMessageHandler*>* handlers) const OVERRIDE;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetDialogSize(gfx::Size* size) const OVERRIDE;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual std::string GetDialogArgs() const OVERRIDE;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnCloseContents(WebContents* source,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               bool* out_close_dialog) OVERRIDE;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool ShouldShowDialogTitle() const OVERRIDE;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  WebContents* initiator_;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogDelegate);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochPrintPreviewDialogDelegate::PrintPreviewDialogDelegate(WebContents* initiator)
99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    : initiator_(initiator) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrintPreviewDialogDelegate::~PrintPreviewDialogDelegate() {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::ModalType PrintPreviewDialogDelegate::GetDialogModalType() const {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Not used, returning dummy value.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED();
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ui::MODAL_TYPE_WINDOW;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)string16 PrintPreviewDialogDelegate::GetDialogTitle() const {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only used on Windows? UI folks prefer no title.
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return string16();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL PrintPreviewDialogDelegate::GetDialogContentURL() const {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GURL(chrome::kChromeUIPrintURL);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintPreviewDialogDelegate::GetWebUIMessageHandlers(
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<WebUIMessageHandler*>* /* handlers */) const {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // PrintPreviewUI adds its own message handlers.
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintPreviewDialogDelegate::GetDialogSize(gfx::Size* size) const {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(size);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Size kMinDialogSize(800, 480);
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const int kBorder = 25;
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const int kConstrainedWindowOverlap = 3;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect rect;
131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  initiator_->GetView()->GetContainerBounds(&rect);
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  size->set_width(std::max(rect.width(), kMinDialogSize.width()) - 2 * kBorder);
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  size->set_height(std::max(rect.height(), kMinDialogSize.height()) - kBorder +
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                   kConstrainedWindowOverlap);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_MACOSX)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Limit the maximum size on MacOS X.
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://crbug.com/105815
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Size kMaxDialogSize(1000, 660);
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size->set_width(std::min(size->width(), kMaxDialogSize.width()));
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size->set_height(std::min(size->height(), kMaxDialogSize.height()));
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string PrintPreviewDialogDelegate::GetDialogArgs() const {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return std::string();
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintPreviewDialogDelegate::OnDialogClosed(
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& /* json_retval */) {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintPreviewDialogDelegate::OnCloseContents(WebContents* /* source */,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 bool* out_close_dialog) {
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (out_close_dialog)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out_close_dialog = true;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PrintPreviewDialogDelegate::ShouldShowDialogTitle() const {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WebContentsDelegate that forwards shortcut keys in the print preview
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// renderer to the browser.
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PrintPreviewWebContentDelegate : public WebDialogWebContentsDelegate {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
167ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  PrintPreviewWebContentDelegate(Profile* profile, WebContents* initiator);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~PrintPreviewWebContentDelegate();
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from WebDialogWebContentsDelegate:
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void HandleKeyboardEvent(
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebContents* source,
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const NativeWebKeyboardEvent& event) OVERRIDE;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  WebContents* initiator_;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PrintPreviewWebContentDelegate);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrintPreviewWebContentDelegate::PrintPreviewWebContentDelegate(
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile,
183ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    WebContents* initiator)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : WebDialogWebContentsDelegate(profile, new ChromeWebContentsHandler),
185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      initiator_(initiator) {}
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrintPreviewWebContentDelegate::~PrintPreviewWebContentDelegate() {}
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintPreviewWebContentDelegate::HandleKeyboardEvent(
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* source,
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const NativeWebKeyboardEvent& event) {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Disabled on Mac due to http://crbug.com/112173
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_MACOSX)
194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Browser* current_browser = chrome::FindBrowserWithWebContents(initiator_);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!current_browser)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_browser->window()->HandleKeyboardEvent(event);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace printing {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrintPreviewDialogController::PrintPreviewDialogController()
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : waiting_for_new_preview_page_(false),
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_creating_print_preview_dialog_(false) {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrintPreviewDialogController* PrintPreviewDialogController::GetInstance() {
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!g_browser_process)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return g_browser_process->print_preview_dialog_controller();
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PrintPreviewDialogController::PrintPreview(WebContents* initiator) {
219ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (initiator->ShowingInterstitialPage())
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrintPreviewDialogController* dialog_controller = GetInstance();
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dialog_controller)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!dialog_controller->GetOrCreatePreviewDialog(initiator))
226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    PrintViewManager::FromWebContents(initiator)->PrintPreviewDone();
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebContents* PrintPreviewDialogController::GetOrCreatePreviewDialog(
230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    WebContents* initiator) {
231ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK(initiator);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Get the print preview dialog for |initiator|.
234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  WebContents* preview_dialog = GetPrintPreviewForContents(initiator);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!preview_dialog)
236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return CreatePrintPreviewDialog(initiator);
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Show the initiator holding the existing preview dialog.
239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  initiator->GetDelegate()->ActivateContents(initiator);
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return preview_dialog;
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebContents* PrintPreviewDialogController::GetPrintPreviewForContents(
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* contents) const {
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |preview_dialog_map_| is keyed by the preview dialog, so if find()
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // succeeds, then |contents| is the preview dialog.
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrintPreviewDialogMap::const_iterator it = preview_dialog_map_.find(contents);
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it != preview_dialog_map_.end())
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return contents;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (it = preview_dialog_map_.begin();
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != preview_dialog_map_.end();
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // If |contents| is an initiator.
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (contents == it->second) {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Return the associated preview dialog.
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return it->first;
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochWebContents* PrintPreviewDialogController::GetInitiator(
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* preview_dialog) {
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrintPreviewDialogMap::iterator it = preview_dialog_map_.find(preview_dialog);
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (it != preview_dialog_map_.end()) ? it->second : NULL;
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintPreviewDialogController::Observe(
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int type,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::NotificationSource& source,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::NotificationDetails& details) {
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type == content::NOTIFICATION_RENDERER_PROCESS_CLOSED) {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OnRendererProcessClosed(
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Source<content::RenderProcessHost>(source).ptr());
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) {
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OnWebContentsDestroyed(content::Source<WebContents>(source).ptr());
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_EQ(content::NOTIFICATION_NAV_ENTRY_COMMITTED, type);
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* contents =
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Source<NavigationController>(source)->GetWebContents();
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OnNavEntryCommitted(
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        contents,
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Details<content::LoadCommittedDetails>(details).ptr());
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PrintPreviewDialogController::IsPrintPreviewDialog(WebContents* contents) {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return IsPrintPreviewURL(contents->GetURL());
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PrintPreviewDialogController::IsPrintPreviewURL(const GURL& url) {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (url.SchemeIs(chrome::kChromeUIScheme) &&
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url.host() == chrome::kChromeUIPrintHost);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
299ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PrintPreviewDialogController::EraseInitiatorInfo(
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* preview_dialog) {
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrintPreviewDialogMap::iterator it = preview_dialog_map_.find(preview_dialog);
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it == preview_dialog_map_.end())
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RemoveObservers(it->second);
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  preview_dialog_map_[preview_dialog] = NULL;
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrintPreviewDialogController::~PrintPreviewDialogController() {}
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintPreviewDialogController::OnRendererProcessClosed(
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::RenderProcessHost* rph) {
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store contents in a vector and deal with them after iterating through
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |preview_dialog_map_| because RemoveFoo() can change |preview_dialog_map_|.
315ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::vector<WebContents*> closed_initiators;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<WebContents*> closed_preview_dialogs;
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (PrintPreviewDialogMap::iterator iter = preview_dialog_map_.begin();
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != preview_dialog_map_.end(); ++iter) {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* preview_dialog = iter->first;
320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    WebContents* initiator = iter->second;
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (preview_dialog->GetRenderProcessHost() == rph) {
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      closed_preview_dialogs.push_back(preview_dialog);
323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    } else if (initiator &&
324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch               initiator->GetRenderProcessHost() == rph) {
325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      closed_initiators.push_back(initiator);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < closed_preview_dialogs.size(); ++i) {
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RemovePreviewDialog(closed_preview_dialogs[i]);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        closed_preview_dialogs[i]->GetWebUI()->GetController());
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (print_preview_ui)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      print_preview_ui->OnPrintPreviewDialogClosed();
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
337ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  for (size_t i = 0; i < closed_initiators.size(); ++i)
338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RemoveInitiator(closed_initiators[i]);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintPreviewDialogController::OnWebContentsDestroyed(
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* contents) {
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* preview_dialog = GetPrintPreviewForContents(contents);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!preview_dialog) {
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (contents == preview_dialog)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RemovePreviewDialog(contents);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RemoveInitiator(contents);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintPreviewDialogController::OnNavEntryCommitted(
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* contents, content::LoadCommittedDetails* details) {
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* preview_dialog = GetPrintPreviewForContents(contents);
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!preview_dialog) {
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (contents == preview_dialog) {
364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Preview dialog navigated.
365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (details) {
366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      content::PageTransition transition_type =
367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          details->entry->GetTransitionType();
368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      content::NavigationType nav_type = details->type;
369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // New |preview_dialog| is created. Don't update/erase map entry.
371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      if (waiting_for_new_preview_page_ &&
372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          transition_type == content::PAGE_TRANSITION_AUTO_TOPLEVEL &&
373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          nav_type == content::NAVIGATION_TYPE_NEW_PAGE) {
374a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        waiting_for_new_preview_page_ = false;
375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        SaveInitiatorTitle(preview_dialog);
376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        return;
377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      }
378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // Cloud print sign-in causes a reload.
380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      if (!waiting_for_new_preview_page_ &&
381a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          transition_type == content::PAGE_TRANSITION_RELOAD &&
382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          nav_type == content::NAVIGATION_TYPE_EXISTING_PAGE &&
383a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          IsPrintPreviewURL(details->previous_url)) {
384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        return;
385a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      }
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
387a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    NOTREACHED();
388a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
391a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RemoveInitiator(contents);
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebContents* PrintPreviewDialogController::CreatePrintPreviewDialog(
395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    WebContents* initiator) {
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoReset<bool> auto_reset(&is_creating_print_preview_dialog_, true);
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Profile* profile =
398ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      Profile::FromBrowserContext(initiator->GetBrowserContext());
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeFrame)) {
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Chrome Frame only ever runs on the native desktop, so it is safe to
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // create the popup on the native desktop.
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Browser* current_browser = new Browser(
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Browser::CreateParams(Browser::TYPE_POPUP, profile,
404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              chrome::GetActiveDesktop()));
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!current_browser) {
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED() << "Failed to create popup browser window";
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |web_dialog_ui_delegate| deletes itself in
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // PrintPreviewDialogDelegate::OnDialogClosed().
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebDialogDelegate* web_dialog_delegate =
414ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      new PrintPreviewDialogDelegate(initiator);
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |web_dialog_delegate|'s owner is |constrained_delegate|.
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrintPreviewWebContentDelegate* pp_wcd =
417ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      new PrintPreviewWebContentDelegate(profile, initiator);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ConstrainedWebDialogDelegate* constrained_delegate =
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateConstrainedWebDialog(profile,
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 web_dialog_delegate,
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 pp_wcd,
422ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 initiator);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* preview_dialog = constrained_delegate->GetWebContents();
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnableInternalPDFPluginForContents(preview_dialog);
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrintViewManager::CreateForWebContents(preview_dialog);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add an entry to the map.
428ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  preview_dialog_map_[preview_dialog] = initiator;
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  waiting_for_new_preview_page_ = true;
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AddObservers(initiator);
432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AddObservers(preview_dialog);
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return preview_dialog;
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
437ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PrintPreviewDialogController::SaveInitiatorTitle(
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* preview_dialog) {
439ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  WebContents* initiator = GetInitiator(preview_dialog);
440ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (initiator && preview_dialog->GetWebUI()) {
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        preview_dialog->GetWebUI()->GetController());
443ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    print_preview_ui->SetInitiatorTitle(
444ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        PrintViewManager::FromWebContents(initiator)->RenderSourceName());
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void PrintPreviewDialogController::AddObservers(WebContents* contents) {
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 content::Source<WebContents>(contents));
451a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
452a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      content::Source<NavigationController>(&contents->GetController()));
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Multiple sites may share the same RenderProcessHost, so check if this
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // notification has already been added.
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::Source<content::RenderProcessHost> rph_source(
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents->GetRenderProcessHost());
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!registrar_.IsRegistered(this,
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::NOTIFICATION_RENDERER_PROCESS_CLOSED, rph_source)) {
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   rph_source);
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void PrintPreviewDialogController::RemoveObservers(WebContents* contents) {
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    content::Source<WebContents>(contents));
468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
469a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      content::Source<NavigationController>(&contents->GetController()));
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Multiple sites may share the same RenderProcessHost, so check if this
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // notification has already been added.
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::Source<content::RenderProcessHost> rph_source(
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents->GetRenderProcessHost());
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (registrar_.IsRegistered(this,
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::NOTIFICATION_RENDERER_PROCESS_CLOSED, rph_source)) {
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      rph_source);
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PrintPreviewDialogController::RemoveInitiator(
483ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    WebContents* initiator) {
484ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  WebContents* preview_dialog = GetPrintPreviewForContents(initiator);
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(preview_dialog);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the map entry first, so when the print preview dialog gets destroyed
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and reaches RemovePreviewDialog(), it does not attempt to also remove the
488ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // initiator's observers.
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  preview_dialog_map_[preview_dialog] = NULL;
490a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RemoveObservers(initiator);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  PrintViewManager::FromWebContents(initiator)->PrintPreviewDone();
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
494ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // initiator is closed. Close the print preview dialog too.
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrintPreviewUI* print_preview_ui =
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<PrintPreviewUI*>(preview_dialog->GetWebUI()->GetController());
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (print_preview_ui)
498ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    print_preview_ui->OnInitiatorClosed();
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintPreviewDialogController::RemovePreviewDialog(
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* preview_dialog) {
503ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Remove the initiator's observers before erasing the mapping.
504ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  WebContents* initiator = GetInitiator(preview_dialog);
505ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (initiator) {
506a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    RemoveObservers(initiator);
507ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    PrintViewManager::FromWebContents(initiator)->PrintPreviewDone();
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Print preview WebContents is destroyed. Notify |PrintPreviewUI| to abort
511ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // the initiator preview request.
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrintPreviewUI* print_preview_ui =
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<PrintPreviewUI*>(preview_dialog->GetWebUI()->GetController());
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (print_preview_ui)
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    print_preview_ui->OnPrintPreviewDialogDestroyed();
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  preview_dialog_map_.erase(preview_dialog);
518a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RemoveObservers(preview_dialog);
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace printing
522