diff options
author | sverrir@google.com <sverrir@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-19 15:58:01 +0000 |
---|---|---|
committer | sverrir@google.com <sverrir@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-19 15:58:01 +0000 |
commit | 8227045e458705c27ca116a02fd7b9b9a75237ae (patch) | |
tree | 2e694fc454663eedc62b27e99aeef67d476a09ab | |
parent | b0fd9c1c6b3ccf0b436d38d181ab26100b3135a6 (diff) | |
download | chromium_src-8227045e458705c27ca116a02fd7b9b9a75237ae.zip chromium_src-8227045e458705c27ca116a02fd7b9b9a75237ae.tar.gz chromium_src-8227045e458705c27ca116a02fd7b9b9a75237ae.tar.bz2 |
Add Print Selection support to Chrome. This change is fairly involved since this means that the printing is done async instead of the fully synchronous mode the normal full page printing is.
This means we create an in memory copy of the selected text for printing.
This is the next step to move to fully async printing with print frame support.
This change also removes the print on demand functionality that was no longer used.
BUG=http://crbug.com/1682
TEST=The print dialog on Windows now contains an option to print selection only. Test that with various pages and various selections.
Review URL: http://codereview.chromium.org/125082
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18815 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 162 insertions, 128 deletions
diff --git a/chrome/browser/printing/page_range.cc b/chrome/browser/printing/page_range.cc index bb9d05a..9669a9e 100644 --- a/chrome/browser/printing/page_range.cc +++ b/chrome/browser/printing/page_range.cc @@ -8,6 +8,7 @@ namespace printing { +/* static */ std::vector<int> PageRange::GetPages(const PageRanges& ranges) { std::set<int> pages; for (unsigned i = 0; i < ranges.size(); ++i) { @@ -20,4 +21,11 @@ std::vector<int> PageRange::GetPages(const PageRanges& ranges) { return SetToVector(pages); } +/* static */ +int PageRange::GetTotalPages(const PageRanges& ranges) { + // Since ranges can overlap we need to merge them before counting + std::vector<int> pages = PageRange::GetPages(ranges); + return pages.size(); +} + } // namespace printing diff --git a/chrome/browser/printing/page_range.h b/chrome/browser/printing/page_range.h index a2d042c..1f3e024 100644 --- a/chrome/browser/printing/page_range.h +++ b/chrome/browser/printing/page_range.h @@ -24,6 +24,9 @@ struct PageRange { // Retrieves the sorted list of unique pages in the page ranges. static std::vector<int> GetPages(const PageRanges& ranges); + + // Gets the total number of pages. + static int GetTotalPages(const PageRanges& ranges); }; } // namespace printing diff --git a/chrome/browser/printing/page_range_unittest.cc b/chrome/browser/printing/page_range_unittest.cc index b059d5b..a5ac563 100644 --- a/chrome/browser/printing/page_range_unittest.cc +++ b/chrome/browser/printing/page_range_unittest.cc @@ -27,10 +27,12 @@ TEST(PageRangeTest, RangeMerge) { EXPECT_EQ(10, pages[5]); EXPECT_EQ(11, pages[6]); EXPECT_EQ(12, pages[7]); + EXPECT_EQ(8, printing::PageRange::GetTotalPages(ranges)); } TEST(PageRangeTest, Empty) { printing::PageRanges ranges; std::vector<int> pages(printing::PageRange::GetPages(ranges)); EXPECT_EQ(0U, pages.size()); + EXPECT_EQ(0, printing::PageRange::GetTotalPages(ranges)); } diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc index 19c2add..af32da0 100644 --- a/chrome/browser/printing/print_job_worker.cc +++ b/chrome/browser/printing/print_job_worker.cc @@ -50,7 +50,7 @@ class PrintJobWorker::NotificationTask : public Task { PrintJobWorker::PrintJobWorker(PrintJobWorkerOwner* owner) : Thread("Printing_Worker"), owner_(owner) { - // The object is created in the UI thread. + // The object is created in the IO thread. DCHECK_EQ(owner_->message_loop(), MessageLoop::current()); } @@ -167,7 +167,7 @@ void PrintJobWorker::OnNewPage() { // Is the page available? scoped_refptr<PrintedPage> page; if (!document_->GetPage(page_number_.ToInt(), &page)) { - // The page is implictly requested. + // The page is implicitly requested. break; } // The page is there, print it. @@ -192,21 +192,6 @@ void PrintJobWorker::DismissDialog() { printing_context_.DismissDialog(); } -void PrintJobWorker::RequestMissingPages() { - DCHECK_EQ(message_loop(), MessageLoop::current()); - // It may arrive out of order. Don't mind about it. - if (page_number_ != PageNumber::npos()) { - // We are printing. - document_->RequestMissingPages(); - } - NotificationTask* task = new NotificationTask(); - task->Init(owner_, - JobEventDetails::ALL_PAGES_REQUESTED, - document_.get(), - NULL); - owner_->message_loop()->PostTask(FROM_HERE, task); -} - void PrintJobWorker::OnDocumentDone() { DCHECK_EQ(message_loop(), MessageLoop::current()); DCHECK_EQ(page_number_, PageNumber::npos()); diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h index cc1bde1..b01881a 100644 --- a/chrome/browser/printing/print_job_worker.h +++ b/chrome/browser/printing/print_job_worker.h @@ -55,10 +55,6 @@ class PrintJobWorker : public base::Thread { // Cancels the Print... dialog box if shown, noop otherwise. void DismissDialog(); - // Requests the missing pages in rendered_document_. Sends back a - // ALL_PAGES_REQUESTED notification once done. - void RequestMissingPages(); - protected: // Retrieves the context for testing only. PrintingContext& printing_context() { return printing_context_; } diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 5976bf3..d775ff5 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc @@ -25,6 +25,7 @@ namespace printing { PrintViewManager::PrintViewManager(TabContents& owner) : owner_(owner), waiting_to_print_(false), + printing_succeeded_(false), inside_inner_message_loop_(false) { } @@ -46,7 +47,7 @@ bool PrintViewManager::OnRenderViewGone(RenderViewHost* render_view_host) { scoped_refptr<PrintedDocument> document(print_job_->document()); if (document) { - // If IsComplete() returns false, the document isn't completely renderered. + // If IsComplete() returns false, the document isn't completely rendered. // Since our renderer is gone, there's nothing to do, cancel it. Otherwise, // the print job may finish without problem. TerminatePrintJob(!document->IsComplete()); @@ -148,7 +149,6 @@ void PrintViewManager::OnNotifyPrintJobEvent( const JobEventDetails& event_details) { switch (event_details.type()) { case JobEventDetails::FAILED: { - // TODO(maruel): bug 1123882 Show some kind of notification. TerminatePrintJob(true); break; } @@ -176,6 +176,7 @@ void PrintViewManager::OnNotifyPrintJobEvent( // Printing is done, we don't need it anymore. // print_job_->is_job_pending() may still be true, depending on the order // of object registration. + printing_succeeded_ = true; ReleasePrintJob(); break; } @@ -202,6 +203,7 @@ bool PrintViewManager::RenderAllMissingPagesNow() { // Is the document already complete? if (print_job_->document() && print_job_->document()->IsComplete()) { waiting_to_print_ = false; + printing_succeeded_ = true; return true; } @@ -266,6 +268,7 @@ bool PrintViewManager::CreateNewPrintJob(PrintJobWorkerOwner* job) { print_job_->Initialize(job, this); registrar_.Add(this, NotificationType::PRINT_JOB_EVENT, Source<PrintJob>(print_job_.get())); + printing_succeeded_ = false; return true; } @@ -287,6 +290,12 @@ void PrintViewManager::DisconnectFromCurrentPrintJob() { } } +void PrintViewManager::PrintingDone(bool success) { + if (print_job_.get()) { + owner_.PrintingDone(print_job_->cookie(), success); + } +} + void PrintViewManager::TerminatePrintJob(bool cancel) { if (!print_job_.get()) return; @@ -314,6 +323,8 @@ void PrintViewManager::ReleasePrintJob() { if (!print_job_.get()) return; + PrintingDone(printing_succeeded_); + registrar_.Remove(this, NotificationType::PRINT_JOB_EVENT, Source<PrintJob>(print_job_.get())); print_job_->DisconnectSource(); diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h index 2562885..cd95f06 100644 --- a/chrome/browser/printing/print_view_manager.h +++ b/chrome/browser/printing/print_view_manager.h @@ -77,6 +77,9 @@ class PrintViewManager : public NotificationObserver, // disconnect from it. void DisconnectFromCurrentPrintJob(); + // Notify that the printing is done. + void PrintingDone(bool success); + // Terminates the print job. Noop if no print job has been created. If // |cancel| is true, cancel it instead of waiting for the job to finish. Will // call ReleasePrintJob(). @@ -113,6 +116,9 @@ class PrintViewManager : public NotificationObserver, // called. bool waiting_to_print_; + // Indication of success of the print job. + bool printing_succeeded_; + // Running an inner message loop inside RenderAllMissingPagesNow(). This means // we are _blocking_ until all the necessary pages have been rendered or the // print settings are being loaded. diff --git a/chrome/browser/printing/printed_document.cc b/chrome/browser/printing/printed_document.cc index f330070..c5ea1d9 100644 --- a/chrome/browser/printing/printed_document.cc +++ b/chrome/browser/printing/printed_document.cc @@ -67,25 +67,14 @@ void PrintedDocument::SetPage(int page_number, gfx::Emf* emf, double shrink) { bool PrintedDocument::GetPage(int page_number, scoped_refptr<PrintedPage>* page) { - bool request = false; - { - AutoLock lock(lock_); - PrintedPages::const_iterator itr = mutable_.pages_.find(page_number); - if (itr != mutable_.pages_.end()) { - if (itr->second.get()) { - *page = itr->second; - return true; - } - request = false; - } else { - request = true; - // Force the creation to not repeatedly request the same page. - mutable_.pages_[page_number]; + AutoLock lock(lock_); + PrintedPages::const_iterator itr = mutable_.pages_.find(page_number); + if (itr != mutable_.pages_.end()) { + if (itr->second.get()) { + *page = itr->second; + return true; } } - if (request) { - PrintPage_ThreadJump(page_number); - } return false; } @@ -180,32 +169,6 @@ bool PrintedDocument::IsComplete() const { return true; } -bool PrintedDocument::RequestMissingPages() { - typedef std::set<int> PageNumbers; - PageNumbers missing_pages; - { - AutoLock lock(lock_); - PageNumber page(immutable_.settings_, mutable_.page_count_); - if (page == PageNumber::npos()) - return false; - for (; page != PageNumber::npos(); ++page) { - PrintedPage* printed_page = mutable_.pages_[page.ToInt()].get(); - if (!printed_page || !printed_page->emf()) - missing_pages.insert(page.ToInt()); - } - } - if (!missing_pages.size()) - return true; - PageNumbers::const_iterator end = missing_pages.end(); - for (PageNumbers::const_iterator itr = missing_pages.begin(); - itr != end; - ++itr) { - int page_number = *itr; - PrintPage_ThreadJump(page_number); - } - return true; -} - void PrintedDocument::DisconnectSource() { AutoLock lock(lock_); mutable_.source_ = NULL; @@ -334,20 +297,6 @@ void PrintedDocument::PrintHeaderFooter(HDC context, DCHECK_NE(res, 0); } -void PrintedDocument::PrintPage_ThreadJump(int page_number) { - if (MessageLoop::current() != immutable_.source_message_loop_) { - immutable_.source_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &PrintedDocument::PrintPage_ThreadJump, page_number)); - } else { - PrintedPagesSource* source = NULL; - { - AutoLock lock(lock_); - source = mutable_.source_; - } - NOTREACHED(); - } -} - PrintedDocument::Mutable::Mutable(PrintedPagesSource* source) : source_(source), expected_page_count_(0), diff --git a/chrome/browser/printing/printed_document.h b/chrome/browser/printing/printed_document.h index 6080e0d..c78f57a 100644 --- a/chrome/browser/printing/printed_document.h +++ b/chrome/browser/printing/printed_document.h @@ -63,13 +63,6 @@ class PrintedDocument : public base::RefCountedThreadSafe<PrintedDocument> { // Note: locks while parsing the whole tree. bool IsComplete() const; - // Requests all the missing pages. Returns true if at least one page has been - // requested. Returns false if there was not enough information to request the - // missing pages, i.e. document_page_count_ is not initialized or no page has - // been requested. - // Note: locks while parsing the whole tree. - bool RequestMissingPages(); - // Disconnects the PrintedPage source (PrintedPagesSource). It is done when // the source is being destroyed. void DisconnectSource(); @@ -173,10 +166,6 @@ class PrintedDocument : public base::RefCountedThreadSafe<PrintedDocument> { PageOverlays::VerticalPosition y, const gfx::Font& font) const; - // Calls the render source to render a page. Makes sure to execute the call in - // the right thread context. - void PrintPage_ThreadJump(int page_number); - // All writable data member access must be guarded by this lock. Needs to be // mutable since it can be acquired from const member functions. mutable Lock lock_; diff --git a/chrome/browser/printing/win_printing_context.cc b/chrome/browser/printing/win_printing_context.cc index 6866800..1d0ad0e 100644 --- a/chrome/browser/printing/win_printing_context.cc +++ b/chrome/browser/printing/win_printing_context.cc @@ -403,15 +403,17 @@ bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode, DCHECK(!in_print_job_); DCHECK(hdc_); - // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector. PageRanges ranges_vector; - ranges_vector.reserve(number_ranges); - for (int i = 0; i < number_ranges; ++i) { - PageRange range; - // Transfert from 1-based to 0-based. - range.from = ranges[i].nFromPage - 1; - range.to = ranges[i].nToPage - 1; - ranges_vector.push_back(range); + if (!selection_only) { + // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector. + ranges_vector.reserve(number_ranges); + for (int i = 0; i < number_ranges; ++i) { + PageRange range; + // Transfer from 1-based to 0-based. + range.from = ranges[i].nFromPage - 1; + range.to = ranges[i].nToPage - 1; + ranges_vector.push_back(range); + } } settings_.Init(hdc_, dev_mode, diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index ead11b8..6b46069 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -367,6 +367,10 @@ bool RenderViewHost::PrintPages() { return Send(new ViewMsg_PrintPages(routing_id())); } +void RenderViewHost::PrintingDone(int document_cookie, bool success) { + Send(new ViewMsg_PrintingDone(routing_id(), document_cookie, success)); +} + void RenderViewHost::StartFinding(int request_id, const string16& search_text, bool forward, diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index a14af37..1fb5900 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -181,11 +181,13 @@ class RenderViewHost : public RenderWidgetHost { // Stops the current load. void Stop(); - // Asks the renderer to "render" printed pages and initiate printing on our // behalf. bool PrintPages(); + // Notify renderer of success/failure of print job. + void PrintingDone(int document_cookie, bool success); + // Start looking for a string within the content of the page, with the // specified options. void StartFinding(int request_id, diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index df84333..557d2a6 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -122,10 +122,6 @@ const int kJavascriptMessageExpectedDelay = 1000; const char kLinkDoctorBaseURL[] = "http://linkhelp.clients.google.com/tbproxy/lh/fixurl"; -// The printer icon in shell32.dll. That's a standard icon user will quickly -// recognize. -const int kShell32PrinterIcon = 17; - // The list of prefs we want to observe. const wchar_t* kPrefsToObserve[] = { prefs::kAlternateErrorPagesEnabled, @@ -1033,6 +1029,10 @@ bool TabContents::PrintNow() { return render_view_host()->PrintPages(); } +void TabContents::PrintingDone(int document_cookie, bool success) { + render_view_host()->PrintingDone(document_cookie, success); +} + bool TabContents::IsActiveEntry(int32 page_id) { NavigationEntry* active_entry = controller_.GetActiveEntry(); return (active_entry != NULL && diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 609e154..a94b6e1 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -524,6 +524,9 @@ class TabContents : public PageNavigator, // this function. Returns false if printing is impossible at the moment. bool PrintNow(); + // Notify the completion of a printing job. + void PrintingDone(int document_cookie, bool success); + // Returns true if the active NavigationEntry's page_id equals page_id. bool IsActiveEntry(int32 page_id); diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 9baf4c0..a5a89c4 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -100,6 +100,11 @@ IPC_BEGIN_MESSAGES(View) // requested pages and switch back the CSS to display media type. IPC_MESSAGE_ROUTED0(ViewMsg_PrintPages) + // Tells the render view that printing is done so it can clean up. + IPC_MESSAGE_ROUTED2(ViewMsg_PrintingDone, + int /* document_cookie */, + bool /* success */) + // Tells the render view that a ViewHostMsg_ScrollRect message was processed. // This signals the render view that it can send another ScrollRect message. IPC_MESSAGE_ROUTED0(ViewMsg_ScrollRect_ACK) diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc index 049dbb8..ab61664 100644 --- a/chrome/renderer/print_web_view_helper.cc +++ b/chrome/renderer/print_web_view_helper.cc @@ -13,6 +13,8 @@ #include "printing/units.h" #include "webkit/api/public/WebScreenInfo.h" #include "webkit/api/public/WebSize.h" +#include "webkit/api/public/WebURL.h" +#include "webkit/api/public/WebURLRequest.h" #include "webkit/glue/webframe.h" #if defined(OS_WIN) @@ -86,6 +88,11 @@ class PrepareFrameAndViewForPrint { void PrintWebViewHelper::SyncPrint(WebFrame* frame) { #if defined(OS_WIN) + + // If still not finished with earlier print request simply ignore. + if (IsPrinting()) + return; + // Retrieve the default print settings to calculate the expected number of // pages. ViewMsg_Print_Params default_settings; @@ -126,24 +133,21 @@ void PrintWebViewHelper::SyncPrint(WebFrame* frame) { render_view_->host_window(), default_settings.document_cookie, expected_pages_count, - false, // has_selection + frame->HasSelection(), &print_settings); if (Send(msg)) { msg = NULL; - // Printing selection only not supported yet. - if (print_settings.params.selection_only) { - NOTIMPLEMENTED(); - } - // If the settings are invalid, early quit. if (print_settings.params.dpi && print_settings.params.document_cookie) { - // Render the printed pages. It will implicitly revert the document to - // display CSS media type. - PrintPages(print_settings, frame); - // All went well. - return; + if (print_settings.params.selection_only) { + CopyAndPrint(print_settings, frame); + } else { + // TODO: Always copy before printing. + PrintPages(print_settings, frame); + } + return; // All went well. } else { // The user cancelled. } @@ -158,15 +162,52 @@ void PrintWebViewHelper::SyncPrint(WebFrame* frame) { // Send() failed. NOTREACHED(); } - // TODO(maruel): bug 1123882 Alert the user that printing failed. + DidFinishPrinting(false); #else // defined(OS_WIN) // TODO(port): print not implemented NOTIMPLEMENTED(); #endif } +void PrintWebViewHelper::DidFinishPrinting(bool success) { + if (print_web_view_.get()) { + print_web_view_->Close(); + print_web_view_.release(); // Close deletes object. + print_pages_params_.reset(); + } + + if (!success) { + // TODO(sverrir): http://crbug.com/6833 Show some kind of notification. + } +} + +bool PrintWebViewHelper::CopyAndPrint(const ViewMsg_PrintPages_Params& params, + WebFrame* web_frame) { + // Create a new WebView with the same settings as the current display one. + // Except that we disable javascript (don't want any active content running + // on the page). + WebPreferences prefs = web_frame->GetView()->GetPreferences(); + prefs.javascript_enabled = false; + prefs.java_enabled = false; + print_web_view_.reset(WebView::Create(this, prefs)); + + print_pages_params_.reset(new ViewMsg_PrintPages_Params(params)); + print_pages_params_->pages.clear(); // Print all pages of selection. + + std::string html = web_frame->GetSelection(true); + std::string url_str = "data:text/html;charset=utf-8,"; + url_str.append(html); + GURL url(url_str); + + // When loading is done this will call DidStopLoading that will do the + // actual printing. + print_web_view_->GetMainFrame()->LoadRequest(WebKit::WebURLRequest(url)); + + return true; +} + void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, - WebFrame* frame) { + WebFrame* frame) { PrepareFrameAndViewForPrint prep_frame_view(params.params, frame, frame->GetView()); @@ -314,12 +355,14 @@ int32 PrintWebViewHelper::routing_id() { return render_view_->routing_id(); } -void PrintWebViewHelper::GetWindowRect(WebWidget* webwidget, - WebKit::WebRect* rect) { - NOTREACHED(); +void PrintWebViewHelper::DidStopLoading(WebView* webview) { + DCHECK(print_pages_params_.get() != NULL); + DCHECK_EQ(webview, print_web_view_.get()); + PrintPages(*print_pages_params_.get(), print_web_view_->GetMainFrame()); } -void PrintWebViewHelper::DidStopLoading(WebView* webview) { +void PrintWebViewHelper::GetWindowRect(WebWidget* webwidget, + WebKit::WebRect* rect) { NOTREACHED(); } diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h index 1a56bd9..c2a02c2 100644 --- a/chrome/renderer/print_web_view_helper.h +++ b/chrome/renderer/print_web_view_helper.h @@ -20,6 +20,7 @@ class Message; class RenderView; class WebView; +struct ViewMsg_Print_Params; struct ViewMsg_PrintPage_Params; struct ViewMsg_PrintPages_Params; @@ -36,7 +37,17 @@ class PrintWebViewHelper : public WebViewDelegate { void SyncPrint(WebFrame* frame); + // Is there a background print in progress? + bool IsPrinting() { + return print_web_view_.get() != NULL; + } + + // Notification when printing is done - signal teardown + void DidFinishPrinting(bool success); + protected: + bool CopyAndPrint(const ViewMsg_PrintPages_Params& params, + WebFrame* web_frame); // Prints the page listed in |params|. void PrintPage(const ViewMsg_PrintPage_Params& params, @@ -44,6 +55,7 @@ class PrintWebViewHelper : public WebViewDelegate { WebFrame* frame); // Prints all the pages listed in |params|. + // It will implicitly revert the document to display CSS media type. void PrintPages(const ViewMsg_PrintPages_Params& params, WebFrame* frame); // IPC::Message::Sender @@ -52,7 +64,6 @@ class PrintWebViewHelper : public WebViewDelegate { int32 routing_id(); // WebViewDeletegate - virtual void DidStartLoading(WebView* webview) {} virtual void DidStopLoading(WebView* webview); virtual gfx::NativeViewId GetContainingView(WebWidget* webwidget); virtual void DidInvalidateRect(WebWidget* webwidget, @@ -85,6 +96,7 @@ class PrintWebViewHelper : public WebViewDelegate { private: RenderView* render_view_; scoped_ptr<WebView> print_web_view_; + scoped_ptr<ViewMsg_PrintPages_Params> print_pages_params_; private: DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelper); diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 6151878..8189dad 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -339,6 +339,7 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP(RenderView, message) IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail) IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages) + IPC_MESSAGE_HANDLER(ViewMsg_PrintingDone, OnPrintingDone) IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate) IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop) IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText) @@ -454,6 +455,15 @@ void RenderView::OnPrintPages() { } } +void RenderView::OnPrintingDone(int document_cookie, bool success) { + // Ignoring document cookie here since only one print job can be outstanding + // per renderer and document_cookie is 0 when printing is successful. + DCHECK(print_helper_.get()); + if (print_helper_.get() != NULL) { + print_helper_->DidFinishPrinting(success); + } +} + void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) { if (load_id != page_id_) return; // this capture call is no longer relevant due to navigation @@ -2217,9 +2227,10 @@ void RenderView::SetInputMethodState(bool enabled) { } void RenderView::ScriptedPrint(WebFrame* frame) { - print_render_view_.reset(new PrintWebViewHelper(this)); - print_render_view_->SyncPrint(frame); - print_render_view_.reset(); + if (print_helper_.get() == NULL) { + print_helper_.reset(new PrintWebViewHelper(this)); + } + print_helper_->SyncPrint(frame); } void RenderView::WebInspectorOpened(int num_resources) { diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 5e9d75b..19f3c43 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -461,6 +461,7 @@ class RenderView : public RenderWidget, // RenderView IPC message handlers void SendThumbnail(); void OnPrintPages(); + void OnPrintingDone(int document_cookie, bool success); void OnNavigate(const ViewMsg_Navigate_Params& params); void OnStop(); void OnLoadAlternateHTMLText(const std::string& html_contents, @@ -793,8 +794,9 @@ class RenderView : public RenderWidget, // to the new navigation is created. See DidCreateDataSource. scoped_ptr<NavigationState> pending_navigation_state_; - // Need for printing - scoped_ptr<PrintWebViewHelper> print_render_view_; + // PrintWebViewHelper handles printing. Note that this object is constructed + // when printing for the first time but only destroyed with the RenderView. + scoped_ptr<PrintWebViewHelper> print_helper_; RendererPreferences renderer_preferences_; diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc index 11f064a..36d1771 100644 --- a/webkit/glue/webview_impl.cc +++ b/webkit/glue/webview_impl.cc @@ -907,7 +907,8 @@ void WebViewImpl::Close() { } // Should happen after page_.reset(). - devtools_agent_.reset(NULL); + if (devtools_agent_.get()) + devtools_agent_.reset(NULL); Release(); // Balances AddRef from WebView::Create } |