[Libreoffice-commits] .: 13 commits - filter/source sd/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Oct 10 03:03:59 PDT 2012


 filter/source/svg/presentation_engine.js              | 1052 +++++++++-
 filter/source/svg/svgexport.cxx                       |  701 +++++-
 filter/source/svg/svgfilter.cxx                       |   94 
 filter/source/svg/svgfilter.hxx                       |   36 
 filter/source/svg/svgwriter.cxx                       | 1856 +++++++++++++++++-
 filter/source/svg/svgwriter.hxx                       |  192 +
 sd/source/ui/framework/factories/BasicViewFactory.cxx |   14 
 sd/source/ui/framework/factories/ViewShellWrapper.cxx |   99 
 sd/source/ui/inc/framework/ViewShellWrapper.hxx       |   15 
 9 files changed, 3704 insertions(+), 355 deletions(-)

New commits:
commit aa1927dc257b52edf96de220cc3797e02c83a0ae
Author: Thorsten Behrens <tbehrens at suse.com>
Date:   Wed Oct 10 10:57:35 2012 +0200

    Make svg export use slidesorter selection in most cases.
    
    There was code previously that took the current selection, iff
    Impress main view was in slidesorter mode. Extended this quite
    helpful functionality to also work in other modes (as long as a
    slidesorter pane is displayed & has up-to-date selection, it should
    work).
    
    Change-Id: Ibbfe630a4ca31aa52978501745c2eef0d79fb8e3

diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index 8907bb2..b5b4584 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -32,6 +32,9 @@
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XConfiguration.hpp>
+#include <com/sun/star/drawing/framework/AnchorBindingMode.hpp>
+#include <com/sun/star/drawing/framework/XResourceId.hpp>
 #include <com/sun/star/drawing/framework/XResource.hpp>
 #include <com/sun/star/drawing/framework/XView.hpp>
 #include <com/sun/star/drawing/framework/ResourceId.hpp>
@@ -77,7 +80,6 @@ SVGFilter::~SVGFilter()
 
 // -----------------------------------------------------------------------------
 
-
 sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescriptor )
     throw (RuntimeException)
 {
@@ -92,49 +94,71 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto
         bRet = implImport( rDescriptor );
     else if( mxSrcDoc.is() )
     {
-        if( !mbExportAll )
+        if( !mbExportAll && !mSelectedPages.hasElements() )
         {
-            uno::Reference< frame::XDesktop > xDesktop( mxMSF->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" )) ),
-                                                        uno::UNO_QUERY);
-            if( xDesktop.is() )
+            uno::Reference< frame::XDesktop >                            xDesktop(mxMSF->createInstance( "com.sun.star.frame.Desktop" ),
+                                                                                  uno::UNO_QUERY_THROW);
+            uno::Reference< frame::XFrame >                              xFrame(xDesktop->getCurrentFrame(),
+                                                                                uno::UNO_QUERY_THROW);
+            uno::Reference<frame::XController >                          xController(xFrame->getController(),
+                                                                                     uno::UNO_QUERY_THROW);
+            uno::Reference<drawing::XDrawView >                          xDrawView(xController,
+                                                                                   uno::UNO_QUERY_THROW);
+            uno::Reference<drawing::framework::XControllerManager>       xManager(xController,
+                                                                                  uno::UNO_QUERY_THROW);
+            uno::Reference<drawing::framework::XConfigurationController> xConfigController(xManager->getConfigurationController());
+
+            // which view configuration are we in?
+            //
+            // * traverse Impress resources to find slide preview pane, grab selection from there
+            // * otherwise, fallback to current slide
+            //
+            uno::Sequence<uno::Reference<drawing::framework::XResourceId> > aResIds(
+                xConfigController->getCurrentConfiguration()->getResources(
+                    uno::Reference<drawing::framework::XResourceId>(),
+                    "",
+                    drawing::framework::AnchorBindingMode_INDIRECT));
+
+            for( sal_Int32 i=0; i<aResIds.getLength(); ++i )
             {
-                uno::Reference< frame::XFrame > xFrame( xDesktop->getCurrentFrame() );
-
-                if( xFrame.is() )
+                // can we somehow obtain the slidesorter from the Impress framework?
+                if( aResIds[i]->getResourceURL() == "private:resource/view/SlideSorter" )
                 {
-                    uno::Reference< frame::XController > xController( xFrame->getController() );
-
-                    if( xController.is() )
+                    // got it, grab current selection from there
+                    uno::Reference<drawing::framework::XResource> xRes(
+                        xConfigController->getResource(aResIds[i]));
+
+                    uno::Reference< view::XSelectionSupplier > xSelectionSupplier(
+                        xRes,
+                        uno::UNO_QUERY );
+                    if( xSelectionSupplier.is() )
                     {
-                        /*
-                         *  Get the selection from the Slide Sorter Center Pane
-                         */
-                        if( !mSelectedPages.hasElements() )
+                        uno::Any aSelection = xSelectionSupplier->getSelection();
+                        if( aSelection.hasValue() )
                         {
-                            uno::Reference< beans::XPropertySet > xControllerPropertySet( xController, uno::UNO_QUERY );
-                            uno::Reference< drawing::XDrawSubController > xSubController;
-                            xControllerPropertySet->getPropertyValue(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SubController" ) ) )
-                                    >>= xSubController;
-
-                            if( xSubController.is() )
+                            ObjectSequence aSelectedPageSequence;
+                            aSelection >>= aSelectedPageSequence;
+                            mSelectedPages.realloc( aSelectedPageSequence.getLength() );
+                            for( sal_Int32 j=0; j<mSelectedPages.getLength(); ++j )
                             {
-                                uno::Any aSelection = xSubController->getSelection();
-                                if( aSelection.hasValue() )
-                                {
-                                    ObjectSequence aSelectedPageSequence;
-                                    aSelection >>= aSelectedPageSequence;
-                                    mSelectedPages.realloc( aSelectedPageSequence.getLength() );
-                                    for( sal_Int32 i = 0; i < mSelectedPages.getLength(); ++i )
-                                    {
-                                        uno::Reference< drawing::XDrawPage > xDrawPage( aSelectedPageSequence[i],  uno::UNO_QUERY );
-                                        mSelectedPages[i] = xDrawPage;
-                                    }
-                                }
+                                uno::Reference< drawing::XDrawPage > xDrawPage( aSelectedPageSequence[j],
+                                                                                uno::UNO_QUERY );
+                                mSelectedPages[j] = xDrawPage;
                             }
+
+                            // and stop looping. it is likely not getting better
+                            break;
                         }
                     }
                 }
             }
+
+            if( !mSelectedPages.hasElements() )
+            {
+                // apparently failed to glean selection - fallback to current page
+                mSelectedPages.realloc( 1 );
+                mSelectedPages[0] = xDrawView->getCurrentPage();
+            }
         }
 
         /*
@@ -154,8 +178,8 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto
                 }
             }
 
-            uno::Reference< drawing::XMasterPagesSupplier >        xMasterPagesSupplier( mxSrcDoc, uno::UNO_QUERY );
-            uno::Reference< drawing::XDrawPagesSupplier >        xDrawPagesSupplier( mxSrcDoc, uno::UNO_QUERY );
+            uno::Reference< drawing::XMasterPagesSupplier > xMasterPagesSupplier( mxSrcDoc, uno::UNO_QUERY );
+            uno::Reference< drawing::XDrawPagesSupplier >   xDrawPagesSupplier( mxSrcDoc, uno::UNO_QUERY );
 
             if( xMasterPagesSupplier.is() && xDrawPagesSupplier.is() )
             {
diff --git a/sd/source/ui/framework/factories/ViewShellWrapper.cxx b/sd/source/ui/framework/factories/ViewShellWrapper.cxx
index ad27974..058577a 100644
--- a/sd/source/ui/framework/factories/ViewShellWrapper.cxx
+++ b/sd/source/ui/framework/factories/ViewShellWrapper.cxx
@@ -30,11 +30,22 @@
 #include "framework/ViewShellWrapper.hxx"
 #include "framework/Pane.hxx"
 #include "taskpane/ToolPanelViewShell.hxx"
+#include "sdpage.hxx"
 #include "ViewShell.hxx"
 #include "Window.hxx"
 
+#include "SlideSorter.hxx"
+#include "SlideSorterViewShell.hxx"
+#include "controller/SlsPageSelector.hxx"
+#include "controller/SlsCurrentSlideManager.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "model/SlsPageEnumerationProvider.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageDescriptor.hxx"
+
 #include <com/sun/star/drawing/framework/XPane.hpp>
 #include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
 
 #include <toolkit/helper/vclunohelper.hxx>
 #include <comphelper/sequence.hxx>
@@ -64,6 +75,8 @@ ViewShellWrapper::ViewShellWrapper (
     const Reference<awt::XWindow>& rxWindow)
     : ViewShellWrapperInterfaceBase(MutexOwner::maMutex),
       mpViewShell(pViewShell),
+      mpSlideSorterViewShell(
+          ::boost::dynamic_pointer_cast< ::sd::slidesorter::SlideSorterViewShell >( pViewShell )),
       mxViewId(rxViewId),
       mxWindow(rxWindow)
 {
@@ -94,6 +107,20 @@ void SAL_CALL ViewShellWrapper::disposing (void)
     mpViewShell.reset();
 }
 
+uno::Any SAL_CALL ViewShellWrapper::queryInterface( const uno::Type & rType ) throw(uno::RuntimeException)
+{
+    if( mpSlideSorterViewShell &&
+        rType == ::getCppuType( static_cast< uno::Reference< view::XSelectionSupplier > * >( 0 ) ) )
+    {
+        uno::Any aAny;
+        uno::Reference<view::XSelectionSupplier> xSupplier( this );
+        aAny <<= xSupplier;
+
+        return aAny;
+    }
+    else
+        return ViewShellWrapperInterfaceBase::queryInterface( rType );
+}
 
 
 
@@ -123,6 +150,70 @@ sal_Bool SAL_CALL ViewShellWrapper::isAnchorOnly (void)
 }
 
 
+//----- XSelectionSupplier --------------------------------------------------
+
+sal_Bool SAL_CALL ViewShellWrapper::select( const ::com::sun::star::uno::Any& aSelection ) throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+    bool bOk = true;
+
+    ::sd::slidesorter::controller::SlideSorterController& rSlideSorterController
+        = mpSlideSorterViewShell->GetSlideSorter().GetController();
+    ::sd::slidesorter::controller::PageSelector& rSelector (rSlideSorterController.GetPageSelector());
+    rSelector.DeselectAllPages();
+    Sequence<Reference<drawing::XDrawPage> > xPages;
+    aSelection >>= xPages;
+    const sal_uInt32 nCount = xPages.getLength();
+    for (sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex)
+    {
+        Reference<beans::XPropertySet> xSet (xPages[nIndex], UNO_QUERY);
+        if (xSet.is())
+        {
+            try
+            {
+                Any aNumber = xSet->getPropertyValue("Number");
+                sal_Int32 nPageNumber = 0;
+                aNumber >>= nPageNumber;
+                nPageNumber -=1; // Transform 1-based page numbers to 0-based ones.
+                rSelector.SelectPage(nPageNumber);
+            }
+            catch (const RuntimeException&)
+            {
+            }
+        }
+    }
+
+    return bOk;
+}
+
+uno::Any SAL_CALL ViewShellWrapper::getSelection() throw(uno::RuntimeException)
+{
+    Any aResult;
+
+    slidesorter::model::PageEnumeration aSelectedPages (
+        slidesorter::model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+            mpSlideSorterViewShell->GetSlideSorter().GetModel()));
+    int nSelectedPageCount (
+        mpSlideSorterViewShell->GetSlideSorter().GetController().GetPageSelector().GetSelectedPageCount());
+
+    Sequence<Reference<XInterface> > aPages(nSelectedPageCount);
+    int nIndex = 0;
+    while (aSelectedPages.HasMoreElements() && nIndex<nSelectedPageCount)
+    {
+        slidesorter::model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
+        aPages[nIndex++] = pDescriptor->GetPage()->getUnoPage();
+    }
+    aResult <<= aPages;
+
+    return aResult;
+}
+
+void SAL_CALL ViewShellWrapper::addSelectionChangeListener( const uno::Reference< view::XSelectionChangeListener >& ) throw(uno::RuntimeException)
+{
+}
+
+void SAL_CALL ViewShellWrapper::removeSelectionChangeListener( const uno::Reference< view::XSelectionChangeListener >& ) throw(uno::RuntimeException)
+{
+}
 
 
 //----- XRelocatableResource --------------------------------------------------
diff --git a/sd/source/ui/inc/framework/ViewShellWrapper.hxx b/sd/source/ui/inc/framework/ViewShellWrapper.hxx
index 87c2eb7..b491476 100644
--- a/sd/source/ui/inc/framework/ViewShellWrapper.hxx
+++ b/sd/source/ui/inc/framework/ViewShellWrapper.hxx
@@ -23,18 +23,20 @@
 #include "MutexOwner.hxx"
 #include <com/sun/star/drawing/framework/XView.hpp>
 #include <com/sun/star/drawing/framework/XRelocatableResource.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
 #include <com/sun/star/awt/XWindow.hpp>
 #include <com/sun/star/lang/XUnoTunnel.hpp>
 #include <osl/mutex.hxx>
-#include <cppuhelper/compbase4.hxx>
+#include <cppuhelper/compbase5.hxx>
 #include <cppuhelper/implbase1.hxx>
 
 #include <boost/shared_ptr.hpp>
 
 namespace {
 
-typedef ::cppu::WeakComponentImplHelper4    <   ::com::sun::star::lang::XUnoTunnel
+typedef ::cppu::WeakComponentImplHelper5    <   ::com::sun::star::lang::XUnoTunnel
                                             ,   ::com::sun::star::awt::XWindowListener
+                                            ,   ::com::sun::star::view::XSelectionSupplier
                                             ,   ::com::sun::star::drawing::framework::XRelocatableResource
                                             ,   ::com::sun::star::drawing::framework::XView
                                             >   ViewShellWrapperInterfaceBase;
@@ -42,6 +44,7 @@ typedef ::cppu::WeakComponentImplHelper4    <   ::com::sun::star::lang::XUnoTunn
 } // end of anonymous namespace.
 
 namespace sd { class ViewShell; }
+namespace sd { namespace slidesorter { class SlideSorterViewShell; } }
 
 namespace sd { namespace framework {
 
@@ -72,6 +75,7 @@ public:
     virtual ~ViewShellWrapper (void);
 
     virtual void SAL_CALL disposing (void);
+    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
 
     static const ::com::sun::star::uno::Sequence<sal_Int8>& getUnoTunnelId (void);
 
@@ -95,6 +99,12 @@ public:
     virtual sal_Bool SAL_CALL isAnchorOnly (void)
         throw (com::sun::star::uno::RuntimeException);
 
+    // XSelectionSupplier
+
+    virtual sal_Bool SAL_CALL select( const ::com::sun::star::uno::Any& aSelection ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+    virtual ::com::sun::star::uno::Any SAL_CALL getSelection(  ) throw(::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL addSelectionChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL removeSelectionChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
 
     // XRelocatableResource
 
@@ -131,6 +141,7 @@ public:
 
 private:
     ::boost::shared_ptr< ViewShell >                                                            mpViewShell;
+    ::boost::shared_ptr< ::sd::slidesorter::SlideSorterViewShell >                              mpSlideSorterViewShell;
     const ::com::sun::star::uno::Reference< com::sun::star::drawing::framework::XResourceId >   mxViewId;
     ::com::sun::star::uno::Reference<com::sun::star::awt::XWindow >                             mxWindow;
 };
commit 7f69b4a5310667378fcb127795654f410dbaa7c6
Author: Thorsten Behrens <tbehrens at suse.com>
Date:   Wed Oct 10 10:50:17 2012 +0200

    Don't (indirectly) call virtual funcs in ctor.
    
    We're not fully constructed at that point.
    
    Change-Id: Ie80874c57000481c4eaa8d71118c8be6f0059164

diff --git a/sd/source/ui/framework/factories/BasicViewFactory.cxx b/sd/source/ui/framework/factories/BasicViewFactory.cxx
index 9badf15..237dc72 100644
--- a/sd/source/ui/framework/factories/BasicViewFactory.cxx
+++ b/sd/source/ui/framework/factories/BasicViewFactory.cxx
@@ -368,10 +368,22 @@ void SAL_CALL BasicViewFactory::initialize (const Sequence<Any>& aArguments)
         pDescriptor->mpViewShell->Init(bIsCenterPane);
         mpBase->GetViewShellManager()->ActivateViewShell(pDescriptor->mpViewShell.get());
 
+        Reference<awt::XWindow> xWindow(rxPane->getWindow());
         pDescriptor->mpWrapper = new ViewShellWrapper(
             pDescriptor->mpViewShell,
             rxViewId,
-            rxPane->getWindow());
+            xWindow);
+
+        // register ViewShellWrapper on pane window
+        if (xWindow.is())
+        {
+            xWindow->addWindowListener(pDescriptor->mpWrapper);
+            if (pDescriptor->mpViewShell != NULL)
+            {
+                pDescriptor->mpViewShell->Resize();
+            }
+        }
+
         pDescriptor->mxView.set( pDescriptor->mpWrapper->queryInterface( XResource::static_type() ), UNO_QUERY_THROW );
     }
 
diff --git a/sd/source/ui/framework/factories/ViewShellWrapper.cxx b/sd/source/ui/framework/factories/ViewShellWrapper.cxx
index 1108ffe..ad27974 100644
--- a/sd/source/ui/framework/factories/ViewShellWrapper.cxx
+++ b/sd/source/ui/framework/factories/ViewShellWrapper.cxx
@@ -67,14 +67,6 @@ ViewShellWrapper::ViewShellWrapper (
       mxViewId(rxViewId),
       mxWindow(rxWindow)
 {
-    if (rxWindow.is())
-    {
-        rxWindow->addWindowListener(this);
-        if (pViewShell != NULL)
-        {
-            pViewShell->Resize();
-        }
-    }
 }
 
 
commit d32ee009e07a98e54237872263eeb53d4812e805
Author: Thorsten Behrens <tbehrens at suse.com>
Date:   Wed Oct 10 10:39:17 2012 +0200

    Don't assume we're exporting Impress to svg, unconditionally
    
    Svg export is also used on Draw documents, which do not bear the
    transition properties. Guard accordingly.
    
    Change-Id: I2e4a5d478a8de8621265a0d1de16bd60b1f47cc1

diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index 905500a..d8f3a84 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -1123,7 +1123,8 @@ sal_Bool SVGFilter::implGenerateMetaData()
                         // We look for a slide transition.
                         // Transition properties are exported together with animations.
                         sal_Int16 nTransitionType(0);
-                        if( xPropSet->getPropertyValue( B2UCONST( "TransitionType" ) )  >>= nTransitionType )
+                        if( xPropSet->getPropertySetInfo()->hasPropertyByName( "TransitionType" ) &&
+                            (xPropSet->getPropertyValue( "TransitionType" ) >>= nTransitionType) )
                         {
                             sal_Int16 nTransitionSubType(0);
                             if( xPropSet->getPropertyValue( B2UCONST( "TransitionSubtype" ) )  >>= nTransitionSubType )
@@ -1187,7 +1188,7 @@ sal_Bool SVGFilter::implExportAnimations()
     {
         Reference< XPropertySet > xProps( mSelectedPages[i], UNO_QUERY );
 
-        if( xProps.is() )
+        if( xProps.is() && xProps->getPropertySetInfo()->hasPropertyByName( "TransitionType" ) )
         {
             sal_Int16 nTransition = 0;
             xProps->getPropertyValue(  B2UCONST( "TransitionType" ) )  >>= nTransition;
commit f64457b19cea3c16c0a53f1d98134d48833ef4ed
Author: Thorsten Behrens <tbehrens at suse.com>
Date:   Wed Oct 10 11:05:30 2012 +0200

    Define ooo xmlns prefix unconditionally for svg export
    
    Plus some commented-code cleanup

diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index f3c8350..905500a 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -738,7 +738,6 @@ Reference< XDocumentHandler > SVGFilter::implCreateExportDocumentHandler( const
 
 // -----------------------------------------------------------------------------
 
-inline
 sal_Bool SVGFilter::implLookForFirstVisiblePage()
 {
     sal_Int32 nCurPage = 0, nLastPage = mSelectedPages.getLength() - 1;
@@ -781,7 +780,6 @@ sal_Bool SVGFilter::implExportDocument()
 
     mbSinglePage = (nLastPage == 0) || !bExperimentalMode;
     mnVisiblePage = -1;
-//    mnVisibleMasterPage = -1;
 
     const Reference< XPropertySet >             xDefaultPagePropertySet( mxDefaultPage, UNO_QUERY );
     const Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
@@ -836,13 +834,7 @@ sal_Bool SVGFilter::implExportDocument()
     // standard line width is based on 1 pixel on a 90 DPI device (0.28222mmm)
     mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-width", OUString::valueOf( 28.222 ) );
     mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-linejoin", B2UCONST( "round" ) );
-
-    if( !mbSinglePage )
-    {
-        mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:ooo", B2UCONST( "http://xml.openoffice.org/svg/export" ) );
-    }
-
-
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:ooo", B2UCONST( "http://xml.openoffice.org/svg/export" ) );
     mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns", B2UCONST( "http://www.w3.org/2000/svg" ) );
     mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:xlink", B2UCONST( "http://www.w3.org/1999/xlink" ) );
 
@@ -2116,7 +2108,6 @@ OUString SVGFilter::implGetClassFromShape( const Reference< XShape >& rxShape )
 
 // -----------------------------------------------------------------------------
 
-//inline
 void SVGFilter::implRegisterInterface( const Reference< XInterface >& rxIf )
 {
     if( rxIf.is() )
@@ -2125,13 +2116,11 @@ void SVGFilter::implRegisterInterface( const Reference< XInterface >& rxIf )
 
 // -----------------------------------------------------------------------------
 
-//inline
 const ::rtl::OUString & SVGFilter::implGetValidIDFromInterface( const Reference< XInterface >& rxIf )
 {
    return (mpSVGExport->getInterfaceToIdentifierMapper()).getIdentifier( rxIf );
 }
 
-
 // -----------------------------------------------------------------------------
 
 OUString SVGFilter::implGetInterfaceName( const Reference< XInterface >& rxIf )
commit a6eb00438d5ae8555a71b4cf79caf3b3c2fe1b77
Author: Marco Cecchetti <mrcekets at gmail.com>
Date:   Sun Aug 26 18:48:01 2012 +0200

    Bug Fix: background objects on master pages were not stacked in the correct order

diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index a94d784..e9e2e73 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -1606,6 +1606,34 @@ function getClassAttribute(  aElem )
     return '';
 }
 
+function createElementGroup( aParentElement, aElementList, nFrom, nCount, sGroupClass, sGroupId )
+{
+    var nTo = nFrom + nCount;
+    if( nCount < 1 || aElementList.length < nTo )
+    {
+        log( 'createElementGroup: not enough elements available.' );
+        return;
+    }
+    var firstElement = aElementList[nFrom];
+    if( !firstElement )
+    {
+        log( 'createElementGroup: element not found.' );
+        return;
+    }
+    var aGroupElement = document.createElementNS( NSS['svg'], 'g' );
+    if( sGroupId )
+        aGroupElement.setAttribute( 'id', sGroupId );
+    if( sGroupClass )
+        aGroupElement.setAttribute( 'class', sGroupClass );
+    aParentElement.insertBefore( aGroupElement, firstElement );
+    var i = nFrom;
+    for( ; i < nTo; ++i )
+    {
+        aParentElement.removeChild( aElementList[i] );
+        aGroupElement.appendChild( aElementList[i] );
+    }
+}
+
 function initVisibilityProperty( aElement )
 {
     var nVisibility = VISIBLE;
@@ -2213,6 +2241,47 @@ function MasterPage( sMasterPageId )
     {
         this.backgroundObjectsId = this.backgroundObjects.getAttribute( 'id' );
         this.backgroundObjectsVisibility = initVisibilityProperty( this.backgroundObjects );
+
+        if( this.backgroundObjectsVisibility != HIDDEN )
+        {
+            var aBackgroundObjectList = getElementChildren( this.backgroundObjects );
+            var nFrom = 0;
+            var nCount = 0;
+            var nSubGroupId = 1;
+            var sClass;
+            var sId = '';
+            this.aBackgroundObjectSubGroupIdList = new Array();
+            var i = 0;
+            for( ; i < aBackgroundObjectList.length; ++i )
+            {
+                sClass = aBackgroundObjectList[i].getAttribute( 'class' );
+                if( !sClass || ( ( sClass !== aDateTimeClassName ) && ( sClass !== aFooterClassName )
+                                     && ( sClass !== aHeaderClassName ) && ( sClass !== aSlideNumberClassName ) ) )
+                {
+                    if( nCount === 0 )
+                    {
+                        nFrom = i;
+                        sId = this.backgroundObjectsId + '.' + nSubGroupId;
+                        ++nSubGroupId;
+                        this.aBackgroundObjectSubGroupIdList.push( sId );
+                    }
+                    ++nCount;
+                }
+                else
+                {
+                    this.aBackgroundObjectSubGroupIdList.push( sClass );
+                    if( nCount !== 0 )
+                    {
+                        createElementGroup( this.backgroundObjects, aBackgroundObjectList, nFrom, nCount, 'BackgroundObjectSubgroup', sId );
+                        nCount = 0;
+                    }
+                }
+            }
+            if( nCount !== 0 )
+            {
+                createElementGroup( this.backgroundObjects, aBackgroundObjectList, nFrom, nCount, 'BackgroundObjectSubgroup', sId );
+            }
+        }
     }
     else
     {
@@ -2355,15 +2424,14 @@ PlaceholderShape.prototype.init = function()
  *  <g class='MasterPageView'>
  *      <use class='Background'>               // reference to master page background element
  *      <g class='BackgroundObjects'>
- *          <g class='BackgroundFields'>
- *              <g class='Slide_Number'>       // a cloned element
+ *          <use class='BackgroundObjectSubGroup'>     // reference to the group of shapes on the master page that are below text fields
+ *          <g class='Slide_Number'>                   // a cloned element
  *                  ...
- *              </g>
- *              <use class='Date/Time'>        // reference to a clone
- *              <use class='Footer'>
- *              <use class='Header'>
  *          </g>
- *          <use class='BackgroundShapes'>     // reference to the group of shapes on the master page
+ *          <use class='Date/Time'>                    // reference to a clone
+ *          <use class='Footer'>
+ *          <use class='Header'>
+ *          <use class='BackgroundObjectSubGroup'>     // reference to the group of shapes on the master page that are above text fields
  *      </g>
  *  </g>
  *
@@ -2458,11 +2526,9 @@ MasterPageView.prototype.createElement = function()
         this.aBackgroundObjectsElement = theDocument.createElementNS( NSS['svg'], 'g' );
         this.aBackgroundObjectsElement.setAttribute( 'class', 'BackgroundObjects' );
 
-        // create background fields group
-        this.aBackgroundFieldsElement = theDocument.createElementNS( NSS['svg'], 'g' );
-        this.aBackgroundFieldsElement.setAttribute( 'class', 'BackgroundFields' );
-
         // clone and initialize text field elements
+        var aBackgroundObjectSubGroupIdList = this.aMasterPage.aBackgroundObjectSubGroupIdList;
+        this.aBackgroundSubGroupElementSet = new Array();
         var aPlaceholderShapeSet = this.aMasterPage.aPlaceholderShapeSet;
         var aTextFieldContentProviderSet = this.aMetaSlide.aTextFieldContentProviderSet;
         // where cloned elements are appended
@@ -2470,58 +2536,76 @@ MasterPageView.prototype.createElement = function()
         var aTextFieldHandlerSet = this.aMetaSlide.theMetaDoc.aTextFieldHandlerSet;
         var sMasterSlideId = this.aMasterPage.id;
 
-        // Slide Number Field
-        // The cloned element is appended directly to the field group element
-        // since there is no slide number field content shared between two slide
-        // (because the slide number of two slide is always different).
-        if( aPlaceholderShapeSet[aSlideNumberClassName] &&
-            aPlaceholderShapeSet[aSlideNumberClassName].isValid() &&
-            this.aMetaSlide.nIsPageNumberVisible &&
-            aTextFieldContentProviderSet[aSlideNumberClassName] )
-        {
-            this.aSlideNumberFieldHandler =
-            new SlideNumberFieldHandler( aPlaceholderShapeSet[aSlideNumberClassName],
-                                         aTextFieldContentProviderSet[aSlideNumberClassName] );
-            this.aSlideNumberFieldHandler.update( this.aMetaSlide.nSlideNumber );
-            this.aSlideNumberFieldHandler.appendTo( this.aBackgroundFieldsElement );
-        }
-
-        // Date/Time field
-        if( this.aMetaSlide.nIsDateTimeVisible )
-        {
-            this.aDateTimeFieldHandler =
-            this.initTextFieldHandler( aDateTimeClassName, aPlaceholderShapeSet,
-                                       aTextFieldContentProviderSet, aDefsElement,
-                                       aTextFieldHandlerSet, sMasterSlideId );
-        }
-
-        // Footer Field
-        if( this.aMetaSlide.nIsFooterVisible )
+        var i = 0;
+        var sId;
+        for( ; i < aBackgroundObjectSubGroupIdList.length; ++i )
         {
-            this.aFooterFieldHandler =
-            this.initTextFieldHandler( aFooterClassName, aPlaceholderShapeSet,
-                                       aTextFieldContentProviderSet, aDefsElement,
-                                       aTextFieldHandlerSet, sMasterSlideId );
-        }
+            sId = aBackgroundObjectSubGroupIdList[i];
+            if( sId === aSlideNumberClassName )
+            {
+                // Slide Number Field
+                // The cloned element is appended directly to the field group element
+                // since there is no slide number field content shared between two slide
+                // (because the slide number of two slide is always different).
+                if( aPlaceholderShapeSet[aSlideNumberClassName] &&
+                    aPlaceholderShapeSet[aSlideNumberClassName].isValid() &&
+                    this.aMetaSlide.nIsPageNumberVisible &&
+                    aTextFieldContentProviderSet[aSlideNumberClassName] )
+                {
+                    this.aSlideNumberFieldHandler =
+                    new SlideNumberFieldHandler( aPlaceholderShapeSet[aSlideNumberClassName],
+                                                 aTextFieldContentProviderSet[aSlideNumberClassName] );
+                    this.aSlideNumberFieldHandler.update( this.aMetaSlide.nSlideNumber );
+                    this.aSlideNumberFieldHandler.appendTo( this.aBackgroundObjectsElement );
+                }
+            }
+            else if( sId === aDateTimeClassName )
+            {
+                // Date/Time field
+                if( this.aMetaSlide.nIsDateTimeVisible )
+                {
+                    this.aDateTimeFieldHandler =
+                    this.initTextFieldHandler( aDateTimeClassName, aPlaceholderShapeSet,
+                                               aTextFieldContentProviderSet, aDefsElement,
+                                               aTextFieldHandlerSet, sMasterSlideId );
+                }
+            }
+            else if( sId === aFooterClassName )
+            {
+                // Footer Field
+                if( this.aMetaSlide.nIsFooterVisible )
+                {
+                    this.aFooterFieldHandler =
+                    this.initTextFieldHandler( aFooterClassName, aPlaceholderShapeSet,
+                                               aTextFieldContentProviderSet, aDefsElement,
+                                               aTextFieldHandlerSet, sMasterSlideId );
+                }
+            }
+            else if( sId === aHeaderClassName )
+            {
+                // Header Field
+                if( this.aMetaSlide.nIsHeaderVisible )
+                {
+                    this.aHeaderFieldHandler =
+                    this.initTextFieldHandler( aHeaderClassName, aPlaceholderShapeSet,
+                                               aTextFieldContentProviderSet, aDefsElement,
+                                               aTextFieldHandlerSet, sMasterSlideId );
+                }
+            }
+            else
+            {
+                // init BackgroundObjectSubGroup elements
+                var aBackgroundSubGroupElement = theDocument.createElementNS( NSS['svg'], 'use' );
+                aBackgroundSubGroupElement.setAttribute( 'class', 'BackgroundObjectSubGroup' );
+                setNSAttribute( 'xlink', aBackgroundSubGroupElement,
+                                'href', '#' + sId );
+                this.aBackgroundSubGroupElementSet.push( aBackgroundSubGroupElement );
+                // node linking
+                this.aBackgroundObjectsElement.appendChild( aBackgroundSubGroupElement );
+            }
 
-        // Header Field
-        if( this.aMetaSlide.nIsHeaderVisible )
-        {
-            this.aHeaderFieldHandler =
-            this.initTextFieldHandler( aHeaderClassName, aPlaceholderShapeSet,
-                                       aTextFieldContentProviderSet, aDefsElement,
-                                       aTextFieldHandlerSet, sMasterSlideId );
         }
-
-        // init BackgroundShapes element
-        this.aBackgroundShapesElement = theDocument.createElementNS( NSS['svg'], 'use' );
-        this.aBackgroundShapesElement.setAttribute( 'class', 'BackgroundShapes' );
-        setNSAttribute( 'xlink', this.aBackgroundShapesElement,
-                        'href', '#' + this.aMasterPage.backgroundObjectsId );
-
         // node linking
-        this.aBackgroundObjectsElement.appendChild( this.aBackgroundFieldsElement );
-        this.aBackgroundObjectsElement.appendChild( this.aBackgroundShapesElement );
         aMasterPageViewElement.appendChild( this.aBackgroundObjectsElement );
     }
 
@@ -2561,7 +2645,7 @@ function( sClassName, aPlaceholderShapeSet, aTextFieldContentProviderSet,
         setNSAttribute( 'xlink', aTextFieldElement,
                         'href', '#' + aTextFieldHandler.sId );
         // node linking
-        this.aBackgroundFieldsElement.appendChild( aTextFieldElement );
+        this.aBackgroundObjectsElement.appendChild( aTextFieldElement );
     }
     return aTextFieldHandler;
 };
commit 3bf528b4dff743b604a84ff7d02066e0d4f2a145
Author: Marco Cecchetti <mrcekets at gmail.com>
Date:   Sat Aug 25 12:01:24 2012 +0200

    Bug fix: fixed date/time fields were not exported correctly when positioned chars are used.

diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index dec1eee..a94d784 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -2323,6 +2323,24 @@ PlaceholderShape.prototype.init = function()
                 this.element = aTextFieldElement;
                 this.textElement = aPlaceholderElement;
             }
+
+            // We remove all text lines but the first one used as placeholder.
+            var aTextLineGroupElem = this.textElement.parentNode.parentNode;
+            if( aTextLineGroupElem )
+            {
+                // Just to be sure it is the element we are looking for.
+                var sFontFamilyAttr = aTextLineGroupElem.getAttribute( 'font-family' );
+                if( sFontFamilyAttr )
+                {
+                    var aChildSet = getElementChildren( aTextLineGroupElem );
+                    if( aChildSet.length > 1  )
+                    var i = 1;
+                    for( ; i < aChildSet.length; ++i )
+                    {
+                        aTextLineGroupElem.removeChild( aChildSet[i] );
+                    }
+                }
+            }
         }
     }
 };
commit 83be76cab18745ff1f8b8343a2fd53a7d13194ad
Author: Marco Cecchetti <mrcekets at gmail.com>
Date:   Sat Aug 25 11:27:56 2012 +0200

    IsUsePositionedCharacters() tries to get its value from filter data passed to SVGExport ctor
    
    Now IsUseTinyProfile and IsEmbedFonts methods are depended by
    IsUsePositionedCharacters

diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index cf76b91..f3c8350 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -352,7 +352,7 @@ sal_Bool SVGExport::IsUseTinyProfile() const
 {
     sal_Bool bRet = sal_False;
 
-    if( mrFilterData.getLength() > 0 )
+    if( IsUsePositionedCharacters() && mrFilterData.getLength() > 0 )
         mrFilterData[ 0 ].Value >>= bRet;
 
     return bRet;
@@ -364,7 +364,7 @@ sal_Bool SVGExport::IsEmbedFonts() const
 {
     sal_Bool bRet = sal_False;
 
-    if( mrFilterData.getLength() > 1 )
+    if( IsUsePositionedCharacters() && mrFilterData.getLength() > 1 )
         mrFilterData[ 1 ].Value >>= bRet;
 
     return bRet;
@@ -372,13 +372,6 @@ sal_Bool SVGExport::IsEmbedFonts() const
 
 // -----------------------------------------------------------------------------
 
-sal_Bool SVGExport::IsUsePositionedCharacters() const
-{
-    return false;
-}
-
-// -----------------------------------------------------------------------------
-
 sal_Bool SVGExport::IsUseNativeTextDecoration() const
 {
     sal_Bool bRet = !IsUseTinyProfile();
@@ -401,6 +394,18 @@ sal_Bool SVGExport::IsUseOpacity() const
     return bRet;
 }
 
+// -----------------------------------------------------------------------------
+
+sal_Bool SVGExport::IsUsePositionedCharacters() const
+{
+    sal_Bool bRet = sal_False;
+    if( mrFilterData.getLength() > 6 )
+        mrFilterData[ 6 ].Value >>= bRet;
+
+    return bRet;
+}
+
+
 // ------------------------
 // - ObjectRepresentation -
 // ------------------------
commit 8c673fa8af0ac7419b6b6d03621d91d44a87ca7a
Author: Marco Cecchetti <mrcekets at gmail.com>
Date:   Fri Aug 24 10:55:30 2012 +0200

    Now debugging code is conditionally compiled and JavaScript debug log are turned off.

diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index f05e00a..dec1eee 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -341,7 +341,7 @@ function mouseClickHelper( aEvt )
             var sSelectedText =  aTextSelection.toString();
             if( sSelectedText )
             {
-                log( 'text selection: ' + sSelectedText );
+                DBGLOG( 'text selection: ' + sSelectedText );
                 if( sLastSelectedText !== sSelectedText )
                 {
                     bTextHasBeenSelected = true;
@@ -1682,6 +1682,10 @@ DebugPrinter.prototype.print = function( sMessage, nTime )
 
 
 // - Debug Printers -
+var aGenericDebugPrinter = new DebugPrinter();
+aGenericDebugPrinter.on();
+var DBGLOG = bind2( DebugPrinter.prototype.print, aGenericDebugPrinter );
+
 var NAVDBG = new DebugPrinter();
 NAVDBG.off();
 
@@ -9749,7 +9753,7 @@ AnimatedTextElement.prototype.setToElement = function( aElement )
 
 AnimatedTextElement.prototype.notifySlideStart = function( aSlideShowContext )
 {
-    log( 'AnimatedTextElement.notifySlideStart' );
+    DBGLOG( 'AnimatedTextElement.notifySlideStart' );
     AnimatedTextElement.superclass.notifySlideStart.call( this, aSlideShowContext );
     this.aGraphicGroupElement = getElementByClassName( this.aActiveElement, 'GraphicGroup' );
     this.restoreBaseTextParagraph();
@@ -9757,7 +9761,7 @@ AnimatedTextElement.prototype.notifySlideStart = function( aSlideShowContext )
 
 AnimatedTextElement.prototype.notifySlideEnd = function()
 {
-    log( 'AnimatedTextElement.notifySlideEnd' );
+    DBGLOG( 'AnimatedTextElement.notifySlideEnd' );
     this.aGraphicGroupElement.setAttribute( 'visibility', 'inherit' );
 };
 
@@ -9795,7 +9799,7 @@ AnimatedTextElement.prototype.restoreBaseTextParagraph = function()
 
 AnimatedTextElement.prototype.notifyAnimationStart = function()
 {
-    log( 'AnimatedTextElement.notifyAnimationStart' );
+    DBGLOG( 'AnimatedTextElement.notifyAnimationStart' );
     if( this.nRunningAnimations === 0 )
     {
         var sVisibilityAttr = this.aParagraphElement.getAttribute( 'visibility' );
@@ -9810,7 +9814,7 @@ AnimatedTextElement.prototype.notifyAnimationStart = function()
 
 AnimatedTextElement.prototype.notifyAnimationEnd = function()
 {
-    log( 'AnimatedTextElement.notifyAnimationEnd' );
+    DBGLOG( 'AnimatedTextElement.notifyAnimationEnd' );
     --this.nRunningAnimations;
     if( this.nRunningAnimations === 0 )
     {
diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index 8f8d727..cf76b91 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -1749,42 +1749,6 @@ sal_Bool SVGFilter::implExportShape( const Reference< XShape >& rxShape )
                 {   // for text field shapes we set up text-adjust attributes
                     // and set visibility to hidden
                     OUString aShapeClass = implGetClassFromShape( rxShape );
-
-
-
-                    {
-//                        Reference< XPropertySetInfo > xPropSetInfo = xShapePropSet->getPropertySetInfo();
-//                        Sequence< Property > aPropSeq = xPropSetInfo->getProperties();
-//                        sal_Int32 nLength = aPropSeq.getLength();
-//                        OUString sGraphicPropList;
-//                        for( sal_Int32 i = 0; i < nLength; ++i )
-//                        {
-//                            sGraphicPropList += aPropSeq[i].Name;
-//                            sGraphicPropList += B2UCONST( ": " );
-//                            sGraphicPropList += aPropSeq[i].Type.getTypeName();
-//                            sGraphicPropList += B2UCONST( "; " );
-//                        }
-//                        mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "Graphic" ) );
-//                        mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "property-list", sGraphicPropList );
-//                        SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "desc", sal_True, sal_True );
-
-//                        if( xPropSetInfo->hasPropertyByName( B2UCONST( "GraphicURL" ) ) )
-//                        {
-//                            OUString sGraphicURL;
-//                            if( xShapePropSet->getPropertyValue( B2UCONST( "GraphicURL" ) ) >>= sGraphicURL )
-//                            {
-//                                if( !sGraphicURL.isEmpty() )
-//                                {
-//                                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "GraphicURL" ) );
-//                                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xlink:ref", sGraphicURL );
-//                                    SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "desc", sal_True, sal_True );
-//                                }
-//                            }
-//                        }
-                    }
-
-
-
                     if( mbPresentation )
                     {
                         sal_Bool bIsPageNumber  = ( aShapeClass == "Slide_Number" );
@@ -1859,7 +1823,6 @@ sal_Bool SVGFilter::implExportShape( const Reference< XShape >& rxShape )
                     if( !rShapeId.isEmpty() )
                     {
                         mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", rShapeId );
-
                     }
 
                     const GDIMetaFile* pEmbeddedBitmapsMtf = NULL;
@@ -1968,7 +1931,6 @@ sal_Bool SVGFilter::implCreateObjectsFromShapes( const Reference< XDrawPage > &
 sal_Bool SVGFilter::implCreateObjectsFromShape( const Reference< XDrawPage > & rxPage, const Reference< XShape >& rxShape )
 {
     sal_Bool bRet = sal_False;
-
     if( rxShape->getShapeType().lastIndexOf( B2UCONST( "drawing.GroupShape" ) ) != -1 )
     {
         Reference< XShapes > xShapes( rxShape, UNO_QUERY );
@@ -2075,8 +2037,8 @@ sal_Bool SVGFilter::implCreateObjectsFromShape( const Reference< XDrawPage > & r
                         }
                     }
                     (*mpObjects)[ rxShape ] = ObjectRepresentation( rxShape, aGraphic.GetGDIMetaFile() );
-                    bRet = sal_True;
                 }
+                bRet = sal_True;
             }
         }
     }
@@ -2183,7 +2145,6 @@ OUString SVGFilter::implGetInterfaceName( const Reference< XInterface >& rxIf )
 IMPL_LINK( SVGFilter, CalcFieldHdl, EditFieldInfo*, pInfo )
 {
     sal_Bool bFieldProcessed = sal_False;
-
     if( pInfo && mbPresentation )
     {
         bFieldProcessed = true;
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index d13ac78..ab7efe3 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -109,8 +109,6 @@ static sal_Char const XML_UNO_NAME_NRULE_BULLET_CHAR[] = "BulletChar";
 // -----------------------------------------------------------------------------
 
 
-
-
 // ----------------------
 // - SVGAttributeWriter -
 // ----------------------
@@ -949,6 +947,8 @@ sal_Bool SVGTextWriter::nextParagraph()
     mrCurrentTextParagraph.clear();
     mbIsNewListItem = sal_False;
     mbIsListLevelStyleImage = sal_False;
+
+#if OSL_DEBUG_LEVEL > 0
     if( mrParagraphEnumeration.is() && mrParagraphEnumeration->hasMoreElements() )
     {
         Reference < XTextContent >  xTextContent( mrParagraphEnumeration->nextElement(), UNO_QUERY_THROW );
@@ -960,21 +960,6 @@ sal_Bool SVGTextWriter::nextParagraph()
                 OUString sInfo;
                 if( xServiceInfo->supportsService( B2UCONST( "com.sun.star.text.Paragraph" ) ) )
                 {
-//                    {
-//                        Reference < XEnumeration> xContentEnum;
-//                        Reference < XContentEnumerationAccess > xCEA( xTextContent, UNO_QUERY );
-//                        if( xCEA.is() )
-//                            xContentEnum.set(xCEA->createContentEnumeration( B2UCONST( "com.sun.star.text.Paragraph" ) ));
-//                        const sal_Bool bHasContentEnum = xContentEnum.is() &&
-//                                                            xContentEnum->hasMoreElements();
-//
-//                        if( bHasContentEnum )
-//                        {
-//                            sInfo = B2UCONST( "true" );
-//                            mrExport.AddAttribute( XML_NAMESPACE_NONE, "has-content-enum", sInfo );
-//                        }
-//                    }
-
                     mrCurrentTextParagraph.set( xTextContent );
                     Reference< XPropertySet > xPropSet( xTextContent, UNO_QUERY_THROW );
                     Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
@@ -1049,7 +1034,6 @@ sal_Bool SVGTextWriter::nextParagraph()
                                                     cBullet = 0xF000 + 149;
                                                 }
                                                 mcBulletChar = cBullet;
-                                                // text:bullet-char="..."
                                                 sInfo = OUString::valueOf( (sal_Int32) cBullet );
                                                 mrExport.AddAttribute( XML_NAMESPACE_NONE, "bullet-char", sInfo );
                                             }
@@ -1072,6 +1056,7 @@ sal_Bool SVGTextWriter::nextParagraph()
                 }
                 else if( xServiceInfo->supportsService( B2UCONST( "com.sun.star.text.Table" ) ) )
                 {
+                    OSL_FAIL( "SVGTextWriter::nextParagraph: text tables are not handled." );
                     sInfo = B2UCONST( "Table" );
                 }
                 else
@@ -1097,6 +1082,126 @@ sal_Bool SVGTextWriter::nextParagraph()
             return sal_True;
         }
     }
+#else
+    if( mrParagraphEnumeration.is() && mrParagraphEnumeration->hasMoreElements() )
+    {
+        Reference < XTextContent >  xTextContent( mrParagraphEnumeration->nextElement(), UNO_QUERY_THROW );
+        if( xTextContent.is() )
+        {
+            Reference< XServiceInfo > xServiceInfo( xTextContent, UNO_QUERY_THROW );
+            if( xServiceInfo.is() )
+            {
+                if( xServiceInfo->supportsService( B2UCONST( "com.sun.star.text.Paragraph" ) ) )
+                {
+                    mrCurrentTextParagraph.set( xTextContent );
+                    Reference< XPropertySet > xPropSet( xTextContent, UNO_QUERY_THROW );
+                    Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
+                    if( xPropSetInfo->hasPropertyByName( B2UCONST( "NumberingLevel" ) ) )
+                    {
+                        sal_Int16 nListLevel = 0;
+                        if( xPropSet->getPropertyValue( B2UCONST( "NumberingLevel" ) ) >>= nListLevel )
+                        {
+                            mbIsNewListItem = sal_True;
+
+                            Reference< XIndexReplace > xNumRules;
+                            if( xPropSetInfo->hasPropertyByName( B2UCONST( "NumberingRules" ) ) )
+                            {
+                                xPropSet->getPropertyValue( B2UCONST( "NumberingRules" ) ) >>= xNumRules;
+                            }
+                            if( xNumRules.is() && ( nListLevel < xNumRules->getCount() ) )
+                            {
+                                sal_Bool bIsNumbered = sal_True;
+                                OUString msNumberingIsNumber(RTL_CONSTASCII_USTRINGPARAM("NumberingIsNumber"));
+                                if( xPropSetInfo->hasPropertyByName( msNumberingIsNumber ) )
+                                {
+                                    if( !(xPropSet->getPropertyValue( msNumberingIsNumber ) >>= bIsNumbered ) )
+                                    {
+                                        OSL_FAIL( "numbered paragraph without number info" );
+                                        bIsNumbered = sal_False;
+                                    }
+                                }
+                                mbIsNewListItem = bIsNumbered;
+
+                                if( bIsNumbered )
+                                {
+                                    Sequence<PropertyValue> aProps;
+                                    if( xNumRules->getByIndex( nListLevel ) >>= aProps )
+                                    {
+                                        sal_Int16 eType = NumberingType::CHAR_SPECIAL;
+                                        sal_Unicode cBullet = 0xf095;
+                                        const sal_Int32 nCount = aProps.getLength();
+                                        const PropertyValue* pPropArray = aProps.getConstArray();
+                                        for( sal_Int32 i = 0; i < nCount; ++i )
+                                        {
+                                            const PropertyValue& rProp = pPropArray[i];
+                                            if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_NUMBERINGTYPE, sizeof(XML_UNO_NAME_NRULE_NUMBERINGTYPE)-1 ) )
+                                            {
+                                                rProp.Value >>= eType;
+                                            }
+                                            else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_CHAR, sizeof(XML_UNO_NAME_NRULE_BULLET_CHAR)-1 ) )
+                                            {
+                                                OUString sValue;
+                                                rProp.Value >>= sValue;
+                                                if( !sValue.isEmpty() )
+                                                {
+                                                    cBullet = (sal_Unicode)sValue[0];
+                                                }
+                                            }
+                                        }
+                                        meNumberingType = eType;
+                                        mbIsListLevelStyleImage = ( NumberingType::BITMAP == meNumberingType );
+                                        if( NumberingType::CHAR_SPECIAL == meNumberingType )
+                                        {
+                                            if( cBullet )
+                                            {
+                                                if( cBullet < ' ' )
+                                                {
+                                                    cBullet = 0xF000 + 149;
+                                                }
+                                                mcBulletChar = cBullet;
+                                            }
+
+                                        }
+                                    }
+                                }
+                            }
+
+                        }
+                    }
+
+                    Reference< XEnumerationAccess > xEnumerationAccess( xTextContent, UNO_QUERY_THROW );
+                    Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
+                    if( xEnumeration.is() && xEnumeration->hasMoreElements() )
+                    {
+                        mrTextPortionEnumeration.set( xEnumeration );
+                    }
+                }
+                else if( xServiceInfo->supportsService( B2UCONST( "com.sun.star.text.Table" ) ) )
+                {
+                    OSL_FAIL( "SVGTextWriter::nextParagraph: text tables are not handled." );
+                }
+                else
+                {
+                    OSL_FAIL( "SVGTextWriter::nextParagraph: Unknown text content." );
+                    return sal_False;
+                }
+            }
+            else
+            {
+                OSL_FAIL( "SVGTextWriter::nextParagraph: no XServiceInfo interface available for text content." );
+                return sal_False;
+            }
+
+            Reference< XInterface > xRef( xTextContent, UNO_QUERY );
+            const OUString& rParagraphId = implGetValidIDFromInterface( xRef );
+            if( !rParagraphId.isEmpty() )
+            {
+                mrExport.AddAttribute( XML_NAMESPACE_NONE, "id", rParagraphId );
+            }
+            return sal_True;
+        }
+    }
+#endif
     return sal_False;
 }
 
@@ -1107,6 +1212,7 @@ sal_Bool SVGTextWriter::nextTextPortion()
     mrCurrentTextPortion.clear();
     mbIsURLField = sal_False;
     mbIsPlacehlolderShape = sal_False;
+#if OSL_DEBUG_LEVEL > 0
     if( mrTextPortionEnumeration.is() && mrTextPortionEnumeration->hasMoreElements() )
     {
         OUString sInfo;
@@ -1221,6 +1327,96 @@ sal_Bool SVGTextWriter::nextTextPortion()
             return sal_True;
         }
     }
+#else
+    if( mrTextPortionEnumeration.is() && mrTextPortionEnumeration->hasMoreElements() )
+    {
+        OUString sInfo;
+        Reference< XPropertySet > xPortionPropSet( mrTextPortionEnumeration->nextElement(), UNO_QUERY );
+        Reference< XPropertySetInfo > xPortionPropInfo( xPortionPropSet->getPropertySetInfo() );
+        Reference < XTextRange > xPortionTextRange( xPortionPropSet, UNO_QUERY);
+        if( xPortionPropSet.is() && xPortionPropInfo.is()
+                && xPortionPropInfo->hasPropertyByName( B2UCONST( "TextPortionType" ) ) )
+        {
+            if( xPortionTextRange.is() )
+            {
+                mrCurrentTextPortion.set( xPortionTextRange );
+
+                Reference < XPropertySet > xRangePropSet( xPortionTextRange, UNO_QUERY );
+                if( xRangePropSet.is() && xRangePropSet->getPropertySetInfo()->hasPropertyByName( B2UCONST( "TextField" ) ) )
+                {
+                    Reference < XTextField > xTextField( xRangePropSet->getPropertyValue( B2UCONST( "TextField" ) ), UNO_QUERY );
+                    if( xTextField.is() )
+                    {
+                        const ::rtl::OUString sServicePrefix( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.textfield.") );
+                        const ::rtl::OUString sPresentationServicePrefix( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.TextField.") );
+
+                        Reference< XServiceInfo > xService( xTextField, UNO_QUERY );
+                        const Sequence< OUString > aServices = xService->getSupportedServiceNames();
+
+                        const OUString* pNames = aServices.getConstArray();
+                        sal_Int32 nCount = aServices.getLength();
+
+                        OUString sFieldName;    // service name postfix of current field
+
+                        // search for TextField service name
+                        while( nCount-- )
+                        {
+                            if ( pNames->matchIgnoreAsciiCase( sServicePrefix ) )
+                            {
+                                // TextField found => postfix is field type!
+                                sFieldName = pNames->copy( sServicePrefix.getLength() );
+                                break;
+                            }
+                            else if( 0 == pNames->compareTo( sPresentationServicePrefix, sPresentationServicePrefix.getLength() ) )
+                            {
+                                // TextField found => postfix is field type!
+                                sFieldName = pNames->copy( sPresentationServicePrefix.getLength() );
+                                break;
+                            }
+
+                            ++pNames;
+                        }
+
+                        if( sFieldName.equalsAscii( "DateTime" ) || sFieldName.equalsAscii( "Header" )
+                                || sFieldName.equalsAscii( "Footer" ) || sFieldName.equalsAscii( "PageNumber" ) )
+                        {
+                            mbIsPlacehlolderShape = sal_True;
+                        }
+                        else
+                        {
+                            mbIsURLField = sFieldName.equalsAscii( "URL" );
+                            if( mbIsURLField )
+                            {
+                                Reference<XPropertySet> xTextFieldPropSet(xTextField, UNO_QUERY);
+                                if( xTextFieldPropSet.is() )
+                                {
+                                    OUString sURL;
+                                    if( ( xTextFieldPropSet->getPropertyValue( sFieldName ) ) >>= sURL )
+                                    {
+                                        msUrl = mrExport.GetRelativeReference( sURL );
+                                        if( !msUrl.isEmpty() )
+                                        {
+                                            implRegisterInterface( xPortionTextRange );
+
+                                            Reference< XInterface > xRef( xPortionTextRange, UNO_QUERY );
+                                            const OUString& rTextPortionId = implGetValidIDFromInterface( xRef );
+                                            if( !rTextPortionId.isEmpty() )
+                                            {
+                                                msHyperlinkIdList += rTextPortionId;
+                                                msHyperlinkIdList += B2UCONST( " " );
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            return sal_True;
+        }
+    }
+#endif
     return sal_False;
 }
 
@@ -1472,7 +1668,7 @@ void SVGTextWriter::implWriteEmbeddedBitmaps()
         const GDIMetaFile& rMtf = *mpTextEmbeddedBitmapMtf;
 
         OUString sId, sRefId;
-        sal_uLong nId, nChecksum;
+        sal_uLong nId, nChecksum = 0;
         Point aPt;
         Size  aSz;
         sal_uLong nCount = rMtf.GetActionSize();
@@ -1555,45 +1751,42 @@ void SVGTextWriter::writeTextPortion( const Point& rPos,
         bool bNotSync = true;
         OUString sContent;
         sal_Int32 nStartPos;
-//        do
-//        {
-            while( bNotSync )
+        while( bNotSync )
+        {
+            if( mnLeftTextPortionLength <= 0 )
             {
-                if( mnLeftTextPortionLength <= 0 )
-                {
-                    if( !nextTextPortion() )
-                        break;
-                    else
-                    {
-                        sContent = mrCurrentTextPortion->getString();
-                        if( mbIsURLField && sContent.isEmpty() )
-                        {
-                            Reference < XPropertySet > xPropSet( mrCurrentTextPortion, UNO_QUERY );
-                            Reference < XTextField > xTextField( xPropSet->getPropertyValue( B2UCONST( "TextField" ) ), UNO_QUERY );
-                            sContent = xTextField->getPresentation( /* show command: */ sal_False );
-                            if( sContent.isEmpty() )
-                                OSL_FAIL( "SVGTextWriter::writeTextPortion: content of URL TextField is empty." );
-                        }
-                        mnLeftTextPortionLength = sContent.getLength();
-                    }
-                }
+                if( !nextTextPortion() )
+                    break;
                 else
                 {
                     sContent = mrCurrentTextPortion->getString();
+                    if( mbIsURLField && sContent.isEmpty() )
+                    {
+                        Reference < XPropertySet > xPropSet( mrCurrentTextPortion, UNO_QUERY );
+                        Reference < XTextField > xTextField( xPropSet->getPropertyValue( B2UCONST( "TextField" ) ), UNO_QUERY );
+                        sContent = xTextField->getPresentation( /* show command: */ sal_False );
+                        if( sContent.isEmpty() )
+                            OSL_FAIL( "SVGTextWriter::writeTextPortion: content of URL TextField is empty." );
+                    }
+                    mnLeftTextPortionLength = sContent.getLength();
                 }
