mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-11-16 01:21:16 +01:00
Merge babd115ca7 into be824b126f
This commit is contained in:
commit
58ffa02663
@ -27,6 +27,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest;
|
||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.common.util.ExceptionUtils;
|
||||
import stirling.software.common.util.FormUtils;
|
||||
import stirling.software.common.util.GeneralUtils;
|
||||
import stirling.software.common.util.WebResponseUtils;
|
||||
@ -49,26 +50,113 @@ public class MultiPageLayoutController {
|
||||
public ResponseEntity<byte[]> mergeMultiplePagesIntoOne(
|
||||
@ModelAttribute MergeMultiplePagesRequest request) throws IOException {
|
||||
|
||||
int pagesPerSheet = request.getPagesPerSheet();
|
||||
MultipartFile file = request.getFileInput();
|
||||
boolean addBorder = Boolean.TRUE.equals(request.getAddBorder());
|
||||
int MAX_PAGES = 100000;
|
||||
int MAX_COLS = 300;
|
||||
int MAX_ROWS = 300;
|
||||
|
||||
if (pagesPerSheet != 2
|
||||
&& pagesPerSheet != 3
|
||||
&& pagesPerSheet != (int) Math.sqrt(pagesPerSheet) * Math.sqrt(pagesPerSheet)) {
|
||||
throw new IllegalArgumentException("pagesPerSheet must be 2, 3 or a perfect square");
|
||||
String mode = request.getMode();
|
||||
if (mode == null || mode.trim().isEmpty()) {
|
||||
mode = "DEFAULT";
|
||||
}
|
||||
|
||||
int cols =
|
||||
int rows;
|
||||
int cols;
|
||||
int pagesPerSheet;
|
||||
switch (mode) {
|
||||
case "DEFAULT":
|
||||
pagesPerSheet = request.getPagesPerSheet();
|
||||
if (pagesPerSheet != 2
|
||||
&& pagesPerSheet != 3
|
||||
&& pagesPerSheet
|
||||
!= (int) Math.sqrt(pagesPerSheet) * Math.sqrt(pagesPerSheet)) {
|
||||
throw ExceptionUtils.createIllegalArgumentException(
|
||||
"error.invalidFormat",
|
||||
"Invalid {0} format: {1}",
|
||||
"pagesPerSheet",
|
||||
"only 2, 3, and perfect squares are supported");
|
||||
}
|
||||
|
||||
cols =
|
||||
pagesPerSheet == 2 || pagesPerSheet == 3
|
||||
? pagesPerSheet
|
||||
: (int) Math.sqrt(pagesPerSheet);
|
||||
int rows = pagesPerSheet == 2 || pagesPerSheet == 3 ? 1 : (int) Math.sqrt(pagesPerSheet);
|
||||
rows =
|
||||
pagesPerSheet == 2 || pagesPerSheet == 3
|
||||
? 1
|
||||
: (int) Math.sqrt(pagesPerSheet);
|
||||
break;
|
||||
case "CUSTOM":
|
||||
rows = request.getRows();
|
||||
cols = request.getCols();
|
||||
if (rows <= 0 || cols <= 0) {
|
||||
throw ExceptionUtils.createIllegalArgumentException(
|
||||
"error.invalidFormat",
|
||||
"Invalid {0} format: {1}",
|
||||
"rows and cols",
|
||||
"only strictly positive values are allowed");
|
||||
}
|
||||
pagesPerSheet = cols * rows;
|
||||
break;
|
||||
default:
|
||||
throw ExceptionUtils.createIllegalArgumentException(
|
||||
"error.invalidFormat",
|
||||
"Invalid {0} format: {1}",
|
||||
"mode",
|
||||
"only 'DEFAULT' and 'CUSTOM' are supported");
|
||||
}
|
||||
|
||||
if (pagesPerSheet > MAX_PAGES) {
|
||||
throw ExceptionUtils.createIllegalArgumentException(
|
||||
"error.invalidArgument",
|
||||
"Invalid {0} format: {1}",
|
||||
"pagesPerSheet",
|
||||
"must be less than " + MAX_PAGES);
|
||||
}
|
||||
if (cols > MAX_COLS) {
|
||||
throw ExceptionUtils.createIllegalArgumentException(
|
||||
"error.invalidArgument",
|
||||
"Invalid {0} format: {1}",
|
||||
"cols",
|
||||
"must be less than " + MAX_COLS);
|
||||
}
|
||||
if (rows > MAX_ROWS) {
|
||||
throw ExceptionUtils.createIllegalArgumentException(
|
||||
"error.invalidArgument",
|
||||
"Invalid {0} format: {1}",
|
||||
"rows",
|
||||
"must be less than " + MAX_ROWS);
|
||||
}
|
||||
|
||||
MultipartFile file = request.getFileInput();
|
||||
String orientation = request.getOrientation();
|
||||
if (orientation == null || orientation.trim().isEmpty()) {
|
||||
orientation = "PORTRAIT";
|
||||
}
|
||||
if (!"PORTRAIT".equals(orientation) && !"LANDSCAPE".equals(orientation)) {
|
||||
throw ExceptionUtils.createIllegalArgumentException(
|
||||
"error.invalidFormat",
|
||||
"Invalid {0} format: {1}",
|
||||
"orientation",
|
||||
"only 'PORTRAIT' and 'LANDSCAPE' are supported");
|
||||
}
|
||||
String pageOrder = request.getPageOrder();
|
||||
if (pageOrder == null || pageOrder.trim().isEmpty()) {
|
||||
pageOrder = "LR_TD";
|
||||
}
|
||||
|
||||
boolean addBorder = Boolean.TRUE.equals(request.getAddBorder());
|
||||
|
||||
PDDocument sourceDocument = pdfDocumentFactory.load(file);
|
||||
PDDocument newDocument =
|
||||
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||
PDPage newPage = new PDPage(PDRectangle.A4);
|
||||
|
||||
// Create a new A4 landscape rectangle that we use when orientation is landscape
|
||||
PDRectangle a4Landscape =
|
||||
new PDRectangle(PDRectangle.A4.getHeight(), PDRectangle.A4.getWidth());
|
||||
PDPage newPage =
|
||||
"PORTRAIT".equals(orientation)
|
||||
? new PDPage(PDRectangle.A4)
|
||||
: new PDPage(a4Landscape);
|
||||
newDocument.addPage(newPage);
|
||||
|
||||
int totalPages = sourceDocument.getNumberOfPages();
|
||||
@ -88,7 +176,10 @@ public class MultiPageLayoutController {
|
||||
if (i != 0 && i % pagesPerSheet == 0) {
|
||||
// Close the current content stream and create a new page and content stream
|
||||
contentStream.close();
|
||||
newPage = new PDPage(PDRectangle.A4);
|
||||
newPage =
|
||||
"PORTRAIT".equals(orientation)
|
||||
? new PDPage(PDRectangle.A4)
|
||||
: new PDPage(a4Landscape);
|
||||
newDocument.addPage(newPage);
|
||||
contentStream =
|
||||
new PDPageContentStream(
|
||||
@ -108,8 +199,36 @@ public class MultiPageLayoutController {
|
||||
int adjustedPageIndex =
|
||||
i % pagesPerSheet; // Close the current content stream and create a new
|
||||
// page and content stream
|
||||
int rowIndex = adjustedPageIndex / cols;
|
||||
int colIndex = adjustedPageIndex % cols;
|
||||
int rowIndex;
|
||||
int colIndex;
|
||||
|
||||
switch (pageOrder) {
|
||||
case "LR_TD": // Left→Right, then Top→Down
|
||||
rowIndex = adjustedPageIndex / cols;
|
||||
colIndex = adjustedPageIndex % cols;
|
||||
break;
|
||||
|
||||
case "RL_TD": // Right→Left, then Top→Down
|
||||
rowIndex = adjustedPageIndex / cols;
|
||||
colIndex = cols - 1 - (adjustedPageIndex % cols);
|
||||
break;
|
||||
|
||||
case "TD_LR": // Top→Down, then Left→Right
|
||||
colIndex = adjustedPageIndex / rows;
|
||||
rowIndex = adjustedPageIndex % rows;
|
||||
break;
|
||||
|
||||
case "TD_RL": // Top→Down, then Right→Left
|
||||
colIndex = cols - 1 - (adjustedPageIndex / rows);
|
||||
rowIndex = adjustedPageIndex % rows;
|
||||
break;
|
||||
default:
|
||||
throw ExceptionUtils.createIllegalArgumentException(
|
||||
"error.invalidFormat",
|
||||
"Invalid {0} format: {1}",
|
||||
"pageOrder",
|
||||
"only 'LR_TD', 'RL_TD', 'TD_LR', and 'TD_RL' are supported");
|
||||
}
|
||||
|
||||
float x = colIndex * cellWidth + (cellWidth - rect.getWidth() * scale) / 2;
|
||||
float y =
|
||||
@ -139,7 +258,7 @@ public class MultiPageLayoutController {
|
||||
|
||||
// If any source page is rotated, skip form copying/transformation entirely
|
||||
boolean hasRotation = FormUtils.hasAnyRotatedPage(sourceDocument);
|
||||
if (hasRotation) {
|
||||
if (hasRotation || "LANDSCAPE".equals(orientation)) {
|
||||
log.info("Source document has rotated pages; skipping form field copying.");
|
||||
} else {
|
||||
try {
|
||||
|
||||
@ -10,15 +10,53 @@ import stirling.software.common.model.api.PDFFile;
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class MergeMultiplePagesRequest extends PDFFile {
|
||||
@Schema(
|
||||
description = "Input mode: DEFAULT uses pagesPerSheet; CUSTOM uses explicit cols×rows.",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED,
|
||||
type = "string",
|
||||
defaultValue = "DEFAULT",
|
||||
allowableValues = {"DEFAULT", "CUSTOM"})
|
||||
private String mode;
|
||||
|
||||
@Schema(
|
||||
description = "The number of pages to fit onto a single sheet in the output PDF.",
|
||||
type = "number",
|
||||
defaultValue = "2",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED,
|
||||
allowableValues = {"2", "3", "4", "9", "16"})
|
||||
private int pagesPerSheet;
|
||||
|
||||
@Schema(
|
||||
description = "Options for the ordering of pages",
|
||||
type = "string",
|
||||
defaultValue = "LR_TD",
|
||||
allowableValues = {"LR_TD", "RL_TD", "TD_LR", "TD_RL"})
|
||||
private String pageOrder;
|
||||
|
||||
@Schema(
|
||||
description = "Number of rows",
|
||||
type = "number",
|
||||
defaultValue = "1",
|
||||
maximum = "300",
|
||||
minimum = "1",
|
||||
example = "3")
|
||||
private Integer rows;
|
||||
|
||||
@Schema(
|
||||
description = "Number of columns",
|
||||
type = "number",
|
||||
defaultValue = "2",
|
||||
maximum = "300",
|
||||
minimum = "1",
|
||||
example = "2")
|
||||
private Integer cols;
|
||||
|
||||
@Schema(
|
||||
description = "The orientation of the output PDF pages",
|
||||
type = "string",
|
||||
defaultValue = "PORTRAIT",
|
||||
allowableValues = {"PORTRAIT", "LANDSCAPE"})
|
||||
private String orientation;
|
||||
|
||||
@Schema(description = "Boolean for if you wish to add border around the pages")
|
||||
private Boolean addBorder;
|
||||
}
|
||||
|
||||
@ -1166,7 +1166,20 @@ pipeline.title=Pipeline
|
||||
#pageLayout
|
||||
pageLayout.title=Multi Page Layout
|
||||
pageLayout.header=Multi Page Layout
|
||||
pageLayout.mode=Mode
|
||||
pageLayout.custom=Custom
|
||||
pageLayout.pagesPerSheet=Pages per sheet:
|
||||
pageLayout.rows=Rows
|
||||
pageLayout.columns=Columns
|
||||
pageLayout.advancedSettings=Advanced settings
|
||||
pageLayout.pageOrder=Page order :
|
||||
pageLayout.leftRightTopDown=Left -> Right, then Top -> Bottom
|
||||
pageLayout.rightLeftTopDown=Right -> Left, then Top -> Bottom
|
||||
pageLayout.topDownLeftRight=Top -> Bottom, then Left -> Right
|
||||
pageLayout.topDownRightLeft=Top -> Bottom, then Right -> Left
|
||||
pageLayout.orientation=Orientation :
|
||||
pageLayout.portrait=Portrait
|
||||
pageLayout.landscape=Landscape
|
||||
pageLayout.addBorder=Add Borders
|
||||
pageLayout.submit=Submit
|
||||
|
||||
|
||||
@ -616,6 +616,10 @@ home.cbrToPdf.title=CBR to PDF
|
||||
home.cbrToPdf.desc=Convert CBR comic book archives to PDF format.
|
||||
cbrToPdf.tags=conversion,comic,book,archive,cbr,rar
|
||||
|
||||
home.ebookToPdf.title=eBook to PDF
|
||||
home.ebookToPdf.desc=Convert eBook files (EPUB, MOBI, AZW3, FB2, TXT, DOCX) to PDF using Calibre.
|
||||
ebookToPdf.tags=conversion,ebook,calibre,epub,mobi,azw3
|
||||
|
||||
home.pdfToCbz.title=PDF to CBZ
|
||||
home.pdfToCbz.desc=Convert PDF files to CBZ comic book archives.
|
||||
pdfToCbz.tags=conversion,comic,book,archive,cbz,pdf
|
||||
@ -1162,7 +1166,20 @@ pipeline.title=Pipeline
|
||||
#pageLayout
|
||||
pageLayout.title=Multi Page Layout
|
||||
pageLayout.header=Multi Page Layout
|
||||
pageLayout.mode=Mode
|
||||
pageLayout.custom=Custom
|
||||
pageLayout.pagesPerSheet=Pages per sheet:
|
||||
pageLayout.rows=Rows
|
||||
pageLayout.columns=Columns
|
||||
pageLayout.advancedSettings=Advanced settings
|
||||
pageLayout.pageOrder=Page order :
|
||||
pageLayout.leftRightTopDown=Left -> Right, then Top -> Bottom
|
||||
pageLayout.rightLeftTopDown=Right -> Left, then Top -> Bottom
|
||||
pageLayout.topDownLeftRight=Top -> Bottom, then Left -> Right
|
||||
pageLayout.topDownRightLeft=Top -> Bottom, then Right -> Left
|
||||
pageLayout.orientation=Orientation :
|
||||
pageLayout.portrait=Portrait
|
||||
pageLayout.landscape=Landscape
|
||||
pageLayout.addBorder=Add Borders
|
||||
pageLayout.submit=Submit
|
||||
|
||||
@ -1490,6 +1507,17 @@ cbrToPDF.submit=Convert to PDF
|
||||
cbrToPDF.selectText=Select CBR file
|
||||
cbrToPDF.optimizeForEbook=Optimize PDF for ebook readers (uses Ghostscript)
|
||||
|
||||
#ebookToPDF
|
||||
ebookToPDF.title=eBook to PDF
|
||||
ebookToPDF.header=eBook to PDF
|
||||
ebookToPDF.submit=Convert to PDF
|
||||
ebookToPDF.selectText=Select eBook file
|
||||
ebookToPDF.embedAllFonts=Embed all fonts in the output PDF (may increase file size)
|
||||
ebookToPDF.includeTableOfContents=Add a generated table of contents to the PDF
|
||||
ebookToPDF.includePageNumbers=Add page numbers to the generated PDF
|
||||
ebookToPDF.optimizeForEbook=Optimize PDF for ebook readers (uses Ghostscript)
|
||||
ebookToPDF.calibreDisabled=Calibre support is disabled. Enable the Calibre tool group or install Calibre to use this feature.
|
||||
|
||||
#pdfToCBR
|
||||
pdfToCBR.title=PDF to CBR
|
||||
pdfToCBR.header=PDF to CBR
|
||||
|
||||
@ -616,6 +616,10 @@ home.cbrToPdf.title=CBR en PDF
|
||||
home.cbrToPdf.desc=Convertissez une archive de bande dessinée CBR en PDF.
|
||||
cbrToPdf.tags=bande dessinée,convertir,conversion,comic,book,archive,cbr,rar
|
||||
|
||||
home.ebookToPdf.title=eBook to PDF
|
||||
home.ebookToPdf.desc=Convert eBook files (EPUB, MOBI, AZW3, FB2, TXT, DOCX) to PDF using Calibre.
|
||||
ebookToPdf.tags=conversion,ebook,calibre,epub,mobi,azw3
|
||||
|
||||
home.pdfToCbz.title=PDF en CBZ
|
||||
home.pdfToCbz.desc=Convertissez un fichier PDF en archive de bande dessinée CBZ.
|
||||
pdfToCbz.tags=bande dessinée,convertir,conversion,comic,book,archive,cbz,pdf
|
||||
@ -1162,7 +1166,20 @@ pipeline.title=Pipeline
|
||||
#pageLayout
|
||||
pageLayout.title=Fusionner des pages
|
||||
pageLayout.header=Fusionner des pages
|
||||
pageLayout.mode=Mode
|
||||
pageLayout.custom=Custom
|
||||
pageLayout.pagesPerSheet=Pages par feuille
|
||||
pageLayout.rows=Rows
|
||||
pageLayout.columns=Columns
|
||||
pageLayout.advancedSettings=Advanced settings
|
||||
pageLayout.pageOrder=Page order :
|
||||
pageLayout.leftRightTopDown=Left -> Right, then Top -> Bottom
|
||||
pageLayout.rightLeftTopDown=Right -> Left, then Top -> Bottom
|
||||
pageLayout.topDownLeftRight=Top -> Bottom, then Left -> Right
|
||||
pageLayout.topDownRightLeft=Top -> Bottom, then Right -> Left
|
||||
pageLayout.orientation=Orientation :
|
||||
pageLayout.portrait=Portrait
|
||||
pageLayout.landscape=Paysage
|
||||
pageLayout.addBorder=Ajouter des bordures
|
||||
pageLayout.submit=Fusionner
|
||||
|
||||
@ -1490,6 +1507,17 @@ cbrToPDF.submit=Convertir en PDF
|
||||
cbrToPDF.selectText=Sélectionnez un fichier CBR
|
||||
cbrToPDF.optimizeForEbook=Optimiser un PDF pour une liseuse (utilise Ghostscript)
|
||||
|
||||
#ebookToPDF
|
||||
ebookToPDF.title=eBook to PDF
|
||||
ebookToPDF.header=eBook to PDF
|
||||
ebookToPDF.submit=Convert to PDF
|
||||
ebookToPDF.selectText=Select eBook file
|
||||
ebookToPDF.embedAllFonts=Embed all fonts in the output PDF (may increase file size)
|
||||
ebookToPDF.includeTableOfContents=Add a generated table of contents to the PDF
|
||||
ebookToPDF.includePageNumbers=Add page numbers to the generated PDF
|
||||
ebookToPDF.optimizeForEbook=Optimize PDF for ebook readers (uses Ghostscript)
|
||||
ebookToPDF.calibreDisabled=Calibre support is disabled. Enable the Calibre tool group or install Calibre to use this feature.
|
||||
|
||||
#pdfToCBR
|
||||
pdfToCBR.title=PDF en CBR
|
||||
pdfToCBR.header=PDF en CBR
|
||||
|
||||
@ -18,9 +18,13 @@
|
||||
</div>
|
||||
<form id="multiPdfForm" th:action="@{'/api/v1/general/multi-page-layout'}" method="post" enctype="multipart/form-data">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check mb-3">
|
||||
<input type="checkbox" id="modeCustom">
|
||||
<label for="modeCustom" th:text="#{pageLayout.custom}"></label>
|
||||
</div>
|
||||
<div id="defaultSection" class="mb-3" style="border:1px solid #eee; padding:1em; border-radius:8px; margin-bottom:1em;">
|
||||
<label for="pagesPerSheet" th:text="#{pageLayout.pagesPerSheet}"></label>
|
||||
<select class="form-control" id="pagesPerSheet" name="pagesPerSheet">
|
||||
<select class="form-control" id="pagesPerSheet" name="pagesPerSheet" required>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
@ -28,12 +32,91 @@
|
||||
<option value="16">16</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="customSection" class="mb-3" style="border:1px solid #eee; padding:1em; border-radius:8px; margin-bottom:1em;">
|
||||
<div class="mb-3">
|
||||
<label for="rows" th:text="#{pageLayout.rows}"></label>
|
||||
<input class="form-control" type="number" id="rows" name="rows" step="1" min="1" max="300" value="1" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="cols" th:text="#{pageLayout.columns}"></label>
|
||||
<input class="form-control" type="number" id="cols" name="cols" step="1" min="1" max="300" value="1" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-check mb-3">
|
||||
<input id="advancedSettingsToggle" type="checkbox">
|
||||
<label for="advancedSettingsToggle" th:text="#{pageLayout.advancedSettings}"></label>
|
||||
</div>
|
||||
<div id="advancedSettings" style="display:none; border:1px solid #eee; padding:1em; border-radius:8px; margin-bottom:1em;">
|
||||
<div class="mb-3">
|
||||
<label for="pageOrder" th:text="#{pageLayout.pageOrder}"></label>
|
||||
<select class="form-control" id="pageOrder" name="pageOrder">
|
||||
<option value="LR_TD" th:text="#{pageLayout.leftRightTopDown}"></option>
|
||||
<option value="RL_TD" th:text="#{pageLayout.rightLeftTopDown}"></option>
|
||||
<option value="TD_LR" th:text="#{pageLayout.topDownLeftRight}"></option>
|
||||
<option value="TD_RL" th:text="#{pageLayout.topDownRightLeft}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="orientation" th:text="#{pageLayout.orientation}"></label>
|
||||
<select class="form-control" id="orientation" name="orientation">
|
||||
<option value="PORTRAIT" th:text="#{pageLayout.portrait}"></option>
|
||||
<option value="LANDSCAPE" th:text="#{pageLayout.landscape}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-check mb-3">
|
||||
<input id="addBorder" name="addBorder" type="checkbox">
|
||||
<label for="addBorder" th:text="#{pageLayout.addBorder}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pageLayout.submit}"></button>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
const modeCheckbox = document.getElementById('modeCustom');
|
||||
const defaultSection = document.getElementById('defaultSection');
|
||||
const customSection = document.getElementById('customSection');
|
||||
const pagesPerSheet = document.getElementById('pagesPerSheet');
|
||||
const rowsInput = document.getElementById('rows');
|
||||
const colsInput = document.getElementById('cols');
|
||||
|
||||
function sync() {
|
||||
const mode = modeCheckbox.checked? 'CUSTOM' : 'DEFAULT';
|
||||
const isDefault = mode === 'DEFAULT';
|
||||
|
||||
// Enable/disable relevant fields
|
||||
pagesPerSheet.disabled = !isDefault;
|
||||
rowsInput.disabled = isDefault;
|
||||
colsInput.disabled = isDefault;
|
||||
|
||||
if (isDefault) {
|
||||
defaultSection.style.display = 'block'; // show Default
|
||||
customSection.style.display = 'none'; // hide Custom
|
||||
} else {
|
||||
defaultSection.style.display = 'none'; // hide Default
|
||||
customSection.style.display = 'block'; // show Custom
|
||||
}
|
||||
}
|
||||
|
||||
modeCheckbox.addEventListener('change', sync);
|
||||
|
||||
// Show/hide advanced settings
|
||||
const advancedToggle = document.getElementById('advancedSettingsToggle');
|
||||
const advancedSettings = document.getElementById('advancedSettings');
|
||||
|
||||
if (advancedToggle && advancedSettings) {
|
||||
advancedToggle.addEventListener('change', function() {
|
||||
advancedSettings.style.display = this.checked ? 'block' : 'none';
|
||||
advancedSettings.querySelector('#addBorder').checked = false;
|
||||
advancedSettings.querySelector('#pageOrder').value = 'LR_TD';
|
||||
advancedSettings.querySelector('#orientation').value = 'PORTRAIT';
|
||||
});
|
||||
}
|
||||
// initial state
|
||||
sync();
|
||||
})();
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user