[Libreoffice-commits] core.git: sfx2/inc sfx2/source

Muhammet Kara (via logerrit) logerrit at kemper.freedesktop.org
Mon May 13 10:49:22 UTC 2019


 sfx2/inc/SfxRedactionHelper.hxx        |   20 ++++
 sfx2/source/doc/SfxRedactionHelper.cxx |  148 +++++++++++++++++++++++++++++++++
 2 files changed, 168 insertions(+)

New commits:
commit 57667603c52e7d6bb82f5040151c8b7defcc6f8a
Author:     Muhammet Kara <muhammet.kara at collabora.com>
AuthorDate: Fri Mar 1 21:56:31 2019 +0300
Commit:     Muhammet Kara <muhammet.kara at collabora.com>
CommitDate: Mon May 13 12:48:38 2019 +0200

    Auto-redact - First stab
    
    Add a SfxRedactionHelper::autoRedactPage method which searches for the given term
    through the gdimetafile which has the whole content of an xPage (a Draw page),
    and draws redaction rectangles at proper positions with proper sizes.
    
    The search is case sensitive, and finds only the first occurences on a line.
    Will switch to a proper search provider via a follow-up patch.
    
    Change-Id: If3db62e50994670143785b6727fdcf1ccd4c6f8e
    Reviewed-on: https://gerrit.libreoffice.org/68597
    Tested-by: Jenkins
    Reviewed-by: Muhammet Kara <muhammet.kara at collabora.com>

diff --git a/sfx2/inc/SfxRedactionHelper.hxx b/sfx2/inc/SfxRedactionHelper.hxx
index ac15bb790fe9..44a78ab9b877 100644
--- a/sfx2/inc/SfxRedactionHelper.hxx
+++ b/sfx2/inc/SfxRedactionHelper.hxx
@@ -14,6 +14,7 @@
 #include <com/sun/star/lang/XComponent.hpp>
 #include <com/sun/star/frame/XModel.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
 
 #include <sal/types.h>
 #include <rtl/ustring.hxx>
@@ -87,6 +88,25 @@ public:
      * pages inserted into Draw for redaction.
      * */
     static PageMargins getPageMarginsForCalc(css::uno::Reference<css::frame::XModel>& xModel);
+
+    static void searchInMetaFile(const OUString& sSearchTerm, const GDIMetaFile& rMtf,
+                                 std::vector<tools::Rectangle>& aRedactionRectangles,
+                                 uno::Reference<XComponent>& xComponent);
+
+    /*
+     * Draws a redaction rectangle on the draw page referenced with its page number (0-based)
+     * */
+    static void addRedactionRectToPage(uno::Reference<XComponent>& xComponent,
+                                       uno::Reference<drawing::XDrawPage>& xPage,
+                                       const std::vector<tools::Rectangle>& aNewRectangles);
+
+    /*
+     * Search for the given term through the gdimetafile, which has the whole content of a draw page,
+     * and draw redaction rectangles to the appropriate positions with suitable sizes.
+     * */
+    static void autoRedactPage(const OUString& sRedactionTerm, const GDIMetaFile& rGDIMetaFile,
+                               uno::Reference<drawing::XDrawPage>& xPage,
+                               uno::Reference<XComponent>& xComponent);
 };
 
 #endif // INCLUDED_CUI_SOURCE_INC_SFXREDACTIONHELPER_HXX
diff --git a/sfx2/source/doc/SfxRedactionHelper.cxx b/sfx2/source/doc/SfxRedactionHelper.cxx
index 4f1c01da4907..59203b6467ec 100644
--- a/sfx2/source/doc/SfxRedactionHelper.cxx
+++ b/sfx2/source/doc/SfxRedactionHelper.cxx
@@ -10,6 +10,7 @@
 #include <SfxRedactionHelper.hxx>
 
 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <com/sun/star/graphic/XGraphic.hpp>
 #include <com/sun/star/frame/XLayoutManager.hpp>
@@ -31,12 +32,17 @@
 
 #include <svtools/DocumentToGraphicRenderer.hxx>
 
+#include <tools/gen.hxx>
+
 #include <vcl/gdimtf.hxx>
 #include <vcl/graph.hxx>
 #include <sal/log.hxx>
 
 #include <vcl/wmf.hxx>
 #include <vcl/gdimetafiletools.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/vcllayout.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::lang;
@@ -105,8 +111,66 @@ void setPageMargins(uno::Reference<beans::XPropertySet>& xPageProperySet,
     xPageProperySet->setPropertyValue("BorderLeft", css::uno::makeAny(aPageMargins.nLeft));
     xPageProperySet->setPropertyValue("BorderRight", css::uno::makeAny(aPageMargins.nRight));
 }
+
+// #i10613# Extracted from ImplCheckRect::ImplCreate
+tools::Rectangle ImplCalcActionBounds(const MetaAction& rAct, const OutputDevice& rOut,
+                                      const OUString& sSubString, const sal_Int32& nStrPos)
+{
+    tools::Rectangle aActionBounds;
+
+    switch (rAct.GetType())
+    {
+        case MetaActionType::TEXTARRAY:
+        {
+            const MetaTextArrayAction& rTextAct = static_cast<const MetaTextArrayAction&>(rAct);
+            const OUString aString(rTextAct.GetText().copy(rTextAct.GetIndex(), rTextAct.GetLen()));
+
+            if (!aString.isEmpty())
+            {
+                // #105987# ImplLayout takes everything in logical coordinates
+                std::unique_ptr<SalLayout> pSalLayout1 = rOut.ImplLayout(
+                    aString, 0, nStrPos, rTextAct.GetPoint(), 0, rTextAct.GetDXArray());
+                std::unique_ptr<SalLayout> pSalLayout2
+                    = rOut.ImplLayout(aString, 0, nStrPos + sSubString.getLength(),
+                                      rTextAct.GetPoint(), 0, rTextAct.GetDXArray());
+                if (pSalLayout2)
+                {
+                    tools::Rectangle aBoundRect2(
+                        const_cast<OutputDevice&>(rOut).ImplGetTextBoundRect(*pSalLayout2));
+                    aActionBounds = rOut.PixelToLogic(aBoundRect2);
+                }
+                if (pSalLayout1 && nStrPos > 0)
+                {
+                    tools::Rectangle aBoundRect1(
+                        const_cast<OutputDevice&>(rOut).ImplGetTextBoundRect(*pSalLayout1));
+                    aActionBounds.SetLeft(rOut.PixelToLogic(aBoundRect1).getX()
+                                          + rOut.PixelToLogic(aBoundRect1).getWidth());
+                }
+
+                // FIXME: Is this really needed?
+                aActionBounds.SetTop(aActionBounds.getY() + 100);
+            }
+        }
+        break;
+
+        default:
+            break;
+    }
+
+    if (!aActionBounds.IsEmpty())
+    {
+        // fdo#40421 limit current action's output to clipped area
+        if (rOut.IsClipRegion())
+            return rOut.GetClipRegion().GetBoundRect().Intersection(aActionBounds);
+        else
+            return aActionBounds;
+    }
+    else
+        return aActionBounds;
 }
 
+} // End of anon namespace
+
 void SfxRedactionHelper::getPageMetaFilesFromDoc(std::vector<GDIMetaFile>& aMetaFiles,
                                                  std::vector<::Size>& aPageSizes,
                                                  const sal_Int32& nPages,
@@ -184,6 +248,8 @@ void SfxRedactionHelper::addPagesToDraw(uno::Reference<XComponent>& xComponent,
             awt::Size(rGDIMetaFile.GetPrefSize().Width(), rGDIMetaFile.GetPrefSize().Height()));
 
         xPage->add(xShape);
+
+        //autoRedactPage("deployment", rGDIMetaFile, xPage, xComponent);
     }
 
     // Remove the extra page at the beginning
@@ -334,4 +400,86 @@ SfxRedactionHelper::getPageMarginsForCalc(css::uno::Reference<css::frame::XModel
     return aPageMargins;
 }
 