+            }
+            else
+            {
+                sContent = mrCurrentTextPortion->getString();
+            }
 
-                nStartPos = sContent.getLength() - mnLeftTextPortionLength;
-                if( nStartPos < 0 ) nStartPos = 0;
-                mnLeftTextPortionLength -= rText.Len();
+            nStartPos = sContent.getLength() - mnLeftTextPortionLength;
+            if( nStartPos < 0 ) nStartPos = 0;
+            mnLeftTextPortionLength -= rText.Len();
 
-                if( sContent.isEmpty() )
-                    continue;
-                if( sContent.equalsAscii( "\n" ) )
-                    mbLineBreak = sal_True;
-                if( sContent.match( rText, nStartPos ) )
-                    bNotSync = false;
-            }
-//        } while( bNotSync && nextParagraph() );
+            if( sContent.isEmpty() )
+                continue;
+            if( sContent.equalsAscii( "\n" ) )
+                mbLineBreak = sal_True;
+            if( sContent.match( rText, nStartPos ) )
+                bNotSync = false;
+        }
     }
 
     if( !mpVDev )
@@ -1607,82 +1800,10 @@ void SVGTextWriter::writeTextPortion( const Point& rPos,
     {
         implWriteTextPortion( rPos, rText, mpVDev->GetTextColor(), bApplyMapping );
     }
-//    else
-//    {
-//        if( aMetric.GetRelief() != RELIEF_NONE )
-//        {
-//            Color aReliefColor( COL_LIGHTGRAY );
-//            Color aTextColor( mpVDev->GetTextColor() );
-//
-//            if ( aTextColor.GetColor() == COL_BLACK )
-//                aTextColor = Color( COL_WHITE );
-//
-//            if ( aTextColor.GetColor() == COL_WHITE )
-//                aReliefColor = Color( COL_BLACK );
-//
-//
-//            Point aPos( rPos );
-//            Point aOffset( 6, 6 );
-//
-//            if ( aMetric.GetRelief() == RELIEF_ENGRAVED )
-//            {
-//                aPos -= aOffset;
-//            }
-//            else
-//            {
-//                aPos += aOffset;
-//            }
-//
-//            ImplWriteText( aPos, rText, pDXArray, nWidth, aReliefColor, bApplyMapping );
-//            ImplWriteText( rPos, rText, pDXArray, nWidth, aTextColor, bApplyMapping );
-//        }
-//        else
-//        {
-//            if( aMetric.IsShadow() )
-//            {
-//                long nOff = 1 + ((aMetric.GetLineHeight()-24)/24);
-//                if ( aMetric.IsOutline() )
-//                    nOff += 6;
-//
-//                Color aTextColor( mpVDev->GetTextColor() );
-//                Color aShadowColor = Color( COL_BLACK );
-//
-//                if ( (aTextColor.GetColor() == COL_BLACK) || (aTextColor.GetLuminance() < 8) )
-//                    aShadowColor = Color( COL_LIGHTGRAY );
-//
-//                Point aPos( rPos );
-//                aPos += Point( nOff, nOff );
-//                ImplWriteText( aPos, rText, pDXArray, nWidth, aShadowColor, bApplyMapping );
-//
-//                if( !aMetric.IsOutline() )
-//                {
-//                    ImplWriteText( rPos, rText, pDXArray, nWidth, aTextColor, bApplyMapping );
-//                }
-//            }
-//
-//            if( aMetric.IsOutline() )
-//            {
-//                Point aPos = rPos + Point( -6, -6 );
-//                ImplWriteText( aPos, rText, pDXArray, nWidth, mpVDev->GetTextColor(), bApplyMapping );
-//                aPos = rPos + Point( +6, +6);
-//                ImplWriteText( aPos, rText, pDXArray, nWidth, mpVDev->GetTextColor(), bApplyMapping );
-//                aPos = rPos + Point( -6, +0);
-//                ImplWriteText( aPos, rText, pDXArray, nWidth, mpVDev->GetTextColor(), bApplyMapping );
-//                aPos = rPos + Point( -6, +6);
-//                ImplWriteText( aPos, rText, pDXArray, nWidth, mpVDev->GetTextColor(), bApplyMapping );
-//                aPos = rPos + Point( +0, +6);
-//                ImplWriteText( aPos, rText, pDXArray, nWidth, mpVDev->GetTextColor(), bApplyMapping );
-//                aPos = rPos + Point( +0, -6);
-//                ImplWriteText( aPos, rText, pDXArray, nWidth, mpVDev->GetTextColor(), bApplyMapping );
-//                aPos = rPos + Point( +6, -1);
-//                ImplWriteText( aPos, rText, pDXArray, nWidth, mpVDev->GetTextColor(), bApplyMapping );
-//                aPos = rPos + Point( +6, +0);
-//                ImplWriteText( aPos, rText, pDXArray, nWidth, mpVDev->GetTextColor(), bApplyMapping );
-//
-//                ImplWriteText( rPos, rText, pDXArray, nWidth, Color( COL_WHITE ), bApplyMapping );
-//            }
-//        }
-//    }
+    else
+    {
+        // to be implemented
+    }
 
 }
 
