diff options
-rw-r--r-- | chrome/browser/printing/print_preview_message_handler.cc | 12 | ||||
-rw-r--r-- | chrome/browser/printing/print_preview_message_handler.h | 9 | ||||
-rw-r--r-- | chrome/browser/ui/webui/print_preview_handler.cc | 28 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 15 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper.cc | 136 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper.h | 23 | ||||
-rw-r--r-- | content/browser/renderer_host/render_view_host.cc | 4 |
7 files changed, 164 insertions, 63 deletions
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc index de2c00e..a14738e 100644 --- a/chrome/browser/printing/print_preview_message_handler.cc +++ b/chrome/browser/printing/print_preview_message_handler.cc @@ -79,12 +79,24 @@ void PrintPreviewMessageHandler::OnPagesReadyForPreview( #endif // defined(OS_POSIX) } +void PrintPreviewMessageHandler::OnPrintPreviewNodeUnderContextMenu() { + tab_contents()->PrintPreview(); +} + +void PrintPreviewMessageHandler::OnScriptInitiatedPrintPreview() { + tab_contents()->PrintPreview(); +} + bool PrintPreviewMessageHandler::OnMessageReceived( const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message) IPC_MESSAGE_HANDLER(ViewHostMsg_PagesReadyForPreview, OnPagesReadyForPreview) + IPC_MESSAGE_HANDLER(ViewHostMsg_PrintPreviewNodeUnderContextMenu, + OnPrintPreviewNodeUnderContextMenu) + IPC_MESSAGE_HANDLER(ViewHostMsg_ScriptInitiatedPrintPreview, + OnScriptInitiatedPrintPreview) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h index eddc489..c889afb 100644 --- a/chrome/browser/printing/print_preview_message_handler.h +++ b/chrome/browser/printing/print_preview_message_handler.h @@ -20,9 +20,6 @@ class PrintPreviewMessageHandler : public TabContentsObserver { explicit PrintPreviewMessageHandler(TabContents* tab_contents); virtual ~PrintPreviewMessageHandler(); - void OnPagesReadyForPreview( - const ViewHostMsg_DidPreviewDocument_Params& params); - // TabContentsObserver implementation. virtual bool OnMessageReceived(const IPC::Message& message); @@ -30,6 +27,12 @@ class PrintPreviewMessageHandler : public TabContentsObserver { // Gets the print preview tab associated with |owner_|. TabContents* GetPrintPreviewTab(); + void OnPagesReadyForPreview( + const ViewHostMsg_DidPreviewDocument_Params& params); + void OnPrintPreviewNodeUnderContextMenu(); + void OnScriptInitiatedPrintPreview(); + + DISALLOW_COPY_AND_ASSIGN(PrintPreviewMessageHandler); }; diff --git a/chrome/browser/ui/webui/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview_handler.cc index 66a3da3..863e2d7 100644 --- a/chrome/browser/ui/webui/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview_handler.cc @@ -4,15 +4,30 @@ #include "chrome/browser/ui/webui/print_preview_handler.h" +#include <string> + #include "base/json/json_reader.h" #include "base/threading/thread.h" #include "base/values.h" #include "chrome/browser/printing/print_preview_tab_controller.h" +#include "chrome/common/render_messages.h" #include "content/browser/browser_thread.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/tab_contents/tab_contents.h" #include "printing/backend/print_backend.h" +namespace { + +TabContents* GetInitiatorTab(TabContents* preview_tab) { + printing::PrintPreviewTabController* tab_controller = + printing::PrintPreviewTabController::GetInstance(); + if (!tab_controller) + return NULL; + return tab_controller->GetInitiatorTab(preview_tab); +} + +} // namespace + class EnumeratePrintersTaskProxy : public base::RefCountedThreadSafe<EnumeratePrintersTaskProxy, BrowserThread::DeleteOnUIThread> { @@ -85,18 +100,19 @@ void PrintPreviewHandler::HandleGetPrinters(const ListValue*) { } void PrintPreviewHandler::HandleGetPreview(const ListValue*) { - printing::PrintPreviewTabController* tab_controller = - printing::PrintPreviewTabController::GetInstance(); - if (!tab_controller) - return; - TabContents* initiator_tab = - tab_controller->GetInitiatorTab(web_ui_->tab_contents()); + TabContents* initiator_tab = GetInitiatorTab(web_ui_->tab_contents()); if (!initiator_tab) return; initiator_tab->render_view_host()->PrintPreview(); } void PrintPreviewHandler::HandlePrint(const ListValue* args) { + TabContents* initiator_tab = GetInitiatorTab(web_ui_->tab_contents()); + if (initiator_tab) { + RenderViewHost* rvh = initiator_tab->render_view_host(); + rvh->Send(new ViewMsg_ResetScriptedPrintCount(rvh->routing_id())); + } + std::string json_str; if (!args->GetString(0, &json_str)) { NOTREACHED() << "Could not read JSON argument"; diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 081247b..9b9d15b 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -399,8 +399,12 @@ IPC_MESSAGE_ROUTED2(ViewMsg_PrintingDone, bool /* success */) // Tells the render view to switch the CSS to print media type, renders every -// requested pages for print preview. -IPC_MESSAGE_ROUTED0(ViewMsg_PrintPreview) +// requested pages for print preview using the given |settngs|. +IPC_MESSAGE_ROUTED1(ViewMsg_PrintPreview, + DictionaryValue /* settings */) + +// Tells a renderer to stop blocking script initiated printing. +IPC_MESSAGE_ROUTED0(ViewMsg_ResetScriptedPrintCount) // Sends back to the browser the rendered "printed document" for preview that // was requested by a ViewMsg_PrintPreview message. The memory handle in this @@ -1825,6 +1829,12 @@ IPC_MESSAGE_CONTROL1(ViewHostMsg_TempFileForPrintingWritten, int /* fd in browser */) #endif +// Asks the browser to do print preview for the node under the context menu. +IPC_MESSAGE_ROUTED0(ViewHostMsg_PrintPreviewNodeUnderContextMenu) + +// Asks the browser to do print preview for window.print(). +IPC_MESSAGE_ROUTED0(ViewHostMsg_ScriptInitiatedPrintPreview) + // Asks the browser to create a block of shared memory for the renderer to // fill in and pass back to the browser. IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_AllocateSharedMemoryBuffer, @@ -2172,4 +2182,3 @@ IPC_MESSAGE_ROUTED3(ViewHostMsg_RegisterProtocolHandler, std::string /* scheme */, GURL /* url */, string16 /* title */) - diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc index 834da83..251e46b 100644 --- a/chrome/renderer/print_web_view_helper.cc +++ b/chrome/renderer/print_web_view_helper.cc @@ -109,6 +109,8 @@ PrepareFrameAndViewForPrint::~PrepareFrameAndViewForPrint() { PrintWebViewHelper::PrintWebViewHelper(RenderView* render_view) : RenderViewObserver(render_view), print_web_view_(NULL), + script_initiated_preview_frame_(NULL), + context_menu_preview_node_(NULL), user_cancelled_scripted_print_count_(0) { is_preview_ = CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnablePrintPreview); @@ -122,8 +124,17 @@ void PrintWebViewHelper::ScriptInitiatedPrint(WebKit::WebFrame* frame) { if (IsScriptInitiatedPrintTooFrequent(frame)) return; IncrementScriptedPrintCount(); - // TODO(thestig) Handle print preview case. http://crbug.com/75505. - Print(frame, NULL); + + if (is_preview_) { + script_initiated_preview_frame_ = frame; + if (!render_view()->Send(new ViewHostMsg_ScriptInitiatedPrintPreview( + render_view()->routing_id()))) { + NOTREACHED(); + return; + } + } else { + Print(frame, NULL); + } } bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) { @@ -136,6 +147,8 @@ bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_PrintPreview, OnPrintPreview) IPC_MESSAGE_HANDLER(ViewMsg_PrintNodeUnderContextMenu, OnPrintNodeUnderContextMenu) + IPC_MESSAGE_HANDLER(ViewMsg_ResetScriptedPrintCount, + ResetScriptedPrintCount) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -181,27 +194,47 @@ void PrintWebViewHelper::OnPrintForPrintPreview( #endif } -void PrintWebViewHelper::OnPrint() { +bool PrintWebViewHelper::GetPrintFrame(WebKit::WebFrame** frame) { + DCHECK(frame); DCHECK(render_view()->webview()); if (!render_view()->webview()) - return; + return false; // If the user has selected text in the currently focused frame we print // only that frame (this makes print selection work for multiple frames). - WebFrame* frame = render_view()->webview()->focusedFrame()->hasSelection() ? + *frame = render_view()->webview()->focusedFrame()->hasSelection() ? render_view()->webview()->focusedFrame() : render_view()->webview()->mainFrame(); - Print(frame, NULL); + return true; } void PrintWebViewHelper::OnPrintPages() { DCHECK(!is_preview_); - OnPrint(); + WebFrame* frame; + if (GetPrintFrame(&frame)) + Print(frame, NULL); } -void PrintWebViewHelper::OnPrintPreview() { +void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) { DCHECK(is_preview_); - OnPrint(); + + if (script_initiated_preview_frame_) { + // Script initiated print preview. + DCHECK(!context_menu_preview_node_.get()); + PrintPreview(script_initiated_preview_frame_, NULL, settings); + script_initiated_preview_frame_ = NULL; + } else if (context_menu_preview_node_.get()) { + // User initiated - print node under context menu. + DCHECK(!script_initiated_preview_frame_); + PrintPreview(context_menu_preview_node_->document().frame(), + context_menu_preview_node_.get(), settings); + context_menu_preview_node_.reset(); + } else { + // User initiated - normal print preview. + WebFrame* frame; + if (GetPrintFrame(&frame)) + PrintPreview(frame, NULL, settings); + } } void PrintWebViewHelper::OnPrintingDone(int document_cookie, bool success) { @@ -211,20 +244,29 @@ void PrintWebViewHelper::OnPrintingDone(int document_cookie, bool success) { } void PrintWebViewHelper::OnPrintNodeUnderContextMenu() { - if (render_view()->context_menu_node().isNull()) { + const WebNode& context_menu_node = render_view()->context_menu_node(); + if (context_menu_node.isNull()) { NOTREACHED(); return; } - // TODO(thestig) Handle print preview case. http://crbug.com/75505. - - // Make a copy of the node, since we will do a sync call to the browser and - // during that time OnContextMenuClosed might reset context_menu_node_. - WebNode context_menu_node(render_view()->context_menu_node()); - Print(context_menu_node.document().frame(), &context_menu_node); + // Make a copy of the node, in case RenderView::OnContextMenuClosed resets + // its |context_menu_node_|. + if (is_preview_) { + context_menu_preview_node_.reset(new WebNode(context_menu_node)); + if (!render_view()->Send(new ViewHostMsg_PrintPreviewNodeUnderContextMenu( + render_view()->routing_id()))) { + NOTREACHED(); + return; + } + } else { + WebNode duplicate_node(context_menu_node); + Print(duplicate_node.document().frame(), &duplicate_node); + } } void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) { + DCHECK(!is_preview_); // If still not finished with earlier print request simply ignore. if (print_web_view_) return; @@ -246,38 +288,42 @@ void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) { use_browser_overlays = prep_frame_view.ShouldUseBrowserOverlays(); } - bool print_cancelled = false; - // Some full screen plugins can say they don't want to print. - if (expected_pages_count) { - if (!is_preview_) { - // Ask the browser to show UI to retrieve the final print settings. - if (!GetPrintSettingsFromUser(frame, expected_pages_count, - use_browser_overlays)) { - print_cancelled = true; - } - } + if (!expected_pages_count) { + DidFinishPrinting(true); // Release all printing resources. + return; + } - // Render Pages for printing. - if (!print_cancelled) { - if (is_preview_) - RenderPagesForPreview(frame, node); - else - RenderPagesForPrint(frame, node); + // Ask the browser to show UI to retrieve the final print settings. + if (!GetPrintSettingsFromUser(frame, expected_pages_count, + use_browser_overlays)) { + DidFinishPrinting(true); // Release all printing resources. + return; + } - ResetScriptedPrintCount(); - return; // All went well. - } - } else { - // Nothing to print. - print_cancelled = true; + // Render Pages for printing. + RenderPagesForPrint(frame, node); + ResetScriptedPrintCount(); +} + +void PrintWebViewHelper::PrintPreview(WebKit::WebFrame* frame, + WebKit::WebNode* node, + const DictionaryValue& settings) { + DCHECK(is_preview_); + + if (!InitPrintSettings(frame, node)) { + NOTREACHED() << "Failed to initialize print page settings"; + return; + } + + if (!UpdatePrintSettings(settings)) { + NOTREACHED() << "Failed to update print page settings"; + DidFinishPrinting(true); // Release all printing resources. + return; } - // When |print_cancelled| is true, we treat it as success so that - // DidFinishPrinting() won't show any error alert. we call - // DidFinishPrinting() here to release printing resources, since - // we don't need them anymore. - if (print_cancelled) - DidFinishPrinting(print_cancelled); + + // Render Pages for printing. + RenderPagesForPreview(frame, node); } void PrintWebViewHelper::DidFinishPrinting(bool success) { @@ -628,7 +674,7 @@ bool PrintWebViewHelper::IsScriptInitiatedPrintTooFrequent( } void PrintWebViewHelper::ResetScriptedPrintCount() { - // Reset cancel counter on first successful print. + // Reset cancel counter on successful print. user_cancelled_scripted_print_count_ = 0; } diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h index 2f71c2e..548f177 100644 --- a/chrome/renderer/print_web_view_helper.h +++ b/chrome/renderer/print_web_view_helper.h @@ -96,12 +96,11 @@ class PrintWebViewHelper : public RenderViewObserver , // Message handlers --------------------------------------------------------- - // Print the document or generate a print preview. + // Print the document. void OnPrintPages(); - void OnPrintPreview(); - // Common method for OnPrintPages() and OnPrintPreview(). - void OnPrint(); + // Generate a print preview using |settings|. + void OnPrintPreview(const DictionaryValue& settings); // Print / preview the node under the context menu. void OnPrintNodeUnderContextMenu(); @@ -116,6 +115,10 @@ class PrintWebViewHelper : public RenderViewObserver , void Print(WebKit::WebFrame* frame, WebKit::WebNode* node); + void PrintPreview(WebKit::WebFrame* frame, + WebKit::WebNode* node, + const DictionaryValue& settings); + // Notification when printing is done - signal teardown. void DidFinishPrinting(bool success); @@ -167,7 +170,8 @@ class PrintWebViewHelper : public RenderViewObserver , // On success, Send ViewHostMsg_PagesReadyForPreview message with a // valid metafile data handle. void CreatePreviewDocument(const ViewMsg_PrintPages_Params& params, - WebKit::WebFrame* frame, WebKit::WebNode* node); + WebKit::WebFrame* frame, + WebKit::WebNode* node); // Platform specific helper function for rendering page(s) to |metafile|. #if defined(OS_WIN) @@ -209,6 +213,8 @@ class PrintWebViewHelper : public RenderViewObserver , WebKit::WebNode* node, ViewMsg_Print_Params* params); + bool GetPrintFrame(WebKit::WebFrame** frame); + // Script Initiated Printing ------------------------------------------------ // Returns true if script initiated printing occurs too often. @@ -223,6 +229,13 @@ class PrintWebViewHelper : public RenderViewObserver , void IncrementScriptedPrintCount(); WebKit::WebView* print_web_view_; + + // The frame to print for script initiated print preview. + WebKit::WebFrame* script_initiated_preview_frame_; + + // The node under the context menu to print preview. + scoped_ptr<WebKit::WebNode> context_menu_preview_node_; + scoped_ptr<ViewMsg_PrintPages_Params> print_pages_params_; base::Time last_cancelled_script_print_; int user_cancelled_scripted_print_count_; diff --git a/content/browser/renderer_host/render_view_host.cc b/content/browser/renderer_host/render_view_host.cc index 3e0858f..62fde16 100644 --- a/content/browser/renderer_host/render_view_host.cc +++ b/content/browser/renderer_host/render_view_host.cc @@ -363,7 +363,9 @@ bool RenderViewHost::PrintPages() { } bool RenderViewHost::PrintPreview() { - return Send(new ViewMsg_PrintPreview(routing_id())); + // TODO(thestig) Get settings from the print preview UI. + DictionaryValue dummy_dict; + return Send(new ViewMsg_PrintPreview(routing_id(), dummy_dict)); } void RenderViewHost::PrintingDone(int document_cookie, bool success) { |