commit
e0b9395a13
17 changed files with 323 additions and 27 deletions
|
@ -44,6 +44,7 @@
|
||||||
#include "base/process/process_handle.h"
|
#include "base/process/process_handle.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "base/threading/thread_task_runner_handle.h"
|
#include "base/threading/thread_task_runner_handle.h"
|
||||||
|
#include "base/values.h"
|
||||||
#include "brightray/browser/inspectable_web_contents.h"
|
#include "brightray/browser/inspectable_web_contents.h"
|
||||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||||
#include "chrome/browser/printing/print_preview_message_handler.h"
|
#include "chrome/browser/printing/print_preview_message_handler.h"
|
||||||
|
@ -74,6 +75,7 @@
|
||||||
#include "content/public/browser/storage_partition.h"
|
#include "content/public/browser/storage_partition.h"
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
#include "content/public/common/context_menu_params.h"
|
#include "content/public/common/context_menu_params.h"
|
||||||
|
#include "native_mate/converter.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
#include "net/url_request/url_request_context.h"
|
#include "net/url_request/url_request_context.h"
|
||||||
|
@ -93,6 +95,7 @@ namespace {
|
||||||
struct PrintSettings {
|
struct PrintSettings {
|
||||||
bool silent;
|
bool silent;
|
||||||
bool print_background;
|
bool print_background;
|
||||||
|
base::string16 device_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -130,10 +133,25 @@ struct Converter<PrintSettings> {
|
||||||
return false;
|
return false;
|
||||||
dict.Get("silent", &(out->silent));
|
dict.Get("silent", &(out->silent));
|
||||||
dict.Get("printBackground", &(out->print_background));
|
dict.Get("printBackground", &(out->print_background));
|
||||||
|
dict.Get("deviceName", &(out->device_name));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<printing::PrinterBasicInfo> {
|
||||||
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
const printing::PrinterBasicInfo& val) {
|
||||||
|
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||||
|
dict.Set("name", val.printer_name);
|
||||||
|
dict.Set("description", val.printer_description);
|
||||||
|
dict.Set("status", val.printer_status);
|
||||||
|
dict.Set("isDefault", val.is_default ? true : false);
|
||||||
|
dict.Set("options", val.options);
|
||||||
|
return dict.GetHandle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct Converter<WindowOpenDisposition> {
|
struct Converter<WindowOpenDisposition> {
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
@ -1291,7 +1309,7 @@ bool WebContents::IsAudioMuted() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::Print(mate::Arguments* args) {
|
void WebContents::Print(mate::Arguments* args) {
|
||||||
PrintSettings settings = { false, false };
|
PrintSettings settings = { false, false, base::string16() };
|
||||||
if (args->Length() == 1 && !args->GetNext(&settings)) {
|
if (args->Length() == 1 && !args->GetNext(&settings)) {
|
||||||
args->ThrowError();
|
args->ThrowError();
|
||||||
return;
|
return;
|
||||||
|
@ -1300,7 +1318,15 @@ void WebContents::Print(mate::Arguments* args) {
|
||||||
printing::PrintViewManagerBasic::FromWebContents(web_contents())->
|
printing::PrintViewManagerBasic::FromWebContents(web_contents())->
|
||||||
PrintNow(web_contents()->GetMainFrame(),
|
PrintNow(web_contents()->GetMainFrame(),
|
||||||
settings.silent,
|
settings.silent,
|
||||||
settings.print_background);
|
settings.print_background,
|
||||||
|
settings.device_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<printing::PrinterBasicInfo> WebContents::GetPrinterList() {
|
||||||
|
std::vector<printing::PrinterBasicInfo> printers;
|
||||||
|
auto print_backend = printing::PrintBackend::CreateInstance(nullptr);
|
||||||
|
print_backend->EnumeratePrinters(&printers);
|
||||||
|
return printers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::PrintToPDF(const base::DictionaryValue& setting,
|
void WebContents::PrintToPDF(const base::DictionaryValue& setting,
|
||||||
|
@ -1844,6 +1870,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||||
&WebContents::UnregisterServiceWorker)
|
&WebContents::UnregisterServiceWorker)
|
||||||
.SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
|
.SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
|
||||||
.SetMethod("print", &WebContents::Print)
|
.SetMethod("print", &WebContents::Print)
|
||||||
|
.SetMethod("getPrinters", &WebContents::GetPrinterList)
|
||||||
.SetMethod("_printToPDF", &WebContents::PrintToPDF)
|
.SetMethod("_printToPDF", &WebContents::PrintToPDF)
|
||||||
.SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
|
.SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
|
||||||
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
|
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "content/public/browser/web_contents_observer.h"
|
#include "content/public/browser/web_contents_observer.h"
|
||||||
#include "content/public/common/favicon_url.h"
|
#include "content/public/common/favicon_url.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
|
#include "printing/backend/print_backend.h"
|
||||||
#include "ui/gfx/image/image.h"
|
#include "ui/gfx/image/image.h"
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
@ -121,6 +122,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||||
void SetAudioMuted(bool muted);
|
void SetAudioMuted(bool muted);
|
||||||
bool IsAudioMuted();
|
bool IsAudioMuted();
|
||||||
void Print(mate::Arguments* args);
|
void Print(mate::Arguments* args);
|
||||||
|
std::vector<printing::PrinterBasicInfo> GetPrinterList();
|
||||||
void SetEmbedder(const WebContents* embedder);
|
void SetEmbedder(const WebContents* embedder);
|
||||||
|
|
||||||
// Print current page as PDF.
|
// Print current page as PDF.
|
||||||
|
|
|
@ -30,6 +30,20 @@
|
||||||
#include "printing/printing_utils.h"
|
#include "printing/printing_utils.h"
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "base/strings/string_number_conversions.h"
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "base/time/time.h"
|
||||||
|
#include "printing/page_size_margins.h"
|
||||||
|
#include "printing/print_job_constants.h"
|
||||||
|
#include "printing/print_settings.h"
|
||||||
|
#include "printing/units.h"
|
||||||
|
|
||||||
using content::BrowserThread;
|
using content::BrowserThread;
|
||||||
|
|
||||||
namespace printing {
|
namespace printing {
|
||||||
|
@ -42,6 +56,81 @@ void HoldRefCallback(const scoped_refptr<PrintJobWorkerOwner>& owner,
|
||||||
callback.Run();
|
callback.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetCustomMarginsToJobSettings(const PageSizeMargins& page_size_margins,
|
||||||
|
base::DictionaryValue* settings) {
|
||||||
|
std::unique_ptr<base::DictionaryValue> custom_margins(new base::DictionaryValue());
|
||||||
|
custom_margins->SetDouble(kSettingMarginTop, page_size_margins.margin_top);
|
||||||
|
custom_margins->SetDouble(kSettingMarginBottom, page_size_margins.margin_bottom);
|
||||||
|
custom_margins->SetDouble(kSettingMarginLeft, page_size_margins.margin_left);
|
||||||
|
custom_margins->SetDouble(kSettingMarginRight, page_size_margins.margin_right);
|
||||||
|
settings->Set(kSettingMarginsCustom, std::move(custom_margins));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintSettingsToJobSettings(const PrintSettings& settings,
|
||||||
|
base::DictionaryValue* job_settings) {
|
||||||
|
// header footer
|
||||||
|
job_settings->SetBoolean(kSettingHeaderFooterEnabled,
|
||||||
|
settings.display_header_footer());
|
||||||
|
job_settings->SetString(kSettingHeaderFooterTitle, settings.title());
|
||||||
|
job_settings->SetString(kSettingHeaderFooterURL, settings.url());
|
||||||
|
|
||||||
|
// bg
|
||||||
|
job_settings->SetBoolean(kSettingShouldPrintBackgrounds,
|
||||||
|
settings.should_print_backgrounds());
|
||||||
|
job_settings->SetBoolean(kSettingShouldPrintSelectionOnly,
|
||||||
|
settings.selection_only());
|
||||||
|
|
||||||
|
// margin
|
||||||
|
auto margin_type = settings.margin_type();
|
||||||
|
job_settings->SetInteger(kSettingMarginsType, settings.margin_type());
|
||||||
|
if (margin_type == CUSTOM_MARGINS) {
|
||||||
|
const auto& margins_in_points = settings.requested_custom_margins_in_points();
|
||||||
|
|
||||||
|
PageSizeMargins page_size_margins;
|
||||||
|
|
||||||
|
page_size_margins.margin_top = margins_in_points.top;
|
||||||
|
page_size_margins.margin_bottom = margins_in_points.bottom;
|
||||||
|
page_size_margins.margin_left = margins_in_points.left;
|
||||||
|
page_size_margins.margin_right = margins_in_points.right;
|
||||||
|
SetCustomMarginsToJobSettings(page_size_margins, job_settings);
|
||||||
|
}
|
||||||
|
job_settings->SetInteger(kSettingPreviewPageCount, 1);
|
||||||
|
|
||||||
|
// range
|
||||||
|
|
||||||
|
if (!settings.ranges().empty()) {
|
||||||
|
base::ListValue* page_range_array = new base::ListValue;
|
||||||
|
job_settings->Set(kSettingPageRange, page_range_array);
|
||||||
|
for (size_t i = 0; i < settings.ranges().size(); ++i) {
|
||||||
|
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
|
||||||
|
dict->SetInteger(kSettingPageRangeFrom, settings.ranges()[i].from + 1);
|
||||||
|
dict->SetInteger(kSettingPageRangeTo, settings.ranges()[i].to + 1);
|
||||||
|
page_range_array->Append(std::move(dict));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
job_settings->SetBoolean(kSettingCollate, settings.collate());
|
||||||
|
job_settings->SetInteger(kSettingCopies, 1);
|
||||||
|
job_settings->SetInteger(kSettingColor, settings.color());
|
||||||
|
job_settings->SetInteger(kSettingDuplexMode, settings.duplex_mode());
|
||||||
|
job_settings->SetBoolean(kSettingLandscape, settings.landscape());
|
||||||
|
job_settings->SetString(kSettingDeviceName, settings.device_name());
|
||||||
|
job_settings->SetInteger(kSettingScaleFactor, 100);
|
||||||
|
job_settings->SetBoolean("rasterizePDF", false);
|
||||||
|
|
||||||
|
job_settings->SetInteger("desiredDpi", settings.desired_dpi());
|
||||||
|
job_settings->SetInteger("dpi", settings.dpi());
|
||||||
|
|
||||||
|
job_settings->SetBoolean(kSettingPrintToPDF, false);
|
||||||
|
job_settings->SetBoolean(kSettingCloudPrintDialog, false);
|
||||||
|
job_settings->SetBoolean(kSettingPrintWithPrivet, false);
|
||||||
|
job_settings->SetBoolean(kSettingPrintWithExtension, false);
|
||||||
|
|
||||||
|
job_settings->SetBoolean(kSettingShowSystemDialog, false);
|
||||||
|
job_settings->SetInteger(kSettingPreviewPageCount, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class PrintingContextDelegate : public PrintingContext::Delegate {
|
class PrintingContextDelegate : public PrintingContext::Delegate {
|
||||||
public:
|
public:
|
||||||
PrintingContextDelegate(int render_process_id, int render_frame_id);
|
PrintingContextDelegate(int render_process_id, int render_frame_id);
|
||||||
|
@ -133,7 +222,8 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
|
||||||
bool has_selection,
|
bool has_selection,
|
||||||
MarginType margin_type,
|
MarginType margin_type,
|
||||||
bool is_scripted,
|
bool is_scripted,
|
||||||
bool is_modifiable) {
|
bool is_modifiable,
|
||||||
|
const base::string16& device_name) {
|
||||||
DCHECK(task_runner_->RunsTasksOnCurrentThread());
|
DCHECK(task_runner_->RunsTasksOnCurrentThread());
|
||||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
DCHECK_EQ(page_number_, PageNumber::npos());
|
||||||
|
|
||||||
|
@ -157,6 +247,13 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
|
||||||
document_page_count,
|
document_page_count,
|
||||||
has_selection,
|
has_selection,
|
||||||
is_scripted)));
|
is_scripted)));
|
||||||
|
} else if (!device_name.empty()) {
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
|
||||||
|
base::Bind(&PrintJobWorker::InitWithDeviceName,
|
||||||
|
base::Unretained(this),
|
||||||
|
device_name)));
|
||||||
} else {
|
} else {
|
||||||
BrowserThread::PostTask(
|
BrowserThread::PostTask(
|
||||||
BrowserThread::UI, FROM_HERE,
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
@ -225,6 +322,14 @@ void PrintJobWorker::UseDefaultSettings() {
|
||||||
GetSettingsDone(result);
|
GetSettingsDone(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintJobWorker::InitWithDeviceName(const base::string16& device_name) {
|
||||||
|
const auto& settings = printing_context_->settings();
|
||||||
|
std::unique_ptr<base::DictionaryValue> dic(new base::DictionaryValue);
|
||||||
|
PrintSettingsToJobSettings(settings, dic.get());
|
||||||
|
dic->SetString(kSettingDeviceName, device_name);
|
||||||
|
UpdatePrintSettings(std::move(dic));
|
||||||
|
}
|
||||||
|
|
||||||
void PrintJobWorker::StartPrinting(PrintedDocument* new_document) {
|
void PrintJobWorker::StartPrinting(PrintedDocument* new_document) {
|
||||||
DCHECK(task_runner_->RunsTasksOnCurrentThread());
|
DCHECK(task_runner_->RunsTasksOnCurrentThread());
|
||||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
DCHECK_EQ(page_number_, PageNumber::npos());
|
||||||
|
|
|
@ -51,7 +51,8 @@ class PrintJobWorker {
|
||||||
bool has_selection,
|
bool has_selection,
|
||||||
MarginType margin_type,
|
MarginType margin_type,
|
||||||
bool is_scripted,
|
bool is_scripted,
|
||||||
bool is_modifiable);
|
bool is_modifiable,
|
||||||
|
const base::string16& device_name);
|
||||||
|
|
||||||
// Set the new print settings.
|
// Set the new print settings.
|
||||||
void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings);
|
void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings);
|
||||||
|
@ -128,6 +129,9 @@ class PrintJobWorker {
|
||||||
// systems.
|
// systems.
|
||||||
void UseDefaultSettings();
|
void UseDefaultSettings();
|
||||||
|
|
||||||
|
// set the printer name
|
||||||
|
void InitWithDeviceName(const base::string16& device_name);
|
||||||
|
|
||||||
// Printing context delegate.
|
// Printing context delegate.
|
||||||
std::unique_ptr<PrintingContext::Delegate> printing_context_delegate_;
|
std::unique_ptr<PrintingContext::Delegate> printing_context_delegate_;
|
||||||
|
|
||||||
|
|
|
@ -67,11 +67,12 @@ PrintViewManagerBase::~PrintViewManagerBase() {
|
||||||
|
|
||||||
#if !defined(DISABLE_BASIC_PRINTING)
|
#if !defined(DISABLE_BASIC_PRINTING)
|
||||||
bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
|
bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
|
||||||
bool silent, bool print_background) {
|
bool silent, bool print_background,
|
||||||
|
const base::string16& device_name) {
|
||||||
int32_t id = rfh->GetRoutingID();
|
int32_t id = rfh->GetRoutingID();
|
||||||
return PrintNowInternal(
|
return PrintNowInternal(
|
||||||
rfh,
|
rfh,
|
||||||
base::MakeUnique<PrintMsg_PrintPages>(id, silent, print_background));
|
base::MakeUnique<PrintMsg_PrintPages>(id, silent, print_background, device_name));
|
||||||
}
|
}
|
||||||
#endif // !DISABLE_BASIC_PRINTING
|
#endif // !DISABLE_BASIC_PRINTING
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,8 @@ class PrintViewManagerBase : public content::NotificationObserver,
|
||||||
// asynchronous, the actual printing will not be completed on the return of
|
// asynchronous, the actual printing will not be completed on the return of
|
||||||
// this function. Returns false if printing is impossible at the moment.
|
// this function. Returns false if printing is impossible at the moment.
|
||||||
virtual bool PrintNow(content::RenderFrameHost* rfh,
|
virtual bool PrintNow(content::RenderFrameHost* rfh,
|
||||||
bool silent, bool print_background);
|
bool silent, bool print_background,
|
||||||
|
const base::string16& device_name);
|
||||||
#endif // !DISABLE_BASIC_PRINTING
|
#endif // !DISABLE_BASIC_PRINTING
|
||||||
|
|
||||||
// PrintedPagesSource implementation.
|
// PrintedPagesSource implementation.
|
||||||
|
|
|
@ -86,7 +86,27 @@ void PrinterQuery::GetSettings(GetSettingsAskParam ask_user_for_settings,
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
base::Bind(&PrintJobWorker::GetSettings, base::Unretained(worker_.get()),
|
base::Bind(&PrintJobWorker::GetSettings, base::Unretained(worker_.get()),
|
||||||
is_print_dialog_box_shown_, expected_page_count, has_selection,
|
is_print_dialog_box_shown_, expected_page_count, has_selection,
|
||||||
margin_type, is_scripted, is_modifiable));
|
margin_type, is_scripted, is_modifiable, base::string16()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrinterQuery::GetSettings(
|
||||||
|
GetSettingsAskParam ask_user_for_settings,
|
||||||
|
int expected_page_count,
|
||||||
|
bool has_selection,
|
||||||
|
MarginType margin_type,
|
||||||
|
bool is_scripted,
|
||||||
|
bool is_modifiable,
|
||||||
|
const base::string16& device_name,
|
||||||
|
const base::Closure& callback) {
|
||||||
|
DCHECK(RunsTasksOnCurrentThread());
|
||||||
|
DCHECK(!is_print_dialog_box_shown_);
|
||||||
|
StartWorker(callback);
|
||||||
|
|
||||||
|
is_print_dialog_box_shown_ = false;
|
||||||
|
worker_->PostTask(FROM_HERE,
|
||||||
|
base::Bind(&PrintJobWorker::GetSettings, base::Unretained(worker_.get()),
|
||||||
|
is_print_dialog_box_shown_, expected_page_count, has_selection,
|
||||||
|
margin_type, is_scripted, is_modifiable, device_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrinterQuery::SetSettings(
|
void PrinterQuery::SetSettings(
|
||||||
|
|
|
@ -53,7 +53,17 @@ class PrinterQuery : public PrintJobWorkerOwner {
|
||||||
bool is_modifiable,
|
bool is_modifiable,
|
||||||
const base::Closure& callback);
|
const base::Closure& callback);
|
||||||
|
|
||||||
// Updates the current settings with |new_settings| dictionary values.
|
void GetSettings(
|
||||||
|
GetSettingsAskParam ask_user_for_settings,
|
||||||
|
int expected_page_count,
|
||||||
|
bool has_selection,
|
||||||
|
MarginType margin_type,
|
||||||
|
bool is_scripted,
|
||||||
|
bool is_modifiable,
|
||||||
|
const base::string16& device_name,
|
||||||
|
const base::Closure& callback);
|
||||||
|
|
||||||
|
// Updates the current settings with |new_settings| dictionary values.
|
||||||
void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings,
|
void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings,
|
||||||
const base::Closure& callback);
|
const base::Closure& callback);
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,8 @@ bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message) {
|
||||||
#endif
|
#endif
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
|
||||||
OnGetDefaultPrintSettings)
|
OnGetDefaultPrintSettings)
|
||||||
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_InitSettingWithDeviceName,
|
||||||
|
OnInitSettingWithDeviceName)
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings,
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings,
|
||||||
OnUpdatePrintSettings)
|
OnUpdatePrintSettings)
|
||||||
|
@ -174,6 +176,32 @@ void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
|
||||||
printer_query, reply_msg));
|
printer_query, reply_msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OnInitSettingWithDeviceName(const base::string16& device_name,
|
||||||
|
IPC::Message* reply_msg) {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||||
|
scoped_refptr<PrinterQuery> printer_query;
|
||||||
|
printer_query = queue_->PopPrinterQuery(0);
|
||||||
|
if (!printer_query.get()) {
|
||||||
|
printer_query =
|
||||||
|
queue_->CreatePrinterQuery(render_process_id_, reply_msg->routing_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loads default settings. This is asynchronous, only the IPC message sender
|
||||||
|
// will hang until the settings are retrieved.
|
||||||
|
printer_query->GetSettings(
|
||||||
|
PrinterQuery::GetSettingsAskParam::DEFAULTS,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
DEFAULT_MARGINS,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
device_name,
|
||||||
|
base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply,
|
||||||
|
this,
|
||||||
|
printer_query,
|
||||||
|
reply_msg));
|
||||||
|
}
|
||||||
|
|
||||||
void PrintingMessageFilter::OnGetDefaultPrintSettingsReply(
|
void PrintingMessageFilter::OnGetDefaultPrintSettingsReply(
|
||||||
scoped_refptr<PrinterQuery> printer_query,
|
scoped_refptr<PrinterQuery> printer_query,
|
||||||
IPC::Message* reply_msg) {
|
IPC::Message* reply_msg) {
|
||||||
|
|
|
@ -61,6 +61,11 @@ class PrintingMessageFilter : public content::BrowserMessageFilter {
|
||||||
|
|
||||||
// Get the default print setting.
|
// Get the default print setting.
|
||||||
void OnGetDefaultPrintSettings(IPC::Message* reply_msg);
|
void OnGetDefaultPrintSettings(IPC::Message* reply_msg);
|
||||||
|
|
||||||
|
// Set deviceName
|
||||||
|
void OnInitSettingWithDeviceName(const base::string16& device_name,
|
||||||
|
IPC::Message* reply_msg);
|
||||||
|
|
||||||
void OnGetDefaultPrintSettingsReply(scoped_refptr<PrinterQuery> printer_query,
|
void OnGetDefaultPrintSettingsReply(scoped_refptr<PrinterQuery> printer_query,
|
||||||
IPC::Message* reply_msg);
|
IPC::Message* reply_msg);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,9 @@ PrintMsg_Print_Params::PrintMsg_Print_Params()
|
||||||
display_header_footer(false),
|
display_header_footer(false),
|
||||||
title(),
|
title(),
|
||||||
url(),
|
url(),
|
||||||
should_print_backgrounds(false) {}
|
should_print_backgrounds(false),
|
||||||
|
device_name() {
|
||||||
|
}
|
||||||
|
|
||||||
PrintMsg_Print_Params::~PrintMsg_Print_Params() {}
|
PrintMsg_Print_Params::~PrintMsg_Print_Params() {}
|
||||||
|
|
||||||
|
@ -52,6 +54,7 @@ void PrintMsg_Print_Params::Reset() {
|
||||||
title = base::string16();
|
title = base::string16();
|
||||||
url = base::string16();
|
url = base::string16();
|
||||||
should_print_backgrounds = false;
|
should_print_backgrounds = false;
|
||||||
|
device_name.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintMsg_PrintPages_Params::PrintMsg_PrintPages_Params()
|
PrintMsg_PrintPages_Params::PrintMsg_PrintPages_Params()
|
||||||
|
|
|
@ -55,6 +55,7 @@ struct PrintMsg_Print_Params {
|
||||||
base::string16 title;
|
base::string16 title;
|
||||||
base::string16 url;
|
base::string16 url;
|
||||||
bool should_print_backgrounds;
|
bool should_print_backgrounds;
|
||||||
|
base::string16 device_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PrintMsg_PrintPages_Params {
|
struct PrintMsg_PrintPages_Params {
|
||||||
|
@ -233,9 +234,10 @@ IPC_STRUCT_END()
|
||||||
|
|
||||||
// Tells the render view to switch the CSS to print media type, renders every
|
// Tells the render view to switch the CSS to print media type, renders every
|
||||||
// requested pages and switch back the CSS to display media type.
|
// requested pages and switch back the CSS to display media type.
|
||||||
IPC_MESSAGE_ROUTED2(PrintMsg_PrintPages,
|
IPC_MESSAGE_ROUTED3(PrintMsg_PrintPages,
|
||||||
bool /* silent print */,
|
bool /* silent print */,
|
||||||
bool /* print page's background */)
|
bool /* print page's background */,
|
||||||
|
base::string16 /* device name*/)
|
||||||
|
|
||||||
// Tells the render view that printing is done so it can clean up.
|
// Tells the render view that printing is done so it can clean up.
|
||||||
IPC_MESSAGE_ROUTED1(PrintMsg_PrintingDone,
|
IPC_MESSAGE_ROUTED1(PrintMsg_PrintingDone,
|
||||||
|
@ -280,6 +282,11 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPrintPage,
|
||||||
IPC_SYNC_MESSAGE_ROUTED0_1(PrintHostMsg_GetDefaultPrintSettings,
|
IPC_SYNC_MESSAGE_ROUTED0_1(PrintHostMsg_GetDefaultPrintSettings,
|
||||||
PrintMsg_Print_Params /* default_settings */)
|
PrintMsg_Print_Params /* default_settings */)
|
||||||
|
|
||||||
|
// you can set the printer
|
||||||
|
IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_InitSettingWithDeviceName,
|
||||||
|
base::string16, /* device name */
|
||||||
|
PrintMsg_Print_Params /* default_settings */)
|
||||||
|
|
||||||
// The renderer wants to update the current print settings with new
|
// The renderer wants to update the current print settings with new
|
||||||
// |job_settings|.
|
// |job_settings|.
|
||||||
IPC_SYNC_MESSAGE_ROUTED2_2(PrintHostMsg_UpdatePrintSettings,
|
IPC_SYNC_MESSAGE_ROUTED2_2(PrintHostMsg_UpdatePrintSettings,
|
||||||
|
|
|
@ -659,12 +659,13 @@ void PrintWebViewHelper::OnDestruct() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(DISABLE_BASIC_PRINTING)
|
#if !defined(DISABLE_BASIC_PRINTING)
|
||||||
void PrintWebViewHelper::OnPrintPages(bool silent, bool print_background) {
|
void PrintWebViewHelper::OnPrintPages(bool silent, bool print_background,
|
||||||
|
const base::string16& device_name) {
|
||||||
if (ipc_nesting_level_> 1)
|
if (ipc_nesting_level_> 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
|
blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
|
||||||
Print(frame, blink::WebNode(), silent, print_background);
|
Print(frame, blink::WebNode(), silent, print_background, device_name);
|
||||||
}
|
}
|
||||||
#endif // !DISABLE_BASIC_PRINTING
|
#endif // !DISABLE_BASIC_PRINTING
|
||||||
|
|
||||||
|
@ -847,7 +848,8 @@ void PrintWebViewHelper::PrintNode(const blink::WebNode& node) {
|
||||||
void PrintWebViewHelper::Print(blink::WebLocalFrame* frame,
|
void PrintWebViewHelper::Print(blink::WebLocalFrame* frame,
|
||||||
const blink::WebNode& node,
|
const blink::WebNode& node,
|
||||||
bool silent,
|
bool silent,
|
||||||
bool print_background) {
|
bool print_background,
|
||||||
|
const base::string16& device_name) {
|
||||||
// If still not finished with earlier print request simply ignore.
|
// If still not finished with earlier print request simply ignore.
|
||||||
if (prep_frame_view_)
|
if (prep_frame_view_)
|
||||||
return;
|
return;
|
||||||
|
@ -855,7 +857,7 @@ void PrintWebViewHelper::Print(blink::WebLocalFrame* frame,
|
||||||
FrameReference frame_ref(frame);
|
FrameReference frame_ref(frame);
|
||||||
|
|
||||||
int expected_page_count = 0;
|
int expected_page_count = 0;
|
||||||
if (!CalculateNumberOfPages(frame, node, &expected_page_count)) {
|
if (!CalculateNumberOfPages(frame, node, &expected_page_count, device_name)) {
|
||||||
DidFinishPrinting(FAIL_PRINT_INIT);
|
DidFinishPrinting(FAIL_PRINT_INIT);
|
||||||
return; // Failed to init print page settings.
|
return; // Failed to init print page settings.
|
||||||
}
|
}
|
||||||
|
@ -991,10 +993,16 @@ void PrintWebViewHelper::ComputePageLayoutInPointsForCss(
|
||||||
CalculatePageLayoutFromPrintParams(params, page_layout_in_points);
|
CalculatePageLayoutFromPrintParams(params, page_layout_in_points);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PrintWebViewHelper::InitPrintSettings(bool fit_to_paper_size) {
|
bool PrintWebViewHelper::InitPrintSettings(bool fit_to_paper_size,
|
||||||
|
const base::string16& device_name) {
|
||||||
PrintMsg_PrintPages_Params settings;
|
PrintMsg_PrintPages_Params settings;
|
||||||
Send(new PrintHostMsg_GetDefaultPrintSettings(routing_id(),
|
if (device_name.empty()) {
|
||||||
&settings.params));
|
Send(new PrintHostMsg_GetDefaultPrintSettings(routing_id(),
|
||||||
|
&settings.params));
|
||||||
|
} else {
|
||||||
|
Send(new PrintHostMsg_InitSettingWithDeviceName(routing_id(), device_name,
|
||||||
|
&settings.params));
|
||||||
|
}
|
||||||
// Check if the printer returned any settings, if the settings is empty, we
|
// Check if the printer returned any settings, if the settings is empty, we
|
||||||
// can safely assume there are no printer drivers configured. So we safely
|
// can safely assume there are no printer drivers configured. So we safely
|
||||||
// terminate.
|
// terminate.
|
||||||
|
@ -1019,10 +1027,11 @@ bool PrintWebViewHelper::InitPrintSettings(bool fit_to_paper_size) {
|
||||||
|
|
||||||
bool PrintWebViewHelper::CalculateNumberOfPages(blink::WebLocalFrame* frame,
|
bool PrintWebViewHelper::CalculateNumberOfPages(blink::WebLocalFrame* frame,
|
||||||
const blink::WebNode& node,
|
const blink::WebNode& node,
|
||||||
int* number_of_pages) {
|
int* number_of_pages,
|
||||||
|
const base::string16& device_name) {
|
||||||
DCHECK(frame);
|
DCHECK(frame);
|
||||||
bool fit_to_paper_size = !(PrintingNodeOrPdfFrame(frame, node));
|
bool fit_to_paper_size = !(PrintingNodeOrPdfFrame(frame, node));
|
||||||
if (!InitPrintSettings(fit_to_paper_size)) {
|
if (!InitPrintSettings(fit_to_paper_size, device_name)) {
|
||||||
notify_browser_of_print_failure_ = false;
|
notify_browser_of_print_failure_ = false;
|
||||||
Send(new PrintHostMsg_ShowInvalidPrinterSettingsError(routing_id()));
|
Send(new PrintHostMsg_ShowInvalidPrinterSettingsError(routing_id()));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -99,7 +99,9 @@ class PrintWebViewHelper
|
||||||
|
|
||||||
// Message handlers ---------------------------------------------------------
|
// Message handlers ---------------------------------------------------------
|
||||||
#if !defined(DISABLE_BASIC_PRINTING)
|
#if !defined(DISABLE_BASIC_PRINTING)
|
||||||
void OnPrintPages(bool silent, bool print_background);
|
void OnPrintPages(bool silent,
|
||||||
|
bool print_background,
|
||||||
|
const base::string16& device_name);
|
||||||
void OnPrintingDone(bool success);
|
void OnPrintingDone(bool success);
|
||||||
#endif // !DISABLE_BASIC_PRINTING
|
#endif // !DISABLE_BASIC_PRINTING
|
||||||
void OnPrintPreview(const base::DictionaryValue& settings);
|
void OnPrintPreview(const base::DictionaryValue& settings);
|
||||||
|
@ -138,7 +140,8 @@ class PrintWebViewHelper
|
||||||
void Print(blink::WebLocalFrame* frame,
|
void Print(blink::WebLocalFrame* frame,
|
||||||
const blink::WebNode& node,
|
const blink::WebNode& node,
|
||||||
bool silent = false,
|
bool silent = false,
|
||||||
bool print_background = false);
|
bool print_background = false,
|
||||||
|
const base::string16& device_name = base::string16());
|
||||||
|
|
||||||
// Notification when printing is done - signal tear-down/free resources.
|
// Notification when printing is done - signal tear-down/free resources.
|
||||||
void DidFinishPrinting(PrintingResult result);
|
void DidFinishPrinting(PrintingResult result);
|
||||||
|
@ -147,12 +150,14 @@ class PrintWebViewHelper
|
||||||
|
|
||||||
// Initialize print page settings with default settings.
|
// Initialize print page settings with default settings.
|
||||||
// Used only for native printing workflow.
|
// Used only for native printing workflow.
|
||||||
bool InitPrintSettings(bool fit_to_paper_size);
|
bool InitPrintSettings(bool fit_to_paper_size,
|
||||||
|
const base::string16& device_name = base::string16());
|
||||||
|
|
||||||
// Calculate number of pages in source document.
|
// Calculate number of pages in source document.
|
||||||
bool CalculateNumberOfPages(blink::WebLocalFrame* frame,
|
bool CalculateNumberOfPages(blink::WebLocalFrame* frame,
|
||||||
const blink::WebNode& node,
|
const blink::WebNode& node,
|
||||||
int* number_of_pages);
|
int* number_of_pages,
|
||||||
|
const base::string16& device_name = base::string16());
|
||||||
|
|
||||||
// Update the current print settings with new |passed_job_settings|.
|
// Update the current print settings with new |passed_job_settings|.
|
||||||
// |passed_job_settings| dictionary contains print job details such as printer
|
// |passed_job_settings| dictionary contains print job details such as printer
|
||||||
|
|
44
docs/api/structures/printer-info.md
Normal file
44
docs/api/structures/printer-info.md
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# PrinterInfo Object
|
||||||
|
|
||||||
|
* `name` String
|
||||||
|
* `description` String
|
||||||
|
* `status` Number
|
||||||
|
* `isDefault` Boolean
|
||||||
|
* `options` Object - Additional fields
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Below is an example of some of the additional options that may be set which
|
||||||
|
may be different on each platform.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
name: 'Zebra_LP2844',
|
||||||
|
description: 'Zebra LP2844',
|
||||||
|
status: 3,
|
||||||
|
isDefault: false,
|
||||||
|
options: {
|
||||||
|
copies: '1',
|
||||||
|
'device-uri': 'usb://Zebra/LP2844?location=14200000',
|
||||||
|
finishings: '3',
|
||||||
|
'job-cancel-after': '10800',
|
||||||
|
'job-hold-until': 'no-hold',
|
||||||
|
'job-priority': '50',
|
||||||
|
'job-sheets': 'none,none',
|
||||||
|
'marker-change-time': '0',
|
||||||
|
'number-up': '1',
|
||||||
|
'printer-commands': 'none',
|
||||||
|
'printer-info': 'Zebra LP2844',
|
||||||
|
'printer-is-accepting-jobs': 'true',
|
||||||
|
'printer-is-shared': 'true',
|
||||||
|
'printer-location': '',
|
||||||
|
'printer-make-and-model': 'Zebra EPL2 Label Printer',
|
||||||
|
'printer-state': '3',
|
||||||
|
'printer-state-change-time': '1484872644',
|
||||||
|
'printer-state-reasons': 'offline-report',
|
||||||
|
'printer-type': '36932',
|
||||||
|
'printer-uri-supported': 'ipp://localhost/printers/Zebra_LP2844',
|
||||||
|
system_driverinfo: 'Z'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
|
@ -916,18 +916,26 @@ Unregisters any ServiceWorker if present and returns a boolean as
|
||||||
response to `callback` when the JS promise is fulfilled or false
|
response to `callback` when the JS promise is fulfilled or false
|
||||||
when the JS promise is rejected.
|
when the JS promise is rejected.
|
||||||
|
|
||||||
|
#### `contents.getPrinters()`
|
||||||
|
|
||||||
|
Get the system printer list.
|
||||||
|
|
||||||
|
Returns [PrinterInfo[]](structures/printer-info.md)
|
||||||
|
|
||||||
#### `contents.print([options])`
|
#### `contents.print([options])`
|
||||||
|
|
||||||
* `options` Object (optional)
|
* `options` Object (optional)
|
||||||
* `silent` Boolean - Don't ask user for print settings. Default is `false`.
|
* `silent` Boolean - Don't ask user for print settings. Default is `false`.
|
||||||
* `printBackground` Boolean - Also prints the background color and image of
|
* `printBackground` Boolean - Also prints the background color and image of
|
||||||
the web page. Default is `false`.
|
the web page. Default is `false`.
|
||||||
|
* `deviceName` String - Set the printer device name to use. Default is `''`.
|
||||||
|
|
||||||
Prints window's web page. When `silent` is set to `true`, Electron will pick
|
Prints window's web page. When `silent` is set to `true`, Electron will pick
|
||||||
up system's default printer and default settings for printing.
|
the system's default printer if `deviceName` is empty and the default settings
|
||||||
|
for printing.
|
||||||
|
|
||||||
Calling `window.print()` in web page is equivalent to calling
|
Calling `window.print()` in web page is equivalent to calling
|
||||||
`webContents.print({silent: false, printBackground: false})`.
|
`webContents.print({silent: false, printBackground: false, deviceName: ''})`.
|
||||||
|
|
||||||
Use `page-break-before: always; ` CSS style to force to print to a new page.
|
Use `page-break-before: always; ` CSS style to force to print to a new page.
|
||||||
|
|
||||||
|
|
|
@ -1114,6 +1114,23 @@ describe('BrowserWindow module', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('can get printer list', function (done) {
|
||||||
|
w.destroy()
|
||||||
|
w = new BrowserWindow({
|
||||||
|
show: false,
|
||||||
|
webPreferences: {
|
||||||
|
sandbox: true,
|
||||||
|
preload: preload
|
||||||
|
}
|
||||||
|
})
|
||||||
|
w.loadURL('data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E')
|
||||||
|
w.webContents.once('did-finish-load', function () {
|
||||||
|
const printers = w.webContents.getPrinters()
|
||||||
|
assert.equal(Array.isArray(printers), true)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('can print to PDF', function (done) {
|
it('can print to PDF', function (done) {
|
||||||
w.destroy()
|
w.destroy()
|
||||||
w = new BrowserWindow({
|
w = new BrowserWindow({
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue