mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1669854 - Add a single pageRanges print setting. r=nordzilla
... which is an array of pairs of ranges, and use it instead of the existing printRange / startPage / endPage settings. Differential Revision: https://phabricator.services.mozilla.com/D96093
This commit is contained in:
parent
3bf1904869
commit
771dd03229
@ -96,42 +96,7 @@ void PrintedSheetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
// NS_PAGE_SKIPPED_BY_CUSTOM_RANGE state bit and returns true.
|
||||
static bool TagIfSkippedByCustomRange(nsPageFrame* aPageFrame, int32_t aPageNum,
|
||||
nsSharedPageData* aPD) {
|
||||
if (!aPD->mDoingPageRange) {
|
||||
MOZ_ASSERT(!aPageFrame->HasAnyStateBits(NS_PAGE_SKIPPED_BY_CUSTOM_RANGE),
|
||||
"page frames shouldn't be tagged as skipped if we're not "
|
||||
"printing with a custom page range");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isPageSkipped = false;
|
||||
|
||||
// As described in nsSharedPageData documentation: we can use mFromPageNum
|
||||
// and mToPageNum as a quick way to reject entirely-out-of-range pages. For
|
||||
// page numbers inside these bounds, we need to check mRanges to find out if
|
||||
// they're included in our subranges (if there are any).
|
||||
if (aPageNum < aPD->mFromPageNum || aPageNum > aPD->mToPageNum) {
|
||||
// Page is out-of-bounds; it's skipped.
|
||||
isPageSkipped = true;
|
||||
} else {
|
||||
// Check subranges (if there are any).
|
||||
const auto& ranges = aPD->mPageRanges;
|
||||
int32_t length = ranges.Length();
|
||||
|
||||
// Page ranges are pairs (start, end) of included pages.
|
||||
if (length && (length % 2 == 0)) {
|
||||
isPageSkipped = true;
|
||||
for (int32_t i = 0; i < length; i += 2) {
|
||||
if (ranges[i] <= aPageNum && aPageNum <= ranges[i + 1]) {
|
||||
// The page is included in this piece of the custom range,
|
||||
// so it's not skipped.
|
||||
isPageSkipped = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isPageSkipped) {
|
||||
if (!nsIPrintSettings::IsPageSkipped(aPageNum, aPD->mPageRanges)) {
|
||||
MOZ_ASSERT(!aPageFrame->HasAnyStateBits(NS_PAGE_SKIPPED_BY_CUSTOM_RANGE),
|
||||
"page frames NS_PAGE_SKIPPED_BY_CUSTOM_RANGE state should "
|
||||
"only be set if we actually want to skip the page");
|
||||
|
@ -296,15 +296,8 @@ void nsPageSequenceFrame::Reflow(nsPresContext* aPresContext,
|
||||
mPageData->mEdgePaperMargin = nsPresContext::CSSTwipsToAppUnits(edgeTwips);
|
||||
|
||||
// Get the custom page-range state:
|
||||
mPageData->mPrintSettings->GetStartPageRange(&mPageData->mFromPageNum);
|
||||
mPageData->mPrintSettings->GetEndPageRange(&mPageData->mToPageNum);
|
||||
mPageData->mPrintSettings->GetPageRanges(mPageData->mPageRanges);
|
||||
|
||||
int16_t printType;
|
||||
mPageData->mPrintSettings->GetPrintRange(&printType);
|
||||
mPageData->mDoingPageRange =
|
||||
nsIPrintSettings::kRangeSpecifiedPageRange == printType;
|
||||
|
||||
// We use the CSS "margin" property on the -moz-printed-sheet pseudoelement
|
||||
// to determine the space between each printed sheet in print preview.
|
||||
// Keep a running y-offset for each printed sheet.
|
||||
@ -453,14 +446,6 @@ nsresult nsPageSequenceFrame::StartPrint(nsPresContext* aPresContext,
|
||||
mPageData->mDocURL = aDocURL;
|
||||
}
|
||||
|
||||
// If printing a range of pages make sure at least the starting page
|
||||
// number is valid
|
||||
if (mPageData->mDoingPageRange) {
|
||||
if (mPageData->mFromPageNum > mPageData->mRawNumPages) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
// Begin printing of the document
|
||||
mCurrentSheetIdx = 0;
|
||||
return NS_OK;
|
||||
|
@ -63,19 +63,9 @@ class nsSharedPageData {
|
||||
// that it's reflowed the final page):
|
||||
int32_t mRawNumPages = 0;
|
||||
|
||||
// Smallest included page num. 1-based. Only used if mDoingPageRange is true.
|
||||
int32_t mFromPageNum = 0;
|
||||
|
||||
// Largest included page num. 1-based. Only used if mDoingPageRange is true.
|
||||
int32_t mToPageNum = 0;
|
||||
|
||||
// If there's more than one page-range, then its components are stored here
|
||||
// as pairs of (start,end). They're stored in the order provided (not
|
||||
// necessarily in ascending order). The most extreme included values will
|
||||
// still be stored in mFromPageNum and mToPageNum, so that entirely
|
||||
// out-of-bounds pages can be easily filtered out without needing to inspect
|
||||
// this array. As above, the values are 1-based, and this member is only used
|
||||
// if mDoingPageRange is true.
|
||||
// necessarily in ascending order).
|
||||
nsTArray<int32_t> mPageRanges;
|
||||
|
||||
// Margin for headers and footers; it defaults to 4/100 of an inch on UNIX
|
||||
@ -90,9 +80,6 @@ class nsSharedPageData {
|
||||
// frames that overflowed. It's 1.0 if none overflowed horizontally.
|
||||
float mShrinkToFitRatio = 1.0f;
|
||||
|
||||
// True if the current print operation uses one or more print ranges:
|
||||
bool mDoingPageRange = false;
|
||||
|
||||
// Lazy getter, to look up our pages-per-sheet info based on mPrintSettings
|
||||
// (if it's available). The result is stored in our mPagesPerSheetInfo
|
||||
// member-var to speed up subsequent lookups.
|
||||
|
@ -784,7 +784,7 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
|
||||
// In legacy print-preview mode, override any UI that wants to PrintPreview
|
||||
// any selection or page range. The legacy print-preview intends to view
|
||||
// every page in PrintPreview each time.
|
||||
printData->mPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages);
|
||||
printData->mPrintSettings->SetPageRanges({});
|
||||
}
|
||||
|
||||
MOZ_TRY(EnablePOsForPrinting());
|
||||
@ -1380,14 +1380,12 @@ nsresult nsPrintJob::SetupToPrintContent() {
|
||||
int32_t startPage = 1;
|
||||
int32_t endPage = printData->mNumPrintablePages;
|
||||
|
||||
int16_t printRangeType = nsIPrintSettings::kRangeAllPages;
|
||||
printData->mPrintSettings->GetPrintRange(&printRangeType);
|
||||
if (printRangeType == nsIPrintSettings::kRangeSpecifiedPageRange) {
|
||||
printData->mPrintSettings->GetStartPageRange(&startPage);
|
||||
printData->mPrintSettings->GetEndPageRange(&endPage);
|
||||
if (endPage > printData->mNumPrintablePages) {
|
||||
endPage = printData->mNumPrintablePages;
|
||||
}
|
||||
nsTArray<int32_t> ranges;
|
||||
printData->mPrintSettings->GetPageRanges(ranges);
|
||||
for (size_t i = 0; i < ranges.Length(); i += 2) {
|
||||
startPage = std::max(1, std::min(startPage, ranges[i]));
|
||||
endPage = std::min(printData->mNumPrintablePages,
|
||||
std::max(endPage, ranges[i + 1]));
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -12,6 +12,7 @@ print test-print-selection.html test-text-ref.html
|
||||
print test-print-selection-shadow-dom.html test-text-ref.html
|
||||
print test-print-selection-iframe.html test-text-ref.html
|
||||
print test-print-range.html test-print-range-ref.html
|
||||
print test-print-range-complex.html test-print-range-complex-ref.html
|
||||
fails print test-print-single-page.html test-print-single-page-noref.html
|
||||
print test-async-print.html test-text-ref.html
|
||||
fails print test-unexpected-text.html test-unexpected-text-noref.html
|
||||
|
12
layout/reftests/printing/test-print-range-complex-ref.html
Normal file
12
layout/reftests/printing/test-print-range-complex-ref.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link href="print.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<p>This text should appear on page 1</p>
|
||||
<p>This text should appear on page 2</p>
|
||||
<p>This text should appear on page 3</p>
|
||||
</body>
|
||||
</html>
|
15
layout/reftests/printing/test-print-range-complex.html
Normal file
15
layout/reftests/printing/test-print-range-complex.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html reftest-print-range="2-2,4-5">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link href="print.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<p>This text should not be here</p>
|
||||
<p>This text should appear on page 1</p>
|
||||
<p>This text should not be here</p>
|
||||
<p>This text should appear on page 2</p>
|
||||
<p>This text should appear on page 3</p>
|
||||
<p>This text should not be here</p>
|
||||
</body>
|
||||
</html>
|
@ -274,7 +274,7 @@ function printToPdf() {
|
||||
if (printRange) {
|
||||
if (printRange === 'selection') {
|
||||
isPrintSelection = true;
|
||||
} else if (!/^[1-9]\d*-[1-9]\d*$/.test(printRange)) {
|
||||
} else if (!printRange.split(',').every(range => /^[1-9]\d*-[1-9]\d*$/.test(range))) {
|
||||
SendException("invalid value for reftest-print-range");
|
||||
return;
|
||||
}
|
||||
|
@ -1702,10 +1702,10 @@ function RecvStartPrint(isPrintSelection, printRange)
|
||||
ps.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
|
||||
ps.printSelectionOnly = isPrintSelection;
|
||||
if (printRange) {
|
||||
ps.printRange = Ci.nsIPrintSettings.kRangeSpecifiedPageRange;
|
||||
let range = printRange.split('-');
|
||||
ps.startPageRange = +range[0] || 1;
|
||||
ps.endPageRange = +range[1] || 1;
|
||||
ps.pageRanges = printRange.split(',').map(function(r) {
|
||||
let range = r.split('-');
|
||||
return [+range[0] || 1, +range[1] || 1]
|
||||
}).flat();
|
||||
}
|
||||
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
|
@ -98,11 +98,7 @@ class PrintingChild extends JSWindowActorChild {
|
||||
BrowsingContext.get(data.browsingContextId),
|
||||
data.simplifiedMode,
|
||||
data.changingBrowsers,
|
||||
data.lastUsedPrinterName,
|
||||
data.outputFormat,
|
||||
data.startPageRange,
|
||||
data.endPageRange,
|
||||
data.printRange
|
||||
data.lastUsedPrinterName
|
||||
);
|
||||
break;
|
||||
}
|
||||
@ -332,11 +328,7 @@ class PrintingChild extends JSWindowActorChild {
|
||||
browsingContext,
|
||||
simplifiedMode,
|
||||
changingBrowsers,
|
||||
lastUsedPrinterName,
|
||||
outputFormat,
|
||||
startPageRange,
|
||||
endPageRange,
|
||||
printRange
|
||||
lastUsedPrinterName
|
||||
) {
|
||||
const { docShell } = this;
|
||||
|
||||
@ -350,16 +342,6 @@ class PrintingChild extends JSWindowActorChild {
|
||||
false
|
||||
);
|
||||
|
||||
if (outputFormat == printSettings.kOutputFormatPDF) {
|
||||
printSettings.outputFormat = printSettings.kOutputFormatPDF;
|
||||
printSettings.printToFile = true;
|
||||
}
|
||||
|
||||
// TODO: waiting on the print preview to be updated in Bug 1659005
|
||||
printSettings.startPageRange = startPageRange;
|
||||
printSettings.endPageRange = endPageRange;
|
||||
printSettings.printRange = printRange;
|
||||
|
||||
// If we happen to be on simplified mode, we need to set docURL in order
|
||||
// to generate header/footer content correctly, since simplified tab has
|
||||
// "about:blank" as its URI.
|
||||
|
@ -148,11 +148,7 @@ var PrintEventHandler = {
|
||||
|
||||
// These settings do not have an associated pref value or flag, but
|
||||
// changing them requires us to update the print preview.
|
||||
_nonFlaggedUpdatePreviewSettings: new Set([
|
||||
"printAllOrCustomRange",
|
||||
"startPageRange",
|
||||
"endPageRange",
|
||||
]),
|
||||
_nonFlaggedUpdatePreviewSettings: new Set(["pageRanges"]),
|
||||
|
||||
async init() {
|
||||
Services.telemetry.scalarAdd("printing.preview_opened_tm", 1);
|
||||
@ -1178,11 +1174,6 @@ var PrintSettingsViewProxy = {
|
||||
name => !!target[name]
|
||||
);
|
||||
|
||||
case "printAllOrCustomRange":
|
||||
return target.printRange == Ci.nsIPrintSettings.kRangeAllPages
|
||||
? "all"
|
||||
: "custom";
|
||||
|
||||
case "supportsColor":
|
||||
return this.availablePrinters[target.printerName].supportsColor;
|
||||
|
||||
@ -1271,13 +1262,6 @@ var PrintSettingsViewProxy = {
|
||||
}
|
||||
break;
|
||||
|
||||
case "printAllOrCustomRange":
|
||||
target.printRange =
|
||||
value == "all"
|
||||
? Ci.nsIPrintSettings.kRangeAllPages
|
||||
: Ci.nsIPrintSettings.kRangeSpecifiedPageRange;
|
||||
break;
|
||||
|
||||
case "customMargins":
|
||||
if (value != null) {
|
||||
for (let [settingName, newVal] of Object.entries(value)) {
|
||||
@ -1779,14 +1763,14 @@ class PageRangeInput extends PrintUIControlMixin(HTMLElement) {
|
||||
|
||||
updatePageRange() {
|
||||
this.dispatchSettingsChange({
|
||||
printAllOrCustomRange: this._rangePicker.value,
|
||||
startPageRange: this._startRange.value,
|
||||
endPageRange: this._endRange.value,
|
||||
pageRanges: this._rangePicker.value
|
||||
? [this._startRange.value, this._endRange.value]
|
||||
: [],
|
||||
});
|
||||
}
|
||||
|
||||
update(settings) {
|
||||
this.toggleAttribute("all-pages", settings.printRange == 0);
|
||||
this.toggleAttribute("all-pages", !settings.pageRanges.length);
|
||||
}
|
||||
|
||||
handleEvent(e) {
|
||||
@ -1832,8 +1816,7 @@ class PageRangeInput extends PrintUIControlMixin(HTMLElement) {
|
||||
|
||||
if (this._startRange.validity.valid && this._endRange.validity.valid) {
|
||||
this.dispatchSettingsChange({
|
||||
startPageRange: this._startRange.value,
|
||||
endPageRange: this._endRange.value,
|
||||
pageRanges: [this._startRange.value, this._endRange.value],
|
||||
});
|
||||
this._rangeError.hidden = true;
|
||||
this._startRangeOverflowError.hidden = true;
|
||||
|
@ -39,8 +39,7 @@ add_task(async function testRangeResetAfterScale() {
|
||||
helper.resolvePrint();
|
||||
});
|
||||
helper.assertPrintedWithSettings({
|
||||
startPageRange: 1,
|
||||
endPageRange: 1,
|
||||
pageRanges: [1, 1],
|
||||
scaling: 0.1,
|
||||
});
|
||||
});
|
||||
@ -56,8 +55,8 @@ add_task(async function testInvalidRangeResetAfterDestinationChange() {
|
||||
let startPageRange = helper.get("custom-range-start");
|
||||
|
||||
await helper.assertSettingsChanged(
|
||||
{ printRange: 0 },
|
||||
{ printRange: 1 },
|
||||
{ pageRanges: [] },
|
||||
{ pageRanges: [1, 1] },
|
||||
async () => {
|
||||
await helper.waitForPreview(() => changeAllToCustom(helper));
|
||||
}
|
||||
@ -65,7 +64,7 @@ add_task(async function testInvalidRangeResetAfterDestinationChange() {
|
||||
|
||||
let rangeError = helper.get("error-invalid-start-range-overflow");
|
||||
|
||||
await helper.assertSettingsNotChanged({ startPageRange: 1 }, async () => {
|
||||
await helper.assertSettingsNotChanged({ pageRanges: [1, 1] }, async () => {
|
||||
ok(rangeError.hidden, "Range error is hidden");
|
||||
await helper.text(startPageRange, "9");
|
||||
await BrowserTestUtils.waitForAttributeRemoval("hidden", rangeError);
|
||||
|
@ -109,9 +109,7 @@ add_task(async function testSheetCountPageRange() {
|
||||
// Set page range to 2-3, sheet count should be 2.
|
||||
await helper.waitForPreview(() =>
|
||||
helper.dispatchSettingsChange({
|
||||
printRange: helper.settings.kRangeSpecifiedPageRange,
|
||||
startPageRange: 2,
|
||||
endPageRange: 3,
|
||||
pageRanges: [2, 3],
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -302,17 +302,28 @@ class PrintHelper {
|
||||
return this.win.PrintEventHandler.viewSettings;
|
||||
}
|
||||
|
||||
_assertMatches(a, b, msg) {
|
||||
if (Array.isArray(a)) {
|
||||
is(a.length, b.length, msg);
|
||||
for (let i = 0; i < a.length; ++i) {
|
||||
this._assertMatches(a[i], b[i], msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
is(a, b, msg);
|
||||
}
|
||||
|
||||
assertSettingsMatch(expected) {
|
||||
let { settings } = this;
|
||||
for (let [setting, value] of Object.entries(expected)) {
|
||||
is(settings[setting], value, `${setting} matches`);
|
||||
this._assertMatches(settings[setting], value, `${setting} matches`);
|
||||
}
|
||||
}
|
||||
|
||||
assertPrintedWithSettings(expected) {
|
||||
ok(this._printedSettings, "Printed settings have been recorded");
|
||||
for (let [setting, value] of Object.entries(expected)) {
|
||||
is(
|
||||
this._assertMatches(
|
||||
this._printedSettings[setting],
|
||||
value,
|
||||
`${setting} matches printed setting`
|
||||
|
@ -15,8 +15,6 @@ struct CStringKeyValue {
|
||||
|
||||
struct PrintData {
|
||||
nullable PRemotePrintJob remotePrintJob;
|
||||
int32_t startPageRange;
|
||||
int32_t endPageRange;
|
||||
double edgeTop;
|
||||
double edgeLeft;
|
||||
double edgeBottom;
|
||||
@ -36,7 +34,7 @@ struct PrintData {
|
||||
bool showMarginGuides;
|
||||
bool isPrintSelectionRBEnabled;
|
||||
bool printSelectionOnly;
|
||||
short printRange;
|
||||
int32_t[] pageRanges;
|
||||
nsString title;
|
||||
nsString docURL;
|
||||
nsString headerStrLeft;
|
||||
|
@ -221,13 +221,21 @@ NSPrintInfo* nsPrintSettingsX::CreateOrCopyPrintInfo(bool aWithScaling) {
|
||||
// if the caller explicitly asked for it.
|
||||
[printInfo setScalingFactor:CGFloat(aWithScaling ? mScaling : 1.0f)];
|
||||
|
||||
BOOL allPages = mPrintRange == nsIPrintSettings::kRangeAllPages ? YES : NO;
|
||||
const bool allPages = mPageRanges.IsEmpty();
|
||||
|
||||
NSMutableDictionary* dict = [printInfo dictionary];
|
||||
[dict setObject:[NSNumber numberWithInt:mNumCopies] forKey:NSPrintCopies];
|
||||
[dict setObject:[NSNumber numberWithBool:allPages] forKey:NSPrintAllPages];
|
||||
[dict setObject:[NSNumber numberWithInt:mStartPageNum] forKey:NSPrintFirstPage];
|
||||
[dict setObject:[NSNumber numberWithInt:mEndPageNum] forKey:NSPrintLastPage];
|
||||
|
||||
int32_t start = 1;
|
||||
int32_t end = 1;
|
||||
for (size_t i = 0; i < mPageRanges.Length(); i += 2) {
|
||||
start = std::min(start, mPageRanges[i]);
|
||||
end = std::max(end, mPageRanges[i + 1]);
|
||||
}
|
||||
|
||||
[dict setObject:[NSNumber numberWithInt:start] forKey:NSPrintFirstPage];
|
||||
[dict setObject:[NSNumber numberWithInt:end] forKey:NSPrintLastPage];
|
||||
|
||||
NSURL* jobSavingURL = nullptr;
|
||||
if (!mToFileName.IsEmpty()) {
|
||||
@ -359,11 +367,11 @@ void nsPrintSettingsX::SetFromPrintInfo(NSPrintInfo* aPrintInfo, bool aAdoptPrin
|
||||
nsCocoaUtils::GetStringForNSString([aPrintInfo jobDisposition], mDisposition);
|
||||
|
||||
mNumCopies = [[dict objectForKey:NSPrintCopies] intValue];
|
||||
mPrintRange = [[dict objectForKey:NSPrintAllPages] boolValue]
|
||||
? nsIPrintSettings::kRangeAllPages
|
||||
: nsIPrintSettings::kRangeSpecifiedPageRange;
|
||||
mStartPageNum = [[dict objectForKey:NSPrintFirstPage] intValue];
|
||||
mEndPageNum = [[dict objectForKey:NSPrintLastPage] intValue];
|
||||
mPageRanges.Clear();
|
||||
if (![[dict objectForKey:NSPrintAllPages] boolValue]) {
|
||||
mPageRanges.AppendElement([[dict objectForKey:NSPrintFirstPage] intValue]);
|
||||
mPageRanges.AppendElement([[dict objectForKey:NSPrintLastPage] intValue]);
|
||||
}
|
||||
|
||||
NSDictionary* printSettings = [aPrintInfo printSettings];
|
||||
NSNumber* value = [printSettings objectForKey:@"com_apple_print_PrintSettings_PMDuplexing"];
|
||||
|
@ -48,7 +48,7 @@ nsPrintSettingsGTK::nsPrintSettingsGTK()
|
||||
}
|
||||
|
||||
already_AddRefed<nsIPrintSettings> CreatePlatformPrintSettings(
|
||||
const PrintSettingsInitializer& aSettings) {
|
||||
const mozilla::PrintSettingsInitializer& aSettings) {
|
||||
RefPtr<nsPrintSettings> settings = new nsPrintSettingsGTK();
|
||||
settings->InitWithInitializer(aSettings);
|
||||
settings->SetDefaultFileName();
|
||||
@ -204,91 +204,26 @@ NS_IMETHODIMP nsPrintSettingsGTK::GetOutputFormat(int16_t* aOutputFormat) {
|
||||
* from the GTK objects rather than our own variables.
|
||||
*/
|
||||
|
||||
NS_IMETHODIMP nsPrintSettingsGTK::GetPrintRange(int16_t* aPrintRange) {
|
||||
NS_ENSURE_ARG_POINTER(aPrintRange);
|
||||
|
||||
GtkPrintPages gtkRange = gtk_print_settings_get_print_pages(mPrintSettings);
|
||||
if (gtkRange == GTK_PRINT_PAGES_RANGES)
|
||||
*aPrintRange = kRangeSpecifiedPageRange;
|
||||
else
|
||||
*aPrintRange = kRangeAllPages;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsPrintSettingsGTK::SetPrintRange(int16_t aPrintRange) {
|
||||
if (aPrintRange == kRangeSpecifiedPageRange)
|
||||
gtk_print_settings_set_print_pages(mPrintSettings, GTK_PRINT_PAGES_RANGES);
|
||||
else
|
||||
gtk_print_settings_set_print_pages(mPrintSettings, GTK_PRINT_PAGES_ALL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettingsGTK::GetStartPageRange(int32_t* aStartPageRange) {
|
||||
gint ctRanges;
|
||||
GtkPageRange* lstRanges =
|
||||
gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
|
||||
|
||||
// Make sure we got a range.
|
||||
if (ctRanges < 1) {
|
||||
*aStartPageRange = 1;
|
||||
} else {
|
||||
// GTK supports multiple page ranges; gecko only supports 1. So find
|
||||
// the lowest start page.
|
||||
int32_t start(lstRanges[0].start);
|
||||
for (gint ii = 1; ii < ctRanges; ii++) {
|
||||
start = std::min(lstRanges[ii].start, start);
|
||||
}
|
||||
*aStartPageRange = start + 1;
|
||||
nsPrintSettingsGTK::SetPageRanges(const nsTArray<int32_t>& aRanges) {
|
||||
if (aRanges.Length() % 2 != 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
g_free(lstRanges);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettingsGTK::SetStartPageRange(int32_t aStartPageRange) {
|
||||
int32_t endRange;
|
||||
GetEndPageRange(&endRange);
|
||||
gtk_print_settings_set_print_pages(
|
||||
mPrintSettings,
|
||||
aRanges.IsEmpty() ? GTK_PRINT_PAGES_ALL : GTK_PRINT_PAGES_RANGES);
|
||||
|
||||
GtkPageRange gtkRange;
|
||||
gtkRange.start = aStartPageRange - 1;
|
||||
gtkRange.end = endRange - 1;
|
||||
|
||||
gtk_print_settings_set_page_ranges(mPrintSettings, >kRange, 1);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettingsGTK::GetEndPageRange(int32_t* aEndPageRange) {
|
||||
gint ctRanges;
|
||||
GtkPageRange* lstRanges =
|
||||
gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
|
||||
|
||||
if (ctRanges < 1) {
|
||||
*aEndPageRange = 1;
|
||||
} else {
|
||||
int32_t end(lstRanges[0].end);
|
||||
for (gint ii = 1; ii < ctRanges; ii++) {
|
||||
end = std::max(lstRanges[ii].end, end);
|
||||
}
|
||||
*aEndPageRange = end + 1;
|
||||
nsTArray<GtkPageRange> ranges;
|
||||
ranges.SetCapacity(aRanges.Length() / 2);
|
||||
for (size_t i = 0; i < aRanges.Length(); i += 2) {
|
||||
GtkPageRange* gtkRange = ranges.AppendElement();
|
||||
gtkRange->start = aRanges[i] - 1;
|
||||
gtkRange->end = aRanges[i + 1] - 1;
|
||||
}
|
||||
|
||||
g_free(lstRanges);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettingsGTK::SetEndPageRange(int32_t aEndPageRange) {
|
||||
int32_t startRange;
|
||||
GetStartPageRange(&startRange);
|
||||
|
||||
GtkPageRange gtkRange;
|
||||
gtkRange.start = startRange - 1;
|
||||
gtkRange.end = aEndPageRange - 1;
|
||||
|
||||
gtk_print_settings_set_page_ranges(mPrintSettings, >kRange, 1);
|
||||
|
||||
gtk_print_settings_set_page_ranges(mPrintSettings, ranges.Elements(),
|
||||
ranges.Length());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -406,7 +341,7 @@ nsPrintSettingsGTK::GetPrinterName(nsAString& aPrinter) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
CopyUTF8toUTF16(MakeStringSpan(gtkPrintName), aPrinter);
|
||||
CopyUTF8toUTF16(mozilla::MakeStringSpan(gtkPrintName), aPrinter);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -668,18 +603,22 @@ nsPrintSettingsGTK::SetupSilentPrinting() {
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettingsGTK::GetPageRanges(nsTArray<int32_t>& aPages) {
|
||||
GtkPrintPages gtkRange = gtk_print_settings_get_print_pages(mPrintSettings);
|
||||
if (gtkRange != GTK_PRINT_PAGES_RANGES) {
|
||||
aPages.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
gint ctRanges;
|
||||
GtkPageRange* lstRanges =
|
||||
gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
|
||||
|
||||
aPages.Clear();
|
||||
|
||||
if (ctRanges > 1) {
|
||||
for (gint i = 0; i < ctRanges; i++) {
|
||||
aPages.AppendElement(lstRanges[i].start + 1);
|
||||
aPages.AppendElement(lstRanges[i].end + 1);
|
||||
}
|
||||
}
|
||||
|
||||
g_free(lstRanges);
|
||||
return NS_OK;
|
||||
|
@ -46,16 +46,6 @@ class nsPrintSettingsGTK : public nsPrintSettings {
|
||||
GtkPrinter* GetGtkPrinter() { return mGTKPrinter; };
|
||||
void SetGtkPrinter(GtkPrinter* aPrinter);
|
||||
|
||||
// If not printing the selection, this is stored in the GtkPrintSettings.
|
||||
NS_IMETHOD GetPrintRange(int16_t* aPrintRange) override;
|
||||
NS_IMETHOD SetPrintRange(int16_t aPrintRange) override;
|
||||
|
||||
// The page range is stored as as single range in the GtkPrintSettings object.
|
||||
NS_IMETHOD GetStartPageRange(int32_t* aStartPageRange) override;
|
||||
NS_IMETHOD SetStartPageRange(int32_t aStartPageRange) override;
|
||||
NS_IMETHOD GetEndPageRange(int32_t* aEndPageRange) override;
|
||||
NS_IMETHOD SetEndPageRange(int32_t aEndPageRange) override;
|
||||
|
||||
// Reversed, color, orientation and file name are all stored in the
|
||||
// GtkPrintSettings. Orientation is also stored in the GtkPageSetup and its
|
||||
// setting takes priority when getting the orientation.
|
||||
@ -109,7 +99,8 @@ class nsPrintSettingsGTK : public nsPrintSettings {
|
||||
|
||||
NS_IMETHOD SetupSilentPrinting() override;
|
||||
|
||||
NS_IMETHOD GetPageRanges(nsTArray<int32_t>& aPages) override;
|
||||
NS_IMETHOD SetPageRanges(const nsTArray<int32_t>&) override;
|
||||
NS_IMETHOD GetPageRanges(nsTArray<int32_t>&) override;
|
||||
|
||||
NS_IMETHOD GetResolution(int32_t* aResolution) override;
|
||||
NS_IMETHOD SetResolution(int32_t aResolution) override;
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
native nsNativeIntMargin(nsIntMargin);
|
||||
[ref] native nsNativeIntMarginRef(nsIntMargin);
|
||||
[ref] native IntegerArray(nsTArray<int32_t>);
|
||||
|
||||
interface nsIPrintSession;
|
||||
|
||||
@ -62,10 +61,6 @@ interface nsIPrintSettings : nsISupports
|
||||
|
||||
const unsigned long kInitSaveAll = 0xFFFFFFFF;
|
||||
|
||||
/* Print Range Enums */
|
||||
const long kRangeAllPages = 0;
|
||||
const long kRangeSpecifiedPageRange = 1;
|
||||
|
||||
/* Justification Enums */
|
||||
const long kJustLeft = 0;
|
||||
const long kJustCenter = 1;
|
||||
@ -118,9 +113,6 @@ interface nsIPrintSettings : nsISupports
|
||||
*/
|
||||
[noscript] attribute nsIPrintSession printSession; /* We hold a weak reference */
|
||||
|
||||
attribute long startPageRange;
|
||||
attribute long endPageRange;
|
||||
|
||||
/**
|
||||
* The edge measurements define the positioning of the headers
|
||||
* and footers on the page. They're treated as an offset from the edges of
|
||||
@ -167,8 +159,6 @@ interface nsIPrintSettings : nsISupports
|
||||
/** Whether to only print the selected nodes */
|
||||
[infallible] attribute boolean printSelectionOnly;
|
||||
|
||||
attribute short printRange;
|
||||
|
||||
attribute AString title;
|
||||
attribute AString docURL;
|
||||
|
||||
@ -270,9 +260,13 @@ interface nsIPrintSettings : nsISupports
|
||||
* ranges (start, end), must not overlap and must be in the
|
||||
* (startPageRange, endPageRange) scope.
|
||||
*
|
||||
* If there are no print ranges the aPages array is cleared.
|
||||
* If there are no print ranges the aPages array is empty.
|
||||
*/
|
||||
[noscript] void GetPageRanges(in IntegerArray aPages);
|
||||
attribute Array<long> pageRanges;
|
||||
|
||||
%{C++
|
||||
static bool IsPageSkipped(int32_t aPageNum, const nsTArray<int32_t>& aRanges);
|
||||
%}
|
||||
};
|
||||
|
||||
%{ C++
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "nsPrintSettingsImpl.h"
|
||||
|
||||
#include "prenv.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsPaper.h"
|
||||
#include "nsReadableUtils.h"
|
||||
@ -16,10 +17,7 @@
|
||||
NS_IMPL_ISUPPORTS(nsPrintSettings, nsIPrintSettings)
|
||||
|
||||
nsPrintSettings::nsPrintSettings()
|
||||
: mPrintRange(kRangeAllPages),
|
||||
mStartPageNum(1),
|
||||
mEndPageNum(1),
|
||||
mScaling(1.0),
|
||||
: mScaling(1.0),
|
||||
mPrintBGColors(false),
|
||||
mPrintBGImages(false),
|
||||
mIsCancelled(false),
|
||||
@ -103,6 +101,7 @@ NS_IMETHODIMP nsPrintSettings::GetPrintSession(
|
||||
NS_ADDREF(*aPrintSession);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintSettings::SetPrintSession(nsIPrintSession* aPrintSession) {
|
||||
// Clearing it by passing nullptr is not allowed. That's why we
|
||||
// use a weak ref so that it doesn't have to be cleared.
|
||||
@ -118,28 +117,7 @@ NS_IMETHODIMP nsPrintSettings::SetPrintSession(nsIPrintSession* aPrintSession) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintSettings::GetStartPageRange(int32_t* aStartPageRange) {
|
||||
// NS_ENSURE_ARG_POINTER(aStartPageRange);
|
||||
*aStartPageRange = mStartPageNum;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsPrintSettings::SetStartPageRange(int32_t aStartPageRange) {
|
||||
mStartPageNum = aStartPageRange;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintSettings::GetEndPageRange(int32_t* aEndPageRange) {
|
||||
// NS_ENSURE_ARG_POINTER(aEndPageRange);
|
||||
*aEndPageRange = mEndPageNum;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsPrintSettings::SetEndPageRange(int32_t aEndPageRange) {
|
||||
mEndPageNum = aEndPageRange;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintSettings::GetPrintReversed(bool* aPrintReversed) {
|
||||
// NS_ENSURE_ARG_POINTER(aPrintReversed);
|
||||
*aPrintReversed = mPrintReversed;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -149,7 +127,6 @@ NS_IMETHODIMP nsPrintSettings::SetPrintReversed(bool aPrintReversed) {
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintSettings::GetPrintInColor(bool* aPrintInColor) {
|
||||
// NS_ENSURE_ARG_POINTER(aPrintInColor);
|
||||
*aPrintInColor = mPrintInColor;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -159,7 +136,6 @@ NS_IMETHODIMP nsPrintSettings::SetPrintInColor(bool aPrintInColor) {
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintSettings::GetOrientation(int32_t* aOrientation) {
|
||||
NS_ENSURE_ARG_POINTER(aOrientation);
|
||||
*aOrientation = mOrientation;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -453,16 +429,6 @@ NS_IMETHODIMP nsPrintSettings::SetPrintBGImages(bool aPrintBGImages) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintSettings::GetPrintRange(int16_t* aPrintRange) {
|
||||
NS_ENSURE_ARG_POINTER(aPrintRange);
|
||||
*aPrintRange = mPrintRange;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsPrintSettings::SetPrintRange(int16_t aPrintRange) {
|
||||
mPrintRange = aPrintRange;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintSettings::GetTitle(nsAString& aTitle) {
|
||||
aTitle = mTitle;
|
||||
return NS_OK;
|
||||
@ -732,11 +698,37 @@ nsPrintSettings::GetEffectivePageSize(double* aWidth, double* aHeight) {
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettings::GetPageRanges(nsTArray<int32_t>& aPages) {
|
||||
aPages.Clear();
|
||||
nsPrintSettings::SetPageRanges(const nsTArray<int32_t>& aPages) {
|
||||
// Needs to be a set of (start, end) pairs.
|
||||
if (aPages.Length() % 2 != 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mPageRanges = aPages.Clone();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettings::GetPageRanges(nsTArray<int32_t>& aPages) {
|
||||
aPages = mPageRanges.Clone();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsIPrintSettings::IsPageSkipped(int32_t aPageNum,
|
||||
const nsTArray<int32_t>& aRanges) {
|
||||
MOZ_RELEASE_ASSERT(aRanges.Length() % 2 == 0);
|
||||
if (aRanges.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < aRanges.Length(); i += 2) {
|
||||
if (aRanges[i] <= aPageNum && aPageNum <= aRanges[i + 1]) {
|
||||
// The page is included in this piece of the custom range,
|
||||
// so it's not skipped.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult nsPrintSettings::_Clone(nsIPrintSettings** _retval) {
|
||||
RefPtr<nsPrintSettings> printSettings = new nsPrintSettings(*this);
|
||||
printSettings.forget(_retval);
|
||||
@ -767,15 +759,13 @@ nsPrintSettings& nsPrintSettings::operator=(const nsPrintSettings& rhs) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
mStartPageNum = rhs.mStartPageNum;
|
||||
mEndPageNum = rhs.mEndPageNum;
|
||||
mPageRanges = rhs.mPageRanges.Clone();
|
||||
mMargin = rhs.mMargin;
|
||||
mEdge = rhs.mEdge;
|
||||
mUnwriteableMargin = rhs.mUnwriteableMargin;
|
||||
mScaling = rhs.mScaling;
|
||||
mPrintBGColors = rhs.mPrintBGColors;
|
||||
mPrintBGImages = rhs.mPrintBGImages;
|
||||
mPrintRange = rhs.mPrintRange;
|
||||
mTitle = rhs.mTitle;
|
||||
mURL = rhs.mURL;
|
||||
mIsCancelled = rhs.mIsCancelled;
|
||||
|
@ -78,10 +78,8 @@ class nsPrintSettings : public nsIPrintSettings {
|
||||
nsIntMargin mEdge;
|
||||
nsIntMargin mUnwriteableMargin;
|
||||
|
||||
// scriptable data members
|
||||
int16_t mPrintRange;
|
||||
int32_t mStartPageNum; // only used for ePrintRange_SpecifiedRange
|
||||
int32_t mEndPageNum;
|
||||
nsTArray<int32_t> mPageRanges;
|
||||
|
||||
double mScaling;
|
||||
bool mPrintBGColors; // print background colors
|
||||
bool mPrintBGImages; // print background images
|
||||
|
@ -91,8 +91,7 @@ nsPrintSettingsService::SerializeToPrintData(nsIPrintSettings* aSettings,
|
||||
data->remotePrintJobChild() = session->GetRemotePrintJob();
|
||||
}
|
||||
|
||||
aSettings->GetStartPageRange(&data->startPageRange());
|
||||
aSettings->GetEndPageRange(&data->endPageRange());
|
||||
aSettings->GetPageRanges(data->pageRanges());
|
||||
|
||||
aSettings->GetEdgeTop(&data->edgeTop());
|
||||
aSettings->GetEdgeLeft(&data->edgeLeft());
|
||||
@ -118,8 +117,6 @@ nsPrintSettingsService::SerializeToPrintData(nsIPrintSettings* aSettings,
|
||||
data->isPrintSelectionRBEnabled() = aSettings->GetIsPrintSelectionRBEnabled();
|
||||
data->printSelectionOnly() = aSettings->GetPrintSelectionOnly();
|
||||
|
||||
aSettings->GetPrintRange(&data->printRange());
|
||||
|
||||
aSettings->GetTitle(data->title());
|
||||
aSettings->GetDocURL(data->docURL());
|
||||
|
||||
@ -180,8 +177,8 @@ nsPrintSettingsService::DeserializeToPrintSettings(const PrintData& data,
|
||||
session->SetRemotePrintJob(
|
||||
static_cast<RemotePrintJobChild*>(data.remotePrintJobChild()));
|
||||
}
|
||||
settings->SetStartPageRange(data.startPageRange());
|
||||
settings->SetEndPageRange(data.endPageRange());
|
||||
|
||||
settings->SetPageRanges(data.pageRanges());
|
||||
|
||||
settings->SetEdgeTop(data.edgeTop());
|
||||
settings->SetEdgeLeft(data.edgeLeft());
|
||||
@ -205,7 +202,6 @@ nsPrintSettingsService::DeserializeToPrintSettings(const PrintData& data,
|
||||
settings->SetShowMarginGuides(data.showMarginGuides());
|
||||
settings->SetIsPrintSelectionRBEnabled(data.isPrintSelectionRBEnabled());
|
||||
settings->SetPrintSelectionOnly(data.printSelectionOnly());
|
||||
settings->SetPrintRange(data.printRange());
|
||||
|
||||
settings->SetTitle(data.title());
|
||||
settings->SetDocURL(data.docURL());
|
||||
|
@ -219,19 +219,24 @@ static nsresult ShowNativePrintDialog(HWND aHWnd,
|
||||
prntdlg.Flags |= PD_NOSELECTION;
|
||||
}
|
||||
|
||||
int16_t printRangeType = nsIPrintSettings::kRangeAllPages;
|
||||
aPrintSettings->GetPrintRange(&printRangeType);
|
||||
// if there is a specified page range then enable the "Custom" radio button
|
||||
if (printRangeType == nsIPrintSettings::kRangeSpecifiedPageRange) {
|
||||
nsTArray<int32_t> pageRanges;
|
||||
aPrintSettings->GetPageRanges(pageRanges);
|
||||
|
||||
// If there is a specified page range then enable the "Custom" radio button
|
||||
if (!pageRanges.IsEmpty()) {
|
||||
prntdlg.Flags |= PD_PAGENUMS;
|
||||
}
|
||||
|
||||
int32_t pg = 1;
|
||||
aPrintSettings->GetStartPageRange(&pg);
|
||||
prntdlg.nFromPage = pg;
|
||||
// TODO(emilio): Can we represent all the page ranges instead?
|
||||
int32_t start = 1;
|
||||
int32_t end = 1;
|
||||
for (size_t i = 0; i < pageRanges.Length(); i += 2) {
|
||||
start = std::min(start, pageRanges[i]);
|
||||
end = std::max(end, pageRanges[i + 1]);
|
||||
}
|
||||
|
||||
aPrintSettings->GetEndPageRange(&pg);
|
||||
prntdlg.nToPage = pg;
|
||||
prntdlg.nFromPage = start;
|
||||
prntdlg.nToPage = end;
|
||||
|
||||
prntdlg.nMinPage = 1;
|
||||
prntdlg.nMaxPage = 0xFFFF;
|
||||
@ -303,13 +308,14 @@ static nsresult ShowNativePrintDialog(HWND aHWnd,
|
||||
aPrintSettings->SetPrinterName(nsDependentString(device));
|
||||
aPrintSettings->SetPrintSelectionOnly(prntdlg.Flags & PD_SELECTION);
|
||||
|
||||
nsTArray<int32_t> pageRanges;
|
||||
if (prntdlg.Flags & PD_PAGENUMS) {
|
||||
aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSpecifiedPageRange);
|
||||
aPrintSettings->SetStartPageRange(prntdlg.nFromPage);
|
||||
aPrintSettings->SetEndPageRange(prntdlg.nToPage);
|
||||
} else { // (prntdlg.Flags & PD_ALLPAGES)
|
||||
aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages);
|
||||
pageRanges.AppendElement(prntdlg.nFromPage);
|
||||
pageRanges.AppendElement(prntdlg.nToPage);
|
||||
} else {
|
||||
// (prntdlg.Flags & PD_ALLPAGES)
|
||||
}
|
||||
aPrintSettings->SetPageRanges(pageRanges);
|
||||
|
||||
// Unlock DeviceNames
|
||||
::GlobalUnlock(prntdlg.hDevNames);
|
||||
|
Loading…
Reference in New Issue
Block a user