diff options
Diffstat (limited to 'filter/source/svg')
-rw-r--r-- | filter/source/svg/svgexport.cxx | 154 | ||||
-rw-r--r-- | filter/source/svg/svgfilter.cxx | 94 | ||||
-rw-r--r-- | filter/source/svg/svgfilter.hxx | 5 | ||||
-rw-r--r-- | filter/source/svg/svgwriter.cxx | 12 |
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 ); } |