Core: Introduce PDF Import-Export dialog (#20860)

* Core: Introduce PDF Import-Export dialog

Currently, we only have hardcoded exporting to one pdf version, which
leads to (as in one of the below issues) to problems, such as
non-transparent layers, which are by default not supported in PDF/A-1b.

So, this patch adds an option to the user to select their preferred PDF
version by introducing new dialog under Import-Export in Preferences,
and allowing to update that version before exporting.

* Core: Add informational messages regarding selected PDF format

* Gui: Handle Qt < 6.8 unsupported PDF format

* Gui: Switch PDF export prefs dialog to use tr()

* Gui: Remove center alignment of PDF version description

---------

Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
This commit is contained in:
tetektoza
2025-04-28 02:31:34 +02:00
committed by GitHub
parent 8ba8c04b20
commit 8fda3b4bd1
11 changed files with 290 additions and 14 deletions

View File

@@ -44,6 +44,8 @@
#include <Base/PyWrapParseTupleAndKeywords.h>
#include <CXX/Objects.hxx>
#include <Gui/PreferencePages/DlgSettingsPDF.h>
#include "Application.h"
#include "ApplicationPy.h"
#include "BitmapFactory.h"
@@ -773,8 +775,10 @@ PyObject* ApplicationPy::sExport(PyObject * /*self*/, PyObject *args)
view3d->viewAll();
}
QPrinter printer(QPrinter::ScreenResolution);
// setPdfVersion sets the printed PDF Version to comply with PDF/A-1b, more details under: https://www.kdab.com/creating-pdfa-documents-qt/
printer.setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
// setPdfVersion sets the printed PDF Version to what is chosen in
// Preferences/Import-Export/PDF more details under:
// https://www.kdab.com/creating-pdfa-documents-qt/
printer.setPdfVersion(Gui::Dialog::DlgSettingsPDF::evaluatePDFVersion());
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);
printer.setCreator(QString::fromStdString(App::Application::getNameWithVersion()));

View File

