summaryrefslogtreecommitdiff
path: root/filter/source/svg
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/svg')
-rw-r--r--filter/source/svg/svgexport.cxx154
-rw-r--r--filter/source/svg/svgfilter.cxx94
-rw-r--r--filter/source/svg/svgfilter.hxx5
-rw-r--r--filter/source/svg/svgwriter.cxx12
4 files changed, 227 insertions, 38 deletions
diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index 1938ee451db2..bf47d2a7d529 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -31,6 +31,8 @@
#include "svgfilter.hxx"
#include "impsvgdialog.hxx"
+#include <com/sun/star/graphic/XPrimitiveFactory2D.hpp>
+
#include <svx/unopage.hxx>
#include <svx/unoshape.hxx>
#include <svx/svdpage.hxx>
@@ -41,6 +43,8 @@
#include <svx/svdlegacy.hxx>
#include <svx/svdetc.hxx>
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::geometry;
using ::rtl::OUString;
// -------------
@@ -215,6 +219,11 @@ sal_Bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
{
pValue[ i ].Value >>= maFilterData;
}
+ else if( pValue[ i ].Name.equalsAscii( "ShapeSelection" ) )
+ {
+ // #124608# read selection if given
+ pValue[ i ].Value >>= maShapeSelection;
+ }
}
// if no filter data is given use stored/prepared ones
@@ -395,6 +404,7 @@ sal_Bool SVGFilter::implExportDocument( const Reference< XDrawPages >& rxMasterP
"SVGFilter::implExportDocument: invalid parameter" );
OUString aAttr;
+ sal_Int32 nDocX = 0, nDocY = 0; // #124608#
sal_Int32 nDocWidth = 0, nDocHeight = 0;
sal_Int32 nVisible = -1, nVisibleMaster = -1;
sal_Bool bRet = sal_False;
@@ -405,10 +415,61 @@ sal_Bool SVGFilter::implExportDocument( const Reference< XDrawPages >& rxMasterP
const Reference< XPropertySet > xDefaultPagePropertySet( mxDefaultPage, UNO_QUERY );
const Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
- if( xDefaultPagePropertySet.is() )
+ // #124608#
+ mbExportSelection = maShapeSelection.is() && maShapeSelection->getCount();
+
+ if(xDefaultPagePropertySet.is())
{
- xDefaultPagePropertySet->getPropertyValue( B2UCONST( "Width" ) ) >>= nDocWidth;
- xDefaultPagePropertySet->getPropertyValue( B2UCONST( "Height" ) ) >>= nDocHeight;
+ xDefaultPagePropertySet->getPropertyValue(B2UCONST("Width")) >>= nDocWidth;
+ xDefaultPagePropertySet->getPropertyValue(B2UCONST("Height")) >>= nDocHeight;
+ }
+
+ if(mbExportSelection)
+ {
+ // #124608# create BoundRange and set nDocX, nDocY, nDocWidth and nDocHeight
+ basegfx::B2DRange aShapeRange;
+
+ Reference< XPrimitiveFactory2D > xPrimitiveFactory(
+ mxMSF->createInstance(
+ String(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.graphic.PrimitiveFactory2D"))),
+ UNO_QUERY);
+
+ // use XPrimitiveFactory2D and go the way over getting the primitives; this
+ // will give better precision (doubles) and be based on the true object
+ // geometry. If needed aViewInformation may be expanded to carry a view
+ // resolution for which to prepare the geometry.
+ if(xPrimitiveFactory.is())
+ {
+ Reference< XShape > xShapeCandidate;
+ const Sequence< PropertyValue > aViewInformation;
+ const Sequence< PropertyValue > aParams;
+
+ for(sal_Int32 a(0); a < maShapeSelection->getCount(); a++)
+ {
+ if((maShapeSelection->getByIndex(a) >>= xShapeCandidate) && xShapeCandidate.is())
+ {
+ const Sequence< Reference< XPrimitive2D > > aPrimitiveSequence(
+ xPrimitiveFactory->createPrimitivesFromXShape( xShapeCandidate, aParams ));
+ const sal_Int32 nCount(aPrimitiveSequence.getLength());
+
+ for(sal_Int32 nIndex = 0; nIndex < nCount; nIndex++)
+ {
+ const RealRectangle2D aRect(aPrimitiveSequence[nIndex]->getRange(aViewInformation));
+
+ aShapeRange.expand(basegfx::B2DTuple(aRect.X1, aRect.Y1));
+ aShapeRange.expand(basegfx::B2DTuple(aRect.X2, aRect.Y2));
+ }
+ }
+ }
+ }
+
+ if(!aShapeRange.isEmpty())
+ {
+ nDocX = basegfx::fround(aShapeRange.getMinX());
+ nDocY = basegfx::fround(aShapeRange.getMinY());
+ nDocWidth = basegfx::fround(aShapeRange.getWidth());
+ nDocHeight = basegfx::fround(aShapeRange.getHeight());
+ }
}
if( xExtDocHandler.is() && !mpSVGExport->IsUseTinyProfile() )
@@ -431,11 +492,23 @@ sal_Bool SVGFilter::implExportDocument( const Reference< XDrawPages >& rxMasterP
mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", aAttr );
#endif
- aAttr = B2UCONST( "0 0 " );
+ // #124608# set viewBox explicitely to the exported content
+ if(mbExportSelection)
+ {
+ aAttr = OUString::valueOf( nDocX );
+ aAttr += B2UCONST( " " );
+ aAttr += OUString::valueOf( nDocY );
+ aAttr += B2UCONST( " " );
+ }
+ else
+ {
+ aAttr = B2UCONST( "0 0 " );
+ }
+
aAttr += OUString::valueOf( nDocWidth );
aAttr += B2UCONST( " " );
aAttr += OUString::valueOf( nDocHeight );
- mpSVGExport->SetViewBox( Rectangle( Point(), Size( nDocWidth, nDocHeight ) ) );
+ mpSVGExport->SetViewBox( Rectangle( Point(nDocX, nDocY), Size( nDocWidth, nDocHeight ) ) );
mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "viewBox", aAttr );
mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "preserveAspectRatio", B2UCONST( "xMidYMid" ) );
mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "fill-rule", B2UCONST( "evenodd" ) );
@@ -509,8 +582,17 @@ sal_Bool SVGFilter::implExportDocument( const Reference< XDrawPages >& rxMasterP
if( -1 != nVisible )
{
- if( bSinglePage )
- implExportPages( rxMasterPages, nVisibleMaster, nVisibleMaster, nVisibleMaster, sal_True );
+ if(bSinglePage)
+ {
+ if(mbExportSelection)
+ {
+ // #124608# export a given object selection, so no MasterPage export at all
+ }
+ else
+ {
+ implExportPages(rxMasterPages,nVisibleMaster,nVisibleMaster,nVisibleMaster,sal_True);
+ }
+ }
else
{
implGenerateMetaData( rxMasterPages, rxDrawPages );
@@ -625,7 +707,17 @@ sal_Bool SVGFilter::implExportPages( const Reference< XDrawPages >& rxPages,
if( xDrawPage.is() )
{
- Reference< XShapes > xShapes( xDrawPage, UNO_QUERY );
+ Reference< XShapes > xShapes;
+
+ if(mbExportSelection)
+ {
+ // #124608# export a given object selection
+ xShapes = maShapeSelection;
+ }
+ else
+ {
+ xShapes = Reference< XShapes >( xDrawPage, UNO_QUERY );
+ }
if( xShapes.is() )
{
@@ -862,6 +954,7 @@ sal_Bool SVGFilter::implCreateObjects( const Reference< XDrawPages >& rxMasterPa
{
if( SVG_EXPORT_ALLPAGES == nPageToExport )
{
+ // export the whole document
sal_Int32 i, nCount;
for( i = 0, nCount = rxMasterPages->getCount(); i < nCount; ++i )
@@ -901,34 +994,43 @@ sal_Bool SVGFilter::implCreateObjects( const Reference< XDrawPages >& rxMasterPa
DBG_ASSERT( nPageToExport >= 0 && nPageToExport < rxDrawPages->getCount(),
"SVGFilter::implCreateObjects: invalid page number to export" );
- Reference< XDrawPage > xDrawPage;
-
- rxDrawPages->getByIndex( nPageToExport ) >>= xDrawPage;
+ if(mbExportSelection)
+ {
+ // #124608# export a given object selection
+ implCreateObjectsFromShapes(maShapeSelection);
+ }
+ else
+ {
+ // export a given xDrawPage
+ Reference< XDrawPage > xDrawPage;
- if( xDrawPage.is() )
- {
- Reference< XMasterPageTarget > xMasterTarget( xDrawPage, UNO_QUERY );
+ rxDrawPages->getByIndex(nPageToExport) >>= xDrawPage;
- if( xMasterTarget.is() )
+ if(xDrawPage.is())
{
- Reference< XDrawPage > xMasterPage( xMasterTarget->getMasterPage() );
+ Reference< XMasterPageTarget > xMasterTarget(xDrawPage,UNO_QUERY);
- if( xMasterPage.is() )
+ if(xMasterTarget.is())
{
- Reference< XShapes > xShapes( xMasterPage, UNO_QUERY );
+ Reference< XDrawPage > xMasterPage(xMasterTarget->getMasterPage());
- implCreateObjectsFromBackground( xMasterPage );
+ if(xMasterPage.is())
+ {
+ Reference< XShapes > xShapes(xMasterPage,UNO_QUERY);
+
+ implCreateObjectsFromBackground(xMasterPage);
- if( xShapes.is() )
- implCreateObjectsFromShapes( xShapes );
+ if(xShapes.is())
+ implCreateObjectsFromShapes(xShapes);
+ }
}
- }
- Reference< XShapes > xShapes( xDrawPage, UNO_QUERY );
+ Reference< XShapes > xShapes(xDrawPage,UNO_QUERY);
- if( xShapes.is() )
- implCreateObjectsFromShapes( xShapes );
- }
+ if(xShapes.is())
+ implCreateObjectsFromShapes(xShapes);
+ }
+ }
}
return sal_True;
diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index e7f3a3f5c8f8..4e4c5abfd47c 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -32,6 +32,7 @@
#include <com/sun/star/drawing/XDrawView.hpp>
#include <com/sun/star/frame/XDesktop.hdl>
#include <com/sun/star/frame/XController.hdl>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
#define SVG_FILTER_SERVICE_NAME "com.sun.star.comp.Draw.SVGFilter"
#define SVG_FILTER_IMPLEMENTATION_NAME SVG_FILTER_SERVICE_NAME
@@ -51,7 +52,22 @@ SVGFilter::SVGFilter( const Reference< XMultiServiceFactory > &rxMSF ) :
mpSVGWriter( NULL ),
mpDefaultSdrPage( NULL ),
mpSdrModel( NULL ),
- mbPresentation( sal_False )
+ mbPresentation( sal_False ),
+ mpObjects( NULL ),
+ mxSrcDoc(),
+#ifdef SOLAR_JAVA
+ mxDstDoc(),
+#endif
+ mxDefaultPage(),
+ maFilterData(),
+ maShapeSelection(),
+ mbExportSelection(false),
+ maUniqueIdVector(),
+ mnMasterSlideId(0),
+ mnSlideId(0),
+ mnDrawingGroupId(0),
+ mnDrawingId(0),
+ maOldFieldHdl()
{
}
@@ -86,6 +102,20 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto
#endif
if( mxSrcDoc.is() )
{
+ // #124608# detext selection
+ sal_Bool bSelectionOnly = sal_False;
+ bool bGotSelection(false);
+ Reference< drawing::XShapes > xShapes;
+
+ // #124608# extract Single selection wanted from dialog return values
+ for ( sal_Int32 nInd = 0; nInd < rDescriptor.getLength(); nInd++ )
+ {
+ if ( rDescriptor[nInd].Name.equalsAscii( "SelectionOnly" ) )
+ {
+ rDescriptor[nInd].Value >>= bSelectionOnly;
+ }
+ }
+
uno::Reference< frame::XDesktop > xDesktop( mxMSF->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ),
uno::UNO_QUERY);
if( xDesktop.is() )
@@ -110,22 +140,66 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto
getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Number" ) ) ) >>= nCurrentPageNumber;
}
}
+
+ if(bSelectionOnly)
+ {
+ // #124608# when selection only is wanted, get the current object selection
+ // from the DrawView
+ Reference< view::XSelectionSupplier > xSelection (xController, UNO_QUERY);
+
+ if (xSelection.is())
+ {
+ uno::Any aSelection;
+
+ if(xSelection->getSelection() >>= aSelection)
+ {
+ bGotSelection = (sal_True == ( aSelection >>= xShapes ));
+ }
+ }
+ }
}
}
}
- Sequence< PropertyValue > aNewDescriptor( rDescriptor );
-
- if( nCurrentPageNumber > 0 )
+ if(bSelectionOnly && bGotSelection && 0 == xShapes->getCount())
{
- const sal_uInt32 nOldLength = rDescriptor.getLength();
-
- aNewDescriptor.realloc( nOldLength + 1 );
- aNewDescriptor[ nOldLength ].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PagePos" ) );
- aNewDescriptor[ nOldLength ].Value <<= static_cast< sal_Int16 >( nCurrentPageNumber - 1 );
+ // #124608# export selection, got xShapes but no shape selected -> nothing
+ // to export, we are done (maybe return true, but a hint that nothing was done
+ // may be useful; it may have happened by error)
+ bRet = sal_False;
}
+ else
+ {
+ Sequence< PropertyValue > aNewDescriptor(rDescriptor);
+ const bool bSinglePage(nCurrentPageNumber > 0);
+
+ if(bSinglePage || bGotSelection)
+ {
+ const sal_uInt32 nOldLength = rDescriptor.getLength();
+ sal_uInt32 nInsert(nOldLength);
+
+ aNewDescriptor.realloc(nOldLength + (bSinglePage ? 1 : 0) + (bGotSelection ? 1 : 0));
+
+ if(bSinglePage)
+ {
+ aNewDescriptor[nInsert].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PagePos"));
+ aNewDescriptor[nInsert].Value <<= static_cast<sal_Int16>(nCurrentPageNumber - 1);
+ nInsert++;
+ }
- bRet = implExport( aNewDescriptor );
+ if(bGotSelection)
+ {
+ // #124608# add retrieved ShapeSelection if export of only selected shapes is wanted
+ // so that the filter implementation can use it
+ aNewDescriptor[nInsert].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShapeSelection"));
+ aNewDescriptor[nInsert].Value <<= xShapes;
+ // reactivate this when you add other properties to aNewDescriptor
+ // nInsert++;
+ }
+ }
+
+ bRet = implExport(aNewDescriptor);
+ }
}
else
bRet = sal_False;
diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx
index 97a660eed7f1..b4822079ad2f 100644
--- a/filter/source/svg/svgfilter.hxx
+++ b/filter/source/svg/svgfilter.hxx
@@ -246,6 +246,11 @@ private:
#endif
Reference< XDrawPage > mxDefaultPage;
Sequence< PropertyValue > maFilterData;
+
+ // #124608# explicit ShapeSelection for export when export of the selection is wanted
+ Reference< XShapes > maShapeSelection;
+ bool mbExportSelection;
+
UniqueIdVector maUniqueIdVector;
sal_Int32 mnMasterSlideId;
sal_Int32 mnSlideId;
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index 416020c03d62..26f3d2ad78d7 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -1647,7 +1647,11 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
if(aStartArrow.Count())
{
mapCurShape->maShapePolyPoly = aStartArrow;
- mapCurShape->maId = *pElementId + B2UCONST("_") + ::rtl::OUString::valueOf(nEntryCount++);
+
+ if( pElementId ) // #i124825# pElementId is optinal, may be zero
+ {
+ mapCurShape->maId = *pElementId + B2UCONST("_") + ::rtl::OUString::valueOf(nEntryCount++);
+ }
ImplWriteShape( *mapCurShape );
}
@@ -1655,7 +1659,11 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
if(aEndArrow.Count())
{
mapCurShape->maShapePolyPoly = aEndArrow;
- mapCurShape->maId = *pElementId + B2UCONST("_") + ::rtl::OUString::valueOf(nEntryCount++);
+
+ if( pElementId ) // #i124825# pElementId is optinal, may be zero
+ {
+ mapCurShape->maId = *pElementId + B2UCONST("_") + ::rtl::OUString::valueOf(nEntryCount++);
+ }
ImplWriteShape( *mapCurShape );
}