[TD]prevent crash on attempt to print hidden page
This commit is contained in:
@@ -56,7 +56,6 @@
|
||||
#include "QGSPage.h"
|
||||
#include "Rez.h"
|
||||
#include "ViewProviderPage.h"
|
||||
#include "MDIViewPage.h"
|
||||
|
||||
using namespace TechDrawGui;
|
||||
using namespace TechDraw;
|
||||
@@ -71,19 +70,6 @@ constexpr double mmPerInch = 25.4;
|
||||
|
||||
//TYPESYSTEM_SOURCE_ABSTRACT(TechDrawGui::PagePrinter)
|
||||
|
||||
PagePrinter::PagePrinter(ViewProviderPage* pageVp)
|
||||
: m_vpPage(pageVp), m_orientation(QPageLayout::Landscape),
|
||||
m_paperSize(QPageSize::A4), m_pagewidth(0.0), m_pageheight(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
void PagePrinter::setScene(QGSPage* scene)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
|
||||
void PagePrinter::setDocumentName(const std::string& name) { m_documentName = name; }
|
||||
|
||||
|
||||
//! retrieve the attributes of a DrawPage and its Template
|
||||
PaperAttributes PagePrinter::getPaperAttributes(TechDraw::DrawPage* dPage)
|
||||
@@ -99,144 +85,78 @@ PaperAttributes PagePrinter::getPaperAttributes(TechDraw::DrawPage* dPage)
|
||||
width = pageTemplate->Width.getValue();
|
||||
height = pageTemplate->Height.getValue();
|
||||
}
|
||||
result.pagewidth = width;
|
||||
result.pageheight = height;
|
||||
// result.m_pagewidth = width;
|
||||
// result.m_pageheight = height;
|
||||
|
||||
//Qt's page size determination assumes Portrait orientation. To get the right paper size
|
||||
//we need to ask in the proper form.
|
||||
QPageSize::PageSizeId paperSizeID =
|
||||
QPageSize::id(QSizeF(std::min(width, height), std::max(width, height)),
|
||||
QPageSize::Millimeter, QPageSize::FuzzyOrientationMatch);
|
||||
result.paperSize = paperSizeID;
|
||||
auto paperSize = paperSizeID;
|
||||
|
||||
result.orientation = (QPageLayout::Orientation)dPage->getOrientation();
|
||||
if (result.paperSize == QPageSize::Ledger) {
|
||||
auto orientation = (QPageLayout::Orientation)dPage->getOrientation();
|
||||
if (paperSize == QPageSize::Ledger) {
|
||||
// Ledger size paper orientation is reversed inside Qt
|
||||
result.orientation =(QPageLayout::Orientation)(1 - result.orientation);
|
||||
orientation = (QPageLayout::Orientation)(1 - orientation);
|
||||
}
|
||||
|
||||
return result;
|
||||
return {orientation, paperSize, width, height};
|
||||
}
|
||||
|
||||
void PagePrinter::getPaperAttributes()
|
||||
//! retrieve the attributes of a DrawPage by its viewProvider
|
||||
PaperAttributes PagePrinter::getPaperAttributes(ViewProviderPage* vpPage)
|
||||
{
|
||||
PaperAttributes attr = getPaperAttributes(m_vpPage->getDrawPage());
|
||||
m_pagewidth = attr.pagewidth;
|
||||
m_pageheight = attr.pageheight;
|
||||
m_paperSize = attr.paperSize;
|
||||
m_orientation = attr.orientation;
|
||||
auto page = vpPage->getDrawPage();
|
||||
return getPaperAttributes(page);
|
||||
}
|
||||
|
||||
|
||||
//! construct a page layout object that reflects the characteristics of a DrawPage
|
||||
//static
|
||||
void PagePrinter::makePageLayout(TechDraw::DrawPage* dPage, QPageLayout& pageLayout, double& width,
|
||||
double& height)
|
||||
{
|
||||
PaperAttributes attr = getPaperAttributes(dPage);
|
||||
width = attr.pagewidth;
|
||||
height = attr.pageheight;
|
||||
pageLayout.setPageSize(QPageSize(attr.paperSize));
|
||||
pageLayout.setOrientation(attr.orientation);
|
||||
width = attr.pageWidth();
|
||||
height = attr.pageHeight();
|
||||
pageLayout.setPageSize(QPageSize(attr.pageSize()));
|
||||
pageLayout.setOrientation(attr.orientation());
|
||||
pageLayout.setMode(QPageLayout::FullPageMode);
|
||||
pageLayout.setMargins(QMarginsF());
|
||||
}
|
||||
|
||||
/// print the Page associated with the parent MDIViewPage as a Pdf file
|
||||
void PagePrinter::printPdf(std::string file)
|
||||
{
|
||||
// Base::Console().Message("PP::printPdf(%s)\n", file.c_str());
|
||||
if (file.empty()) {
|
||||
Base::Console().Warning("PagePrinter - no file specified\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// set up the pdfwriter
|
||||
auto filespec = Base::Tools::escapeEncodeFilename(file);
|
||||
filespec = DU::cleanFilespecBackslash(filespec);
|
||||
QString outputFile = Base::Tools::fromStdString(filespec);
|
||||
QPdfWriter pdfWriter(outputFile);
|
||||
QPageLayout pageLayout = pdfWriter.pageLayout();
|
||||
auto marginsdb = pageLayout.margins(QPageLayout::Millimeter);
|
||||
QString documentName = QString::fromUtf8(m_vpPage->getDrawPage()->getNameInDocument());
|
||||
pdfWriter.setTitle(documentName);
|
||||
// default pdfWriter dpi is 1200.
|
||||
|
||||
// set up the page layout
|
||||
auto dPage = m_vpPage->getDrawPage();
|
||||
double width = A4Heightmm;//default to A4 Landscape 297 x 210
|
||||
double height = A4Widthmm;
|
||||
makePageLayout(dPage, pageLayout, width, height);
|
||||
pdfWriter.setPageLayout(pageLayout);
|
||||
marginsdb = pageLayout.margins(QPageLayout::Millimeter);
|
||||
|
||||
// first page does not respect page layout unless painter is created after
|
||||
// pdfWriter layout is established.
|
||||
QPainter painter(&pdfWriter);
|
||||
|
||||
// render the page
|
||||
m_scene->setExportingPdf(true);
|
||||
QRectF sourceRect(0.0, Rez::guiX(-height), Rez::guiX(width), Rez::guiX(height));
|
||||
double dpmm = pdfWriter.resolution() / mmPerInch;
|
||||
int twide = int(std::round(width * dpmm));
|
||||
int thigh = int(std::round(height * dpmm));
|
||||
QRect targetRect(0, 0, twide, thigh);
|
||||
renderPage(m_vpPage, painter, sourceRect, targetRect);
|
||||
m_scene->setExportingPdf(false);
|
||||
}
|
||||
|
||||
|
||||
/// print the Page associated with the parent MDIViewPage
|
||||
void PagePrinter::print(QPrinter* printer)
|
||||
{
|
||||
// Base::Console().Message("PP::print(printer)\n");
|
||||
QPageLayout pageLayout = printer->pageLayout();
|
||||
|
||||
TechDraw::DrawPage* dp = m_vpPage->getDrawPage();
|
||||
double width = A4Heightmm;//default to A4 Landscape 297 x 210
|
||||
double height = A4Widthmm;
|
||||
makePageLayout(dp, pageLayout, width, height);
|
||||
printer->setPageLayout(pageLayout);
|
||||
|
||||
QPainter painter(printer);
|
||||
|
||||
QRect targetRect = printer->pageLayout().fullRectPixels(printer->resolution());
|
||||
QRectF sourceRect(0.0, Rez::guiX(-height), Rez::guiX(width), Rez::guiX(height));
|
||||
renderPage(m_vpPage, painter, sourceRect, targetRect);
|
||||
}
|
||||
|
||||
//static routine to print all pages in a document
|
||||
//! print all pages in a document
|
||||
void PagePrinter::printAll(QPrinter* printer, App::Document* doc)
|
||||
{
|
||||
Base::Console().Message("PP::printAll()\n");
|
||||
|
||||
QPageLayout pageLayout = printer->pageLayout();
|
||||
std::vector<App::DocumentObject*> docObjs =
|
||||
doc->getObjectsOfType(TechDraw::DrawPage::getClassTypeId());
|
||||
auto firstPage = docObjs.front();
|
||||
|
||||
auto dPage = static_cast<TechDraw::DrawPage*>(firstPage);
|
||||
double width = A4Heightmm;//default to A4 Landscape 297 x 210
|
||||
double width = A4Heightmm; // default to A4 Landscape 297 x 210
|
||||
double height = A4Widthmm;
|
||||
makePageLayout(dPage, pageLayout, width, height);
|
||||
printer->setPageLayout(pageLayout);
|
||||
QPainter painter(printer);
|
||||
|
||||
auto ourDoc = Gui::Application::Instance->getDocument(doc);
|
||||
auto docModifiedState = ourDoc->isModified();
|
||||
|
||||
bool firstTime = true;
|
||||
for (auto& obj : docObjs) {
|
||||
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(obj);
|
||||
if (!vp) {
|
||||
continue;// can't print this one
|
||||
continue; // can't print this one
|
||||
}
|
||||
auto* vpp = dynamic_cast<TechDrawGui::ViewProviderPage*>(vp);
|
||||
if (!vpp) {
|
||||
continue;// can't print this one
|
||||
continue; // can't print this one
|
||||
}
|
||||
// is there always a mdi when printAll is called?
|
||||
auto mdi = vpp->getMDIViewPage();
|
||||
mdi->savePageExportState(vpp);
|
||||
|
||||
auto dPage = static_cast<TechDraw::DrawPage*>(obj);
|
||||
double width = A4Heightmm;//default to A4 Landscape 297 x 210
|
||||
double width = A4Heightmm; // default to A4 Landscape 297 x 210
|
||||
double height = A4Widthmm;
|
||||
makePageLayout(dPage, pageLayout, width, height);
|
||||
printer->setPageLayout(pageLayout);
|
||||
@@ -247,25 +167,27 @@ void PagePrinter::printAll(QPrinter* printer, App::Document* doc)
|
||||
firstTime = false;
|
||||
QRectF sourceRect(0.0, Rez::guiX(-height), Rez::guiX(width), Rez::guiX(height));
|
||||
QRect targetRect = printer->pageLayout().fullRectPixels(printer->resolution());
|
||||
|
||||
renderPage(vpp, painter, sourceRect, targetRect);
|
||||
mdi->resetPageExportState(vpp);
|
||||
dPage->redrawCommand();
|
||||
}
|
||||
|
||||
ourDoc->setModified(docModifiedState);
|
||||
}
|
||||
|
||||
//static routine to print all pages in a document to pdf
|
||||
//! print all pages in a document to pdf
|
||||
void PagePrinter::printAllPdf(QPrinter* printer, App::Document* doc)
|
||||
{
|
||||
// Base::Console().Message("PP::printAllPdf()\n");
|
||||
double dpmm = printer->resolution() / mmPerInch;
|
||||
|
||||
QString outputFile = printer->outputFileName();
|
||||
QString documentName = QString::fromUtf8(doc->getName());
|
||||
QPdfWriter pdfWriter(outputFile);
|
||||
// setPdfVersion sets the printed PDF Version to comply with PDF/A-1b, more details under: https://www.kdab.com/creating-pdfa-documents-qt/
|
||||
// but this is not working as of Qt 5.12
|
||||
//printer->setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
|
||||
//pdfWriter.setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
|
||||
|
||||
// setPdfVersion sets the printed PDF Version to comply with PDF/A-1b, more details under:
|
||||
// https://www.kdab.com/creating-pdfa-documents-qt/ but this is not working as of Qt 5.12
|
||||
// printer->setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
|
||||
// pdfWriter.setPdfVersion(QPagedPaintDevice::PdfVersion_A1b);
|
||||
|
||||
pdfWriter.setTitle(documentName);
|
||||
pdfWriter.setResolution(printer->resolution());
|
||||
QPageLayout pageLayout = printer->pageLayout();
|
||||
@@ -285,6 +207,9 @@ void PagePrinter::printAllPdf(QPrinter* printer, App::Document* doc)
|
||||
// start() or end() until all the pages are printed.
|
||||
QPainter painter(&pdfWriter);
|
||||
|
||||
auto ourDoc = Gui::Application::Instance->getDocument(doc);
|
||||
auto docModifiedState = ourDoc->isModified();
|
||||
|
||||
bool firstTime = true;
|
||||
for (auto& obj : docObjs) {
|
||||
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(obj);
|
||||
@@ -295,12 +220,9 @@ void PagePrinter::printAllPdf(QPrinter* printer, App::Document* doc)
|
||||
if (!vpp) {
|
||||
continue;// can't print this one
|
||||
}
|
||||
// is there always a mdi when printAll is called?
|
||||
auto mdi = vpp->getMDIViewPage();
|
||||
mdi->savePageExportState(vpp);
|
||||
|
||||
auto scene = vpp->getQGSPage();
|
||||
scene->setExportingPdf(true);
|
||||
auto ourScene = vpp->getQGSPage();
|
||||
ourScene->setExportingPdf(true);
|
||||
|
||||
auto dPage = static_cast<TechDraw::DrawPage*>(obj);
|
||||
double width{0};
|
||||
@@ -315,13 +237,16 @@ void PagePrinter::printAllPdf(QPrinter* printer, App::Document* doc)
|
||||
QRectF sourceRect(0.0, Rez::guiX(-height), Rez::guiX(width), Rez::guiX(height));
|
||||
QRect targetRect(0, 0, width * dpmm, height * dpmm);
|
||||
renderPage(vpp, painter, sourceRect, targetRect);
|
||||
mdi->resetPageExportState(vpp);
|
||||
dPage->redrawCommand();
|
||||
|
||||
ourScene->setExportingPdf(true);
|
||||
}
|
||||
|
||||
ourDoc->setModified(docModifiedState);
|
||||
}
|
||||
|
||||
//static
|
||||
//! we don't need the banner page any more
|
||||
|
||||
//! we don't need the banner page any more, but it might become useful again in the future.
|
||||
void PagePrinter::printBannerPage(QPrinter* printer, QPainter& painter, QPageLayout& pageLayout,
|
||||
App::Document* doc, std::vector<App::DocumentObject*>& docObjs)
|
||||
{
|
||||
@@ -353,11 +278,10 @@ void PagePrinter::printBannerPage(QPrinter* printer, QPainter& painter, QPageLay
|
||||
painter.setFont(savePainterFont);//restore the original font
|
||||
}
|
||||
|
||||
//static
|
||||
|
||||
void PagePrinter::renderPage(ViewProviderPage* vpp, QPainter& painter, QRectF& sourceRect,
|
||||
QRect& targetRect)
|
||||
{
|
||||
// Base::Console().Message("PP::renderPage()\n");
|
||||
//turn off view frames for print
|
||||
bool saveState = vpp->getFrameState();
|
||||
vpp->setFrameState(false);
|
||||
@@ -381,7 +305,90 @@ void PagePrinter::renderPage(ViewProviderPage* vpp, QPainter& painter, QRectF& s
|
||||
vpp->getQGSPage()->refreshViews();
|
||||
}
|
||||
|
||||
void PagePrinter::saveSVG(std::string file)
|
||||
|
||||
/// print the Page associated with the view provider
|
||||
void PagePrinter::print(ViewProviderPage* vpPage, QPrinter* printer)
|
||||
{
|
||||
QPageLayout pageLayout = printer->pageLayout();
|
||||
|
||||
TechDraw::DrawPage* dPage = vpPage->getDrawPage();
|
||||
double width = A4Heightmm; // default to A4 Landscape 297 x 210
|
||||
double height = A4Widthmm;
|
||||
makePageLayout(dPage, pageLayout, width, height);
|
||||
printer->setPageLayout(pageLayout);
|
||||
|
||||
QPainter painter(printer);
|
||||
|
||||
auto ourScene = vpPage->getQGSPage();
|
||||
if (!printer->outputFileName().isEmpty()) {
|
||||
ourScene->setExportingPdf(true);
|
||||
}
|
||||
auto ourDoc = Gui::Application::Instance->getDocument(dPage->getDocument());
|
||||
auto docModifiedState = ourDoc->isModified();
|
||||
|
||||
QRect targetRect = printer->pageLayout().fullRectPixels(printer->resolution());
|
||||
QRectF sourceRect(0.0, Rez::guiX(-height), Rez::guiX(width), Rez::guiX(height));
|
||||
renderPage(vpPage, painter, sourceRect, targetRect);
|
||||
|
||||
ourScene->setExportingPdf(false); // doesn't hurt if not pdf
|
||||
ourDoc->setModified(docModifiedState);
|
||||
dPage->redrawCommand();
|
||||
}
|
||||
|
||||
|
||||
/// print the Page associated with the ViewProvider as a Pdf file
|
||||
void PagePrinter::printPdf(ViewProviderPage* vpPage, const std::string& file)
|
||||
{
|
||||
if (file.empty()) {
|
||||
Base::Console().Warning("PagePrinter - no file specified\n");
|
||||
return;
|
||||
}
|
||||
|
||||
auto filespec = Base::Tools::escapeEncodeFilename(file);
|
||||
filespec = DU::cleanFilespecBackslash(filespec);
|
||||
|
||||
// set up the pdfwriter
|
||||
QString outputFile = Base::Tools::fromStdString(filespec);
|
||||
QPdfWriter pdfWriter(outputFile);
|
||||
QPageLayout pageLayout = pdfWriter.pageLayout();
|
||||
auto marginsdb = pageLayout.margins(QPageLayout::Millimeter);
|
||||
QString documentName = QString::fromUtf8(vpPage->getDrawPage()->getNameInDocument());
|
||||
pdfWriter.setTitle(documentName);
|
||||
// default pdfWriter dpi is 1200.
|
||||
|
||||
// set up the page layout
|
||||
auto dPage = vpPage->getDrawPage();
|
||||
double width = A4Heightmm; // default to A4 Landscape 297 x 210
|
||||
double height = A4Widthmm;
|
||||
makePageLayout(dPage, pageLayout, width, height);
|
||||
pdfWriter.setPageLayout(pageLayout);
|
||||
marginsdb = pageLayout.margins(QPageLayout::Millimeter);
|
||||
|
||||
// first page does not respect page layout unless painter is created after
|
||||
// pdfWriter layout is established.
|
||||
QPainter painter(&pdfWriter);
|
||||
|
||||
auto ourScene = vpPage->getQGSPage();
|
||||
ourScene->setExportingPdf(true);
|
||||
auto ourDoc = Gui::Application::Instance->getDocument(dPage->getDocument());
|
||||
auto docModifiedState = ourDoc->isModified();
|
||||
|
||||
// render the page
|
||||
QRectF sourceRect(0.0, Rez::guiX(-height), Rez::guiX(width), Rez::guiX(height));
|
||||
double dpmm = pdfWriter.resolution() / mmPerInch;
|
||||
int twide = int(std::round(width * dpmm));
|
||||
int thigh = int(std::round(height * dpmm));
|
||||
QRect targetRect(0, 0, twide, thigh);
|
||||
renderPage(vpPage, painter, sourceRect, targetRect);
|
||||
|
||||
ourScene->setExportingPdf(false);
|
||||
ourDoc->setModified(docModifiedState);
|
||||
dPage->redrawCommand();
|
||||
}
|
||||
|
||||
|
||||
//! save the page associated with the view provider as an svg file
|
||||
void PagePrinter::saveSVG(ViewProviderPage* vpPage, const std::string& file)
|
||||
{
|
||||
if (file.empty()) {
|
||||
Base::Console().Warning("PagePrinter - no file specified\n");
|
||||
@@ -390,14 +397,24 @@ void PagePrinter::saveSVG(std::string file)
|
||||
auto filespec = Base::Tools::escapeEncodeFilename(file);
|
||||
filespec = DU::cleanFilespecBackslash(file);
|
||||
QString filename = Base::Tools::fromStdString(filespec);
|
||||
if (m_scene) {
|
||||
m_scene->saveSvg(filename);
|
||||
}
|
||||
|
||||
auto ourScene = vpPage->getQGSPage();
|
||||
ourScene->setExportingSvg(true);
|
||||
auto ourDoc = vpPage->getDocument();
|
||||
auto docModifiedState = ourDoc->isModified();
|
||||
|
||||
ourScene->saveSvg(filename);
|
||||
|
||||
ourScene->setExportingSvg(false);
|
||||
ourDoc->setModified(docModifiedState);
|
||||
}
|
||||
|
||||
void PagePrinter::saveDXF(std::string inFileName)
|
||||
|
||||
//! save the page associated with the view provider as an svg file
|
||||
// Note: the dxf exporter does not modify the page, so we do not need to reset the modified flag
|
||||
void PagePrinter::saveDXF(ViewProviderPage* vpPage, const std::string& inFileName)
|
||||
{
|
||||
TechDraw::DrawPage* page = m_vpPage->getDrawPage();
|
||||
TechDraw::DrawPage* page = vpPage->getDrawPage();
|
||||
std::string PageName = page->getNameInDocument();
|
||||
auto filespec = Base::Tools::escapeEncodeFilename(inFileName);
|
||||
filespec = DU::cleanFilespecBackslash(filespec);
|
||||
@@ -405,21 +422,23 @@ void PagePrinter::saveDXF(std::string inFileName)
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "import TechDraw");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"TechDraw.writeDXFPage(App.activeDocument().%s, u\"%s\")",
|
||||
PageName.c_str(), filespec.c_str());
|
||||
PageName.c_str(),
|
||||
filespec.c_str());
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
|
||||
void PagePrinter::savePDF(std::string file)
|
||||
// this one is somewhat superfluous (just a redirect).
|
||||
void PagePrinter::savePDF(ViewProviderPage* vpPage, const std::string& file)
|
||||
{
|
||||
// Base::Console().Message("PP::savePDF(%s)\n", file.c_str());
|
||||
printPdf(file);
|
||||
printPdf(vpPage, file);
|
||||
}
|
||||
|
||||
|
||||
PaperAttributes::PaperAttributes()
|
||||
{
|
||||
// set default values to A4 Landscape
|
||||
orientation = QPageLayout::Orientation::Landscape;
|
||||
paperSize = QPageSize::A4;
|
||||
pagewidth = A4Heightmm;
|
||||
pageheight = A4Widthmm;
|
||||
m_orientation = QPageLayout::Orientation::Landscape;
|
||||
m_paperSize = QPageSize::A4;
|
||||
m_pagewidth = A4Heightmm;
|
||||
m_pageheight = A4Widthmm;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user