@@ -2784,13 +2905,14 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
         nWriteFlags |= SVGWRITER_NO_SHAPE_COMMENTS;
 
 
+#if OSL_DEBUG_LEVEL > 0
     bool bIsTextShape = false;
     if( !mrExport.IsUsePositionedCharacters() && pxShape
             && Reference< XText >( *pxShape, UNO_QUERY ).is() )
     {
         bIsTextShape = true;
     }
-
+#endif
     mbIsPlacehlolderShape = false;
     if( ( pElementId != NULL ) && ( *pElementId == sPlaceholderTag ) )
     {
@@ -2804,6 +2926,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
         const MetaAction*   pAction = rMtf.GetAction( nCurAction );
         const sal_uInt16        nType = pAction->GetType();
 
+#if OSL_DEBUG_LEVEL > 0
         if( bIsTextShape )
         {
             try
@@ -2848,7 +2971,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
             }
 
         }
-
+#endif
         switch( nType )
         {
             case( META_PIXEL_ACTION ):
commit f77bd4a7c83e8d84655f4e3a4f3c6c44a735053e
Author: Marco Cecchetti <mrcekets at gmail.com>
Date:   Mon Aug 20 20:22:09 2012 +0200

    some improvement in making text animation compatible with text selection

diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index 5fc68f6..f05e00a 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -2130,11 +2130,7 @@ initHyperlinks : function()
                     {
                         var sId = aHyperlinkIdSet[j];
                         //log( 'initHyperlinks: j=' + j + ' id: <' + sId + '>' );
-                        var aHyperlinkElem = document.getElementById( sId );
-                        if( aHyperlinkElem )
-                        {
-                            aHyperlinkSet[ sId ] = new HyperlinkElement( sId, aHyperlinkElem, this.aSlideAnimationsHandler.aEventMultiplexer );
-                        }
+                        aHyperlinkSet[ sId ] = new HyperlinkElement( sId, this.aSlideAnimationsHandler.aEventMultiplexer );
                     }
                 }
             }
