Print enhancement: add webContents.printerList And a print option to select printer
This commit is contained in:
parent
093b844859
commit
023a3fd547
15 changed files with 290 additions and 27 deletions
|
@ -24,6 +24,21 @@
|
|||
#include "printing/printing_utils.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#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;
|
||||
|
||||
namespace printing {
|
||||
|
@ -36,6 +51,81 @@ void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner,
|
|||
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("scaleFactor", 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("showSystemDialog", false);
|
||||
job_settings->SetInteger(kSettingPreviewPageCount, 1);
|
||||
}
|
||||
|
||||
|
||||
class PrintingContextDelegate : public PrintingContext::Delegate {
|
||||
public:
|
||||
PrintingContextDelegate(int render_process_id, int render_view_id);
|
||||
|
@ -115,7 +205,8 @@ void PrintJobWorker::GetSettings(
|
|||
bool ask_user_for_settings,
|
||||
int document_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type) {
|
||||
MarginType margin_type,
|
||||
const base::string16& device_name) {
|
||||
DCHECK(task_runner_->RunsTasksOnCurrentThread());
|
||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
||||
|
||||
|
@ -137,6 +228,13 @@ void PrintJobWorker::GetSettings(
|
|||
base::Unretained(this),
|
||||
document_page_count,
|
||||
has_selection)));
|
||||
} 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 {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
|
@ -212,6 +310,14 @@ void PrintJobWorker::UseDefaultSettings() {
|
|||
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) {
|
||||
DCHECK(task_runner_->RunsTasksOnCurrentThread());
|
||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
||||
|
|
|
@ -46,7 +46,8 @@ class PrintJobWorker {
|
|||
bool ask_user_for_settings,
|
||||
int document_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type);
|
||||
MarginType margin_type,
|
||||
const base::string16& device_name);
|
||||
|
||||
// Set the new print settings.
|
||||
void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings);
|
||||
|
@ -127,6 +128,9 @@ class PrintJobWorker {
|
|||
// systems.
|
||||
void UseDefaultSettings();
|
||||
|
||||
// set the printer name
|
||||
void InitWithDeviceName(const base::string16& device_name);
|
||||
|
||||
// Printing context delegate.
|
||||
std::unique_ptr<PrintingContext::Delegate> printing_context_delegate_;
|
||||
|
||||
|
|
|
@ -64,9 +64,10 @@ PrintViewManagerBase::~PrintViewManagerBase() {
|
|||
}
|
||||
|
||||
#if !defined(DISABLE_BASIC_PRINTING)
|
||||
bool PrintViewManagerBase::PrintNow(bool silent, bool print_background) {
|
||||
bool PrintViewManagerBase::PrintNow(bool silent, bool print_background,
|
||||
const base::string16& device_name) {
|
||||
return PrintNowInternal(new PrintMsg_PrintPages(
|
||||
routing_id(), silent, print_background));
|
||||
routing_id(), silent, print_background, device_name));
|
||||
}
|
||||
#endif // !DISABLE_BASIC_PRINTING
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class PrintViewManagerBase : public content::NotificationObserver,
|
|||
// Prints the current document immediately. Since the rendering is
|
||||
// asynchronous, the actual printing will not be completed on the return of
|
||||
// this function. Returns false if printing is impossible at the moment.
|
||||
virtual bool PrintNow(bool silent, bool print_background);
|
||||
virtual bool PrintNow(bool silent, bool print_background, const base::string16&);
|
||||
#endif // !DISABLE_BASIC_PRINTING
|
||||
|
||||
// PrintedPagesSource implementation.
|
||||
|
|
|
@ -82,7 +82,31 @@ void PrinterQuery::GetSettings(
|
|||
is_print_dialog_box_shown_,
|
||||
expected_page_count,
|
||||
has_selection,
|
||||
margin_type));
|
||||
margin_type,
|
||||
base::string16()));
|
||||
}
|
||||
|
||||
void PrinterQuery::GetSettings(
|
||||
GetSettingsAskParam ask_user_for_settings,
|
||||
int expected_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
const base::string16& device_name,
|
||||
const base::Closure& callback) {
|
||||
DCHECK(RunsTasksOnCurrentThread());
|
||||
DCHECK(!is_print_dialog_box_shown_);
|
||||
StartWorker(callback);
|
||||
|
||||
// Real work is done in PrintJobWorker::GetSettings().
|
||||
is_print_dialog_box_shown_ = ask_user_for_settings == ASK_USER;
|
||||
worker_->PostTask(FROM_HERE,
|
||||
base::Bind(&PrintJobWorker::GetSettings,
|
||||
base::Unretained(worker_.get()),
|
||||
is_print_dialog_box_shown_,
|
||||
expected_page_count,
|
||||
has_selection,
|
||||
margin_type,
|
||||
device_name));
|
||||
}
|
||||
|
||||
void PrinterQuery::SetSettings(std::unique_ptr<base::DictionaryValue> new_settings,
|
||||
|
|
|
@ -50,7 +50,15 @@ class PrinterQuery : public PrintJobWorkerOwner {
|
|||
MarginType margin_type,
|
||||
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,
|
||||
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,
|
||||
const base::Closure& callback);
|
||||
|
||||
|
|
|
@ -123,6 +123,9 @@ bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message) {
|
|||
#endif
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
|
||||
OnGetDefaultPrintSettings)
|
||||
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_InitSettingWithDeviceName,
|
||||
OnInitSettingWithDeviceName)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings,
|
||||
OnUpdatePrintSettings)
|
||||
|
@ -278,6 +281,30 @@ void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
|
|||
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::DEFAULTS,
|
||||
0,
|
||||
false,
|
||||
DEFAULT_MARGINS,
|
||||
device_name,
|
||||
base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply,
|
||||
this,
|
||||
printer_query,
|
||||
reply_msg));
|
||||
}
|
||||
|
||||
void PrintingMessageFilter::OnGetDefaultPrintSettingsReply(
|
||||
scoped_refptr<PrinterQuery> printer_query,
|
||||
IPC::Message* reply_msg) {
|
||||
|
|
|
@ -85,6 +85,11 @@ class PrintingMessageFilter : public content::BrowserMessageFilter {
|
|||
|
||||
// Get the default print setting.
|
||||
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,
|
||||
IPC::Message* reply_msg);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue