diff options
author | Marco Cecchetti <mrcekets@gmail.com> | 2012-08-20 20:22:09 +0200 |
---|---|---|
committer | Thorsten Behrens <tbehrens@suse.com> | 2012-10-10 12:03:29 +0200 |
commit | f77bd4a7c83e8d84655f4e3a4f3c6c44a735053e (patch) | |
tree | ebd4b4a4407f03388c5da33c5cffc83f5f6a2218 /filter/source | |
parent | df9a436a85fa281cd53d46fdb832965d36aa9135 (diff) |
some improvement in making text animation compatible with text selection
Diffstat (limited to 'filter/source')
-rw-r--r-- | filter/source/svg/presentation_engine.js | 258 | ||||
-rw-r--r-- | filter/source/svg/svgexport.cxx | 36 | ||||
-rw-r--r-- | filter/source/svg/svgfilter.hxx | 1 | ||||
-rw-r--r-- | filter/source/svg/svgwriter.cxx | 13 |
4 files changed, 235 insertions, 73 deletions
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js index 5fc68f6b214a..f05e00a1ac6c 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 38cad60161a2..8f8d727da5e7 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 3ef33a655ac3..c5567dfe7de1 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 2575bfe3aa03..d13ac782f356 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; } |