@@ -8990,6 +8986,8 @@ function AnimatedElement( aElement )
         log( 'AnimatedElement constructor: element is not valid' );
     }
 
+    this.aSlideShowContext = null;
+
     this.aBaseElement = aElement.cloneNode( true );
     this.aActiveElement = aElement;
     this.sElementId = this.aActiveElement.getAttribute( 'id' );
@@ -9109,8 +9107,14 @@ AnimatedElement.prototype.setToElement = function( aElement )
     return true;
 };
 
-AnimatedElement.prototype.notifySlideStart = function()
+AnimatedElement.prototype.notifySlideStart = function( aSlideShowContext )
 {
+    if( !aSlideShowContext )
+    {
+        log( 'AnimatedElement.notifySlideStart: slideshow context is not valid' );
+    }
+    this.aSlideShowContext = aSlideShowContext;
+
     var aClone = this.aBaseElement.cloneNode( true );
     this.aActiveElement.parentNode.replaceChild( aClone, this.aActiveElement );
     this.aActiveElement = aClone;
@@ -9119,6 +9123,11 @@ AnimatedElement.prototype.notifySlideStart = function()
     this.DBG( '.notifySlideStart invoked' );
 };
 
+AnimatedElement.prototype.notifySlideEnd = function()
+{
+    // empty body
+};
+
 AnimatedElement.prototype.notifyAnimationStart = function()
 {
     // empty body
@@ -9544,7 +9553,7 @@ AnimatedElement.prototype.DBG = function( sMessage, nTime )
 };
 
 // ------------------------------------------------------------------------------------------ //
