Return node::Buffer as a printToPDF callback result.

This commit is contained in:
Haojian Wu 2015-06-10 15:16:00 +08:00
parent ab40da3f31
commit ac62871645
4 changed files with 25 additions and 71 deletions

View file

@ -52,7 +52,7 @@ class WebContents : public mate::EventEmitter,
public content::WebContentsObserver,
public content::GpuDataManagerObserver {
public:
typedef base::Callback<void(int)> PrintToPDFCallback;
typedef base::Callback<void(v8::Local<v8::Value>)> PrintToPDFCallback;
// Create from an existing WebContents.
static mate::Handle<WebContents> CreateFrom(

View file

@ -89,7 +89,6 @@ wrapWebContents = (webContents) ->
collate:true,
shouldPrintBackgrounds:false,
shouldPrintSelectionOnly:false
silent:false
if options.landscape
printingSetting.landscape = options.landscape

View file

@ -25,6 +25,8 @@
#include "printing/print_job_constants.h"
#include "printing/pdf_metafile_skia.h"
#include "atom/common/node_includes.h"
using content::BrowserThread;
using content::WebContents;
@ -60,18 +62,6 @@ base::RefCountedBytes* GetDataFromHandle(base::SharedMemoryHandle handle,
return base::RefCountedBytes::TakeVector(&data);
}
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);
return metafile.SaveTo(&file)?
printing::PrintPreviewMessageHandler::SUCCESS :
printing::PrintPreviewMessageHandler::FAIL_SAVEFILE;
}
} // namespace
namespace printing {
@ -111,43 +101,15 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
return;
}
// TODO(joth): This seems like a good match for using RefCountedStaticMemory
// to avoid the memory copy, but the SetPrintPreviewData call chain below
// needs updating to accept the RefCountedMemory* base class.
scoped_refptr<base::RefCountedBytes> data(
base::RefCountedBytes *data = (
GetDataFromHandle(params.metafile_data_handle, params.data_size));
if (!data || !data->size())
return;
int request_id = params.preview_request_id;
std::string file_path =
print_to_pdf_request_details_map_[request_id].save_path;
base::FilePath save_path =
file_path.empty() ? base::FilePath(FILE_PATH_LITERAL("print.pdf")):
base::FilePath::FromUTF8Unsafe(file_path);
if (!print_to_pdf_request_details_map_[request_id].silent) {
atom::NativeWindow* window = atom::NativeWindow::FromWebContents(
web_contents());
if (!file_dialog::ShowSaveDialog(window, "Save As",
base::FilePath(FILE_PATH_LITERAL("print.pdf")),
file_dialog::Filters(), &save_path)) { // Users cancel dialog.
RunPrintToPDFCallback(request_id, FAIL_CANCEL);
return;
}
}
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::FILE,
FROM_HERE,
base::Bind(&SavePDF, data, save_path),
base::Bind(&PrintPreviewMessageHandler::RunPrintToPDFCallback,
base::Unretained(this),
request_id));
RunPrintToPDFCallback(params.preview_request_id, data);
}
void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie,
int request_id) {
StopWorker(document_cookie);
RunPrintToPDFCallback(request_id, FAIL_PREVIEW);
RunPrintToPDFCallback(request_id, nullptr);
}
bool PrintPreviewMessageHandler::OnMessageReceived(
@ -172,21 +134,26 @@ void PrintPreviewMessageHandler::PrintToPDF(
const atom::api::WebContents::PrintToPDFCallback& callback) {
int request_id;
options.GetInteger(printing::kPreviewRequestID, &request_id);
PrintToPDFRequestDetails details;
options.GetBoolean("silent", &details.silent);
options.GetString("savePath", &details.save_path);
details.callback = callback;
print_to_pdf_request_details_map_[request_id] = details;
print_to_pdf_callback_map_[request_id] = callback;
content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
rvh->Send(new PrintMsg_PrintPreview(rvh->GetRoutingID(), options));
}
void PrintPreviewMessageHandler::RunPrintToPDFCallback(
int request_id, PrintPDFResult result) {
print_to_pdf_request_details_map_[request_id].callback.Run(
static_cast<int>(result));
print_to_pdf_request_details_map_.erase(request_id);
int request_id, base::RefCountedBytes* data) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
if (data) {
v8::Local<v8::Value> buffer = node::Buffer::Use(
const_cast<char*>(reinterpret_cast<const char*>(data->front())),
data->size());
print_to_pdf_callback_map_[request_id].Run(buffer);
} else {
print_to_pdf_callback_map_[request_id].Run(v8::Null(isolate));
}
print_to_pdf_callback_map_.erase(request_id);
}
} // namespace printing

View file

@ -37,13 +37,6 @@ class PrintPreviewMessageHandler
: public content::WebContentsObserver,
public content::WebContentsUserData<PrintPreviewMessageHandler> {
public:
enum PrintPDFResult {
SUCCESS,
FAIL_PREVIEW,
FAIL_SAVEFILE,
FAIL_CANCEL,
};
~PrintPreviewMessageHandler() override;
// content::WebContentsObserver implementation.
@ -53,14 +46,8 @@ class PrintPreviewMessageHandler
const atom::api::WebContents::PrintToPDFCallback& callback);
private:
struct PrintToPDFRequestDetails {
std::string save_path;
bool silent;
atom::api::WebContents::PrintToPDFCallback callback;
};
typedef std::map<int, PrintToPDFRequestDetails>
PrintToPDFRequestDetailsMap;
typedef std::map<int, atom::api::WebContents::PrintToPDFCallback>
PrintToPDFCallbackMap;
explicit PrintPreviewMessageHandler(content::WebContents* web_contents);
friend class content::WebContentsUserData<PrintPreviewMessageHandler>;
@ -73,9 +60,10 @@ class PrintPreviewMessageHandler
const PrintHostMsg_DidPreviewDocument_Params& params);
void OnPrintPreviewFailed(int document_cookie, int request_id);
void RunPrintToPDFCallback(int request_id, PrintPDFResult result);
void RunPrintToPDFCallback(
int request_id, base::RefCountedBytes* data);
PrintToPDFRequestDetailsMap print_to_pdf_request_details_map_;
PrintToPDFCallbackMap print_to_pdf_callback_map_;
DISALLOW_COPY_AND_ASSIGN(PrintPreviewMessageHandler);
};