+void SfxRedactionHelper::searchInMetaFile(const rtl::OUString& sSearchTerm, const GDIMetaFile& rMtf,
+                                          std::vector<::tools::Rectangle>& aRedactionRectangles,
+                                          uno::Reference<XComponent>& xComponent)
+{
+    MetaAction* pCurrAct;
+
+    // Watch for TEXTARRAY actions.
+    // They contain the text of paragraphes.
+    for (pCurrAct = const_cast<GDIMetaFile&>(rMtf).FirstAction(); pCurrAct;
+         pCurrAct = const_cast<GDIMetaFile&>(rMtf).NextAction())
+    {
+        if (pCurrAct->GetType() == MetaActionType::TEXTARRAY)
+        {
+            MetaTextArrayAction* pMetaTextArrayAction = static_cast<MetaTextArrayAction*>(pCurrAct);
+
+            //sal_Int32 aIndex = pMetaTextArrayAction->GetIndex();
+            //sal_Int32 aLength = pMetaTextArrayAction->GetLen();
+            //Point aPoint = pMetaTextArrayAction->GetPoint();
+            OUString sText = pMetaTextArrayAction->GetText();
+            sal_Int32 nFoundIndex = sText.indexOf(sSearchTerm);
+
+            // If found the string, add the corresponding rectangle to the collection
+            if (nFoundIndex >= 0)
+            {
+                OutputDevice* pOutputDevice
+                    = SfxObjectShell::GetShellFromComponent(xComponent)->GetDocumentRefDev();
+                tools::Rectangle aNewRect(ImplCalcActionBounds(
+                    *pMetaTextArrayAction, *pOutputDevice, sSearchTerm, nFoundIndex));
+
+                if (!aNewRect.IsEmpty())
+                    aRedactionRectangles.push_back(aNewRect);
+            }
+        }
+    }
+}
+
+void SfxRedactionHelper::addRedactionRectToPage(
+    uno::Reference<XComponent>& xComponent, uno::Reference<drawing::XDrawPage>& xPage,
+    const std::vector<::tools::Rectangle>& aNewRectangles)
+{
+    if (!xComponent.is() || !xPage.is())
+        return;
+
+    if (aNewRectangles.empty())
+        return;
+
+    uno::Reference<css::lang::XMultiServiceFactory> xFactory(xComponent, uno::UNO_QUERY);
+
+    for (auto const& aNewRectangle : aNewRectangles)
+    {
+        uno::Reference<drawing::XShape> xRectShape(
+            xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
+        uno::Reference<beans::XPropertySet> xRectShapeProperySet(xRectShape, uno::UNO_QUERY);
+
+        xRectShapeProperySet->setPropertyValue("Name",
+                                               uno::Any(OUString("RectangleRedactionShape")));
+        xRectShapeProperySet->setPropertyValue("FillTransparence",
+                                               css::uno::makeAny(static_cast<sal_Int16>(50)));
+        xRectShapeProperySet->setPropertyValue("FillColor", css::uno::makeAny(COL_GRAY7));
+        xRectShapeProperySet->setPropertyValue(
+            "LineStyle", css::uno::makeAny(css::drawing::LineStyle::LineStyle_NONE));
+
+        xRectShape->setSize(awt::Size(aNewRectangle.GetWidth(), aNewRectangle.GetHeight()));
+        xRectShape->setPosition(awt::Point(aNewRectangle.getX(), aNewRectangle.getY()));
+
+        xPage->add(xRectShape);
+    }
+}
+
+void SfxRedactionHelper::autoRedactPage(const OUString& sRedactionTerm,
+                                        const GDIMetaFile& rGDIMetaFile,
+                                        uno::Reference<drawing::XDrawPage>& xPage,
+                                        uno::Reference<XComponent>& xComponent)
+{
+    // Search for the redaction strings, and get the rectangle coordinates
+    std::vector<::tools::Rectangle> aRedactionRectangles;
+    searchInMetaFile(sRedactionTerm, rGDIMetaFile, aRedactionRectangles, xComponent);
+
+    // Add the redaction rectangles to the page
+    addRedactionRectToPage(xComponent, xPage, aRedactionRectangles);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */


More information about the Libreoffice-commits mailing list