sfx2/inc/SfxRedactionHelper.hxx | 29 ++++ sfx2/source/doc/SfxRedactionHelper.cxx | 200 ++++++++++++++++++++++++++++----- sfx2/source/doc/objserv.cxx | 12 + 3 files changed, 205 insertions(+), 36 deletions(-)
New commits: commit 35157cb3a8b4b7b8983192df4e8168ebf4d3a9f5 Author: Muhammet Kara <muhammet.k...@collabora.com> AuthorDate: Tue May 7 22:03:25 2019 +0300 Commit: Muhammet Kara <muhammet.k...@collabora.com> CommitDate: Mon Jun 17 22:54:26 2019 +0200 Respect page margins of the source doc during redaction Change-Id: Ieaa50a2eba17145180ddd5d2bfc77add4801c43a Reviewed-on: https://gerrit.libreoffice.org/71929 Tested-by: Jenkins Reviewed-by: Muhammet Kara <muhammet.k...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/74224 Tested-by: Muhammet Kara <muhammet.k...@collabora.com> diff --git a/sfx2/inc/SfxRedactionHelper.hxx b/sfx2/inc/SfxRedactionHelper.hxx index 8b1bdd57e247..ac15bb790fe9 100644 --- a/sfx2/inc/SfxRedactionHelper.hxx +++ b/sfx2/inc/SfxRedactionHelper.hxx @@ -12,6 +12,8 @@ #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> #include <sal/types.h> #include <rtl/ustring.hxx> @@ -29,6 +31,15 @@ class GDIMetaFile; class DocumentToGraphicRenderer; class SfxViewFrame; +struct PageMargins +{ + // Page margins in mm100th + sal_Int32 nTop; + sal_Int32 nBottom; + sal_Int32 nLeft; + sal_Int32 nRight; +}; + /* * Mostly a bunch of static methods to handle the redaction functionality at * different points of the process. @@ -56,13 +67,26 @@ public: * */ static void addPagesToDraw(uno::Reference<XComponent>& xComponent, const sal_Int32& nPages, const std::vector<GDIMetaFile>& aMetaFiles, - const std::vector<::Size>& aPageSizes); + const std::vector<::Size>& aPageSizes, + const PageMargins& aPageMargins); /* * Makes the Redaction toolbar visible to the user. * Meant to be called after converting a document to a Draw doc * for redaction purposes. * */ static void showRedactionToolbar(SfxViewFrame* pViewFrame); + + /* + * Used to get the page margins from the original/source Writer document. Then we apply these values to the + * pages inserted into Draw for redaction. + * */ + static PageMargins getPageMarginsForWriter(css::uno::Reference<css::frame::XModel>& xModel); + + /* + * Used to get the page margins from the original/source Calc document. Then we apply these values to the + * pages inserted into Draw for redaction. + * */ + static PageMargins getPageMarginsForCalc(css::uno::Reference<css::frame::XModel>& xModel); }; #endif // INCLUDED_CUI_SOURCE_INC_SFXREDACTIONHELPER_HXX diff --git a/sfx2/source/doc/SfxRedactionHelper.cxx b/sfx2/source/doc/SfxRedactionHelper.cxx index d898dfc4130c..457ed41d1b9a 100644 --- a/sfx2/source/doc/SfxRedactionHelper.cxx +++ b/sfx2/source/doc/SfxRedactionHelper.cxx @@ -11,10 +11,17 @@ #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> +// For page margin related methods +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/text/XPageCursor.hpp> +#include <com/sun/star/text/XTextViewCursor.hpp> +#include <com/sun/star/text/XTextViewCursorSupplier.hpp> +#include <com/sun/star/sheet/XSpreadsheetView.hpp> + #include <sfx2/request.hxx> #include <sfx2/sfxsids.hrc> #include <sfx2/viewfrm.hxx> @@ -65,6 +72,12 @@ OUString SfxRedactionHelper::getStringParam(const SfxRequest& rReq, const sal_uI namespace { +/* + * Roundtrip the gdimetafile to and from WMF + * to get rid of the position and size irregularities + * We better check the conversion method to see what it + * actually does to correct these issues, and do it ourselves. + * */ void fixMetaFile(GDIMetaFile& tmpMtf) { SvMemoryStream aDestStrm(65535, 65535); @@ -75,6 +88,22 @@ void fixMetaFile(GDIMetaFile& tmpMtf) ReadWindowMetafile(aDestStrm, tmpMtf); } + +/* + * Sets page margins for a Draw page. Negative values are considered erronous. + * */ +void setPageMargins(uno::Reference<beans::XPropertySet>& xPageProperySet, + const PageMargins& aPageMargins) +{ + if (aPageMargins.nTop < 0 || aPageMargins.nBottom < 0 || aPageMargins.nLeft < 0 + || aPageMargins.nRight < 0) + return; + + xPageProperySet->setPropertyValue("BorderTop", css::uno::makeAny(aPageMargins.nTop)); + xPageProperySet->setPropertyValue("BorderBottom", css::uno::makeAny(aPageMargins.nBottom)); + xPageProperySet->setPropertyValue("BorderLeft", css::uno::makeAny(aPageMargins.nLeft)); + xPageProperySet->setPropertyValue("BorderRight", css::uno::makeAny(aPageMargins.nRight)); +} } void SfxRedactionHelper::getPageMetaFilesFromDoc(std::vector<GDIMetaFile>& aMetaFiles, @@ -114,7 +143,8 @@ void SfxRedactionHelper::getPageMetaFilesFromDoc(std::vector<GDIMetaFile>& aMeta void SfxRedactionHelper::addPagesToDraw(uno::Reference<XComponent>& xComponent, const sal_Int32& nPages, const std::vector<GDIMetaFile>& aMetaFiles, - const std::vector<::Size>& aPageSizes) + const std::vector<::Size>& aPageSizes, + const PageMargins& aPageMargins) { // Access the draw pages uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(xComponent, uno::UNO_QUERY); @@ -133,11 +163,13 @@ void SfxRedactionHelper::addPagesToDraw(uno::Reference<XComponent>& xComponent, uno::Reference<graphic::XGraphic> xGraph = aGraphic.GetXGraphic(); uno::Reference<drawing::XDrawPage> xPage = xDrawPages->insertNewByIndex(nPage); - // Set page size + // Set page size & margins uno::Reference<beans::XPropertySet> xPageProperySet(xPage, uno::UNO_QUERY); xPageProperySet->setPropertyValue("Height", css::uno::makeAny(nPageHeight)); xPageProperySet->setPropertyValue("Width", css::uno::makeAny(nPageWidth)); + setPageMargins(xPageProperySet, aPageMargins); + // Create and insert the shape uno::Reference<drawing::XShape> xShape( xFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), uno::UNO_QUERY); @@ -187,4 +219,118 @@ void SfxRedactionHelper::showRedactionToolbar(SfxViewFrame* pViewFrame) } } +PageMargins +SfxRedactionHelper::getPageMarginsForWriter(css::uno::Reference<css::frame::XModel>& xModel) +{ + PageMargins aPageMargins = { -1, -1, -1, -1 }; + + Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), + UNO_QUERY); + if (!xTextViewCursorSupplier.is()) + { + SAL_WARN("sfx.doc", "Ref to xTextViewCursorSupplier is null in setPageMargins()."); + return aPageMargins; + } + + Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), UNO_QUERY); + + uno::Reference<beans::XPropertySet> xPageProperySet(xCursor, UNO_QUERY); + OUString sPageStyleName; + Any aValue = xPageProperySet->getPropertyValue("PageStyleName"); + aValue >>= sPageStyleName; + + Reference<css::style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xModel, UNO_QUERY); + if (!xStyleFamiliesSupplier.is()) + { + SAL_WARN("sfx.doc", "Ref to xStyleFamiliesSupplier is null in setPageMargins()."); + return aPageMargins; + } + uno::Reference<container::XNameAccess> xStyleFamilies( + xStyleFamiliesSupplier->getStyleFamilies(), UNO_QUERY); + + if (!xStyleFamilies.is()) + return aPageMargins; + + uno::Reference<container::XNameAccess> xPageStyles(xStyleFamilies->getByName("PageStyles"), + UNO_QUERY); + + if (!xPageStyles.is()) + return aPageMargins; + + uno::Reference<css::style::XStyle> xPageStyle(xPageStyles->getByName(sPageStyleName), + UNO_QUERY); + + if (!xPageStyle.is()) + return aPageMargins; + + uno::Reference<beans::XPropertySet> xPageProperties(xPageStyle, uno::UNO_QUERY); + + if (!xPageProperties.is()) + return aPageMargins; + + xPageProperties->getPropertyValue("LeftMargin") >>= aPageMargins.nLeft; + xPageProperties->getPropertyValue("RightMargin") >>= aPageMargins.nRight; + xPageProperties->getPropertyValue("TopMargin") >>= aPageMargins.nTop; + xPageProperties->getPropertyValue("BottomMargin") >>= aPageMargins.nBottom; + + return aPageMargins; +} + +PageMargins +SfxRedactionHelper::getPageMarginsForCalc(css::uno::Reference<css::frame::XModel>& xModel) +{ + PageMargins aPageMargins = { -1, -1, -1, -1 }; + OUString sPageStyleName("Default"); + + css::uno::Reference<css::sheet::XSpreadsheetView> xSpreadsheetView( + xModel->getCurrentController(), UNO_QUERY); + + if (!xSpreadsheetView.is()) + { + SAL_WARN("sfx.doc", "Ref to xSpreadsheetView is null in getPageMarginsForCalc()."); + return aPageMargins; + } + + uno::Reference<beans::XPropertySet> xSheetProperties(xSpreadsheetView->getActiveSheet(), + UNO_QUERY); + + xSheetProperties->getPropertyValue("PageStyle") >>= sPageStyleName; + + Reference<css::style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xModel, UNO_QUERY); + if (!xStyleFamiliesSupplier.is()) + { + SAL_WARN("sfx.doc", "Ref to xStyleFamiliesSupplier is null in getPageMarginsForCalc()."); + return aPageMargins; + } + uno::Reference<container::XNameAccess> xStyleFamilies( + xStyleFamiliesSupplier->getStyleFamilies(), UNO_QUERY); + + if (!xStyleFamilies.is()) + return aPageMargins; + + uno::Reference<container::XNameAccess> xPageStyles(xStyleFamilies->getByName("PageStyles"), + UNO_QUERY); + + if (!xPageStyles.is()) + return aPageMargins; + + uno::Reference<css::style::XStyle> xPageStyle(xPageStyles->getByName(sPageStyleName), + UNO_QUERY); + + if (!xPageStyle.is()) + return aPageMargins; + + uno::Reference<beans::XPropertySet> xPageProperties(xPageStyle, uno::UNO_QUERY); + + if (!xPageProperties.is()) + return aPageMargins; + + xPageProperties->getPropertyValue("LeftMargin") >>= aPageMargins.nLeft; + xPageProperties->getPropertyValue("RightMargin") >>= aPageMargins.nRight; + xPageProperties->getPropertyValue("TopMargin") >>= aPageMargins.nTop; + xPageProperties->getPropertyValue("BottomMargin") >>= aPageMargins.nBottom; + + return aPageMargins; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index 5a83874f348b..e3d2b3b5b706 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -553,6 +553,13 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) DocumentToGraphicRenderer aRenderer(xSourceDoc, false); + // Get the page margins of the original doc + PageMargins aPageMargins = {-1, -1, -1, -1}; + if (aRenderer.isWriter()) + aPageMargins = SfxRedactionHelper::getPageMarginsForWriter(xModel); + else if (aRenderer.isCalc()) + aPageMargins = SfxRedactionHelper::getPageMarginsForCalc(xModel); + sal_Int32 nPages = aRenderer.getPageCount(); std::vector< GDIMetaFile > aMetaFiles; std::vector< ::Size > aPageSizes; @@ -566,7 +573,7 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) uno::Reference<lang::XComponent> xComponent = xComponentLoader->loadComponentFromURL("private:factory/sdraw", "_default", 0, {}); // Add the doc pages to the new draw document - SfxRedactionHelper::addPagesToDraw(xComponent, nPages, aMetaFiles, aPageSizes); + SfxRedactionHelper::addPagesToDraw(xComponent, nPages, aMetaFiles, aPageSizes, aPageMargins); // Show the Redaction toolbar SfxViewFrame* pViewFrame = SfxViewFrame::Current(); commit 11d48556208fa4f0a93fc0ba07638e0dd453a3d4 Author: Muhammet Kara <muhammet.k...@collabora.com> AuthorDate: Fri May 3 22:07:59 2019 +0300 Commit: Muhammet Kara <muhammet.k...@collabora.com> CommitDate: Mon Jun 17 22:54:10 2019 +0200 tdf#125135: Standardize content placement for redaction Correct the position & size by roundtrip conversion from/to wmf as a temporary solution. Simplify a bit. Change-Id: I59f32bd29750f9ac759800893583308f29b8aad5 Reviewed-on: https://gerrit.libreoffice.org/71860 Tested-by: Jenkins Reviewed-by: Muhammet Kara <muhammet.k...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/74223 Tested-by: Muhammet Kara <muhammet.k...@collabora.com> diff --git a/sfx2/inc/SfxRedactionHelper.hxx b/sfx2/inc/SfxRedactionHelper.hxx index 1cd653650557..8b1bdd57e247 100644 --- a/sfx2/inc/SfxRedactionHelper.hxx +++ b/sfx2/inc/SfxRedactionHelper.hxx @@ -49,15 +49,14 @@ public: * */ static void getPageMetaFilesFromDoc(std::vector<GDIMetaFile>& aMetaFiles, std::vector<::Size>& aPageSizes, const sal_Int32& nPages, - DocumentToGraphicRenderer& aRenderer, bool bIsWriter, - bool bIsCalc); + DocumentToGraphicRenderer& aRenderer); /* * Creates one shape and one draw page for each gdimetafile, * and inserts the shapes into the newly created draw pages. * */ static void addPagesToDraw(uno::Reference<XComponent>& xComponent, const sal_Int32& nPages, const std::vector<GDIMetaFile>& aMetaFiles, - const std::vector<::Size>& aPageSizes, bool bIsCalc); + const std::vector<::Size>& aPageSizes); /* * Makes the Redaction toolbar visible to the user. * Meant to be called after converting a document to a Draw doc diff --git a/sfx2/source/doc/SfxRedactionHelper.cxx b/sfx2/source/doc/SfxRedactionHelper.cxx index b1743e5ba20b..d898dfc4130c 100644 --- a/sfx2/source/doc/SfxRedactionHelper.cxx +++ b/sfx2/source/doc/SfxRedactionHelper.cxx @@ -27,6 +27,9 @@ #include <vcl/gdimtf.hxx> #include <vcl/graph.hxx> +#include <vcl/wmf.hxx> +#include <vcl/gdimetafiletools.hxx> + using namespace ::com::sun::star; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::uno; @@ -60,11 +63,24 @@ OUString SfxRedactionHelper::getStringParam(const SfxRequest& rReq, const sal_uI return sStringParam; } +namespace +{ +void fixMetaFile(GDIMetaFile& tmpMtf) +{ + SvMemoryStream aDestStrm(65535, 65535); + ConvertGDIMetaFileToWMF(tmpMtf, aDestStrm, nullptr, false); + aDestStrm.Seek(0); + + tmpMtf.Clear(); + + ReadWindowMetafile(aDestStrm, tmpMtf); +} +} + void SfxRedactionHelper::getPageMetaFilesFromDoc(std::vector<GDIMetaFile>& aMetaFiles, std::vector<::Size>& aPageSizes, const sal_Int32& nPages, - DocumentToGraphicRenderer& aRenderer, - bool bIsWriter, bool bIsCalc) + DocumentToGraphicRenderer& aRenderer) { for (sal_Int32 nPage = 1; nPage <= nPages; ++nPage) { @@ -74,12 +90,10 @@ void SfxRedactionHelper::getPageMetaFilesFromDoc(std::vector<GDIMetaFile>& aMeta ::Size aCalcPageContentSize; ::Size aLogic = aRenderer.getDocumentSizeIn100mm(nPage, &aLogicPos, &aCalcPageLogicPos, &aCalcPageContentSize); - // FIXME: This is a temporary hack. Need to figure out a proper way to derive this scale factor. - ::Size aTargetSize(aDocumentSizePixel.Width() * 1.23, aDocumentSizePixel.Height() * 1.23); aPageSizes.push_back(aLogic); - Graphic aGraphic = aRenderer.renderToGraphic(nPage, aDocumentSizePixel, aTargetSize, + Graphic aGraphic = aRenderer.renderToGraphic(nPage, aDocumentSizePixel, aDocumentSizePixel, COL_TRANSPARENT, true); auto& rGDIMetaFile = const_cast<GDIMetaFile&>(aGraphic.GetGDIMetaFile()); @@ -87,24 +101,11 @@ void SfxRedactionHelper::getPageMetaFilesFromDoc(std::vector<GDIMetaFile>& aMeta // will be correct in MM. MapMode aMapMode; aMapMode.SetMapUnit(MapUnit::Map100thMM); - // FIXME: This is a temporary hack. Need to figure out a proper way to derive these magic numbers. - if (bIsWriter) - aMapMode.SetOrigin(::Point(-(aLogicPos.getX() - 512) * 1.53, - -((aLogicPos.getY() - 501) * 1.53 + (nPage - 1) * 740))); - else if (bIsCalc) - rGDIMetaFile.Scale(0.566, 0.566); rGDIMetaFile.SetPrefMapMode(aMapMode); + rGDIMetaFile.SetPrefSize(aLogic); - if (bIsCalc) - { - double aWidthRatio = static_cast<double>(aCalcPageContentSize.Width()) / aLogic.Width(); - // FIXME: Get rid of these magic numbers. Also watch for floating point rounding errors - rGDIMetaFile.Move(-2400 + aCalcPageLogicPos.X() * (aWidthRatio - 0.0887), - -3300 + aCalcPageLogicPos.Y() * 0.64175); - } - - rGDIMetaFile.SetPrefSize(bIsCalc ? aCalcPageContentSize : aLogic); + fixMetaFile(rGDIMetaFile); aMetaFiles.push_back(rGDIMetaFile); } @@ -113,7 +114,7 @@ void SfxRedactionHelper::getPageMetaFilesFromDoc(std::vector<GDIMetaFile>& aMeta void SfxRedactionHelper::addPagesToDraw(uno::Reference<XComponent>& xComponent, const sal_Int32& nPages, const std::vector<GDIMetaFile>& aMetaFiles, - const std::vector<::Size>& aPageSizes, bool bIsCalc) + const std::vector<::Size>& aPageSizes) { // Access the draw pages uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(xComponent, uno::UNO_QUERY); @@ -145,16 +146,11 @@ void SfxRedactionHelper::addPagesToDraw(uno::Reference<XComponent>& xComponent, xShapeProperySet->setPropertyValue("MoveProtect", uno::Any(true)); xShapeProperySet->setPropertyValue("SizeProtect", uno::Any(true)); - // Set size and position + // Set size xShape->setSize( awt::Size(rGDIMetaFile.GetPrefSize().Width(), rGDIMetaFile.GetPrefSize().Height())); xPage->add(xShape); - - // Shapes from Calc have the size of the content instead of the whole standard page (like A4) - // so it needs positioning on the draw page - if (bIsCalc) - xShape->setPosition(awt::Point(1000, 1000)); } // Remove the extra page at the beginning diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index 72d46d50e217..5a83874f348b 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -553,15 +553,12 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) DocumentToGraphicRenderer aRenderer(xSourceDoc, false); - bool bIsWriter = aRenderer.isWriter(); - bool bIsCalc = aRenderer.isCalc(); - sal_Int32 nPages = aRenderer.getPageCount(); std::vector< GDIMetaFile > aMetaFiles; std::vector< ::Size > aPageSizes; // Convert the pages of the document to gdimetafiles - SfxRedactionHelper::getPageMetaFilesFromDoc(aMetaFiles, aPageSizes, nPages, aRenderer, bIsWriter, bIsCalc); + SfxRedactionHelper::getPageMetaFilesFromDoc(aMetaFiles, aPageSizes, nPages, aRenderer); // Create an empty Draw component. uno::Reference<frame::XDesktop2> xDesktop = css::frame::Desktop::create(comphelper::getProcessComponentContext()); @@ -569,7 +566,7 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) uno::Reference<lang::XComponent> xComponent = xComponentLoader->loadComponentFromURL("private:factory/sdraw", "_default", 0, {}); // Add the doc pages to the new draw document - SfxRedactionHelper::addPagesToDraw(xComponent, nPages, aMetaFiles, aPageSizes, bIsCalc); + SfxRedactionHelper::addPagesToDraw(xComponent, nPages, aMetaFiles, aPageSizes); // Show the Redaction toolbar SfxViewFrame* pViewFrame = SfxViewFrame::Current(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits