Dialog for pdf image rendering

This commit is contained in:
Jakub Melka
2020-02-08 18:09:46 +01:00
parent beaa3425ac
commit a1d270e2ab
9 changed files with 916 additions and 1 deletions

View File

@ -38,6 +38,7 @@ SOURCES += \
pdfadvancedfindwidget.cpp \
pdfdocumentpropertiesdialog.cpp \
pdfrecentfilemanager.cpp \
pdfrendertoimagesdialog.cpp \
pdfsendmail.cpp \
pdfsidebarwidget.cpp \
pdfviewermainwindow.cpp \
@ -50,6 +51,7 @@ HEADERS += \
pdfadvancedfindwidget.h \
pdfdocumentpropertiesdialog.h \
pdfrecentfilemanager.h \
pdfrendertoimagesdialog.h \
pdfsendmail.h \
pdfsidebarwidget.h \
pdfviewermainwindow.h \
@ -61,6 +63,7 @@ FORMS += \
pdfaboutdialog.ui \
pdfadvancedfindwidget.ui \
pdfdocumentpropertiesdialog.ui \
pdfrendertoimagesdialog.ui \
pdfsidebarwidget.ui \
pdfviewermainwindow.ui \
pdfviewersettingsdialog.ui

View File

@ -0,0 +1,233 @@
// Copyright (C) 2020 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 "pdfrendertoimagesdialog.h"
#include "ui_pdfrendertoimagesdialog.h"
#include "pdfutils.h"
#include "pdfwidgetutils.h"
#include <QFileDialog>
namespace pdfviewer
{
PDFRenderToImagesDialog::PDFRenderToImagesDialog(QWidget* parent) :
QDialog(parent),
ui(new Ui::PDFRenderToImagesDialog),
m_isLoadingData(false)
{
ui->setupUi(this);
// Load image formats
for (const QByteArray& format : m_imageWriterSettings.getFormats())
{
ui->formatComboBox->addItem(QString::fromLatin1(format), format);
}
connect(ui->pagesAllButton, &QRadioButton::clicked, this, &PDFRenderToImagesDialog::onPagesButtonClicked);
connect(ui->pagesSelectButton, &QRadioButton::clicked, this, &PDFRenderToImagesDialog::onPagesButtonClicked);
connect(ui->selectedPagesEdit, &QLineEdit::textChanged, this, &PDFRenderToImagesDialog::onSelectedPagesChanged);
connect(ui->directoryEdit, &QLineEdit::textChanged, this, &PDFRenderToImagesDialog::onDirectoryChanged);
connect(ui->fileTemplateEdit, &QLineEdit::textChanged, this, &PDFRenderToImagesDialog::onFileTemplateChanged);
connect(ui->resolutionDPIButton, &QRadioButton::clicked, this, &PDFRenderToImagesDialog::onResolutionButtonClicked);
connect(ui->resolutionPixelsButton, &QRadioButton::clicked, this, &PDFRenderToImagesDialog::onResolutionButtonClicked);
connect(ui->resolutionDPIEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &PDFRenderToImagesDialog::onResolutionDPIChanged);
connect(ui->resolutionPixelsEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &PDFRenderToImagesDialog::onResolutionPixelsChanged);
connect(ui->formatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFRenderToImagesDialog::onFormatChanged);
connect(ui->subtypeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFRenderToImagesDialog::onSubtypeChanged);
connect(ui->compressionEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &PDFRenderToImagesDialog::onCompressionChanged);
connect(ui->qualityEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &PDFRenderToImagesDialog::onQualityChanged);
connect(ui->gammaEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &PDFRenderToImagesDialog::onGammaChanged);
connect(ui->optimizedWriteCheckBox, &QCheckBox::clicked, this, &PDFRenderToImagesDialog::onOptimizedWriteChanged);
connect(ui->progressiveScanWriteCheckBox, &QCheckBox::clicked, this, &PDFRenderToImagesDialog::onProgressiveScanWriteChanged);
loadImageWriterSettings();
loadImageExportSettings();
PDFWidgetUtils::scaleWidget(this, QSize(1000, 600));
}
PDFRenderToImagesDialog::~PDFRenderToImagesDialog()
{
delete ui;
}
void PDFRenderToImagesDialog::loadImageWriterSettings()
{
if (m_isLoadingData)
{
return;
}
pdf::PDFTemporaryValueChange guard(&m_isLoadingData, true);
ui->formatComboBox->setCurrentIndex(ui->formatComboBox->findData(m_imageWriterSettings.getCurrentFormat()));
ui->subtypeComboBox->setUpdatesEnabled(false);
ui->subtypeComboBox->clear();
for (const QByteArray& subtype : m_imageWriterSettings.getSubtypes())
{
ui->subtypeComboBox->addItem(QString::fromLatin1(subtype), subtype);
}
ui->subtypeComboBox->setCurrentIndex(ui->subtypeComboBox->findData(m_imageWriterSettings.getCurrentSubtype()));
ui->subtypeComboBox->setUpdatesEnabled(true);
ui->compressionEdit->setValue(m_imageWriterSettings.getCompression());
ui->qualityEdit->setValue(m_imageWriterSettings.getQuality());
ui->gammaEdit->setValue(m_imageWriterSettings.getGamma());
ui->optimizedWriteCheckBox->setChecked(m_imageWriterSettings.hasOptimizedWrite());
ui->progressiveScanWriteCheckBox->setChecked(m_imageWriterSettings.hasProgressiveScanWrite());
ui->subtypeComboBox->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::SupportedSubTypes));
ui->compressionEdit->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::CompressionRatio));
ui->qualityEdit->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::Quality));
ui->gammaEdit->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::Gamma));
ui->optimizedWriteCheckBox->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::OptimizedWrite));
ui->progressiveScanWriteCheckBox->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::ProgressiveScanWrite));
}
void PDFRenderToImagesDialog::loadImageExportSettings()
{
if (m_isLoadingData)
{
return;
}
pdf::PDFTemporaryValueChange guard(&m_isLoadingData, true);
const pdf::PDFPageImageExportSettings::PageSelectionMode pageSelectionMode = m_imageExportSettings.getPageSelectionMode();
ui->pagesAllButton->setChecked(pageSelectionMode == pdf::PDFPageImageExportSettings::PageSelectionMode::All);
ui->pagesSelectButton->setChecked(pageSelectionMode == pdf::PDFPageImageExportSettings::PageSelectionMode::Selection);
if (pageSelectionMode == pdf::PDFPageImageExportSettings::PageSelectionMode::Selection)
{
ui->selectedPagesEdit->setEnabled(true);
ui->selectedPagesEdit->setText(m_imageExportSettings.getPageSelection());
}
else
{
ui->selectedPagesEdit->setEnabled(false);
ui->selectedPagesEdit->setText(QString());
}
ui->directoryEdit->setText(m_imageExportSettings.getDirectory());
ui->fileTemplateEdit->setText(m_imageExportSettings.getFileTemplate());
const pdf::PDFPageImageExportSettings::ResolutionMode resolutionMode = m_imageExportSettings.getResolutionMode();
ui->resolutionDPIButton->setChecked(resolutionMode == pdf::PDFPageImageExportSettings::ResolutionMode::DPI);
ui->resolutionPixelsButton->setChecked(resolutionMode == pdf::PDFPageImageExportSettings::ResolutionMode::Pixels);
ui->resolutionDPIEdit->setValue(m_imageExportSettings.getDpiResolution());
ui->resolutionPixelsEdit->setValue(m_imageExportSettings.getPixelResolution());
ui->resolutionDPIEdit->setEnabled(resolutionMode == pdf::PDFPageImageExportSettings::ResolutionMode::DPI);
ui->resolutionPixelsEdit->setEnabled(resolutionMode == pdf::PDFPageImageExportSettings::ResolutionMode::Pixels);
}
void PDFRenderToImagesDialog::onFormatChanged()
{
m_imageWriterSettings.selectFormat(ui->formatComboBox->currentData().toByteArray());
loadImageWriterSettings();
}
void PDFRenderToImagesDialog::onSubtypeChanged()
{
m_imageWriterSettings.setCurrentSubtype(ui->subtypeComboBox->currentData().toByteArray());
}
void PDFRenderToImagesDialog::onPagesButtonClicked(bool checked)
{
if (checked)
{
const pdf::PDFPageImageExportSettings::PageSelectionMode pageSelectionMode = (sender() == ui->pagesAllButton) ? pdf::PDFPageImageExportSettings::PageSelectionMode::All
: pdf::PDFPageImageExportSettings::PageSelectionMode::Selection;
m_imageExportSettings.setPageSelectionMode(pageSelectionMode);
loadImageExportSettings();
}
}
void PDFRenderToImagesDialog::onSelectedPagesChanged(const QString& text)
{
m_imageExportSettings.setPageSelection(text);
}
void PDFRenderToImagesDialog::onDirectoryChanged(const QString& text)
{
m_imageExportSettings.setDirectory(text);
}
void PDFRenderToImagesDialog::onFileTemplateChanged(const QString& text)
{
m_imageExportSettings.setFileTemplate(text);
}
void PDFRenderToImagesDialog::onResolutionButtonClicked(bool checked)
{
if (checked)
{
const pdf::PDFPageImageExportSettings::ResolutionMode resolutionMode = (sender() == ui->resolutionDPIButton) ? pdf::PDFPageImageExportSettings::ResolutionMode::DPI
: pdf::PDFPageImageExportSettings::ResolutionMode::Pixels;
m_imageExportSettings.setResolutionMode(resolutionMode);
loadImageExportSettings();
}
}
void PDFRenderToImagesDialog::onResolutionDPIChanged(int value)
{
m_imageExportSettings.setDpiResolution(value);
}
void PDFRenderToImagesDialog::onResolutionPixelsChanged(int value)
{
m_imageExportSettings.setPixelResolution(value);
}
void PDFRenderToImagesDialog::onCompressionChanged(int value)
{
m_imageWriterSettings.setCompression(value);
}
void PDFRenderToImagesDialog::onQualityChanged(int value)
{
m_imageWriterSettings.setQuality(value);
}
void PDFRenderToImagesDialog::onGammaChanged(double value)
{
m_imageWriterSettings.setGamma(value);
}
void PDFRenderToImagesDialog::onOptimizedWriteChanged(bool value)
{
m_imageWriterSettings.setOptimizedWrite(value);
}
void PDFRenderToImagesDialog::onProgressiveScanWriteChanged(bool value)
{
m_imageWriterSettings.setProgressiveScanWrite(value);
}
void PDFRenderToImagesDialog::on_selectDirectoryButton_clicked()
{
QString directory = QFileDialog::getExistingDirectory(this, tr("Select output directory"), ui->directoryEdit->text());
if (!directory.isEmpty())
{
ui->directoryEdit->setText(directory);
}
}
} // namespace pdfviewer

