diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2021-07-14 19:50:18 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2021-07-16 18:48:46 +0200 |
commit | 86c0f58b6f9f392865196606173d1b98a6897f32 (patch) | |
tree | 740c02474529d6a4c7cb4b52e234068c1b28c227 /svx | |
parent | 4461e14d08c7d1c1c43b136a5a8e3acb868c0b51 (diff) |
tdf#92796 ODF import: remove unused bitmap fills
With CWS impress64 a partial fix for this was implemented to drop
unreferenced named items including all non-color fills after ODF import,
but this is only done in sd so move the code that does that to svx and
call it from sc and sw as well.
Implement some UNO interface for this, it's at least better than a magic
string, and not obvious how a better solution would look like since it's
known only at the end of the import if a bitmap is used or not.
Another problem: when the Area tab is used to change to a different kind
of fill, the items with the details for the previous fill aren't
cleared, and so they are written to ODF files. Hence bitmaps in the
file can be referenced even if they aren't actually used, and bloat up
the files.
Fix this by dropping all unused draw:fill-image-name attributes in ODF
import.
Also do the same for Gradient and Hatch fills; Transparency gradients
can be combined with anything so leave them as they are.
Change-Id: I0b591fd9f963d974d0c3e7208b99621ad61dd93c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118950
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'svx')
-rw-r--r-- | svx/source/unodraw/UnoNameItemTable.cxx | 17 | ||||
-rw-r--r-- | svx/source/unodraw/UnoNameItemTable.hxx | 14 | ||||
-rw-r--r-- | svx/source/unodraw/unomtabl.cxx | 30 | ||||
-rw-r--r-- | svx/source/xml/xmlgrhlp.cxx | 67 |
4 files changed, 108 insertions, 20 deletions
diff --git a/svx/source/unodraw/UnoNameItemTable.cxx b/svx/source/unodraw/UnoNameItemTable.cxx index dfa75c460f66..17e952ea5d4c 100644 --- a/svx/source/unodraw/UnoNameItemTable.cxx +++ b/svx/source/unodraw/UnoNameItemTable.cxx @@ -68,6 +68,8 @@ SvxUnoNameItemTable::SvxUnoNameItemTable( SdrModel* pModel, sal_uInt16 nWhich, s SvxUnoNameItemTable::~SvxUnoNameItemTable() noexcept { + SolarMutexGuard aGuard; + if( mpModel ) EndListening( *mpModel ); dispose(); @@ -122,20 +124,19 @@ void SAL_CALL SvxUnoNameItemTable::insertByName( const OUString& aApiName, const ImplInsertByName( aName, aElement ); } +void SAL_CALL SvxUnoNameItemTable::cancel() +{ + SolarMutexGuard aGuard; + // drop all items that are owned by this service and not the document + // (i.e. they are unused) + dispose(); +} void SAL_CALL SvxUnoNameItemTable::removeByName( const OUString& aApiName ) { SolarMutexGuard aGuard; comphelper::ProfileZone aZone("SvxUnoNameItemTable::removeByName"); - // a little quickfix for 2.0 to let applications clear api - // created items that are not used - if ( aApiName == "~clear~" ) - { - dispose(); - return; - } - OUString sName = SvxUnogetInternalNameForItem(mnWhich, aApiName); auto aIter = std::find_if(maItemSetVector.begin(), maItemSetVector.end(), diff --git a/svx/source/unodraw/UnoNameItemTable.hxx b/svx/source/unodraw/UnoNameItemTable.hxx index 47654aaf4f8f..c1c798869ce5 100644 --- a/svx/source/unodraw/UnoNameItemTable.hxx +++ b/svx/source/unodraw/UnoNameItemTable.hxx @@ -22,6 +22,7 @@ #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/util/XCancellable.hpp> #include <cppuhelper/implbase.hxx> @@ -35,8 +36,12 @@ class SfxItemPool; class SfxItemSet; typedef std::vector< std::unique_ptr< SfxItemSet > > ItemPoolVector; -class SvxUnoNameItemTable : public cppu::WeakImplHelper< css::container::XNameContainer, css::lang::XServiceInfo >, - public SfxListener +class SvxUnoNameItemTable + : public cppu::WeakImplHelper< + css::util::XCancellable, + css::container::XNameContainer, + css::lang::XServiceInfo > + , public SfxListener { private: SdrModel* mpModel; @@ -44,6 +49,8 @@ private: sal_uInt16 mnWhich; sal_uInt8 mnMemberId; + /// vector contains all items that were created by this service and will + /// keep them alive even if nothing in the document references them ItemPoolVector maItemSetVector; void ImplInsertByName( const OUString& aName, const css::uno::Any& aElement ); @@ -63,6 +70,9 @@ public: // XServiceInfo virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + // XCancellable + virtual void SAL_CALL cancel() override; + // XNameContainer virtual void SAL_CALL insertByName( const OUString& aName, const css::uno::Any& aElement ) override; virtual void SAL_CALL removeByName( const OUString& Name ) override; diff --git a/svx/source/unodraw/unomtabl.cxx b/svx/source/unodraw/unomtabl.cxx index d57e9665156f..bca16038a99d 100644 --- a/svx/source/unodraw/unomtabl.cxx +++ b/svx/source/unodraw/unomtabl.cxx @@ -24,6 +24,7 @@ #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/drawing/PointSequence.hpp> +#include <com/sun/star/util/XCancellable.hpp> #include <comphelper/sequence.hxx> #include <cppuhelper/implbase.hxx> @@ -51,8 +52,12 @@ typedef std::vector<std::unique_ptr<SfxItemSet>> ItemPoolVector; namespace { -class SvxUnoMarkerTable : public WeakImplHelper< container::XNameContainer, lang::XServiceInfo >, - public SfxListener +class SvxUnoMarkerTable + : public WeakImplHelper< + util::XCancellable, + container::XNameContainer, + lang::XServiceInfo> + , public SfxListener { private: SdrModel* mpModel; @@ -76,6 +81,9 @@ public: virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + // XCancellable + virtual void SAL_CALL cancel() override; + // XNameContainer virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override; virtual void SAL_CALL removeByName( const OUString& Name ) override; @@ -105,6 +113,8 @@ SvxUnoMarkerTable::SvxUnoMarkerTable( SdrModel* pModel ) noexcept SvxUnoMarkerTable::~SvxUnoMarkerTable() noexcept { + SolarMutexGuard aGuard; + if( mpModel ) EndListening( *mpModel ); dispose(); @@ -174,17 +184,17 @@ void SAL_CALL SvxUnoMarkerTable::insertByName( const OUString& aApiName, const u ImplInsertByName( aName, aElement ); } -void SAL_CALL SvxUnoMarkerTable::removeByName( const OUString& aApiName ) +void SAL_CALL SvxUnoMarkerTable::cancel() { SolarMutexGuard aGuard; + // drop all items that are owned by this service and not the document + // (i.e. they are unused) + dispose(); +} - // a little quickfix for 2.0 to let applications clear api - // created items that are not used - if ( aApiName == "~clear~" ) - { - dispose(); - return; - } +void SAL_CALL SvxUnoMarkerTable::removeByName( const OUString& aApiName ) +{ + SolarMutexGuard aGuard; OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName); diff --git a/svx/source/xml/xmlgrhlp.cxx b/svx/source/xml/xmlgrhlp.cxx index bdb453579224..6b671c3a245b 100644 --- a/svx/source/xml/xmlgrhlp.cxx +++ b/svx/source/xml/xmlgrhlp.cxx @@ -26,6 +26,8 @@ #include <com/sun/star/io/NotConnectedException.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/util/XCancellable.hpp> #include <comphelper/fileformat.h> #include <comphelper/graphicmimetype.hxx> #include <cppuhelper/compbase.hxx> @@ -40,6 +42,7 @@ #include <vcl/gfxlink.hxx> #include <vcl/metaact.hxx> #include <tools/zcodec.hxx> +#include <tools/diagnose_ex.h> #include <vcl/GraphicObject.hxx> #include <vcl/graphicfilter.hxx> @@ -1121,4 +1124,68 @@ com_sun_star_comp_Svx_GraphicExportHelper_get_implementation( return cppu::acquire(new SvXMLGraphicImportExportHelper(SvXMLGraphicHelperMode::Write)); } +namespace svx { + + void DropUnusedNamedItems(css::uno::Reference<css::uno::XInterface> const& xModel) + { + uno::Reference<lang::XMultiServiceFactory> const xModelFactory(xModel, uno::UNO_QUERY); + assert(xModelFactory.is()); + try + { + uno::Reference<util::XCancellable> const xGradient( + xModelFactory->createInstance("com.sun.star.drawing.GradientTable"), + uno::UNO_QUERY ); + if (xGradient.is()) + { + xGradient->cancel(); + } + + uno::Reference<util::XCancellable> const xHatch( + xModelFactory->createInstance("com.sun.star.drawing.HatchTable"), + uno::UNO_QUERY ); + if (xHatch.is()) + { + xHatch->cancel(); + } + + uno::Reference<util::XCancellable> const xBitmap( + xModelFactory->createInstance("com.sun.star.drawing.BitmapTable"), + uno::UNO_QUERY ); + if (xBitmap.is()) + { + xBitmap->cancel(); + } + + uno::Reference<util::XCancellable> const xTransGradient( + xModelFactory->createInstance("com.sun.star.drawing.TransparencyGradientTable"), + uno::UNO_QUERY ); + if (xTransGradient.is()) + { + xTransGradient->cancel(); + } + + uno::Reference<util::XCancellable> const xMarker( + xModelFactory->createInstance("com.sun.star.drawing.MarkerTable"), + uno::UNO_QUERY ); + if (xMarker.is()) + { + xMarker->cancel(); + } + + uno::Reference<util::XCancellable> const xDashes( + xModelFactory->createInstance("com.sun.star.drawing.DashTable"), + uno::UNO_QUERY ); + if (xDashes.is()) + { + xDashes->cancel(); + } + } + catch (const Exception&) + { + TOOLS_WARN_EXCEPTION("svx", "dropUnusedNamedItems(): exception during clearing of unused named items"); + } + } + +} // namespace svx + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |