Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Z/src/nglwidgets/nglpdfpage.cpp
T

214 lines
4.8 KiB
C++
Executable File

#include "nglpdfpage.h"
#include <utility>
#include <QtGui/QPainter>
#include <QtGui/QMouseEvent>
#include <QtCore/QUrl>
#include <math.h>
#include <iostream>
namespace NGL
{
template <typename T>
static inline T getRotatedSize(const T &in, Poppler::Page::Rotation rot)
{
switch (rot)
{
case Poppler::Page::Rotate0:
case Poppler::Page::Rotate180:
return in;
case Poppler::Page::Rotate90:
case Poppler::Page::Rotate270:
return in.transposed();
}
Q_ASSERT(false);
return in;
}
PDFPage::PDFPage(QWidget *parent)
: QWidget(parent)
, m_page(nullptr)
, m_scaleFactor(1.0)
, m_rotation(Poppler::Page::Rotate0)
{
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setMouseTracking(true);
}
PDFPage::~PDFPage()
{
delete m_page;
}
void PDFPage::setPopplerPage(Poppler::Page *page)
{
if (m_page == page)
return;
delete m_page;
m_page = page;
m_links.clear();
m_linkRects.clear();
if (!m_page)
return;
// Poppler::Page::links() returns std::vector<std::unique_ptr<Poppler::Link>> in Poppler Qt6
auto links = m_page->links();
for (auto &linkUp : links)
{
Poppler::Link *link = linkUp.get();
if (!link)
continue;
if (link->linkType() == Poppler::Link::Browse ||
link->linkType() == Poppler::Link::Goto)
m_links.emplace_back(std::move(linkUp));
else
std::cerr << "linktype: " << link->linkType() << std::endl;
}
rebuildInternalData();
}
void PDFPage::setZoomFactor(double zoom)
{
if (qFuzzyCompare(m_scaleFactor, zoom))
return;
m_scaleFactor = zoom;
rebuildInternalData();
}
void PDFPage::setRotation(Poppler::Page::Rotation rot)
{
if (m_rotation == rot)
return;
m_rotation = rot;
rebuildInternalData();
}
void PDFPage::clearPixmap()
{
m_pdfPixmap = QPixmap();
}
QImage PDFPage::getPrintableImage(int resolution) const
{
if (!m_page)
return QImage();
Poppler::Page::Rotation rot = Poppler::Page::Rotate0;
if (m_page->orientation() == Poppler::Page::Landscape)
rot = Poppler::Page::Rotate270;
else if (m_page->orientation() == Poppler::Page::Seascape)
rot = Poppler::Page::Rotate90;
else if (m_page->orientation() == Poppler::Page::UpsideDown)
rot = Poppler::Page::Rotate180;
Q_UNUSED(rot)
return m_page->renderToImage(resolution, resolution, -1, -1, -1, -1, m_rotation);
}
QSize PDFPage::sizeHint() const
{
if (!m_page)
return QSize();
return getRotatedSize(m_page->pageSize(), m_rotation);
}
void PDFPage::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
if (!m_page)
return;
if (m_pdfPixmap.isNull())
{
const QImage img = m_page->renderToImage(m_scaleFactor * 72, m_scaleFactor * 72, -1, -1, -1, -1, m_rotation);
m_pdfPixmap = QPixmap::fromImage(img);
emit pageRendered();
}
QPainter p(this);
p.drawPixmap(0, 0, m_pdfPixmap);
p.end();
}
void PDFPage::mouseMoveEvent(QMouseEvent *event)
{
const QPointF pos = event->position();
for (const auto &linkRect : std::as_const(m_linkRects))
{
if (linkRect.contains(pos))
{
setCursor(Qt::PointingHandCursor);
return;
}
}
setCursor(Qt::ArrowCursor);
QWidget::mouseMoveEvent(event);
}
void PDFPage::mouseReleaseEvent(QMouseEvent *event)
{
const QPointF pos = event->position();
for (int i = 0; i < m_linkRects.size(); ++i)
{
if (m_linkRects.at(i).contains(pos))
{
const Poppler::Link *link = m_links.at(i).get();
if (!link)
continue;
if (link->linkType() == Poppler::Link::Browse)
{
const Poppler::LinkBrowse *linkBrowse = static_cast<const Poppler::LinkBrowse *>(link);
emit externalLinkClicked(linkBrowse->url());
return;
}
else if (link->linkType() == Poppler::Link::Goto)
{
const Poppler::LinkGoto *linkGoto = static_cast<const Poppler::LinkGoto *>(link);
if (linkGoto->isExternal())
{
const QUrl url = QUrl::fromLocalFile(linkGoto->fileName());
emit externalLinkClicked(url.toString());
return;
}
emit linkClicked(linkGoto->destination());
return;
}
}
}
QWidget::mouseReleaseEvent(event);
}
void PDFPage::rebuildInternalData()
{
clearPixmap();
if (!m_page)
return;
const QSizeF s(rotatedPageSize());
const int w = qRound(s.width() * m_scaleFactor);
const int h = qRound(s.height() * m_scaleFactor);
setMinimumSize(w, h);
resize(sizeHint());
m_linkRects.clear();
m_linkRects.reserve(static_cast<int>(m_links.size()));
for (const auto &linkUp : m_links)
{
const Poppler::Link *link = linkUp.get();
if (!link)
continue;
const QRectF r = link->linkArea();
m_linkRects += QRectF(r.x() * w, r.y() * h, r.width() * w, r.height() * h);
}
}
QSizeF PDFPage::rotatedPageSize() const
{
return m_page ? getRotatedSize(m_page->pageSizeF(), m_rotation) : QSizeF();
}
}