23 #include <QPrintDialog>
24 #include <QProgressDialog>
30 #include "ui_previewdialogbase.h"
36 class PagePreviewWidget :
public QWidget
40 PagePreviewWidget(
QWidget *parent =
nullptr)
46 void setPixmap(
const QPixmap &pixmap)
51 int pixmapWidth()
const {
return m_pixmap.width(); }
52 int pixmapHeight()
const {
return m_pixmap.height(); }
53 QSize pixmapSize()
const {
return m_pixmap.size(); }
56 void mouseMoved(
QPoint pos);
57 void mouseClicked(
QPoint pos);
60 QPoint pixmapOffset()
const
62 return QPoint((
width() - m_pixmap.width()) / 2, (
height() - m_pixmap.height()) / 2);
69 painter.drawPixmap(pixmapOffset(), m_pixmap);
74 Q_EMIT mouseMoved(ev->
pos() - pixmapOffset());
79 Q_EMIT mouseClicked(ev->
pos() - pixmapOffset());
86 class KDReports::PreviewWidgetPrivate :
public Ui::PreviewWidgetBase
95 QPixmap paintPreview(
int index)
const;
96 void printSelectedPages();
97 void setupComboBoxes();
98 void pageCountChanged();
101 void fillZoomCombo();
102 void updatePageButtons();
103 void updatePreview();
104 void pageNumberReturnPressed();
107 void handleMouseMove(
QPoint pos);
108 void handleMouseRelease(
QPoint pos);
109 void slotCurrentPageChanged();
110 void slotFirstPage();
114 void slotPaperSizeActivated(
int);
115 void slotPaperOrientationActivated(
int);
118 void slotZoomChanged();
119 void previewNextItems();
121 PagePreviewWidget *m_previewWidget;
123 qreal m_zoomFactor = 1.0;
124 qreal m_endlessPrinterWidth = 114.0;
129 int m_firstDirtyPreviewItem = -1;
130 bool m_eatPageNumberClick =
false;
131 bool m_onAnchor =
false;
135 : m_previewWidget(new PagePreviewWidget)
140 handleMouseMove(pos);
143 handleMouseRelease(pos);
147 void KDReports::PreviewWidgetPrivate::init()
150 actionBar->setEnabled(
false);
152 m_printer.setFullPage(
true);
157 previewArea->setWidget(m_previewWidget);
159 previewArea->setFocus();
176 auto *nextPageShortcut =
new QShortcut(q);
179 auto *prevPageShortcut =
new QShortcut(q);
182 pageNumber->setValidator(
new QIntValidator(1, 100000, pageNumber));
183 pageNumber->installEventFilter(q);
186 void KDReports::PreviewWidgetPrivate::paintItem(
QListWidgetItem *item,
int index)
const
193 const QSizeF paperSize = m_report->paperSize();
194 const qreal longestSide = qMax(paperSize.
width(), paperSize.
height());
195 qreal width = img.width() * paperSize.
width() / longestSide;
196 qreal height = img.height() * paperSize.
height() / longestSide;
198 img.fill(qRgba(0, 0, 0, 0));
201 painter.translate((img.width() - width) / 2, (img.height() - height) / 2);
203 painter.scale(img.width() / longestSide, img.height() / longestSide);
204 m_report->paintPage(index, painter);
205 painter.setPen(
QPen(1));
211 void KDReports::PreviewWidgetPrivate::previewNextItems()
213 if (m_firstDirtyPreviewItem == -1 || m_firstDirtyPreviewItem >= m_pageCount) {
214 m_previewTimer.stop();
215 m_firstDirtyPreviewItem = -1;
218 paintItem(pageList->item(m_firstDirtyPreviewItem), m_firstDirtyPreviewItem);
219 ++m_firstDirtyPreviewItem;
223 QPixmap KDReports::PreviewWidgetPrivate::paintPreview(
int index)
const
225 const QSizeF paperSize = m_report->paperSize();
226 const int width = qCeil(paperSize.
width() * m_zoomFactor);
227 const int height = qCeil(paperSize.
height() * m_zoomFactor);
238 painter.scale(m_zoomFactor, m_zoomFactor);
239 m_report->paintPage(index, painter);
240 painter.setPen(
QPen(1));
246 void KDReports::PreviewWidgetPrivate::handleMouseMove(
QPoint pos)
248 const QPoint unscaledPos = pos / m_zoomFactor;
249 const QString link = m_report->anchorAt(pageList->currentRow(), unscaledPos);
253 }
else if (!m_onAnchor) {
259 void KDReports::PreviewWidgetPrivate::handleMouseRelease(
QPoint pos)
261 const QPoint unscaledPos = pos / m_zoomFactor;
262 const QString link = m_report->anchorAt(pageList->currentRow(), unscaledPos);
264 Q_EMIT q->linkActivated(link);
268 void KDReports::PreviewWidgetPrivate::printSelectedPages()
272 m_report->setPageSize(m_printer.pageLayout().pageSize());
273 m_report->setPageOrientation(m_printer.pageLayout().orientation());
280 for (
int pageIndex = 0; pageIndex < pageList->count(); ++pageIndex) {
281 if (pageList->item(pageIndex)->checkState() ==
Qt::Checked)
289 painter.
begin(&m_printer);
292 bool firstPage =
true;
293 for (
int pageIndex = 0; pageIndex < m_pageCount; ++pageIndex) {
296 qApp->processEvents();
298 if (dialog.wasCanceled())
301 if (q->isSelected(pageIndex)) {
306 m_report->paintPage(pageIndex, painter);
307 dialog.setValue(++printed);
314 void KDReports::PreviewWidgetPrivate::setupComboBoxes()
316 paperSizeCombo->addItem(PreviewWidget::tr(
"A0 (841 x 1189 mm)"),
QPageSize::A0);
317 paperSizeCombo->addItem(PreviewWidget::tr(
"A1 (594 x 841 mm)"),
QPageSize::A1);
318 paperSizeCombo->addItem(PreviewWidget::tr(
"A2 (420 x 594 mm)"),
QPageSize::A2);
319 paperSizeCombo->addItem(PreviewWidget::tr(
"A3 (297 x 420 mm)"),
QPageSize::A3);
320 paperSizeCombo->addItem(PreviewWidget::tr(
"A4 (210 x 297 mm)"),
QPageSize::A4);
321 paperSizeCombo->addItem(PreviewWidget::tr(
"A5 (148 x 210 mm)"),
QPageSize::A5);
322 paperSizeCombo->addItem(PreviewWidget::tr(
"A6 (105 x 148 mm)"),
QPageSize::A6);
323 paperSizeCombo->addItem(PreviewWidget::tr(
"A7 (74 x 105 mm)"),
QPageSize::A7);
324 paperSizeCombo->addItem(PreviewWidget::tr(
"A8 (52 x 74 mm)"),
QPageSize::A8);
326 paperSizeCombo->addItem(PreviewWidget::tr(
"B0 (1000 x 1414 mm)"),
QPageSize::B0);
327 paperSizeCombo->addItem(PreviewWidget::tr(
"B1 (707 x 1000 mm)"),
QPageSize::B1);
328 paperSizeCombo->addItem(PreviewWidget::tr(
"B2 (500 x 707 mm)"),
QPageSize::B2);
329 paperSizeCombo->addItem(PreviewWidget::tr(
"B3 (353 x 500 mm)"),
QPageSize::B3);
330 paperSizeCombo->addItem(PreviewWidget::tr(
"B4 (250 x 353 mm)"),
QPageSize::B4);
331 paperSizeCombo->addItem(PreviewWidget::tr(
"B5 (176 x 250 mm)"),
QPageSize::B5);
332 paperSizeCombo->addItem(PreviewWidget::tr(
"B6 (125 x 176 mm)"),
QPageSize::B6);
333 paperSizeCombo->addItem(PreviewWidget::tr(
"B7 (88 x 125 mm)"),
QPageSize::B7);
334 paperSizeCombo->addItem(PreviewWidget::tr(
"B8 (62 x 88 mm)"),
QPageSize::B8);
337 paperSizeCombo->addItem(PreviewWidget::tr(
"C5E (163 x 229 mm)"),
QPageSize::C5E);
338 paperSizeCombo->addItem(PreviewWidget::tr(
"DLE (110 x 220 mm)"),
QPageSize::DLE);
339 paperSizeCombo->addItem(PreviewWidget::tr(
"Executive (7.5 x 10 inches)"),
QPageSize::Executive);
340 paperSizeCombo->addItem(PreviewWidget::tr(
"Folio (210 x 330 mm)"),
QPageSize::Folio);
341 paperSizeCombo->addItem(PreviewWidget::tr(
"Ledger (432 x 279 mm)"),
QPageSize::Ledger);
342 paperSizeCombo->addItem(PreviewWidget::tr(
"Legal (8.5 x 14 inches)"),
QPageSize::Legal);
343 paperSizeCombo->addItem(PreviewWidget::tr(
"Letter (8.5 x 11 inches)"),
QPageSize::Letter);
344 paperSizeCombo->addItem(PreviewWidget::tr(
"Tabloid (279 x 432 mm)"),
QPageSize::Tabloid);
345 paperSizeCombo->addItem(PreviewWidget::tr(
"US #10 Envelope (105 x 241 mm)"),
QPageSize::Comm10E);
346 paperSizeCombo->addItem(PreviewWidget::tr(
"Endless printer (%1 mm wide)").arg(m_endlessPrinterWidth),
QPageSize::Custom);
352 void KDReports::PreviewWidgetPrivate::slotCurrentPageChanged()
358 void KDReports::PreviewWidgetPrivate::updatePageButtons()
360 prevPage->setEnabled(pageList->currentRow() > 0);
361 nextPage->setEnabled(pageList->currentRow() < pageList->count() - 1);
365 void KDReports::PreviewWidgetPrivate::updatePreview()
367 if (!pageList->currentItem())
369 const QSize oldSize = m_previewWidget->pixmapSize();
370 const QPixmap pixmap = paintPreview(pageList->currentRow());
371 m_previewWidget->setPixmap(pixmap);
372 if (pixmap.
size() != oldSize) {
377 void KDReports::PreviewWidgetPrivate::pageNumberReturnPressed()
380 const int newPageNumber = pageNumber->text().toInt(&ok) - 1;
381 if (!ok || newPageNumber < 0 || newPageNumber > pageList->count() - 1)
383 pageList->setCurrentRow(newPageNumber);
386 void KDReports::PreviewWidgetPrivate::slotFirstPage()
388 pageList->setCurrentRow(0);
391 void KDReports::PreviewWidgetPrivate::slotPrevPage()
393 if (!pageList->currentItem() || pageList->currentRow() == 0)
395 pageList->setCurrentRow(pageList->currentRow() - 1);
398 void KDReports::PreviewWidgetPrivate::slotNextPage()
400 if (!pageList->currentItem() || pageList->currentRow() >= pageList->count() - 1)
402 pageList->setCurrentRow(pageList->currentRow() + 1);
405 void KDReports::PreviewWidgetPrivate::slotLastPage()
407 if (pageList->count() == 0)
409 pageList->setCurrentRow(pageList->count() - 1);
412 void KDReports::PreviewWidgetPrivate::slotPaperSizeActivated(
int index)
415 m_printer.setPageSize(qPageSize);
417 m_report->setWidthForEndlessPrinter(m_endlessPrinterWidth);
419 m_report->setWidthForEndlessPrinter(0);
420 m_report->setPageSize(qPageSize);
423 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
426 emit q->pageSizeChanged(qPageSize);
430 void KDReports::PreviewWidgetPrivate::slotPaperOrientationActivated(
int index)
433 m_printer.setPageOrientation(orientation);
434 m_report->setPageOrientation(orientation);
436 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
439 emit q->orientationChanged(orientation);
443 void KDReports::PreviewWidgetPrivate::pageCountChanged()
450 m_pageCount = m_report->numberOfPages();
454 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
455 int numberWidth = 20 + pageNumber->fontMetrics().width(
QString::number(m_pageCount));
457 int numberWidth = 20 + pageNumber->fontMetrics().horizontalAdvance(
QString::number(m_pageCount));
459 pageNumber->setMinimumWidth(numberWidth);
460 pageNumber->setMaximumWidth(numberWidth);
461 pageCount->setText(QStringLiteral(
" / ") +
QString::number(m_pageCount));
464 int numberOfItems = pageList->count();
465 while (numberOfItems < m_pageCount) {
471 if (pageList->currentRow() >= m_pageCount) {
473 pageList->setCurrentRow(m_pageCount - 1);
475 while (numberOfItems > m_pageCount) {
476 delete pageList->item(numberOfItems - 1);
483 for (
int index = 0; index < m_pageCount; ++index)
484 pageList->item(index)->setIcon(whitePixmap);
486 m_firstDirtyPreviewItem = 0;
488 #ifdef PAINT_ALL_PREVIEWS
491 while (m_firstDirtyPreviewItem != -1) {
496 qDebug() << m_pageCount <<
"previews in" << dt.
elapsed() / 1000.0 <<
"s";
498 m_previewTimer.start(0);
504 qApp->restoreOverrideCursor();
507 void KDReports::PreviewWidgetPrivate::centerPreview()
509 #if 0 // extreme flicker, due to QScrollArea doing a move(0,0) every time (issue N152085)
511 const QPoint offset( ( previewArea->width() - m_previewWidget->width() ) / 2,
512 ( previewArea->height() - m_previewWidget->height() ) / 2 );
513 qDebug() <<
"Moving to " << offset;
514 m_previewWidget->move( offset );
517 int width = qMax(m_previewWidget->pixmapWidth(), previewArea->viewport()->width());
518 int height = qMax(m_previewWidget->pixmapHeight(), previewArea->viewport()->height());
519 m_previewWidget->resize(width, height);
522 void KDReports::PreviewWidgetPrivate::slotZoomIn()
524 if (m_zoomFactor > 1.99)
525 m_zoomFactor = qMin<qreal>(4.0, m_zoomFactor + 0.5);
526 else if (m_zoomFactor > 0.99)
534 void KDReports::PreviewWidgetPrivate::slotZoomOut()
536 if (m_zoomFactor > 1.99)
538 else if (m_zoomFactor > 0.99)
540 else if (m_zoomFactor >= 0.2)
546 void KDReports::PreviewWidgetPrivate::slotZoomChanged()
548 QString str = zoomCombo->currentText();
553 void KDReports::PreviewWidgetPrivate::zoomChanged()
560 void KDReports::PreviewWidgetPrivate::fillZoomCombo()
562 static const double s_zoomFactors[] = {0.125, 0.25, 0.333, 0.5, 0.667, 0.75, 1, 1.25, 1.50, 2, 4};
565 bool currentZoomFound =
false;
566 for (
const qreal val : s_zoomFactors) {
567 if (!currentZoomFound && m_zoomFactor <= val - 0.001) {
569 zoomCombo->setCurrentIndex(zoomCombo->count() - 1);
570 currentZoomFound =
true;
573 if (m_zoomFactor > val - 0.001 && m_zoomFactor < val + 0.001) {
574 zoomCombo->setCurrentIndex(zoomCombo->count() - 1);
575 currentZoomFound =
true;
584 , d(new PreviewWidgetPrivate(this))
595 if (pageNumber >= 0 && pageNumber < d->pageList->count())
596 return (d->pageList->item(pageNumber)->checkState() ==
Qt::Checked);
608 d->paperSizeCombo->setVisible(b);
609 d->paperOrientationCombo->setVisible(b);
610 d->labelPaperSize->setVisible(b);
611 d->labelOrientation->setVisible(b);
616 d->tableBreakingButton->setVisible(b);
623 if (obj == d->pageNumber) {
625 auto *keyev =
static_cast<QKeyEvent *
>(ev);
627 d->pageNumberReturnPressed();
629 d->previewArea->setFocus();
633 d->m_eatPageNumberClick =
true;
634 d->pageNumber->selectAll();
636 d->m_eatPageNumberClick =
false;
646 d->m_endlessPrinterWidth = widthMM;
664 for (
int pageIndex = 0; pageIndex < d->pageList->count(); ++pageIndex) {
665 d->pageList->item(pageIndex)->setCheckState(
Qt::Checked);
668 const int fromPage = dialog->fromPage() - 1;
669 const int toPage = dialog->toPage() - 1;
671 for (
int pageIndex = 0; pageIndex < d->pageList->count(); ++pageIndex) {
672 const bool checked = (pageIndex >= fromPage && pageIndex <= toPage);
676 d->printSelectedPages();
685 d->setReport(report);
692 actionBar->setEnabled(
true);
695 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
696 paperSizeCombo->setCurrentIndex(paperSizeCombo->findData(m_report->pageSize()));
698 paperSizeCombo->setCurrentIndex(paperSizeCombo->findData(m_report->pageSize().id()));
700 paperOrientationCombo->setCurrentIndex(paperOrientationCombo->findData(m_report->pageOrientation()));
704 m_report->setupPrinter(&m_printer);
706 if (!pageList->currentItem()) {
708 pageList->setCurrentItem(pageList->item(0));
710 slotCurrentPageChanged();
711 pageList->scrollToTop();
716 d->pageList->setVisible(show);
721 d->pageCountChanged();
722 d->slotCurrentPageChanged();
727 return QSize(800, 600);
730 #include "KDReportsPreviewWidget.moc"