Blame SOURCES/0001-rhbz-1326602-avoid-exp.-bg-bitmaps-from-deleted-slid.patch

a9add1
From 9a36cf42d6ea424a2ca5c92f8bf1546ab618dc5d Mon Sep 17 00:00:00 2001
a9add1
From: David Tardon <dtardon@redhat.com>
a9add1
Date: Tue, 26 Apr 2016 09:17:11 +0200
a9add1
Subject: [PATCH] rhbz#1326602 avoid exp. bg bitmaps from deleted slides
a9add1
a9add1
ODF export uses SvxUnoBitmapTable (impl. of
a9add1
com.sun.star.drawing.BitmapTable) to create fill bitmap styles. That
a9add1
returns all XATTR_FILLBITMAP items that are in the document's pool. So
a9add1
we ensure that bitmaps that are only used on deleted (either explicitly
a9add1
or by undoing their insertion) slides are not in the pool.
a9add1
a9add1
(cherry picked from commit b876bbe2cacce8af379b10d82da6c7e7d229b361)
a9add1
a9add1
Change-Id: I54c594a94989158f22b156fe660c1e716b988b3e
a9add1
---
a9add1
 include/svx/svdundo.hxx        | 13 ++++++++
a9add1
 sd/source/ui/func/undoback.cxx | 44 ++++++++++++++++++++++++--
a9add1
 sd/source/ui/inc/undoback.hxx  |  6 ++++
a9add1
 svx/source/svdraw/svdundo.cxx  | 70 ++++++++++++++++++++++++++++++++++++++++++
a9add1
 4 files changed, 131 insertions(+), 2 deletions(-)
a9add1
a9add1
diff --git a/include/svx/svdundo.hxx b/include/svx/svdundo.hxx
a9add1
index a6c9f24..6472946 100644
a9add1
--- a/include/svx/svdundo.hxx
a9add1
+++ b/include/svx/svdundo.hxx
a9add1
@@ -20,6 +20,11 @@
a9add1
 #ifndef INCLUDED_SVX_SVDUNDO_HXX
a9add1
 #define INCLUDED_SVX_SVDUNDO_HXX
a9add1
 
a9add1
+#include <sal/config.h>
a9add1
+
a9add1
+#include <memory>
a9add1
+#include <vector>
a9add1
+
a9add1
 #include <svl/solar.hrc>
a9add1
 #include <svl/undo.hxx>
a9add1
 #include <svl/style.hxx>
a9add1
@@ -29,6 +34,7 @@
a9add1
 #include <svx/svxdllapi.h>
a9add1
 
a9add1
 class SfxItemSet;
a9add1
+class SfxPoolItem;
a9add1
 class SfxStyleSheet;
a9add1
 class SdrView;
a9add1
 class SdrPageView;
a9add1
@@ -589,6 +595,8 @@ class SVX_DLLPUBLIC SdrUndoDelPage : public SdrUndoPageList
a9add1
     // When deleting a MasterPage, we remember all relations of the
a9add1
     // Character Page with the MasterPage in this UndoGroup.
a9add1
     SdrUndoGroup*               pUndoGroup;
a9add1
+    std::unique_ptr<SfxPoolItem> mpFillBitmapItem;
a9add1
+    bool mbHasFillBitmap;
a9add1
 
a9add1
 public:
a9add1
     SdrUndoDelPage(SdrPage& rNewPg);
a9add1
@@ -602,6 +610,11 @@ public:
a9add1
 
a9add1
     virtual void SdrRepeat(SdrView& rView) SAL_OVERRIDE;
a9add1
     virtual bool CanSdrRepeat(SdrView& rView) const SAL_OVERRIDE;
a9add1
+
a9add1
+private:
a9add1
+    void queryFillBitmap(const SfxItemSet &rItemSet);
a9add1
+    void clearFillBitmap();
a9add1
+    void restoreFillBitmap();
a9add1
 };
a9add1
 
