include/svx/graphichelper.hxx | 12 ++++ include/vcl/print.hxx | 3 + sc/source/ui/drawfunc/chartsh.cxx | 9 +++ sd/source/ui/view/DocumentRenderer.cxx | 20 +++---- svx/source/core/graphichelper.cxx | 83 ++++++++++++++++++++++++--------- vcl/inc/printdlg.hxx | 1 vcl/source/gdi/print.cxx | 5 + vcl/source/window/printdlg.cxx | 30 ++++++++--- 8 files changed, 119 insertions(+), 44 deletions(-)
New commits: commit 2b6853729591c9a687cf5855a26acc2a4e8f5e5d Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Jan 4 16:28:03 2022 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Tue Mar 15 13:01:53 2022 +0100 sc export chart as graphic: handle PDF The context menu for Calc charts would call into GraphicFilter::ExportGraphic(), which has explicit code for e.g. SVG, but not for PDF. The graphic exporter to PDF is only meant to work with images backed with PDF data, not with all shapes. Fix the problem by explicitly handling PDF in GraphicHelper::SaveShapeAsGraphic() in svx/, and invoking the normal PDF export in that case. Continue to fall back to XGraphicExportFilter for other formats. This requires passing down the current document from sc/. (cherry picked from commit 77d2bbaa18e0be5347d7bd7167b245264789e0a4) Conflicts: sc/source/ui/drawfunc/chartsh.cxx svx/Module_svx.mk svx/source/core/graphichelper.cxx Change-Id: Ia5f78bffa1d26989bb0ad3ed265b922e609f076f diff --git a/include/svx/graphichelper.hxx b/include/svx/graphichelper.hxx index b582de4a2669..7a5e483a1b37 100644 --- a/include/svx/graphichelper.hxx +++ b/include/svx/graphichelper.hxx @@ -24,6 +24,10 @@ #include <svx/svxdllapi.h> namespace com::sun::star::drawing { class XShape; } +namespace com::sun::star::lang +{ +class XComponent; +} namespace weld { class Widget; } namespace weld { class Window; } @@ -33,7 +37,13 @@ class SVXCORE_DLLPUBLIC GraphicHelper public: static void GetPreferredExtension( OUString& rExtension, const Graphic& rGraphic ); static OUString ExportGraphic(weld::Window* pWin, const Graphic& rGraphic, const OUString& rGraphicName); - static void SaveShapeAsGraphic(weld::Window* pWin, const css::uno::Reference< css::drawing::XShape >& xShape); + static void + SaveShapeAsGraphicToPath(const css::uno::Reference<css::lang::XComponent>& xComponent, + const css::uno::Reference<css::drawing::XShape>& xShape, + const OUString& rMimeType, const OUString& rPath); + static void SaveShapeAsGraphic(weld::Window* pWin, + const css::uno::Reference<css::lang::XComponent>& xComponent, + const css::uno::Reference<css::drawing::XShape>& xShape); static short HasToSaveTransformedImage(weld::Widget* pWin); }; diff --git a/sc/source/ui/drawfunc/chartsh.cxx b/sc/source/ui/drawfunc/chartsh.cxx index 25b66b0fb7e2..87b73f4fc88d 100644 --- a/sc/source/ui/drawfunc/chartsh.cxx +++ b/sc/source/ui/drawfunc/chartsh.cxx @@ -92,8 +92,15 @@ void ScChartShell::ExecuteExportAsGraphic( SfxRequest& ) if( dynamic_cast<const SdrOle2Obj*>( pObject) ) { vcl::Window* pWin = GetViewData().GetActiveWin(); + css::uno::Reference<css::lang::XComponent> xComponent; + const SfxObjectShell* pShell = GetObjectShell(); + if (pShell) + { + xComponent = pShell->GetModel(); + } Reference< drawing::XShape > xSourceDoc( pObject->getUnoShape(), UNO_QUERY_THROW ); - GraphicHelper::SaveShapeAsGraphic(pWin ? pWin->GetFrameWeld() : nullptr, xSourceDoc); + GraphicHelper::SaveShapeAsGraphic(pWin ? pWin->GetFrameWeld() : nullptr, xComponent, + xSourceDoc); } } diff --git a/svx/source/core/graphichelper.cxx b/svx/source/core/graphichelper.cxx index 160f8147f76c..18a86bad37e4 100644 --- a/svx/source/core/graphichelper.cxx +++ b/svx/source/core/graphichelper.cxx @@ -46,9 +46,14 @@ #include <com/sun/star/beans/XPropertyAccess.hpp> #include <com/sun/star/task/ErrorCodeIOException.hpp> #include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/drawing/ShapeCollection.hpp> #include <map> +#include <sfx2/objsh.hxx> +#include <unotools/streamwrap.hxx> +#include <comphelper/propertyvalue.hxx> + using namespace css::uno; using namespace css::lang; using namespace css::graphic; @@ -338,7 +343,61 @@ OUString GraphicHelper::ExportGraphic(weld::Window* pParent, const Graphic& rGra return OUString(); } -void GraphicHelper::SaveShapeAsGraphic(weld::Window* pParent, const Reference< drawing::XShape >& xShape) +void GraphicHelper::SaveShapeAsGraphicToPath( + const css::uno::Reference<css::lang::XComponent>& xComponent, + const css::uno::Reference<css::drawing::XShape>& xShape, const OUString& aExportMimeType, + const OUString& sPath) +{ + Reference<XComponentContext> xContext(::comphelper::getProcessComponentContext()); + Reference<XInputStream> xGraphStream; + + if (xGraphStream.is()) + { + Reference<XSimpleFileAccess3> xFileAccess = SimpleFileAccess::create(xContext); + xFileAccess->writeFile(sPath, xGraphStream); + } + else if (xComponent.is() && aExportMimeType == "application/pdf") + { + css::uno::Reference<css::lang::XMultiServiceFactory> xMSF(xContext->getServiceManager(), + css::uno::UNO_QUERY); + css::uno::Reference<css::document::XExporter> xExporter( + xMSF->createInstance("com.sun.star.comp.PDF.PDFFilter"), css::uno::UNO_QUERY); + xExporter->setSourceDocument(xComponent); + + css::uno::Reference<css::drawing::XShapes> xShapes + = css::drawing::ShapeCollection::create(comphelper::getProcessComponentContext()); + xShapes->add(xShape); + css::uno::Sequence<PropertyValue> aFilterData{ + comphelper::makePropertyValue("Selection", xShapes), + }; + SvFileStream aStream(sPath, StreamMode::READWRITE | StreamMode::TRUNC); + css::uno::Reference<css::io::XOutputStream> xStream(new utl::OStreamWrapper(aStream)); + css::uno::Sequence<PropertyValue> aDescriptor{ + comphelper::makePropertyValue("FilterData", aFilterData), + comphelper::makePropertyValue("OutputStream", xStream) + }; + css::uno::Reference<css::document::XFilter> xFilter(xExporter, css::uno::UNO_QUERY); + xFilter->filter(aDescriptor); + } + else + { + Reference<css::drawing::XGraphicExportFilter> xGraphicExporter = css::drawing::GraphicExportFilter::create( xContext ); + + Sequence<PropertyValue> aDescriptor( 2 ); + aDescriptor[0].Name = "MediaType"; + aDescriptor[0].Value <<= aExportMimeType; + aDescriptor[1].Name = "URL"; + aDescriptor[1].Value <<= sPath; + + Reference< XComponent > xSourceDocument( xShape, UNO_QUERY_THROW ); + xGraphicExporter->setSourceDocument( xSourceDocument ); + xGraphicExporter->filter( aDescriptor ); + } +} + +void GraphicHelper::SaveShapeAsGraphic(weld::Window* pParent, + const css::uno::Reference<css::lang::XComponent>& xComponent, + const Reference<drawing::XShape>& xShape) { try { @@ -386,27 +445,7 @@ void GraphicHelper::SaveShapeAsGraphic(weld::Window* pParent, const Reference< OUString sPath( xFilePicker->getFiles().getConstArray()[0] ); OUString aExportMimeType( aMimeTypeMap[xFilePicker->getCurrentFilter()] ); - Reference< XInputStream > xGraphStream; - - if( xGraphStream.is() ) - { - Reference<XSimpleFileAccess3> xFileAccess = SimpleFileAccess::create( xContext ); - xFileAccess->writeFile( sPath, xGraphStream ); - } - else - { - Reference<css::drawing::XGraphicExportFilter> xGraphicExporter = css::drawing::GraphicExportFilter::create( xContext ); - - Sequence<PropertyValue> aDescriptor( 2 ); - aDescriptor[0].Name = "MediaType"; - aDescriptor[0].Value <<= aExportMimeType; - aDescriptor[1].Name = "URL"; - aDescriptor[1].Value <<= sPath; - - Reference< XComponent > xSourceDocument( xShape, UNO_QUERY_THROW ); - xGraphicExporter->setSourceDocument( xSourceDocument ); - xGraphicExporter->filter( aDescriptor ); - } + GraphicHelper::SaveShapeAsGraphicToPath(xComponent, xShape, aExportMimeType, sPath); } } catch( Exception& ) commit d58091edd8e248de4042d56751115784c206144d Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Wed Nov 10 14:34:39 2021 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Tue Mar 15 13:00:36 2022 +0100 tdf#145354: Revert "tdf#91362: Use document paper size for printing slides" Reverting it has been suggested a couple of times over the years, for instance in https://bugs.documentfoundation.org/show_bug.cgi?id=91362#c23 and in https://bugs.documentfoundation.org/show_bug.cgi?id=145354#c41 . The paper size for a presentation document is typically just made-up dimensions with no connection to any actual paper size. (Or transparency size.) What matters is the aspect ratio. This reverts commit 57991f885e60d04e93bf5004d4fdceee7d29f3d8 Change-Id: I5099039f5fdb836694f2b100fb28093584e8294b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125111 Tested-by: Aron Budea <aron.bu...@collabora.com> Reviewed-by: Aron Budea <aron.bu...@collabora.com> diff --git a/sd/source/ui/view/DocumentRenderer.cxx b/sd/source/ui/view/DocumentRenderer.cxx index 7d8e8c6fdb25..d03c7d6dadf7 100644 --- a/sd/source/ui/view/DocumentRenderer.cxx +++ b/sd/source/ui/view/DocumentRenderer.cxx @@ -153,7 +153,7 @@ namespace { return nQuality; } - bool IsPaperSize() const + bool IsPageSize() const { return GetBoolValue("PageOptions", sal_Int32(1)); } @@ -173,10 +173,10 @@ namespace { return GetBoolValue("PrintProspect", false); } - bool IsPrinterPreferred() const + bool IsPrinterPreferred(DocumentType eDocType) const { - return IsTilePage() || IsPaperSize() || IsBooklet() || - IsNotes() || IsHandout() || IsOutline(); + bool bIsDraw = eDocType == DocumentType::Draw; + return IsTilePage() || IsPageSize() || IsBooklet() || (!bIsDraw && !IsNotes()); } bool IsPrintExcluded() const @@ -1374,7 +1374,7 @@ private: // Draw and Notes should usually abide by their specified paper size Size aPaperSize; - if (!mpOptions->IsPrinterPreferred()) + if (!mpOptions->IsPrinterPreferred(pDocument->GetDocumentType())) { aPaperSize.setWidth(rInfo.maPageSize.Width()); aPaperSize.setHeight(rInfo.maPageSize.Height()); @@ -1387,7 +1387,7 @@ private: maPrintSize = awt::Size(aPaperSize.Width(), aPaperSize.Height()); - if (mpOptions->IsPrinterPreferred()) + if (mpOptions->IsPrinterPreferred(pDocument->GetDocumentType())) { if( (rInfo.meOrientation == Orientation::Landscape && (aPaperSize.Width() < aPaperSize.Height())) @@ -1448,7 +1448,7 @@ private: aInfo.msTimeDate += GetSdrGlobalData().GetLocaleData()->getTime( ::tools::Time( ::tools::Time::SYSTEM ), false ); // Draw and Notes should usually use specified paper size when printing - if (!mpOptions->IsPrinterPreferred()) + if (!mpOptions->IsPrinterPreferred(mrBase.GetDocShell()->GetDocumentType())) { aInfo.maPrintSize = mrBase.GetDocument()->GetSdPage(0, PageKind::Standard)->GetSize(); maPrintSize = awt::Size(aInfo.maPrintSize.Width(), @@ -1770,7 +1770,7 @@ private: OSL_ASSERT(pDocument != nullptr); SdPage& rHandoutPage (*pDocument->GetSdPage(0, PageKind::Handout)); - const bool bScalePage (mpOptions->IsPaperSize()); + const bool bScalePage (mpOptions->IsPageSize()); sal_uInt16 nPaperBin; if ( ! mpOptions->IsPaperBin()) @@ -1930,7 +1930,7 @@ private: // is it possible that the page size changed? const Size aPageSize = pPage->GetSize(); - if (mpOptions->IsPrinterPreferred()) + if (mpOptions->IsPageSize()) { const double fHorz (static_cast<double>(rInfo.maPrintSize.Width()) / aPageSize.Width()); const double fVert (static_cast<double>(rInfo.maPrintSize.Height()) / aPageSize.Height()); @@ -2159,7 +2159,7 @@ private: // (without the unprintable borders). // 3. Split the page into parts of the size of the // printable area. - const bool bScalePage (mpOptions->IsPaperSize()); + const bool bScalePage (mpOptions->IsPageSize()); const bool bCutPage (mpOptions->IsCutPage()); MapMode aMap (rInfo.maMap); if ( (bScalePage || bCutPage) && CheckForFrontBackPages( nPageIndex ) ) commit 6067394c40bab250d182d8ef1dac101c5f0368e5 Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Tue Nov 9 13:37:33 2021 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Tue Mar 15 13:00:32 2022 +0100 tdf#145354: Don't let an arbitrary paper size match any other arbitrary size Don't preselect whatever random paper size the printer driver offers last if the document is asking for some other random paper size. Change-Id: I57af245f28f0d61541da698844f2527be5ec004e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124911 Tested-by: Jenkins Reviewed-by: Tor Lillqvist <t...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124926 Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index 89f656200806..4ff70cb9917a 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -868,6 +868,7 @@ void PrintDialog::setPaperSizes() VclPtr<Printer> aPrt( maPController->getPrinter() ); mePaper = aPrt->GetPaper(); + Size aSizeOfPaper = aPrt->GetSizeOfPaper(); if ( isPrintToFile() ) { @@ -906,8 +907,9 @@ void PrintDialog::setPaperSizes() mxPaperSizeBox->append_text(aPaperName); - if ( ePaper == mePaper ) - mxPaperSizeBox->set_active( nPaper ); + if ( (ePaper != PAPER_USER && ePaper == mePaper) || + (ePaper == PAPER_USER && aInfo.sloppyEqual( PaperInfo(aSizeOfPaper.getWidth(), aSizeOfPaper.getHeight())) ) ) + mxPaperSizeBox->set_active( nPaper ); } mxPaperSizeBox->set_sensitive( true ); commit 3616578d615a3f8ca030f407e4da2b9addd037ca Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Tue Nov 9 13:16:29 2021 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Tue Mar 15 13:00:28 2022 +0100 Add Printer::GetSizeOfPaper() with semantics to match GetPaper() Will be used in follow-up commits. Change-Id: I18b167a217a4f82d8b6605e2ba14f1ddc6e98324 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124910 Reviewed-by: Tor Lillqvist <t...@collabora.com> Tested-by: Tor Lillqvist <t...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124925 Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/include/vcl/print.hxx b/include/vcl/print.hxx index 3d50fd089a60..34a154f64aff 100644 --- a/include/vcl/print.hxx +++ b/include/vcl/print.hxx @@ -294,7 +294,10 @@ public: sal_uInt16 GetPaperBin() const; void SetPaper( Paper ePaper ); bool SetPaperSizeUser( const Size& rSize ); + /** @return The paper format of the printer's current "jobsetup". Note that if PAPER_USER the actual size can be anything. */ Paper GetPaper() const; + /** @return Size of the paper of the printer's current "jobsetup". */ + Size GetSizeOfPaper() const; static OUString GetPaperName( Paper ePaper ); /** @return Number of available paper formats */ diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx index fb3e5de9a95b..ba7c63296c97 100644 --- a/vcl/source/gdi/print.cxx +++ b/vcl/source/gdi/print.cxx @@ -1470,6 +1470,11 @@ Paper Printer::GetPaper() const return maJobSetup.ImplGetConstData().GetPaperFormat(); } +Size Printer::GetSizeOfPaper() const +{ + return Size(maJobSetup.ImplGetConstData().GetPaperWidth(), maJobSetup.ImplGetConstData().GetPaperHeight()); +} + sal_uInt16 Printer::GetPaperBinCount() const { if ( IsDisplayPrinter() ) commit 59c39cf967eda78759d583937479811908ae9ddf Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Wed Nov 3 14:58:45 2021 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Tue Mar 15 13:00:24 2022 +0100 tdf#145354: Don't claim random paper sizes from the system are "User Defined" For instance, the driver for my printer (or maybe Windows itself, no idea where the list of sizes comes from originally) says it supports 215 x 345 mm. Which apparently is an obscure paper size called "India Legal". It is confusing if the Print dialog claims that it is "User Defined" when I have never even heard of such a size, and the document does not specify it either. Change-Id: I44196fd21fd83a94d255ebb909e5d63e35c5d1e8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124649 Reviewed-by: Tor Lillqvist <t...@collabora.com> Tested-by: Tor Lillqvist <t...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124924 Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index 0afe5d487a8f..89f656200806 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -895,7 +895,14 @@ void PrintDialog::setPaperSizes() OUString aWidth( rLocWrap.getNum( aLogicPaperSize.Width(), nDigits ) ); OUString aHeight( rLocWrap.getNum( aLogicPaperSize.Height(), nDigits ) ); OUString aUnit = eUnit == MapUnit::MapMM ? OUString("mm") : OUString("in"); - OUString aPaperName = Printer::GetPaperName( ePaper ) + " " + aWidth + aUnit + " x " + aHeight + aUnit; + OUString aPaperName; + + // Paper sizes that we don't know of but the system printer driver lists are not "User + // Defined". Displaying them as such is just confusing. + if (ePaper != PAPER_USER) + aPaperName = Printer::GetPaperName( ePaper ) + " "; + + aPaperName += aWidth + aUnit + " x " + aHeight + aUnit; mxPaperSizeBox->append_text(aPaperName); commit 3e7ccf89394835ef94fe9a7e46e0d695c1b79125 Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Tue Nov 2 20:16:31 2021 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Tue Mar 15 13:00:20 2022 +0100 tdf#145354: Ensure displayed paper name matches displayed paper dimensions I could not reproduce it now but at least in some slightly older version of LibreOffice, it could happen that at the top of the print preview image was displayed "143 mm (A4)" which is silly, as neither side of an A4 paper is 143 mm. Look up the matching paper size from the dimensions displayed. Use the "sloppy" match function to allow for sub-millimeter rounding errors. Change-Id: I6320798061246101c6fc78baf841b71b32b25833 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124635 Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/vcl/inc/printdlg.hxx b/vcl/inc/printdlg.hxx index db1e6a73bcfc..703b4f247fe9 100644 --- a/vcl/inc/printdlg.hxx +++ b/vcl/inc/printdlg.hxx @@ -65,7 +65,6 @@ namespace vcl virtual void Resize() override; void setPreview( const GDIMetaFile&, const Size& i_rPaperSize, - const OUString& i_rPaperName, const OUString& i_rNoPageString, sal_Int32 i_nDPIX, sal_Int32 i_nDPIY, bool i_bGreyscale diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index 8866abe43733..0afe5d487a8f 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -214,7 +214,6 @@ bool PrintDialog::PrintPreviewWindow::Command( const CommandEvent& rEvt ) void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPreview, const Size& i_rOrigSize, - const OUString& i_rPaperName, const OUString& i_rReplacement, sal_Int32 i_nDPIX, sal_Int32 i_nDPIY, @@ -243,12 +242,18 @@ void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPrevi aBuf.append( aNumText ) .append( u' ' ); aBuf.appendAscii( eUnit == MapUnit::MapMM ? "mm" : "in" ); - if( !i_rPaperName.isEmpty() ) + + // Look up the paper name from the dimensions + PaperInfo aPaperInfoFromSize(i_rOrigSize.getWidth(), i_rOrigSize.getHeight()); + aPaperInfoFromSize.doSloppyFit(); + + if (aPaperInfoFromSize.getPaper() != PAPER_USER) { aBuf.append( " (" ); - aBuf.append( i_rPaperName ); + aBuf.append( Printer::GetPaperName(aPaperInfoFromSize.getPaper()) ); aBuf.append( ')' ); } + maHorzText = aBuf.makeStringAndClear(); aNumText = rLocWrap.getNum( aLogicPaperSize.Height(), nDigits ); @@ -953,7 +958,6 @@ void PrintDialog::preparePreview( bool i_bMayUseCache ) if ( !hasPreview() ) { mxPreview->setPreview( aMtf, aCurPageSize, - Printer::GetPaperName( mePaper ), maNoPreviewStr, aPrt->GetDPIX(), aPrt->GetDPIY(), aPrt->GetPrinterOptions().IsConvertToGreyscales() @@ -988,7 +992,6 @@ void PrintDialog::preparePreview( bool i_bMayUseCache ) } mxPreview->setPreview( aMtf, aCurPageSize, - Printer::GetPaperName( mePaper ), nPages > 0 ? OUString() : maNoPageStr, aPrt->GetDPIX(), aPrt->GetDPIY(), aPrt->GetPrinterOptions().IsConvertToGreyscales()