Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(305)

Side by Side Diff: chrome/browser/printing/print_view_manager.cc

Issue 8515017: Print Preview: Properly handle window.print(). (Closed)
Patch Set: fail instead of crash when 2 views both do window.print() Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/printing/print_view_manager.h" 5 #include "chrome/browser/printing/print_view_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
9 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/browser_process.h" 11 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/printing/print_job.h" 12 #include "chrome/browser/printing/print_job.h"
12 #include "chrome/browser/printing/print_job_manager.h" 13 #include "chrome/browser/printing/print_job_manager.h"
13 #include "chrome/browser/printing/print_preview_tab_controller.h" 14 #include "chrome/browser/printing/print_preview_tab_controller.h"
14 #include "chrome/browser/printing/printer_query.h" 15 #include "chrome/browser/printing/printer_query.h"
15 #include "chrome/browser/printing/print_view_manager_observer.h" 16 #include "chrome/browser/printing/print_view_manager_observer.h"
16 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 17 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
17 #include "chrome/browser/ui/webui/print_preview_ui.h" 18 #include "chrome/browser/ui/webui/print_preview_ui.h"
(...skipping 25 matching lines...) Expand all
43 44
44 scoped_refptr<printing::PrinterQuery> printer_query; 45 scoped_refptr<printing::PrinterQuery> printer_query;
45 print_job_manager->PopPrinterQuery(cookie, &printer_query); 46 print_job_manager->PopPrinterQuery(cookie, &printer_query);
46 if (printer_query.get()) { 47 if (printer_query.get()) {
47 BrowserThread::PostTask( 48 BrowserThread::PostTask(
48 BrowserThread::IO, FROM_HERE, 49 BrowserThread::IO, FROM_HERE,
49 base::Bind(&printing::PrinterQuery::StopWorker, printer_query.get())); 50 base::Bind(&printing::PrinterQuery::StopWorker, printer_query.get()));
50 } 51 }
51 } 52 }
52 53
54 // Keeps track of pending scripted print preview closures.
55 // No locking, only access on the UI thread.
56 typedef std::map<content::RenderProcessHost*, base::Closure>
57 ScriptedPrintPreviewClosureMap;
58 static base::LazyInstance<ScriptedPrintPreviewClosureMap>
59 g_scripted_print_preview_closure_map = LAZY_INSTANCE_INITIALIZER;
60
53 } // namespace 61 } // namespace
54 62
55 namespace printing { 63 namespace printing {
56 64
57 PrintViewManager::PrintViewManager(TabContentsWrapper* tab) 65 PrintViewManager::PrintViewManager(TabContentsWrapper* tab)
58 : TabContentsObserver(tab->tab_contents()), 66 : TabContentsObserver(tab->tab_contents()),
59 tab_(tab), 67 tab_(tab),
60 number_pages_(0), 68 number_pages_(0),
61 printing_succeeded_(false), 69 printing_succeeded_(false),
62 inside_inner_message_loop_(false), 70 inside_inner_message_loop_(false),
63 observer_(NULL), 71 observer_(NULL),
64 cookie_(0) { 72 cookie_(0),
73 print_preview_state_(NOT_PREVIEWING),
74 scripted_print_preview_rph_(NULL) {
65 #if defined(OS_POSIX) && !defined(OS_MACOSX) 75 #if defined(OS_POSIX) && !defined(OS_MACOSX)
66 expecting_first_page_ = true; 76 expecting_first_page_ = true;
67 #endif 77 #endif
68 } 78 }
69 79
70 PrintViewManager::~PrintViewManager() { 80 PrintViewManager::~PrintViewManager() {
81 DCHECK_EQ(NOT_PREVIEWING, print_preview_state_);
71 ReleasePrinterQuery(cookie_); 82 ReleasePrinterQuery(cookie_);
72 DisconnectFromCurrentPrintJob(); 83 DisconnectFromCurrentPrintJob();
73 } 84 }
74 85
75 bool PrintViewManager::PrintNow() { 86 bool PrintViewManager::PrintNow() {
76 return PrintNowInternal(new PrintMsg_PrintPages(routing_id())); 87 return PrintNowInternal(new PrintMsg_PrintPages(routing_id()));
77 } 88 }
78 89
79 bool PrintViewManager::PrintForSystemDialogNow() { 90 bool PrintViewManager::PrintForSystemDialogNow() {
80 return PrintNowInternal(new PrintMsg_PrintForSystemDialog(routing_id())); 91 return PrintNowInternal(new PrintMsg_PrintForSystemDialog(routing_id()));
81 } 92 }
82 93
83 bool PrintViewManager::AdvancedPrintNow() { 94 bool PrintViewManager::AdvancedPrintNow() {
84 PrintPreviewTabController* tab_controller = 95 PrintPreviewTabController* tab_controller =
85 PrintPreviewTabController::GetInstance(); 96 PrintPreviewTabController::GetInstance();
86 if (!tab_controller) 97 if (!tab_controller)
87 return false; 98 return false;
88 TabContentsWrapper* wrapper =
89 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents());
90 TabContentsWrapper* print_preview_tab = 99 TabContentsWrapper* print_preview_tab =
91 tab_controller->GetPrintPreviewForTab(wrapper); 100 tab_controller->GetPrintPreviewForTab(tab_);
92 if (print_preview_tab) { 101 if (print_preview_tab) {
93 // Preview tab exist for current tab or current tab is preview tab. 102 // Preview tab exist for current tab or current tab is preview tab.
94 if (!print_preview_tab->web_ui()) 103 if (!print_preview_tab->web_ui())
95 return false; 104 return false;
96 PrintPreviewUI* print_preview_ui = 105 PrintPreviewUI* print_preview_ui =
97 static_cast<PrintPreviewUI*>(print_preview_tab->web_ui()); 106 static_cast<PrintPreviewUI*>(print_preview_tab->web_ui());
98 print_preview_ui->OnShowSystemDialog(); 107 print_preview_ui->OnShowSystemDialog();
99 return true; 108 return true;
100 } else { 109 } else {
101 return PrintNow(); 110 return PrintNow();
102 } 111 }
103 } 112 }
104 113
105 bool PrintViewManager::PrintPreviewNow() { 114 bool PrintViewManager::PrintPreviewNow() {
115 if (print_preview_state_ != NOT_PREVIEWING) {
116 NOTREACHED();
117 return false;
118 }
119 print_preview_state_ = USER_INITIATED_PREVIEW;
106 return PrintNowInternal(new PrintMsg_InitiatePrintPreview(routing_id())); 120 return PrintNowInternal(new PrintMsg_InitiatePrintPreview(routing_id()));
107 } 121 }
108 122
123 void PrintViewManager::PrintPreviewDone() {
124 BrowserThread::CurrentlyOn(BrowserThread::UI);
125 DCHECK_NE(NOT_PREVIEWING, print_preview_state_);
126
127 if (print_preview_state_ == SCRIPTED_PREVIEW) {
128 ScriptedPrintPreviewClosureMap& map =
129 g_scripted_print_preview_closure_map.Get();
130 ScriptedPrintPreviewClosureMap::iterator it =
131 map.find(scripted_print_preview_rph_);
132 CHECK(it != map.end());
133 it->second.Run();
134 map.erase(scripted_print_preview_rph_);
135 scripted_print_preview_rph_ = NULL;
136 }
137 print_preview_state_ = NOT_PREVIEWING;
138 }
139
109 void PrintViewManager::PreviewPrintingRequestCancelled() { 140 void PrintViewManager::PreviewPrintingRequestCancelled() {
110 if (!tab_contents()) 141 if (!tab_contents())
111 return; 142 return;
112 RenderViewHost* rvh = tab_contents()->render_view_host(); 143 RenderViewHost* rvh = tab_contents()->render_view_host();
113 rvh->Send(new PrintMsg_PreviewPrintingRequestCancelled(rvh->routing_id())); 144 rvh->Send(new PrintMsg_PreviewPrintingRequestCancelled(rvh->routing_id()));
114 } 145 }
115 146
116 void PrintViewManager::set_observer(PrintViewManagerObserver* observer) { 147 void PrintViewManager::set_observer(PrintViewManagerObserver* observer) {
117 DCHECK(!observer || !observer_); 148 DCHECK(!observer || !observer_);
118 observer_ = observer; 149 observer_ = observer;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 251
221 void PrintViewManager::OnPrintingFailed(int cookie) { 252 void PrintViewManager::OnPrintingFailed(int cookie) {
222 ReleasePrinterQuery(cookie); 253 ReleasePrinterQuery(cookie);
223 254
224 content::NotificationService::current()->Notify( 255 content::NotificationService::current()->Notify(
225 chrome::NOTIFICATION_PRINT_JOB_RELEASED, 256 chrome::NOTIFICATION_PRINT_JOB_RELEASED,
226 content::Source<TabContents>(tab_contents()), 257 content::Source<TabContents>(tab_contents()),
227 content::NotificationService::NoDetails()); 258 content::NotificationService::NoDetails());
228 } 259 }
229 260
261 void PrintViewManager::OnScriptedPrintPreview(IPC::Message* reply_msg) {
262 BrowserThread::CurrentlyOn(BrowserThread::UI);
263 ScriptedPrintPreviewClosureMap& map =
264 g_scripted_print_preview_closure_map.Get();
265 content::RenderProcessHost* rph =
266 tab_contents()->render_view_host()->process();
267
268 // This should always be 0 once we get modal window.print().
269 if (map.count(rph) != 0) {
270 // Renderer already handling window.print() in another View.
271 Send(reply_msg);
272 return;
273 }
274 if (print_preview_state_ != NOT_PREVIEWING) {
275 // If a user initiated print dialog is already open, ignore the scripted
276 // print message.
277 DCHECK_EQ(USER_INITIATED_PREVIEW, print_preview_state_);
278 Send(reply_msg);
279 return;
280 }
281
282 print_preview_state_ = SCRIPTED_PREVIEW;
283 base::Closure callback =
284 base::Bind(&PrintViewManager::OnScriptedPrintPreviewReply,
285 base::Unretained(this),
286 reply_msg);
287 map[rph] = callback;
288 scripted_print_preview_rph_ = rph;
289
290 PrintPreviewTabController::PrintPreview(tab_);
291 }
292
293 void PrintViewManager::OnScriptedPrintPreviewReply(IPC::Message* reply_msg) {
294 BrowserThread::CurrentlyOn(BrowserThread::UI);
295 Send(reply_msg);
296 }
297
230 bool PrintViewManager::OnMessageReceived(const IPC::Message& message) { 298 bool PrintViewManager::OnMessageReceived(const IPC::Message& message) {
231 bool handled = true; 299 bool handled = true;
232 IPC_BEGIN_MESSAGE_MAP(PrintViewManager, message) 300 IPC_BEGIN_MESSAGE_MAP(PrintViewManager, message)
233 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount, 301 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount,
234 OnDidGetPrintedPagesCount) 302 OnDidGetPrintedPagesCount)
235 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDocumentCookie, 303 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDocumentCookie,
236 OnDidGetDocumentCookie) 304 OnDidGetDocumentCookie)
237 IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog) 305 IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog)
238 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) 306 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage)
239 IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed, OnPrintingFailed) 307 IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed, OnPrintingFailed)
308 IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrintPreview,
309 OnScriptedPrintPreview)
240 IPC_MESSAGE_UNHANDLED(handled = false) 310 IPC_MESSAGE_UNHANDLED(handled = false)
241 IPC_END_MESSAGE_MAP() 311 IPC_END_MESSAGE_MAP()
242 return handled; 312 return handled;
243 } 313 }
244 314
245 void PrintViewManager::Observe(int type, 315 void PrintViewManager::Observe(int type,
246 const content::NotificationSource& source, 316 const content::NotificationSource& source,
247 const content::NotificationDetails& details) { 317 const content::NotificationDetails& details) {
248 switch (type) { 318 switch (type) {
249 case chrome::NOTIFICATION_PRINT_JOB_EVENT: { 319 case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 } 581 }
512 582
513 bool PrintViewManager::PrintNowInternal(IPC::Message* message) { 583 bool PrintViewManager::PrintNowInternal(IPC::Message* message) {
514 // Don't print / print preview interstitials. 584 // Don't print / print preview interstitials.
515 if (tab_contents()->showing_interstitial_page()) 585 if (tab_contents()->showing_interstitial_page())
516 return false; 586 return false;
517 return Send(message); 587 return Send(message);
518 } 588 }
519 589
520 } // namespace printing 590 } // namespace printing
OLDNEW
« no previous file with comments | « chrome/browser/printing/print_view_manager.h ('k') | chrome/browser/printing/printing_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698