1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/presentation/EffectPresetClass.hpp>
21 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
22 #include <com/sun/star/animations/ParallelTimeContainer.hpp>
23 #include <com/sun/star/view/XSelectionSupplier.hpp>
24 #include <com/sun/star/drawing/XDrawView.hpp>
25 #include <com/sun/star/drawing/XShape.hpp>
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <com/sun/star/presentation/EffectNodeType.hpp>
28 #include <com/sun/star/presentation/EffectCommands.hpp>
29 #include <com/sun/star/animations/AnimationTransformType.hpp>
30 #include <com/sun/star/text/XTextRangeCompare.hpp>
31 #include <com/sun/star/container/XEnumerationAccess.hpp>
32 #include <com/sun/star/container/XIndexAccess.hpp>
33 #include <com/sun/star/presentation/ParagraphTarget.hpp>
34 #include <com/sun/star/text/XText.hpp>
35 #include <com/sun/star/awt/XWindow.hpp>
36 #include <com/sun/star/drawing/LineStyle.hpp>
37 #include <com/sun/star/drawing/FillStyle.hpp>
38 #include <comphelper/processfactory.hxx>
39 #include <sfx2/dispatch.hxx>
40 #include "STLPropertySet.hxx"
41 #include "CustomAnimationPane.hxx"
42 #include "CustomAnimationDialog.hxx"
43 #include "CustomAnimationCreateDialog.hxx"
44 #include "CustomAnimation.hrc"
45 #include "CustomAnimationList.hxx"
46 #include "createcustomanimationpanel.hxx"
47 #include <vcl/lstbox.hxx>
48 #include <vcl/fixed.hxx>
50 #include <vcl/button.hxx>
51 #include <vcl/combobox.hxx>
52 #include <vcl/scrbar.hxx>
54 #include <comphelper/sequence.hxx>
55 #include <sfx2/frame.hxx>
56 #include <sfx2/sidebar/Theme.hxx>
58 #include <svx/unoapi.hxx>
59 #include <svx/svxids.hrc>
60 #include <DrawDocShell.hxx>
61 #include <ViewShellBase.hxx>
62 #include "DrawViewShell.hxx"
63 #include "DrawController.hxx"
64 #include "sdresid.hxx"
65 #include "drawview.hxx"
66 #include "slideshow.hxx"
67 #include "undoanim.hxx"
68 #include "optsitem.hxx"
70 #include "framework/FrameworkHelper.hxx"
72 #include "EventMultiplexer.hxx"
76 #include "drawdoc.hxx"
81 #include <basegfx/polygon/b2dpolypolygontools.hxx>
82 #include <basegfx/matrix/b2dhommatrix.hxx>
83 #include <basegfx/range/b2drange.hxx>
84 #include <boost/scoped_ptr.hpp>
86 using namespace ::com::sun::star
;
87 using namespace ::com::sun::star::animations
;
88 using namespace ::com::sun::star::presentation
;
89 using namespace ::com::sun::star::text
;
91 using namespace ::com::sun::star::uno
;
92 using namespace ::com::sun::star::drawing
;
93 using ::com::sun::star::view::XSelectionSupplier
;
94 using ::com::sun::star::view::XSelectionChangeListener
;
95 using ::com::sun::star::frame::XController
;
96 using ::com::sun::star::frame::XModel
;
97 using ::com::sun::star::beans::XPropertySet
;
98 using ::com::sun::star::beans::XPropertyChangeListener
;
99 using ::com::sun::star::container::XIndexAccess
;
100 using ::com::sun::star::container::XEnumerationAccess
;
101 using ::com::sun::star::container::XEnumeration
;
102 using ::com::sun::star::text::XText
;
103 using ::sd::framework::FrameworkHelper
;
107 void fillDurationComboBox( ListBox
* pBox
)
109 static const double gdVerySlow
= 5.0;
110 static const double gdSlow
= 3.0;
111 static const double gdNormal
= 2.0;
112 static const double gdFast
= 1.0;
113 static const double gdVeryFast
= 0.5;
115 OUString
aVerySlow( SD_RESSTR( STR_CUSTOMANIMATION_DURATION_VERY_SLOW
) );
116 pBox
->SetEntryData( pBox
->InsertEntry( aVerySlow
), (void*)&gdVerySlow
);
118 OUString
aSlow( SD_RESSTR( STR_CUSTOMANIMATION_DURATION_SLOW
) );
119 pBox
->SetEntryData( pBox
->InsertEntry( aSlow
), (void*)&gdSlow
);
121 OUString
aNormal( SD_RESSTR( STR_CUSTOMANIMATION_DURATION_NORMAL
) );
122 pBox
->SetEntryData( pBox
->InsertEntry( aNormal
), (void*)&gdNormal
);
124 OUString
aFast( SD_RESSTR( STR_CUSTOMANIMATION_DURATION_FAST
) );
125 pBox
->SetEntryData( pBox
->InsertEntry( aFast
), (void*)&gdFast
);
127 OUString
aVeryFast( SD_RESSTR( STR_CUSTOMANIMATION_DURATION_VERY_FAST
) );
128 pBox
->SetEntryData( pBox
->InsertEntry( aVeryFast
), (void*)&gdVeryFast
);
131 void fillRepeatComboBox( ListBox
* pBox
)
133 OUString
aNone( SD_RESSTR( STR_CUSTOMANIMATION_REPEAT_NONE
) );
134 pBox
->InsertEntry(aNone
);
135 pBox
->InsertEntry(OUString::number(2));
136 pBox
->InsertEntry(OUString::number(3));
137 pBox
->InsertEntry(OUString::number(4));
138 pBox
->InsertEntry(OUString::number(5));
139 pBox
->InsertEntry(OUString::number(10));
141 OUString
aUntilClick( SD_RESSTR( STR_CUSTOMANIMATION_REPEAT_UNTIL_NEXT_CLICK
) );
142 pBox
->InsertEntry(aUntilClick
);
144 OUString
aEndOfSlide( SD_RESSTR( STR_CUSTOMANIMATION_REPEAT_UNTIL_END_OF_SLIDE
) );
145 pBox
->InsertEntry(aEndOfSlide
);
148 CustomAnimationPane::CustomAnimationPane( Window
* pParent
, ViewShellBase
& rBase
,
149 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
,
150 const Size
& rMinSize
)
151 : PanelLayout( pParent
, "CustomAnimationsPanel", "modules/simpress/ui/customanimationspanel.ui", rxFrame
),
153 mpCustomAnimationPresets(NULL
),
154 mnPropertyType( nPropertyTypeNone
),
155 maMinSize( rMinSize
),
156 mxModel( rBase
.GetDocShell()->GetDoc()->getUnoModel(), UNO_QUERY
),
160 get(mpPBAddEffect
, "add_effect");
161 get(mpPBChangeEffect
, "change_effect");
162 get(mpPBRemoveEffect
, "remove_effect");
164 get(mpFTEffect
, "effect_label");
166 get(mpFTStart
, "start_effect");
167 get(mpLBStart
, "start_effect_list");
168 get(mpFTProperty
, "effect_property");
169 get(mpPlaceholderBox
, "placeholder");
170 get(mpLBProperty
, "effect_property_list");
171 get(mpPBPropertyMore
, "more_properties");
173 get(mpFTSpeed
, "effect_speed");
174 get(mpCBSpeed
, "effect_speed_list");
176 get(mpCustomAnimationList
, "custom_animation_list");
177 mpCustomAnimationList
->setController( dynamic_cast<ICustomAnimationListController
*> ( this ) );
178 mpCustomAnimationList
->set_width_request(mpCustomAnimationList
->approximate_char_width() * 16);
179 mpCustomAnimationList
->set_height_request(mpCustomAnimationList
->GetTextHeight() * 16);
181 get(mpPBMoveUp
, "move_up");
182 get(mpPBMoveDown
, "move_down");
183 get(mpPBPlay
, "play");
184 get(mpCBAutoPreview
,"auto_preview");
186 maStrProperty
= mpFTProperty
->GetText();
188 fillDurationComboBox( mpCBSpeed
);
190 mpPBAddEffect
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
191 mpPBChangeEffect
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
192 mpPBRemoveEffect
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
193 mpLBStart
->SetSelectHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
194 mpCBSpeed
->SetSelectHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
195 mpPBPropertyMore
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
196 mpPBMoveUp
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
197 mpPBMoveDown
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
198 mpPBPlay
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
199 mpCBAutoPreview
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
201 maStrModify
= mpFTEffect
->GetText();
203 // get current controller and initialize listeners
206 mxView
= Reference
< XDrawView
>::query(mrBase
.GetController());
211 OSL_FAIL( "sd::CustomAnimationPane::CustomAnimationPane(), Exception caught!" );
214 // get current page and update custom animation list
215 onChangeCurrentPage();
217 // Wait a short time before the presets list is created. This gives the
218 // system time to paint the control.
219 maLateInitTimer
.SetTimeout(100);
220 maLateInitTimer
.SetTimeoutHdl(LINK(this, CustomAnimationPane
, lateInitCallback
));
221 maLateInitTimer
.Start();
226 CustomAnimationPane::~CustomAnimationPane()
231 void CustomAnimationPane::dispose()
233 maLateInitTimer
.Stop();
237 MotionPathTagVector aTags
;
238 aTags
.swap( maMotionPathTags
);
239 MotionPathTagVector::iterator aIter
;
240 for( aIter
= aTags
.begin(); aIter
!= aTags
.end(); ++aIter
)
243 mpPBAddEffect
.clear();
244 mpPBChangeEffect
.clear();
245 mpPBRemoveEffect
.clear();
249 mpFTProperty
.clear();
250 mpPlaceholderBox
.clear();
251 mpLBProperty
.clear();
252 mpPBPropertyMore
.clear();
255 mpCustomAnimationList
.clear();
257 mpPBMoveDown
.clear();
259 mpCBAutoPreview
.clear();
260 PanelLayout::dispose();
263 void CustomAnimationPane::addUndo()
265 ::svl::IUndoManager
* pManager
= mrBase
.GetDocShell()->GetUndoManager();
268 SdPage
* pPage
= SdPage::getImplementation( mxCurrentPage
);
270 pManager
->AddUndoAction( new UndoAnimation( mrBase
.GetDocShell()->GetDoc(), pPage
) );
274 void CustomAnimationPane::StateChanged( StateChangedType nStateChange
)
276 Control::StateChanged( nStateChange
);
278 if( nStateChange
== StateChangedType::Visible
)
279 updateMotionPathTags();
282 void CustomAnimationPane::KeyInput( const KeyEvent
& rKEvt
)
284 if( mpCustomAnimationList
)
285 mpCustomAnimationList
->KeyInput( rKEvt
);
288 void CustomAnimationPane::addListener()
290 Link
<> aLink( LINK(this,CustomAnimationPane
,EventMultiplexerListener
) );
291 mrBase
.GetEventMultiplexer()->AddEventListener (
293 tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
294 | tools::EventMultiplexerEvent::EID_CURRENT_PAGE
295 | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
296 | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
297 | tools::EventMultiplexerEvent::EID_DISPOSING
298 | tools::EventMultiplexerEvent::EID_END_TEXT_EDIT
);
301 void CustomAnimationPane::removeListener()
303 Link
<> aLink( LINK(this,CustomAnimationPane
,EventMultiplexerListener
) );
304 mrBase
.GetEventMultiplexer()->RemoveEventListener( aLink
);
307 IMPL_LINK(CustomAnimationPane
,EventMultiplexerListener
,
308 tools::EventMultiplexerEvent
*,pEvent
)
310 switch (pEvent
->meEventId
)
312 case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
:
313 onSelectionChanged();
316 case tools::EventMultiplexerEvent::EID_CURRENT_PAGE
:
317 onChangeCurrentPage();
320 case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
:
321 // At this moment the controller may not yet been set at model
322 // or ViewShellBase. Take it from the view shell passed with
324 if (mrBase
.GetMainViewShell() != 0)
326 if( mrBase
.GetMainViewShell()->GetShellType() == ViewShell::ST_IMPRESS
)
328 mxView
= Reference
<XDrawView
>::query(mrBase
.GetDrawController());
329 onSelectionChanged();
330 onChangeCurrentPage();
334 // fall through intended
335 case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
:
341 case tools::EventMultiplexerEvent::EID_DISPOSING
:
343 onSelectionChanged();
344 onChangeCurrentPage();
346 case tools::EventMultiplexerEvent::EID_END_TEXT_EDIT
:
347 if( mpMainSequence
.get() && pEvent
->mpUserData
)
348 mpCustomAnimationList
->update( mpMainSequence
);
354 static sal_Int32
getPropertyType( const OUString
& rProperty
)
356 if ( rProperty
== "Direction" )
357 return nPropertyTypeDirection
;
359 if ( rProperty
== "Spokes" )
360 return nPropertyTypeSpokes
;
362 if ( rProperty
== "Zoom" )
363 return nPropertyTypeZoom
;
365 if ( rProperty
== "Accelerate" )
366 return nPropertyTypeAccelerate
;
368 if ( rProperty
== "Decelerate" )
369 return nPropertyTypeDecelerate
;
371 if ( rProperty
== "Color1" )
372 return nPropertyTypeFirstColor
;
374 if ( rProperty
== "Color2" )
375 return nPropertyTypeSecondColor
;
377 if ( rProperty
== "FillColor" )
378 return nPropertyTypeFillColor
;
380 if ( rProperty
== "ColorStyle" )
381 return nPropertyTypeColorStyle
;
383 if ( rProperty
== "AutoReverse" )
384 return nPropertyTypeAutoReverse
;
386 if ( rProperty
== "FontStyle" )
387 return nPropertyTypeFont
;
389 if ( rProperty
== "CharColor" )
390 return nPropertyTypeCharColor
;
392 if ( rProperty
== "CharHeight" )
393 return nPropertyTypeCharHeight
;
395 if ( rProperty
== "CharDecoration" )
396 return nPropertyTypeCharDecoration
;
398 if ( rProperty
== "LineColor" )
399 return nPropertyTypeLineColor
;
401 if ( rProperty
== "Rotate" )
402 return nPropertyTypeRotate
;
404 if ( rProperty
== "Transparency" )
405 return nPropertyTypeTransparency
;
407 if ( rProperty
== "Color" )
408 return nPropertyTypeColor
;
410 if ( rProperty
== "Scale" )
411 return nPropertyTypeScale
;
413 return nPropertyTypeNone
;
416 OUString
getPropertyName( sal_Int32 nPropertyType
)
418 switch( nPropertyType
)
420 case nPropertyTypeDirection
:
421 return SD_RESSTR(STR_CUSTOMANIMATION_DIRECTION_PROPERTY
);
423 case nPropertyTypeSpokes
:
424 return SD_RESSTR(STR_CUSTOMANIMATION_SPOKES_PROPERTY
);
426 case nPropertyTypeFirstColor
:
427 return SD_RESSTR(STR_CUSTOMANIMATION_FIRST_COLOR_PROPERTY
);
429 case nPropertyTypeSecondColor
:
430 return SD_RESSTR(STR_CUSTOMANIMATION_SECOND_COLOR_PROPERTY
);
432 case nPropertyTypeZoom
:
433 return SD_RESSTR(STR_CUSTOMANIMATION_ZOOM_PROPERTY
);
435 case nPropertyTypeFillColor
:
436 return SD_RESSTR(STR_CUSTOMANIMATION_FILL_COLOR_PROPERTY
);
438 case nPropertyTypeColorStyle
:
439 return SD_RESSTR(STR_CUSTOMANIMATION_STYLE_PROPERTY
);
441 case nPropertyTypeFont
:
442 return SD_RESSTR(STR_CUSTOMANIMATION_FONT_PROPERTY
);
444 case nPropertyTypeCharHeight
:
445 return SD_RESSTR(STR_CUSTOMANIMATION_SIZE_PROPERTY
);
447 case nPropertyTypeCharColor
:
448 return SD_RESSTR(STR_CUSTOMANIMATION_FONT_COLOR_PROPERTY
);
450 case nPropertyTypeCharHeightStyle
:
451 return SD_RESSTR(STR_CUSTOMANIMATION_FONT_SIZE_STYLE_PROPERTY
);
453 case nPropertyTypeCharDecoration
:
454 return SD_RESSTR(STR_CUSTOMANIMATION_FONT_STYLE_PROPERTY
);
456 case nPropertyTypeLineColor
:
457 return SD_RESSTR(STR_CUSTOMANIMATION_LINE_COLOR_PROPERTY
);
459 case nPropertyTypeRotate
:
460 return SD_RESSTR(STR_CUSTOMANIMATION_AMOUNT_PROPERTY
);
462 case nPropertyTypeColor
:
463 return SD_RESSTR(STR_CUSTOMANIMATION_COLOR_PROPERTY
);
465 case nPropertyTypeTransparency
:
466 return SD_RESSTR(STR_CUSTOMANIMATION_AMOUNT_PROPERTY
);
468 case nPropertyTypeScale
:
469 return SD_RESSTR(STR_CUSTOMANIMATION_SCALE_PROPERTY
);
475 void CustomAnimationPane::updateControls()
477 mpFTSpeed
->Enable( mxView
.is() );
478 mpCBSpeed
->Enable( mxView
.is() );
479 mpCustomAnimationList
->Enable( mxView
.is() );
480 mpPBMoveUp
->Enable( mxView
.is() );
481 mpPBMoveDown
->Enable( mxView
.is() );
482 mpPBPlay
->Enable( mxView
.is() );
483 mpCBAutoPreview
->Enable( mxView
.is() );
487 mpPBAddEffect
->Enable( false );
488 mpPBChangeEffect
->Enable( false );
489 mpPBRemoveEffect
->Enable( false );
490 mpFTStart
->Enable( false );
491 mpLBStart
->Enable( false );
492 mpPBPropertyMore
->Enable( false );
493 mpLBProperty
->Enable( false );
494 mpFTProperty
->Enable( false );
495 mpCustomAnimationList
->clear();
499 const int nSelectionCount
= maListSelection
.size();
501 mpPBAddEffect
->Enable( maViewSelection
.hasValue() );
502 mpPBChangeEffect
->Enable( nSelectionCount
);
503 mpPBRemoveEffect
->Enable(nSelectionCount
);
505 mpFTStart
->Enable(nSelectionCount
> 0);
506 mpLBStart
->Enable(nSelectionCount
> 0);
507 mpPBPropertyMore
->Enable(nSelectionCount
> 0);
509 mpFTProperty
->SetText( maStrProperty
);
511 mnPropertyType
= nPropertyTypeNone
;
513 if( nSelectionCount
== 1 )
515 CustomAnimationEffectPtr pEffect
= maListSelection
.front();
517 OUString
aUIName( getPresets().getUINameForPresetId( pEffect
->getPresetId() ) );
519 OUString
aTemp( maStrModify
);
521 if( !aUIName
.isEmpty() )
523 aTemp
+= OUString( (sal_Unicode
)' ' );
525 mpFTEffect
->SetText( aTemp
);
528 CustomAnimationPresetPtr pDescriptor
= getPresets().getEffectDescriptor( pEffect
->getPresetId() );
529 if( pDescriptor
.get() )
531 PropertySubControl
* pSubControl
= NULL
;
535 UStringList
aProperties( pDescriptor
->getProperties() );
536 if( aProperties
.size() >= 1 )
538 mnPropertyType
= getPropertyType( aProperties
.front() );
540 mpFTProperty
->SetText( getPropertyName( mnPropertyType
) );
542 aValue
= getProperty1Value( mnPropertyType
, pEffect
);
545 if( aValue
.hasValue() )
547 pSubControl
= mpLBProperty
->getSubControl();
548 if( !pSubControl
|| (pSubControl
->getControlType() != mnPropertyType
) )
550 pSubControl
= PropertySubControl::create( mnPropertyType
, mpPlaceholderBox
, aValue
, pEffect
->getPresetId(), LINK( this, CustomAnimationPane
, implPropertyHdl
) );
551 mpLBProperty
->setSubControl( pSubControl
);
555 pSubControl
->setValue( aValue
, pEffect
->getPresetId() );
560 mpLBProperty
->setSubControl( 0 );
563 bool bEnable
= (pSubControl
!= 0) && (pSubControl
->getControl()->IsEnabled());
564 mpLBProperty
->Enable( bEnable
);
565 mpFTProperty
->Enable( bEnable
);
569 mpLBProperty
->setSubControl( 0 );
570 mpFTProperty
->Enable( false );
571 mpLBProperty
->Enable( false );
572 mpPBPropertyMore
->Enable( false );
575 sal_uInt16 nPos
= 0xffff;
577 sal_Int16 nNodeType
= pEffect
->getNodeType();
580 case EffectNodeType::ON_CLICK
: nPos
= 0; break;
581 case EffectNodeType::WITH_PREVIOUS
: nPos
= 1; break;
582 case EffectNodeType::AFTER_PREVIOUS
: nPos
= 2; break;
585 mpLBStart
->SelectEntryPos( nPos
);
587 double fDuration
= pEffect
->getDuration();
588 const bool bHasSpeed
= fDuration
> 0.001;
590 mpFTSpeed
->Enable(bHasSpeed
);
591 mpCBSpeed
->Enable(bHasSpeed
);
595 if( fDuration
== 5.0 )
597 else if( fDuration
== 3.0 )
599 else if( fDuration
== 2.0 )
601 else if( fDuration
== 1.0 )
603 else if( fDuration
== 0.5 )
608 mpCBSpeed
->SelectEntryPos( nPos
);
611 mpPBPropertyMore
->Enable( true );
615 mpLBProperty
->setSubControl( 0 );
616 mpFTProperty
->Enable( false );
617 mpLBProperty
->Enable( false );
618 mpPBPropertyMore
->Enable( false );
619 mpFTSpeed
->Enable(false);
620 mpCBSpeed
->Enable(false);
621 mpLBStart
->SetNoSelection();
622 mpCBSpeed
->SetNoSelection();
623 mpFTEffect
->SetText( maStrModify
);
626 bool bEnableUp
= true;
627 bool bEnableDown
= true;
628 if( nSelectionCount
== 0 )
635 if( mpMainSequence
->find( maListSelection
.front() ) == mpMainSequence
->getBegin() )
638 EffectSequence::iterator
aIter( mpMainSequence
->find( maListSelection
.back() ) );
639 if( aIter
== mpMainSequence
->getEnd() )
649 while( (aIter
!= mpMainSequence
->getEnd()) && !(mpCustomAnimationList
->isExpanded((*aIter
)) ) );
651 if( aIter
== mpMainSequence
->getEnd() )
655 if( bEnableUp
|| bEnableDown
)
657 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
659 EffectSequenceHelper
* pSequence
= 0;
660 EffectSequence::iterator
aRebuildIter( maListSelection
.begin() );
661 const EffectSequence::iterator
aRebuildEnd( maListSelection
.end() );
662 while( aRebuildIter
!= aRebuildEnd
)
664 CustomAnimationEffectPtr pEffect
= (*aRebuildIter
++);
670 pSequence
= pEffect
->getEffectSequence();
674 if( pSequence
!= pEffect
->getEffectSequence() )
686 mpPBMoveUp
->Enable(bEnableUp
);
687 mpPBMoveDown
->Enable(bEnableDown
);
689 SdOptions
* pOptions
= SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS
);
690 mpCBAutoPreview
->Check( pOptions
->IsPreviewChangedEffects() );
692 updateMotionPathTags();
695 static bool updateMotionPathImpl( CustomAnimationPane
& rPane
, ::sd::View
& rView
, EffectSequence::iterator aIter
, EffectSequence::iterator aEnd
, MotionPathTagVector
& rOldTags
, MotionPathTagVector
& rNewTags
)
697 bool bChanges
= false;
698 while( aIter
!= aEnd
)
700 CustomAnimationEffectPtr
pEffect( (*aIter
++) );
701 if( pEffect
.get() && pEffect
->getPresetClass() == ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH
)
703 rtl::Reference
< MotionPathTag
> xMotionPathTag
;
704 // first try to find if there is already a tag for this
705 MotionPathTagVector::iterator
aMIter( rOldTags
.begin() );
706 for( ; aMIter
!= rOldTags
.end(); ++aMIter
)
708 rtl::Reference
< MotionPathTag
> xTag( (*aMIter
) );
709 if( xTag
->getEffect() == pEffect
)
711 if( !xTag
->isDisposed() )
713 xMotionPathTag
= xTag
;
714 rOldTags
.erase( aMIter
);
720 // if not found, create new one
721 if( !xMotionPathTag
.is() )
723 xMotionPathTag
.set( new MotionPathTag( rPane
, rView
, pEffect
) );
727 if( xMotionPathTag
.is() )
728 rNewTags
.push_back( xMotionPathTag
);
735 void CustomAnimationPane::updateMotionPathTags()
737 bool bChanges
= false;
739 MotionPathTagVector aTags
;
740 aTags
.swap( maMotionPathTags
);
742 ::sd::View
* pView
= 0;
746 ::boost::shared_ptr
<ViewShell
> xViewShell( mrBase
.GetMainViewShell() );
747 if( xViewShell
.get() )
748 pView
= xViewShell
->GetView();
751 if( IsVisible() && mpMainSequence
.get() && pView
)
753 bChanges
= updateMotionPathImpl( *this, *pView
, mpMainSequence
->getBegin(), mpMainSequence
->getEnd(), aTags
, maMotionPathTags
);
755 const InteractiveSequenceList
& rISL
= mpMainSequence
->getInteractiveSequenceList();
756 InteractiveSequenceList::const_iterator
aISI( rISL
.begin() );
757 while( aISI
!= rISL
.end() )
759 InteractiveSequencePtr
pIS( (*aISI
++) );
760 bChanges
|= updateMotionPathImpl( *this, *pView
, pIS
->getBegin(), pIS
->getEnd(), aTags
, maMotionPathTags
);
767 MotionPathTagVector::iterator
aIter( aTags
.begin() );
768 while( aIter
!= aTags
.end() )
770 rtl::Reference
< MotionPathTag
> xTag( (*aIter
++) );
775 if( bChanges
&& pView
)
776 pView
->updateHandles();
779 void CustomAnimationPane::onSelectionChanged()
781 if( !maSelectionLock
.isLocked() )
783 ScopeLockGuard
aGuard( maSelectionLock
);
785 if( mxView
.is() ) try
787 Reference
< XSelectionSupplier
> xSel( mxView
, UNO_QUERY_THROW
);
790 maViewSelection
= xSel
->getSelection();
791 mpCustomAnimationList
->onSelectionChanged( maViewSelection
);
797 OSL_FAIL( "sd::CustomAnimationPane::onSelectionChanged(), Exception caught!" );
802 void CustomAnimationPane::onDoubleClick()
807 void CustomAnimationPane::onContextMenu( sal_uInt16 nSelectedPopupEntry
)
809 switch( nSelectedPopupEntry
)
811 case CM_WITH_CLICK
: onChangeStart( EffectNodeType::ON_CLICK
); break;
812 case CM_WITH_PREVIOUS
: onChangeStart( EffectNodeType::WITH_PREVIOUS
); break;
813 case CM_AFTER_PREVIOUS
: onChangeStart( EffectNodeType::AFTER_PREVIOUS
); break;
814 case CM_OPTIONS
: showOptions(); break;
815 case CM_DURATION
: showOptions("timing"); break;
816 case CM_REMOVE
: onRemove(); break;
817 case CM_CREATE
: if( maViewSelection
.hasValue() ) onChange( true ); break;
823 void CustomAnimationPane::DataChanged (const DataChangedEvent
& rEvent
)
829 void CustomAnimationPane::UpdateLook()
831 const Wallpaper
aBackground (
832 ::sfx2::sidebar::Theme::GetWallpaper(
833 ::sfx2::sidebar::Theme::Paint_PanelBackground
));
834 SetBackground(aBackground
);
835 if (mpFTStart
!= nullptr)
836 mpFTStart
->SetBackground(aBackground
);
837 if (mpFTProperty
!= nullptr)
838 mpFTProperty
->SetBackground(aBackground
);
839 if (mpFTSpeed
!= nullptr)
840 mpFTSpeed
->SetBackground(aBackground
);
843 void addValue( STLPropertySet
* pSet
, sal_Int32 nHandle
, const Any
& rValue
)
845 switch( pSet
->getPropertyState( nHandle
) )
847 case STLPropertyState_AMBIGUOUS
:
848 // value is already ambiguous, do nothing
850 case STLPropertyState_DIRECT
:
851 // set to ambiguous if existing value is different
852 if( rValue
!= pSet
->getPropertyValue( nHandle
) )
853 pSet
->setPropertyState( nHandle
, STLPropertyState_AMBIGUOUS
);
855 case STLPropertyState_DEFAULT
:
856 // just set new value
857 pSet
->setPropertyValue( nHandle
, rValue
);
862 static sal_Int32
calcMaxParaDepth( Reference
< XShape
> xTargetShape
)
864 sal_Int32 nMaxParaDepth
= -1;
866 if( xTargetShape
.is() )
868 Reference
< XEnumerationAccess
> xText( xTargetShape
, UNO_QUERY
);
871 Reference
< XPropertySet
> xParaSet
;
872 const OUString
strNumberingLevel( "NumberingLevel" );
874 Reference
< XEnumeration
> xEnumeration( xText
->createEnumeration(), UNO_QUERY_THROW
);
875 while( xEnumeration
->hasMoreElements() )
877 xEnumeration
->nextElement() >>= xParaSet
;
880 sal_Int32 nParaDepth
= 0;
881 xParaSet
->getPropertyValue( strNumberingLevel
) >>= nParaDepth
;
883 if( nParaDepth
> nMaxParaDepth
)
884 nMaxParaDepth
= nParaDepth
;
890 return nMaxParaDepth
+ 1;
893 Any
CustomAnimationPane::getProperty1Value( sal_Int32 nType
, CustomAnimationEffectPtr pEffect
)
897 case nPropertyTypeDirection
:
898 case nPropertyTypeSpokes
:
899 case nPropertyTypeZoom
:
900 return makeAny( pEffect
->getPresetSubType() );
902 case nPropertyTypeColor
:
903 case nPropertyTypeFillColor
:
904 case nPropertyTypeFirstColor
:
905 case nPropertyTypeSecondColor
:
906 case nPropertyTypeCharColor
:
907 case nPropertyTypeLineColor
:
909 const sal_Int32 nIndex
= (nPropertyTypeFirstColor
== nType
) ? 0 : 1;
910 return pEffect
->getColor( nIndex
);
913 case nPropertyTypeFont
:
914 return pEffect
->getProperty( AnimationNodeType::SET
, "CharFontName" , VALUE_TO
);
916 case nPropertyTypeCharHeight
:
918 const OUString
aAttributeName( "CharHeight" );
919 Any
aValue( pEffect
->getProperty( AnimationNodeType::SET
, aAttributeName
, VALUE_TO
) );
920 if( !aValue
.hasValue() )
921 aValue
= pEffect
->getProperty( AnimationNodeType::ANIMATE
, aAttributeName
, VALUE_TO
);
925 case nPropertyTypeRotate
:
926 return pEffect
->getTransformationProperty( AnimationTransformType::ROTATE
, VALUE_BY
);
928 case nPropertyTypeTransparency
:
929 return pEffect
->getProperty( AnimationNodeType::SET
, "Opacity" , VALUE_TO
);
931 case nPropertyTypeScale
:
932 return pEffect
->getTransformationProperty( AnimationTransformType::SCALE
, VALUE_BY
);
934 case nPropertyTypeCharDecoration
:
936 Sequence
< Any
> aValues(3);
937 aValues
[0] = pEffect
->getProperty( AnimationNodeType::SET
, "CharWeight" , VALUE_TO
);
938 aValues
[1] = pEffect
->getProperty( AnimationNodeType::SET
, "CharPosture" , VALUE_TO
);
939 aValues
[2] = pEffect
->getProperty( AnimationNodeType::SET
, "CharUnderline" , VALUE_TO
);
940 return makeAny( aValues
);
948 bool CustomAnimationPane::setProperty1Value( sal_Int32 nType
, CustomAnimationEffectPtr pEffect
, const Any
& rValue
)
950 bool bEffectChanged
= false;
953 case nPropertyTypeDirection
:
954 case nPropertyTypeSpokes
:
955 case nPropertyTypeZoom
:
957 OUString aPresetSubType
;
958 rValue
>>= aPresetSubType
;
959 if( aPresetSubType
!= pEffect
->getPresetSubType() )
961 getPresets().changePresetSubType( pEffect
, aPresetSubType
);
962 bEffectChanged
= true;
967 case nPropertyTypeFillColor
:
968 case nPropertyTypeColor
:
969 case nPropertyTypeFirstColor
:
970 case nPropertyTypeSecondColor
:
971 case nPropertyTypeCharColor
:
972 case nPropertyTypeLineColor
:
974 const sal_Int32 nIndex
= (nPropertyTypeFirstColor
== nType
) ? 0 : 1;
975 Any
aOldColor( pEffect
->getColor( nIndex
) );
976 if( aOldColor
!= rValue
)
978 pEffect
->setColor( nIndex
, rValue
);
979 bEffectChanged
= true;
984 case nPropertyTypeFont
:
985 bEffectChanged
= pEffect
->setProperty( AnimationNodeType::SET
, "CharFontName" , VALUE_TO
, rValue
);
988 case nPropertyTypeCharHeight
:
990 const OUString
aAttributeName( "CharHeight" );
991 bEffectChanged
= pEffect
->setProperty( AnimationNodeType::SET
, aAttributeName
, VALUE_TO
, rValue
);
992 if( !bEffectChanged
)
993 bEffectChanged
= pEffect
->setProperty( AnimationNodeType::ANIMATE
, aAttributeName
, VALUE_TO
, rValue
);
996 case nPropertyTypeRotate
:
997 bEffectChanged
= pEffect
->setTransformationProperty( AnimationTransformType::ROTATE
, VALUE_BY
, rValue
);
1000 case nPropertyTypeTransparency
:
1001 bEffectChanged
= pEffect
->setProperty( AnimationNodeType::SET
, "Opacity" , VALUE_TO
, rValue
);
1004 case nPropertyTypeScale
:
1005 bEffectChanged
= pEffect
->setTransformationProperty( AnimationTransformType::SCALE
, VALUE_BY
, rValue
);
1008 case nPropertyTypeCharDecoration
:
1010 Sequence
< Any
> aValues(3);
1012 bEffectChanged
= pEffect
->setProperty( AnimationNodeType::SET
, "CharWeight" , VALUE_TO
, aValues
[0] );
1013 bEffectChanged
|= pEffect
->setProperty( AnimationNodeType::SET
, "CharPosture" , VALUE_TO
, aValues
[1] );
1014 bEffectChanged
|= pEffect
->setProperty( AnimationNodeType::SET
, "CharUnderline" , VALUE_TO
, aValues
[2] );
1020 return bEffectChanged
;
1023 static bool hasVisibleShape( const Reference
< XShape
>& xShape
)
1027 const OUString
sShapeType( xShape
->getShapeType() );
1029 if( sShapeType
== "com.sun.star.presentation.TitleTextShape" || sShapeType
== "com.sun.star.presentation.OutlinerShape" ||
1030 sShapeType
== "com.sun.star.presentation.SubtitleShape" || sShapeType
== "com.sun.star.drawing.TextShape" )
1032 const OUString
sFillStyle( "FillStyle" );
1033 const OUString
sLineStyle( "LineStyle" );
1034 Reference
< XPropertySet
> xSet( xShape
, UNO_QUERY_THROW
);
1036 FillStyle eFillStyle
;
1037 xSet
->getPropertyValue( sFillStyle
) >>= eFillStyle
;
1039 ::com::sun::star::drawing::LineStyle eLineStyle
;
1040 xSet
->getPropertyValue( sLineStyle
) >>= eLineStyle
;
1042 return eFillStyle
!= FillStyle_NONE
|| eLineStyle
!= ::com::sun::star::drawing::LineStyle_NONE
;
1051 STLPropertySet
* CustomAnimationPane::createSelectionSet()
1053 STLPropertySet
* pSet
= CustomAnimationDialog::createDefaultSet();
1055 pSet
->setPropertyValue( nHandleCurrentPage
, makeAny( mxCurrentPage
) );
1057 sal_Int32 nMaxParaDepth
= 0;
1059 // get options from selected effects
1060 EffectSequence::iterator
aIter( maListSelection
.begin() );
1061 const EffectSequence::iterator
aEnd( maListSelection
.end() );
1062 const CustomAnimationPresets
& rPresets (getPresets());
1063 while( aIter
!= aEnd
)
1065 CustomAnimationEffectPtr pEffect
= (*aIter
++);
1067 EffectSequenceHelper
* pEffectSequence
= pEffect
->getEffectSequence();
1068 if( !pEffectSequence
)
1069 pEffectSequence
= mpMainSequence
.get();
1071 if( pEffect
->hasText() )
1073 sal_Int32 n
= calcMaxParaDepth(pEffect
->getTargetShape());
1074 if( n
> nMaxParaDepth
)
1078 addValue( pSet
, nHandleHasAfterEffect
, makeAny( pEffect
->hasAfterEffect() ) );
1079 addValue( pSet
, nHandleAfterEffectOnNextEffect
, makeAny( pEffect
->IsAfterEffectOnNext() ? sal_True
: sal_False
) );
1080 addValue( pSet
, nHandleDimColor
, pEffect
->getDimColor() );
1081 addValue( pSet
, nHandleIterateType
, makeAny( pEffect
->getIterateType() ) );
1083 // convert absolute time to percentage value
1084 // This calculation is done in float to avoid some rounding artifacts.
1085 float fIterateInterval
= (float)pEffect
->getIterateInterval();
1086 if( pEffect
->getDuration() )
1087 fIterateInterval
= (float)(fIterateInterval
/ pEffect
->getDuration() );
1088 fIterateInterval
*= 100.0;
1089 addValue( pSet
, nHandleIterateInterval
, makeAny( (double)fIterateInterval
) );
1091 addValue( pSet
, nHandleBegin
, makeAny( pEffect
->getBegin() ) );
1092 addValue( pSet
, nHandleDuration
, makeAny( pEffect
->getDuration() ) );
1093 addValue( pSet
, nHandleStart
, makeAny( pEffect
->getNodeType() ) );
1094 addValue( pSet
, nHandleRepeat
, pEffect
->getRepeatCount() );
1095 addValue( pSet
, nHandleEnd
, pEffect
->getEnd() );
1096 addValue( pSet
, nHandleRewind
, makeAny( pEffect
->getFill() ) );
1098 addValue( pSet
, nHandlePresetId
, makeAny( pEffect
->getPresetId() ) );
1100 addValue( pSet
, nHandleHasText
, makeAny( pEffect
->hasText() ) );
1102 addValue( pSet
, nHandleHasVisibleShape
, Any( hasVisibleShape( pEffect
->getTargetShape() ) ) );
1105 if( pEffect
->getAudio().is() )
1107 aSoundSource
= pEffect
->getAudio()->getSource();
1108 addValue( pSet
, nHandleSoundVolumne
, makeAny( pEffect
->getAudio()->getVolume() ) );
1109 // todo addValue( pSet, nHandleSoundEndAfterSlide, makeAny( pEffect->getAudio()->getEndAfterSlide() ) );
1110 // this is now stored at the XCommand parameter sequence
1112 else if( pEffect
->getCommand() == EffectCommands::STOPAUDIO
)
1114 aSoundSource
= makeAny( true );
1116 addValue( pSet
, nHandleSoundURL
, aSoundSource
);
1118 sal_Int32 nGroupId
= pEffect
->getGroupId();
1119 CustomAnimationTextGroupPtr pTextGroup
;
1120 if( nGroupId
!= -1 )
1121 pTextGroup
= pEffectSequence
->findGroup( nGroupId
);
1123 addValue( pSet
, nHandleTextGrouping
, makeAny( pTextGroup
.get() ? pTextGroup
->getTextGrouping() : (sal_Int32
)-1 ) );
1124 addValue( pSet
, nHandleAnimateForm
, makeAny( pTextGroup
.get() == nullptr || pTextGroup
->getAnimateForm() ) );
1125 addValue( pSet
, nHandleTextGroupingAuto
, makeAny( pTextGroup
.get() ? pTextGroup
->getTextGroupingAuto() : (double)-1.0 ) );
1126 addValue( pSet
, nHandleTextReverse
, makeAny( pTextGroup
.get() && pTextGroup
->getTextReverse() ) );
1128 if( pEffectSequence
->getSequenceType() == EffectNodeType::INTERACTIVE_SEQUENCE
)
1130 InteractiveSequence
* pIS
= static_cast< InteractiveSequence
* >( pEffectSequence
);
1131 addValue( pSet
, nHandleTrigger
, makeAny( pIS
->getTriggerShape() ) );
1134 CustomAnimationPresetPtr pDescriptor
= rPresets
.getEffectDescriptor( pEffect
->getPresetId() );
1135 if( pDescriptor
.get() )
1137 sal_Int32 nType
= nPropertyTypeNone
;
1139 UStringList
aProperties( pDescriptor
->getProperties() );
1140 if( aProperties
.size() >= 1 )
1141 nType
= getPropertyType( aProperties
.front() );
1143 if( nType
!= nPropertyTypeNone
)
1145 addValue( pSet
, nHandleProperty1Type
, makeAny( nType
) );
1146 addValue( pSet
, nHandleProperty1Value
, getProperty1Value( nType
, pEffect
) );
1149 if( pDescriptor
->hasProperty( "Accelerate" ) )
1151 addValue( pSet
, nHandleAccelerate
, makeAny( pEffect
->getAcceleration() ) );
1154 if( pDescriptor
->hasProperty( "Decelerate" ) )
1156 addValue( pSet
, nHandleDecelerate
, makeAny( pEffect
->getDecelerate() ) );
1159 if( pDescriptor
->hasProperty( "AutoReverse" ) )
1161 addValue( pSet
, nHandleAutoReverse
, makeAny( pEffect
->getAutoReverse() ) );
1166 addValue( pSet
, nHandleMaxParaDepth
, makeAny( nMaxParaDepth
) );
1171 void CustomAnimationPane::changeSelection( STLPropertySet
* pResultSet
, STLPropertySet
* pOldSet
)
1173 // change selected effect
1174 bool bChanged
= false;
1176 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
1178 EffectSequence::iterator
aIter( maListSelection
.begin() );
1179 const EffectSequence::iterator
aEnd( maListSelection
.end() );
1180 while( aIter
!= aEnd
)
1182 CustomAnimationEffectPtr pEffect
= (*aIter
++);
1184 DBG_ASSERT( pEffect
->getEffectSequence(), "sd::CustomAnimationPane::changeSelection(), dead effect in selection!" );
1185 if( !pEffect
->getEffectSequence() )
1188 double fDuration
= 0.0; // we might need this for iterate-interval
1189 if( pResultSet
->getPropertyState( nHandleDuration
) == STLPropertyState_DIRECT
)
1191 pResultSet
->getPropertyValue( nHandleDuration
) >>= fDuration
;
1195 fDuration
= pEffect
->getDuration();
1198 if( pResultSet
->getPropertyState( nHandleIterateType
) == STLPropertyState_DIRECT
)
1200 sal_Int16 nIterateType
= 0;
1201 pResultSet
->getPropertyValue( nHandleIterateType
) >>= nIterateType
;
1202 if( pEffect
->getIterateType() != nIterateType
)
1204 pEffect
->setIterateType( nIterateType
);
1209 if( pEffect
->getIterateType() )
1211 if( pResultSet
->getPropertyState( nHandleIterateInterval
) == STLPropertyState_DIRECT
)
1213 double fIterateInterval
= 0.0;
1214 pResultSet
->getPropertyValue( nHandleIterateInterval
) >>= fIterateInterval
;
1215 if( pEffect
->getIterateInterval() != fIterateInterval
)
1217 const double f
= fIterateInterval
* pEffect
->getDuration() / 100;
1218 pEffect
->setIterateInterval( f
);
1224 if( pResultSet
->getPropertyState( nHandleBegin
) == STLPropertyState_DIRECT
)
1226 double fBegin
= 0.0;
1227 pResultSet
->getPropertyValue( nHandleBegin
) >>= fBegin
;
1228 if( pEffect
->getBegin() != fBegin
)
1230 pEffect
->setBegin( fBegin
);
1235 if( pResultSet
->getPropertyState( nHandleDuration
) == STLPropertyState_DIRECT
)
1237 if( pEffect
->getDuration() != fDuration
)
1239 pEffect
->setDuration( fDuration
);
1244 if( pResultSet
->getPropertyState( nHandleStart
) == STLPropertyState_DIRECT
)
1246 sal_Int16 nNodeType
= 0;
1247 pResultSet
->getPropertyValue( nHandleStart
) >>= nNodeType
;
1248 if( pEffect
->getNodeType() != nNodeType
)
1250 pEffect
->setNodeType( nNodeType
);
1255 if( pResultSet
->getPropertyState( nHandleRepeat
) == STLPropertyState_DIRECT
)
1257 Any
aRepeatCount( pResultSet
->getPropertyValue( nHandleRepeat
) );
1258 if( aRepeatCount
!= pEffect
->getRepeatCount() )
1260 pEffect
->setRepeatCount( aRepeatCount
);
1265 if( pResultSet
->getPropertyState( nHandleEnd
) == STLPropertyState_DIRECT
)
1267 Any
aEndValue( pResultSet
->getPropertyValue( nHandleEnd
) );
1268 if( pEffect
->getEnd() != aEndValue
)
1270 pEffect
->setEnd( aEndValue
);
1275 if( pResultSet
->getPropertyState( nHandleRewind
) == STLPropertyState_DIRECT
)
1277 sal_Int16 nFill
= 0;
1278 pResultSet
->getPropertyValue( nHandleRewind
) >>= nFill
;
1279 if( pEffect
->getFill() != nFill
)
1281 pEffect
->setFill( nFill
);
1286 if( pResultSet
->getPropertyState( nHandleHasAfterEffect
) == STLPropertyState_DIRECT
)
1288 bool bHasAfterEffect
= false;
1289 if( pResultSet
->getPropertyValue( nHandleHasAfterEffect
) >>= bHasAfterEffect
)
1291 if( pEffect
->hasAfterEffect() != bHasAfterEffect
)
1293 pEffect
->setHasAfterEffect( bHasAfterEffect
);
1299 if( pResultSet
->getPropertyState( nHandleAfterEffectOnNextEffect
) == STLPropertyState_DIRECT
)
1301 bool bAfterEffectOnNextEffect
= false;
1302 if( (pResultSet
->getPropertyValue( nHandleAfterEffectOnNextEffect
) >>= bAfterEffectOnNextEffect
)
1303 && (pEffect
->IsAfterEffectOnNext() != bAfterEffectOnNextEffect
) )
1305 pEffect
->setAfterEffectOnNext( bAfterEffectOnNextEffect
);
1310 if( pResultSet
->getPropertyState( nHandleDimColor
) == STLPropertyState_DIRECT
)
1312 Any
aDimColor( pResultSet
->getPropertyValue( nHandleDimColor
) );
1313 if( pEffect
->getDimColor() != aDimColor
)
1315 pEffect
->setDimColor( aDimColor
);
1320 if( pResultSet
->getPropertyState( nHandleAccelerate
) == STLPropertyState_DIRECT
)
1322 double fAccelerate
= 0.0;
1323 pResultSet
->getPropertyValue( nHandleAccelerate
) >>= fAccelerate
;
1324 if( pEffect
->getAcceleration() != fAccelerate
)
1326 pEffect
->setAcceleration( fAccelerate
);
1331 if( pResultSet
->getPropertyState( nHandleDecelerate
) == STLPropertyState_DIRECT
)
1333 double fDecelerate
= 0.0;
1334 pResultSet
->getPropertyValue( nHandleDecelerate
) >>= fDecelerate
;
1335 if( pEffect
->getDecelerate() != fDecelerate
)
1337 pEffect
->setDecelerate( fDecelerate
);
1342 if( pResultSet
->getPropertyState( nHandleAutoReverse
) == STLPropertyState_DIRECT
)
1344 bool bAutoReverse
= false;
1345 pResultSet
->getPropertyValue( nHandleAutoReverse
) >>= bAutoReverse
;
1346 if( pEffect
->getAutoReverse() != bAutoReverse
)
1348 pEffect
->setAutoReverse( bAutoReverse
);
1353 if( pResultSet
->getPropertyState( nHandleProperty1Value
) == STLPropertyState_DIRECT
)
1355 sal_Int32 nType
= 0;
1356 pOldSet
->getPropertyValue( nHandleProperty1Type
) >>= nType
;
1358 bChanged
|= setProperty1Value( nType
, pEffect
, pResultSet
->getPropertyValue( nHandleProperty1Value
) );
1361 if( pResultSet
->getPropertyState( nHandleSoundURL
) == STLPropertyState_DIRECT
)
1363 const Any
aSoundSource( pResultSet
->getPropertyValue( nHandleSoundURL
) );
1365 if( aSoundSource
.getValueType() == ::cppu::UnoType
<sal_Bool
>::get() )
1367 pEffect
->setStopAudio();
1373 aSoundSource
>>= aSoundURL
;
1375 if( !aSoundURL
.isEmpty() )
1377 if( !pEffect
->getAudio().is() )
1379 pEffect
->createAudio( aSoundSource
);
1384 if( pEffect
->getAudio()->getSource() != aSoundSource
)
1386 pEffect
->getAudio()->setSource( aSoundSource
);
1393 if( pEffect
->getAudio().is() || pEffect
->getStopAudio() )
1395 pEffect
->removeAudio();
1402 if( pResultSet
->getPropertyState( nHandleTrigger
) == STLPropertyState_DIRECT
)
1404 Reference
< XShape
> xTriggerShape
;
1405 pResultSet
->getPropertyValue( nHandleTrigger
) >>= xTriggerShape
;
1406 bChanged
|= mpMainSequence
->setTrigger( pEffect
, xTriggerShape
);
1410 const bool bHasTextGrouping
= pResultSet
->getPropertyState( nHandleTextGrouping
) == STLPropertyState_DIRECT
;
1411 const bool bHasAnimateForm
= pResultSet
->getPropertyState( nHandleAnimateForm
) == STLPropertyState_DIRECT
;
1412 const bool bHasTextGroupingAuto
= pResultSet
->getPropertyState( nHandleTextGroupingAuto
) == STLPropertyState_DIRECT
;
1413 const bool bHasTextReverse
= pResultSet
->getPropertyState( nHandleTextReverse
) == STLPropertyState_DIRECT
;
1415 if( bHasTextGrouping
|| bHasAnimateForm
|| bHasTextGroupingAuto
|| bHasTextReverse
)
1417 // we need to do a second pass for text grouping options
1418 // since changing them can cause effects to be removed
1419 // or replaced, we do this after we applied all other options
1422 sal_Int32 nTextGrouping
= 0;
1423 bool bAnimateForm
= true, bTextReverse
= false;
1424 double fTextGroupingAuto
= -1.0;
1426 if( bHasTextGrouping
)
1427 pResultSet
->getPropertyValue(nHandleTextGrouping
) >>= nTextGrouping
;
1429 if( bHasAnimateForm
)
1430 pResultSet
->getPropertyValue(nHandleAnimateForm
) >>= bAnimateForm
;
1432 if( bHasTextGroupingAuto
)
1433 pResultSet
->getPropertyValue(nHandleTextGroupingAuto
) >>= fTextGroupingAuto
;
1435 if( bHasTextReverse
)
1436 pResultSet
->getPropertyValue(nHandleTextReverse
) >>= bTextReverse
;
1438 EffectSequence
const aSelectedEffects( maListSelection
);
1439 EffectSequence::const_iterator
iter( aSelectedEffects
.begin() );
1440 const EffectSequence::const_iterator
iEnd( aSelectedEffects
.end() );
1441 while( iter
!= iEnd
)
1443 CustomAnimationEffectPtr
const& pEffect
= (*iter
++);
1445 EffectSequenceHelper
* pEffectSequence
= pEffect
->getEffectSequence();
1446 if( !pEffectSequence
)
1447 pEffectSequence
= mpMainSequence
.get();
1449 sal_Int32 nGroupId
= pEffect
->getGroupId();
1450 CustomAnimationTextGroupPtr pTextGroup
;
1451 if( (nGroupId
!= -1) )
1453 // use existing group
1454 pTextGroup
= pEffectSequence
->findGroup( nGroupId
);
1458 // somethings changed so we need a group now
1459 pTextGroup
= pEffectSequence
->createTextGroup( pEffect
, nTextGrouping
, fTextGroupingAuto
, bAnimateForm
, bTextReverse
);
1464 /************************************************************************/
1466 Note, the setAnimateForm means set the animation from TextGroup to Object's Shape
1467 And on the UI in means "Animate attached shape" in "Effect Option" dialog
1468 The setTextGrouping means set animation to Object's Text,
1469 the nTextGrouping is Text Animation Type
1470 nTextGrouping = -1 is "As one Object", means no text animation.
1472 The previous call order first do the setTextGrouping and then do the setAnimateForm,
1473 that will cause such defect: in the setTextGrouping, the effect has been removed,
1474 but in setAnimateForm still need this effect, then a NULL pointer of that effect will
1475 be gotten, and cause crash.
1477 []bHasAnimateForm means the UI has changed, bAnimateForm is it value
1479 So if create a new textgroup animation, the following animation will never be run!
1480 Since the \A1\B0Animate attached shape\A1\B1 is default checked.
1481 And the bHasAnimateForm default is false, and if user uncheck it the value bAnimateForm will be false,
1482 it same as the TextGroup\A1\AFs default value, also could not be run setAnimateForm.
1483 if( bHasAnimateForm )
1485 if( pTextGroup->getAnimateForm() != bAnimateForm )
1487 pEffectSequence->setAnimateForm( pTextGroup, bAnimateForm );
1492 In setTextGrouping, there are three case:
1493 1. Create new text effects for empty TextGroup
1494 2. Remove all text effects of TextGroup (nTextGrouping == -1)
1495 3. Change all the text effects\A1\AF start type
1497 So here is the right logic:
1498 If set the animation from text to shape and remove text animation,
1499 should do setAnimateForm first, then do setTextGrouping.
1500 Other case,do setTextGrouping first, then do setAnimateForm.
1503 /************************************************************************/
1505 bool bDoSetAnimateFormFirst
= false;
1506 bool bNeedDoSetAnimateForm
= false;
1508 if( bHasAnimateForm
)
1510 if( pTextGroup
.get() && pTextGroup
->getAnimateForm() != bAnimateForm
)
1512 if( (pTextGroup
->getTextGrouping() >= 0) && (nTextGrouping
== -1 ) )
1514 bDoSetAnimateFormFirst
= true;
1516 bNeedDoSetAnimateForm
= true;
1520 if (bDoSetAnimateFormFirst
)
1522 pEffectSequence
->setAnimateForm( pTextGroup
, bAnimateForm
);
1526 if( bHasTextGrouping
)
1528 if( pTextGroup
.get() && pTextGroup
->getTextGrouping() != nTextGrouping
)
1530 pEffectSequence
->setTextGrouping( pTextGroup
, nTextGrouping
);
1535 if (!bDoSetAnimateFormFirst
&& bNeedDoSetAnimateForm
)
1537 if( pTextGroup
.get() )
1539 pEffectSequence
->setAnimateForm( pTextGroup
, bAnimateForm
);
1544 if( bHasTextGroupingAuto
)
1546 if( pTextGroup
.get() && pTextGroup
->getTextGroupingAuto() != fTextGroupingAuto
)
1548 pEffectSequence
->setTextGroupingAuto( pTextGroup
, fTextGroupingAuto
);
1553 if( bHasTextReverse
)
1555 if( pTextGroup
.get() && pTextGroup
->getTextReverse() != bTextReverse
)
1557 pEffectSequence
->setTextReverse( pTextGroup
, bTextReverse
);
1566 mpMainSequence
->rebuild();
1568 mrBase
.GetDocShell()->SetModified();
1572 void CustomAnimationPane::showOptions(const OString
& sPage
)
1574 STLPropertySet
* pSet
= createSelectionSet();
1576 VclPtrInstance
< CustomAnimationDialog
> pDlg(this, pSet
, sPage
);
1577 if( pDlg
->Execute() )
1580 changeSelection( pDlg
->getResultSet(), pSet
);
1585 void CustomAnimationPane::onChangeCurrentPage()
1587 if( mxView
.is() ) try
1589 Reference
< XDrawPage
> xNewPage( mxView
->getCurrentPage() );
1590 if( xNewPage
!= mxCurrentPage
)
1592 mxCurrentPage
= xNewPage
;
1593 SdPage
* pPage
= SdPage::getImplementation( mxCurrentPage
);
1596 mpMainSequence
= pPage
->getMainSequence();
1597 mpCustomAnimationList
->update( mpMainSequence
);
1604 OSL_FAIL( "sd::CustomAnimationPane::onChangeCurrentPage(), exception caught!" );
1608 bool getTextSelection( const Any
& rSelection
, Reference
< XShape
>& xShape
, std::list
< sal_Int16
>& rParaList
)
1610 Reference
< XTextRange
> xSelectedText
;
1611 rSelection
>>= xSelectedText
;
1612 if( xSelectedText
.is() ) try
1614 xShape
.set( xSelectedText
->getText(), UNO_QUERY_THROW
);
1616 Reference
< XTextRangeCompare
> xTextRangeCompare( xShape
, UNO_QUERY_THROW
);
1617 Reference
< XEnumerationAccess
> xParaEnumAccess( xShape
, UNO_QUERY_THROW
);
1618 Reference
< XEnumeration
> xParaEnum( xParaEnumAccess
->createEnumeration(), UNO_QUERY_THROW
);
1619 Reference
< XTextRange
> xRange
;
1620 Reference
< XTextRange
> xStart( xSelectedText
->getStart() );
1621 Reference
< XTextRange
> xEnd( xSelectedText
->getEnd() );
1623 if( xTextRangeCompare
->compareRegionEnds( xStart
, xEnd
) < 0 )
1625 Reference
< XTextRange
> xTemp( xStart
);
1630 sal_Int16 nPara
= 0;
1631 while( xParaEnum
->hasMoreElements() )
1633 xParaEnum
->nextElement() >>= xRange
;
1635 // break if start of selection is prior to end of current paragraph
1636 if( xRange
.is() && (xTextRangeCompare
->compareRegionEnds( xStart
, xRange
) >= 0 ) )
1642 while( xRange
.is() )
1644 if( xRange
.is() && !xRange
->getString().isEmpty() )
1645 rParaList
.push_back( nPara
);
1647 // break if end of selection is before or at end of current paragraph
1648 if( xRange
.is() && xTextRangeCompare
->compareRegionEnds( xEnd
, xRange
) >= 0 )
1653 if( xParaEnum
->hasMoreElements() )
1654 xParaEnum
->nextElement() >>= xRange
;
1663 OSL_FAIL( "sd::CustomAnimationPane::getTextSelection(), exception caught!" );
1669 void CustomAnimationPane::onChange( bool bCreate
)
1671 bool bHasText
= true;
1673 // first create vector of targets for dialog preview
1674 std::vector
< Any
> aTargets
;
1676 double fDuration
= 2.0f
;
1680 // gather shapes from the selection
1681 Reference
< XSelectionSupplier
> xSel( mxView
, UNO_QUERY_THROW
);
1682 maViewSelection
= xSel
->getSelection();
1684 if( maViewSelection
.getValueType() == cppu::UnoType
<XShapes
>::get())
1686 Reference
< XIndexAccess
> xShapes
;
1687 maViewSelection
>>= xShapes
;
1689 sal_Int32 nCount
= xShapes
->getCount();
1691 for( nIndex
= 0; nIndex
< nCount
; nIndex
++ )
1693 Any
aTarget( xShapes
->getByIndex( nIndex
) );
1694 aTargets
.push_back( aTarget
);
1697 Reference
< XText
> xText
;
1699 if( !xText
.is() || xText
->getString().isEmpty() )
1704 else if ( maViewSelection
.getValueType() == cppu::UnoType
<XShape
>::get())
1706 aTargets
.push_back( maViewSelection
);
1707 Reference
< XText
> xText
;
1708 maViewSelection
>>= xText
;
1709 if( !xText
.is() || xText
->getString().isEmpty() )
1712 else if ( maViewSelection
.getValueType() == cppu::UnoType
<XTextCursor
>::get())
1714 Reference
< XShape
> xShape
;
1715 std::list
< sal_Int16
> aParaList
;
1716 if( getTextSelection( maViewSelection
, xShape
, aParaList
) )
1718 ParagraphTarget aParaTarget
;
1719 aParaTarget
.Shape
= xShape
;
1721 std::list
< sal_Int16
>::iterator
aIter( aParaList
.begin() );
1722 for( ; aIter
!= aParaList
.end(); ++aIter
)
1724 aParaTarget
.Paragraph
= (*aIter
);
1725 aTargets
.push_back( makeAny( aParaTarget
) );
1731 OSL_FAIL("sd::CustomAnimationPane::onChange(), unknown view selection!" );
1737 // get selected effect
1738 EffectSequence::iterator
aIter( maListSelection
.begin() );
1739 const EffectSequence::iterator
aEnd( maListSelection
.end() );
1740 while( aIter
!= aEnd
)
1742 if( !bHasText
|| !(*aIter
)->hasText() )
1745 if( sPresetId
.isEmpty() )
1747 sPresetId
= (*aIter
)->getPresetId();
1748 fDuration
= (*aIter
)->getDuration();
1751 aTargets
.push_back( (*aIter
++)->getTarget() );
1756 ScopedVclPtrInstance
< CustomAnimationCreateDialog
> pDlg( this, this, aTargets
, bHasText
, sPresetId
, fDuration
);
1757 if( pDlg
->Execute() )
1760 fDuration
= pDlg
->getSelectedDuration();
1761 CustomAnimationPresetPtr pDescriptor
= pDlg
->getSelectedPreset();
1762 if( pDescriptor
.get() )
1766 mpCustomAnimationList
->SelectAll( false );
1768 // gather shapes from the selection
1769 std::vector
< Any
>::iterator
aIter( aTargets
.begin() );
1770 const std::vector
< Any
>::iterator
aEnd( aTargets
.end() );
1772 for( ; aIter
!= aEnd
; ++aIter
)
1774 CustomAnimationEffectPtr pCreated
= mpMainSequence
->append( pDescriptor
, (*aIter
), fDuration
);
1776 // if only one shape with text and no fill or outline is selected, animate only by first level paragraphs
1777 if( bHasText
&& (aTargets
.size() == 1) )
1779 Reference
< XShape
> xShape( (*aIter
), UNO_QUERY
);
1780 if( xShape
.is() && !hasVisibleShape( xShape
) )
1782 mpMainSequence
->createTextGroup( pCreated
, 1, -1.0, false, false );
1789 pCreated
->setNodeType( EffectNodeType::WITH_PREVIOUS
);
1791 if( pCreated
.get() )
1792 mpCustomAnimationList
->select( pCreated
);
1797 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
1799 // get selected effect
1800 EffectSequence::iterator
aIter( maListSelection
.begin() );
1801 const EffectSequence::iterator
aEnd( maListSelection
.end() );
1802 while( aIter
!= aEnd
)
1804 CustomAnimationEffectPtr pEffect
= (*aIter
++);
1806 EffectSequenceHelper
* pEffectSequence
= pEffect
->getEffectSequence();
1807 if( !pEffectSequence
)
1808 pEffectSequence
= mpMainSequence
.get();
1810 pEffectSequence
->replace( pEffect
, pDescriptor
, fDuration
);
1816 PathKind eKind
= pDlg
->getCreatePathKind();
1817 if( eKind
!= PathKind::NONE
)
1818 createPath( eKind
, aTargets
, fDuration
);
1820 mrBase
.GetDocShell()->SetModified();
1826 // stop running preview from dialog
1827 SlideShow::Stop( mrBase
);
1830 void CustomAnimationPane::createPath( PathKind eKind
, std::vector
< Any
>& rTargets
, double fDuration
)
1832 sal_uInt16 nSID
= 0;
1836 case PathKind::CURVE
: nSID
= SID_DRAW_BEZIER_NOFILL
; break;
1837 case PathKind::POLYGON
: nSID
= SID_DRAW_POLYGON_NOFILL
; break;
1838 case PathKind::FREEFORM
: nSID
= SID_DRAW_FREELINE_NOFILL
; break;
1844 DrawViewShell
* pViewShell
= dynamic_cast< DrawViewShell
* >(
1845 FrameworkHelper::Instance(mrBase
)->GetViewShell(FrameworkHelper::msCenterPaneURL
).get());
1849 DrawView
* pView
= pViewShell
->GetDrawView();
1851 pView
->UnmarkAllObj();
1853 std::vector
< Any
> aTargets( 1, Any( fDuration
) );
1854 aTargets
.insert( aTargets
.end(), rTargets
.begin(), rTargets
.end() );
1855 Sequence
< Any
> aTargetSequence( comphelper::containerToSequence( aTargets
) );
1856 const SfxUnoAnyItem
aItem( SID_ADD_MOTION_PATH
, Any( aTargetSequence
) );
1857 pViewShell
->GetViewFrame()->GetDispatcher()->Execute( nSID
, SfxCallMode::ASYNCHRON
, &aItem
, 0 );
1862 void CustomAnimationPane::onRemove()
1864 if( !maListSelection
.empty() )
1868 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
1870 EffectSequence
aList( maListSelection
);
1872 EffectSequence::iterator
aIter( aList
.begin() );
1873 const EffectSequence::iterator
aEnd( aList
.end() );
1874 while( aIter
!= aEnd
)
1876 CustomAnimationEffectPtr pEffect
= (*aIter
++);
1877 if( pEffect
->getEffectSequence() )
1878 pEffect
->getEffectSequence()->remove( pEffect
);
1881 maListSelection
.clear();
1882 mrBase
.GetDocShell()->SetModified();
1886 void CustomAnimationPane::remove( CustomAnimationEffectPtr
& pEffect
)
1888 if( pEffect
->getEffectSequence() )
1891 pEffect
->getEffectSequence()->remove( pEffect
);
1892 mrBase
.GetDocShell()->SetModified();
1896 void CustomAnimationPane::onChangeStart()
1898 if( mpLBStart
->GetSelectEntryCount() == 1 )
1900 sal_Int16 nNodeType
;
1901 sal_uInt16 nPos
= mpLBStart
->GetSelectEntryPos();
1904 case 0: nNodeType
= EffectNodeType::ON_CLICK
; break;
1905 case 1: nNodeType
= EffectNodeType::WITH_PREVIOUS
; break;
1906 case 2: nNodeType
= EffectNodeType::AFTER_PREVIOUS
; break;
1911 onChangeStart( nNodeType
);
1915 void CustomAnimationPane::onChangeStart( sal_Int16 nNodeType
)
1919 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
1921 bool bNeedRebuild
= false;
1923 EffectSequence::iterator
aIter( maListSelection
.begin() );
1924 const EffectSequence::iterator
aEnd( maListSelection
.end() );
1925 while( aIter
!= aEnd
)
1927 CustomAnimationEffectPtr pEffect
= (*aIter
++);
1928 if( pEffect
->getNodeType() != nNodeType
)
1930 pEffect
->setNodeType( nNodeType
);
1931 bNeedRebuild
= true;
1937 mpMainSequence
->rebuild();
1939 mrBase
.GetDocShell()->SetModified();
1943 void CustomAnimationPane::onChangeProperty()
1945 if( mpLBProperty
->getSubControl() )
1949 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
1951 const Any
aValue( mpLBProperty
->getSubControl()->getValue() );
1953 bool bNeedUpdate
= false;
1955 // change selected effect
1956 EffectSequence::iterator
aIter( maListSelection
.begin() );
1957 const EffectSequence::iterator
aEnd( maListSelection
.end() );
1958 while( aIter
!= aEnd
)
1960 CustomAnimationEffectPtr pEffect
= (*aIter
++);
1962 if( setProperty1Value( mnPropertyType
, pEffect
, aValue
) )
1968 mpMainSequence
->rebuild();
1970 mrBase
.GetDocShell()->SetModified();
1977 void CustomAnimationPane::onChangeSpeed()
1979 if( mpCBSpeed
->GetSelectEntryCount() == 1 )
1983 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
1987 sal_uInt16 nPos
= mpCBSpeed
->GetSelectEntryPos();
1991 case 0: fDuration
= 5.0; break;
1992 case 1: fDuration
= 3.0; break;
1993 case 2: fDuration
= 2.0; break;
1994 case 3: fDuration
= 1.0; break;
1995 case 4: fDuration
= 0.5; break;
2000 // change selected effect
2001 EffectSequence::iterator
aIter( maListSelection
.begin() );
2002 const EffectSequence::iterator
aEnd( maListSelection
.end() );
2003 while( aIter
!= aEnd
)
2005 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2006 pEffect
->setDuration( fDuration
);
2009 mpMainSequence
->rebuild();
2011 mrBase
.GetDocShell()->SetModified();
2017 /// this link is called when the property box is modified by the user
2018 IMPL_LINK_NOARG(CustomAnimationPane
, implPropertyHdl
)
2024 /// this link is called when one of the controls is modified
2025 IMPL_LINK( CustomAnimationPane
, implControlHdl
, Control
*, pControl
)
2027 if( pControl
== mpPBAddEffect
)
2029 else if( pControl
== mpPBChangeEffect
)
2031 else if( pControl
== mpPBRemoveEffect
)
2033 else if( pControl
== mpLBStart
)
2035 else if( pControl
== mpCBSpeed
)
2037 else if( pControl
== mpPBPropertyMore
)
2039 else if( pControl
== mpPBMoveUp
)
2040 moveSelection( true );
2041 else if( pControl
== mpPBMoveDown
)
2042 moveSelection( false );
2043 else if( pControl
== mpPBPlay
)
2045 else if( pControl
== mpCBAutoPreview
)
2047 SdOptions
* pOptions
= SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS
);
2048 pOptions
->SetPreviewChangedEffects( mpCBAutoPreview
->IsChecked() );
2056 IMPL_LINK_NOARG_TYPED(CustomAnimationPane
, lateInitCallback
, Timer
*, void)
2058 // Call getPresets() to initiate the (expensive) construction of the
2062 // update selection and control states
2063 onSelectionChanged();
2066 void CustomAnimationPane::moveSelection( bool bUp
)
2068 if( maListSelection
.empty() )
2071 EffectSequenceHelper
* pSequence
= maListSelection
.front()->getEffectSequence();
2072 if( pSequence
== 0 )
2077 bool bChanged
= false;
2079 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
2080 EffectSequence
& rEffectSequence
= pSequence
->getSequence();
2084 EffectSequence::iterator
aIter( maListSelection
.begin() );
2085 const EffectSequence::iterator
aEnd( maListSelection
.end() );
2087 while( aIter
!= aEnd
)
2089 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2091 EffectSequence::iterator
aUpEffectPos( pSequence
->find( pEffect
) );
2092 if( aUpEffectPos
!= rEffectSequence
.end() )
2094 EffectSequence::iterator
aInsertPos( rEffectSequence
.erase( aUpEffectPos
) );
2096 if( aInsertPos
!= rEffectSequence
.begin() )
2099 while( (aInsertPos
!= rEffectSequence
.begin()) && !mpCustomAnimationList
->isExpanded(*aInsertPos
))
2102 rEffectSequence
.insert( aInsertPos
, pEffect
);
2106 rEffectSequence
.push_front( pEffect
);
2114 EffectSequence::reverse_iterator
aIter( maListSelection
.rbegin() );
2115 const EffectSequence::reverse_iterator
aEnd( maListSelection
.rend() );
2117 while( aIter
!= aEnd
)
2119 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2121 EffectSequence::iterator
aDownEffectPos( pSequence
->find( pEffect
) );
2122 if( aDownEffectPos
!= rEffectSequence
.end() )
2124 EffectSequence::iterator
aInsertPos( rEffectSequence
.erase( aDownEffectPos
) );
2126 if( aInsertPos
!= rEffectSequence
.end() )
2129 while( (aInsertPos
!= rEffectSequence
.end()) && !mpCustomAnimationList
->isExpanded(*aInsertPos
))
2132 rEffectSequence
.insert( aInsertPos
, pEffect
);
2136 rEffectSequence
.push_back( pEffect
);
2145 mpMainSequence
->rebuild();
2147 mrBase
.GetDocShell()->SetModified();
2151 void CustomAnimationPane::onPreview( bool bForcePreview
)
2153 if( !bForcePreview
&& !mpCBAutoPreview
->IsChecked() )
2156 if( maListSelection
.empty() )
2158 rtl::Reference
< MotionPathTag
> xMotionPathTag
;
2159 MotionPathTagVector::iterator aIter
;
2160 for( aIter
= maMotionPathTags
.begin(); aIter
!= maMotionPathTags
.end(); ++aIter
)
2162 if( (*aIter
)->isSelected() )
2164 xMotionPathTag
= (*aIter
);
2169 if( xMotionPathTag
.is() )
2171 MainSequencePtr
pSequence( new MainSequence() );
2172 pSequence
->append( xMotionPathTag
->getEffect()->clone() );
2173 preview( pSequence
->getRootNode() );
2177 Reference
< XAnimationNodeSupplier
> xNodeSupplier( mxCurrentPage
, UNO_QUERY
);
2178 if( !xNodeSupplier
.is() )
2181 preview( xNodeSupplier
->getAnimationNode() );
2186 MainSequencePtr
pSequence( new MainSequence() );
2188 EffectSequence::iterator
aIter( maListSelection
.begin() );
2189 const EffectSequence::iterator
aEnd( maListSelection
.end() );
2191 while( aIter
!= aEnd
)
2193 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2194 pSequence
->append( pEffect
->clone() );
2197 preview( pSequence
->getRootNode() );
2201 void CustomAnimationPane::preview( const Reference
< XAnimationNode
>& xAnimationNode
)
2203 Reference
< XParallelTimeContainer
> xRoot
= ParallelTimeContainer::create( ::comphelper::getProcessComponentContext() );
2204 Sequence
< ::com::sun::star::beans::NamedValue
> aUserData( 1 );
2205 aUserData
[0].Name
= "node-type";
2206 aUserData
[0].Value
<<= ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT
;
2207 xRoot
->setUserData( aUserData
);
2208 xRoot
->appendChild( xAnimationNode
);
2210 SlideShow::StartPreview( mrBase
, mxCurrentPage
, xRoot
);
2213 // ICustomAnimationListController
2214 void CustomAnimationPane::onSelect()
2216 maListSelection
= mpCustomAnimationList
->getSelection();
2218 markShapesFromSelectedEffects();
2221 const CustomAnimationPresets
& CustomAnimationPane::getPresets()
2223 if (mpCustomAnimationPresets
== NULL
)
2224 mpCustomAnimationPresets
= &CustomAnimationPresets::getCustomAnimationPresets();
2225 return *mpCustomAnimationPresets
;
2228 void CustomAnimationPane::markShapesFromSelectedEffects()
2230 if( !maSelectionLock
.isLocked() )
2232 ScopeLockGuard
aGuard( maSelectionLock
);
2233 DrawViewShell
* pViewShell
= dynamic_cast< DrawViewShell
* >(
2234 FrameworkHelper::Instance(mrBase
)->GetViewShell(FrameworkHelper::msCenterPaneURL
).get());
2235 DrawView
* pView
= pViewShell
? pViewShell
->GetDrawView() : NULL
;
2239 pView
->UnmarkAllObj();
2240 EffectSequence::iterator
aIter( maListSelection
.begin() );
2241 const EffectSequence::iterator
aEnd( maListSelection
.end() );
2242 while( aIter
!= aEnd
)
2244 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2246 Reference
< XShape
> xShape( pEffect
->getTargetShape() );
2247 SdrObject
* pObj
= GetSdrObjectFromXShape( xShape
);
2249 pView
->MarkObj(pObj
, pView
->GetSdrPageView(), false, false);
2255 void CustomAnimationPane::updatePathFromMotionPathTag( const rtl::Reference
< MotionPathTag
>& xTag
)
2257 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
2260 SdrPathObj
* pPathObj
= xTag
->getPathObj();
2261 CustomAnimationEffectPtr pEffect
= xTag
->getEffect();
2262 if( (pPathObj
!= 0) && pEffect
.get() != 0 )
2264 ::svl::IUndoManager
* pManager
= mrBase
.GetDocShell()->GetUndoManager();
2267 SdPage
* pPage
= SdPage::getImplementation( mxCurrentPage
);
2269 pManager
->AddUndoAction( new UndoAnimationPath( mrBase
.GetDocShell()->GetDoc(), pPage
, pEffect
->getNode() ) );
2272 pEffect
->updatePathFromSdrPathObj( *pPathObj
);
2277 vcl::Window
* createCustomAnimationPanel( vcl::Window
* pParent
, ViewShellBase
& rBase
, const css::uno::Reference
<css::frame::XFrame
>& rxFrame
)
2279 vcl::Window
* pWindow
= 0;
2281 DrawDocShell
* pDocSh
= rBase
.GetDocShell();
2284 const Size
aMinSize( pParent
->LogicToPixel( Size( 80, 256 ), MAP_APPFONT
) );
2285 pWindow
= VclPtr
<CustomAnimationPane
>::Create( pParent
, rBase
, rxFrame
, aMinSize
);
2293 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */