17#include <QPrintDialog>
18#include <QProgressDialog>
24#include "ui_previewdialogbase.h"
33class PagePreviewWidget :
public QWidget
43 void setPixmap(
const QPixmap &pixmap)
48 int pixmapWidth()
const
50 return m_pixmap.width();
52 int pixmapHeight()
const
54 return m_pixmap.height();
56 QSize pixmapSize()
const
58 return m_pixmap.size();
66 QPoint pixmapOffset()
const
68 return QPoint((
width() - m_pixmap.width()) / 2, (
height() - m_pixmap.height()) / 2);
75 painter.drawPixmap(pixmapOffset(), m_pixmap);
80 Q_EMIT mouseMoved(ev->
pos() - pixmapOffset());
85 Q_EMIT mouseClicked(ev->
pos() - pixmapOffset());
92class KDReports::PreviewWidgetPrivate :
public Ui::PreviewWidgetBase
101 QPixmap paintPreview(
int index)
const;
102 void printSelectedPages();
103 void setupComboBoxes();
104 void pageCountChanged();
105 void centerPreview();
107 void fillZoomCombo();
108 void updatePageButtons();
109 void updatePreview();
110 void pageNumberReturnPressed();
113 void handleMouseMove(
QPoint pos);
114 void handleMouseRelease(
QPoint pos);
115 void slotCurrentPageChanged();
116 void slotFirstPage();
120 void slotPaperSizeActivated(
int);
121 void slotPaperOrientationActivated(
int);
124 void slotZoomChanged();
125 void previewNextItems();
127 PagePreviewWidget *m_previewWidget;
129 qreal m_zoomFactor = 1.0;
130 qreal m_endlessPrinterWidth = 114.0;
135 int m_firstDirtyPreviewItem = -1;
136 bool m_eatPageNumberClick =
false;
137 bool m_onAnchor =
false;
141 : m_previewWidget(new PagePreviewWidget)
146 handleMouseMove(pos);
149 handleMouseRelease(pos);
153void KDReports::PreviewWidgetPrivate::init()
156 actionBar->setEnabled(
false);
158 m_printer.setFullPage(
true);
163 previewArea->setWidget(m_previewWidget);
165 previewArea->setFocus();
182 auto *nextPageShortcut =
new QShortcut(q);
185 auto *prevPageShortcut =
new QShortcut(q);
188 pageNumber->setValidator(
new QIntValidator(1, 100000, pageNumber));
189 pageNumber->installEventFilter(q);
192void KDReports::PreviewWidgetPrivate::paintItem(
QListWidgetItem *item,
int index)
const
198 const qreal dpr = q->devicePixelRatioF();
200 img.setDevicePixelRatio(dpr);
202 const QSizeF paperSize = m_report->paperSize();
203 const qreal paperWidth = paperSize.
width();
204 const qreal paperHeight = paperSize.
height();
205 const qreal longestSide = qMax(paperWidth, paperHeight);
206 const qreal width =
PreviewSize * paperWidth / longestSide;
207 const qreal height =
PreviewSize * paperHeight / longestSide;
213 m_report->paintPage(index, painter);
214 painter.setPen(
QPen(1));
215 painter.drawRect(
QRectF(0, 0, paperWidth, paperHeight));
220void KDReports::PreviewWidgetPrivate::previewNextItems()
222 if (m_firstDirtyPreviewItem == -1 || m_firstDirtyPreviewItem >= m_pageCount) {
223 m_previewTimer.stop();
224 m_firstDirtyPreviewItem = -1;
227 paintItem(pageList->item(m_firstDirtyPreviewItem), m_firstDirtyPreviewItem);
228 ++m_firstDirtyPreviewItem;
232QPixmap KDReports::PreviewWidgetPrivate::paintPreview(
int index)
const
234 const QSizeF paperSize = m_report->paperSize();
235 const int width = qCeil(paperSize.
width() * m_zoomFactor);
236 const int height = qCeil(paperSize.
height() * m_zoomFactor);
237 const qreal dpr = q->devicePixelRatioF();
239 QPixmap pixmap(width * dpr, height * dpr);
240 pixmap.setDevicePixelRatio(dpr);
250 painter.scale(m_zoomFactor, m_zoomFactor);
251 m_report->paintPage(index, painter);
252 painter.setPen(
QPen(1));
258void KDReports::PreviewWidgetPrivate::handleMouseMove(
QPoint pos)
260 const QPoint unscaledPos = pos / m_zoomFactor;
261 const QString link = m_report->anchorAt(pageList->currentRow(), unscaledPos);
265 }
else if (!m_onAnchor) {
271void KDReports::PreviewWidgetPrivate::handleMouseRelease(
QPoint pos)
273 const QPoint unscaledPos = pos / m_zoomFactor;
274 const QString link = m_report->anchorAt(pageList->currentRow(), unscaledPos);
276 Q_EMIT q->linkActivated(link);
280void KDReports::PreviewWidgetPrivate::printSelectedPages()
284 m_report->setPageSize(m_printer.pageLayout().pageSize());
285 m_report->setPageOrientation(m_printer.pageLayout().orientation());
292 for (
int pageIndex = 0; pageIndex < pageList->count(); ++pageIndex) {
293 if (pageList->item(pageIndex)->checkState() ==
Qt::Checked)
301 painter.
begin(&m_printer);
304 bool firstPage =
true;
305 for (
int pageIndex = 0; pageIndex < m_pageCount; ++pageIndex) {
308 qApp->processEvents();
310 if (dialog.wasCanceled())
313 if (q->isSelected(pageIndex)) {
318 m_report->paintPage(pageIndex, painter);
319 dialog.setValue(++printed);
326void KDReports::PreviewWidgetPrivate::setupComboBoxes()
328 paperSizeCombo->addItem(PreviewWidget::tr(
"A0 (841 x 1189 mm)"),
QPageSize::A0);
329 paperSizeCombo->addItem(PreviewWidget::tr(
"A1 (594 x 841 mm)"),
QPageSize::A1);
330 paperSizeCombo->addItem(PreviewWidget::tr(
"A2 (420 x 594 mm)"),
QPageSize::A2);
331 paperSizeCombo->addItem(PreviewWidget::tr(
"A3 (297 x 420 mm)"),
QPageSize::A3);
332 paperSizeCombo->addItem(PreviewWidget::tr(
"A4 (210 x 297 mm)"),
QPageSize::A4);
333 paperSizeCombo->addItem(PreviewWidget::tr(
"A5 (148 x 210 mm)"),
QPageSize::A5);
334 paperSizeCombo->addItem(PreviewWidget::tr(
"A6 (105 x 148 mm)"),
QPageSize::A6);
335 paperSizeCombo->addItem(PreviewWidget::tr(
"A7 (74 x 105 mm)"),
QPageSize::A7);
336 paperSizeCombo->addItem(PreviewWidget::tr(
"A8 (52 x 74 mm)"),
QPageSize::A8);
338 paperSizeCombo->addItem(PreviewWidget::tr(
"B0 (1000 x 1414 mm)"),
QPageSize::B0);
339 paperSizeCombo->addItem(PreviewWidget::tr(
"B1 (707 x 1000 mm)"),
QPageSize::B1);
340 paperSizeCombo->addItem(PreviewWidget::tr(
"B2 (500 x 707 mm)"),
QPageSize::B2);
341 paperSizeCombo->addItem(PreviewWidget::tr(
"B3 (353 x 500 mm)"),
QPageSize::B3);
342 paperSizeCombo->addItem(PreviewWidget::tr(
"B4 (250 x 353 mm)"),
QPageSize::B4);
343 paperSizeCombo->addItem(PreviewWidget::tr(
"B5 (176 x 250 mm)"),
QPageSize::B5);
344 paperSizeCombo->addItem(PreviewWidget::tr(
"B6 (125 x 176 mm)"),
QPageSize::B6);
345 paperSizeCombo->addItem(PreviewWidget::tr(
"B7 (88 x 125 mm)"),
QPageSize::B7);
346 paperSizeCombo->addItem(PreviewWidget::tr(
"B8 (62 x 88 mm)"),
QPageSize::B8);
349 paperSizeCombo->addItem(PreviewWidget::tr(
"C5E (163 x 229 mm)"),
QPageSize::C5E);
350 paperSizeCombo->addItem(PreviewWidget::tr(
"DLE (110 x 220 mm)"),
QPageSize::DLE);
351 paperSizeCombo->addItem(PreviewWidget::tr(
"Executive (7.5 x 10 inches)"),
QPageSize::Executive);
352 paperSizeCombo->addItem(PreviewWidget::tr(
"Folio (210 x 330 mm)"),
QPageSize::Folio);
353 paperSizeCombo->addItem(PreviewWidget::tr(
"Ledger (432 x 279 mm)"),
QPageSize::Ledger);
354 paperSizeCombo->addItem(PreviewWidget::tr(
"Legal (8.5 x 14 inches)"),
QPageSize::Legal);
355 paperSizeCombo->addItem(PreviewWidget::tr(
"Letter (8.5 x 11 inches)"),
QPageSize::Letter);
356 paperSizeCombo->addItem(PreviewWidget::tr(
"Tabloid (279 x 432 mm)"),
QPageSize::Tabloid);
357 paperSizeCombo->addItem(PreviewWidget::tr(
"US #10 Envelope (105 x 241 mm)"),
QPageSize::Comm10E);
358 paperSizeCombo->addItem(PreviewWidget::tr(
"Endless printer (%1 mm wide)").arg(m_endlessPrinterWidth),
QPageSize::Custom);
364void KDReports::PreviewWidgetPrivate::slotCurrentPageChanged()
370void KDReports::PreviewWidgetPrivate::updatePageButtons()
372 prevPage->setEnabled(pageList->currentRow() > 0);
373 nextPage->setEnabled(pageList->currentRow() < pageList->count() - 1);
377void KDReports::PreviewWidgetPrivate::updatePreview()
379 if (!pageList->currentItem())
381 const QSize oldSize = m_previewWidget->pixmapSize();
382 const QPixmap pixmap = paintPreview(pageList->currentRow());
383 m_previewWidget->setPixmap(pixmap);
384 if (pixmap.
size() != oldSize) {
389void KDReports::PreviewWidgetPrivate::pageNumberReturnPressed()
392 const int newPageNumber = pageNumber->text().toInt(&ok) - 1;
393 if (!ok || newPageNumber < 0 || newPageNumber > pageList->count() - 1)
395 pageList->setCurrentRow(newPageNumber);
398void KDReports::PreviewWidgetPrivate::slotFirstPage()
400 pageList->setCurrentRow(0);
403void KDReports::PreviewWidgetPrivate::slotPrevPage()
405 if (!pageList->currentItem() || pageList->currentRow() == 0)
407 pageList->setCurrentRow(pageList->currentRow() - 1);
410void KDReports::PreviewWidgetPrivate::slotNextPage()
412 if (!pageList->currentItem() || pageList->currentRow() >= pageList->count() - 1)
414 pageList->setCurrentRow(pageList->currentRow() + 1);
417void KDReports::PreviewWidgetPrivate::slotLastPage()
419 if (pageList->count() == 0)
421 pageList->setCurrentRow(pageList->count() - 1);
424void KDReports::PreviewWidgetPrivate::slotPaperSizeActivated(
int index)
427 m_printer.setPageSize(qPageSize);
429 m_report->setWidthForEndlessPrinter(m_endlessPrinterWidth);
431 m_report->setWidthForEndlessPrinter(0);
432 m_report->setPageSize(qPageSize);
435#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
438 emit q->pageSizeChanged(qPageSize);
442void KDReports::PreviewWidgetPrivate::slotPaperOrientationActivated(
int index)
445 m_printer.setPageOrientation(orientation);
446 m_report->setPageOrientation(orientation);
448#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
451 emit q->orientationChanged(orientation);
455void KDReports::PreviewWidgetPrivate::pageCountChanged()
462 m_pageCount = m_report->numberOfPages();
466#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
467 int numberWidth = 20 + pageNumber->fontMetrics().width(
QString::number(m_pageCount));
469 int numberWidth = 20 + pageNumber->fontMetrics().horizontalAdvance(
QString::number(m_pageCount));
471 pageNumber->setMinimumWidth(numberWidth);
472 pageNumber->setMaximumWidth(numberWidth);
473 pageCount->setText(QStringLiteral(
" / ") +
QString::number(m_pageCount));
476 int numberOfItems = pageList->count();
477 while (numberOfItems < m_pageCount) {
483 if (pageList->currentRow() >= m_pageCount) {
485 pageList->setCurrentRow(m_pageCount - 1);
487 while (numberOfItems > m_pageCount) {
488 delete pageList->item(numberOfItems - 1);
495 for (
int index = 0; index < m_pageCount; ++index)
496 pageList->item(index)->setIcon(whitePixmap);
498 m_firstDirtyPreviewItem = 0;
500#ifdef PAINT_ALL_PREVIEWS
503 while (m_firstDirtyPreviewItem != -1) {
508 qDebug() << m_pageCount <<
"previews in" << dt.
elapsed() / 1000.0 <<
"s";
510 m_previewTimer.start(0);
516 qApp->restoreOverrideCursor();
519void KDReports::PreviewWidgetPrivate::centerPreview()
523 const QPoint offset( ( previewArea->width() - m_previewWidget->width() ) / 2,
524 ( previewArea->height() - m_previewWidget->height() ) / 2 );
525 qDebug() <<
"Moving to " << offset;
526 m_previewWidget->move( offset );
529 int width = qMax(m_previewWidget->pixmapWidth(), previewArea->viewport()->width());
530 int height = qMax(m_previewWidget->pixmapHeight(), previewArea->viewport()->height());
531 m_previewWidget->resize(width, height);
534void KDReports::PreviewWidgetPrivate::slotZoomIn()
536 if (m_zoomFactor > 1.99)
537 m_zoomFactor = qMin<qreal>(4.0, m_zoomFactor + 0.5);
538 else if (m_zoomFactor > 0.99)
546void KDReports::PreviewWidgetPrivate::slotZoomOut()
548 if (m_zoomFactor > 1.99)
550 else if (m_zoomFactor > 0.99)
552 else if (m_zoomFactor >= 0.2)
558void KDReports::PreviewWidgetPrivate::slotZoomChanged()
560 QString str = zoomCombo->currentText();
565void KDReports::PreviewWidgetPrivate::zoomChanged()
572void KDReports::PreviewWidgetPrivate::fillZoomCombo()
574 static const double s_zoomFactors[] = {0.125, 0.25, 0.333, 0.5, 0.667, 0.75, 1, 1.25, 1.50, 2, 4};
577 bool currentZoomFound =
false;
578 for (
const qreal val : s_zoomFactors) {
579 if (!currentZoomFound && m_zoomFactor <= val - 0.001) {
581 zoomCombo->setCurrentIndex(zoomCombo->count() - 1);
582 currentZoomFound =
true;
585 if (m_zoomFactor > val - 0.001 && m_zoomFactor < val + 0.001) {
586 zoomCombo->setCurrentIndex(zoomCombo->count() - 1);
587 currentZoomFound =
true;
596 , d(new PreviewWidgetPrivate(this))
607 if (pageNumber >= 0 && pageNumber < d->pageList->count())
608 return (d->pageList->item(pageNumber)->checkState() ==
Qt::Checked);
620 d->paperSizeCombo->setVisible(b);
621 d->paperOrientationCombo->setVisible(b);
622 d->labelPaperSize->setVisible(b);
623 d->labelOrientation->setVisible(b);
628 d->tableBreakingButton->setVisible(b);
635 if (obj == d->pageNumber) {
637 auto *keyev =
static_cast<QKeyEvent *
>(ev);
639 d->pageNumberReturnPressed();
641 d->previewArea->setFocus();
645 d->m_eatPageNumberClick =
true;
646 d->pageNumber->selectAll();
648 d->m_eatPageNumberClick =
false;
658 d->m_endlessPrinterWidth = widthMM;
678 for (
int pageIndex = 0; pageIndex < d->pageList->count(); ++pageIndex) {
679 d->pageList->item(pageIndex)->setCheckState(
Qt::Checked);
682 const int fromPage = dialog->fromPage() - 1;
683 const int toPage = dialog->toPage() - 1;
685 for (
int pageIndex = 0; pageIndex < d->pageList->count(); ++pageIndex) {
686 const bool checked = (pageIndex >= fromPage && pageIndex <= toPage);
690 d->printSelectedPages();
699 d->setReport(report);
706 actionBar->setEnabled(
true);
709#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
710 paperSizeCombo->setCurrentIndex(paperSizeCombo->findData(m_report->pageSize()));
712 paperSizeCombo->setCurrentIndex(paperSizeCombo->findData(m_report->pageSize().id()));
714 paperOrientationCombo->setCurrentIndex(paperOrientationCombo->findData(m_report->pageOrientation()));
718 m_report->setupPrinter(&m_printer);
720 if (!pageList->currentItem()) {
722 pageList->setCurrentItem(pageList->item(0));
724 slotCurrentPageChanged();
725 pageList->scrollToTop();
730 d->pageList->setVisible(show);
735 d->pageCountChanged();
736 d->slotCurrentPageChanged();
741 return QSize(800, 600);
744#include "KDReportsPreviewWidget.moc"
void activated(int index)
QEvent::Type type() const const
void setText(const QString &text)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual bool eventFilter(QObject *watched, QEvent *event)
QObject * parent() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
bool begin(QPaintDevice *device)
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
qreal height() const const
qreal width() const const
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString number(int n, int base)
QString & remove(int position, int n)
double toDouble(bool *ok) const const
int elapsed() const const