1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: CustomAnimationPane.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include <com/sun/star/presentation/EffectPresetClass.hpp>
35 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
36 #include <com/sun/star/view/XSelectionSupplier.hpp>
37 #include <com/sun/star/drawing/XDrawView.hpp>
38 #include <com/sun/star/drawing/XShape.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/presentation/EffectNodeType.hpp>
41 #include <com/sun/star/presentation/EffectCommands.hpp>
42 #include <com/sun/star/animations/AnimationTransformType.hpp>
43 #include <com/sun/star/text/XTextRangeCompare.hpp>
44 #include <com/sun/star/container/XEnumerationAccess.hpp>
45 #include <com/sun/star/container/XIndexAccess.hpp>
46 #include <com/sun/star/presentation/ParagraphTarget.hpp>
47 #include <com/sun/star/text/XText.hpp>
48 #include <com/sun/star/awt/XWindow.hpp>
49 #include <com/sun/star/drawing/LineStyle.hpp>
50 #include <com/sun/star/drawing/FillStyle.hpp>
51 #include <comphelper/processfactory.hxx>
52 #include <sfx2/dispatch.hxx>
53 #include "STLPropertySet.hxx"
54 #include "CustomAnimationPane.hxx"
55 #include "CustomAnimationDialog.hxx"
56 #include "CustomAnimationCreateDialog.hxx"
57 #include "CustomAnimationPane.hrc"
58 #include "CustomAnimation.hrc"
59 #include "CustomAnimationList.hxx"
60 #include <vcl/lstbox.hxx>
61 #include <vcl/fixed.hxx>
63 #include <vcl/button.hxx>
64 #include <vcl/combobox.hxx>
65 #include <vcl/scrbar.hxx>
67 #include <comphelper/sequence.hxx>
68 #include <sfx2/frame.hxx>
70 #include <svx/unoapi.hxx>
71 #include <svx/svxids.hrc>
72 #include <DrawDocShell.hxx>
73 #include <ViewShellBase.hxx>
74 #include "DrawViewShell.hxx"
75 #include "DrawController.hxx"
76 #include "sdresid.hxx"
77 #include "drawview.hxx"
78 #include "slideshow.hxx"
79 #include "undoanim.hxx"
80 #include "optsitem.hxx"
82 #include "framework/FrameworkHelper.hxx"
84 #include "EventMultiplexer.hxx"
85 #include "DialogListBox.hxx"
89 #include "drawdoc.hxx"
95 #include <basegfx/polygon/b2dpolypolygontools.hxx>
96 #include <basegfx/matrix/b2dhommatrix.hxx>
97 #include <basegfx/range/b2drange.hxx>
99 using namespace ::com::sun::star
;
100 using namespace ::com::sun::star::animations
;
101 using namespace ::com::sun::star::presentation
;
102 using namespace ::com::sun::star::text
;
104 using ::rtl::OUString
;
105 using namespace ::com::sun::star::uno
;
106 using namespace ::com::sun::star::drawing
;
107 using ::com::sun::star::view::XSelectionSupplier
;
108 using ::com::sun::star::view::XSelectionChangeListener
;
109 using ::com::sun::star::frame::XController
;
110 using ::com::sun::star::frame::XModel
;
111 using ::com::sun::star::beans::XPropertySet
;
112 using ::com::sun::star::beans::XPropertyChangeListener
;
113 using ::com::sun::star::container::XIndexAccess
;
114 using ::com::sun::star::container::XEnumerationAccess
;
115 using ::com::sun::star::container::XEnumeration
;
116 using ::com::sun::star::text::XText
;
117 using ::sd::framework::FrameworkHelper
;
121 // --------------------------------------------------------------------
123 void fillDurationComboBox( ComboBox
* pBox
)
125 static const double gdVerySlow
= 5.0;
126 static const double gdSlow
= 3.0;
127 static const double gdNormal
= 2.0;
128 static const double gdFast
= 1.0;
129 static const double gdVeryFast
= 0.5;
131 String
aVerySlow( SdResId( STR_CUSTOMANIMATION_DURATION_VERY_SLOW
) );
132 pBox
->SetEntryData( pBox
->InsertEntry( aVerySlow
), (void*)&gdVerySlow
);
134 String
aSlow( SdResId( STR_CUSTOMANIMATION_DURATION_SLOW
) );
135 pBox
->SetEntryData( pBox
->InsertEntry( aSlow
), (void*)&gdSlow
);
137 String
aNormal( SdResId( STR_CUSTOMANIMATION_DURATION_NORMAL
) );
138 pBox
->SetEntryData( pBox
->InsertEntry( aNormal
), (void*)&gdNormal
);
140 String
aFast( SdResId( STR_CUSTOMANIMATION_DURATION_FAST
) );
141 pBox
->SetEntryData( pBox
->InsertEntry( aFast
), (void*)&gdFast
);
143 String
aVeryFast( SdResId( STR_CUSTOMANIMATION_DURATION_VERY_FAST
) );
144 pBox
->SetEntryData( pBox
->InsertEntry( aVeryFast
), (void*)&gdVeryFast
);
147 void fillRepeatComboBox( ComboBox
* pBox
)
149 String
aNone( SdResId( STR_CUSTOMANIMATION_REPEAT_NONE
) );
150 pBox
->SetEntryData( pBox
->InsertEntry( aNone
), (void*)((sal_Int32
)0) );
152 pBox
->SetEntryData( pBox
->InsertEntry( String::CreateFromInt32( 2 ) ), (void*)((sal_Int32
)1) );
153 pBox
->SetEntryData( pBox
->InsertEntry( String::CreateFromInt32( 3 ) ), (void*)((sal_Int32
)3) );
154 pBox
->SetEntryData( pBox
->InsertEntry( String::CreateFromInt32( 4 ) ), (void*)((sal_Int32
)4) );
155 pBox
->SetEntryData( pBox
->InsertEntry( String::CreateFromInt32( 5 ) ), (void*)((sal_Int32
)5) );
156 pBox
->SetEntryData( pBox
->InsertEntry( String::CreateFromInt32( 10 ) ), (void*)((sal_Int32
)10) );
158 String
aUntilClick( SdResId( STR_CUSTOMANIMATION_REPEAT_UNTIL_NEXT_CLICK
) );
159 pBox
->SetEntryData( pBox
->InsertEntry( aUntilClick
), (void*)((sal_Int32
)-1) );
161 String
aEndOfSlide( SdResId( STR_CUSTOMANIMATION_REPEAT_UNTIL_END_OF_SLIDE
) );
162 pBox
->SetEntryData( pBox
->InsertEntry( aEndOfSlide
), (void*)((sal_Int32
)-2) );
165 // --------------------------------------------------------------------
167 CustomAnimationPane::CustomAnimationPane( ::Window
* pParent
, ViewShellBase
& rBase
, const Size
& rMinSize
)
168 : Control( pParent
, SdResId(DLG_CUSTOMANIMATIONPANE
) ),
170 mpCustomAnimationPresets(NULL
),
171 mnPropertyType( nPropertyTypeNone
),
172 maMinSize( rMinSize
),
173 mxModel( rBase
.GetDocShell()->GetDoc()->getUnoModel(), UNO_QUERY
),
177 mpFLEffect
= new FixedLine( this, SdResId( FL_EFFECT
) );
179 mpPBAddEffect
= new PushButton( this, SdResId( PB_ADD_EFFECT
) );
180 mpPBChangeEffect
= new PushButton( this, SdResId( PB_CHANGE_EFFECT
) );
181 mpPBRemoveEffect
= new PushButton( this, SdResId( PB_REMOVE_EFFECT
) );
183 mpFLModify
= new FixedLine( this, SdResId( FL_MODIFY
) );
185 mpFTStart
= new FixedText( this, SdResId( FT_START
) );
186 mpLBStart
= new ListBox( this, SdResId( LB_START
) );
187 mpFTProperty
= new FixedText( this, SdResId( FT_PROPERTY
) );
188 mpLBProperty
= new PropertyControl( this, SdResId( LB_PROPERTY
) );
189 mpPBPropertyMore
= new PushButton( this, SdResId( PB_PROPERTY_MORE
) );
191 mpFTSpeed
= new FixedText( this, SdResId( FT_SPEED
) );
192 mpCBSpeed
= new ComboBox( this, SdResId( CB_SPEED
) );
194 mpCustomAnimationList
= new CustomAnimationList( this, SdResId( CT_CUSTOM_ANIMATION_LIST
), this );
196 mpPBMoveUp
= new PushButton( this, SdResId( PB_MOVE_UP
) );
197 mpPBMoveDown
= new PushButton( this, SdResId( PB_MOVE_DOWN
) );
198 mpFTChangeOrder
= new FixedText( this, SdResId( FT_CHANGE_ORDER
) );
199 mpFLSeperator1
= new FixedLine( this, SdResId( FL_SEPERATOR1
) );
200 mpPBPlay
= new PushButton( this, SdResId( PB_PLAY
) );
201 mpPBSlideShow
= new PushButton( this, SdResId( PB_SLIDE_SHOW
) );
202 mpFLSeperator2
= new FixedLine( this, SdResId( FL_SEPERATOR2
) );
203 mpCBAutoPreview
= new CheckBox( this, SdResId( CB_AUTOPREVIEW
) );
205 maStrProperty
= mpFTProperty
->GetText();
209 // use bold font for group headings (same font for all fixed lines):
210 Font
font( mpFLEffect
->GetFont() );
211 font
.SetWeight( WEIGHT_BOLD
);
212 mpFLEffect
->SetFont( font
);
213 mpFLModify
->SetFont( font
);
215 fillDurationComboBox( mpCBSpeed
);
216 mpPBMoveUp
->SetSymbol( SYMBOL_ARROW_UP
);
217 mpPBMoveDown
->SetSymbol( SYMBOL_ARROW_DOWN
);
219 mpPBAddEffect
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
220 mpPBChangeEffect
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
221 mpPBRemoveEffect
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
222 mpLBStart
->SetSelectHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
223 mpCBSpeed
->SetSelectHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
224 mpPBPropertyMore
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
225 mpPBMoveUp
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
226 mpPBMoveDown
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
227 mpPBPlay
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
228 mpPBSlideShow
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
229 mpCBAutoPreview
->SetClickHdl( LINK( this, CustomAnimationPane
, implControlHdl
) );
231 maStrModify
= mpFLEffect
->GetText();
233 // resize controls according to current size
236 // get current controller and initialize listeners
239 mxView
= Reference
< XDrawView
>::query(mrBase
.GetController());
242 catch( Exception
& e
)
245 DBG_ERROR( "sd::CustomAnimationPane::CustomAnimationPane(), Exception cought!" );
248 // get current page and update custom animation list
249 onChangeCurrentPage();
251 // Wait a short time before the presets list is created. This gives the
252 // system time to paint the control.
253 maLateInitTimer
.SetTimeout(100);
254 maLateInitTimer
.SetTimeoutHdl(LINK(this, CustomAnimationPane
, lateInitCallback
));
255 maLateInitTimer
.Start();
258 CustomAnimationPane::~CustomAnimationPane()
260 maLateInitTimer
.Stop();
264 MotionPathTagVector aTags
;
265 aTags
.swap( maMotionPathTags
);
266 MotionPathTagVector::iterator aIter
;
267 for( aIter
= aTags
.begin(); aIter
!= aTags
.end(); aIter
++ )
271 delete mpPBAddEffect
;
272 delete mpPBChangeEffect
;
273 delete mpPBRemoveEffect
;
279 delete mpPBPropertyMore
;
282 delete mpCustomAnimationList
;
283 delete mpFTChangeOrder
;
286 delete mpFLSeperator1
;
288 delete mpPBSlideShow
;
289 delete mpFLSeperator2
;
290 delete mpCBAutoPreview
;
293 void CustomAnimationPane::addUndo()
295 SfxUndoManager
* pManager
= mrBase
.GetDocShell()->GetUndoManager();
298 SdPage
* pPage
= SdPage::getImplementation( mxCurrentPage
);
300 pManager
->AddUndoAction( new UndoAnimation( mrBase
.GetDocShell()->GetDoc(), pPage
) );
304 void CustomAnimationPane::Resize()
309 void CustomAnimationPane::StateChanged( StateChangedType nStateChange
)
311 Control::StateChanged( nStateChange
);
313 if( nStateChange
== STATE_CHANGE_VISIBLE
)
314 updateMotionPathTags();
317 void CustomAnimationPane::KeyInput( const KeyEvent
& rKEvt
)
319 if( mpCustomAnimationList
)
320 mpCustomAnimationList
->KeyInput( rKEvt
);
323 void CustomAnimationPane::addListener()
325 Link
aLink( LINK(this,CustomAnimationPane
,EventMultiplexerListener
) );
326 mrBase
.GetEventMultiplexer()->AddEventListener (
328 tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
329 | tools::EventMultiplexerEvent::EID_CURRENT_PAGE
330 | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
331 | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
332 | tools::EventMultiplexerEvent::EID_DISPOSING
333 | tools::EventMultiplexerEvent::EID_END_TEXT_EDIT
);
336 void CustomAnimationPane::removeListener()
338 Link
aLink( LINK(this,CustomAnimationPane
,EventMultiplexerListener
) );
339 mrBase
.GetEventMultiplexer()->RemoveEventListener( aLink
);
342 IMPL_LINK(CustomAnimationPane
,EventMultiplexerListener
,
343 tools::EventMultiplexerEvent
*,pEvent
)
345 switch (pEvent
->meEventId
)
347 case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
:
348 onSelectionChanged();
351 case tools::EventMultiplexerEvent::EID_CURRENT_PAGE
:
352 onChangeCurrentPage();
355 case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
:
356 // At this moment the controller may not yet been set at model
357 // or ViewShellBase. Take it from the view shell passed with
359 if (mrBase
.GetMainViewShell() != NULL
)
361 if( mrBase
.GetMainViewShell()->GetShellType() == ViewShell::ST_IMPRESS
)
363 mxView
= Reference
<XDrawView
>::query(mrBase
.GetDrawController());
364 onSelectionChanged();
365 onChangeCurrentPage();
369 // fall through intended
370 case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
:
376 case tools::EventMultiplexerEvent::EID_DISPOSING
:
377 mxView
= Reference
<XDrawView
>();
378 onSelectionChanged();
379 onChangeCurrentPage();
381 case tools::EventMultiplexerEvent::EID_END_TEXT_EDIT
:
382 if( mpMainSequence
.get() && pEvent
->mpUserData
)
383 mpCustomAnimationList
->update( mpMainSequence
);
390 void CustomAnimationPane::updateLayout()
392 Size
aPaneSize( GetSizePixel() );
393 if( aPaneSize
.Width() < maMinSize
.Width() )
394 aPaneSize
.Width() = maMinSize
.Width();
396 if( aPaneSize
.Height() < maMinSize
.Height() )
397 aPaneSize
.Height() = maMinSize
.Height();
399 Point
aOffset( LogicToPixel( Point(3,3), MAP_APPFONT
) );
400 Point
aCursor( aOffset
);
402 // place the modify fixed line
404 // place the "modify effect" fixed line
405 Size
aSize( mpFLModify
->GetSizePixel() );
406 aSize
.Width() = aPaneSize
.Width() - 2 * aOffset
.X();
408 mpFLModify
->SetPosSizePixel( aCursor
, aSize
);
410 aCursor
.Y() += aSize
.Height() + aOffset
.Y();
412 const int nButtonExtraWidth
= 4 * aOffset
.X();
414 // the "add effect" button is placed top-left
415 Size
aCtrlSize( mpPBAddEffect
->GetSizePixel() );
416 aCtrlSize
.setWidth( mpPBAddEffect
->CalcMinimumSize( aSize
.Width() ).getWidth() + nButtonExtraWidth
);
417 mpPBAddEffect
->SetPosSizePixel( aCursor
, aCtrlSize
);
419 aCursor
.X() += aOffset
.X() + aCtrlSize
.Width();
421 // place the "change effect" button
423 // if the "change" button does not fit right of the "add effect", put it on the next line
424 aCtrlSize
= mpPBChangeEffect
->GetSizePixel();
425 aCtrlSize
.setWidth( mpPBChangeEffect
->CalcMinimumSize( aSize
.Width() ).getWidth() + nButtonExtraWidth
);
426 if( ( aCursor
.X() + aCtrlSize
.Width() + aOffset
.X() ) > aPaneSize
.Width() )
428 aCursor
.X() = aOffset
.X();
429 aCursor
.Y() += aCtrlSize
.Height() + aOffset
.Y();
431 mpPBChangeEffect
->SetPosSizePixel( aCursor
, aCtrlSize
);
433 aCursor
.X() += aOffset
.X() + aCtrlSize
.Width();
435 // place the "remove effect" button
437 // if the "remove" button does not fit right of the "add effect", put it on the next line
438 aCtrlSize
= mpPBRemoveEffect
->GetSizePixel();
439 aCtrlSize
.setWidth( mpPBRemoveEffect
->CalcMinimumSize( aSize
.Width() ).getWidth() + nButtonExtraWidth
);
440 if( ( aCursor
.X() + aCtrlSize
.Width() + aOffset
.X() ) > aPaneSize
.Width() )
442 aCursor
.X() = aOffset
.X();
443 aCursor
.Y() += aCtrlSize
.Height() + aOffset
.Y();
446 mpPBRemoveEffect
->SetPosSizePixel( aCursor
, aCtrlSize
);
448 aCursor
.X() = aOffset
.X();
449 aCursor
.Y() += aCtrlSize
.Height() + 2 * aOffset
.Y();
451 // place the "modify effect" fixed line
452 aSize
= mpFLEffect
->GetSizePixel();
453 aSize
.Width() = aPaneSize
.Width() - 2 * aOffset
.X();
455 mpFLEffect
->SetPosSizePixel( aCursor
, aSize
);
457 aCursor
.Y() += aSize
.Height() + aOffset
.Y();
459 // ---------------------------------------------------------------------------
460 // place the properties controls
462 // calc minimum width for fixedtext
464 Size
aFixedTextSize( mpFTStart
->CalcMinimumSize() );
465 long nWidth
= aFixedTextSize
.Width();
466 aFixedTextSize
= mpFTProperty
->CalcMinimumSize();
467 nWidth
= std::max( nWidth
, aFixedTextSize
.Width() );
468 aFixedTextSize
= mpFTSpeed
->CalcMinimumSize();
469 aFixedTextSize
.Width() = std::max( nWidth
, aFixedTextSize
.Width() ) + aOffset
.X();
470 mpFTStart
->SetSizePixel(aFixedTextSize
);
471 mpFTProperty
->SetSizePixel(aFixedTextSize
);
472 mpFTSpeed
->SetSizePixel(aFixedTextSize
);
474 aSize
= mpPBPropertyMore
->GetSizePixel();
476 // place the "start" fixed text
478 Point
aFTPos( aCursor
);
479 Point
aLBPos( aCursor
);
480 Size
aListBoxSize( LogicToPixel( Size( 60, 12 ), MAP_APPFONT
) );
481 long nDeltaY
= aListBoxSize
.Height() + aOffset
.Y();
484 if( (aFixedTextSize
.Width() + aListBoxSize
.Width() + aSize
.Width() + 4 * aOffset
.X()) > aPaneSize
.Width() )
486 // y position for list box is below fixed text
487 aLBPos
.Y() += aFixedTextSize
.Height() + aOffset
.Y();
489 // height of fixed text + list box + something = 2 * list box
490 nDeltaY
= aListBoxSize
.Height() + aFixedTextSize
.Height() + 2*aOffset
.Y();
494 // x position for list box is right of fixed text
495 aLBPos
.X() += aFixedTextSize
.Width() + aOffset
.X();
497 if( aListBoxSize
.Height() > aFixedTextSize
.Height() )
498 aFTPos
.Y() = aLBPos
.Y() + ((aListBoxSize
.Height() - aFixedTextSize
.Height()) >> 1);
500 aLBPos
.Y() = aFTPos
.Y() + ((aFixedTextSize
.Height() - aListBoxSize
.Height()) >> 1);
503 // width of the listbox is from its left side until end of pane
504 aListBoxSize
.Width() = aPaneSize
.Width() - aLBPos
.X() - aSize
.Width() - 2 * aOffset
.X();
506 mpFTStart
->SetPosPixel( aFTPos
);
507 mpLBStart
->SetPosSizePixel( aLBPos
, aListBoxSize
);
509 aFTPos
.Y() += nDeltaY
; aLBPos
.Y() += nDeltaY
;
511 mpFTProperty
->SetPosPixel( aFTPos
);
512 mpLBProperty
->SetPosSizePixel( aLBPos
, aListBoxSize
);
513 mpLBProperty
->Resize();
515 Point
aMorePos( aLBPos
);
516 aMorePos
.X() += aListBoxSize
.Width() + aOffset
.X();
517 mpPBPropertyMore
->SetPosPixel( aMorePos
);
519 aFTPos
.Y() += nDeltaY
; aLBPos
.Y() += nDeltaY
;
521 mpFTSpeed
->SetPosPixel( aFTPos
);
522 mpCBSpeed
->SetPosSizePixel( aLBPos
, aListBoxSize
);
524 aFTPos
.Y() += nDeltaY
+ aOffset
.Y();
526 Point
aListPos( aFTPos
);
528 // positionate the buttons on the bottom
530 // place the auto preview checkbox
531 aCursor
= Point( aOffset
.X(), aPaneSize
.Height() - mpCBAutoPreview
->GetSizePixel().Height() - aOffset
.Y() );
532 mpCBAutoPreview
->SetPosPixel( aCursor
);
534 // place the seperator 2 fixed line
535 aCursor
.Y() -= /* aOffset.Y() + */ mpFLSeperator2
->GetSizePixel().Height();
536 aSize
= mpFLSeperator2
->GetSizePixel();
537 aSize
.Width() = aPaneSize
.Width() - 2 * aOffset
.X();
538 mpFLSeperator2
->SetPosSizePixel( aCursor
, aSize
);
540 // next, layout and place the play and slide show buttons
541 aCtrlSize
= mpPBSlideShow
->GetSizePixel();
542 aCtrlSize
.setWidth( mpPBSlideShow
->CalcMinimumSize( aSize
.Width() ).getWidth() + nButtonExtraWidth
);
544 Size
aPlaySize( mpPBPlay
->GetSizePixel() );
545 aPlaySize
.setWidth( mpPBPlay
->CalcMinimumSize( aSize
.Width() ).getWidth() + nButtonExtraWidth
);
547 aCursor
.Y() -= aCtrlSize
.Height() /* + aOffset.Y() */;
549 // do we need two lines for the buttons?
550 int aTestWidth
= aCursor
.X() + mpPBPlay
->GetSizePixel().Width() + 2 * aOffset
.X() + mpPBSlideShow
->GetSizePixel().Width();
551 if( aTestWidth
> aPaneSize
.Width() )
553 mpPBSlideShow
->SetPosSizePixel( aCursor
, aCtrlSize
);
554 aCursor
.Y() -= aCtrlSize
.Height() + aOffset
.Y();
555 mpPBPlay
->SetPosSizePixel( aCursor
, aPlaySize
);
559 mpPBPlay
->SetPosSizePixel( aCursor
, aPlaySize
);
560 aCursor
.X() += aPlaySize
.Width() + aOffset
.X();
561 mpPBSlideShow
->SetPosSizePixel( aCursor
, aCtrlSize
);
564 // place the seperator 1 fixed line
565 aCursor
.X() = aOffset
.X();
566 aCursor
.Y() -= /* aOffset.Y() + */ mpFLSeperator1
->GetSizePixel().Height();
567 aSize
= mpFLSeperator1
->GetSizePixel();
568 aSize
.Width() = aPaneSize
.Width() - 2 * aOffset
.X();
569 mpFLSeperator1
->SetPosSizePixel( aCursor
, aSize
);
571 // place the move down button
572 aSize
= mpPBMoveDown
->GetSizePixel();
574 aCursor
.X() = aPaneSize
.Width() - aOffset
.X() - aSize
.Width();
575 aCursor
.Y() -= aOffset
.Y() + aSize
.Height();
576 mpPBMoveDown
->SetPosPixel( aCursor
);
578 aCursor
.X() -= aOffset
.X() + aSize
.Width();
579 mpPBMoveUp
->SetPosPixel( aCursor
);
581 // Place the change order label.
582 // Its width has to be calculated dynamically so that is can be
583 // displayed flush right without having too much space to the buttons
584 // with some languages or truncated text with others.
585 mpFTChangeOrder
->SetSizePixel(mpFTChangeOrder
->CalcMinimumSize());
587 aCursor
.X() -= aOffset
.X() + mpFTChangeOrder
->GetSizePixel().Width();
588 aCursor
.Y() += (aSize
.Height() - mpFTChangeOrder
->GetSizePixel().Height()) >> 1;
589 mpFTChangeOrder
->SetPosPixel( aCursor
);
591 // positionate the custom animation list control
592 Size
aCustomAnimationListSize( aPaneSize
.Width() - aListPos
.X() - aOffset
.X(), aCursor
.Y() - aListPos
.Y() - 2 * aOffset
.Y() );
593 mpCustomAnimationList
->SetPosSizePixel( aListPos
, aCustomAnimationListSize
);
596 static sal_Int32
getPropertyType( const OUString
& rProperty
)
598 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Direction") ) )
599 return nPropertyTypeDirection
;
601 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Spokes") ) )
602 return nPropertyTypeSpokes
;
604 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Zoom") ) )
605 return nPropertyTypeZoom
;
607 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Accelerate") ) )
608 return nPropertyTypeAccelerate
;
610 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Decelerate") ) )
611 return nPropertyTypeDecelerate
;
613 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Color1") ) )
614 return nPropertyTypeFirstColor
;
616 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Color2") ) )
617 return nPropertyTypeSecondColor
;
619 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FillColor") ) )
620 return nPropertyTypeFillColor
;
622 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ColorStyle") ) )
623 return nPropertyTypeColorStyle
;
625 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AutoReverse") ) )
626 return nPropertyTypeAutoReverse
;
628 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FontStyle") ) )
629 return nPropertyTypeFont
;
631 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CharColor") ) )
632 return nPropertyTypeCharColor
;
634 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CharHeight") ) )
635 return nPropertyTypeCharHeight
;
637 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CharDecoration") ) )
638 return nPropertyTypeCharDecoration
;
640 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("LineColor") ) )
641 return nPropertyTypeLineColor
;
643 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Rotate") ) )
644 return nPropertyTypeRotate
;
646 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Transparency") ) )
647 return nPropertyTypeTransparency
;
649 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Color") ) )
650 return nPropertyTypeColor
;
652 if( rProperty
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Scale") ) )
653 return nPropertyTypeScale
;
655 return nPropertyTypeNone
;
658 OUString
getPropertyName( sal_Int32 nPropertyType
)
660 switch( nPropertyType
)
662 case nPropertyTypeDirection
:
663 return OUString( String( SdResId( STR_CUSTOMANIMATION_DIRECTION_PROPERTY
) ) );
665 case nPropertyTypeSpokes
:
666 return OUString( String( SdResId( STR_CUSTOMANIMATION_SPOKES_PROPERTY
) ) );
668 case nPropertyTypeFirstColor
:
669 return OUString( String( SdResId( STR_CUSTOMANIMATION_FIRST_COLOR_PROPERTY
) ) );
671 case nPropertyTypeSecondColor
:
672 return OUString( String( SdResId( STR_CUSTOMANIMATION_SECOND_COLOR_PROPERTY
) ) );
674 case nPropertyTypeZoom
:
675 return OUString( String( SdResId( STR_CUSTOMANIMATION_ZOOM_PROPERTY
) ) );
677 case nPropertyTypeFillColor
:
678 return OUString( String( SdResId( STR_CUSTOMANIMATION_FILL_COLOR_PROPERTY
) ) );
680 case nPropertyTypeColorStyle
:
681 return OUString( String( SdResId( STR_CUSTOMANIMATION_STYLE_PROPERTY
) ) );
683 case nPropertyTypeFont
:
684 return OUString( String( SdResId( STR_CUSTOMANIMATION_FONT_PROPERTY
) ) );
686 case nPropertyTypeCharHeight
:
687 return OUString( String( SdResId( STR_CUSTOMANIMATION_SIZE_PROPERTY
) ) );
689 case nPropertyTypeCharColor
:
690 return OUString( String( SdResId( STR_CUSTOMANIMATION_FONT_COLOR_PROPERTY
) ) );
692 case nPropertyTypeCharHeightStyle
:
693 return OUString( String( SdResId( STR_CUSTOMANIMATION_FONT_SIZE_STYLE_PROPERTY
) ) );
695 case nPropertyTypeCharDecoration
:
696 return OUString( String( SdResId( STR_CUSTOMANIMATION_FONT_STYLE_PROPERTY
) ) );
698 case nPropertyTypeLineColor
:
699 return OUString( String( SdResId( STR_CUSTOMANIMATION_LINE_COLOR_PROPERTY
) ) );
701 case nPropertyTypeRotate
:
702 return OUString( String( SdResId( STR_CUSTOMANIMATION_AMOUNT_PROPERTY
) ) );
704 case nPropertyTypeColor
:
705 return OUString( String( SdResId( STR_CUSTOMANIMATION_COLOR_PROPERTY
) ) );
707 case nPropertyTypeTransparency
:
708 return OUString( String( SdResId( STR_CUSTOMANIMATION_AMOUNT_PROPERTY
) ) );
710 case nPropertyTypeScale
:
711 return OUString( String( SdResId( STR_CUSTOMANIMATION_SCALE_PROPERTY
) ) );
718 void CustomAnimationPane::updateControls()
720 mpFLModify
->Enable( mxView
.is() );
721 mpFTSpeed
->Enable( mxView
.is() );
722 mpCBSpeed
->Enable( mxView
.is() );
723 mpCustomAnimationList
->Enable( mxView
.is() );
724 mpFTChangeOrder
->Enable( mxView
.is() );
725 mpPBMoveUp
->Enable( mxView
.is() );
726 mpPBMoveDown
->Enable( mxView
.is() );
727 mpFLSeperator1
->Enable( mxView
.is() );
728 mpPBPlay
->Enable( mxView
.is() );
729 mpPBSlideShow
->Enable( mxView
.is() );
730 mpFLSeperator2
->Enable( mxView
.is() );
731 mpCBAutoPreview
->Enable( mxView
.is() );
735 mpPBAddEffect
->Enable( FALSE
);
736 mpPBChangeEffect
->Enable( FALSE
);
737 mpPBRemoveEffect
->Enable( FALSE
);
738 mpFLEffect
->Enable( FALSE
);
739 mpFTStart
->Enable( FALSE
);
740 mpLBStart
->Enable( FALSE
);
741 mpPBPropertyMore
->Enable( FALSE
);
742 mpLBProperty
->Enable( FALSE
);
743 mpFTProperty
->Enable( FALSE
);
744 mpCustomAnimationList
->clear();
748 const int nSelectionCount
= maListSelection
.size();
750 mpPBAddEffect
->Enable( maViewSelection
.hasValue() );
751 mpPBChangeEffect
->Enable( nSelectionCount
);
752 mpPBRemoveEffect
->Enable(nSelectionCount
);
754 mpFLEffect
->Enable(nSelectionCount
> 0);
755 mpFTStart
->Enable(nSelectionCount
> 0);
756 mpLBStart
->Enable(nSelectionCount
> 0);
757 mpPBPropertyMore
->Enable(nSelectionCount
> 0);
759 // mpPBPlay->Enable(nSelectionCount > 0);
761 mpFTProperty
->SetText( maStrProperty
);
763 mnPropertyType
= nPropertyTypeNone
;
765 if( nSelectionCount
== 1 )
767 CustomAnimationEffectPtr pEffect
= maListSelection
.front();
769 OUString
aUIName( getPresets().getUINameForPresetId( pEffect
->getPresetId() ) );
771 OUString
aTemp( maStrModify
);
773 if( aUIName
.getLength() )
775 aTemp
+= OUString( (sal_Unicode
)' ' );
778 mpFLEffect
->SetText( aTemp
);
780 CustomAnimationPresetPtr pDescriptor
= getPresets().getEffectDescriptor( pEffect
->getPresetId() );
781 if( pDescriptor
.get() )
783 PropertySubControl
* pSubControl
= NULL
;
787 UStringList
aProperties( pDescriptor
->getProperties() );
788 if( aProperties
.size() >= 1 )
790 OUString
aProperty( aProperties
.front() );
792 mnPropertyType
= getPropertyType( aProperties
.front() );
794 mpFTProperty
->SetText( getPropertyName( mnPropertyType
) );
796 aValue
= getProperty1Value( mnPropertyType
, pEffect
);
799 if( aValue
.hasValue() )
801 pSubControl
= mpLBProperty
->getSubControl();
802 if( !pSubControl
|| (pSubControl
->getControlType() != mnPropertyType
) )
804 pSubControl
= PropertySubControl::create( mnPropertyType
, this, aValue
, pEffect
->getPresetId(), LINK( this, CustomAnimationPane
, implPropertyHdl
) );
805 mpLBProperty
->setSubControl( pSubControl
);
809 pSubControl
->setValue( aValue
, pEffect
->getPresetId() );
814 mpLBProperty
->setSubControl( 0 );
817 bool bEnable
= (pSubControl
!= 0) && (pSubControl
->getControl()->IsEnabled());
818 mpLBProperty
->Enable( bEnable
);
819 mpFTProperty
->Enable( bEnable
);
823 mpLBProperty
->setSubControl( 0 );
824 mpFTProperty
->Enable( FALSE
);
825 mpLBProperty
->Enable( FALSE
);
826 mpPBPropertyMore
->Enable( FALSE
);
832 USHORT nPos
= 0xffff;
834 sal_Int16 nNodeType
= pEffect
->getNodeType();
837 case EffectNodeType::ON_CLICK
: nPos
= 0; break;
838 case EffectNodeType::WITH_PREVIOUS
: nPos
= 1; break;
839 case EffectNodeType::AFTER_PREVIOUS
: nPos
= 2; break;
842 mpLBStart
->SelectEntryPos( nPos
);
844 double fDuration
= pEffect
->getDuration();
845 const bool bHasSpeed
= fDuration
> 0.001;
847 mpFTSpeed
->Enable(bHasSpeed
);
848 mpCBSpeed
->Enable(bHasSpeed
);
852 if( fDuration
== 5.0 )
854 else if( fDuration
== 3.0 )
856 else if( fDuration
== 2.0 )
858 else if( fDuration
== 1.0 )
860 else if( fDuration
== 0.5 )
865 mpCBSpeed
->SelectEntryPos( nPos
);
868 mpPBPropertyMore
->Enable( TRUE
);
870 mpFTChangeOrder
->Enable( TRUE
);
874 mpLBProperty
->setSubControl( 0 );
875 mpFTProperty
->Enable( FALSE
);
876 mpLBProperty
->Enable( FALSE
);
877 mpPBPropertyMore
->Enable( FALSE
);
878 mpFTSpeed
->Enable(FALSE
);
879 mpCBSpeed
->Enable(FALSE
);
880 mpFTChangeOrder
->Enable( FALSE
);
881 mpLBStart
->SetNoSelection();
882 mpCBSpeed
->SetNoSelection();
883 mpFLEffect
->SetText( maStrModify
);
886 bool bEnableUp
= true;
887 bool bEnableDown
= true;
888 if( nSelectionCount
== 0 )
895 if( mpMainSequence
->find( maListSelection
.front() ) == mpMainSequence
->getBegin() )
898 EffectSequence::iterator
aIter( mpMainSequence
->find( maListSelection
.back() ) );
899 if( aIter
== mpMainSequence
->getEnd() )
909 while( (aIter
!= mpMainSequence
->getEnd()) && !(mpCustomAnimationList
->isExpanded((*aIter
)) ) );
911 if( aIter
== mpMainSequence
->getEnd() )
915 if( bEnableUp
|| bEnableDown
)
917 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
919 EffectSequenceHelper
* pSequence
= 0;
920 EffectSequence::iterator
aRebuildIter( maListSelection
.begin() );
921 const EffectSequence::iterator
aRebuildEnd( maListSelection
.end() );
922 while( aRebuildIter
!= aRebuildEnd
)
924 CustomAnimationEffectPtr pEffect
= (*aRebuildIter
++);
930 pSequence
= pEffect
->getEffectSequence();
934 if( pSequence
!= pEffect
->getEffectSequence() )
946 mpPBMoveUp
->Enable(bEnableUp
);
947 mpPBMoveDown
->Enable(bEnableDown
);
949 SdOptions
* pOptions
= SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS
);
950 mpCBAutoPreview
->Check( pOptions
->IsPreviewChangedEffects() == sal_True
);
952 updateMotionPathTags();
955 static bool updateMotionPathImpl( CustomAnimationPane
& rPane
, ::sd::View
& rView
, EffectSequence::iterator aIter
, EffectSequence::iterator aEnd
, MotionPathTagVector
& rOldTags
, MotionPathTagVector
& rNewTags
)
957 bool bChanges
= false;
958 while( aIter
!= aEnd
)
960 CustomAnimationEffectPtr
pEffect( (*aIter
++) );
961 if( pEffect
.get() && pEffect
->getPresetClass() == ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH
)
963 rtl::Reference
< MotionPathTag
> xMotionPathTag
;
964 // first try to find if there is already a tag for this
965 MotionPathTagVector::iterator
aMIter( rOldTags
.begin() );
966 for( ; aMIter
!= rOldTags
.end(); aMIter
++ )
968 rtl::Reference
< MotionPathTag
> xTag( (*aMIter
) );
969 if( xTag
->getEffect() == pEffect
)
971 if( !xTag
->isDisposed() )
973 xMotionPathTag
= xTag
;
974 rOldTags
.erase( aMIter
);
980 // if not found, create new one
981 if( !xMotionPathTag
.is() )
983 xMotionPathTag
.set( new MotionPathTag( rPane
, rView
, pEffect
) );
987 if( xMotionPathTag
.is() )
988 rNewTags
.push_back( xMotionPathTag
);
995 void CustomAnimationPane::updateMotionPathTags()
997 bool bChanges
= false;
999 MotionPathTagVector aTags
;
1000 aTags
.swap( maMotionPathTags
);
1002 ::sd::View
* pView
= 0;
1006 ::boost::shared_ptr
<ViewShell
> xViewShell( mrBase
.GetMainViewShell() );
1007 if( xViewShell
.get() )
1008 pView
= xViewShell
->GetView();
1011 if( IsVisible() && mpMainSequence
.get() && pView
)
1013 bChanges
= updateMotionPathImpl( *this, *pView
, mpMainSequence
->getBegin(), mpMainSequence
->getEnd(), aTags
, maMotionPathTags
);
1015 const InteractiveSequenceList
& rISL
= mpMainSequence
->getInteractiveSequenceList();
1016 InteractiveSequenceList::const_iterator
aISI( rISL
.begin() );
1017 while( aISI
!= rISL
.end() )
1019 InteractiveSequencePtr
pIS( (*aISI
++) );
1020 bChanges
|= updateMotionPathImpl( *this, *pView
, pIS
->getBegin(), pIS
->getEnd(), aTags
, maMotionPathTags
);
1024 if( !aTags
.empty() )
1027 MotionPathTagVector::iterator
aIter( aTags
.begin() );
1028 while( aIter
!= aTags
.end() )
1030 rtl::Reference
< MotionPathTag
> xTag( (*aIter
++) );
1035 if( bChanges
&& pView
)
1036 pView
->updateHandles();
1039 void CustomAnimationPane::onSelectionChanged()
1041 if( !maSelectionLock
.isLocked() )
1043 ScopeLockGuard
aGuard( maSelectionLock
);
1045 if( mxView
.is() ) try
1047 Reference
< XSelectionSupplier
> xSel( mxView
, UNO_QUERY_THROW
);
1050 maViewSelection
= xSel
->getSelection();
1051 mpCustomAnimationList
->onSelectionChanged( maViewSelection
);
1057 DBG_ERROR( "sd::CustomAnimationPane::onSelectionChanged(), Exception catched!" );
1062 void CustomAnimationPane::onDoubleClick()
1067 void CustomAnimationPane::onContextMenu( USHORT nSelectedPopupEntry
)
1069 switch( nSelectedPopupEntry
)
1071 case CM_WITH_CLICK
: onChangeStart( EffectNodeType::ON_CLICK
); break;
1072 case CM_WITH_PREVIOUS
: onChangeStart( EffectNodeType::WITH_PREVIOUS
); break;
1073 case CM_AFTER_PREVIOUS
: onChangeStart( EffectNodeType::AFTER_PREVIOUS
); break;
1074 case CM_OPTIONS
: showOptions(); break;
1075 case CM_DURATION
: showOptions(RID_TP_CUSTOMANIMATION_DURATION
); break;
1076 case CM_REMOVE
: onRemove(); break;
1077 case CM_CREATE
: if( maViewSelection
.hasValue() ) onChange( true ); break;
1083 void addValue( STLPropertySet
* pSet
, sal_Int32 nHandle
, const Any
& rValue
)
1085 switch( pSet
->getPropertyState( nHandle
) )
1087 case STLPropertyState_AMBIGUOUS
:
1088 // value is already ambiguous, do nothing
1090 case STLPropertyState_DIRECT
:
1091 // set to ambiguous if existing value is different
1092 if( rValue
!= pSet
->getPropertyValue( nHandle
) )
1093 pSet
->setPropertyState( nHandle
, STLPropertyState_AMBIGUOUS
);
1095 case STLPropertyState_DEFAULT
:
1096 // just set new value
1097 pSet
->setPropertyValue( nHandle
, rValue
);
1102 static sal_Int32
calcMaxParaDepth( Reference
< XShape
> xTargetShape
)
1104 sal_Int32 nMaxParaDepth
= -1;
1106 if( xTargetShape
.is() )
1108 Reference
< XEnumerationAccess
> xText( xTargetShape
, UNO_QUERY
);
1111 Reference
< XPropertySet
> xParaSet
;
1112 const OUString
strNumberingLevel( RTL_CONSTASCII_USTRINGPARAM("NumberingLevel") );
1114 Reference
< XEnumeration
> xEnumeration( xText
->createEnumeration(), UNO_QUERY_THROW
);
1115 while( xEnumeration
->hasMoreElements() )
1117 xEnumeration
->nextElement() >>= xParaSet
;
1120 sal_Int32 nParaDepth
= 0;
1121 xParaSet
->getPropertyValue( strNumberingLevel
) >>= nParaDepth
;
1123 if( nParaDepth
> nMaxParaDepth
)
1124 nMaxParaDepth
= nParaDepth
;
1130 return nMaxParaDepth
+ 1;
1133 Any
CustomAnimationPane::getProperty1Value( sal_Int32 nType
, CustomAnimationEffectPtr pEffect
)
1137 case nPropertyTypeDirection
:
1138 case nPropertyTypeSpokes
:
1139 case nPropertyTypeZoom
:
1140 return makeAny( pEffect
->getPresetSubType() );
1142 case nPropertyTypeColor
:
1143 case nPropertyTypeFillColor
:
1144 case nPropertyTypeFirstColor
:
1145 case nPropertyTypeSecondColor
:
1146 case nPropertyTypeCharColor
:
1147 case nPropertyTypeLineColor
:
1149 const sal_Int32 nIndex
= (nPropertyTypeFirstColor
== nType
) ? 0 : 1;
1150 return pEffect
->getColor( nIndex
);
1153 case nPropertyTypeFont
:
1154 return pEffect
->getProperty( AnimationNodeType::SET
, OUString( RTL_CONSTASCII_USTRINGPARAM("CharFontName") ), VALUE_TO
);
1156 case nPropertyTypeCharHeight
:
1158 const OUString
aAttributeName( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ) );
1159 Any
aValue( pEffect
->getProperty( AnimationNodeType::SET
, aAttributeName
, VALUE_TO
) );
1160 if( !aValue
.hasValue() )
1161 aValue
= pEffect
->getProperty( AnimationNodeType::ANIMATE
, aAttributeName
, VALUE_TO
);
1165 case nPropertyTypeRotate
:
1166 return pEffect
->getTransformationProperty( AnimationTransformType::ROTATE
, VALUE_BY
);
1168 case nPropertyTypeTransparency
:
1169 return pEffect
->getProperty( AnimationNodeType::SET
, OUString(RTL_CONSTASCII_USTRINGPARAM("Opacity")), VALUE_TO
);
1171 case nPropertyTypeScale
:
1172 return pEffect
->getTransformationProperty( AnimationTransformType::SCALE
, VALUE_BY
);
1174 case nPropertyTypeCharDecoration
:
1176 Sequence
< Any
> aValues(3);
1177 aValues
[0] = pEffect
->getProperty( AnimationNodeType::SET
, OUString(RTL_CONSTASCII_USTRINGPARAM("CharWeight")), VALUE_TO
);
1178 aValues
[1] = pEffect
->getProperty( AnimationNodeType::SET
, OUString(RTL_CONSTASCII_USTRINGPARAM("CharPosture")), VALUE_TO
);
1179 aValues
[2] = pEffect
->getProperty( AnimationNodeType::SET
, OUString(RTL_CONSTASCII_USTRINGPARAM("CharUnderline")), VALUE_TO
);
1180 return makeAny( aValues
);
1188 bool CustomAnimationPane::setProperty1Value( sal_Int32 nType
, CustomAnimationEffectPtr pEffect
, const Any
& rValue
)
1190 bool bEffectChanged
= false;
1193 case nPropertyTypeDirection
:
1194 case nPropertyTypeSpokes
:
1195 case nPropertyTypeZoom
:
1197 OUString aPresetSubType
;
1198 rValue
>>= aPresetSubType
;
1199 if( aPresetSubType
!= pEffect
->getPresetSubType() )
1201 getPresets().changePresetSubType( pEffect
, aPresetSubType
);
1202 bEffectChanged
= true;
1207 case nPropertyTypeFillColor
:
1208 case nPropertyTypeColor
:
1209 case nPropertyTypeFirstColor
:
1210 case nPropertyTypeSecondColor
:
1211 case nPropertyTypeCharColor
:
1212 case nPropertyTypeLineColor
:
1214 const sal_Int32 nIndex
= (nPropertyTypeFirstColor
== nType
) ? 0 : 1;
1215 Any
aOldColor( pEffect
->getColor( nIndex
) );
1216 if( aOldColor
!= rValue
)
1218 pEffect
->setColor( nIndex
, rValue
);
1219 bEffectChanged
= true;
1224 case nPropertyTypeFont
:
1225 bEffectChanged
= pEffect
->setProperty( AnimationNodeType::SET
, OUString( RTL_CONSTASCII_USTRINGPARAM( "CharFontName" ) ), VALUE_TO
, rValue
);
1228 case nPropertyTypeCharHeight
:
1230 const OUString
aAttributeName( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ) );
1231 bEffectChanged
= pEffect
->setProperty( AnimationNodeType::SET
, aAttributeName
, VALUE_TO
, rValue
);
1232 if( !bEffectChanged
)
1233 bEffectChanged
= pEffect
->setProperty( AnimationNodeType::ANIMATE
, aAttributeName
, VALUE_TO
, rValue
);
1236 case nPropertyTypeRotate
:
1237 bEffectChanged
= pEffect
->setTransformationProperty( AnimationTransformType::ROTATE
, VALUE_BY
, rValue
);
1240 case nPropertyTypeTransparency
:
1241 bEffectChanged
= pEffect
->setProperty( AnimationNodeType::SET
, OUString( RTL_CONSTASCII_USTRINGPARAM("Opacity") ), VALUE_TO
, rValue
);
1244 case nPropertyTypeScale
:
1245 bEffectChanged
= pEffect
->setTransformationProperty( AnimationTransformType::SCALE
, VALUE_BY
, rValue
);
1248 case nPropertyTypeCharDecoration
:
1250 Sequence
< Any
> aValues(3);
1252 bEffectChanged
= pEffect
->setProperty( AnimationNodeType::SET
, OUString(RTL_CONSTASCII_USTRINGPARAM("CharWeight")), VALUE_TO
, aValues
[0] );
1253 bEffectChanged
|= pEffect
->setProperty( AnimationNodeType::SET
, OUString(RTL_CONSTASCII_USTRINGPARAM("CharPosture")), VALUE_TO
, aValues
[1] );
1254 bEffectChanged
|= pEffect
->setProperty( AnimationNodeType::SET
, OUString(RTL_CONSTASCII_USTRINGPARAM("CharUnderline")), VALUE_TO
, aValues
[2] );
1260 return bEffectChanged
;
1263 static sal_Bool
hasVisibleShape( const Reference
< XShape
>& xShape
)
1267 const OUString
sShapeType( xShape
->getShapeType() );
1269 if( sShapeType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation.TitleTextShape") ) ||
1270 sShapeType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation.OutlinerShape") ) ||
1271 sShapeType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation.SubtitleShape") ) ||
1272 sShapeType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.TextShape") ) )
1274 const OUString
sFillStyle( RTL_CONSTASCII_USTRINGPARAM("FillStyle" ) );
1275 const OUString
sLineStyle( RTL_CONSTASCII_USTRINGPARAM("LineStyle" ) );
1276 Reference
< XPropertySet
> xSet( xShape
, UNO_QUERY_THROW
);
1278 FillStyle eFillStyle
;
1279 xSet
->getPropertyValue( sFillStyle
) >>= eFillStyle
;
1281 ::com::sun::star::drawing::LineStyle eLineStyle
;
1282 xSet
->getPropertyValue( sLineStyle
) >>= eLineStyle
;
1284 return eFillStyle
!= FillStyle_NONE
|| eLineStyle
!= ::com::sun::star::drawing::LineStyle_NONE
;
1287 catch( Exception
& e
)
1294 STLPropertySet
* CustomAnimationPane::createSelectionSet()
1296 STLPropertySet
* pSet
= CustomAnimationDialog::createDefaultSet();
1298 pSet
->setPropertyValue( nHandleCurrentPage
, makeAny( mxCurrentPage
) );
1300 sal_Int32 nMaxParaDepth
= 0;
1302 // get options from selected effects
1303 EffectSequence::iterator
aIter( maListSelection
.begin() );
1304 const EffectSequence::iterator
aEnd( maListSelection
.end() );
1305 const CustomAnimationPresets
& rPresets (getPresets());
1306 while( aIter
!= aEnd
)
1308 CustomAnimationEffectPtr pEffect
= (*aIter
++);
1310 EffectSequenceHelper
* pEffectSequence
= pEffect
->getEffectSequence();
1311 if( !pEffectSequence
)
1312 pEffectSequence
= mpMainSequence
.get();
1314 if( pEffect
->hasText() )
1316 sal_Int32 n
= calcMaxParaDepth(pEffect
->getTargetShape());
1317 if( n
> nMaxParaDepth
)
1321 addValue( pSet
, nHandleHasAfterEffect
, makeAny( pEffect
->hasAfterEffect() ) );
1322 addValue( pSet
, nHandleAfterEffectOnNextEffect
, makeAny( pEffect
->IsAfterEffectOnNext() ? sal_True
: sal_False
) );
1323 addValue( pSet
, nHandleDimColor
, pEffect
->getDimColor() );
1324 addValue( pSet
, nHandleIterateType
, makeAny( pEffect
->getIterateType() ) );
1326 // convert absolute time to percentage value
1327 // This calculation is done in float to avoid some rounding artifacts.
1328 float fIterateInterval
= (float)pEffect
->getIterateInterval();
1329 if( pEffect
->getDuration() )
1330 fIterateInterval
= (float)(fIterateInterval
/ pEffect
->getDuration() );
1331 fIterateInterval
*= 100.0;
1332 addValue( pSet
, nHandleIterateInterval
, makeAny( (double)fIterateInterval
) );
1334 addValue( pSet
, nHandleBegin
, makeAny( pEffect
->getBegin() ) );
1335 addValue( pSet
, nHandleDuration
, makeAny( pEffect
->getDuration() ) );
1336 addValue( pSet
, nHandleStart
, makeAny( pEffect
->getNodeType() ) );
1337 addValue( pSet
, nHandleRepeat
, makeAny( pEffect
->getRepeatCount() ) );
1338 addValue( pSet
, nHandleEnd
, pEffect
->getEnd() );
1339 addValue( pSet
, nHandleRewind
, makeAny( pEffect
->getFill() ) );
1341 addValue( pSet
, nHandlePresetId
, makeAny( pEffect
->getPresetId() ) );
1343 addValue( pSet
, nHandleHasText
, makeAny( (sal_Bool
)pEffect
->hasText() ) );
1345 addValue( pSet
, nHandleHasVisibleShape
, Any( hasVisibleShape( pEffect
->getTargetShape() ) ) );
1348 if( pEffect
->getAudio().is() )
1350 aSoundSource
= pEffect
->getAudio()->getSource();
1351 addValue( pSet
, nHandleSoundVolumne
, makeAny( pEffect
->getAudio()->getVolume() ) );
1352 // todo addValue( pSet, nHandleSoundEndAfterSlide, makeAny( pEffect->getAudio()->getEndAfterSlide() ) );
1353 // this is now stored at the XCommand parameter sequence
1355 else if( pEffect
->getCommand() == EffectCommands::STOPAUDIO
)
1357 aSoundSource
= makeAny( (sal_Bool
)sal_True
);
1359 addValue( pSet
, nHandleSoundURL
, aSoundSource
);
1361 sal_Int32 nGroupId
= pEffect
->getGroupId();
1362 CustomAnimationTextGroupPtr pTextGroup
;
1363 if( nGroupId
!= -1 )
1364 pTextGroup
= pEffectSequence
->findGroup( nGroupId
);
1366 addValue( pSet
, nHandleTextGrouping
, makeAny( pTextGroup
.get() ? pTextGroup
->getTextGrouping() : (sal_Int32
)-1 ) );
1367 addValue( pSet
, nHandleAnimateForm
, makeAny( pTextGroup
.get() ? (sal_Bool
)pTextGroup
->getAnimateForm() : sal_True
) );
1368 addValue( pSet
, nHandleTextGroupingAuto
, makeAny( pTextGroup
.get() ? pTextGroup
->getTextGroupingAuto() : (double)-1.0 ) );
1369 addValue( pSet
, nHandleTextReverse
, makeAny( pTextGroup
.get() ? (sal_Bool
)pTextGroup
->getTextReverse() : sal_False
) );
1371 if( pEffectSequence
->getSequenceType() == EffectNodeType::INTERACTIVE_SEQUENCE
)
1373 InteractiveSequence
* pIS
= static_cast< InteractiveSequence
* >( pEffectSequence
);
1374 addValue( pSet
, nHandleTrigger
, makeAny( pIS
->getTriggerShape() ) );
1379 CustomAnimationPresetPtr pDescriptor
= rPresets
.getEffectDescriptor( pEffect
->getPresetId() );
1380 if( pDescriptor
.get() )
1382 sal_Int32 nType
= nPropertyTypeNone
;
1384 UStringList
aProperties( pDescriptor
->getProperties() );
1385 if( aProperties
.size() >= 1 )
1386 nType
= getPropertyType( aProperties
.front() );
1388 if( nType
!= nPropertyTypeNone
)
1390 addValue( pSet
, nHandleProperty1Type
, makeAny( nType
) );
1391 addValue( pSet
, nHandleProperty1Value
, getProperty1Value( nType
, pEffect
) );
1394 if( pDescriptor
->hasProperty( OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerate" ) ) ) )
1396 addValue( pSet
, nHandleAccelerate
, makeAny( pEffect
->getAcceleration() ) );
1399 if( pDescriptor
->hasProperty( OUString( RTL_CONSTASCII_USTRINGPARAM( "Decelerate" ) ) ) )
1401 addValue( pSet
, nHandleDecelerate
, makeAny( pEffect
->getDecelerate() ) );
1404 if( pDescriptor
->hasProperty( OUString( RTL_CONSTASCII_USTRINGPARAM( "AutoReverse" ) ) ) )
1406 addValue( pSet
, nHandleAutoReverse
, makeAny( pEffect
->getAutoReverse() ) );
1411 addValue( pSet
, nHandleMaxParaDepth
, makeAny( nMaxParaDepth
) );
1416 void CustomAnimationPane::changeSelection( STLPropertySet
* pResultSet
, STLPropertySet
* pOldSet
)
1418 // change selected effect
1419 bool bChanged
= false;
1421 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
1423 EffectSequence::iterator
aIter( maListSelection
.begin() );
1424 const EffectSequence::iterator
aEnd( maListSelection
.end() );
1425 while( aIter
!= aEnd
)
1427 CustomAnimationEffectPtr pEffect
= (*aIter
++);
1429 DBG_ASSERT( pEffect
->getEffectSequence(), "sd::CustomAnimationPane::changeSelection(), dead effect in selection!" );
1430 if( !pEffect
->getEffectSequence() )
1433 double fDuration
= 0.0; // we might need this for iterate-interval
1434 if( pResultSet
->getPropertyState( nHandleDuration
) == STLPropertyState_DIRECT
)
1436 pResultSet
->getPropertyValue( nHandleDuration
) >>= fDuration
;
1440 fDuration
= pEffect
->getDuration();
1443 if( pResultSet
->getPropertyState( nHandleIterateType
) == STLPropertyState_DIRECT
)
1445 sal_Int16 nIterateType
= 0;
1446 pResultSet
->getPropertyValue( nHandleIterateType
) >>= nIterateType
;
1447 if( pEffect
->getIterateType() != nIterateType
)
1449 pEffect
->setIterateType( nIterateType
);
1454 if( pEffect
->getIterateType() )
1456 if( pResultSet
->getPropertyState( nHandleIterateInterval
) == STLPropertyState_DIRECT
)
1458 double fIterateInterval
= 0.0;
1459 pResultSet
->getPropertyValue( nHandleIterateInterval
) >>= fIterateInterval
;
1460 if( pEffect
->getIterateInterval() != fIterateInterval
)
1462 const double f
= fIterateInterval
* pEffect
->getDuration() / 100;
1463 pEffect
->setIterateInterval( f
);
1469 if( pResultSet
->getPropertyState( nHandleBegin
) == STLPropertyState_DIRECT
)
1471 double fBegin
= 0.0;
1472 pResultSet
->getPropertyValue( nHandleBegin
) >>= fBegin
;
1473 if( pEffect
->getBegin() != fBegin
)
1475 pEffect
->setBegin( fBegin
);
1480 if( pResultSet
->getPropertyState( nHandleDuration
) == STLPropertyState_DIRECT
)
1482 if( pEffect
->getDuration() != fDuration
)
1484 pEffect
->setDuration( fDuration
);
1489 if( pResultSet
->getPropertyState( nHandleStart
) == STLPropertyState_DIRECT
)
1491 sal_Int16 nNodeType
= 0;
1492 pResultSet
->getPropertyValue( nHandleStart
) >>= nNodeType
;
1493 if( pEffect
->getNodeType() != nNodeType
)
1495 pEffect
->setNodeType( nNodeType
);
1500 if( pResultSet
->getPropertyState( nHandleRepeat
) == STLPropertyState_DIRECT
)
1502 Any
aRepeatCount( pResultSet
->getPropertyValue( nHandleRepeat
) );
1503 if( aRepeatCount
!= pEffect
->getRepeatCount() )
1505 pEffect
->setRepeatCount( aRepeatCount
);
1510 if( pResultSet
->getPropertyState( nHandleEnd
) == STLPropertyState_DIRECT
)
1512 Any
aEndValue( pResultSet
->getPropertyValue( nHandleEnd
) );
1513 if( pEffect
->getEnd() != aEndValue
)
1515 pEffect
->setEnd( aEndValue
);
1520 if( pResultSet
->getPropertyState( nHandleRewind
) == STLPropertyState_DIRECT
)
1522 sal_Int16 nFill
= 0;
1523 pResultSet
->getPropertyValue( nHandleRewind
) >>= nFill
;
1524 if( pEffect
->getFill() != nFill
)
1526 pEffect
->setFill( nFill
);
1531 if( pResultSet
->getPropertyState( nHandleHasAfterEffect
) == STLPropertyState_DIRECT
)
1533 sal_Bool bHasAfterEffect
= sal_False
;
1534 if( pResultSet
->getPropertyValue( nHandleHasAfterEffect
) >>= bHasAfterEffect
)
1536 if( pEffect
->hasAfterEffect() != bHasAfterEffect
)
1538 pEffect
->setHasAfterEffect( bHasAfterEffect
);
1544 if( pResultSet
->getPropertyState( nHandleAfterEffectOnNextEffect
) == STLPropertyState_DIRECT
)
1546 sal_Bool bAfterEffectOnNextEffect
= sal_False
;
1547 if( (pResultSet
->getPropertyValue( nHandleAfterEffectOnNextEffect
) >>= bAfterEffectOnNextEffect
) && ((pEffect
->IsAfterEffectOnNext() ? sal_True
: sal_False
) != bAfterEffectOnNextEffect
) )
1549 pEffect
->setAfterEffectOnNext( bAfterEffectOnNextEffect
);
1554 if( pResultSet
->getPropertyState( nHandleDimColor
) == STLPropertyState_DIRECT
)
1556 Any
aDimColor( pResultSet
->getPropertyValue( nHandleDimColor
) );
1557 if( pEffect
->getDimColor() != aDimColor
)
1559 pEffect
->setDimColor( aDimColor
);
1564 if( pResultSet
->getPropertyState( nHandleAccelerate
) == STLPropertyState_DIRECT
)
1566 double fAccelerate
= 0.0;
1567 pResultSet
->getPropertyValue( nHandleAccelerate
) >>= fAccelerate
;
1568 if( pEffect
->getAcceleration() != fAccelerate
)
1570 pEffect
->setAcceleration( fAccelerate
);
1575 if( pResultSet
->getPropertyState( nHandleDecelerate
) == STLPropertyState_DIRECT
)
1577 double fDecelerate
= 0.0;
1578 pResultSet
->getPropertyValue( nHandleDecelerate
) >>= fDecelerate
;
1579 if( pEffect
->getDecelerate() != fDecelerate
)
1581 pEffect
->setDecelerate( fDecelerate
);
1586 if( pResultSet
->getPropertyState( nHandleAutoReverse
) == STLPropertyState_DIRECT
)
1588 sal_Bool bAutoReverse
= sal_False
;
1589 pResultSet
->getPropertyValue( nHandleAutoReverse
) >>= bAutoReverse
;
1590 if( pEffect
->getAutoReverse() != bAutoReverse
)
1592 pEffect
->setAutoReverse( bAutoReverse
);
1597 if( pResultSet
->getPropertyState( nHandleProperty1Value
) == STLPropertyState_DIRECT
)
1599 sal_Int32 nType
= 0;
1600 pOldSet
->getPropertyValue( nHandleProperty1Type
) >>= nType
;
1602 bChanged
|= setProperty1Value( nType
, pEffect
, pResultSet
->getPropertyValue( nHandleProperty1Value
) );
1605 if( pResultSet
->getPropertyState( nHandleSoundURL
) == STLPropertyState_DIRECT
)
1607 const Any
aSoundSource( pResultSet
->getPropertyValue( nHandleSoundURL
) );
1609 if( aSoundSource
.getValueType() == ::getCppuType((const sal_Bool
*)0) )
1611 pEffect
->setStopAudio();
1617 aSoundSource
>>= aSoundURL
;
1619 if( aSoundURL
.getLength() )
1621 if( !pEffect
->getAudio().is() )
1623 pEffect
->createAudio( aSoundSource
);
1628 if( pEffect
->getAudio()->getSource() != aSoundSource
)
1630 pEffect
->getAudio()->setSource( aSoundSource
);
1637 if( pEffect
->getAudio().is() || pEffect
->getStopAudio() )
1639 pEffect
->removeAudio();
1646 if( pResultSet
->getPropertyState( nHandleTrigger
) == STLPropertyState_DIRECT
)
1648 Reference
< XShape
> xTriggerShape
;
1649 pResultSet
->getPropertyValue( nHandleTrigger
) >>= xTriggerShape
;
1650 bChanged
|= mpMainSequence
->setTrigger( pEffect
, xTriggerShape
);
1654 const bool bHasTextGrouping
= pResultSet
->getPropertyState( nHandleTextGrouping
) == STLPropertyState_DIRECT
;
1655 const bool bHasAnimateForm
= pResultSet
->getPropertyState( nHandleAnimateForm
) == STLPropertyState_DIRECT
;
1656 const bool bHasTextGroupingAuto
= pResultSet
->getPropertyState( nHandleTextGroupingAuto
) == STLPropertyState_DIRECT
;
1657 const bool bHasTextReverse
= pResultSet
->getPropertyState( nHandleTextReverse
) == STLPropertyState_DIRECT
;
1659 if( bHasTextGrouping
|| bHasAnimateForm
|| bHasTextGroupingAuto
|| bHasTextReverse
)
1661 // we need to do a second pass for text grouping options
1662 // since changing them can cause effects to be removed
1663 // or replaced, we do this after we aplied all other options
1666 sal_Int32 nTextGrouping
= 0;
1667 sal_Bool bAnimateForm
= sal_True
, bTextReverse
= sal_False
;
1668 double fTextGroupingAuto
= -1.0;
1670 if( bHasTextGrouping
)
1671 pResultSet
->getPropertyValue(nHandleTextGrouping
) >>= nTextGrouping
;
1673 if( bHasAnimateForm
)
1674 pResultSet
->getPropertyValue(nHandleAnimateForm
) >>= bAnimateForm
;
1676 if( bHasTextGroupingAuto
)
1677 pResultSet
->getPropertyValue(nHandleTextGroupingAuto
) >>= fTextGroupingAuto
;
1679 if( bHasTextReverse
)
1680 pResultSet
->getPropertyValue(nHandleTextReverse
) >>= bTextReverse
;
1682 EffectSequence
const aSelectedEffects( maListSelection
);
1683 EffectSequence::const_iterator
iter( aSelectedEffects
.begin() );
1684 const EffectSequence::const_iterator
iEnd( aSelectedEffects
.end() );
1685 while( iter
!= iEnd
)
1687 CustomAnimationEffectPtr
const& pEffect
= (*iter
++);
1689 EffectSequenceHelper
* pEffectSequence
= pEffect
->getEffectSequence();
1690 if( !pEffectSequence
)
1691 pEffectSequence
= mpMainSequence
.get();
1693 sal_Int32 nGroupId
= pEffect
->getGroupId();
1694 CustomAnimationTextGroupPtr pTextGroup
;
1695 if( (nGroupId
!= -1) )
1697 // use existing group
1698 pTextGroup
= pEffectSequence
->findGroup( nGroupId
);
1702 // somethings changed so we need a group now
1703 pTextGroup
= pEffectSequence
->createTextGroup( pEffect
, nTextGrouping
, fTextGroupingAuto
, bAnimateForm
, bTextReverse
);
1707 if( bHasTextGrouping
)
1709 if( (pTextGroup
->getTextGrouping() != nTextGrouping
) )
1711 pEffectSequence
->setTextGrouping( pTextGroup
, nTextGrouping
);
1716 if( bHasAnimateForm
)
1718 if( pTextGroup
->getAnimateForm() != bAnimateForm
)
1720 pEffectSequence
->setAnimateForm( pTextGroup
, bAnimateForm
);
1725 if( bHasTextGroupingAuto
)
1727 if( pTextGroup
->getTextGroupingAuto() != fTextGroupingAuto
)
1729 pEffectSequence
->setTextGroupingAuto( pTextGroup
, fTextGroupingAuto
);
1734 if( bHasTextReverse
)
1736 if( pTextGroup
->getTextReverse() != bTextReverse
)
1738 pEffectSequence
->setTextReverse( pTextGroup
, bTextReverse
);
1747 mpMainSequence
->rebuild();
1749 mrBase
.GetDocShell()->SetModified();
1753 void CustomAnimationPane::showOptions( USHORT nPage
/* = 0 */ )
1755 STLPropertySet
* pSet
= createSelectionSet();
1757 CustomAnimationDialog
* pDlg
= new CustomAnimationDialog( this, pSet
, nPage
);
1758 if( pDlg
->Execute() )
1761 changeSelection( pDlg
->getResultSet(), pSet
);
1768 void CustomAnimationPane::onChangeCurrentPage()
1770 if( mxView
.is() ) try
1772 Reference
< XDrawPage
> xNewPage( mxView
->getCurrentPage() );
1773 if( xNewPage
!= mxCurrentPage
)
1775 mxCurrentPage
= xNewPage
;
1776 SdPage
* pPage
= SdPage::getImplementation( mxCurrentPage
);
1779 mpMainSequence
= pPage
->getMainSequence();
1780 mpCustomAnimationList
->update( mpMainSequence
);
1787 DBG_ERROR( "sd::CustomAnimationPane::onChangeCurrentPage(), exception catched!" );
1791 bool getTextSelection( const Any
& rSelection
, Reference
< XShape
>& xShape
, std::list
< sal_Int16
>& rParaList
)
1793 Reference
< XTextRange
> xSelectedText
;
1794 rSelection
>>= xSelectedText
;
1795 if( xSelectedText
.is() ) try
1797 xShape
.set( xSelectedText
->getText(), UNO_QUERY_THROW
);
1799 Reference
< XTextRangeCompare
> xTextRangeCompare( xShape
, UNO_QUERY_THROW
);
1800 Reference
< XEnumerationAccess
> xParaEnumAccess( xShape
, UNO_QUERY_THROW
);
1801 Reference
< XEnumeration
> xParaEnum( xParaEnumAccess
->createEnumeration(), UNO_QUERY_THROW
);
1802 Reference
< XTextRange
> xRange
;
1803 Reference
< XTextRange
> xStart( xSelectedText
->getStart() );
1804 Reference
< XTextRange
> xEnd( xSelectedText
->getEnd() );
1806 if( xTextRangeCompare
->compareRegionEnds( xStart
, xEnd
) < 0 )
1808 Reference
< XTextRange
> xTemp( xStart
);
1813 sal_Int16 nPara
= 0;
1814 while( xParaEnum
->hasMoreElements() )
1816 xParaEnum
->nextElement() >>= xRange
;
1818 // break if start of selection is prior to end of current paragraph
1819 if( xRange
.is() && (xTextRangeCompare
->compareRegionEnds( xStart
, xRange
) >= 0 ) )
1825 while( xRange
.is() )
1827 if( xRange
.is() && xRange
->getString().getLength() )
1828 rParaList
.push_back( nPara
);
1830 // break if end of selection is before or at end of current paragraph
1831 if( xRange
.is() && xTextRangeCompare
->compareRegionEnds( xEnd
, xRange
) >= 0 )
1836 if( xParaEnum
->hasMoreElements() )
1837 xParaEnum
->nextElement() >>= xRange
;
1844 catch( Exception
& e
)
1847 DBG_ERROR( "sd::CustomAnimationPane::getTextSelection(), exception cought!" );
1853 void CustomAnimationPane::onChange( bool bCreate
)
1855 bool bHasText
= true;
1857 // first create vector of targets for dialog preview
1858 std::vector
< Any
> aTargets
;
1860 double fDuration
= 2.0f
;
1864 // gather shapes from the selection
1865 Reference
< XSelectionSupplier
> xSel( mxView
, UNO_QUERY_THROW
);
1866 maViewSelection
= xSel
->getSelection();
1868 if( maViewSelection
.getValueType() == ::getCppuType((const Reference
< XShapes
>*)0) )
1870 Reference
< XIndexAccess
> xShapes
;
1871 maViewSelection
>>= xShapes
;
1873 sal_Int32 nCount
= xShapes
->getCount();
1875 for( nIndex
= 0; nIndex
< nCount
; nIndex
++ )
1877 Any
aTarget( xShapes
->getByIndex( nIndex
) );
1878 aTargets
.push_back( aTarget
);
1881 Reference
< XText
> xText
;
1883 if( !xText
.is() || xText
->getString().getLength() == 0 )
1888 else if ( maViewSelection
.getValueType() == ::getCppuType((const Reference
< XShape
>*)0) )
1890 aTargets
.push_back( maViewSelection
);
1891 Reference
< XText
> xText
;
1892 maViewSelection
>>= xText
;
1893 if( !xText
.is() || xText
->getString().getLength() == 0 )
1896 else if ( maViewSelection
.getValueType() == ::getCppuType((const Reference
< XTextCursor
>*)0) )
1898 Reference
< XShape
> xShape
;
1899 std::list
< sal_Int16
> aParaList
;
1900 if( getTextSelection( maViewSelection
, xShape
, aParaList
) )
1902 ParagraphTarget aParaTarget
;
1903 aParaTarget
.Shape
= xShape
;
1905 std::list
< sal_Int16
>::iterator
aIter( aParaList
.begin() );
1906 for( ; aIter
!= aParaList
.end(); aIter
++ )
1908 aParaTarget
.Paragraph
= (*aIter
);
1909 aTargets
.push_back( makeAny( aParaTarget
) );
1915 DBG_ERROR("sd::CustomAnimationPane::onChange(), unknown view selection!" );
1921 // get selected effect
1922 EffectSequence::iterator
aIter( maListSelection
.begin() );
1923 const EffectSequence::iterator
aEnd( maListSelection
.end() );
1924 while( aIter
!= aEnd
)
1926 if( !bHasText
|| !(*aIter
)->hasText() )
1929 if( sPresetId
.getLength() == 0 )
1931 sPresetId
= (*aIter
)->getPresetId();
1932 fDuration
= (*aIter
)->getDuration();
1935 aTargets
.push_back( (*aIter
++)->getTarget() );
1939 CustomAnimationCreateDialog
* pDlg
= new CustomAnimationCreateDialog( this, this, aTargets
, bHasText
, sPresetId
, fDuration
);
1940 if( pDlg
->Execute() )
1943 fDuration
= pDlg
->getSelectedDuration();
1944 CustomAnimationPresetPtr pDescriptor
= pDlg
->getSelectedPreset();
1945 if( pDescriptor
.get() )
1949 mpCustomAnimationList
->SelectAll( FALSE
);
1951 // gather shapes from the selection
1952 std::vector
< Any
>::iterator
aIter( aTargets
.begin() );
1953 const std::vector
< Any
>::iterator
aEnd( aTargets
.end() );
1955 for( ; aIter
!= aEnd
; aIter
++ )
1957 CustomAnimationEffectPtr pCreated
= mpMainSequence
->append( pDescriptor
, (*aIter
), fDuration
);
1962 pCreated
->setNodeType( EffectNodeType::WITH_PREVIOUS
);
1964 if( pCreated
.get() )
1966 mpCustomAnimationList
->select( pCreated
);
1972 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
1974 // get selected effect
1975 EffectSequence::iterator
aIter( maListSelection
.begin() );
1976 const EffectSequence::iterator
aEnd( maListSelection
.end() );
1977 while( aIter
!= aEnd
)
1979 CustomAnimationEffectPtr pEffect
= (*aIter
++);
1981 EffectSequenceHelper
* pEffectSequence
= pEffect
->getEffectSequence();
1982 if( !pEffectSequence
)
1983 pEffectSequence
= mpMainSequence
.get();
1985 pEffectSequence
->replace( pEffect
, pDescriptor
, fDuration
);
1991 PathKind eKind
= pDlg
->getCreatePathKind();
1993 createPath( eKind
, aTargets
, fDuration
);
1995 mrBase
.GetDocShell()->SetModified();
2002 // stop running preview from dialog
2003 SlideShow::Stop( mrBase
);
2006 void CustomAnimationPane::createPath( PathKind eKind
, std::vector
< Any
>& rTargets
, double fDuration
)
2012 case CURVE
: nSID
= SID_DRAW_BEZIER_NOFILL
; break;
2013 case POLYGON
: nSID
= SID_DRAW_POLYGON_NOFILL
; break;
2014 case FREEFORM
: nSID
= SID_DRAW_FREELINE_NOFILL
; break;
2020 DrawViewShell
* pViewShell
= dynamic_cast< DrawViewShell
* >(
2021 FrameworkHelper::Instance(mrBase
)->GetViewShell(FrameworkHelper::msCenterPaneURL
).get());
2025 DrawView
* pView
= pViewShell
->GetDrawView();
2027 pView
->UnmarkAllObj();
2029 std::vector
< Any
> aTargets( 1, Any( fDuration
) );
2030 aTargets
.insert( aTargets
.end(), rTargets
.begin(), rTargets
.end() );
2031 Sequence
< Any
> aTargetSequence( comphelper::containerToSequence( aTargets
) );
2032 const SfxUnoAnyItem
aItem( SID_ADD_MOTION_PATH
, Any( aTargetSequence
) );
2033 pViewShell
->GetViewFrame()->GetDispatcher()->Execute( nSID
, SFX_CALLMODE_ASYNCHRON
, &aItem
, 0 );
2038 void CustomAnimationPane::onRemove()
2040 if( maListSelection
.size() )
2044 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
2046 EffectSequence
aList( maListSelection
);
2048 EffectSequence::iterator
aIter( aList
.begin() );
2049 const EffectSequence::iterator
aEnd( aList
.end() );
2050 while( aIter
!= aEnd
)
2052 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2053 if( pEffect
->getEffectSequence() )
2054 pEffect
->getEffectSequence()->remove( pEffect
);
2057 maListSelection
.clear();
2058 mrBase
.GetDocShell()->SetModified();
2062 void CustomAnimationPane::remove( CustomAnimationEffectPtr
& pEffect
)
2064 if( pEffect
->getEffectSequence() )
2067 pEffect
->getEffectSequence()->remove( pEffect
);
2068 mrBase
.GetDocShell()->SetModified();
2072 void CustomAnimationPane::onChangeStart()
2074 if( mpLBStart
->GetSelectEntryCount() == 1 )
2076 sal_Int16 nNodeType
;
2077 USHORT nPos
= mpLBStart
->GetSelectEntryPos();
2080 case 0: nNodeType
= EffectNodeType::ON_CLICK
; break;
2081 case 1: nNodeType
= EffectNodeType::WITH_PREVIOUS
; break;
2082 case 2: nNodeType
= EffectNodeType::AFTER_PREVIOUS
; break;
2087 onChangeStart( nNodeType
);
2091 void CustomAnimationPane::onChangeStart( sal_Int16 nNodeType
)
2095 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
2097 bool bNeedRebuild
= false;
2099 EffectSequence::iterator
aIter( maListSelection
.begin() );
2100 const EffectSequence::iterator
aEnd( maListSelection
.end() );
2101 while( aIter
!= aEnd
)
2103 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2104 if( pEffect
->getNodeType() != nNodeType
)
2106 pEffect
->setNodeType( nNodeType
);
2107 bNeedRebuild
= true;
2113 mpMainSequence
->rebuild();
2115 mrBase
.GetDocShell()->SetModified();
2119 void CustomAnimationPane::onChangeProperty()
2121 if( mpLBProperty
->getSubControl() )
2125 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
2127 const Any
aValue( mpLBProperty
->getSubControl()->getValue() );
2129 bool bNeedUpdate
= false;
2131 // change selected effect
2132 EffectSequence::iterator
aIter( maListSelection
.begin() );
2133 const EffectSequence::iterator
aEnd( maListSelection
.end() );
2134 while( aIter
!= aEnd
)
2136 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2138 if( setProperty1Value( mnPropertyType
, pEffect
, aValue
) )
2144 mpMainSequence
->rebuild();
2146 mrBase
.GetDocShell()->SetModified();
2153 void CustomAnimationPane::onChangeSpeed()
2155 if( mpCBSpeed
->GetSelectEntryCount() == 1 )
2159 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
2163 USHORT nPos
= mpCBSpeed
->GetSelectEntryPos();
2167 case 0: fDuration
= 5.0; break;
2168 case 1: fDuration
= 3.0; break;
2169 case 2: fDuration
= 2.0; break;
2170 case 3: fDuration
= 1.0; break;
2171 case 4: fDuration
= 0.5; break;
2176 // change selected effect
2177 EffectSequence::iterator
aIter( maListSelection
.begin() );
2178 const EffectSequence::iterator
aEnd( maListSelection
.end() );
2179 while( aIter
!= aEnd
)
2181 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2182 pEffect
->setDuration( fDuration
);
2185 mpMainSequence
->rebuild();
2187 mrBase
.GetDocShell()->SetModified();
2193 /// this link is called when the property box is modified by the user
2194 IMPL_LINK( CustomAnimationPane
, implPropertyHdl
, Control
*, EMPTYARG
)
2200 /// this link is called when one of the controls is modified
2201 IMPL_LINK( CustomAnimationPane
, implControlHdl
, Control
*, pControl
)
2203 if( pControl
== mpPBAddEffect
)
2205 else if( pControl
== mpPBChangeEffect
)
2207 else if( pControl
== mpPBRemoveEffect
)
2209 else if( pControl
== mpLBStart
)
2211 else if( pControl
== mpCBSpeed
)
2213 else if( pControl
== mpPBPropertyMore
)
2215 else if( pControl
== mpPBMoveUp
)
2216 moveSelection( true );
2217 else if( pControl
== mpPBMoveDown
)
2218 moveSelection( false );
2219 else if( pControl
== mpPBPlay
)
2221 else if( pControl
== mpPBSlideShow
)
2223 mrBase
.StartPresentation();
2225 else if( pControl
== mpCBAutoPreview
)
2227 SdOptions
* pOptions
= SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS
);
2228 pOptions
->SetPreviewChangedEffects( mpCBAutoPreview
->IsChecked() ? sal_True
: sal_False
);
2236 IMPL_LINK(CustomAnimationPane
, lateInitCallback
, Timer
*, EMPTYARG
)
2238 // Call getPresets() to initiate the (expensive) construction of the
2242 // update selection and control states
2243 onSelectionChanged();
2248 void CustomAnimationPane::moveSelection( bool bUp
)
2250 if( maListSelection
.empty() )
2253 EffectSequenceHelper
* pSequence
= maListSelection
.front()->getEffectSequence();
2254 if( pSequence
== 0 )
2259 bool bChanged
= false;
2261 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
2262 EffectSequence
& rEffectSequence
= pSequence
->getSequence();
2266 EffectSequence::iterator
aIter( maListSelection
.begin() );
2267 const EffectSequence::iterator
aEnd( maListSelection
.end() );
2269 while( aIter
!= aEnd
)
2271 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2273 EffectSequence::iterator
aEffectPos( pSequence
->find( pEffect
) );
2274 if( aEffectPos
!= rEffectSequence
.end() )
2276 EffectSequence::iterator
aInsertPos( rEffectSequence
.erase( aEffectPos
) );
2278 if( aInsertPos
!= rEffectSequence
.begin() )
2281 while( (aInsertPos
!= rEffectSequence
.begin()) && !mpCustomAnimationList
->isExpanded(*aInsertPos
))
2284 rEffectSequence
.insert( aInsertPos
, pEffect
);
2288 rEffectSequence
.push_front( pEffect
);
2296 EffectSequence::reverse_iterator
aIter( maListSelection
.rbegin() );
2297 const EffectSequence::reverse_iterator
aEnd( maListSelection
.rend() );
2299 while( aIter
!= aEnd
)
2301 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2303 EffectSequence::iterator
aEffectPos( pSequence
->find( pEffect
) );
2304 if( aEffectPos
!= rEffectSequence
.end() )
2306 EffectSequence::iterator
aInsertPos( rEffectSequence
.erase( aEffectPos
) );
2308 if( aInsertPos
!= rEffectSequence
.end() )
2311 while( (aInsertPos
!= rEffectSequence
.end()) && !mpCustomAnimationList
->isExpanded(*aInsertPos
))
2314 rEffectSequence
.insert( aInsertPos
, pEffect
);
2318 rEffectSequence
.push_back( pEffect
);
2327 mpMainSequence
->rebuild();
2329 mrBase
.GetDocShell()->SetModified();
2333 void CustomAnimationPane::onPreview( bool bForcePreview
)
2335 if( !bForcePreview
&& !mpCBAutoPreview
->IsChecked() )
2338 if( maListSelection
.empty() )
2340 rtl::Reference
< MotionPathTag
> xMotionPathTag
;
2341 MotionPathTagVector::iterator aIter
;
2342 for( aIter
= maMotionPathTags
.begin(); aIter
!= maMotionPathTags
.end(); aIter
++ )
2344 if( (*aIter
)->isSelected() )
2346 xMotionPathTag
= (*aIter
);
2351 if( xMotionPathTag
.is() )
2353 MainSequencePtr
pSequence( new MainSequence() );
2354 pSequence
->append( xMotionPathTag
->getEffect()->clone() );
2355 preview( pSequence
->getRootNode() );
2359 Reference
< XAnimationNodeSupplier
> xNodeSupplier( mxCurrentPage
, UNO_QUERY
);
2360 if( !xNodeSupplier
.is() )
2363 preview( xNodeSupplier
->getAnimationNode() );
2368 MainSequencePtr
pSequence( new MainSequence() );
2370 EffectSequence::iterator
aIter( maListSelection
.begin() );
2371 const EffectSequence::iterator
aEnd( maListSelection
.end() );
2373 while( aIter
!= aEnd
)
2375 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2376 pSequence
->append( pEffect
->clone() );
2379 preview( pSequence
->getRootNode() );
2383 void CustomAnimationPane::preview( const Reference
< XAnimationNode
>& xAnimationNode
)
2385 Reference
< XTimeContainer
> xRoot(::comphelper::getProcessServiceFactory()->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.animations.ParallelTimeContainer"))), UNO_QUERY
);
2388 Sequence
< ::com::sun::star::beans::NamedValue
> aUserData( 1 );
2389 aUserData
[0].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "node-type" ) );
2390 aUserData
[0].Value
<<= ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT
;
2391 xRoot
->setUserData( aUserData
);
2392 xRoot
->appendChild( xAnimationNode
);
2394 Reference
< XAnimationNode
> xNode( xRoot
, UNO_QUERY
);
2395 SlideShow::StartPreview( mrBase
, mxCurrentPage
, xNode
);
2400 // ICustomAnimationListController
2401 void CustomAnimationPane::onSelect()
2403 maListSelection
= mpCustomAnimationList
->getSelection();
2405 markShapesFromSelectedEffects();
2411 const CustomAnimationPresets
& CustomAnimationPane::getPresets (void)
2413 if (mpCustomAnimationPresets
== NULL
)
2414 mpCustomAnimationPresets
= &CustomAnimationPresets::getCustomAnimationPresets();
2415 return *mpCustomAnimationPresets
;
2420 void CustomAnimationPane::markShapesFromSelectedEffects()
2422 if( !maSelectionLock
.isLocked() )
2424 ScopeLockGuard
aGuard( maSelectionLock
);
2425 DrawViewShell
* pViewShell
= dynamic_cast< DrawViewShell
* >(
2426 FrameworkHelper::Instance(mrBase
)->GetViewShell(FrameworkHelper::msCenterPaneURL
).get());
2427 DrawView
* pView
= pViewShell
? pViewShell
->GetDrawView() : NULL
;
2431 pView
->UnmarkAllObj();
2432 EffectSequence::iterator
aIter( maListSelection
.begin() );
2433 const EffectSequence::iterator
aEnd( maListSelection
.end() );
2434 while( aIter
!= aEnd
)
2436 CustomAnimationEffectPtr pEffect
= (*aIter
++);
2438 Reference
< XShape
> xShape( pEffect
->getTargetShape() );
2439 SdrObject
* pObj
= GetSdrObjectFromXShape( xShape
);
2441 pView
->MarkObj(pObj
, pView
->GetSdrPageView(), FALSE
, FALSE
);
2448 void CustomAnimationPane::updatePathFromMotionPathTag( const rtl::Reference
< MotionPathTag
>& xTag
)
2450 MainSequenceRebuildGuard
aGuard( mpMainSequence
);
2453 SdrPathObj
* pPathObj
= xTag
->getPathObj();
2454 CustomAnimationEffectPtr pEffect
= xTag
->getEffect();
2455 if( (pPathObj
!= 0) && pEffect
.get() != 0 )
2457 SfxUndoManager
* pManager
= mrBase
.GetDocShell()->GetUndoManager();
2460 SdPage
* pPage
= SdPage::getImplementation( mxCurrentPage
);
2462 pManager
->AddUndoAction( new UndoAnimationPath( mrBase
.GetDocShell()->GetDoc(), pPage
, pEffect
->getNode() ) );
2465 pEffect
->updatePathFromSdrPathObj( *pPathObj
);
2470 // ====================================================================
2472 ::Window
* createCustomAnimationPanel( ::Window
* pParent
, ViewShellBase
& rBase
)
2474 DialogListBox
* pWindow
= 0;
2476 DrawDocShell
* pDocSh
= rBase
.GetDocShell();
2479 pWindow
= new DialogListBox( pParent
, WB_CLIPCHILDREN
|WB_TABSTOP
|WB_AUTOHSCROLL
);
2481 Size
aMinSize( pWindow
->LogicToPixel( Size( 80, 256 ), MAP_APPFONT
) );
2482 ::Window
* pPaneWindow
= new CustomAnimationPane( pWindow
, rBase
, aMinSize
);
2483 pWindow
->SetChildWindow( pPaneWindow
, aMinSize
);
2484 pWindow
->SetText( pPaneWindow
->GetText() );