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.
5 #include "chrome/browser/printing/print_view_manager.h"
10 #include "base/lazy_instance.h"
11 #include "base/metrics/histogram.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/printing/print_job_manager.h"
14 #include "chrome/browser/printing/print_preview_dialog_controller.h"
15 #include "chrome/browser/printing/print_view_manager_observer.h"
16 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
17 #include "chrome/common/print_messages.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/web_contents.h"
21 using content::BrowserThread
;
23 DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintViewManager
);
27 // Keeps track of pending scripted print preview closures.
28 // No locking, only access on the UI thread.
29 typedef std::map
<content::RenderProcessHost
*, base::Closure
>
30 ScriptedPrintPreviewClosureMap
;
31 static base::LazyInstance
<ScriptedPrintPreviewClosureMap
>
32 g_scripted_print_preview_closure_map
= LAZY_INSTANCE_INITIALIZER
;
38 PrintViewManager::PrintViewManager(content::WebContents
* web_contents
)
39 : PrintViewManagerBase(web_contents
),
41 print_preview_state_(NOT_PREVIEWING
),
42 scripted_print_preview_rph_(NULL
) {
45 PrintViewManager::~PrintViewManager() {
46 DCHECK_EQ(NOT_PREVIEWING
, print_preview_state_
);
49 #if !defined(DISABLE_BASIC_PRINTING)
50 bool PrintViewManager::PrintForSystemDialogNow() {
51 return PrintNowInternal(new PrintMsg_PrintForSystemDialog(routing_id()));
54 bool PrintViewManager::BasicPrint() {
55 PrintPreviewDialogController
* dialog_controller
=
56 PrintPreviewDialogController::GetInstance();
57 if (!dialog_controller
)
59 content::WebContents
* print_preview_dialog
=
60 dialog_controller
->GetPrintPreviewForContents(web_contents());
61 if (print_preview_dialog
) {
62 if (!print_preview_dialog
->GetWebUI())
64 PrintPreviewUI
* print_preview_ui
= static_cast<PrintPreviewUI
*>(
65 print_preview_dialog
->GetWebUI()->GetController());
66 print_preview_ui
->OnShowSystemDialog();
72 #endif // !DISABLE_BASIC_PRINTING
73 bool PrintViewManager::PrintPreviewNow(bool selection_only
) {
74 // Users can send print commands all they want and it is beyond
75 // PrintViewManager's control. Just ignore the extra commands.
76 // See http://crbug.com/136842 for example.
77 if (print_preview_state_
!= NOT_PREVIEWING
)
80 if (!PrintNowInternal(new PrintMsg_InitiatePrintPreview(routing_id(),
85 print_preview_state_
= USER_INITIATED_PREVIEW
;
89 void PrintViewManager::PrintPreviewForWebNode() {
90 if (print_preview_state_
!= NOT_PREVIEWING
)
92 print_preview_state_
= USER_INITIATED_PREVIEW
;
95 void PrintViewManager::PrintPreviewDone() {
96 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
97 DCHECK_NE(NOT_PREVIEWING
, print_preview_state_
);
99 if (print_preview_state_
== SCRIPTED_PREVIEW
) {
100 ScriptedPrintPreviewClosureMap
& map
=
101 g_scripted_print_preview_closure_map
.Get();
102 ScriptedPrintPreviewClosureMap::iterator it
=
103 map
.find(scripted_print_preview_rph_
);
104 CHECK(it
!= map
.end());
106 map
.erase(scripted_print_preview_rph_
);
107 scripted_print_preview_rph_
= NULL
;
109 print_preview_state_
= NOT_PREVIEWING
;
112 void PrintViewManager::set_observer(PrintViewManagerObserver
* observer
) {
113 DCHECK(!observer
|| !observer_
);
114 observer_
= observer
;
117 void PrintViewManager::RenderProcessGone(base::TerminationStatus status
) {
118 print_preview_state_
= NOT_PREVIEWING
;
119 PrintViewManagerBase::RenderProcessGone(status
);
122 void PrintViewManager::OnDidShowPrintDialog() {
124 observer_
->OnPrintDialogShown();
127 void PrintViewManager::OnSetupScriptedPrintPreview(IPC::Message
* reply_msg
) {
128 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
129 ScriptedPrintPreviewClosureMap
& map
=
130 g_scripted_print_preview_closure_map
.Get();
131 content::RenderProcessHost
* rph
= web_contents()->GetRenderProcessHost();
133 // This should always be 0 once we get modal window.print().
134 if (map
.count(rph
) != 0) {
135 // Renderer already handling window.print() in another View.
139 if (print_preview_state_
!= NOT_PREVIEWING
) {
140 // If a user initiated print dialog is already open, ignore the scripted
142 DCHECK_EQ(USER_INITIATED_PREVIEW
, print_preview_state_
);
147 PrintPreviewDialogController
* dialog_controller
=
148 PrintPreviewDialogController::GetInstance();
149 if (!dialog_controller
) {
154 print_preview_state_
= SCRIPTED_PREVIEW
;
155 base::Closure callback
=
156 base::Bind(&PrintViewManager::OnScriptedPrintPreviewReply
,
157 base::Unretained(this),
160 scripted_print_preview_rph_
= rph
;
163 void PrintViewManager::OnShowScriptedPrintPreview(bool source_is_modifiable
) {
164 PrintPreviewDialogController
* dialog_controller
=
165 PrintPreviewDialogController::GetInstance();
166 if (!dialog_controller
) {
170 dialog_controller
->PrintPreview(web_contents());
171 PrintHostMsg_RequestPrintPreview_Params params
;
172 params
.is_modifiable
= source_is_modifiable
;
173 PrintPreviewUI::SetInitialParams(
174 dialog_controller
->GetPrintPreviewForContents(web_contents()), params
);
177 void PrintViewManager::OnScriptedPrintPreviewReply(IPC::Message
* reply_msg
) {
178 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
182 bool PrintViewManager::OnMessageReceived(const IPC::Message
& message
) {
184 IPC_BEGIN_MESSAGE_MAP(PrintViewManager
, message
)
185 IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog
, OnDidShowPrintDialog
)
186 IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_SetupScriptedPrintPreview
,
187 OnSetupScriptedPrintPreview
)
188 IPC_MESSAGE_HANDLER(PrintHostMsg_ShowScriptedPrintPreview
,
189 OnShowScriptedPrintPreview
)
190 IPC_MESSAGE_UNHANDLED(handled
= false)
191 IPC_END_MESSAGE_MAP()
193 return handled
? true : PrintViewManagerBase::OnMessageReceived(message
);
196 } // namespace printing