Add callback function in printToPDF API.
authorHaojian Wu <hokein.wu@gmail.com>
Mon, 1 Jun 2015 02:37:27 +0000 (10:37 +0800)
committerHaojian Wu <hokein.wu@gmail.com>
Tue, 16 Jun 2015 12:02:24 +0000 (20:02 +0800)
atom/browser/api/atom_api_window.cc
atom/browser/native_window.cc
atom/browser/native_window.h
chromium_src/chrome/browser/printing/print_preview_message_handler.cc
chromium_src/chrome/browser/printing/print_preview_message_handler.h

index 66f1702..8872a0e 100644 (file)
@@ -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<void(int)> 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) {
index f7616f4..2edf890 100644 (file)
@@ -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() {
index dd10dd1..78187bc 100644 (file)
@@ -55,6 +55,7 @@ class NativeWindow : public CommonWebContentsDelegate,
                      public content::NotificationObserver {
  public:
   typedef base::Callback<void(const SkBitmap& bitmap)> CapturePageCallback;
+  typedef base::Callback<void(int)> 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();
index bb960b2..36befec 100644 (file)
@@ -60,19 +60,23 @@ base::RefCountedBytes* GetDataFromHandle(base::SharedMemoryHandle handle,
   return base::RefCountedBytes::TakeVector(&data);
 }
 
-void PrintToPdfCallback(const scoped_refptr<base::RefCountedBytes>& data,
-                        const base::FilePath& save_path) {
+printing::PrintPreviewMessageHandler::PrintPDFResult
+SavePDF(const scoped_refptr<base::RefCountedBytes>& data,
+        const base::FilePath& save_path) {
   printing::PdfMetafileSkia metafile;
   metafile.InitFromData(static_cast<const void*>(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::DictionaryValue*>(
           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<int>(result));
+  print_to_pdf_callback_map_.erase(request_id);
+}
+
 }  // namespace printing
index 38943b0..5594a41 100644 (file)
@@ -5,6 +5,9 @@
 #ifndef CHROME_BROWSER_PRINTING_PRINT_PREVIEW_MESSAGE_HANDLER_H_
 #define CHROME_BROWSER_PRINTING_PRINT_PREVIEW_MESSAGE_HANDLER_H_
 
+#include <map>
+
+#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<PrintPreviewMessageHandler> {
  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<int, atom::NativeWindow::PrintToPDFCallback> PrintToPDFCallbackMap;
+
   explicit PrintPreviewMessageHandler(content::WebContents* web_contents);
   friend class content::WebContentsUserData<PrintPreviewMessageHandler>;
 
@@ -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);
 };