Allow customization of print options via CefHandler::HandlePrintOptions() (issue #112).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@98 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2010-08-31 15:19:33 +00:00
parent 79134a77f2
commit d51d871a52
13 changed files with 455 additions and 73 deletions

View File

@ -635,6 +635,19 @@ public:
virtual RetVal HandleMenuAction(CefRefPtr<CefBrowser> browser,
MenuId menuId) =0;
// Structure representing print options.
typedef cef_print_options_t CefPrintOptions;
// Event called to allow customization of standard print options before the
// print dialog is displayed. |printOptions| allows specification of paper
// size, orientation and margins. Note that the specified margins may be
// adjusted if they are outside the range supported by the printer. All units
// are in inches. Return RV_CONTINUE to display the default print options or
// RV_HANDLED to display the modified |printOptions|.
/*--cef()--*/
virtual RetVal HandlePrintOptions(CefRefPtr<CefBrowser> browser,
CefPrintOptions& printOptions) = 0;
// Event called to format print headers and footers. |printInfo| contains
// platform-specific information about the printer context. |url| is the
// URL if the currently printing page, |title| is the title of the currently

View File

@ -461,6 +461,16 @@ typedef struct _cef_handler_t
struct _cef_handler_t* self, struct _cef_browser_t* browser,
enum cef_handler_menuid_t menuId);
// Event called to allow customization of standard print options before the
// print dialog is displayed. |printOptions| allows specification of paper
// size, orientation and margins. Note that the specified margins may be
// adjusted if they are outside the range supported by the printer. All units
// are in inches. Return RV_CONTINUE to display the default print options or
// RV_HANDLED to display the modified |printOptions|.
enum cef_retval_t (CEF_CALLBACK *handle_print_options)(
struct _cef_handler_t* self, struct _cef_browser_t* browser,
struct _cef_print_options_t* printOptions);
// Event called to format print headers and footers. |printInfo| contains
// platform-specific information about the printer context. |url| is the URL
// if the currently printing page, |title| is the title of the currently
@ -534,9 +544,13 @@ typedef struct _cef_handler_t
enum cef_handler_keyevent_type_t type, int code, int modifiers,
int isSystemKey);
enum cef_retval_t (CEF_CALLBACK *handle_tooltip)(
struct _cef_handler_t* self, struct _cef_browser_t* browser,
cef_string_t* text);
// Event called when the browser is about to display a tooltip. |text|
// contains the text that will be displayed in the tooltip. To handle the
// display of the tooltip yourself return RV_HANDLED. Otherwise, you can
// optionally modify |text| and then return RV_CONTINUE to allow the browser
// to display the tooltip.
enum cef_retval_t (CEF_CALLBACK *handle_tooltip)(struct _cef_handler_t* self,
struct _cef_browser_t* browser, cef_string_t* text);
// Called to display a console message. Return RV_HANDLED to stop the message
// from being output to the console.

View File

@ -237,6 +237,55 @@ enum cef_thread_id_t
TID_FILE = 2,
};
// Paper type for printing.
enum cef_paper_type_t
{
PT_LETTER = 0,
PT_LEGAL,
PT_EXECUTIVE,
PT_A3,
PT_A4,
PT_CUSTOM
};
// Paper metric information for printing.
struct cef_paper_metrics
{
enum cef_paper_type_t paper_type;
//Length and width needed if paper_type is custom_size
//Units are in inches.
double length;
double width;
};
// Paper print margins.
struct cef_print_margins
{
//Margin size in inches for left/right/top/bottom (this is content margins).
double left;
double right;
double top;
double bottom;
//Margin size (top/bottom) in inches for header/footer.
double header;
double footer;
};
// Page orientation for printing
enum cef_page_orientation
{
PORTRAIT = 0,
LANDSCAPE
};
// Printing options.
typedef struct _cef_print_options_t
{
enum cef_page_orientation page_orientation;
struct cef_paper_metrics paper_metrics;
struct cef_print_margins paper_margins;
} cef_print_options_t;
#ifdef __cplusplus
}
#endif

View File

