From 8572ccb80733bab172e64d5c06814acc7d1b27ea Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 1 Jun 2015 10:37:27 +0800 Subject: [PATCH] Add callback function in printToPDF API. --- atom/browser/api/atom_api_window.cc | 8 ++-- atom/browser/native_window.cc | 5 ++- atom/browser/native_window.h | 4 +- .../printing/print_preview_message_handler.cc | 43 +++++++++++++------ .../printing/print_preview_message_handler.h | 20 ++++++++- 5 files changed, 61 insertions(+), 19 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 66f17029bd54..8872a0e7f6ca 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -16,7 +16,6 @@ #include "native_mate/callback.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" -#include "printing/print_job_constants.h" #include "ui/gfx/geometry/rect.h" #include "atom/common/node_includes.h" @@ -433,11 +432,14 @@ void Window::Print(mate::Arguments* args) { void Window::PrintToPDF(mate::Arguments* args) { mate::Dictionary options; - if (args->Length() == 1 && !args->GetNext(&options)) { + base::Callback callback; + if (!(args->Length() == 1 && !args->GetNext(&callback)) && + !(args->Length() == 2 && args->GetNext(&options) + && args->GetNext(&callback))) { args->ThrowError(); return; } - window_->PrintToPDF(options); + window_->PrintToPDF(options, callback); } void Window::SetProgressBar(double progress) { diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index f7616f423666..2edf8906d6c2 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -265,9 +265,10 @@ void NativeWindow::Print(bool silent, bool print_background) { PrintNow(silent, print_background); } -void NativeWindow::PrintToPDF(const mate::Dictionary& options) { +void NativeWindow::PrintToPDF(const mate::Dictionary& options, + const PrintToPDFCallback& callback) { printing::PrintPreviewMessageHandler::FromWebContents(GetWebContents())-> - HandleGetPreview(options); + HandleGetPreview(options, callback); } void NativeWindow::ShowDefinitionForSelection() { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index dd10dd1229f2..78187bc8d458 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -55,6 +55,7 @@ class NativeWindow : public CommonWebContentsDelegate, public content::NotificationObserver { public: typedef base::Callback CapturePageCallback; + typedef base::Callback PrintToPDFCallback; class DialogScope { public: @@ -158,7 +159,8 @@ class NativeWindow : public CommonWebContentsDelegate, virtual void Print(bool silent, bool print_background); // Print current page as PDF. - virtual void PrintToPDF(const mate::Dictionary& options); + virtual void PrintToPDF(const mate::Dictionary& options, + const PrintToPDFCallback& callback); // Show popup dictionary. virtual void ShowDefinitionForSelection(); diff --git a/chromium_src/chrome/browser/printing/print_preview_message_handler.cc b/chromium_src/chrome/browser/printing/print_preview_message_handler.cc index bb960b2ef75e..36befec47915 100644 --- a/chromium_src/chrome/browser/printing/print_preview_message_handler.cc +++ b/chromium_src/chrome/browser/printing/print_preview_message_handler.cc @@ -60,19 +60,23 @@ base::RefCountedBytes* GetDataFromHandle(base::SharedMemoryHandle handle, return base::RefCountedBytes::TakeVector(&data); } -void PrintToPdfCallback(const scoped_refptr& data, - const base::FilePath& save_path) { +printing::PrintPreviewMessageHandler::PrintPDFResult +SavePDF(const scoped_refptr& data, + const base::FilePath& save_path) { printing::PdfMetafileSkia metafile; metafile.InitFromData(static_cast(data->front()), data->size()); base::File file(save_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); - metafile.SaveTo(&file); + return metafile.SaveTo(&file)? + printing::PrintPreviewMessageHandler::SUCCESS : + printing::PrintPreviewMessageHandler::FAIL_SAVEFILE; } } // namespace namespace printing { + PrintPreviewMessageHandler::PrintPreviewMessageHandler( WebContents* web_contents) : content::WebContentsObserver(web_contents) { @@ -122,14 +126,19 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting( atom::NativeWindow* window = atom::NativeWindow::FromWebContents( web_contents()); base::FilePath save_path; - file_dialog::ShowSaveDialog(window, "Save As", - base::FilePath(FILE_PATH_LITERAL("print.pdf")), - file_dialog::Filters(), &save_path); - BrowserThread::PostTask(BrowserThread::FILE, - FROM_HERE, - base::Bind(&PrintToPdfCallback, - data, - save_path)); + if (!file_dialog::ShowSaveDialog(window, "Save As", + base::FilePath(FILE_PATH_LITERAL("print.pdf")), + file_dialog::Filters(), &save_path)) { // Users cancel dialog. + RunPrintToPDFCallback(params.preview_request_id, FAIL_CANCEL); + return; + } + BrowserThread::PostTaskAndReplyWithResult( + BrowserThread::FILE, + FROM_HERE, + base::Bind(&SavePDF, data, save_path), + base::Bind(&PrintPreviewMessageHandler::RunPrintToPDFCallback, + base::Unretained(this), + params.preview_request_id)); } //void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie) { @@ -200,7 +209,8 @@ bool PrintPreviewMessageHandler::OnMessageReceived( } void PrintPreviewMessageHandler::HandleGetPreview( - const mate::Dictionary& options) { + const mate::Dictionary& options, + const atom::NativeWindow::PrintToPDFCallback& callback) { static int request_id = 0; request_id++; // A simulated Chromium print preivew setting. @@ -238,6 +248,9 @@ void PrintPreviewMessageHandler::HandleGetPreview( static_cast( base::JSONReader::Read(setting_json_str))); settings->SetInteger(printing::kPreviewRequestID, request_id); + print_to_pdf_callback_map_[request_id] = callback; + + // Default Print PDF settings: int margins_type = 0; // DEFAULT_MARGINS bool print_background = false; @@ -263,4 +276,10 @@ void PrintPreviewMessageHandler::HandleGetPreview( rvh->Send(new PrintMsg_PrintPreview(rvh->GetRoutingID(), *settings)); } +void PrintPreviewMessageHandler::RunPrintToPDFCallback( + int request_id, PrintPDFResult result) { + print_to_pdf_callback_map_[request_id].Run(static_cast(result)); + print_to_pdf_callback_map_.erase(request_id); +} + } // namespace printing diff --git a/chromium_src/chrome/browser/printing/print_preview_message_handler.h b/chromium_src/chrome/browser/printing/print_preview_message_handler.h index 38943b01b80a..5594a41f2db1 100644 --- a/chromium_src/chrome/browser/printing/print_preview_message_handler.h +++ b/chromium_src/chrome/browser/printing/print_preview_message_handler.h @@ -5,6 +5,9 @@ #ifndef CHROME_BROWSER_PRINTING_PRINT_PREVIEW_MESSAGE_HANDLER_H_ #define CHROME_BROWSER_PRINTING_PRINT_PREVIEW_MESSAGE_HANDLER_H_ +#include + +#include "atom/browser/native_window.h" #include "base/compiler_specific.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -34,6 +37,13 @@ class PrintPreviewMessageHandler : public content::WebContentsObserver, public content::WebContentsUserData { public: + enum PrintPDFResult { + SUCCESS, + FAIL_PREVIEW, + FAIL_SAVEFILE, + FAIL_CANCEL, + }; + ~PrintPreviewMessageHandler() override; // content::WebContentsObserver implementation. @@ -41,8 +51,12 @@ class PrintPreviewMessageHandler // Asks the initiator renderer to generate a preview. First element of |args| // is a job settings JSON string. - void HandleGetPreview(const mate::Dictionary& options); + void HandleGetPreview(const mate::Dictionary& options, + const atom::NativeWindow::PrintToPDFCallback& callback); + private: + typedef std::map PrintToPDFCallbackMap; + explicit PrintPreviewMessageHandler(content::WebContents* web_contents); friend class content::WebContentsUserData; @@ -65,6 +79,10 @@ class PrintPreviewMessageHandler //void OnSetOptionsFromDocument( //const PrintHostMsg_SetOptionsFromDocument_Params& params); + void RunPrintToPDFCallback(int request_id, PrintPDFResult result); + + PrintToPDFCallbackMap print_to_pdf_callback_map_; + DISALLOW_COPY_AND_ASSIGN(PrintPreviewMessageHandler); };