mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Rendering error reporting dialog
This commit is contained in:
@ -51,7 +51,8 @@ SOURCES += \
|
||||
sources/pdfcolorspaces.cpp \
|
||||
sources/pdfrenderer.cpp \
|
||||
sources/pdfpagecontentprocessor.cpp \
|
||||
sources/pdfpainter.cpp
|
||||
sources/pdfpainter.cpp \
|
||||
sources/pdfrenderingerrorswidget.cpp
|
||||
|
||||
HEADERS += \
|
||||
sources/pdfobject.h \
|
||||
@ -75,7 +76,8 @@ HEADERS += \
|
||||
sources/pdfrenderer.h \
|
||||
sources/pdfpagecontentprocessor.h \
|
||||
sources/pdfpainter.h \
|
||||
sources/pdfutils.h
|
||||
sources/pdfutils.h \
|
||||
sources/pdfrenderingerrorswidget.h
|
||||
|
||||
unix {
|
||||
target.path = /usr/lib
|
||||
@ -87,3 +89,6 @@ CONFIG += force_debug_info
|
||||
|
||||
|
||||
QMAKE_CXXFLAGS += /std:c++latest /utf-8
|
||||
|
||||
FORMS += \
|
||||
sources/pdfrenderingerrorswidget.ui
|
||||
|
@ -535,8 +535,36 @@ void PDFDrawWidgetProxy::draw(QPainter* painter, QRect rect)
|
||||
|
||||
PDFRenderer renderer(m_controller->getDocument());
|
||||
QList<PDFRenderError> errors = renderer.render(painter, placedRect, item.pageIndex);
|
||||
|
||||
if (!errors.empty())
|
||||
{
|
||||
emit renderingError(item.pageIndex, errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<PDFInteger> PDFDrawWidgetProxy::getPagesIntersectingRect(QRect rect) const
|
||||
{
|
||||
std::vector<PDFInteger> pages;
|
||||
|
||||
// We assume, that no more, than 32 pages will be displayed in the rectangle
|
||||
pages.reserve(32);
|
||||
|
||||
// Iterate trough pages, place them and test, if they intersects with rectangle
|
||||
for (const LayoutItem& item : m_layout.items)
|
||||
{
|
||||
// The offsets m_horizontalOffset and m_verticalOffset are offsets to the
|
||||
// topleft point of the block. But block maybe doesn't start at (0, 0),
|
||||
// so we must also use translation from the block beginning.
|
||||
QRect placedRect = item.pageRect.translated(m_horizontalOffset - m_layout.blockRect.left(), m_verticalOffset - m_layout.blockRect.top());
|
||||
if (placedRect.intersects(rect))
|
||||
{
|
||||
pages.push_back(item.pageIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
void PDFDrawWidgetProxy::performOperation(Operation operation)
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "pdfglobal.h"
|
||||
#include "pdfdocument.h"
|
||||
#include "pdfrenderer.h"
|
||||
|
||||
#include <QRectF>
|
||||
#include <QObject>
|
||||
@ -177,11 +178,16 @@ public:
|
||||
/// Returns the page layout
|
||||
PageLayout getPageLayout() const { return m_controller->getPageLayout(); }
|
||||
|
||||
/// Returns pages, which are intersecting rectangle (even partially)
|
||||
/// \param rect Rectangle to test
|
||||
std::vector<PDFInteger> getPagesIntersectingRect(QRect rect) const;
|
||||
|
||||
static constexpr PDFReal ZOOM_STEP = 1.2;
|
||||
|
||||
signals:
|
||||
void drawSpaceChanged();
|
||||
void pageLayoutChanged();
|
||||
void renderingError(PDFInteger pageIndex, const QList<PDFRenderError>& errors);
|
||||
|
||||
private:
|
||||
struct LayoutItem
|
||||
|
@ -49,6 +49,7 @@ PDFWidget::PDFWidget(QWidget* parent) :
|
||||
|
||||
m_proxy = new PDFDrawWidgetProxy(this);
|
||||
m_proxy->init(this);
|
||||
connect(m_proxy, &PDFDrawWidgetProxy::renderingError, this, &PDFWidget::onRenderingError);
|
||||
}
|
||||
|
||||
PDFWidget::~PDFWidget()
|
||||
@ -61,6 +62,24 @@ void PDFWidget::setDocument(const PDFDocument* document)
|
||||
m_proxy->setDocument(document);
|
||||
}
|
||||
|
||||
int PDFWidget::getPageRenderingErrorCount() const
|
||||
{
|
||||
int count = 0;
|
||||
for (const auto& item : m_pageRenderingErrors)
|
||||
{
|
||||
count += item.second.size();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void PDFWidget::onRenderingError(PDFInteger pageIndex, const QList<PDFRenderError>& errors)
|
||||
{
|
||||
// Empty list of error should not be reported!
|
||||
Q_ASSERT(!errors.empty());
|
||||
m_pageRenderingErrors[pageIndex] = errors;
|
||||
emit pageRenderingErrorsChanged(pageIndex, errors.size());
|
||||
}
|
||||
|
||||
PDFDrawWidget::PDFDrawWidget(PDFWidget* widget, QWidget* parent) :
|
||||
QWidget(parent),
|
||||
m_widget(widget),
|
||||
@ -74,6 +93,11 @@ PDFDrawWidget::~PDFDrawWidget()
|
||||
|
||||
}
|
||||
|
||||
std::vector<PDFInteger> PDFDrawWidget::getCurrentPages() const
|
||||
{
|
||||
return m_widget->getDrawWidgetProxy()->getPagesIntersectingRect(this->rect());
|
||||
}
|
||||
|
||||
QSize PDFDrawWidget::minimumSizeHint() const
|
||||
{
|
||||
return QSize(200, 200);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define PDFDRAWWIDGET_H
|
||||
|
||||
#include "pdfglobal.h"
|
||||
#include "pdfrenderer.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QScrollBar>
|
||||
@ -38,6 +39,8 @@ public:
|
||||
explicit PDFWidget(QWidget* parent);
|
||||
virtual ~PDFWidget() override;
|
||||
|
||||
using PageRenderingErrors = std::map<PDFInteger, QList<PDFRenderError>>;
|
||||
|
||||
/// Sets the document to be viewed in this widget. Document can be nullptr,
|
||||
/// in that case, widget contents are cleared.
|
||||
/// \param document Document
|
||||
@ -47,12 +50,20 @@ public:
|
||||
QScrollBar* getHorizontalScrollbar() const { return m_horizontalScrollBar; }
|
||||
QScrollBar* getVerticalScrollbar() const { return m_verticalScrollBar; }
|
||||
PDFDrawWidgetProxy* getDrawWidgetProxy() const { return m_proxy; }
|
||||
const PageRenderingErrors* getPageRenderingErrors() const { return &m_pageRenderingErrors; }
|
||||
int getPageRenderingErrorCount() const;
|
||||
|
||||
signals:
|
||||
void pageRenderingErrorsChanged(PDFInteger pageIndex, int errorsCount);
|
||||
|
||||
private:
|
||||
void onRenderingError(PDFInteger pageIndex, const QList<PDFRenderError>& errors);
|
||||
|
||||
PDFDrawWidget* m_drawWidget;
|
||||
QScrollBar* m_horizontalScrollBar;
|
||||
QScrollBar* m_verticalScrollBar;
|
||||
PDFDrawWidgetProxy* m_proxy;
|
||||
PageRenderingErrors m_pageRenderingErrors;
|
||||
};
|
||||
|
||||
class PDFFORQTLIBSHARED_EXPORT PDFDrawWidget : public QWidget
|
||||
@ -63,6 +74,9 @@ public:
|
||||
explicit PDFDrawWidget(PDFWidget* widget, QWidget* parent);
|
||||
virtual ~PDFDrawWidget() override;
|
||||
|
||||
/// Returns page indices, which are currently displayed in the widget
|
||||
std::vector<PDFInteger> getCurrentPages() const;
|
||||
|
||||
virtual QSize minimumSizeHint() const override;
|
||||
|
||||
protected:
|
||||
|
95
PdfForQtLib/sources/pdfrenderingerrorswidget.cpp
Normal file
95
PdfForQtLib/sources/pdfrenderingerrorswidget.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright (C) 2019 Jakub Melka
|
||||
//
|
||||
// This file is part of PdfForQt.
|
||||
//
|
||||
// PdfForQt is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// PdfForQt is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "pdfrenderingerrorswidget.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
#include "ui_pdfrenderingerrorswidget.h"
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
||||
PDFRenderingErrorsWidget::PDFRenderingErrorsWidget(QWidget* parent, PDFWidget* pdfWidget) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::PDFRenderingErrorsWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->renderErrorsTreeWidget->setColumnCount(3);
|
||||
ui->renderErrorsTreeWidget->setColumnWidth(0, 100);
|
||||
ui->renderErrorsTreeWidget->setColumnWidth(1, 300);
|
||||
ui->renderErrorsTreeWidget->setHeaderLabels({ tr("Page"), tr("Error type"), tr("Description") });
|
||||
|
||||
Q_ASSERT(pdfWidget);
|
||||
std::vector<PDFInteger> currentPages = pdfWidget->getDrawWidget()->getCurrentPages();
|
||||
qSort(currentPages);
|
||||
|
||||
QTreeWidgetItem* scrollToItem = nullptr;
|
||||
const PDFWidget::PageRenderingErrors* pageRenderingErrors = pdfWidget->getPageRenderingErrors();
|
||||
for (const auto& pageRenderingError : *pageRenderingErrors)
|
||||
{
|
||||
// TODO: udelat realna cisla stranek
|
||||
const PDFInteger pageIndex = pageRenderingError.first;
|
||||
QTreeWidgetItem* root = new QTreeWidgetItem(ui->renderErrorsTreeWidget, QStringList() << QString::number(pageIndex + 1) << QString() << QString());
|
||||
|
||||
for (const PDFRenderError& error : pageRenderingError.second)
|
||||
{
|
||||
QString typeString;
|
||||
switch (error.type)
|
||||
{
|
||||
case RenderErrorType::Error:
|
||||
{
|
||||
typeString = tr("Error");
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderErrorType::NotImplemented:
|
||||
{
|
||||
typeString = tr("Not implemented");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
new QTreeWidgetItem(root, QStringList() << QString() << typeString << error.message);
|
||||
}
|
||||
|
||||
bool isCurrentPage = std::binary_search(currentPages.cbegin(), currentPages.cend(), pageIndex);
|
||||
ui->renderErrorsTreeWidget->setItemExpanded(root, isCurrentPage);
|
||||
|
||||
if (isCurrentPage && !scrollToItem)
|
||||
{
|
||||
scrollToItem = root;
|
||||
}
|
||||
}
|
||||
|
||||
if (scrollToItem)
|
||||
{
|
||||
ui->renderErrorsTreeWidget->scrollToItem(scrollToItem, QAbstractItemView::EnsureVisible);
|
||||
}
|
||||
}
|
||||
|
||||
PDFRenderingErrorsWidget::~PDFRenderingErrorsWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
} // namespace pdf
|
48
PdfForQtLib/sources/pdfrenderingerrorswidget.h
Normal file
48
PdfForQtLib/sources/pdfrenderingerrorswidget.h
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2019 Jakub Melka
|
||||
//
|
||||
// This file is part of PdfForQt.
|
||||
//
|
||||
// PdfForQt is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// PdfForQt is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef PDFRENDERINGERRORSWIDGET_H
|
||||
#define PDFRENDERINGERRORSWIDGET_H
|
||||
|
||||
#include "pdfglobal.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class PDFRenderingErrorsWidget;
|
||||
}
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
class PDFWidget;
|
||||
|
||||
class PDFFORQTLIBSHARED_EXPORT PDFRenderingErrorsWidget : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PDFRenderingErrorsWidget(QWidget* parent, PDFWidget* pdfWidget);
|
||||
virtual ~PDFRenderingErrorsWidget() override;
|
||||
|
||||
private:
|
||||
Ui::PDFRenderingErrorsWidget* ui;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFRENDERINGERRORSWIDGET_H
|
73
PdfForQtLib/sources/pdfrenderingerrorswidget.ui
Normal file
73
PdfForQtLib/sources/pdfrenderingerrorswidget.ui
Normal file
@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PDFRenderingErrorsWidget</class>
|
||||
<widget class="QDialog" name="PDFRenderingErrorsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>798</width>
|
||||
<height>510</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Rendering errors</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="renderErrorsTreeWidget">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>PDFRenderingErrorsWidget</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>PDFRenderingErrorsWidget</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -23,6 +23,7 @@
|
||||
#include "pdfstreamfilters.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
#include "pdfdrawspacecontroller.h"
|
||||
#include "pdfrenderingerrorswidget.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QFileDialog>
|
||||
@ -76,6 +77,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget *parent) :
|
||||
setFocusProxy(m_pdfWidget);
|
||||
|
||||
connect(m_pdfWidget->getDrawWidgetProxy(), &pdf::PDFDrawWidgetProxy::pageLayoutChanged, this, &PDFViewerMainWindow::updatePageLayoutActions);
|
||||
connect(m_pdfWidget, &pdf::PDFWidget::pageRenderingErrorsChanged, this, &PDFViewerMainWindow::onPageRenderingErrorsChanged, Qt::QueuedConnection);
|
||||
|
||||
readSettings();
|
||||
updatePageLayoutActions();
|
||||
@ -105,6 +107,14 @@ void PDFViewerMainWindow::onActionQuitTriggered()
|
||||
close();
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::onPageRenderingErrorsChanged(pdf::PDFInteger pageIndex, int errorsCount)
|
||||
{
|
||||
if (errorsCount > 0)
|
||||
{
|
||||
statusBar()->showMessage(tr("Rendering of page %1: %2 errors occured.").arg(pageIndex + 1).arg(errorsCount), 4000);
|
||||
}
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::readSettings()
|
||||
{
|
||||
QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||
@ -287,4 +297,10 @@ void PDFViewerMainWindow::on_actionFirstPageOnRightSide_triggered()
|
||||
}
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::on_actionRendering_Errors_triggered()
|
||||
{
|
||||
pdf::PDFRenderingErrorsWidget renderingErrorsDialog(this, m_pdfWidget);
|
||||
renderingErrorsDialog.exec();
|
||||
}
|
||||
|
||||
} // namespace pdfviewer
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define PDFVIEWERMAINWINDOW_H
|
||||
|
||||
#include "pdfcatalog.h"
|
||||
#include "pdfrenderer.h"
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QSharedPointer>
|
||||
@ -54,10 +55,13 @@ private slots:
|
||||
void on_actionPageLayoutTwoColumns_triggered();
|
||||
void on_actionFirstPageOnRightSide_triggered();
|
||||
|
||||
void on_actionRendering_Errors_triggered();
|
||||
|
||||
private:
|
||||
void onActionOpenTriggered();
|
||||
void onActionCloseTriggered();
|
||||
void onActionQuitTriggered();
|
||||
void onPageRenderingErrorsChanged(pdf::PDFInteger pageIndex, int errorsCount);
|
||||
|
||||
void readSettings();
|
||||
void writeSettings();
|
||||
|
@ -53,9 +53,16 @@
|
||||
</widget>
|
||||
<addaction name="menuPage_Layout"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuTools">
|
||||
<property name="title">
|
||||
<string>Tools</string>
|
||||
</property>
|
||||
<addaction name="actionRendering_Errors"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuGoTo"/>
|
||||
<addaction name="menuTools"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mainToolBar">
|
||||
<attribute name="toolBarArea">
|
||||
@ -139,6 +146,14 @@
|
||||
<string>Ctrl+5</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRendering_Errors">
|
||||
<property name="text">
|
||||
<string>Rendering Errors</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+E</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
|
Reference in New Issue
Block a user