-function AnimatedTextElement( aElement )
+function AnimatedTextElement( aElement, aEventMultiplexer )
 {
     var theDocument = document;
 
@@ -9579,6 +9588,11 @@ function AnimatedTextElement( aElement )
     // Clone paragraph element <tspan>
     var aParagraphElement = aElement.cloneNode( true );
 
+    // We create a group element for wrapping bullets, bitmaps
+    // and text decoration
+    this.aGraphicGroupElement = theDocument.createElementNS( NSS['svg'], 'g' );
+    this.aGraphicGroupElement.setAttribute( 'class', 'GraphicGroup' );
+
     // In case we are dealing with a list item that utilizes a bullet char
     // we need to clone the related bullet char too.
     var aBulletCharClone = null;
@@ -9643,7 +9657,8 @@ function AnimatedTextElement( aElement )
 
     // Change clone element id.
     this.sParagraphId = sId = aParagraphElement.getAttribute( 'id' );
-    aParagraphElement.setAttribute( 'id', sId +'.a' );
+    aParagraphElement.removeAttribute( 'id' );
+    aAnimatableElement.setAttribute( 'id', sId +'.a' );
     if( aBulletCharClone )
         aBulletCharClone.removeAttribute( 'id' );
     for( i = 0; i < aBitmapCloneSet.length; ++i )
@@ -9652,56 +9667,48 @@ function AnimatedTextElement( aElement )
             aBitmapCloneSet[i].removeAttribute( 'id' );
     }
 
-    // Hide original text paragraph.
+    // Set up visibility
     var sVisibilityAttr = aElement.getAttribute( 'visibility' );
-    if( sVisibilityAttr === 'hidden' )
-    {
-        aAnimatableElement.setAttribute( 'visibility', 'hidden' );
-        this.eInitialVisibility = HIDDEN;
-    }
-    else
-    {
-        aElement.setAttribute( 'visibility', 'hidden' );
-        this.eInitialVisibility = VISIBLE;
-    }
+    if( !sVisibilityAttr )
+        sVisibilityAttr = 'inherit';
+    aAnimatableElement.setAttribute( 'visibility', sVisibilityAttr );
     aParagraphElement.setAttribute( 'visibility', 'inherit' );
-    if( aBulletCharClone )
-        aBulletCharClone.setAttribute( 'visibility', 'inherit' );
+    this.aGraphicGroupElement.setAttribute( 'visibility', 'inherit' );
     if( aBulletCharElem )
         aBulletCharElem.setAttribute( 'visibility', 'hidden' );
-
     for( i = 0; i < aBitmapCloneSet.length; ++i )
     {
         if( aBitmapElemSet[i] )
             aBitmapElemSet[i].setAttribute( 'visibility', 'hidden' );
-        if( aBitmapCloneSet[i] )
-            aBitmapCloneSet[i].setAttribute( 'visibility', 'inherit' );
     }
 
-
     // Append each element to its parent.
     // <g class='AnimatedElements'>
     //   <g>
     //     <text>
     //       <tspan class='TextParagraph'> ... </tspan>
     //     </text>
-    //     [<g class='BulletChar'>...</g>]
-    //     [<g class='EmbeddedBitmap'>...</g>]
-    //     .
-    //     .
-    //     [<g class='EmbeddedBitmap'>...</g>]
+    //     <g class='GraphicGroup'>
+    //       [<g class='BulletChar'>...</g>]
+    //       [<g class='EmbeddedBitmap'>...</g>]
+    //       .
+    //       .
+    //       [<g class='EmbeddedBitmap'>...</g>]
+    //     </g>
     //   </g>
     // </g>
 
     aTextElement.appendChild( aParagraphElement );
     aAnimatableElement.appendChild( aTextElement );
+
     if( aBulletCharClone )
-        aAnimatableElement.appendChild( aBulletCharClone );
+        this.aGraphicGroupElement.appendChild( aBulletCharClone );
     for( i = 0; i < aBitmapCloneSet.length; ++i )
     {
         if( aBitmapCloneSet[i] )
-            aAnimatableElement.appendChild( aBitmapCloneSet[i] );
+            this.aGraphicGroupElement.appendChild( aBitmapCloneSet[i] );
     }
+    aAnimatableElement.appendChild( this.aGraphicGroupElement );
     aAnimatedElementGroup.appendChild( aAnimatableElement );
 
     this.aParentTextElement = aElement.parentNode;
@@ -9709,32 +9716,81 @@ function AnimatedTextElement( aElement )
     this.aAnimatedElementGroup = aAnimatedElementGroup;
     this.nRunningAnimations = 0;
 
