Index: chrome/browser/printing/print_view_manager.cc |
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc |
index 77dda243a46ab497e19bf7569fad4cbcfca4ebb8..e5187ea8c9ec3502eac4776a715b70e5f5cd61a9 100644 |
--- a/chrome/browser/printing/print_view_manager.cc |
+++ b/chrome/browser/printing/print_view_manager.cc |
@@ -5,6 +5,7 @@ |
#include "chrome/browser/printing/print_view_manager.h" |
#include "base/bind.h" |
+#include "base/lazy_instance.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/utf_string_conversions.h" |
#include "chrome/browser/browser_process.h" |
@@ -50,6 +51,13 @@ void ReleasePrinterQuery(int cookie) { |
} |
} |
+// Keeps track of pending scripted print preview closures. |
+// No locking, only access on the UI thread. |
+typedef std::map<RenderProcessHost*, base::Closure> |
+ ScriptedPrintPreviewClosureMap; |
+static base::LazyInstance<ScriptedPrintPreviewClosureMap> |
+ g_scripted_print_preview_closure_map(base::LINKER_INITIALIZED); |
+ |
} // namespace |
namespace printing { |
@@ -61,13 +69,16 @@ PrintViewManager::PrintViewManager(TabContentsWrapper* tab) |
printing_succeeded_(false), |
inside_inner_message_loop_(false), |
observer_(NULL), |
- cookie_(0) { |
+ cookie_(0), |
+ print_preview_state_(NOT_PREVIEWING), |
+ scripted_print_preview_rph_(NULL) { |
#if defined(OS_POSIX) && !defined(OS_MACOSX) |
expecting_first_page_ = true; |
#endif |
} |
PrintViewManager::~PrintViewManager() { |
+ DCHECK_EQ(NOT_PREVIEWING, print_preview_state_); |
vandebo (ex-Chrome)
2011/11/10 23:59:59
What if you close a tab/window while previewing?
Lei Zhang
2011/11/11 11:45:11
RemoveInitiatorTab() will call PrintPreviewDone()
|
ReleasePrinterQuery(cookie_); |
DisconnectFromCurrentPrintJob(); |
} |
@@ -103,9 +114,34 @@ bool PrintViewManager::AdvancedPrintNow() { |
} |
bool PrintViewManager::PrintPreviewNow() { |
+ if (print_preview_state_ != NOT_PREVIEWING) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ print_preview_state_ = USER_INITIATED_PREVIEW; |
return PrintNowInternal(new PrintMsg_InitiatePrintPreview(routing_id())); |
} |
+void PrintViewManager::PrintPreviewDone() { |
+ BrowserThread::CurrentlyOn(BrowserThread::UI); |
+ |
+ // Check for spurious call. |
vandebo (ex-Chrome)
2011/11/10 23:59:59
This makes me sad. If you can explain why there m
Lei Zhang
2011/11/11 11:45:11
This is a defensive move. I'll check whether it's
Lei Zhang
2011/11/11 22:34:26
Got rid of this and turned it into a DCHECK.
|
+ if (print_preview_state_ == NOT_PREVIEWING) |
+ return; |
+ |
+ if (print_preview_state_ == SCRIPTED_PREVIEW) { |
+ ScriptedPrintPreviewClosureMap& map = |
+ g_scripted_print_preview_closure_map.Get(); |
+ ScriptedPrintPreviewClosureMap::iterator it = |
+ map.find(scripted_print_preview_rph_); |
+ CHECK(it != map.end()); |
+ it->second.Run(); |
+ map.erase(scripted_print_preview_rph_); |
+ scripted_print_preview_rph_ = NULL; |
+ } |
+ print_preview_state_ = NOT_PREVIEWING; |
+} |
+ |
void PrintViewManager::PreviewPrintingRequestCancelled() { |
if (!tab_contents()) |
return; |
@@ -227,6 +263,35 @@ void PrintViewManager::OnPrintingFailed(int cookie) { |
content::NotificationService::NoDetails()); |
} |
+void PrintViewManager::OnScriptedPrintPreview(IPC::Message* reply_msg) { |
+ BrowserThread::CurrentlyOn(BrowserThread::UI); |
+ if (print_preview_state_ != NOT_PREVIEWING) { |
+ // If a user initiated print dialog is already open, ignore the scripted |
+ // print message. |
+ DCHECK_EQ(USER_INITIATED_PREVIEW, print_preview_state_); |
+ Send(reply_msg); |
+ return; |
+ } |
+ |
+ print_preview_state_ = SCRIPTED_PREVIEW; |
+ scripted_print_preview_rph_ = tab_contents()->render_view_host()->process(); |
+ base::Closure callback = |
+ base::Bind(&PrintViewManager::OnScriptedPrintPreviewReply, |
+ base::Unretained(this), |
+ reply_msg); |
+ ScriptedPrintPreviewClosureMap& map = |
+ g_scripted_print_preview_closure_map.Get(); |
+ CHECK_EQ(0U, map.count(scripted_print_preview_rph_)); |
+ map[scripted_print_preview_rph_] = callback; |
+ |
+ PrintNowInternal(new PrintMsg_InitiatePrintPreview(routing_id())); |
vandebo (ex-Chrome)
2011/11/10 23:59:59
This will trigger GetPrintFrame(), but the caller
Lei Zhang
2011/11/11 11:45:11
I'm surprised this didn't blow up, fixed.
|
+} |
+ |
+void PrintViewManager::OnScriptedPrintPreviewReply(IPC::Message* reply_msg) { |
+ BrowserThread::CurrentlyOn(BrowserThread::UI); |
+ Send(reply_msg); |
+} |
+ |
bool PrintViewManager::OnMessageReceived(const IPC::Message& message) { |
bool handled = true; |
IPC_BEGIN_MESSAGE_MAP(PrintViewManager, message) |
@@ -237,6 +302,8 @@ bool PrintViewManager::OnMessageReceived(const IPC::Message& message) { |
IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog) |
IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) |
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed, OnPrintingFailed) |
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrintPreview, |
+ OnScriptedPrintPreview) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
return handled; |