@ -237,13 +237,11 @@ void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages,
const printing::PrintSettings &settings = print_context_.settings();
settings.RenderParams(&params);
int src_size_x = canvas_size.width();
int src_size_y = canvas_size.height();
float src_margin = .1f * src_size_x;
const int src_size_x = canvas_size.width();
const int src_size_y = canvas_size.height();
int dest_size_x = settings.page_setup_pixels().physical_size().width();
int dest_size_y = settings.page_setup_pixels().physical_size().height();
float dest_margin = .1f * dest_size_x;
const int dest_size_x = settings.page_setup_pixels().printable_area().width();
const int dest_size_y = settings.page_setup_pixels().printable_area().height();
print_context_.NewPage();
@ -257,21 +255,26 @@ void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages,
skia::VectorCanvas canvas(hDC, dest_size_x, dest_size_y);
//The hDC 0 coord is the left most printeable area and not physical area of the paper
//so subtract that out of our canvas translate.
const int left_margin_offset = settings.page_setup_pixels().effective_margins().left -
settings.page_setup_pixels().printable_area().x();
const int top_margin_offset = settings.page_setup_pixels().effective_margins().top -
settings.page_setup_pixels().printable_area().y();
// Adjust for the margin offset.
canvas.translate(dest_margin, dest_margin);
canvas.translate(static_cast<float>(left_margin_offset),
static_cast<float>(top_margin_offset));
// Apply the print scaling factor.
float print_scale = (dest_size_x - dest_margin * 2) / src_size_x;
canvas.scale(print_scale, print_scale);
// Set the clipping region to be sure to not overflow.
SkRect clip_rect;
clip_rect.set(0, 0, static_cast<float>(src_size_x),
static_cast<float>(src_size_y));
canvas.clipRect(clip_rect);
const float print_scale_x = static_cast<float>(settings.page_setup_pixels().content_area().width())
/ src_size_x;
const float print_scale_y = static_cast<float>(settings.page_setup_pixels().content_area().height())
/ src_size_y;
canvas.scale(print_scale_x, print_scale_y);
// Apply the WebKit scaling factor.
float webkit_scale = frame->getPrintPageShrink(page_number);
const float webkit_scale = frame->getPrintPageShrink(page_number);
if (webkit_scale <= 0) {
NOTREACHED() << "Printing page " << page_number << " failed.";
}
@ -288,13 +291,18 @@ void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages,
// Gather print header state information
RECT rect;
rect.left = (int)floor(dest_margin / 2);
rect.top = rect.left;
rect.right = (int)ceil(dest_size_x - dest_margin / 2);
rect.bottom = (int)ceil(dest_size_y - dest_margin / 2);
rect.left = left_margin_offset;
rect.top = settings.page_setup_pixels().effective_margins().header -
settings.page_setup_pixels().printable_area().y();
rect.right = left_margin_offset + settings.page_setup_pixels().content_area().width();
rect.bottom = settings.page_setup_pixels().printable_area().height() -
(settings.page_setup_pixels().effective_margins().footer -
(settings.page_setup_pixels().physical_size().height() -
settings.page_setup_pixels().printable_area().bottom()));
const double scale = static_cast<double>(settings.dpi()) /
static_cast<double>(settings.desired_dpi);
double scale = (double)settings.dpi() / (double)settings.desired_dpi;
CefPrintInfo printInfo;
printInfo.m_hDC = hDC;
@ -374,13 +382,18 @@ void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages,
void CefBrowserImpl::UIT_PrintPages(WebKit::WebFrame* frame) {
REQUIRE_UIT();
TCHAR printername[512];
DWORD size = sizeof(printername)-1;
if(GetDefaultPrinter(printername, &size)) {
printing::PrintSettings settings;
settings.set_device_name(printername);
// Initialize it.
print_context_.InitWithSettings(settings);
print_context_.Init();
{
// Make a copy of settings.
printing::PrintSettings settings = print_context_.settings();
cef_print_options_t print_options;
settings.UpdatePrintOptions(print_options);
// Ask the handler if they want to update the print options.
if (handler_.get() && RV_HANDLED == handler_->HandlePrintOptions(this, print_options)) {
settings.UpdateFromPrintOptions(print_options);
print_context_.InitWithSettings(settings);
}
}
if(print_context_.AskUserForSettings(
@ -398,12 +411,12 @@ void CefBrowserImpl::UIT_PrintPages(WebKit::WebFrame* frame) {
canvas_size.set_width(
printing::ConvertUnit(
settings.page_setup_pixels().physical_size().width(),
settings.page_setup_pixels().content_area().width(),
static_cast<int>(params.dpi),
params.desired_dpi));
canvas_size.set_height(
printing::ConvertUnit(
settings.page_setup_pixels().physical_size().height(),
settings.page_setup_pixels().content_area().height(),
static_cast<int>(params.dpi),
params.desired_dpi));
page_count = frame->printBegin(WebSize(canvas_size));
@ -412,19 +425,19 @@ void CefBrowserImpl::UIT_PrintPages(WebKit::WebFrame* frame) {
bool old_state = MessageLoop::current()->NestableTasksAllowed();
MessageLoop::current()->SetNestableTasksAllowed(false);
// TODO(cef): Use the page title as the document name
print_context_.NewDocument(L"New Document");
if(settings.ranges.size() > 0) {
for (unsigned x = 0; x < settings.ranges.size(); ++x) {
const printing::PageRange& range = settings.ranges[x];
for(int i = range.from; i <= range.to; ++i)
if (print_context_.NewDocument(title_) == printing::PrintingContext::OK) {
if(settings.ranges.size() > 0) {
for (unsigned x = 0; x < settings.ranges.size(); ++x) {
const printing::PageRange& range = settings.ranges[x];
for(int i = range.from; i <= range.to; ++i)
UIT_PrintPage(i, page_count, canvas_size, frame);
}
} else {
for(int i = 0; i < page_count; ++i)
UIT_PrintPage(i, page_count, canvas_size, frame);
}
} else {
for(int i = 0; i < page_count; ++i)
UIT_PrintPage(i, page_count, canvas_size, frame);
print_context_.DocumentDone();
}
print_context_.DocumentDone();
MessageLoop::current()->SetNestableTasksAllowed(old_state);
}
@ -450,12 +463,12 @@ int CefBrowserImpl::UIT_GetPagesCount(WebKit::WebFrame* frame)
canvas_size.set_width(
printing::ConvertUnit(
settings.page_setup_pixels().physical_size().width(),
settings.page_setup_pixels().content_area().width(),
static_cast<int>(params.dpi),
params.desired_dpi));
canvas_size.set_height(
printing::ConvertUnit(
settings.page_setup_pixels().physical_size().height(),
settings.page_setup_pixels().content_area().height(),
static_cast<int>(params.dpi),
params.desired_dpi));
page_count = frame->printBegin(WebSize(canvas_size));

View File

@ -13,6 +13,24 @@ namespace printing {
// Global SequenceNumber used for generating unique cookie values.
static base::AtomicSequenceNumber cookie_seq(base::LINKER_INITIALIZED);
PageMeasurements::PageMeasurements()
: page_type(PT_LETTER),
page_length(0.0f),
page_width(0.0f) {
}
void PageMeasurements::Clear() {
page_type = PT_LETTER;
page_length = 0.0f;
page_width = 0.0f;
}
bool PageMeasurements::Equals(const PageMeasurements& rhs) const {
return page_type == rhs.page_type &&
page_length == rhs.page_length &&
page_width == rhs.page_width;
}
PrintSettings::PrintSettings()
: min_shrink(1.25),
max_shrink(2.0),
@ -20,7 +38,8 @@ PrintSettings::PrintSettings()
selection_only(false),
to_file(false),
dpi_(0),
landscape_(false) {
landscape(false) {
ResetRequestedPageMargins();
}
void PrintSettings::Clear() {
@ -34,7 +53,22 @@ void PrintSettings::Clear() {
device_name_.clear();
page_setup_pixels_.Clear();
dpi_ = 0;
landscape_ = false;
landscape = false;
page_measurements.Clear();
ResetRequestedPageMargins();
}
void PrintSettings::ResetRequestedPageMargins() {
// Initial requested margins to = 1.0cm = ~2/5 of inch
const int margin_printer_units = ConvertUnit(1000, kHundrethsMMPerInch, desired_dpi);
// Initial requested header/footer margins to = 0.5cm = ~1/5 of inch
const int header_footer_margins = ConvertUnit(500, kHundrethsMMPerInch, desired_dpi);
requested_margins.header = header_footer_margins;
requested_margins.footer = header_footer_margins;
requested_margins.left = margin_printer_units;
requested_margins.top = margin_printer_units;
requested_margins.right = margin_printer_units;
requested_margins.bottom = margin_printer_units;
}
#ifdef WIN32
@ -48,10 +82,39 @@ void PrintSettings::Init(HDC hdc,
printer_name_ = dev_mode.dmDeviceName;
device_name_ = new_device_name;
ranges = new_ranges;
landscape_ = dev_mode.dmOrientation == DMORIENT_LANDSCAPE;
landscape = dev_mode.dmOrientation == DMORIENT_LANDSCAPE;
selection_only = print_selection_only;
to_file = print_to_file;
bool is_custom_paper = true;
if (dev_mode.dmFields & DM_PAPERSIZE) {
switch(dev_mode.dmPaperSize) {
case DMPAPER_LETTER:
page_measurements.page_type = PT_LETTER;
is_custom_paper = false;
break;
case DMPAPER_LEGAL:
page_measurements.page_type = PT_LEGAL;
is_custom_paper = false;
break;
case DMPAPER_EXECUTIVE:
page_measurements.page_type = PT_EXECUTIVE;
is_custom_paper = false;
break;
case DMPAPER_A3:
page_measurements.page_type = PT_A3;
is_custom_paper = false;
break;
case DMPAPER_A4:
page_measurements.page_type = PT_A4;
is_custom_paper = false;
break;
default:
//we'll translate it as a custom paper size.
break;
}
}
dpi_ = GetDeviceCaps(hdc, LOGPIXELSX);
// No printer device is known to advertise different dpi in X and Y axis; even
// the fax device using the 200x100 dpi setting. It's ought to break so many
@ -70,6 +133,22 @@ void PrintSettings::Init(HDC hdc,
GetDeviceCaps(hdc, HORZRES),
GetDeviceCaps(hdc, VERTRES));
if (is_custom_paper) {
page_measurements.page_length = ConvertUnitDouble(
static_cast<double>(physical_size_pixels.height()),
static_cast<double>(dpi_),
static_cast<double>(desired_dpi));
page_measurements.page_width = ConvertUnitDouble(
static_cast<double>(physical_size_pixels.width()),
static_cast<double>(dpi_),
static_cast<double>(desired_dpi));
if (landscape) {
double temp = page_measurements.page_length;
page_measurements.page_length = page_measurements.page_width;
page_measurements.page_width = temp;
}
}
SetPrinterPrintableArea(physical_size_pixels, printable_area_pixels);
}
#endif
@ -77,23 +156,23 @@ void PrintSettings::Init(HDC hdc,
void PrintSettings::SetPrinterPrintableArea(
gfx::Size const& physical_size_pixels,
gfx::Rect const& printable_area_pixels) {
int margin_printer_units = ConvertUnit(500, kHundrethsMMPerInch, dpi_);
// Hard-code text_height = 0.5cm = ~1/5 of inch
const int text_height = ConvertUnit(500, kHundrethsMMPerInch, dpi_);
// Start by setting the user configuration
// Hard-code text_height = 0.5cm = ~1/5 of inch
page_setup_pixels_.Init(physical_size_pixels,
printable_area_pixels,
margin_printer_units);
text_height);
// Now apply user configured settings.
// Now adjust requested margins to the appropriate dpi.
PageMargins margins;
margins.header = margin_printer_units;
margins.footer = margin_printer_units;
margins.left = margin_printer_units;
margins.top = margin_printer_units;
margins.right = margin_printer_units;
margins.bottom = margin_printer_units;
margins.header = ConvertUnit(requested_margins.header, desired_dpi, dpi_);
margins.footer = ConvertUnit(requested_margins.footer, desired_dpi, dpi_);
margins.left = ConvertUnit(requested_margins.left, desired_dpi, dpi_);
margins.top = ConvertUnit(requested_margins.top, desired_dpi, dpi_);
margins.right = ConvertUnit(requested_margins.right, desired_dpi, dpi_);
margins.bottom = ConvertUnit(requested_margins.bottom, desired_dpi, dpi_);
page_setup_pixels_.SetRequestedMargins(margins);
}
@ -125,7 +204,9 @@ bool PrintSettings::Equals(const PrintSettings& rhs) const {
device_name_ == rhs.device_name_ &&
page_setup_pixels_.Equals(rhs.page_setup_pixels_) &&
dpi_ == rhs.dpi_ &&
landscape_ == rhs.landscape_;
landscape == rhs.landscape &&
page_measurements.Equals(rhs.page_measurements) &&
requested_margins.Equals(rhs.requested_margins);
}
int PrintSettings::NewCookie() {
@ -133,5 +214,52 @@ int PrintSettings::NewCookie() {
return cookie_seq.GetNext() + 1;
}
void PrintSettings::UpdatePrintOptions(cef_print_options_t& print_options) {
print_options.page_orientation = (landscape) ? LANDSCAPE : PORTRAIT;
print_options.paper_metrics.paper_type = page_measurements.page_type;
if (page_measurements.page_type == PT_CUSTOM) {
print_options.paper_metrics.length = ConvertUnitDouble(
page_measurements.page_length, desired_dpi, 1);
print_options.paper_metrics.width = ConvertUnitDouble(
page_measurements.page_width, desired_dpi, 1);
}
print_options.paper_margins.left = ConvertUnitDouble(
requested_margins.left, desired_dpi, 1);
print_options.paper_margins.top = ConvertUnitDouble(
requested_margins.top, desired_dpi, 1);
print_options.paper_margins.right = ConvertUnitDouble(
requested_margins.right, desired_dpi, 1);
print_options.paper_margins.bottom = ConvertUnitDouble(
requested_margins.bottom, desired_dpi, 1);
print_options.paper_margins.header = ConvertUnitDouble(
requested_margins.header, desired_dpi, 1);
print_options.paper_margins.footer = ConvertUnitDouble(
requested_margins.footer, desired_dpi, 1);
}
void PrintSettings::UpdateFromPrintOptions(const cef_print_options_t& print_options) {
landscape = print_options.page_orientation == LANDSCAPE;
page_measurements.page_type = print_options.paper_metrics.paper_type;
if (page_measurements.page_type == PT_CUSTOM) {
page_measurements.page_length = ConvertUnitDouble(
print_options.paper_metrics.length, 1, desired_dpi);
page_measurements.page_width = ConvertUnitDouble(
print_options.paper_metrics.width, 1, desired_dpi);
}
requested_margins.left = static_cast<int>(ConvertUnitDouble(
print_options.paper_margins.left, 1, desired_dpi));
requested_margins.top = static_cast<int>(ConvertUnitDouble(
print_options.paper_margins.top, 1, desired_dpi));
requested_margins.right = static_cast<int>(ConvertUnitDouble(
print_options.paper_margins.right, 1, desired_dpi));
requested_margins.bottom = static_cast<int>(ConvertUnitDouble(
print_options.paper_margins.bottom, 1, desired_dpi));
requested_margins.header = static_cast<int>(ConvertUnitDouble(
print_options.paper_margins.header, 1, desired_dpi));
requested_margins.footer = static_cast<int>(ConvertUnitDouble(
print_options.paper_margins.footer, 1, desired_dpi));
}
} // namespace printing

View File

@ -5,6 +5,8 @@
#ifndef _PRINTING_PRINT_SETTINGS_H
#define _PRINTING_PRINT_SETTINGS_H
#include "include/cef_types.h"
#include "gfx/rect.h"
#include "printing/page_range.h"
#include "printing/page_setup.h"
@ -52,6 +54,22 @@ struct PrintParams {
}
};
// Page measurements information.
class PageMeasurements {
public:
PageMeasurements();
void Clear();
// Equality operator.
bool Equals(const PageMeasurements& rhs) const;
enum cef_paper_type_t page_type;
// Page length and width represented in inches.
// These should be filled in if page_type is PT_CUSTOM.
double page_length;
double page_width;
};
// OS-independent print settings.
class PrintSettings {
public:
@ -92,6 +110,9 @@ class PrintSettings {
int dpi() const { return dpi_; }
const PageSetup& page_setup_pixels() const { return page_setup_pixels_; }
void UpdatePrintOptions(cef_print_options_t& print_options);
void UpdateFromPrintOptions(const cef_print_options_t& print_options);
// Multi-page printing. Each PageRange describes a from-to page combination.
// This permits printing selected pages only.
PageRanges ranges;
@ -124,7 +145,17 @@ class PrintSettings {
// correctly associated with its corresponding PrintedDocument.
static int NewCookie();
// Requested Page Margins in pixels based on desired_dpi.
// These are in terms of desired_dpi since printer dpi may vary.
PageMargins requested_margins;
// Is the orientation landscape or portrait.
bool landscape;
// Page Measurements.
PageMeasurements page_measurements;
private:
void ResetRequestedPageMargins();
//////////////////////////////////////////////////////////////////////////////
// Settings that can't be changed without side-effects.
@ -139,9 +170,6 @@ class PrintSettings {
// Printer's device effective dots per inch in both axis.
int dpi_;
// Is the orientation landscape or portrait.
bool landscape_;
};
} // namespace printing

View File

@ -12,6 +12,8 @@
#include "base/time.h"
#include "skia/ext/platform_device_win.h"
#include "printing/units.h"
using base::Time;
namespace {
@ -90,6 +92,17 @@ PrintingContext::Result PrintingContext::AskUserForSettings(
dialog_options.Flags |= PD_NOPAGENUMS;
}
// Adjust the default dev mode for the printdlg settings.
DEVMODE dev_mode;
memset(&dev_mode,0,sizeof(dev_mode));
dev_mode.dmSpecVersion = DM_SPECVERSION;
dev_mode.dmSize = sizeof(DEVMODE);
AdjustDevMode(dev_mode);
dialog_options.hDevMode = GlobalAlloc(GMEM_MOVEABLE, sizeof(DEVMODE));
DEVMODE* locked_dev_mode = reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode));
memcpy(locked_dev_mode, &dev_mode, sizeof(DEVMODE));
GlobalUnlock(dialog_options.hDevMode);
{
if (PrintDlgEx(&dialog_options) != S_OK) {
ResetSettings();
@ -111,20 +124,82 @@ PrintingContext::Result PrintingContext::UseDefaultSettings() {
return ParseDialogResult(dialog_options);
}
void PrintingContext::AdjustDevMode(DEVMODE& dev_mode)
{
dev_mode.dmFields |= DM_ORIENTATION;
dev_mode.dmOrientation = (settings_.landscape) ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
dev_mode.dmFields |= DM_PAPERSIZE;
switch(settings_.page_measurements.page_type) {
case PT_LETTER:
dev_mode.dmPaperSize = DMPAPER_LETTER;
break;
case PT_LEGAL:
dev_mode.dmPaperSize = DMPAPER_LEGAL;
break;
case PT_EXECUTIVE:
dev_mode.dmPaperSize = DMPAPER_EXECUTIVE;
break;
case PT_A3:
dev_mode.dmPaperSize = DMPAPER_A3;
break;
case PT_A4:
dev_mode.dmPaperSize = DMPAPER_A4;
break;
case PT_CUSTOM:
{
dev_mode.dmPaperSize = DMPAPER_USER;
dev_mode.dmFields |= DM_PAPERLENGTH | DM_PAPERWIDTH;
DCHECK_GT(settings_.page_measurements.page_length, 0);
DCHECK_GT(settings_.page_measurements.page_width, 0);
// Convert from desired_dpi to tenths of a mm.
dev_mode.dmPaperLength = static_cast<short>(
ConvertUnitDouble(abs(settings_.page_measurements.page_length),
10.0 * settings_.desired_dpi,
static_cast<double>(kHundrethsMMPerInch)) + 0.5);
dev_mode.dmPaperWidth = static_cast<short>(
ConvertUnitDouble(abs(settings_.page_measurements.page_width),
10.0 * settings_.desired_dpi,
static_cast<double>(kHundrethsMMPerInch)) + 0.5);
break;
}
default:
//we shouldn't ever hit this case.
DCHECK(false);
dev_mode.dmPaperSize = DMPAPER_LETTER;
break;
}
}
PrintingContext::Result PrintingContext::Init() {
DCHECK(!in_print_job_);
TCHAR printername[512];
DWORD size = sizeof(printername)-1;
if(GetDefaultPrinter(printername, &size)) {
return Init(std::wstring(printername), false);
}
return FAILED;
}
PrintingContext::Result PrintingContext::InitWithSettings(
const PrintSettings& settings) {
DCHECK(!in_print_job_);
settings_ = settings;
// TODO(maruel): settings_->ToDEVMODE()
return Init(settings_.device_name().c_str(), true);
}
PrintingContext::Result PrintingContext::Init(const std::wstring& device_name,
bool adjust_dev_mode) {
HANDLE printer;
if (!OpenPrinter(const_cast<wchar_t*>(settings_.device_name().c_str()),
if (!OpenPrinter(const_cast<wchar_t*>(device_name.c_str()),
&printer,
NULL))
return FAILED;
Result status = OK;
if (!GetPrinterSettings(printer, settings_.device_name()))
if (!GetPrinterSettings(printer, device_name, adjust_dev_mode))
status = FAILED;
// Close the printer after retrieving the context.
@ -314,7 +389,8 @@ bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode,
}
bool PrintingContext::GetPrinterSettings(HANDLE printer,
const std::wstring& device_name) {
const std::wstring& device_name,
bool adjust_dev_mode) {
DCHECK(!in_print_job_);
scoped_array<uint8> buffer;
@ -324,6 +400,8 @@ bool PrintingContext::GetPrinterSettings(HANDLE printer,
if (buffer.get()) {
PRINTER_INFO_9* info_9 = reinterpret_cast<PRINTER_INFO_9*>(buffer.get());
if (info_9->pDevMode != NULL) {
if (adjust_dev_mode)
AdjustDevMode(*info_9->pDevMode);
if (!AllocateContext(device_name, info_9->pDevMode)) {
ResetSettings();
return false;
@ -339,6 +417,8 @@ bool PrintingContext::GetPrinterSettings(HANDLE printer,
if (buffer.get()) {
PRINTER_INFO_8* info_8 = reinterpret_cast<PRINTER_INFO_8*>(buffer.get());
if (info_8->pDevMode != NULL) {
if (adjust_dev_mode)
AdjustDevMode(*info_8->pDevMode);
if (!AllocateContext(device_name, info_8->pDevMode)) {
ResetSettings();
return false;
@ -355,6 +435,8 @@ bool PrintingContext::GetPrinterSettings(HANDLE printer,
if (buffer.get()) {
PRINTER_INFO_2* info_2 = reinterpret_cast<PRINTER_INFO_2*>(buffer.get());
if (info_2->pDevMode != NULL) {
if (adjust_dev_mode)
AdjustDevMode(*info_2->pDevMode);
if (!AllocateContext(device_name, info_2->pDevMode)) {
ResetSettings();
return false;
@ -380,8 +462,10 @@ PrintingContext::Result PrintingContext::ParseDialogResultEx(
const PRINTDLGEX& dialog_options) {
// If the user clicked OK or Apply then Cancel, but not only Cancel.
if (dialog_options.dwResultAction != PD_RESULT_CANCEL) {
// Start fresh.
PageMargins requested_margins = settings_.requested_margins;
// Start fresh except for page margins since that isn't controlled by this dialog.
ResetSettings();
settings_.requested_margins = requested_margins;
DEVMODE* dev_mode = NULL;
if (dialog_options.hDevMode) {

View File

@ -38,6 +38,9 @@ class PrintingContext {
// default device settings.
Result UseDefaultSettings();
// Initializes with printer default's settings.
Result Init();
// Initializes with predefined settings.
Result InitWithSettings(const PrintSettings& settings);
@ -100,11 +103,18 @@ class PrintingContext {
// Retrieves the printer's default low-level settings. hdc_ is allocated with
// this call.
bool GetPrinterSettings(HANDLE printer,
const std::wstring& device_name);
const std::wstring& device_name,
bool adjust_dev_mode);
// Allocates the HDC for a specific DEVMODE.
bool AllocateContext(const std::wstring& printer_name,
const DEVMODE* dev_mode);
// Updates printer dev_mode with settings_
void PrintingContext::AdjustDevMode(DEVMODE& dev_mode);
// Initializes the hdc_ either with setting_ or with just printer defaults.
Result Init(const std::wstring& device_name, bool adjust_dev_mode);
// Parses the result of a PRINTDLGEX result.
Result ParseDialogResultEx(const PRINTDLGEX& dialog_options);

View File

@ -276,6 +276,19 @@ enum cef_retval_t CEF_CALLBACK handler_handle_menu_action(
CefBrowserCToCpp::Wrap(browser), menuId);
}
enum cef_retval_t CEF_CALLBACK handler_handle_print_options(
struct _cef_handler_t* self, cef_browser_t* browser,
struct _cef_print_options_t* printOptions)
{
DCHECK(self);
DCHECK(browser);
DCHECK(printOptions);
if(!self || !browser || !printOptions)
return RV_CONTINUE;
return CefHandlerCppToC::Get(self)->HandlePrintOptions(CefBrowserCToCpp::Wrap(browser), *printOptions);
}
enum cef_retval_t CEF_CALLBACK handler_handle_print_header_footer(
struct _cef_handler_t* self, cef_browser_t* browser, cef_frame_t* frame,
cef_print_info_t* printInfo, const wchar_t* url, const wchar_t* title,
@ -458,8 +471,7 @@ enum cef_retval_t CEF_CALLBACK handler_handle_key_event(
}
enum cef_retval_t CEF_CALLBACK handler_handle_tooltip(
struct _cef_handler_t* self, struct _cef_browser_t* browser,
cef_string_t* text)
struct _cef_handler_t* self, cef_browser_t* browser, cef_string_t* text)
{
DCHECK(self);
DCHECK(browser);
@ -533,6 +545,7 @@ CefHandlerCppToC::CefHandlerCppToC(CefHandler* cls)
struct_.struct_.handle_before_menu = handler_handle_before_menu;
struct_.struct_.handle_get_menu_label = handler_handle_get_menu_label;
struct_.struct_.handle_menu_action = handler_handle_menu_action;
struct_.struct_.handle_print_options = handler_handle_print_options;
struct_.struct_.handle_print_header_footer =
handler_handle_print_header_footer;
struct_.struct_.handle_jsalert = handler_handle_jsalert;

View File

@ -215,6 +215,16 @@ CefHandler::RetVal CefHandlerCToCpp::HandleMenuAction(
menuId);
}
CefHandler::RetVal CefHandlerCToCpp::HandlePrintOptions(
CefRefPtr<CefBrowser> browser, CefPrintOptions& printOptions)
{
if (CEF_MEMBER_MISSING(struct_, handle_print_options))
return RV_CONTINUE;
return struct_->handle_print_options(struct_, CefBrowserCppToC::Wrap(browser),
&printOptions);
}
CefHandler::RetVal CefHandlerCToCpp::HandlePrintHeaderFooter(
CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
CefPrintInfo& printInfo, const std::wstring& url,

View File

@ -58,6 +58,8 @@ public:
virtual RetVal HandleGetMenuLabel(CefRefPtr<CefBrowser> browser,
MenuId menuId, std::wstring& label);
virtual RetVal HandleMenuAction(CefRefPtr<CefBrowser> browser, MenuId menuId);
virtual RetVal HandlePrintOptions(CefRefPtr<CefBrowser> browser,
CefPrintOptions& printOptions);
virtual RetVal HandlePrintHeaderFooter(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, CefPrintInfo& printInfo,
const std::wstring& url, const std::wstring& title, int currentPage,

View File

@ -424,6 +424,18 @@ public:
return RV_CONTINUE;
}
// Event called to allow customization of standard print options before the
// print dialog is displayed. |printOptions| allows specification of paper
// size, orientation and margins. Note that the specified margins may be
// adjusted if they are outside the range supported by the printer. All units
// are in inches. Return RV_CONTINUE to display the default print options or
// RV_HANDLED to display the modified |printOptions|.
virtual RetVal HandlePrintOptions(CefRefPtr<CefBrowser> browser,
CefPrintOptions& printOptions)
{
return RV_CONTINUE;
}
// Event called to format print headers and footers. |printInfo| contains
// platform-specific information about the printer context. |url| is the
// URL if the currently printing page, |title| is the title of the currently

View File

@ -129,6 +129,12 @@ public:
return RV_CONTINUE;
}
virtual RetVal HandlePrintOptions(CefRefPtr<CefBrowser> browser,
CefPrintOptions& printOptions)
{
return RV_CONTINUE;
}
virtual RetVal HandlePrintHeaderFooter(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefPrintInfo& printInfo,