-    AnimatedTextElement.superclass.constructor.call( this, aAnimatableElement );
+    // we collect all hyperlink ids
+    this.aHyperlinkIdSet = new Array();
+    var aHyperlinkElementSet = getElementsByClassName( this.aParagraphElement, 'UrlField' );
+    var i = 0;
+    var sHyperlinkId;
+    for( ; i < aHyperlinkElementSet.length; ++i )
+    {
+        sHyperlinkId = aHyperlinkElementSet[i].getAttribute( 'id' );
+        if( sHyperlinkId )
+           this.aHyperlinkIdSet.push( sHyperlinkId );
+        else
+            log( 'error: AnimatedTextElement constructor: hyperlink element has no id' );
+    }
+
+
+    AnimatedTextElement.superclass.constructor.call( this, aAnimatableElement, aEventMultiplexer );
 
 }
 extend( AnimatedTextElement, AnimatedElement );
 
-/*
-AnimatedTextElement.prototype.notifySlideStart = function()
-{
-    var aClone = this.aBaseElement.cloneNode( true );
-    this.aActiveElement.parentNode.replaceChild( aClone, this.aActiveElement );
-    this.aActiveElement = aClone;
 
-    var aAnimatedParagraphElement = this.aActiveElement.firstElementChild.firstElementChild;
-    if( aAnimatedParagraphElement )
+AnimatedTextElement.prototype.setToElement = function( aElement )
+{
+    var bRet = AnimatedTextElement.superclass.setToElement.call( this, aElement );
+    if( bRet )
     {
-        var aParagraphElement = aAnimatedParagraphElement.cloneNode( true );
-        aParagraphElement.setAttribute( 'id', this.sParagraphId );
-        aParagraphElement.setAttribute( 'visibility', aVisibilityAttributeValue[ this.eInitialVisibility  ] );
-        this.aParentTextElement.replaceChild( aParagraphElement, this.aParagraphElement  );
-        this.aParagraphElement = aParagraphElement;
+        this.aGraphicGroupElement = getElementByClassName( this.aActiveElement, 'GraphicGroup' );
     }
-    this.aActiveElement.setAttribute( 'visibility', 'hidden' );
+    return ( bRet && this.aGraphicGroupElement );
+};
 
+AnimatedTextElement.prototype.notifySlideStart = function( aSlideShowContext )
+{
+    log( 'AnimatedTextElement.notifySlideStart' );
+    AnimatedTextElement.superclass.notifySlideStart.call( this, aSlideShowContext );
+    this.aGraphicGroupElement = getElementByClassName( this.aActiveElement, 'GraphicGroup' );
+    this.restoreBaseTextParagraph();
+};
 
-    this.initElement();
-    this.DBG( '.notifySlideStart invoked' );
+AnimatedTextElement.prototype.notifySlideEnd = function()
+{
+    log( 'AnimatedTextElement.notifySlideEnd' );
+    this.aGraphicGroupElement.setAttribute( 'visibility', 'inherit' );
+};
+
+AnimatedTextElement.prototype.restoreBaseTextParagraph = function()
+{
+    var aActiveParagraphElement = this.aActiveElement.firstElementChild.firstElementChild;
+    if( aActiveParagraphElement )
+    {
+        var sVisibilityAttr = this.aActiveElement.getAttribute( 'visibility' );
+        if( !sVisibilityAttr || ( sVisibilityAttr === 'visible' ) )
+            sVisibilityAttr = 'inherit';
+        if( sVisibilityAttr === 'inherit' )
+            this.aGraphicGroupElement.setAttribute( 'visibility', 'visible' );
+        else
+            this.aGraphicGroupElement.setAttribute( 'visibility', 'hidden' );
+
+        var aParagraphClone = aActiveParagraphElement.cloneNode( true );
+        aParagraphClone.setAttribute( 'id', this.sParagraphId );
+        aParagraphClone.setAttribute( 'visibility', sVisibilityAttr );
+        this.aParentTextElement.replaceChild( aParagraphClone, this.aParagraphElement );
+        this.aParagraphElement = aParagraphClone;
+
+
+        var aEventMultiplexer = this.aSlideShowContext.aEventMultiplexer;
+        var aHyperlinkIdSet = this.aHyperlinkIdSet;
+        var aHyperlinkElementSet = getElementsByClassName( this.aParagraphElement, 'UrlField' );
+        var i = 0;
+        for( ; i < aHyperlinkIdSet.length; ++i )
+        {
+            aEventMultiplexer.notifyElementChangedEvent( aHyperlinkIdSet[i], aHyperlinkElementSet[i] );
+        }
+    }
+    this.aActiveElement.setAttribute( 'visibility', 'hidden' );
 };
 
 AnimatedTextElement.prototype.notifyAnimationStart = function()
@@ -9742,8 +9798,12 @@ AnimatedTextElement.prototype.notifyAnimationStart = function()
     log( 'AnimatedTextElement.notifyAnimationStart' );
     if( this.nRunningAnimations === 0 )
     {
+        var sVisibilityAttr = this.aParagraphElement.getAttribute( 'visibility' );
+        if( !sVisibilityAttr )
+            sVisibilityAttr = 'inherit';
+        this.aActiveElement.setAttribute( 'visibility', sVisibilityAttr );
+        this.aGraphicGroupElement.setAttribute( 'visibility', 'inherit' );
         this.aParagraphElement.setAttribute( 'visibility', 'hidden' );
-        this.aActiveElement.setAttribute( 'visibility', aVisibilityAttributeValue[ this.eInitialVisibility  ] );
     }
     ++this.nRunningAnimations;
 };
@@ -9754,20 +9814,29 @@ AnimatedTextElement.prototype.notifyAnimationEnd = function()
     --this.nRunningAnimations;
     if( this.nRunningAnimations === 0 )
     {
-        var sVisibilityAttr = this.aActiveElement.getAttribute( 'visibility' );
-        var aAnimatedParagraphElement = this.aActiveElement.firstElementChild.firstElementChild;
-        if( aAnimatedParagraphElement )
-        {
-            var aParagraphElement = aAnimatedParagraphElement.cloneNode( true );
-            aParagraphElement.setAttribute( 'visibility', sVisibilityAttr );
-            aParagraphElement.setAttribute( 'id', this.sParagraphId );
-            this.aParentTextElement.replaceChild( aParagraphElement, this.aParagraphElement  );
-            this.aParagraphElement = aParagraphElement;
-        }
-        this.aActiveElement.setAttribute( 'visibility', 'hidden' );
+        this.restoreBaseTextParagraph();
     }
 };
-*/
+
+AnimatedTextElement.prototype.saveState = function( nAnimationNodeId )
+{
+    if( this.nRunningAnimations === 0 )
+    {
+        var sVisibilityAttr = this.aParagraphElement.getAttribute( 'visibility' );
+        this.aActiveElement.setAttribute( 'visibility', sVisibilityAttr );
+        this.aGraphicGroupElement.setAttribute( 'visibility', 'inherit' );
+    }
+    AnimatedTextElement.superclass.saveState.call( this, nAnimationNodeId );
+};
+
+AnimatedTextElement.prototype.restoreState = function( nAnimationNodeId )
+{
+    var bRet = AnimatedTextElement.superclass.restoreState.call( this, nAnimationNodeId );
+    if( bRet )
+        this.restoreBaseTextParagraph();
+    return bRet;
+};
+
 
 
 // ------------------------------------------------------------------------------------------ //
@@ -10492,17 +10561,17 @@ SourceEventElement.prototype.setDefaultCursor = function()
 
 // ------------------------------------------------------------------------------------------ //
 
-function HyperlinkElement( sId, aElement, aEventMultiplexer )
+function HyperlinkElement( sId, aEventMultiplexer )
 {
+    var aElement = document.getElementById( sId );
     if( !aElement )
     {
-        log( 'error: HyperlinkElement: passed element is not valid' );
+        log( 'error: HyperlinkElement: no element with id: <' + sId + '> found' );
         return;
     }
     if( !aEventMultiplexer )
     {
-        log( 'error: HyperlinkElement: passed event multiplexer is not valid' );
-        return;
+        log( 'AnimatedElement constructor: event multiplexer is not valid' );
     }
 
     this.sId = sId;
@@ -10522,11 +10591,14 @@ function HyperlinkElement( sId, aElement, aEventMultiplexer )
             }
         }
 
+        this.aEventMultiplexer.registerElementChangedHandler( this.sId, bind2( HyperlinkElement.prototype.onElementChanged, this) );
         this.aEventMultiplexer.registerMouseClickHandler( this, 1100 );
 
         this.bIsPointerOver = false;
-        this.aElement.addEventListener( 'mouseover', bind2( HyperlinkElement.prototype.onMouseEnter, this), false );
-        this.aElement.addEventListener( 'mouseout', bind2( HyperlinkElement.prototype.onMouseLeave, this), false );
+        this.mouseEnterHandler = bind2( HyperlinkElement.prototype.onMouseEnter, this);
+        this.mouseLeaveHandler = bind2( HyperlinkElement.prototype.onMouseLeave, this);
+        this.aElement.addEventListener( 'mouseover', this.mouseEnterHandler, false );
+        this.aElement.addEventListener( 'mouseout', this.mouseLeaveHandler, false );
     }
     else
     {
@@ -10534,6 +10606,25 @@ function HyperlinkElement( sId, aElement, aEventMultiplexer )
     }
 }
 
+HyperlinkElement.prototype.onElementChanged = function( aElement )
+{
+    //var aElement = document.getElementById( this.sId );
+    if( !aElement )
+    {
+        log( 'error: HyperlinkElement: passed element is not valid' );
+        return;
+    }
+
+    if( this.sURL )
+    {
+        this.aElement.removeEventListener( 'mouseover', this.mouseEnterHandler, false );
+        this.aElement.removeEventListener( 'mouseout', this.mouseLeaveHandler, false );
+        this.aElement = aElement;
+        this.aElement.addEventListener( 'mouseover', this.mouseEnterHandler, false );
+        this.aElement.addEventListener( 'mouseout', this.mouseLeaveHandler, false );
+    }
+};
+
 HyperlinkElement.prototype.onMouseEnter = function()
 {
     this.bIsPointerOver = true;
@@ -10693,6 +10784,7 @@ function EventMultiplexer( aTimerEventQueue )
     this.aRewindRunningInteractiveEffectEventSet = new Object();
     this.aRewindEndedInteractiveEffectEventSet = new Object();
     this.aRewindedEffectHandlerSet = new Object();
+    this.aElementChangedHandlerSet = new Object();
 }
 
 EventMultiplexer.CURR_UNIQUE_ID = 0;
@@ -10873,6 +10965,18 @@ EventMultiplexer.prototype.notifyRewindedEffectEvent = function( aNotifierId )
     }
 };
 
+EventMultiplexer.prototype.registerElementChangedHandler = function( aNotifierId, aHandler )
+{
+    this.aElementChangedHandlerSet[ aNotifierId ] = aHandler;
+}
+
+EventMultiplexer.prototype.notifyElementChangedEvent = function( aNotifierId, aElement )
+{
+    if( this.aElementChangedHandlerSet[ aNotifierId ] )
+    {
+        (this.aElementChangedHandlerSet[ aNotifierId ])( aElement );
+    }
+};
 
 EventMultiplexer.DEBUG = aEventMultiplexerDebugPrinter.isEnabled();
 
@@ -12513,7 +12617,7 @@ SlideShow.prototype.notifyNextEffectEnd = function()
     this.aStartedEffectList[ this.aStartedEffectIndexMap[ -1 ] ].end();
 };
 