View File

@ -0,0 +1,74 @@
// Copyright (C) 2020 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 PDFRENDERTOIMAGESDIALOG_H
#define PDFRENDERTOIMAGESDIALOG_H
#include "pdfrenderer.h"
#include <QDialog>
namespace Ui
{
class PDFRenderToImagesDialog;
}
namespace pdfviewer
{
class PDFRenderToImagesDialog : public QDialog
{
Q_OBJECT
public:
explicit PDFRenderToImagesDialog(QWidget* parent);
virtual ~PDFRenderToImagesDialog() override;
private slots:
void on_selectDirectoryButton_clicked();
private:
/// Loads image writer settings to the ui
void loadImageWriterSettings();
/// Load image export settigns to the ui
void loadImageExportSettings();
void onFormatChanged();
void onSubtypeChanged();
void onPagesButtonClicked(bool checked);
void onSelectedPagesChanged(const QString& text);
void onDirectoryChanged(const QString& text);
void onFileTemplateChanged(const QString& text);
void onResolutionButtonClicked(bool checked);
void onResolutionDPIChanged(int value);
void onResolutionPixelsChanged(int value);
void onCompressionChanged(int value);
void onQualityChanged(int value);
void onGammaChanged(double value);
void onOptimizedWriteChanged(bool value);
void onProgressiveScanWriteChanged(bool value);
Ui::PDFRenderToImagesDialog* ui;
pdf::PDFImageWriterSettings m_imageWriterSettings;
pdf::PDFPageImageExportSettings m_imageExportSettings;
bool m_isLoadingData;
};
} // namespace pdfviewer
#endif // PDFRENDERTOIMAGESDIALOG_H