a9add1
 /**
a9add1
diff --git a/sd/source/ui/func/undoback.cxx b/sd/source/ui/func/undoback.cxx
a9add1
index bfb421b..3e3575a 100644
a9add1
--- a/sd/source/ui/func/undoback.cxx
a9add1
+++ b/sd/source/ui/func/undoback.cxx
a9add1
@@ -21,8 +21,13 @@
a9add1
 #include "sdpage.hxx"
a9add1
 #include "sdresid.hxx"
a9add1
 #include "strings.hrc"
a9add1
+
a9add1
+#include <com/sun/star/drawing/FillStyle.hpp>
a9add1
+
a9add1
 #include <svl/itemset.hxx>
a9add1
 
a9add1
+#include <svx/xfillit0.hxx>
a9add1
+
a9add1
 TYPEINIT1( SdBackgroundObjUndoAction, SdUndoAction );
a9add1
 
a9add1
 SdBackgroundObjUndoAction::SdBackgroundObjUndoAction(
a9add1
@@ -31,10 +38,12 @@ SdBackgroundObjUndoAction::SdBackgroundObjUndoAction(
a9add1
     const SfxItemSet& rItenSet)
a9add1
 :   SdUndoAction(&rDoc),
a9add1
     mrPage(rPage),
a9add1
-    mpItemSet(new SfxItemSet(rItenSet))
a9add1
+    mpItemSet(new SfxItemSet(rItenSet)),
a9add1
+    mbHasFillBitmap(false)
a9add1
 {
a9add1
     OUString aString( SdResId( STR_UNDO_CHANGE_PAGEFORMAT ) );
a9add1
     SetComment( aString );
a9add1
+    saveFillBitmap(*mpItemSet);
a9add1
 }
a9add1
 
a9add1
 SdBackgroundObjUndoAction::~SdBackgroundObjUndoAction()
a9add1
@@ -46,9 +55,14 @@ void SdBackgroundObjUndoAction::ImplRestoreBackgroundObj()
a9add1
 {
a9add1
     SfxItemSet* pNew = new SfxItemSet(mrPage.getSdrPageProperties().GetItemSet());
a9add1
     mrPage.getSdrPageProperties().ClearItem();
a9add1
+    if (bool(mpFillBitmapItem))
a9add1
+        restoreFillBitmap(*mpItemSet);
a9add1
+    mpFillBitmapItem.reset();
a9add1
+    mbHasFillBitmap = false;
a9add1
     mrPage.getSdrPageProperties().PutItemSet(*mpItemSet);
a9add1
     delete mpItemSet;
a9add1
     mpItemSet = pNew;
a9add1
+    saveFillBitmap(*mpItemSet);
a9add1
 
a9add1
     // tell the page that it's visualization has changed
a9add1
     mrPage.ActionChanged();
a9add1
@@ -66,7 +80,33 @@ void SdBackgroundObjUndoAction::Redo()
a9add1
 
a9add1
 SdUndoAction* SdBackgroundObjUndoAction::Clone() const
a9add1
 {
a9add1
-    return new SdBackgroundObjUndoAction(*mpDoc, mrPage, *mpItemSet);
a9add1
+    std::unique_ptr<SdBackgroundObjUndoAction> pCopy(new SdBackgroundObjUndoAction(*mpDoc, mrPage, *mpItemSet));
a9add1
+    if (mpFillBitmapItem)
a9add1
+        pCopy->mpFillBitmapItem.reset(mpFillBitmapItem->Clone());
a9add1
+    pCopy->mbHasFillBitmap = mbHasFillBitmap;
a9add1
+    return pCopy.release();
a9add1
+}
a9add1
+
a9add1
+void SdBackgroundObjUndoAction::saveFillBitmap(SfxItemSet &rItemSet)
a9add1
+{
a9add1
+    const SfxPoolItem *pItem = nullptr;
a9add1
+    if (rItemSet.GetItemState(XATTR_FILLBITMAP, false, &pItem) == SfxItemState::SET)
a9add1
+        mpFillBitmapItem.reset(pItem->Clone());
a9add1
+    if (bool(mpFillBitmapItem))
a9add1
+    {
a9add1
+        if (rItemSet.GetItemState(XATTR_FILLSTYLE, false, &pItem) == SfxItemState::SET)
a9add1
+            mbHasFillBitmap = static_cast<const XFillStyleItem*>(pItem)->GetValue() == css::drawing::FillStyle_BITMAP;
a9add1
+        rItemSet.ClearItem(XATTR_FILLBITMAP);
a9add1
+        if (mbHasFillBitmap)
a9add1
+            rItemSet.ClearItem(XATTR_FILLSTYLE);
a9add1
+    }
a9add1
+}
a9add1
+
a9add1
+void SdBackgroundObjUndoAction::restoreFillBitmap(SfxItemSet &rItemSet)
a9add1
+{
a9add1
+    rItemSet.Put(*mpFillBitmapItem);
a9add1
+    if (mbHasFillBitmap)
a9add1
+        rItemSet.Put(XFillStyleItem(css::drawing::FillStyle_BITMAP));
a9add1
 }
a9add1
 
a9add1
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
a9add1
diff --git a/sd/source/ui/inc/undoback.hxx b/sd/source/ui/inc/undoback.hxx
a9add1
index 360f7f5..4234424 100644
a9add1
--- a/sd/source/ui/inc/undoback.hxx
a9add1
+++ b/sd/source/ui/inc/undoback.hxx
a9add1
@@ -20,11 +20,13 @@
a9add1
 #ifndef INCLUDED_SD_SOURCE_UI_INC_UNDOBACK_HXX
a9add1
 #define INCLUDED_SD_SOURCE_UI_INC_UNDOBACK_HXX
a9add1
 
a9add1
+#include <memory>
a9add1
 #include "sdundo.hxx"
a9add1
 
a9add1
 class SdDrawDocument;
a9add1
 class SdPage;
a9add1
 class SfxItemSet;
a9add1
+class SfxPoolItem;
a9add1
 
a9add1
 // SdBackgroundObjUndoAction
a9add1
 class SdBackgroundObjUndoAction : public SdUndoAction
a9add1
@@ -33,8 +35,12 @@ private:
a9add1
 
a9add1
     SdPage&                 mrPage;
a9add1
     SfxItemSet*             mpItemSet;
a9add1
+    std::unique_ptr<SfxPoolItem> mpFillBitmapItem;
a9add1
+    bool                    mbHasFillBitmap;
a9add1
 
a9add1
     void                    ImplRestoreBackgroundObj();
a9add1
+    void                    saveFillBitmap(SfxItemSet &rItemSet);
a9add1
+    void                    restoreFillBitmap(SfxItemSet &rItemSet);
a9add1
 
a9add1
 public:
a9add1
 
a9add1
diff --git a/svx/source/svdraw/svdundo.cxx b/svx/source/svdraw/svdundo.cxx
a9add1
index 7466532..e4dfa12 100644
a9add1
--- a/svx/source/svdraw/svdundo.cxx
a9add1
+++ b/svx/source/svdraw/svdundo.cxx
a9add1
@@ -17,6 +17,7 @@
a9add1
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
a9add1
  */