@@ -418,6 +418,7 @@ SET(Gui_UIC_SRCS
PreferencePages/DlgSettingsUI.ui
PreferencePages/DlgSettingsViewColor.ui
PreferencePages/DlgSettingsWorkbenches.ui
PreferencePages/DlgSettingsPDF.ui
Dialogs/DlgCheckableMessageBox.ui
Dialogs/DlgToolbars.ui
Dialogs/DlgTreeWidget.ui
@@ -659,6 +660,7 @@ SET(Dialog_Settings_CPP_SRCS
Dialogs/DlgOnlineHelpImp.cpp
Dialogs/DlgPreferencesImp.cpp
PreferencePages/DlgSettings3DViewImp.cpp
PreferencePages/DlgSettingsPDF.cpp
PreferencePages/DlgSettingsCacheDirectory.cpp
Dialogs/DlgSettingsColorGradientImp.cpp
PreferencePages/DlgSettingsDocumentImp.cpp
@@ -681,6 +683,7 @@ SET(Dialog_Settings_HPP_SRCS
Dialogs/DlgOnlineHelpImp.h
Dialogs/DlgPreferencesImp.h
PreferencePages/DlgSettings3DViewImp.h
PreferencePages/DlgSettingsPDF.h
PreferencePages/DlgSettingsCacheDirectory.h
Dialogs/DlgSettingsColorGradientImp.h
PreferencePages/DlgSettingsDocumentImp.h
@@ -721,6 +724,7 @@ SET(Dialog_Settings_SRCS
PreferencePages/DlgSettingsUI.ui
PreferencePages/DlgSettingsViewColor.ui
PreferencePages/DlgSettingsWorkbenches.ui
PreferencePages/DlgSettingsPDF.ui
)
SOURCE_GROUP("Dialog\\Settings" FILES ${Dialog_Settings_SRCS})

View File

@@ -57,6 +57,8 @@
#include <Base/Interpreter.h>
#include <Base/Parameter.h>
#include <Gui/PreferencePages/DlgSettingsPDF.h>
using namespace Gui;
namespace Gui
@@ -511,9 +513,10 @@ void EditorView::printPdf()
QStringLiteral("%1 (*.pdf)").arg(tr("PDF file")));
if (!filename.isEmpty()) {
QPrinter printer(QPrinter::ScreenResolution);
// setPdfVersion sets the printied PDF Version to comply with PDF/A-1b, more details under:
// setPdfVersion sets the printed PDF Version to what is chosen in
// Preferences/Import-Export/PDF more details under:
// https://www.kdab.com/creating-pdfa-documents-qt/
printer.setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
printer.setPdfVersion(Gui::Dialog::DlgSettingsPDF::evaluatePDFVersion());
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(filename);
printer.setCreator(QString::fromStdString(App::Application::getNameWithVersion()));

View File

@@ -40,6 +40,7 @@
#include <Base/Interpreter.h>
#include <App/Document.h>
#include <App/Application.h>
#include <Gui/PreferencePages/DlgSettingsPDF.h>
#include "MDIView.h"
#include "MDIViewPy.h"
@@ -261,8 +262,10 @@ void MDIView::printPdf()
QStringLiteral("%1 (*.pdf)").arg(tr("PDF file")));
if (!filename.isEmpty()) {
QPrinter printer(QPrinter::ScreenResolution);
// setPdfVersion sets the printied PDF Version to comply with PDF/A-1b, more details under: https://www.kdab.com/creating-pdfa-documents-qt/
printer.setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
// setPdfVersion sets the printed PDF Version to what is chosen in
// Preferences/Import-Export/PDF more details under:
// https://www.kdab.com/creating-pdfa-documents-qt/
printer.setPdfVersion(Gui::Dialog::DlgSettingsPDF::evaluatePDFVersion());
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(filename);
printer.setCreator(QString::fromStdString(App::Application::getNameWithVersion()));

View File

@@ -0,0 +1,103 @@
#include "PreCompiled.h"
#include <App/Application.h>
#include <Base/Console.h>
#include "DlgSettingsPDF.h"
#include "ui_DlgSettingsPDF.h"
using namespace Gui::Dialog;
/* TRANSLATOR Gui::Dialog::DlgSettingsPDF */
DlgSettingsPDF::DlgSettingsPDF(QWidget* parent)
: PreferencePage( parent )
, ui(new Ui_DlgSettingsPDF)
{
ui->setupUi(this);
ui->warningLabel->setWordWrap(true);
connect(ui->comboBox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
this,
&DlgSettingsPDF::onComboBoxIndexChanged);
}
DlgSettingsPDF::~DlgSettingsPDF() = default;
void DlgSettingsPDF::saveSettings()
{
ui->comboBox->onSave();
}
void DlgSettingsPDF::loadSettings()
{
ui->comboBox->onRestore();
int currentIndex = ui->comboBox->currentIndex();
#if QT_VERSION < QT_VERSION_CHECK(6,8,0)
if (currentIndex == 3) {
Base::Console().Warning("When using another copy of FreeCAD you had set the PDF version to X4, but this build of FreeCAD does not support it. Using 1.4 instead.\n");
currentIndex = 0;
ui->comboBox->setCurrentIndex(0);
}
ui->comboBox->removeItem(3); // PdfVersion_X4
#endif
onComboBoxIndexChanged(currentIndex);
}
QPagedPaintDevice::PdfVersion DlgSettingsPDF::evaluatePDFVersion()
{
auto hGrp = App::GetApplication()
.GetUserParameter()
.GetGroup("BaseApp")
->GetGroup("Preferences")
->GetGroup("Mod");
const int ver = hGrp->GetInt("PDFVersion");
switch (ver) {
case 1:
return QPagedPaintDevice::PdfVersion_A1b;
case 2:
return QPagedPaintDevice::PdfVersion_1_6;
#if QT_VERSION >= QT_VERSION_CHECK(6,8,0)
case 3:
return QPagedPaintDevice::PdfVersion_X4;
#endif
default:
return QPagedPaintDevice::PdfVersion_1_4;
}
}
void DlgSettingsPDF::onComboBoxIndexChanged(int index)
{
switch (index) {
case 1:
ui->warningLabel->setText(
tr("This archival PDF format does not support transparency or layers. All content must be self-contained and static."));
break;
case 2:
ui->warningLabel->setText(
tr("While this version supports more modern features, older PDF readers may not fully handle it."));
break;
case 3:
ui->warningLabel->setText(
tr("This PDF format is intended for professional printing and requires all fonts to be embedded; some interactive features may not be supported."));
break;
default:
ui->warningLabel->setText(
tr("This PDF version has limited support for modern features like embedded multimedia and advanced transparency effects."));
break;
}
}
void DlgSettingsPDF::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
}
QWidget::changeEvent(e);
}
#include "moc_DlgSettingsPDF.cpp"

View File

@@ -0,0 +1,42 @@
#ifndef GUI_DIALOG_DLGSETTINGSPDF_H
#define GUI_DIALOG_DLGSETTINGSPDF_H
#include <Gui/PropertyPage.h>
#include <QPagedPaintDevice>
#include <memory>
namespace Gui {
namespace Dialog {
class Ui_DlgSettingsPDF;
/**
* The DlgSettingsPDF class implements a preference page to change settings
* for the PDF Import-Export.
*/
class GuiExport DlgSettingsPDF: public PreferencePage
{
Q_OBJECT
public:
explicit DlgSettingsPDF(QWidget* parent = nullptr);
~DlgSettingsPDF() override;
void saveSettings() override;
void loadSettings() override;
static QPagedPaintDevice::PdfVersion evaluatePDFVersion();
protected:
void changeEvent(QEvent *e) override;
private:
void onComboBoxIndexChanged(int index);
std::unique_ptr<Ui_DlgSettingsPDF> ui;
// Q_DISABLE_COPY_MOVE(DlgSettingsPDF)
};
} // namespace Dialog
} // namespace Gui
#endif // GUI_DIALOG_DLGSETTINGSPDF_H

View File

@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Gui::Dialog::DlgSettingsPDF</class>
<widget class="QWidget" name="Gui::Dialog::DlgSettingsPDF">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>446</width>
<height>462</height>
</rect>
</property>
<property name="windowTitle">
<string>PDF</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>9</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>PDF Export</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>PDF Version:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefComboBox" name="comboBox">
<property name="toolTip">
<string>This is the PDF Version FreeCAD will use to export to PDF.</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>PDFVersion</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod</cstring>
</property>
<item>
<property name="text">
<string>PDF/1.4</string>
</property>
</item>
<item>
<property name="text">
<string>PDF/A-1b</string>
</property>
</item>
<item>
<property name="text">
<string>PDF/1.6</string>
</property>
</item>
<item>
<property name="text">
<string>PDF/X-4</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="warningLabel">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
<customwidgets>
<customwidget>
<class>Gui::PrefComboBox</class>
<extends>QComboBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -58,6 +58,8 @@
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <Gui/PreferencePages/DlgSettingsPDF.h>
#include "View3DInventor.h"
#include "View3DSettings.h"
#include "Application.h"
@@ -254,8 +256,9 @@ void View3DInventor::printPdf()
if (!filename.isEmpty()) {
Gui::WaitCursor wc;
QPrinter printer(QPrinter::ScreenResolution);
// setPdfVersion sets the printied PDF Version to comply with PDF/A-1b, more details under: https://www.kdab.com/creating-pdfa-documents-qt/
printer.setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
// setPdfVersion sets the printed PDF Version to what is chosen in Preferences/Import-Export/PDF
// more details under: https://www.kdab.com/creating-pdfa-documents-qt/
printer.setPdfVersion(Gui::Dialog::DlgSettingsPDF::evaluatePDFVersion());
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setPageOrientation(QPageLayout::Landscape);
printer.setOutputFileName(filename);

View File

@@ -46,6 +46,7 @@
#include "PreferencePages/DlgSettingsViewColor.h"
#include "PreferencePages/DlgSettingsWorkbenchesImp.h"
#include "PreferencePages/DlgSettingsAdvanced.h"
#include "PreferencePages/DlgSettingsPDF.h"
#include "Dialogs/DlgToolbarsImp.h"
#include "Dialogs/DlgActionsImp.h"
@@ -88,6 +89,7 @@ WidgetFactorySupplier::WidgetFactorySupplier()
new PrefPageProducer<DlgSettingsAdvanced> ( QT_TRANSLATE_NOOP("QObject","Display") );
DlgSettingsUI::attachObserver();
new PrefPageProducer<DlgSettingsWorkbenchesImp> ( QT_TRANSLATE_NOOP("QObject","Workbenches") );
new PrefPageProducer<DlgSettingsPDF> ( QT_TRANSLATE_NOOP("QObject","Import-Export") );
new PrefPageProducer<DlgSettingsMacroImp> ( QT_TRANSLATE_NOOP("QObject", "Python"));
new PrefPageProducer<DlgSettingsPythonConsole> ( QT_TRANSLATE_NOOP("QObject", "Python"));
new PrefPageProducer<DlgSettingsEditor> ( QT_TRANSLATE_NOOP("QObject", "Python"));

View File

@@ -40,6 +40,7 @@
#include <Gui/Document.h>
#include <Gui/FileDialog.h>
#include <Gui/MainWindow.h>
#include <Gui/PreferencePages/DlgSettingsPDF.h>
#include <Mod/Spreadsheet/App/Sheet.h>
#include <Mod/Spreadsheet/App/SheetPy.h>
@@ -302,9 +303,10 @@ void SheetView::printPdf()
QStringLiteral("%1 (*.pdf)").arg(tr("PDF file")));
if (!filename.isEmpty()) {
QPrinter printer(QPrinter::ScreenResolution);
// setPdfVersion sets the printied PDF Version to comply with PDF/A-1b, more details under:
// setPdfVersion sets the printed PDF Version to what is chosen in
// Preferences/Import-Export/PDF more details under:
// https://www.kdab.com/creating-pdfa-documents-qt/
printer.setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
printer.setPdfVersion(Gui::Dialog::DlgSettingsPDF::evaluatePDFVersion());
printer.setPageOrientation(QPageLayout::Landscape);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(filename);

View File

@@ -45,6 +45,7 @@
#include <Gui/Command.h>
#include <Gui/Document.h>
#include <Gui/ViewProvider.h>
#include <Gui/PreferencePages/DlgSettingsPDF.h>
#include <Mod/TechDraw/App/DrawPage.h>
#include <Mod/TechDraw/App/DrawPagePy.h>
@@ -183,9 +184,9 @@ void PagePrinter::printAllPdf(QPrinter* printer, App::Document* doc)
QString documentName = QString::fromUtf8(doc->getName());
QPdfWriter pdfWriter(outputFile);
// set the printed PDF Version to comply with PDF/A-1b, more details under:
// https://www.kdab.com/creating-pdfa-documents-qt/
pdfWriter.setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
// setPdfVersion sets the printed PDF Version to what is chosen in Preferences/Import-Export/PDF
// more details under: https://www.kdab.com/creating-pdfa-documents-qt/
pdfWriter.setPdfVersion(Gui::Dialog::DlgSettingsPDF::evaluatePDFVersion());
pdfWriter.setTitle(documentName);
pdfWriter.setCreator(QString::fromStdString(App::Application::getNameWithVersion())
@@ -352,7 +353,7 @@ void PagePrinter::printPdf(ViewProviderPage* vpPage, const std::string& file)
// set up the pdfwriter
QString outputFile = QString::fromStdString(filespec);
QPdfWriter pdfWriter(outputFile);
pdfWriter.setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
pdfWriter.setPdfVersion(Gui::Dialog::DlgSettingsPDF::evaluatePDFVersion());
QPageLayout pageLayout = pdfWriter.pageLayout();
auto marginsdb = pageLayout.margins(QPageLayout::Millimeter);
QString documentName = QString::fromUtf8(vpPage->getDrawPage()->getNameInDocument());