View File

@ -0,0 +1,286 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFRenderToImagesDialog</class>
<widget class="QDialog" name="PDFRenderToImagesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>690</width>
<height>593</height>
</rect>
</property>
<property name="windowTitle">
<string>Render Document to Images</string>
</property>
<layout class="QVBoxLayout" name="dialogLayout">
<item>
<widget class="QGroupBox" name="filesGroupBox">
<property name="title">
<string>Output Files Settings</string>
</property>
<layout class="QGridLayout" name="filesGroupBoxLayout">
<item row="0" column="0">
<widget class="QLabel" name="pagesToRenderLabel">
<property name="text">
<string>Pages to render</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="fileTemplateLabel">
<property name="text">
<string>File template</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="pagesAllButton">
<property name="text">
<string>All</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="directoryLabel">
<property name="text">
<string>Generate into directory</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QToolButton" name="selectDirectoryButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="directoryEdit"/>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="fileTemplateEdit"/>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="pagesSelectButton">
<property name="text">
<string>Pages:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="selectedPagesEdit"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="imageResolutionGroupBox">
<property name="title">
<string>Image Resolution</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="resolutionLabel">
<property name="text">
<string>Resolution</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="resolutionPixelsButton">
<property name="text">
<string>Pixels</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="resolutionDPIButton">
<property name="text">
<string>DPI</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="resolutionDPIEdit">
<property name="suffix">
<string> dots/inch</string>
</property>
<property name="minimum">
<number>72</number>
</property>
<property name="maximum">
<number>6000</number>
</property>
<property name="singleStep">
<number>36</number>
</property>
<property name="value">
<number>300</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="resolutionPixelsEdit">
<property name="suffix">
<string> px</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>16384</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>1000</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="imageFormatSettings">
<property name="title">
<string>Image Format Settings</string>
</property>
<layout class="QGridLayout" name="imageFormatSettingsLayout">
<item row="0" column="0">
<widget class="QLabel" name="imageFormatLabel">
<property name="text">
<string>Format</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="imageSubtypeLabel">
<property name="text">
<string>Subtype</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="subtypeComboBox"/>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="qualityEdit">
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="formatComboBox"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="gammaLabel">
<property name="text">
<string>Gamma</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="optimizedWriteLabel">
<property name="text">
<string>Optimized write</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="gammaEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="qualityLabel">
<property name="text">
<string>Quality</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="compressionLabel">
<property name="text">
<string>Compression</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="compressionEdit"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="progressiveScanWriteLabel">
<property name="text">
<string>Progressive scan write</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="optimizedWriteCheckBox">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="progressiveScanWriteCheckBox">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="plainTextEdit"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PDFRenderToImagesDialog</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>PDFRenderToImagesDialog</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>