a9add1
 
a9add1
+#include <com/sun/star/drawing/FillStyle.hpp>
a9add1
 
a9add1
 #include <svl/lstner.hxx>
a9add1
 
a9add1
@@ -27,6 +28,7 @@
a9add1
 #include <svx/svdlayer.hxx>
a9add1
 #include <svx/svdmodel.hxx>
a9add1
 #include <svx/svdview.hxx>
a9add1
+#include <svx/xfillit0.hxx>
a9add1
 #include "svx/svdstr.hrc"
a9add1
 #include "svdglob.hxx"
a9add1
 #include <svx/scene3d.hxx>
a9add1
@@ -1483,9 +1485,24 @@ SdrUndoPageList::~SdrUndoPageList()
a9add1
 SdrUndoDelPage::SdrUndoDelPage(SdrPage& rNewPg)
a9add1
     : SdrUndoPageList(rNewPg)
a9add1
     , pUndoGroup(NULL)
a9add1
+    , mbHasFillBitmap(false)
a9add1
 {
a9add1
     bItsMine = true;
a9add1
 
a9add1
+    // keep fill bitmap separately to remove it from pool if not used elsewhere
a9add1
+    if (mrPage.IsMasterPage())
a9add1
+    {
a9add1
+        SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet();
a9add1
+        if (pStyleSheet)
a9add1
+            queryFillBitmap(pStyleSheet->GetItemSet());
a9add1
+    }
a9add1
+    else
a9add1
+    {
a9add1
+        queryFillBitmap(mrPage.getSdrPageProperties().GetItemSet());
a9add1
+    }
a9add1
+    if (bool(mpFillBitmapItem))
a9add1
+        clearFillBitmap();
a9add1
+
a9add1
     // now remember the master page relationships
a9add1
     if(mrPage.IsMasterPage())
a9add1
     {
a9add1
@@ -1520,6 +1537,8 @@ SdrUndoDelPage::~SdrUndoDelPage()
a9add1
 
a9add1
 void SdrUndoDelPage::Undo()
a9add1
 {
a9add1
+    if (bool(mpFillBitmapItem))
a9add1
+        restoreFillBitmap();
a9add1
     ImpInsertPage(nPageNum);
a9add1
     if (pUndoGroup!=NULL)
a9add1
     {
a9add1
@@ -1533,6 +1552,8 @@ void SdrUndoDelPage::Undo()
a9add1
 void SdrUndoDelPage::Redo()
a9add1
 {
a9add1
     ImpRemovePage(nPageNum);
a9add1
+    if (bool(mpFillBitmapItem))
a9add1
+        clearFillBitmap();
a9add1
     // master page relations are dissolved automatically
a9add1
     DBG_ASSERT(!bItsMine,"RedoDeletePage: mrPage already belongs to UndoAction.");
a9add1
     bItsMine=true;
a9add1
@@ -1561,6 +1582,55 @@ bool SdrUndoDelPage::CanSdrRepeat(SdrView& /*rView*/) const
a9add1
     return false;
a9add1
 }
a9add1
 
a9add1
+void SdrUndoDelPage::queryFillBitmap(const SfxItemSet& rItemSet)
a9add1
+{
a9add1
+    const SfxPoolItem *pItem = nullptr;
a9add1
+    if (rItemSet.GetItemState(XATTR_FILLBITMAP, false, &pItem) == SfxItemState::SET)
a9add1
+        mpFillBitmapItem.reset(pItem->Clone());
a9add1
+    if (rItemSet.GetItemState(XATTR_FILLSTYLE, false, &pItem) == SfxItemState::SET)
a9add1
+        mbHasFillBitmap = static_cast<const XFillStyleItem*>(pItem)->GetValue() == css::drawing::FillStyle_BITMAP;
a9add1
+}
a9add1
+
a9add1
+void SdrUndoDelPage::clearFillBitmap()
a9add1
+{
a9add1
+    if (mrPage.IsMasterPage())
a9add1
+    {
a9add1
+        SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet();
a9add1
+        assert(bool(pStyleSheet)); // who took away my stylesheet?
a9add1
+        SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
a9add1
+        rItemSet.ClearItem(XATTR_FILLBITMAP);
a9add1
+        if (mbHasFillBitmap)
a9add1
+            rItemSet.ClearItem(XATTR_FILLSTYLE);
a9add1
+    }
a9add1
+    else
a9add1
+    {
a9add1
+        SdrPageProperties &rPageProps = mrPage.getSdrPageProperties();
a9add1
+        rPageProps.ClearItem(XATTR_FILLBITMAP);
a9add1
+        if (mbHasFillBitmap)
a9add1
+            rPageProps.ClearItem(XATTR_FILLSTYLE);
a9add1
+    }
a9add1
+}
a9add1
+
a9add1
+void SdrUndoDelPage::restoreFillBitmap()
a9add1
+{
a9add1
+    if (mrPage.IsMasterPage())
a9add1
+    {
a9add1
+        SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet();
a9add1
+        assert(bool(pStyleSheet)); // who took away my stylesheet?
a9add1
+        SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
a9add1
+        rItemSet.Put(*mpFillBitmapItem);
a9add1
+        if (mbHasFillBitmap)
a9add1
+            rItemSet.Put(XFillStyleItem(css::drawing::FillStyle_BITMAP));
a9add1
+    }
a9add1
+    else
a9add1
+    {
a9add1
+        SdrPageProperties &rPageProps = mrPage.getSdrPageProperties();
a9add1
+        rPageProps.PutItem(*mpFillBitmapItem);
a9add1
+        if (mbHasFillBitmap)
a9add1
+            rPageProps.PutItem(XFillStyleItem(css::drawing::FillStyle_BITMAP));
a9add1
+    }
a9add1
+}
a9add1
+
a9add1
 
a9add1
 
a9add1
 void SdrUndoNewPage::Undo()
a9add1
-- 
a9add1
2.7.4
a9add1