-SlideShow.prototype.notifySlideStart = function( nSlideIndex )
+SlideShow.prototype.notifySlideStart = function( nNewSlideIndex, nOldSlideIndex )
 {
     this.nCurrentEffect = 0;
     this.bIsRewinding = false;
@@ -12524,10 +12628,18 @@ SlideShow.prototype.notifySlideStart = function( nSlideIndex )
     this.aStartedEffectIndexMap = new Object();
     this.aStartedEffectIndexMap[ -1 ] = undefined;
 
+    var aAnimatedElementMap;
+    var sId;
+    if( nOldSlideIndex !== undefined )
+    {
+        aAnimatedElementMap = theMetaDoc.aMetaSlideSet[nOldSlideIndex].aSlideAnimationsHandler.aAnimatedElementMap;
+        for( sId in aAnimatedElementMap )
+            aAnimatedElementMap[ sId ].notifySlideEnd();
+    }
 
-    var aAnimatedElementMap = theMetaDoc.aMetaSlideSet[nSlideIndex].aSlideAnimationsHandler.aAnimatedElementMap;
-    for( var sId in aAnimatedElementMap )
-        aAnimatedElementMap[ sId ].notifySlideStart();
+    aAnimatedElementMap = theMetaDoc.aMetaSlideSet[nNewSlideIndex].aSlideAnimationsHandler.aAnimatedElementMap;
+    for( sId in aAnimatedElementMap )
+        aAnimatedElementMap[ sId ].notifySlideStart( this.aContext );
 };
 
 SlideShow.prototype.notifyTransitionEnd = function( nSlideIndex )
@@ -12878,7 +12990,7 @@ SlideShow.prototype.displaySlide = function( nNewSlide, bSkipSlideTransition )
         }
     }
 
-    this.notifySlideStart( nNewSlide );
+    this.notifySlideStart( nNewSlide, nOldSlide );
 
     if( this.isEnabled() && !bSkipSlideTransition  )
     {
diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index 38cad60..8f8d727 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -1749,6 +1749,42 @@ sal_Bool SVGFilter::implExportShape( const Reference< XShape >& rxShape )
                 {   // for text field shapes we set up text-adjust attributes
                     // and set visibility to hidden
                     OUString aShapeClass = implGetClassFromShape( rxShape );
+
+
+
+                    {
+//                        Reference< XPropertySetInfo > xPropSetInfo = xShapePropSet->getPropertySetInfo();
+//                        Sequence< Property > aPropSeq = xPropSetInfo->getProperties();
+//                        sal_Int32 nLength = aPropSeq.getLength();
+//                        OUString sGraphicPropList;
+//                        for( sal_Int32 i = 0; i < nLength; ++i )
+//                        {
+//                            sGraphicPropList += aPropSeq[i].Name;
+//                            sGraphicPropList += B2UCONST( ": " );
+//                            sGraphicPropList += aPropSeq[i].Type.getTypeName();
+//                            sGraphicPropList += B2UCONST( "; " );
+//                        }
+//                        mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "Graphic" ) );
+//                        mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "property-list", sGraphicPropList );
+//                        SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "desc", sal_True, sal_True );
+
+//                        if( xPropSetInfo->hasPropertyByName( B2UCONST( "GraphicURL" ) ) )
+//                        {
+//                            OUString sGraphicURL;
+//                            if( xShapePropSet->getPropertyValue( B2UCONST( "GraphicURL" ) ) >>= sGraphicURL )
+//                            {
+//                                if( !sGraphicURL.isEmpty() )
+//                                {
+//                                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "GraphicURL" ) );
+//                                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xlink:ref", sGraphicURL );
+//                                    SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "desc", sal_True, sal_True );
+//                                }
+//                            }
+//                        }
+                    }
+
+
+
                     if( mbPresentation )
                     {
                         sal_Bool bIsPageNumber  = ( aShapeClass == "Slide_Number" );
diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx
index 3ef33a6..c5567df 100644
--- a/filter/source/svg/svgfilter.hxx
+++ b/filter/source/svg/svgfilter.hxx
@@ -20,6 +20,7 @@
 #ifndef SVGFILTER_HXX
 #define SVGFILTER_HXX
 
+#include <com/sun/star/uno/Type.hxx>
 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index 2575bfe..d13ac78 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -1171,6 +1171,10 @@ sal_Bool SVGTextWriter::nextTextPortion()
                         sInfo += sFieldName;
                         sInfo += B2UCONST( "; " );
 
+                        sInfo += B2UCONST( "content: " );
+                        sInfo += xTextField->getPresentation( /* show command: */ sal_False );
+                        sInfo += B2UCONST( "; " );
+
                         if( sFieldName.equalsAscii( "DateTime" ) || sFieldName.equalsAscii( "Header" )
                                 || sFieldName.equalsAscii( "Footer" ) || sFieldName.equalsAscii( "PageNumber" ) )
                         {
@@ -1562,6 +1566,14 @@ void SVGTextWriter::writeTextPortion( const Point& rPos,
                     else
                     {
                         sContent = mrCurrentTextPortion->getString();
+                        if( mbIsURLField && sContent.isEmpty() )
+                        {
+                            Reference < XPropertySet > xPropSet( mrCurrentTextPortion, UNO_QUERY );
+                            Reference < XTextField > xTextField( xPropSet->getPropertyValue( B2UCONST( "TextField" ) ), UNO_QUERY );
+                            sContent = xTextField->getPresentation( /* show command: */ sal_False );
+                            if( sContent.isEmpty() )
+                                OSL_FAIL( "SVGTextWriter::writeTextPortion: content of URL TextField is empty." );
+                        }
                         mnLeftTextPortionLength = sContent.getLength();
                     }
                 }
@@ -1769,6 +1781,7 @@ void SVGTextWriter::implWriteTextPortion( const Point& rPos,
     }
     else if( mbIsURLField && !msUrl.isEmpty() )
     {
+        mrExport.AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "UrlField" ) );
         mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrXLinkHRef, msUrl );
         mbIsURLField = sal_False;
     }
commit df9a436a85fa281cd53d46fdb832965d36aa9135
Author: Marco Cecchetti <mrcekets at gmail.com>
Date:   Sat Aug 18 19:25:17 2012 +0200

    Handled META_BMPSCALE_ACTION, supported hyperlinks, text selection support.
    
    The implCreateObjectFromShape method of the SVGFilter class has been modified in order
    to handling bitmap meta actions of type META_BMPSCALE_ACTION for each bitmap
    embedded into a text shape.
    
    The implCreateObjectFromShape method of the SVGFilter class has been modified in order
    to avoid to generate an id for empty text shapes.
    
    The MetaSlide class has two new methods for collecting text shapes from the text shape
    exported index and hyperlinks. A new HyperlinkElement class has been designed for
    handling text portion with an attached URL. The routine handling mouse click has been
    modified in order to interacting with the EventMultiplexer instance belonging to the current
    slide even when no animations are exported. All that let us supporting both web links and
    local links to slide belonging to the current document.
    
    The routine handling mouse click has been modified in order to avoid to start the next effect
    or switch to the next slide when there is a text fragment selected.
    
    Now when the user selects text or performs a right click in order to copy the selected text no
    further action is executed by the presentation engine. When the left mouse button is clicked
    the previous selection is discarded but still no further action is performed by the presentation
    engine.
    
    The implCreateObjectFromShape method of the SVGFilter class has been modified in order
    to avoid of adding to the group of embedded bitmaps those bitmap belonging to XShape
    object convertible to XText but that does not contain any text shape meta comment action.
    Now a meta bitmap action is handled by the SVGTextWriter class only if the action is between
    a meta comment action of type XTEXT_PAINTSHAPE_BEGIN and a meta comment action of
    type XTEXT_PAINTSHAPE_END.
    
    The writeBitmapPlaceholder and implWriteEmbeddedBitmaps methods of the SVGTextWriter
    class have been modified in order to change the way the id of the <use> elements that
    reference a bitmap is created. That has been needed because when two <use> element
    referencing the same bitmap and embedded into two different text shapes but placed at the
    same position (e.g. for instance when they belong to different slide)  they got the same id.
    Now the id is built by prepending the meta bitmap action checksum with the text shape id
    followed by a dot.

diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index 27075cd..5fc68f6 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -316,6 +316,72 @@ function mouseHandlerDispatch( aEvt, anAction )
 document.onmouseup = function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_UP ); };
 //document.onmousemove = function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_MOVE ); };
 
+
+/** mouseClickHelper
+ *
+ * @return {Object}
+ *   a mouse click handler
+ */
+function mouseClickHelper( aEvt )
+{
+    // In case text is selected we stay on the current slide.
+    // Anyway if we are dealing with Firefox there is an issue:
+    // Firefox supports a naive way of selecting svg text, if you click
+    // on text the current selection is set to the whole text fragment
+    // wrapped by the related <tspan> element.
+    // That means until you click on text you never move to the next slide.
+    // In order to avoid this case we do not test the status of current
+    // selection, when the presentation is running on a mozilla browser.
+    if( !Detect.isMozilla )
+    {
+        var aWindowObject = document.defaultView;
+        if( aWindowObject )
+        {
+            var aTextSelection = aWindowObject.getSelection();
+            var sSelectedText =  aTextSelection.toString();
+            if( sSelectedText )
+            {
+                log( 'text selection: ' + sSelectedText );
+                if( sLastSelectedText !== sSelectedText )
+                {
+                    bTextHasBeenSelected = true;
+                    sLastSelectedText = sSelectedText;
+                }
+                else
+                {
+                    bTextHasBeenSelected = false;
+                }
+                return null;
+            }
+            else if( bTextHasBeenSelected )
+            {
+                bTextHasBeenSelected = false;
+                sLastSelectedText = '';
+                return null;
+            }
+        }
+        else
+        {
+            log( 'error: HyperlinkElement.handleClick: invalid window object.' );
+        }
+    }
+
+    var aSlideAnimationsHandler = theMetaDoc.aMetaSlideSet[nCurSlide].aSlideAnimationsHandler;
+    if( aSlideAnimationsHandler )
+    {
+        var aCurrentEventMultiplexer = aSlideAnimationsHandler.aEventMultiplexer;
+        if( aCurrentEventMultiplexer )
+        {
+            if( aCurrentEventMultiplexer.hasRegisteredMouseClickHandlers() )
+            {
+                return aCurrentEventMultiplexer.notifyMouseClick( aEvt );
+            }
+        }
+    }
+    return slideOnMouseUp( aEvt );
+}
+
+
 /** Function to supply the default mouse handler dictionary.
  *
  *  @returns default mouse handler dictionary
@@ -329,10 +395,11 @@ function getDefaultMouseHandlerDictionary()
 
     // slide mode
     mouseHandlerDict[SLIDE_MODE][MOUSE_UP]
+        = mouseClickHelper;
         //= function( aEvt ) { return slideOnMouseDown( aEvt ); };
-        = function( aEvt ) { return ( aSlideShow.aEventMultiplexer ) ?
-                                        aSlideShow.aEventMultiplexer.notifyMouseClick( aEvt )
-                                        : slideOnMouseUp( aEvt ); };
+//        = function( aEvt ) { return ( aSlideShow.aEventMultiplexer ) ?
+//                                        aSlideShow.aEventMultiplexer.notifyMouseClick( aEvt )
+//                                        : slideOnMouseUp( aEvt ); };
 
     mouseHandlerDict[SLIDE_MODE][MOUSE_WHEEL]
         = function( aEvt ) { return slideOnMouseWheel( aEvt ); };
@@ -615,6 +682,152 @@ PathTools.arcAsBezier = function( last, rx, ry, xRotg, large, sweep, x, y )
 };
 
 
+function has( name )
+{
+    return has.cache[name];
+}
+
+has.cache = {};
+
+has.add = function( name, test )
+{
+    has.cache[name] = test;
+};
+
+function configureDetectionTools()
+{
+    if( !navigator )
+    {
+        log( 'error: configureDetectionTools: configuration failed' );
+        return null;
+    }
+
+    var n = navigator,
+    dua = n.userAgent,
+    dav = n.appVersion,
+    tv = parseFloat(dav);
+
+    has.add('air', dua.indexOf('AdobeAIR') >= 0),
+    has.add('khtml', dav.indexOf('Konqueror') >= 0 ? tv : undefined);
+    has.add('webkit', parseFloat(dua.split('WebKit/')[1]) || undefined);
+    has.add('chrome', parseFloat(dua.split('Chrome/')[1]) || undefined);

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list