View File

@ -23,6 +23,7 @@
#include "pdfadvancedfindwidget.h"
#include "pdfviewersettingsdialog.h"
#include "pdfdocumentpropertiesdialog.h"
#include "pdfrendertoimagesdialog.h"
#include "pdfdocumentreader.h"
#include "pdfvisitor.h"
@ -830,6 +831,7 @@ void PDFViewerMainWindow::updateActionsAvailability()
ui->actionRendering_Errors->setEnabled(hasValidDocument);
ui->actionFind->setEnabled(hasValidDocument);
ui->actionPrint->setEnabled(hasValidDocument && canPrint);
ui->actionRender_to_Images->setEnabled(hasValidDocument && canPrint);
setEnabled(!isBusy);
}
@ -1275,5 +1277,13 @@ void PDFViewerMainWindow::on_actionPrint_triggered()
}
}
} // namespace pdfviewer
void PDFViewerMainWindow::on_actionRender_to_Images_triggered()
{
PDFRenderToImagesDialog dialog(this);
if (dialog.exec() == QDialog::Accepted)
{
}
}
} // namespace pdfviewer

View File

@ -98,6 +98,8 @@ private slots:
void on_actionPrint_triggered();
void on_actionRender_to_Images_triggered();
private:
void onActionOpenTriggered();
void onActionCloseTriggered();

View File

@ -32,6 +32,7 @@
<addaction name="separator"/>
<addaction name="actionSend_by_E_Mail"/>
<addaction name="actionPrint"/>
<addaction name="actionRender_to_Images"/>
<addaction name="separator"/>
<addaction name="actionProperties"/>
<addaction name="separator"/>
@ -450,6 +451,11 @@
<string>Print</string>
</property>
</action>
<action name="actionRender_to_Images">
<property name="text">
<string>Render to Images</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>