File indexing completed on 2024-04-28 04:32:06

0001 /*
0002  * Copyright (C) 2010-2015 by Stephen Allewell
0003  * steve.allewell@gmail.com
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation; either version 2 of the License, or
0008  * (at your option) any later version.
0009  */
0010 
0011 #include "PrintSetupDlg.h"
0012 
0013 #include <math.h>
0014 
0015 #include <QColorDialog>
0016 #include <QFontDialog>
0017 #include <QHideEvent>
0018 #include <QInputDialog>
0019 #include <QMargins>
0020 #include <QMenu>
0021 #include <QPainter>
0022 #include <QPrinter>
0023 #include <QShowEvent>
0024 
0025 #include <KHelpClient>
0026 #include <KLocalizedString>
0027 #include <KMessageBox>
0028 #include <kwidgetsaddons_version.h>
0029 
0030 #include "Document.h"
0031 #include "Element.h"
0032 #include "ImageElementDlg.h"
0033 #include "KeyElementDlg.h"
0034 #include "Page.h"
0035 #include "PageLayoutEditor.h"
0036 #include "PagePropertiesDlg.h"
0037 #include "PaperSizes.h"
0038 #include "PatternElementDlg.h"
0039 #include "TextElementDlg.h"
0040 
0041 static const double zoomFactors[] = {0.25, 0.5, 1.0, 1.5, 2.0, 4.0, 8.0, 16.0};
0042 
0043 PrintSetupDlg::PrintSetupDlg(QWidget *parent, Document *document, QPrinter *printer)
0044     : QDialog(parent)
0045     , m_printerConfiguration(document->printerConfiguration())
0046     , m_elementUnderCursor(nullptr)
0047     , m_document(document)
0048     , m_printer(printer)
0049 {
0050     setWindowModality(Qt::WindowModal);
0051 
0052     setWindowTitle(i18n("Print Setup"));
0053 
0054     ui.setupUi(this);
0055     m_pageLayoutEditor = new PageLayoutEditor(ui.PagePreview, m_document);
0056     ui.PagePreview->setWidget(m_pageLayoutEditor);
0057 
0058     ui.AddPage->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
0059     ui.InsertPage->setIcon(QIcon::fromTheme(QStringLiteral("document-import")));
0060     ui.DeletePage->setIcon(QIcon::fromTheme(QStringLiteral("document-close")));
0061     ui.SelectElement->setIcon(QIcon::fromTheme(QStringLiteral("edit-select")));
0062     ui.TextElement->setIcon(QIcon::fromTheme(QStringLiteral("insert-text")));
0063     ui.PatternElement->setIcon(QIcon::fromTheme(QStringLiteral("insert-table")));
0064     ui.ImageElement->setIcon(QIcon::fromTheme(QStringLiteral("insert-image")));
0065     ui.KeyElement->setIcon(QIcon::fromTheme(QStringLiteral("documentation")));
0066 
0067     m_buttonGroup.addButton(ui.SelectElement);
0068     m_buttonGroup.addButton(ui.TextElement);
0069     m_buttonGroup.addButton(ui.PatternElement);
0070     m_buttonGroup.addButton(ui.ImageElement);
0071     m_buttonGroup.addButton(ui.KeyElement);
0072     m_buttonGroup.setExclusive(true);
0073 
0074     for (QPageSize::PageSizeId id : PageSizes::sizesForPrint()) {
0075         ui.PageSize->addItem(QPageSize::name(id), id);
0076     }
0077 
0078     connect(m_pageLayoutEditor, &PageLayoutEditor::selectionMade, this, &PrintSetupDlg::selectionMade);
0079     connect(m_pageLayoutEditor, &PageLayoutEditor::elementGeometryChanged, this, &PrintSetupDlg::elementGeometryChanged);
0080     connect(m_pageLayoutEditor, &PageLayoutEditor::customContextMenuRequested, this, &PrintSetupDlg::previewContextMenuRequested);
0081 
0082     ui.PageSize->setCurrentIndex(Configuration::page_Size());
0083     ui.Orientation->setCurrentIndex(Configuration::page_Orientation());
0084     ui.Zoom->setCurrentIndex(4); // 200%
0085     ui.SelectElement->click(); // select mode
0086 }
0087 
0088 PrintSetupDlg::~PrintSetupDlg()
0089 {
0090     delete m_pageLayoutEditor;
0091 }
0092 
0093 const PrinterConfiguration &PrintSetupDlg::printerConfiguration() const
0094 {
0095     return m_printerConfiguration;
0096 }
0097 
0098 void PrintSetupDlg::hideEvent(QHideEvent *event)
0099 {
0100     KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("DialogSizes")).writeEntry(QStringLiteral("PrintSetupDlg"), size());
0101 
0102     QDialog::hideEvent(event);
0103 }
0104 
0105 void PrintSetupDlg::showEvent(QShowEvent *event)
0106 {
0107     QDialog::showEvent(event);
0108 
0109     if (KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("DialogSizes")).hasKey(QStringLiteral("PrintSetupDlg"))) {
0110         resize(KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("DialogSizes")).readEntry(QStringLiteral("PrintSetupDlg"), QSize()));
0111     }
0112 
0113     if (ui.Pages->count() == 0) {
0114         initialiseFromConfig();
0115     }
0116 
0117     if (ui.Pages->count()) {
0118         ui.Pages->setCurrentRow(0);
0119     } else {
0120         on_AddPage_clicked();
0121     }
0122 }
0123 
0124 void PrintSetupDlg::on_PageSize_currentIndexChanged(int pageSizeIndex)
0125 {
0126     if (ui.Pages->count() && ui.Pages->currentItem()) {
0127         PagePreviewListWidgetItem *pagePreview = static_cast<PagePreviewListWidgetItem *>(ui.Pages->currentItem());
0128         pagePreview->setPageSize(QPageSize(ui.PageSize->itemData(pageSizeIndex).value<QPageSize::PageSizeId>()));
0129         m_pageLayoutEditor->updatePagePreview();
0130         ui.Pages->repaint();
0131     }
0132 }
0133 
0134 void PrintSetupDlg::on_Orientation_currentIndexChanged(int orientation)
0135 {
0136     if (ui.Pages->count() && ui.Pages->currentItem()) {
0137         PagePreviewListWidgetItem *pagePreview = static_cast<PagePreviewListWidgetItem *>(ui.Pages->currentItem());
0138         pagePreview->setOrientation((orientation == 0) ? QPageLayout::Portrait : QPageLayout::Landscape);
0139         m_pageLayoutEditor->updatePagePreview();
0140         ui.Pages->repaint();
0141     }
0142 }
0143 
0144 void PrintSetupDlg::on_Zoom_currentIndexChanged(int zoomIndex)
0145 {
0146     m_pageLayoutEditor->setZoomFactor(zoomFactors[zoomIndex]);
0147     m_pageLayoutEditor->updatePagePreview();
0148 }
0149 
0150 void PrintSetupDlg::on_Pages_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
0151 {
0152     Q_UNUSED(previous);
0153 
0154     if (current) {
0155         PagePreviewListWidgetItem *pagePreview = static_cast<PagePreviewListWidgetItem *>(current);
0156         m_pageLayoutEditor->setPagePreview(pagePreview);
0157         ui.PageSize->setCurrentIndex(ui.PageSize->findData(pagePreview->pageSize().id()));
0158         ui.Orientation->setCurrentIndex((pagePreview->orientation() == QPageLayout::Portrait) ? 0 : 1);
0159         ui.InsertPage->setEnabled(true);
0160         ui.DeletePage->setEnabled(true);
0161     } else {
0162         m_pageLayoutEditor->setPagePreview(nullptr);
0163         ui.InsertPage->setEnabled(false);
0164         ui.DeletePage->setEnabled(false);
0165     }
0166 }
0167 
0168 void PrintSetupDlg::on_AddPage_clicked()
0169 {
0170     Page *page = new Page(selectedPageSize(), selectedOrientation());
0171     m_printerConfiguration.addPage(page);
0172     addPage(ui.Pages->count(), page);
0173 }
0174 
0175 void PrintSetupDlg::on_InsertPage_clicked()
0176 {
0177     Page *page = new Page(selectedPageSize(), selectedOrientation());
0178     m_printerConfiguration.insertPage(ui.Pages->currentRow(), page);
0179     addPage(ui.Pages->currentRow(), page);
0180 }
0181 
0182 void PrintSetupDlg::on_DeletePage_clicked()
0183 {
0184     if (ui.Pages->count() && ui.Pages->currentItem()) {
0185         int currentRow = ui.Pages->row(ui.Pages->currentItem());
0186         PagePreviewListWidgetItem *pagePreview = static_cast<PagePreviewListWidgetItem *>(ui.Pages->takeItem(currentRow));
0187         m_printerConfiguration.removePage(pagePreview->page());
0188         delete pagePreview->page();
0189         delete pagePreview;
0190 
0191         if (int rows = ui.Pages->count()) {
0192             ui.Pages->setCurrentRow(std::min(currentRow, rows - 1));
0193         } else {
0194             on_Pages_currentItemChanged(nullptr, nullptr);
0195         }
0196     }
0197 
0198     updatePageNumbers();
0199 }
0200 
0201 void PrintSetupDlg::on_SelectElement_clicked()
0202 {
0203     m_elementMode = Select;
0204     m_pageLayoutEditor->setSelecting(true);
0205 }
0206 
0207 void PrintSetupDlg::on_TextElement_clicked()
0208 {
0209     m_elementMode = Text;
0210     m_pageLayoutEditor->setSelecting(false);
0211 }
0212 
0213 void PrintSetupDlg::on_PatternElement_clicked()
0214 {
0215     m_elementMode = Pattern;
0216     m_pageLayoutEditor->setSelecting(false);
0217 }
0218 
0219 void PrintSetupDlg::on_ImageElement_clicked()
0220 {
0221     m_elementMode = Image;
0222     m_pageLayoutEditor->setSelecting(false);
0223 }
0224 
0225 void PrintSetupDlg::on_KeyElement_clicked()
0226 {
0227     m_elementMode = Key;
0228     m_pageLayoutEditor->setSelecting(false);
0229 }
0230 
0231 void PrintSetupDlg::on_DialogButtonBox_accepted()
0232 {
0233     accept();
0234 }
0235 
0236 void PrintSetupDlg::on_DialogButtonBox_rejected()
0237 {
0238     reject();
0239 }
0240 
0241 void PrintSetupDlg::on_DialogButtonBox_helpRequested()
0242 {
0243     KHelpClient::invokeHelp(QStringLiteral("PrinterDialog"), QStringLiteral("kxstitch"));
0244 }
0245 
0246 void PrintSetupDlg::selectionMade(const QRect &rectangle)
0247 {
0248     PagePreviewListWidgetItem *pagePreview = static_cast<PagePreviewListWidgetItem *>(ui.Pages->currentItem());
0249     Page *page = pagePreview->page();
0250 
0251     PatternElement *patternElement;
0252     ImageElement *imageElement;
0253 
0254     switch (m_elementMode) {
0255     case Text:
0256         page->addElement(new TextElement(page, rectangle));
0257         break;
0258 
0259     case Pattern:
0260         patternElement = new PatternElement(page, rectangle);
0261         page->addElement(patternElement);
0262         patternElement->setPatternRect(QRect(0, 0, m_document->pattern()->stitches().width(), m_document->pattern()->stitches().height()));
0263         break;
0264 
0265     case Image:
0266         imageElement = new ImageElement(page, rectangle);
0267         page->addElement(imageElement);
0268         imageElement->setPatternRect(QRect(0, 0, m_document->pattern()->stitches().width(), m_document->pattern()->stitches().height()));
0269         break;
0270 
0271     case Key:
0272         page->addElement(new KeyElement(page, rectangle));
0273         break;
0274 
0275     default:
0276         break;
0277     }
0278 
0279     pagePreview->generatePreviewIcon();
0280     m_pageLayoutEditor->update();
0281 
0282     ui.SelectElement->click(); // select mode
0283 }
0284 
0285 void PrintSetupDlg::elementGeometryChanged()
0286 {
0287     if (ui.Pages->currentItem()) {
0288         PagePreviewListWidgetItem *pagePreview = static_cast<PagePreviewListWidgetItem *>(ui.Pages->currentItem());
0289         pagePreview->generatePreviewIcon();
0290     }
0291 }
0292 
0293 void PrintSetupDlg::previewContextMenuRequested(const QPoint &pos)
0294 {
0295     PagePreviewListWidgetItem *pagePreview = static_cast<PagePreviewListWidgetItem *>(ui.Pages->currentItem());
0296 
0297     if (pagePreview) {
0298         m_elementUnderCursor = pagePreview->page()->itemAt(m_pageLayoutEditor->unscale(pos));
0299         QMenu *contextMenu = new QMenu(this);
0300 
0301         if (m_elementUnderCursor == nullptr || m_elementUnderCursor->type() != Element::Plan) {
0302             contextMenu->addAction(i18n("Properties"), this, &PrintSetupDlg::properties);
0303 
0304             if (m_elementUnderCursor) {
0305                 contextMenu->addSeparator();
0306                 contextMenu->addAction(i18n("Delete Element"), this, &PrintSetupDlg::deleteElement);
0307             }
0308         }
0309 
0310         if (contextMenu->isEmpty()) {
0311             delete contextMenu;
0312         } else {
0313             contextMenu->popup(m_pageLayoutEditor->mapToGlobal(pos));
0314         }
0315     }
0316 }
0317 
0318 void PrintSetupDlg::properties()
0319 {
0320     PagePreviewListWidgetItem *pagePreview = static_cast<PagePreviewListWidgetItem *>(ui.Pages->currentItem());
0321 
0322     bool updatePreviews = false;
0323 
0324     if (m_elementUnderCursor) {
0325         if (m_elementUnderCursor->type() == Element::Text) {
0326             QPointer<TextElementDlg> textElementDlg = new TextElementDlg(this, static_cast<TextElement *>(m_elementUnderCursor));
0327             updatePreviews = (textElementDlg->exec() == QDialog::Accepted);
0328             delete textElementDlg;
0329         }
0330 
0331         if (m_elementUnderCursor->type() == Element::Pattern) {
0332             QMap<int, QList<QRect>> patternRects;
0333             QListIterator<Page *> pageIterator(m_printerConfiguration.pages());
0334 
0335             while (pageIterator.hasNext()) {
0336                 Page *page = pageIterator.next();
0337                 QListIterator<Element *> elementIterator(page->elements());
0338 
0339                 while (elementIterator.hasNext()) {
0340                     Element *element = elementIterator.next();
0341 
0342                     if (element->type() == Element::Pattern) {
0343                         patternRects[page->pageNumber()].append(static_cast<PatternElement *>(element)->patternRect());
0344                     }
0345                 }
0346             }
0347 
0348             QPointer<PatternElementDlg> patternElementDlg =
0349                 new PatternElementDlg(this, static_cast<PatternElement *>(m_elementUnderCursor), m_document, patternRects);
0350 
0351             if (patternElementDlg->exec() == QDialog::Accepted) {
0352                 updatePreviews = true;
0353 
0354                 if (patternElementDlg->showPlan() && !pagePreview->page()->elements().contains(patternElementDlg->planElement())) {
0355                     pagePreview->page()->addElement(patternElementDlg->planElement());
0356                 } else if (!patternElementDlg->showPlan() && pagePreview->page()->elements().contains(patternElementDlg->planElement())) {
0357                     pagePreview->page()->removeElement(patternElementDlg->planElement());
0358                 }
0359             }
0360 
0361             delete patternElementDlg;
0362         }
0363 
0364         if (m_elementUnderCursor->type() == Element::Image) {
0365             QPointer<ImageElementDlg> imageElementDlg = new ImageElementDlg(this, static_cast<ImageElement *>(m_elementUnderCursor), m_document);
0366             updatePreviews = (imageElementDlg->exec() == QDialog::Accepted);
0367             delete imageElementDlg;
0368         }
0369 
0370         if (m_elementUnderCursor->type() == Element::Key) {
0371             QPointer<KeyElementDlg> keyElementDlg = new KeyElementDlg(this, static_cast<KeyElement *>(m_elementUnderCursor));
0372             updatePreviews = (keyElementDlg->exec() == QDialog::Accepted);
0373             delete keyElementDlg;
0374         }
0375     } else {
0376         QPointer<PagePropertiesDlg> pagePropertiesDlg =
0377             new PagePropertiesDlg(this, pagePreview->page()->margins().toMargins(), m_pageLayoutEditor->showGrid(), m_pageLayoutEditor->gridSize());
0378 
0379         if (pagePropertiesDlg->exec() == QDialog::Accepted) {
0380             updatePreviews = true;
0381             pagePreview->page()->setMargins(pagePropertiesDlg->margins());
0382             m_pageLayoutEditor->setShowGrid(pagePropertiesDlg->showGrid());
0383             m_pageLayoutEditor->setGridSize(pagePropertiesDlg->gridSize());
0384         }
0385     }
0386 
0387     if (updatePreviews) {
0388         PagePreviewListWidgetItem *pagePreview = static_cast<PagePreviewListWidgetItem *>(ui.Pages->currentItem());
0389         m_pageLayoutEditor->update();
0390         pagePreview->generatePreviewIcon();
0391     }
0392 }
0393 
0394 void PrintSetupDlg::deleteElement()
0395 {
0396     PagePreviewListWidgetItem *pagePreview = static_cast<PagePreviewListWidgetItem *>(ui.Pages->currentItem());
0397     pagePreview->page()->removeElement(m_elementUnderCursor);
0398     m_pageLayoutEditor->update();
0399     pagePreview->generatePreviewIcon();
0400 }
0401 
0402 void PrintSetupDlg::initialiseFromConfig()
0403 {
0404     QListIterator<Page *> pageIterator(m_printerConfiguration.pages());
0405 
0406     while (pageIterator.hasNext()) {
0407         addPage(ui.Pages->count(), pageIterator.next());
0408     }
0409 }
0410 
0411 void PrintSetupDlg::addPage(int position, Page *page)
0412 {
0413     PagePreviewListWidgetItem *pagePreview = new PagePreviewListWidgetItem(m_document, page);
0414     ui.Pages->insertItem(position, pagePreview);
0415     ui.Pages->setCurrentRow(position);
0416 
0417     updatePageNumbers();
0418 }
0419 
0420 QPageSize PrintSetupDlg::selectedPageSize()
0421 {
0422     return QPageSize(ui.PageSize->itemData(ui.PageSize->currentIndex()).value<QPageSize::PageSizeId>());
0423 }
0424 
0425 QPageLayout::Orientation PrintSetupDlg::selectedOrientation()
0426 {
0427     return (ui.Orientation->currentIndex() == 0) ? QPageLayout::Portrait : QPageLayout::Landscape;
0428 }
0429 
0430 double PrintSetupDlg::selectedZoom()
0431 {
0432     return zoomFactors[ui.Zoom->currentIndex()];
0433 }
0434 
0435 void PrintSetupDlg::updatePageNumbers()
0436 {
0437     for (int i = 0; i < ui.Pages->count(); ++i) {
0438         PagePreviewListWidgetItem *pagePreview = dynamic_cast<PagePreviewListWidgetItem *>(ui.Pages->item(i));
0439         pagePreview->setText(i18n("Page %1 of %2", pagePreview->page()->pageNumber(), ui.Pages->count()));
0440     }
0441 }
0442 
0443 void PrintSetupDlg::on_Templates_clicked()
0444 {
0445     //    QString templateName = qobject_cast<QAction *>(sender())->data().toString();
0446 
0447     bool okToCreate = true;
0448 
0449     if (!m_printerConfiguration.isEmpty()) {
0450 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
0451         okToCreate = (KMessageBox::questionTwoActions(this,
0452 #else
0453         okToCreate = (KMessageBox::questionYesNo(this,
0454 #endif
0455                                                       i18n("Overwrite the current configuration?"),
0456                                                       i18n("Overwrite"),
0457                                                       KStandardGuiItem::overwrite(),
0458                                                       KStandardGuiItem::cancel())
0459 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
0460                       == KMessageBox::PrimaryAction);
0461 #else
0462                       == KMessageBox::Yes);
0463 #endif
0464     }
0465 
0466     if (okToCreate) {
0467         // TODO this section is currently a hack to allow creation of a printerConfiguration
0468         // based on the KDE3 version of KXStitch.  It is intended to create a template based
0469         // functionality so that various templates can be created and selected as required.
0470 
0471         // clear the current configuration
0472         m_printerConfiguration = PrinterConfiguration();
0473         ui.Pages->clear();
0474         // create pages based on template
0475         // Cover sheet
0476         QFont titleFont;
0477         titleFont.setPointSize(16);
0478         QFont pageFont;
0479         pageFont.setPointSize(8);
0480 
0481         Page *page = new Page(QPageSize(QPageSize::A4), QPageLayout::Portrait);
0482         m_printerConfiguration.addPage(page);
0483         addPage(ui.Pages->count(), page);
0484 
0485         QRect printableArea(page->margins().left(),
0486                             page->margins().top(),
0487                             210 - page->margins().left() - page->margins().right(),
0488                             297 - page->margins().top() - page->margins().bottom());
0489         QRect headerTitleArea(printableArea.topLeft(), QSize(printableArea.width(), 10));
0490         QRect patternArea(headerTitleArea.bottomLeft() + QPoint(0, 5), QSize(printableArea.width(), printableArea.height() - 10 - 35));
0491         QRect mapArea(patternArea.bottomRight() - QPoint(30, 5), QSize(30, 30));
0492         QRect pageNumberArea(printableArea.bottomLeft() - QPoint(0, 10), QSize(printableArea.width(), 10));
0493 
0494         Element *element = new TextElement(page, QRect(printableArea.topLeft(), QSize(printableArea.width(), 30)));
0495         static_cast<TextElement *>(element)->setTextFont(titleFont);
0496         static_cast<TextElement *>(element)->setAlignment(Qt::AlignCenter);
0497         static_cast<TextElement *>(element)->setText(QStringLiteral("${title}"));
0498         page->addElement(element);
0499 
0500         element = new ImageElement(page, QRect(printableArea.topLeft() + QPoint(0, 60), QSize(printableArea.width(), printableArea.height() / 3)));
0501         static_cast<ImageElement *>(element)->setPatternRect(
0502             QRect(0, 0, m_document->pattern()->stitches().width(), m_document->pattern()->stitches().height()));
0503         static_cast<ImageElement *>(element)->setShowBorder(true);
0504         static_cast<ImageElement *>(element)->setBorderThickness(2);
0505         page->addElement(element);
0506 
0507         element =
0508             new TextElement(page, QRect(printableArea.topLeft() + QPoint(20, 60 + printableArea.height() / 3 + 5), QSize(printableArea.width() - 40, 60)));
0509         static_cast<TextElement *>(element)->setAlignment(Qt::AlignTop | Qt::AlignLeft);
0510         static_cast<TextElement *>(element)->setText(
0511             i18nc("Do not translate elements in ${...} which are substituted by properties",
0512                   "Created by ${author}\n(C) ${copyright}\n\nPattern Size: ${width.stitches} x ${height.stitches}\nFlosses from the ${scheme} range."));
0513         page->addElement(element);
0514 
0515         element = new TextElement(page, pageNumberArea);
0516         static_cast<TextElement *>(element)->setTextFont(pageFont);
0517         static_cast<TextElement *>(element)->setAlignment(Qt::AlignCenter);
0518         static_cast<TextElement *>(element)->setText(i18nc("Do not translate elements in ${...} which are substituted by properties", "Page ${page}"));
0519         page->addElement(element);
0520 
0521         // pattern sheets
0522         int documentWidth = m_document->pattern()->stitches().width();
0523         int documentHeight = m_document->pattern()->stitches().height();
0524 
0525         // calculate the aspect ratio and the size of the cells to fit within the rectangle and the overall paint area size
0526         double cellWidth = Configuration::patternElement_MinimumCellSize(); // mm
0527         double aspect =
0528             m_document->property(QStringLiteral("horizontalClothCount")).toDouble() / m_document->property(QStringLiteral("verticalClothCount")).toDouble();
0529         double cellHeight = cellWidth * aspect;
0530 
0531         if (cellHeight < cellWidth) {
0532             cellHeight = cellWidth;
0533             cellWidth = cellHeight / aspect;
0534         }
0535 
0536         // at this point, based on a minimum preferred cell size a physical width and height have been calculated
0537         // which can be used to calculate the number of pages wide and tall that the pattern needs to occupy
0538         // based on the size of the pattern area on the page.
0539         int horizontalCellsPerPage = int(double(patternArea.width()) / cellWidth);
0540         int verticalCellsPerPage = int(double(patternArea.height()) / cellHeight);
0541 
0542         int pagesWide =
0543             (documentWidth / horizontalCellsPerPage) + (((documentWidth % horizontalCellsPerPage) < Configuration::patternElement_MinimumOverflow()) ? 0 : 1);
0544         int pagesTall =
0545             (documentHeight / verticalCellsPerPage) + (((documentHeight % verticalCellsPerPage) < Configuration::patternElement_MinimumOverflow()) ? 0 : 1);
0546 
0547         // the number of pages wide and tall has been calculated based on the minimum cell size.
0548         // try and make use of the available space across the pages expanding the cell size to fill the space.
0549         horizontalCellsPerPage = (documentWidth / pagesWide) + ((documentWidth % pagesWide) ? 1 : 0); // equal number per page
0550         verticalCellsPerPage = (documentHeight / pagesTall) + ((documentHeight % pagesTall) ? 1 : 0); // equal number per page
0551 
0552         for (int verticalPage = 0; verticalPage < pagesTall; ++verticalPage) {
0553             for (int horizontalPage = 0; horizontalPage < pagesWide; ++horizontalPage) {
0554                 page = new Page(QPageSize(QPageSize::A4), QPageLayout::Portrait);
0555                 m_printerConfiguration.addPage(page);
0556                 addPage(ui.Pages->count(), page);
0557 
0558                 element = new TextElement(page, headerTitleArea);
0559                 static_cast<TextElement *>(element)->setTextFont(titleFont);
0560                 static_cast<TextElement *>(element)->setAlignment(Qt::AlignCenter);
0561                 static_cast<TextElement *>(element)->setText(QStringLiteral("${title}"));
0562                 page->addElement(element);
0563 
0564                 element = new PatternElement(page, patternArea);
0565                 static_cast<PatternElement *>(element)->setPatternRect(
0566                     QRect(horizontalPage * horizontalCellsPerPage,
0567                           verticalPage * verticalCellsPerPage,
0568                           std::min(horizontalCellsPerPage, documentWidth - (horizontalCellsPerPage * horizontalPage)),
0569                           std::min(verticalCellsPerPage, documentHeight - (verticalCellsPerPage * verticalPage))));
0570                 static_cast<PatternElement *>(element)->setShowScales(true);
0571                 static_cast<PatternElement *>(element)->setRenderStitchesAs(Configuration::EnumRenderer_RenderStitchesAs::BlackWhiteSymbols);
0572                 static_cast<PatternElement *>(element)->setRenderBackstitchesAs(Configuration::EnumRenderer_RenderBackstitchesAs::BlackWhiteSymbols);
0573                 static_cast<PatternElement *>(element)->setRenderKnotsAs(Configuration::EnumRenderer_RenderKnotsAs::BlackWhiteSymbols);
0574                 page->addElement(element);
0575 
0576                 element = new TextElement(page, pageNumberArea);
0577                 static_cast<TextElement *>(element)->setTextFont(pageFont);
0578                 static_cast<TextElement *>(element)->setAlignment(Qt::AlignCenter);
0579                 static_cast<TextElement *>(element)->setText(i18nc("Do not translate elements in ${...} which are substituted by properties", "Page ${page}"));
0580                 page->addElement(element);
0581             }
0582         }
0583 
0584         // key page
0585         page = new Page(QPageSize(QPageSize::A4), QPageLayout::Portrait);
0586         m_printerConfiguration.addPage(page);
0587         addPage(ui.Pages->count(), page);
0588 
0589         element = new TextElement(page, headerTitleArea);
0590         static_cast<TextElement *>(element)->setTextFont(titleFont);
0591         static_cast<TextElement *>(element)->setAlignment(Qt::AlignCenter);
0592         static_cast<TextElement *>(element)->setText(QStringLiteral("${title}"));
0593         page->addElement(element);
0594 
0595         element = new KeyElement(page, patternArea.adjusted(20, 0, -20, 0));
0596         page->addElement(element);
0597 
0598         element = new TextElement(page, pageNumberArea);
0599         static_cast<TextElement *>(element)->setTextFont(titleFont);
0600         static_cast<TextElement *>(element)->setAlignment(Qt::AlignCenter);
0601         static_cast<TextElement *>(element)->setText(i18nc("Do not translate elements in ${...} which are substituted by properties", "Page ${page}"));
0602         page->addElement(element);
0603 
0604         for (int i = 0; i < ui.Pages->count(); ++i) {
0605             static_cast<PagePreviewListWidgetItem *>(ui.Pages->item(i))->generatePreviewIcon();
0606         }
0607     }
0608 }
0609 
0610 #include "moc_PrintSetupDlg.cpp"