Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include <com/sun/star/presentation/EffectPresetClass.hpp>
22 : #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
23 : #include <com/sun/star/animations/ParallelTimeContainer.hpp>
24 : #include <com/sun/star/view/XSelectionSupplier.hpp>
25 : #include <com/sun/star/drawing/XDrawView.hpp>
26 : #include <com/sun/star/drawing/XShape.hpp>
27 : #include <com/sun/star/beans/XPropertySet.hpp>
28 : #include <com/sun/star/presentation/EffectNodeType.hpp>
29 : #include <com/sun/star/presentation/EffectCommands.hpp>
30 : #include <com/sun/star/animations/AnimationTransformType.hpp>
31 : #include <com/sun/star/text/XTextRangeCompare.hpp>
32 : #include <com/sun/star/container/XEnumerationAccess.hpp>
33 : #include <com/sun/star/container/XIndexAccess.hpp>
34 : #include <com/sun/star/presentation/ParagraphTarget.hpp>
35 : #include <com/sun/star/text/XText.hpp>
36 : #include <com/sun/star/awt/XWindow.hpp>
37 : #include <com/sun/star/drawing/LineStyle.hpp>
38 : #include <com/sun/star/drawing/FillStyle.hpp>
39 : #include <comphelper/processfactory.hxx>
40 : #include <sfx2/dispatch.hxx>
41 : #include "STLPropertySet.hxx"
42 : #include "CustomAnimationPane.hxx"
43 : #include "CustomAnimationDialog.hxx"
44 : #include "CustomAnimationCreateDialog.hxx"
45 : #include "CustomAnimation.hrc"
46 : #include "CustomAnimationList.hxx"
47 : #include <vcl/lstbox.hxx>
48 : #include <vcl/fixed.hxx>
49 :
50 : #include <vcl/button.hxx>
51 : #include <vcl/combobox.hxx>
52 : #include <vcl/scrbar.hxx>
53 :
54 : #include <comphelper/sequence.hxx>
55 : #include <sfx2/frame.hxx>
56 : #include <sfx2/sidebar/Theme.hxx>
57 :
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"
69 : #include "sddll.hxx"
70 : #include "framework/FrameworkHelper.hxx"
71 :
72 : #include "EventMultiplexer.hxx"
73 :
74 : #include "glob.hrc"
75 : #include "sdpage.hxx"
76 : #include "drawdoc.hxx"
77 : #include "app.hrc"
78 :
79 : #include <algorithm>
80 :
81 : #include <basegfx/polygon/b2dpolypolygontools.hxx>
82 : #include <basegfx/matrix/b2dhommatrix.hxx>
83 : #include <basegfx/range/b2drange.hxx>
84 :
85 : using namespace ::com::sun::star;
86 : using namespace ::com::sun::star::animations;
87 : using namespace ::com::sun::star::presentation;
88 : using namespace ::com::sun::star::text;
89 :
90 : using namespace ::com::sun::star::uno;
91 : using namespace ::com::sun::star::drawing;
92 : using ::com::sun::star::view::XSelectionSupplier;
93 : using ::com::sun::star::view::XSelectionChangeListener;
94 : using ::com::sun::star::frame::XController;
95 : using ::com::sun::star::frame::XModel;
96 : using ::com::sun::star::beans::XPropertySet;
97 : using ::com::sun::star::beans::XPropertyChangeListener;
98 : using ::com::sun::star::container::XIndexAccess;
99 : using ::com::sun::star::container::XEnumerationAccess;
100 : using ::com::sun::star::container::XEnumeration;
101 : using ::com::sun::star::text::XText;
102 : using ::sd::framework::FrameworkHelper;
103 :
104 : namespace sd {
105 :
106 :
107 :
108 0 : void fillDurationComboBox( ListBox* pBox )
109 : {
110 : static const double gdVerySlow = 5.0;
111 : static const double gdSlow = 3.0;
112 : static const double gdNormal = 2.0;
113 : static const double gdFast = 1.0;
114 : static const double gdVeryFast = 0.5;
115 :
116 0 : OUString aVerySlow( SD_RESSTR( STR_CUSTOMANIMATION_DURATION_VERY_SLOW ) );
117 0 : pBox->SetEntryData( pBox->InsertEntry( aVerySlow ), (void*)&gdVerySlow );
118 :
119 0 : OUString aSlow( SD_RESSTR( STR_CUSTOMANIMATION_DURATION_SLOW ) );
120 0 : pBox->SetEntryData( pBox->InsertEntry( aSlow ), (void*)&gdSlow );
121 :
122 0 : OUString aNormal( SD_RESSTR( STR_CUSTOMANIMATION_DURATION_NORMAL ) );
123 0 : pBox->SetEntryData( pBox->InsertEntry( aNormal ), (void*)&gdNormal );
124 :
125 0 : OUString aFast( SD_RESSTR( STR_CUSTOMANIMATION_DURATION_FAST ) );
126 0 : pBox->SetEntryData( pBox->InsertEntry( aFast ), (void*)&gdFast );
127 :
128 0 : OUString aVeryFast( SD_RESSTR( STR_CUSTOMANIMATION_DURATION_VERY_FAST ) );
129 0 : pBox->SetEntryData( pBox->InsertEntry( aVeryFast ), (void*)&gdVeryFast );
130 0 : }
131 :
132 0 : void fillRepeatComboBox( ListBox* pBox )
133 : {
134 0 : OUString aNone( SD_RESSTR( STR_CUSTOMANIMATION_REPEAT_NONE ) );
135 0 : pBox->SetEntryData( pBox->InsertEntry( aNone ), (void*)((sal_Int32)0) );
136 :
137 0 : pBox->SetEntryData( pBox->InsertEntry( OUString::number( 2 ) ), (void*)((sal_Int32)1) );
138 0 : pBox->SetEntryData( pBox->InsertEntry( OUString::number( 3 ) ), (void*)((sal_Int32)3) );
139 0 : pBox->SetEntryData( pBox->InsertEntry( OUString::number( 4 ) ), (void*)((sal_Int32)4) );
140 0 : pBox->SetEntryData( pBox->InsertEntry( OUString::number( 5 ) ), (void*)((sal_Int32)5) );
141 0 : pBox->SetEntryData( pBox->InsertEntry( OUString::number( 10 ) ), (void*)((sal_Int32)10) );
142 :
143 0 : OUString aUntilClick( SD_RESSTR( STR_CUSTOMANIMATION_REPEAT_UNTIL_NEXT_CLICK ) );
144 0 : pBox->SetEntryData( pBox->InsertEntry( aUntilClick ), (void*)((sal_Int32)-1) );
145 :
146 0 : OUString aEndOfSlide( SD_RESSTR( STR_CUSTOMANIMATION_REPEAT_UNTIL_END_OF_SLIDE ) );
147 0 : pBox->SetEntryData( pBox->InsertEntry( aEndOfSlide ), (void*)((sal_Int32)-2) );
148 0 : }
149 :
150 :
151 :
152 :
153 0 : CustomAnimationPane::CustomAnimationPane( ::Window* pParent, ViewShellBase& rBase,
154 : const cssu::Reference<css::frame::XFrame>& rxFrame,
155 : const Size& rMinSize )
156 : : PanelLayout( pParent, "CustomAnimationsPanel", "modules/simpress/ui/customanimationspanel.ui", rxFrame ),
157 : mrBase( rBase ),
158 : mpCustomAnimationPresets(NULL),
159 : mnPropertyType( nPropertyTypeNone ),
160 : maMinSize( rMinSize ),
161 0 : mxModel( rBase.GetDocShell()->GetDoc()->getUnoModel(), UNO_QUERY ),
162 0 : maLateInitTimer()
163 : {
164 : // load resources
165 0 : get(mpPBAddEffect, "add_effect");
166 0 : get(mpPBChangeEffect, "change_effect");
167 0 : get(mpPBRemoveEffect, "remove_effect");
168 :
169 0 : get(mpFTEffect, "effect_label");
170 :
171 0 : get(mpFTStart, "start_effect");
172 0 : get(mpLBStart, "start_effect_list");
173 0 : get(mpFTProperty, "effect_property");
174 0 : get(mpPlaceholderBox, "placeholder");
175 0 : get(mpLBProperty, "effect_property_list");
176 0 : get(mpPBPropertyMore, "more_properties");
177 :
178 0 : get(mpFTSpeed, "effect_speed");
179 0 : get(mpCBSpeed, "effect_speed_list");
180 :
181 0 : get(mpCustomAnimationList, "custom_animation_list");
182 0 : mpCustomAnimationList->setController( dynamic_cast<ICustomAnimationListController*> ( this ) );
183 0 : mpCustomAnimationList->set_width_request(mpCustomAnimationList->approximate_char_width() * 16);
184 0 : mpCustomAnimationList->set_height_request(mpCustomAnimationList->GetTextHeight() * 16);
185 :
186 0 : get(mpPBMoveUp, "move_up");
187 0 : get(mpPBMoveDown, "move_down");
188 0 : get(mpPBPlay, "play");
189 0 : get(mpCBAutoPreview,"auto_preview");
190 :
191 0 : maStrProperty = mpFTProperty->GetText();
192 :
193 0 : fillDurationComboBox( mpCBSpeed );
194 :
195 0 : mpPBAddEffect->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) );
196 0 : mpPBChangeEffect->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) );
197 0 : mpPBRemoveEffect->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) );
198 0 : mpLBStart->SetSelectHdl( LINK( this, CustomAnimationPane, implControlHdl ) );
199 0 : mpCBSpeed->SetSelectHdl( LINK( this, CustomAnimationPane, implControlHdl ) );
200 0 : mpPBPropertyMore->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) );
201 0 : mpPBMoveUp->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) );
202 0 : mpPBMoveDown->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) );
203 0 : mpPBPlay->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) );
204 0 : mpCBAutoPreview->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) );
205 :
206 0 : maStrModify = mpFTEffect->GetText();
207 :
208 : // get current controller and initialize listeners
209 : try
210 : {
211 0 : mxView = Reference< XDrawView >::query(mrBase.GetController());
212 0 : addListener();
213 : }
214 0 : catch( Exception& )
215 : {
216 : OSL_FAIL( "sd::CustomAnimationPane::CustomAnimationPane(), Exception caught!" );
217 : }
218 :
219 : // get current page and update custom animation list
220 0 : onChangeCurrentPage();
221 :
222 : // Wait a short time before the presets list is created. This gives the
223 : // system time to paint the control.
224 0 : maLateInitTimer.SetTimeout(100);
225 0 : maLateInitTimer.SetTimeoutHdl(LINK(this, CustomAnimationPane, lateInitCallback));
226 0 : maLateInitTimer.Start();
227 :
228 0 : UpdateLook();
229 0 : }
230 :
231 0 : CustomAnimationPane::~CustomAnimationPane()
232 : {
233 0 : maLateInitTimer.Stop();
234 :
235 0 : removeListener();
236 :
237 0 : MotionPathTagVector aTags;
238 0 : aTags.swap( maMotionPathTags );
239 0 : MotionPathTagVector::iterator aIter;
240 0 : for( aIter = aTags.begin(); aIter != aTags.end(); ++aIter )
241 0 : (*aIter)->Dispose();
242 :
243 0 : }
244 :
245 0 : void CustomAnimationPane::addUndo()
246 : {
247 0 : ::svl::IUndoManager* pManager = mrBase.GetDocShell()->GetUndoManager();
248 0 : if( pManager )
249 : {
250 0 : SdPage* pPage = SdPage::getImplementation( mxCurrentPage );
251 0 : if( pPage )
252 0 : pManager->AddUndoAction( new UndoAnimation( mrBase.GetDocShell()->GetDoc(), pPage ) );
253 : }
254 0 : }
255 :
256 0 : void CustomAnimationPane::StateChanged( StateChangedType nStateChange )
257 : {
258 0 : Control::StateChanged( nStateChange );
259 :
260 0 : if( nStateChange == STATE_CHANGE_VISIBLE )
261 0 : updateMotionPathTags();
262 0 : }
263 :
264 0 : void CustomAnimationPane::KeyInput( const KeyEvent& rKEvt )
265 : {
266 0 : if( mpCustomAnimationList )
267 0 : mpCustomAnimationList->KeyInput( rKEvt );
268 0 : }
269 :
270 0 : void CustomAnimationPane::addListener()
271 : {
272 0 : Link aLink( LINK(this,CustomAnimationPane,EventMultiplexerListener) );
273 : mrBase.GetEventMultiplexer()->AddEventListener (
274 : aLink,
275 : tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
276 : | tools::EventMultiplexerEvent::EID_CURRENT_PAGE
277 : | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
278 : | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
279 : | tools::EventMultiplexerEvent::EID_DISPOSING
280 0 : | tools::EventMultiplexerEvent::EID_END_TEXT_EDIT);
281 0 : }
282 :
283 0 : void CustomAnimationPane::removeListener()
284 : {
285 0 : Link aLink( LINK(this,CustomAnimationPane,EventMultiplexerListener) );
286 0 : mrBase.GetEventMultiplexer()->RemoveEventListener( aLink );
287 0 : }
288 :
289 0 : IMPL_LINK(CustomAnimationPane,EventMultiplexerListener,
290 : tools::EventMultiplexerEvent*,pEvent)
291 : {
292 0 : switch (pEvent->meEventId)
293 : {
294 : case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION:
295 0 : onSelectionChanged();
296 0 : break;
297 :
298 : case tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
299 0 : onChangeCurrentPage();
300 0 : break;
301 :
302 : case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
303 : // At this moment the controller may not yet been set at model
304 : // or ViewShellBase. Take it from the view shell passed with
305 : // the event.
306 0 : if (mrBase.GetMainViewShell() != 0)
307 : {
308 0 : if( mrBase.GetMainViewShell()->GetShellType() == ViewShell::ST_IMPRESS )
309 : {
310 0 : mxView = Reference<XDrawView>::query(mrBase.GetDrawController());
311 0 : onSelectionChanged();
312 0 : onChangeCurrentPage();
313 0 : break;
314 : }
315 : }
316 : // fall through intended
317 : case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
318 0 : mxView = 0;
319 0 : mxCurrentPage = 0;
320 0 : updateControls();
321 0 : break;
322 :
323 : case tools::EventMultiplexerEvent::EID_DISPOSING:
324 0 : mxView.clear();
325 0 : onSelectionChanged();
326 0 : onChangeCurrentPage();
327 0 : break;
328 : case tools::EventMultiplexerEvent::EID_END_TEXT_EDIT:
329 0 : if( mpMainSequence.get() && pEvent->mpUserData )
330 0 : mpCustomAnimationList->update( mpMainSequence );
331 0 : break;
332 : }
333 0 : return 0;
334 : }
335 :
336 0 : static sal_Int32 getPropertyType( const OUString& rProperty )
337 : {
338 0 : if ( rProperty == "Direction" )
339 0 : return nPropertyTypeDirection;
340 :
341 0 : if ( rProperty == "Spokes" )
342 0 : return nPropertyTypeSpokes;
343 :
344 0 : if ( rProperty == "Zoom" )
345 0 : return nPropertyTypeZoom;
346 :
347 0 : if ( rProperty == "Accelerate" )
348 0 : return nPropertyTypeAccelerate;
349 :
350 0 : if ( rProperty == "Decelerate" )
351 0 : return nPropertyTypeDecelerate;
352 :
353 0 : if ( rProperty == "Color1" )
354 0 : return nPropertyTypeFirstColor;
355 :
356 0 : if ( rProperty == "Color2" )
357 0 : return nPropertyTypeSecondColor;
358 :
359 0 : if ( rProperty == "FillColor" )
360 0 : return nPropertyTypeFillColor;
361 :
362 0 : if ( rProperty == "ColorStyle" )
363 0 : return nPropertyTypeColorStyle;
364 :
365 0 : if ( rProperty == "AutoReverse" )
366 0 : return nPropertyTypeAutoReverse;
367 :
368 0 : if ( rProperty == "FontStyle" )
369 0 : return nPropertyTypeFont;
370 :
371 0 : if ( rProperty == "CharColor" )
372 0 : return nPropertyTypeCharColor;
373 :
374 0 : if ( rProperty == "CharHeight" )
375 0 : return nPropertyTypeCharHeight;
376 :
377 0 : if ( rProperty == "CharDecoration" )
378 0 : return nPropertyTypeCharDecoration;
379 :
380 0 : if ( rProperty == "LineColor" )
381 0 : return nPropertyTypeLineColor;
382 :
383 0 : if ( rProperty == "Rotate" )
384 0 : return nPropertyTypeRotate;
385 :
386 0 : if ( rProperty == "Transparency" )
387 0 : return nPropertyTypeTransparency;
388 :
389 0 : if ( rProperty == "Color" )
390 0 : return nPropertyTypeColor;
391 :
392 0 : if ( rProperty == "Scale" )
393 0 : return nPropertyTypeScale;
394 :
395 0 : return nPropertyTypeNone;
396 : }
397 :
398 0 : OUString getPropertyName( sal_Int32 nPropertyType )
399 : {
400 0 : switch( nPropertyType )
401 : {
402 : case nPropertyTypeDirection:
403 0 : return SD_RESSTR(STR_CUSTOMANIMATION_DIRECTION_PROPERTY);
404 :
405 : case nPropertyTypeSpokes:
406 0 : return SD_RESSTR(STR_CUSTOMANIMATION_SPOKES_PROPERTY);
407 :
408 : case nPropertyTypeFirstColor:
409 0 : return SD_RESSTR(STR_CUSTOMANIMATION_FIRST_COLOR_PROPERTY);
410 :
411 : case nPropertyTypeSecondColor:
412 0 : return SD_RESSTR(STR_CUSTOMANIMATION_SECOND_COLOR_PROPERTY);
413 :
414 : case nPropertyTypeZoom:
415 0 : return SD_RESSTR(STR_CUSTOMANIMATION_ZOOM_PROPERTY);
416 :
417 : case nPropertyTypeFillColor:
418 0 : return SD_RESSTR(STR_CUSTOMANIMATION_FILL_COLOR_PROPERTY);
419 :
420 : case nPropertyTypeColorStyle:
421 0 : return SD_RESSTR(STR_CUSTOMANIMATION_STYLE_PROPERTY);
422 :
423 : case nPropertyTypeFont:
424 0 : return SD_RESSTR(STR_CUSTOMANIMATION_FONT_PROPERTY);
425 :
426 : case nPropertyTypeCharHeight:
427 0 : return SD_RESSTR(STR_CUSTOMANIMATION_SIZE_PROPERTY);
428 :
429 : case nPropertyTypeCharColor:
430 0 : return SD_RESSTR(STR_CUSTOMANIMATION_FONT_COLOR_PROPERTY);
431 :
432 : case nPropertyTypeCharHeightStyle:
433 0 : return SD_RESSTR(STR_CUSTOMANIMATION_FONT_SIZE_STYLE_PROPERTY);
434 :
435 : case nPropertyTypeCharDecoration:
436 0 : return SD_RESSTR(STR_CUSTOMANIMATION_FONT_STYLE_PROPERTY);
437 :
438 : case nPropertyTypeLineColor:
439 0 : return SD_RESSTR(STR_CUSTOMANIMATION_LINE_COLOR_PROPERTY);
440 :
441 : case nPropertyTypeRotate:
442 0 : return SD_RESSTR(STR_CUSTOMANIMATION_AMOUNT_PROPERTY);
443 :
444 : case nPropertyTypeColor:
445 0 : return SD_RESSTR(STR_CUSTOMANIMATION_COLOR_PROPERTY);
446 :
447 : case nPropertyTypeTransparency:
448 0 : return SD_RESSTR(STR_CUSTOMANIMATION_AMOUNT_PROPERTY);
449 :
450 : case nPropertyTypeScale:
451 0 : return SD_RESSTR(STR_CUSTOMANIMATION_SCALE_PROPERTY);
452 : }
453 :
454 0 : return OUString();
455 : }
456 :
457 0 : void CustomAnimationPane::updateControls()
458 : {
459 0 : mpFTSpeed->Enable( mxView.is() );
460 0 : mpCBSpeed->Enable( mxView.is() );
461 0 : mpCustomAnimationList->Enable( mxView.is() );
462 0 : mpPBMoveUp->Enable( mxView.is() );
463 0 : mpPBMoveDown->Enable( mxView.is() );
464 0 : mpPBPlay->Enable( mxView.is() );
465 0 : mpCBAutoPreview->Enable( mxView.is() );
466 :
467 0 : if( !mxView.is() )
468 : {
469 0 : mpPBAddEffect->Enable( false );
470 0 : mpPBChangeEffect->Enable( false );
471 0 : mpPBRemoveEffect->Enable( false );
472 0 : mpFTStart->Enable( false );
473 0 : mpLBStart->Enable( false );
474 0 : mpPBPropertyMore->Enable( false );
475 0 : mpLBProperty->Enable( false );
476 0 : mpFTProperty->Enable( false );
477 0 : mpCustomAnimationList->clear();
478 0 : return;
479 : }
480 :
481 0 : const int nSelectionCount = maListSelection.size();
482 :
483 0 : mpPBAddEffect->Enable( maViewSelection.hasValue() );
484 0 : mpPBChangeEffect->Enable( nSelectionCount);
485 0 : mpPBRemoveEffect->Enable(nSelectionCount);
486 :
487 0 : mpFTStart->Enable(nSelectionCount > 0);
488 0 : mpLBStart->Enable(nSelectionCount > 0);
489 0 : mpPBPropertyMore->Enable(nSelectionCount > 0);
490 :
491 0 : mpFTProperty->SetText( maStrProperty );
492 :
493 0 : mnPropertyType = nPropertyTypeNone;
494 :
495 0 : if( nSelectionCount == 1 )
496 : {
497 0 : CustomAnimationEffectPtr pEffect = maListSelection.front();
498 :
499 0 : OUString aUIName( getPresets().getUINameForPresetId( pEffect->getPresetId() ) );
500 :
501 0 : OUString aTemp( maStrModify );
502 :
503 0 : if( !aUIName.isEmpty() )
504 : {
505 0 : aTemp += OUString( (sal_Unicode)' ' );
506 0 : aTemp += aUIName;
507 0 : mpFTEffect->SetText( aTemp );
508 : }
509 :
510 0 : CustomAnimationPresetPtr pDescriptor = getPresets().getEffectDescriptor( pEffect->getPresetId() );
511 0 : if( pDescriptor.get() )
512 : {
513 0 : PropertySubControl* pSubControl = NULL;
514 :
515 0 : Any aValue;
516 :
517 0 : UStringList aProperties( pDescriptor->getProperties() );
518 0 : if( aProperties.size() >= 1 )
519 : {
520 0 : mnPropertyType = getPropertyType( aProperties.front() );
521 :
522 0 : mpFTProperty->SetText( getPropertyName( mnPropertyType ) );
523 :
524 0 : aValue = getProperty1Value( mnPropertyType, pEffect );
525 : }
526 :
527 0 : if( aValue.hasValue() )
528 : {
529 0 : pSubControl = mpLBProperty->getSubControl();
530 0 : if( !pSubControl || (pSubControl->getControlType() != mnPropertyType) )
531 : {
532 0 : pSubControl = PropertySubControl::create( mnPropertyType, mpPlaceholderBox, aValue, pEffect->getPresetId(), LINK( this, CustomAnimationPane, implPropertyHdl ) );
533 0 : mpLBProperty->setSubControl( pSubControl );
534 : }
535 : else
536 : {
537 0 : pSubControl->setValue( aValue, pEffect->getPresetId() );
538 : }
539 : }
540 : else
541 : {
542 0 : mpLBProperty->setSubControl( 0 );
543 : }
544 :
545 0 : bool bEnable = (pSubControl != 0) && (pSubControl->getControl()->IsEnabled());
546 0 : mpLBProperty->Enable( bEnable );
547 0 : mpFTProperty->Enable( bEnable );
548 : }
549 : else
550 : {
551 0 : mpLBProperty->setSubControl( 0 );
552 0 : mpFTProperty->Enable( false );
553 0 : mpLBProperty->Enable( false );
554 0 : mpPBPropertyMore->Enable( false );
555 : }
556 :
557 0 : sal_uInt16 nPos = 0xffff;
558 :
559 0 : sal_Int16 nNodeType = pEffect->getNodeType();
560 0 : switch( nNodeType )
561 : {
562 0 : case EffectNodeType::ON_CLICK: nPos = 0; break;
563 0 : case EffectNodeType::WITH_PREVIOUS: nPos = 1; break;
564 0 : case EffectNodeType::AFTER_PREVIOUS: nPos = 2; break;
565 : }
566 :
567 0 : mpLBStart->SelectEntryPos( nPos );
568 :
569 0 : double fDuration = pEffect->getDuration();
570 0 : const bool bHasSpeed = fDuration > 0.001;
571 :
572 0 : mpFTSpeed->Enable(bHasSpeed);
573 0 : mpCBSpeed->Enable(bHasSpeed);
574 :
575 0 : if( bHasSpeed )
576 : {
577 0 : if( fDuration == 5.0 )
578 0 : nPos = 0;
579 0 : else if( fDuration == 3.0 )
580 0 : nPos = 1;
581 0 : else if( fDuration == 2.0 )
582 0 : nPos = 2;
583 0 : else if( fDuration == 1.0 )
584 0 : nPos = 3;
585 0 : else if( fDuration == 0.5 )
586 0 : nPos = 4;
587 : else
588 0 : nPos = 0xffff;
589 :
590 0 : mpCBSpeed->SelectEntryPos( nPos );
591 : }
592 :
593 0 : mpPBPropertyMore->Enable( true );
594 : }
595 : else
596 : {
597 0 : mpLBProperty->setSubControl( 0 );
598 0 : mpFTProperty->Enable( false );
599 0 : mpLBProperty->Enable( false );
600 0 : mpPBPropertyMore->Enable( false );
601 0 : mpFTSpeed->Enable(false);
602 0 : mpCBSpeed->Enable(false);
603 0 : mpLBStart->SetNoSelection();
604 0 : mpCBSpeed->SetNoSelection();
605 0 : mpFTEffect->SetText( maStrModify );
606 : }
607 :
608 0 : bool bEnableUp = true;
609 0 : bool bEnableDown = true;
610 0 : if( nSelectionCount == 0 )
611 : {
612 0 : bEnableUp = false;
613 0 : bEnableDown = false;
614 : }
615 : else
616 : {
617 0 : if( mpMainSequence->find( maListSelection.front() ) == mpMainSequence->getBegin() )
618 0 : bEnableUp = false;
619 :
620 0 : EffectSequence::iterator aIter( mpMainSequence->find( maListSelection.back() ) );
621 0 : if( aIter == mpMainSequence->getEnd() )
622 : {
623 0 : bEnableDown = false;
624 : }
625 : else
626 : {
627 0 : do
628 : {
629 0 : ++aIter;
630 : }
631 0 : while( (aIter != mpMainSequence->getEnd()) && !(mpCustomAnimationList->isExpanded((*aIter)) ) );
632 :
633 0 : if( aIter == mpMainSequence->getEnd() )
634 0 : bEnableDown = false;
635 : }
636 :
637 0 : if( bEnableUp || bEnableDown )
638 : {
639 0 : MainSequenceRebuildGuard aGuard( mpMainSequence );
640 :
641 0 : EffectSequenceHelper* pSequence = 0;
642 0 : EffectSequence::iterator aRebuildIter( maListSelection.begin() );
643 0 : const EffectSequence::iterator aRebuildEnd( maListSelection.end() );
644 0 : while( aRebuildIter != aRebuildEnd )
645 : {
646 0 : CustomAnimationEffectPtr pEffect = (*aRebuildIter++);
647 :
648 0 : if( pEffect.get() )
649 : {
650 0 : if( pSequence == 0 )
651 : {
652 0 : pSequence = pEffect->getEffectSequence();
653 : }
654 : else
655 : {
656 0 : if( pSequence != pEffect->getEffectSequence() )
657 : {
658 0 : bEnableUp = false;
659 0 : bEnableDown = false;
660 0 : break;
661 : }
662 : }
663 : }
664 0 : }
665 : }
666 : }
667 :
668 0 : mpPBMoveUp->Enable(bEnableUp);
669 0 : mpPBMoveDown->Enable(bEnableDown);
670 :
671 0 : SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
672 0 : mpCBAutoPreview->Check( pOptions->IsPreviewChangedEffects() == sal_True );
673 :
674 0 : updateMotionPathTags();
675 : }
676 :
677 0 : static bool updateMotionPathImpl( CustomAnimationPane& rPane, ::sd::View& rView, EffectSequence::iterator aIter, EffectSequence::iterator aEnd, MotionPathTagVector& rOldTags, MotionPathTagVector& rNewTags )
678 : {
679 0 : bool bChanges = false;
680 0 : while( aIter != aEnd )
681 : {
682 0 : CustomAnimationEffectPtr pEffect( (*aIter++) );
683 0 : if( pEffect.get() && pEffect->getPresetClass() == ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH )
684 : {
685 0 : rtl::Reference< MotionPathTag > xMotionPathTag;
686 : // first try to find if there is already a tag for this
687 0 : MotionPathTagVector::iterator aMIter( rOldTags.begin() );
688 0 : for( ; aMIter != rOldTags.end(); ++aMIter )
689 : {
690 0 : rtl::Reference< MotionPathTag > xTag( (*aMIter) );
691 0 : if( xTag->getEffect() == pEffect )
692 : {
693 0 : if( !xTag->isDisposed() )
694 : {
695 0 : xMotionPathTag = xTag;
696 0 : rOldTags.erase( aMIter );
697 : }
698 0 : break;
699 : }
700 0 : }
701 :
702 : // if not found, create new one
703 0 : if( !xMotionPathTag.is() )
704 : {
705 0 : xMotionPathTag.set( new MotionPathTag( rPane, rView, pEffect ) );
706 0 : bChanges = true;
707 : }
708 :
709 0 : if( xMotionPathTag.is() )
710 0 : rNewTags.push_back( xMotionPathTag );
711 : }
712 0 : }
713 :
714 0 : return bChanges;
715 : }
716 :
717 0 : void CustomAnimationPane::updateMotionPathTags()
718 : {
719 0 : bool bChanges = false;
720 :
721 0 : MotionPathTagVector aTags;
722 0 : aTags.swap( maMotionPathTags );
723 :
724 0 : ::sd::View* pView = 0;
725 :
726 0 : if( mxView.is() )
727 : {
728 0 : ::boost::shared_ptr<ViewShell> xViewShell( mrBase.GetMainViewShell() );
729 0 : if( xViewShell.get() )
730 0 : pView = xViewShell->GetView();
731 : }
732 :
733 0 : if( IsVisible() && mpMainSequence.get() && pView )
734 : {
735 0 : bChanges = updateMotionPathImpl( *this, *pView, mpMainSequence->getBegin(), mpMainSequence->getEnd(), aTags, maMotionPathTags );
736 :
737 0 : const InteractiveSequenceList& rISL = mpMainSequence->getInteractiveSequenceList();
738 0 : InteractiveSequenceList::const_iterator aISI( rISL.begin() );
739 0 : while( aISI != rISL.end() )
740 : {
741 0 : InteractiveSequencePtr pIS( (*aISI++) );
742 0 : bChanges |= updateMotionPathImpl( *this, *pView, pIS->getBegin(), pIS->getEnd(), aTags, maMotionPathTags );
743 0 : }
744 : }
745 :
746 0 : if( !aTags.empty() )
747 : {
748 0 : bChanges = true;
749 0 : MotionPathTagVector::iterator aIter( aTags.begin() );
750 0 : while( aIter != aTags.end() )
751 : {
752 0 : rtl::Reference< MotionPathTag > xTag( (*aIter++) );
753 0 : xTag->Dispose();
754 0 : }
755 : }
756 :
757 0 : if( bChanges && pView )
758 0 : pView->updateHandles();
759 0 : }
760 :
761 0 : void CustomAnimationPane::onSelectionChanged()
762 : {
763 0 : if( !maSelectionLock.isLocked() )
764 : {
765 0 : ScopeLockGuard aGuard( maSelectionLock );
766 :
767 0 : if( mxView.is() ) try
768 : {
769 0 : Reference< XSelectionSupplier > xSel( mxView, UNO_QUERY_THROW );
770 0 : if (xSel.is())
771 : {
772 0 : maViewSelection = xSel->getSelection();
773 0 : mpCustomAnimationList->onSelectionChanged( maViewSelection );
774 0 : updateControls();
775 0 : }
776 : }
777 0 : catch( Exception& )
778 : {
779 : OSL_FAIL( "sd::CustomAnimationPane::onSelectionChanged(), Exception caught!" );
780 0 : }
781 : }
782 0 : }
783 :
784 0 : void CustomAnimationPane::onDoubleClick()
785 : {
786 0 : showOptions();
787 0 : }
788 :
789 0 : void CustomAnimationPane::onContextMenu( sal_uInt16 nSelectedPopupEntry )
790 : {
791 0 : switch( nSelectedPopupEntry )
792 : {
793 0 : case CM_WITH_CLICK: onChangeStart( EffectNodeType::ON_CLICK ); break;
794 0 : case CM_WITH_PREVIOUS: onChangeStart( EffectNodeType::WITH_PREVIOUS ); break;
795 0 : case CM_AFTER_PREVIOUS: onChangeStart( EffectNodeType::AFTER_PREVIOUS ); break;
796 0 : case CM_OPTIONS: showOptions(); break;
797 0 : case CM_DURATION: showOptions("timing"); break;
798 0 : case CM_REMOVE: onRemove(); break;
799 0 : case CM_CREATE: if( maViewSelection.hasValue() ) onChange( true ); break;
800 : }
801 :
802 0 : updateControls();
803 0 : }
804 :
805 :
806 :
807 :
808 0 : void CustomAnimationPane::DataChanged (const DataChangedEvent& rEvent)
809 : {
810 : (void)rEvent;
811 0 : UpdateLook();
812 0 : }
813 :
814 :
815 :
816 :
817 0 : void CustomAnimationPane::UpdateLook (void)
818 : {
819 : const Wallpaper aBackground (
820 : ::sfx2::sidebar::Theme::GetWallpaper(
821 0 : ::sfx2::sidebar::Theme::Paint_PanelBackground));
822 0 : SetBackground(aBackground);
823 0 : if (mpFTStart != NULL)
824 0 : mpFTStart->SetBackground(aBackground);
825 0 : if (mpFTProperty != NULL)
826 0 : mpFTProperty->SetBackground(aBackground);
827 0 : if (mpFTSpeed != NULL)
828 0 : mpFTSpeed->SetBackground(aBackground);
829 0 : }
830 :
831 :
832 :
833 :
834 0 : void addValue( STLPropertySet* pSet, sal_Int32 nHandle, const Any& rValue )
835 : {
836 0 : switch( pSet->getPropertyState( nHandle ) )
837 : {
838 : case STLPropertyState_AMBIGUOUS:
839 : // value is already ambiguous, do nothing
840 0 : break;
841 : case STLPropertyState_DIRECT:
842 : // set to ambiguous if existing value is different
843 0 : if( rValue != pSet->getPropertyValue( nHandle ) )
844 0 : pSet->setPropertyState( nHandle, STLPropertyState_AMBIGUOUS );
845 0 : break;
846 : case STLPropertyState_DEFAULT:
847 : // just set new value
848 0 : pSet->setPropertyValue( nHandle, rValue );
849 0 : break;
850 : }
851 0 : }
852 :
853 0 : static sal_Int32 calcMaxParaDepth( Reference< XShape > xTargetShape )
854 : {
855 0 : sal_Int32 nMaxParaDepth = -1;
856 :
857 0 : if( xTargetShape.is() )
858 : {
859 0 : Reference< XEnumerationAccess > xText( xTargetShape, UNO_QUERY );
860 0 : if( xText.is() )
861 : {
862 0 : Reference< XPropertySet > xParaSet;
863 0 : const OUString strNumberingLevel( "NumberingLevel" );
864 :
865 0 : Reference< XEnumeration > xEnumeration( xText->createEnumeration(), UNO_QUERY_THROW );
866 0 : while( xEnumeration->hasMoreElements() )
867 : {
868 0 : xEnumeration->nextElement() >>= xParaSet;
869 0 : if( xParaSet.is() )
870 : {
871 0 : sal_Int32 nParaDepth = 0;
872 0 : xParaSet->getPropertyValue( strNumberingLevel ) >>= nParaDepth;
873 :
874 0 : if( nParaDepth > nMaxParaDepth )
875 0 : nMaxParaDepth = nParaDepth;
876 : }
877 0 : }
878 0 : }
879 : }
880 :
881 0 : return nMaxParaDepth + 1;
882 : }
883 :
884 0 : Any CustomAnimationPane::getProperty1Value( sal_Int32 nType, CustomAnimationEffectPtr pEffect )
885 : {
886 0 : switch( nType )
887 : {
888 : case nPropertyTypeDirection:
889 : case nPropertyTypeSpokes:
890 : case nPropertyTypeZoom:
891 0 : return makeAny( pEffect->getPresetSubType() );
892 :
893 : case nPropertyTypeColor:
894 : case nPropertyTypeFillColor:
895 : case nPropertyTypeFirstColor:
896 : case nPropertyTypeSecondColor:
897 : case nPropertyTypeCharColor:
898 : case nPropertyTypeLineColor:
899 : {
900 0 : const sal_Int32 nIndex = (nPropertyTypeFirstColor == nType) ? 0 : 1;
901 0 : return pEffect->getColor( nIndex );
902 : }
903 :
904 : case nPropertyTypeFont:
905 0 : return pEffect->getProperty( AnimationNodeType::SET, "CharFontName" , VALUE_TO );
906 :
907 : case nPropertyTypeCharHeight:
908 : {
909 0 : const OUString aAttributeName( "CharHeight" );
910 0 : Any aValue( pEffect->getProperty( AnimationNodeType::SET, aAttributeName, VALUE_TO ) );
911 0 : if( !aValue.hasValue() )
912 0 : aValue = pEffect->getProperty( AnimationNodeType::ANIMATE, aAttributeName, VALUE_TO );
913 0 : return aValue;
914 : }
915 :
916 : case nPropertyTypeRotate:
917 0 : return pEffect->getTransformationProperty( AnimationTransformType::ROTATE, VALUE_BY);
918 :
919 : case nPropertyTypeTransparency:
920 0 : return pEffect->getProperty( AnimationNodeType::SET, "Opacity" , VALUE_TO );
921 :
922 : case nPropertyTypeScale:
923 0 : return pEffect->getTransformationProperty( AnimationTransformType::SCALE, VALUE_BY );
924 :
925 : case nPropertyTypeCharDecoration:
926 : {
927 0 : Sequence< Any > aValues(3);
928 0 : aValues[0] = pEffect->getProperty( AnimationNodeType::SET, "CharWeight" , VALUE_TO );
929 0 : aValues[1] = pEffect->getProperty( AnimationNodeType::SET, "CharPosture" , VALUE_TO );
930 0 : aValues[2] = pEffect->getProperty( AnimationNodeType::SET, "CharUnderline" , VALUE_TO );
931 0 : return makeAny( aValues );
932 : }
933 : }
934 :
935 0 : Any aAny;
936 0 : return aAny;
937 : }
938 :
939 0 : bool CustomAnimationPane::setProperty1Value( sal_Int32 nType, CustomAnimationEffectPtr pEffect, const Any& rValue )
940 : {
941 0 : bool bEffectChanged = false;
942 0 : switch( nType )
943 : {
944 : case nPropertyTypeDirection:
945 : case nPropertyTypeSpokes:
946 : case nPropertyTypeZoom:
947 : {
948 0 : OUString aPresetSubType;
949 0 : rValue >>= aPresetSubType;
950 0 : if( aPresetSubType != pEffect->getPresetSubType() )
951 : {
952 0 : getPresets().changePresetSubType( pEffect, aPresetSubType );
953 0 : bEffectChanged = true;
954 0 : }
955 : }
956 0 : break;
957 :
958 : case nPropertyTypeFillColor:
959 : case nPropertyTypeColor:
960 : case nPropertyTypeFirstColor:
961 : case nPropertyTypeSecondColor:
962 : case nPropertyTypeCharColor:
963 : case nPropertyTypeLineColor:
964 : {
965 0 : const sal_Int32 nIndex = (nPropertyTypeFirstColor == nType) ? 0 : 1;
966 0 : Any aOldColor( pEffect->getColor( nIndex ) );
967 0 : if( aOldColor != rValue )
968 : {
969 0 : pEffect->setColor( nIndex, rValue );
970 0 : bEffectChanged = true;
971 0 : }
972 : }
973 0 : break;
974 :
975 : case nPropertyTypeFont:
976 0 : bEffectChanged = pEffect->setProperty( AnimationNodeType::SET, "CharFontName" , VALUE_TO, rValue );
977 0 : break;
978 :
979 : case nPropertyTypeCharHeight:
980 : {
981 0 : const OUString aAttributeName( "CharHeight" );
982 0 : bEffectChanged = pEffect->setProperty( AnimationNodeType::SET, aAttributeName, VALUE_TO, rValue );
983 0 : if( !bEffectChanged )
984 0 : bEffectChanged = pEffect->setProperty( AnimationNodeType::ANIMATE, aAttributeName, VALUE_TO, rValue );
985 : }
986 0 : break;
987 : case nPropertyTypeRotate:
988 0 : bEffectChanged = pEffect->setTransformationProperty( AnimationTransformType::ROTATE, VALUE_BY , rValue );
989 0 : break;
990 :
991 : case nPropertyTypeTransparency:
992 0 : bEffectChanged = pEffect->setProperty( AnimationNodeType::SET, "Opacity" , VALUE_TO, rValue );
993 0 : break;
994 :
995 : case nPropertyTypeScale:
996 0 : bEffectChanged = pEffect->setTransformationProperty( AnimationTransformType::SCALE, VALUE_BY, rValue );
997 0 : break;
998 :
999 : case nPropertyTypeCharDecoration:
1000 : {
1001 0 : Sequence< Any > aValues(3);
1002 0 : rValue >>= aValues;
1003 0 : bEffectChanged = pEffect->setProperty( AnimationNodeType::SET, "CharWeight" , VALUE_TO, aValues[0] );
1004 0 : bEffectChanged |= pEffect->setProperty( AnimationNodeType::SET, "CharPosture" , VALUE_TO, aValues[1] );
1005 0 : bEffectChanged |= pEffect->setProperty( AnimationNodeType::SET, "CharUnderline" , VALUE_TO, aValues[2] );
1006 : }
1007 0 : break;
1008 :
1009 : }
1010 :
1011 0 : return bEffectChanged;
1012 : }
1013 :
1014 0 : static sal_Bool hasVisibleShape( const Reference< XShape >& xShape )
1015 : {
1016 : try
1017 : {
1018 0 : const OUString sShapeType( xShape->getShapeType() );
1019 :
1020 0 : if( sShapeType == "com.sun.star.presentation.TitleTextShape" || sShapeType == "com.sun.star.presentation.OutlinerShape" ||
1021 0 : sShapeType == "com.sun.star.presentation.SubtitleShape" || sShapeType == "com.sun.star.drawing.TextShape" )
1022 : {
1023 0 : const OUString sFillStyle( "FillStyle" );
1024 0 : const OUString sLineStyle( "LineStyle" );
1025 0 : Reference< XPropertySet > xSet( xShape, UNO_QUERY_THROW );
1026 :
1027 : FillStyle eFillStyle;
1028 0 : xSet->getPropertyValue( sFillStyle ) >>= eFillStyle;
1029 :
1030 : ::com::sun::star::drawing::LineStyle eLineStyle;
1031 0 : xSet->getPropertyValue( sLineStyle ) >>= eLineStyle;
1032 :
1033 0 : return eFillStyle != FillStyle_NONE || eLineStyle != ::com::sun::star::drawing::LineStyle_NONE;
1034 0 : }
1035 : }
1036 0 : catch( Exception& )
1037 : {
1038 : }
1039 0 : return sal_True;
1040 : }
1041 :
1042 0 : STLPropertySet* CustomAnimationPane::createSelectionSet()
1043 : {
1044 0 : STLPropertySet* pSet = CustomAnimationDialog::createDefaultSet();
1045 :
1046 0 : pSet->setPropertyValue( nHandleCurrentPage, makeAny( mxCurrentPage ) );
1047 :
1048 0 : sal_Int32 nMaxParaDepth = 0;
1049 :
1050 : // get options from selected effects
1051 0 : EffectSequence::iterator aIter( maListSelection.begin() );
1052 0 : const EffectSequence::iterator aEnd( maListSelection.end() );
1053 0 : const CustomAnimationPresets& rPresets (getPresets());
1054 0 : while( aIter != aEnd )
1055 : {
1056 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
1057 :
1058 0 : EffectSequenceHelper* pEffectSequence = pEffect->getEffectSequence();
1059 0 : if( !pEffectSequence )
1060 0 : pEffectSequence = mpMainSequence.get();
1061 :
1062 0 : if( pEffect->hasText() )
1063 : {
1064 0 : sal_Int32 n = calcMaxParaDepth(pEffect->getTargetShape());
1065 0 : if( n > nMaxParaDepth )
1066 0 : nMaxParaDepth = n;
1067 : }
1068 :
1069 0 : addValue( pSet, nHandleHasAfterEffect, makeAny( pEffect->hasAfterEffect() ) );
1070 0 : addValue( pSet, nHandleAfterEffectOnNextEffect, makeAny( pEffect->IsAfterEffectOnNext() ? sal_True : sal_False ) );
1071 0 : addValue( pSet, nHandleDimColor, pEffect->getDimColor() );
1072 0 : addValue( pSet, nHandleIterateType, makeAny( pEffect->getIterateType() ) );
1073 :
1074 : // convert absolute time to percentage value
1075 : // This calculation is done in float to avoid some rounding artifacts.
1076 0 : float fIterateInterval = (float)pEffect->getIterateInterval();
1077 0 : if( pEffect->getDuration() )
1078 0 : fIterateInterval = (float)(fIterateInterval / pEffect->getDuration() );
1079 0 : fIterateInterval *= 100.0;
1080 0 : addValue( pSet, nHandleIterateInterval, makeAny( (double)fIterateInterval ) );
1081 :
1082 0 : addValue( pSet, nHandleBegin, makeAny( pEffect->getBegin() ) );
1083 0 : addValue( pSet, nHandleDuration, makeAny( pEffect->getDuration() ) );
1084 0 : addValue( pSet, nHandleStart, makeAny( pEffect->getNodeType() ) );
1085 0 : addValue( pSet, nHandleRepeat, makeAny( pEffect->getRepeatCount() ) );
1086 0 : addValue( pSet, nHandleEnd, pEffect->getEnd() );
1087 0 : addValue( pSet, nHandleRewind, makeAny( pEffect->getFill() ) );
1088 :
1089 0 : addValue( pSet, nHandlePresetId, makeAny( pEffect->getPresetId() ) );
1090 :
1091 0 : addValue( pSet, nHandleHasText, makeAny( (sal_Bool)pEffect->hasText() ) );
1092 :
1093 0 : addValue( pSet, nHandleHasVisibleShape, Any( hasVisibleShape( pEffect->getTargetShape() ) ) );
1094 :
1095 0 : Any aSoundSource;
1096 0 : if( pEffect->getAudio().is() )
1097 : {
1098 0 : aSoundSource = pEffect->getAudio()->getSource();
1099 0 : addValue( pSet, nHandleSoundVolumne, makeAny( pEffect->getAudio()->getVolume() ) );
1100 : // todo addValue( pSet, nHandleSoundEndAfterSlide, makeAny( pEffect->getAudio()->getEndAfterSlide() ) );
1101 : // this is now stored at the XCommand parameter sequence
1102 : }
1103 0 : else if( pEffect->getCommand() == EffectCommands::STOPAUDIO )
1104 : {
1105 0 : aSoundSource = makeAny( (sal_Bool)sal_True );
1106 : }
1107 0 : addValue( pSet, nHandleSoundURL, aSoundSource );
1108 :
1109 0 : sal_Int32 nGroupId = pEffect->getGroupId();
1110 0 : CustomAnimationTextGroupPtr pTextGroup;
1111 0 : if( nGroupId != -1 )
1112 0 : pTextGroup = pEffectSequence->findGroup( nGroupId );
1113 :
1114 0 : addValue( pSet, nHandleTextGrouping, makeAny( pTextGroup.get() ? pTextGroup->getTextGrouping() : (sal_Int32)-1 ) );
1115 0 : addValue( pSet, nHandleAnimateForm, makeAny( pTextGroup.get() ? (sal_Bool)pTextGroup->getAnimateForm() : sal_True ) );
1116 0 : addValue( pSet, nHandleTextGroupingAuto, makeAny( pTextGroup.get() ? pTextGroup->getTextGroupingAuto() : (double)-1.0 ) );
1117 0 : addValue( pSet, nHandleTextReverse, makeAny( pTextGroup.get() ? (sal_Bool)pTextGroup->getTextReverse() : sal_False ) );
1118 :
1119 0 : if( pEffectSequence->getSequenceType() == EffectNodeType::INTERACTIVE_SEQUENCE )
1120 : {
1121 0 : InteractiveSequence* pIS = static_cast< InteractiveSequence* >( pEffectSequence );
1122 0 : addValue( pSet, nHandleTrigger, makeAny( pIS->getTriggerShape() ) );
1123 : }
1124 :
1125 0 : CustomAnimationPresetPtr pDescriptor = rPresets.getEffectDescriptor( pEffect->getPresetId() );
1126 0 : if( pDescriptor.get() )
1127 : {
1128 0 : sal_Int32 nType = nPropertyTypeNone;
1129 :
1130 0 : UStringList aProperties( pDescriptor->getProperties() );
1131 0 : if( aProperties.size() >= 1 )
1132 0 : nType = getPropertyType( aProperties.front() );
1133 :
1134 0 : if( nType != nPropertyTypeNone )
1135 : {
1136 0 : addValue( pSet, nHandleProperty1Type, makeAny( nType ) );
1137 0 : addValue( pSet, nHandleProperty1Value, getProperty1Value( nType, pEffect ) );
1138 : }
1139 :
1140 0 : if( pDescriptor->hasProperty( "Accelerate" ) )
1141 : {
1142 0 : addValue( pSet, nHandleAccelerate, makeAny( pEffect->getAcceleration() ) );
1143 : }
1144 :
1145 0 : if( pDescriptor->hasProperty( "Decelerate" ) )
1146 : {
1147 0 : addValue( pSet, nHandleDecelerate, makeAny( pEffect->getDecelerate() ) );
1148 : }
1149 :
1150 0 : if( pDescriptor->hasProperty( "AutoReverse" ) )
1151 : {
1152 0 : addValue( pSet, nHandleAutoReverse, makeAny( pEffect->getAutoReverse() ) );
1153 0 : }
1154 : }
1155 0 : }
1156 :
1157 0 : addValue( pSet, nHandleMaxParaDepth, makeAny( nMaxParaDepth ) );
1158 :
1159 0 : return pSet;
1160 : }
1161 :
1162 0 : void CustomAnimationPane::changeSelection( STLPropertySet* pResultSet, STLPropertySet* pOldSet )
1163 : {
1164 : // change selected effect
1165 0 : bool bChanged = false;
1166 :
1167 0 : MainSequenceRebuildGuard aGuard( mpMainSequence );
1168 :
1169 0 : EffectSequence::iterator aIter( maListSelection.begin() );
1170 0 : const EffectSequence::iterator aEnd( maListSelection.end() );
1171 0 : while( aIter != aEnd )
1172 : {
1173 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
1174 :
1175 : DBG_ASSERT( pEffect->getEffectSequence(), "sd::CustomAnimationPane::changeSelection(), dead effect in selection!" );
1176 0 : if( !pEffect->getEffectSequence() )
1177 0 : continue;
1178 :
1179 0 : double fDuration = 0.0; // we might need this for iterate-interval
1180 0 : if( pResultSet->getPropertyState( nHandleDuration ) == STLPropertyState_DIRECT )
1181 : {
1182 0 : pResultSet->getPropertyValue( nHandleDuration ) >>= fDuration;
1183 : }
1184 : else
1185 : {
1186 0 : fDuration = pEffect->getDuration();
1187 : }
1188 :
1189 0 : if( pResultSet->getPropertyState( nHandleIterateType ) == STLPropertyState_DIRECT )
1190 : {
1191 0 : sal_Int16 nIterateType = 0;
1192 0 : pResultSet->getPropertyValue( nHandleIterateType ) >>= nIterateType;
1193 0 : if( pEffect->getIterateType() != nIterateType )
1194 : {
1195 0 : pEffect->setIterateType( nIterateType );
1196 0 : bChanged = true;
1197 : }
1198 : }
1199 :
1200 0 : if( pEffect->getIterateType() )
1201 : {
1202 0 : if( pResultSet->getPropertyState( nHandleIterateInterval ) == STLPropertyState_DIRECT )
1203 : {
1204 0 : double fIterateInterval = 0.0;
1205 0 : pResultSet->getPropertyValue( nHandleIterateInterval ) >>= fIterateInterval;
1206 0 : if( pEffect->getIterateInterval() != fIterateInterval )
1207 : {
1208 0 : const double f = fIterateInterval * pEffect->getDuration() / 100;
1209 0 : pEffect->setIterateInterval( f );
1210 0 : bChanged = true;
1211 : }
1212 : }
1213 : }
1214 :
1215 0 : if( pResultSet->getPropertyState( nHandleBegin ) == STLPropertyState_DIRECT )
1216 : {
1217 0 : double fBegin = 0.0;
1218 0 : pResultSet->getPropertyValue( nHandleBegin ) >>= fBegin;
1219 0 : if( pEffect->getBegin() != fBegin )
1220 : {
1221 0 : pEffect->setBegin( fBegin );
1222 0 : bChanged = true;
1223 : }
1224 : }
1225 :
1226 0 : if( pResultSet->getPropertyState( nHandleDuration ) == STLPropertyState_DIRECT )
1227 : {
1228 0 : if( pEffect->getDuration() != fDuration )
1229 : {
1230 0 : pEffect->setDuration( fDuration );
1231 0 : bChanged = true;
1232 : }
1233 : }
1234 :
1235 0 : if( pResultSet->getPropertyState( nHandleStart ) == STLPropertyState_DIRECT )
1236 : {
1237 0 : sal_Int16 nNodeType = 0;
1238 0 : pResultSet->getPropertyValue( nHandleStart ) >>= nNodeType;
1239 0 : if( pEffect->getNodeType() != nNodeType )
1240 : {
1241 0 : pEffect->setNodeType( nNodeType );
1242 0 : bChanged = true;
1243 : }
1244 : }
1245 :
1246 0 : if( pResultSet->getPropertyState( nHandleRepeat ) == STLPropertyState_DIRECT )
1247 : {
1248 0 : Any aRepeatCount( pResultSet->getPropertyValue( nHandleRepeat ) );
1249 0 : if( aRepeatCount != pEffect->getRepeatCount() )
1250 : {
1251 0 : pEffect->setRepeatCount( aRepeatCount );
1252 0 : bChanged = true;
1253 0 : }
1254 : }
1255 :
1256 0 : if( pResultSet->getPropertyState( nHandleEnd ) == STLPropertyState_DIRECT )
1257 : {
1258 0 : Any aEndValue( pResultSet->getPropertyValue( nHandleEnd ) );
1259 0 : if( pEffect->getEnd() != aEndValue )
1260 : {
1261 0 : pEffect->setEnd( aEndValue );
1262 0 : bChanged = true;
1263 0 : }
1264 : }
1265 :
1266 0 : if( pResultSet->getPropertyState( nHandleRewind ) == STLPropertyState_DIRECT )
1267 : {
1268 0 : sal_Int16 nFill = 0;
1269 0 : pResultSet->getPropertyValue( nHandleRewind ) >>= nFill;
1270 0 : if( pEffect->getFill() != nFill )
1271 : {
1272 0 : pEffect->setFill( nFill );
1273 0 : bChanged = true;
1274 : }
1275 : }
1276 :
1277 0 : if( pResultSet->getPropertyState( nHandleHasAfterEffect ) == STLPropertyState_DIRECT )
1278 : {
1279 0 : sal_Bool bHasAfterEffect = sal_False;
1280 0 : if( pResultSet->getPropertyValue( nHandleHasAfterEffect ) >>= bHasAfterEffect )
1281 : {
1282 0 : if( pEffect->hasAfterEffect() != bHasAfterEffect )
1283 : {
1284 0 : pEffect->setHasAfterEffect( bHasAfterEffect );
1285 0 : bChanged = true;
1286 : }
1287 : }
1288 : }
1289 :
1290 0 : if( pResultSet->getPropertyState( nHandleAfterEffectOnNextEffect ) == STLPropertyState_DIRECT )
1291 : {
1292 0 : sal_Bool bAfterEffectOnNextEffect = sal_False;
1293 0 : if( (pResultSet->getPropertyValue( nHandleAfterEffectOnNextEffect ) >>= bAfterEffectOnNextEffect) && ((pEffect->IsAfterEffectOnNext() ? sal_True : sal_False) != bAfterEffectOnNextEffect) )
1294 : {
1295 0 : pEffect->setAfterEffectOnNext( bAfterEffectOnNextEffect );
1296 0 : bChanged = true;
1297 : }
1298 : }
1299 :
1300 0 : if( pResultSet->getPropertyState( nHandleDimColor ) == STLPropertyState_DIRECT )
1301 : {
1302 0 : Any aDimColor( pResultSet->getPropertyValue( nHandleDimColor ) );
1303 0 : if( pEffect->getDimColor() != aDimColor )
1304 : {
1305 0 : pEffect->setDimColor( aDimColor );
1306 0 : bChanged = true;
1307 0 : }
1308 : }
1309 :
1310 0 : if( pResultSet->getPropertyState( nHandleAccelerate ) == STLPropertyState_DIRECT )
1311 : {
1312 0 : double fAccelerate = 0.0;
1313 0 : pResultSet->getPropertyValue( nHandleAccelerate ) >>= fAccelerate;
1314 0 : if( pEffect->getAcceleration() != fAccelerate )
1315 : {
1316 0 : pEffect->setAcceleration( fAccelerate );
1317 0 : bChanged = true;
1318 : }
1319 : }
1320 :
1321 0 : if( pResultSet->getPropertyState( nHandleDecelerate ) == STLPropertyState_DIRECT )
1322 : {
1323 0 : double fDecelerate = 0.0;
1324 0 : pResultSet->getPropertyValue( nHandleDecelerate ) >>= fDecelerate;
1325 0 : if( pEffect->getDecelerate() != fDecelerate )
1326 : {
1327 0 : pEffect->setDecelerate( fDecelerate );
1328 0 : bChanged = true;
1329 : }
1330 : }
1331 :
1332 0 : if( pResultSet->getPropertyState( nHandleAutoReverse ) == STLPropertyState_DIRECT )
1333 : {
1334 0 : sal_Bool bAutoReverse = sal_False;
1335 0 : pResultSet->getPropertyValue( nHandleAutoReverse ) >>= bAutoReverse;
1336 0 : if( pEffect->getAutoReverse() != bAutoReverse )
1337 : {
1338 0 : pEffect->setAutoReverse( bAutoReverse );
1339 0 : bChanged = true;
1340 : }
1341 : }
1342 :
1343 0 : if( pResultSet->getPropertyState( nHandleProperty1Value ) == STLPropertyState_DIRECT )
1344 : {
1345 0 : sal_Int32 nType = 0;
1346 0 : pOldSet->getPropertyValue( nHandleProperty1Type ) >>= nType;
1347 :
1348 0 : bChanged |= setProperty1Value( nType, pEffect, pResultSet->getPropertyValue( nHandleProperty1Value ) );
1349 : }
1350 :
1351 0 : if( pResultSet->getPropertyState( nHandleSoundURL ) == STLPropertyState_DIRECT )
1352 : {
1353 0 : const Any aSoundSource( pResultSet->getPropertyValue( nHandleSoundURL ) );
1354 :
1355 0 : if( aSoundSource.getValueType() == ::getCppuType((const sal_Bool*)0) )
1356 : {
1357 0 : pEffect->setStopAudio();
1358 0 : bChanged = true;
1359 : }
1360 : else
1361 : {
1362 0 : OUString aSoundURL;
1363 0 : aSoundSource >>= aSoundURL;
1364 :
1365 0 : if( !aSoundURL.isEmpty() )
1366 : {
1367 0 : if( !pEffect->getAudio().is() )
1368 : {
1369 0 : pEffect->createAudio( aSoundSource );
1370 0 : bChanged = true;
1371 : }
1372 : else
1373 : {
1374 0 : if( pEffect->getAudio()->getSource() != aSoundSource )
1375 : {
1376 0 : pEffect->getAudio()->setSource( aSoundSource );
1377 0 : bChanged = true;
1378 : }
1379 : }
1380 : }
1381 : else
1382 : {
1383 0 : if( pEffect->getAudio().is() || pEffect->getStopAudio() )
1384 : {
1385 0 : pEffect->removeAudio();
1386 0 : bChanged = true;
1387 : }
1388 0 : }
1389 0 : }
1390 : }
1391 :
1392 0 : if( pResultSet->getPropertyState( nHandleTrigger ) == STLPropertyState_DIRECT )
1393 : {
1394 0 : Reference< XShape > xTriggerShape;
1395 0 : pResultSet->getPropertyValue( nHandleTrigger ) >>= xTriggerShape;
1396 0 : bChanged |= mpMainSequence->setTrigger( pEffect, xTriggerShape );
1397 : }
1398 0 : }
1399 :
1400 0 : const bool bHasTextGrouping = pResultSet->getPropertyState( nHandleTextGrouping ) == STLPropertyState_DIRECT;
1401 0 : const bool bHasAnimateForm = pResultSet->getPropertyState( nHandleAnimateForm ) == STLPropertyState_DIRECT;
1402 0 : const bool bHasTextGroupingAuto = pResultSet->getPropertyState( nHandleTextGroupingAuto ) == STLPropertyState_DIRECT;
1403 0 : const bool bHasTextReverse = pResultSet->getPropertyState( nHandleTextReverse ) == STLPropertyState_DIRECT;
1404 :
1405 0 : if( bHasTextGrouping || bHasAnimateForm || bHasTextGroupingAuto || bHasTextReverse )
1406 : {
1407 : // we need to do a second pass for text grouping options
1408 : // since changing them can cause effects to be removed
1409 : // or replaced, we do this after we aplied all other options
1410 : // above
1411 :
1412 0 : sal_Int32 nTextGrouping = 0;
1413 0 : sal_Bool bAnimateForm = sal_True, bTextReverse = sal_False;
1414 0 : double fTextGroupingAuto = -1.0;
1415 :
1416 0 : if( bHasTextGrouping )
1417 0 : pResultSet->getPropertyValue(nHandleTextGrouping) >>= nTextGrouping;
1418 :
1419 0 : if( bHasAnimateForm )
1420 0 : pResultSet->getPropertyValue(nHandleAnimateForm) >>= bAnimateForm;
1421 :
1422 0 : if( bHasTextGroupingAuto )
1423 0 : pResultSet->getPropertyValue(nHandleTextGroupingAuto) >>= fTextGroupingAuto;
1424 :
1425 0 : if( bHasTextReverse )
1426 0 : pResultSet->getPropertyValue(nHandleTextReverse) >>= bTextReverse;
1427 :
1428 0 : EffectSequence const aSelectedEffects( maListSelection );
1429 0 : EffectSequence::const_iterator iter( aSelectedEffects.begin() );
1430 0 : const EffectSequence::const_iterator iEnd( aSelectedEffects.end() );
1431 0 : while( iter != iEnd )
1432 : {
1433 0 : CustomAnimationEffectPtr const& pEffect = (*iter++);
1434 :
1435 0 : EffectSequenceHelper* pEffectSequence = pEffect->getEffectSequence();
1436 0 : if( !pEffectSequence )
1437 0 : pEffectSequence = mpMainSequence.get();
1438 :
1439 0 : sal_Int32 nGroupId = pEffect->getGroupId();
1440 0 : CustomAnimationTextGroupPtr pTextGroup;
1441 0 : if( (nGroupId != -1) )
1442 : {
1443 : // use existing group
1444 0 : pTextGroup = pEffectSequence->findGroup( nGroupId );
1445 : }
1446 : else
1447 : {
1448 : // somethings changed so we need a group now
1449 0 : pTextGroup = pEffectSequence->createTextGroup( pEffect, nTextGrouping, fTextGroupingAuto, bAnimateForm, bTextReverse );
1450 0 : bChanged = true;
1451 : }
1452 :
1453 : //#i119988#
1454 : /************************************************************************/
1455 : /*
1456 : Note, the setAnimateForm means set the animation from TextGroup to Object's Shape
1457 : And on the UI in means "Animate attached shape" in "Effect Option" dialog
1458 : The setTextGrouping means set animation to Object's Text,
1459 : the nTextGrouping is Text Animation Type
1460 : nTextGrouping = -1 is "As one Object", means no text animation.
1461 :
1462 : The previous call order first do the setTextGrouping and then do the setAnimateForm,
1463 : that will cause such defect: in the setTextGrouping, the effect has been removed,
1464 : but in setAnimateForm still need this effect, then a NULL pointer of that effect will
1465 : be gotten, and cause crash.
1466 :
1467 : []bHasAnimateForm means the UI has changed, bAnimateForm is it value
1468 :
1469 : So if create a new textgroup animation, the following animation will never be run!
1470 : Since the \A1\B0Animate attached shape\A1\B1 is default checked.
1471 : And the bHasAnimateForm default is false, and if user uncheck it the value bAnimateForm will be false,
1472 : it same as the TextGroup\A1\AFs default value, also could not be run setAnimateForm.
1473 : if( bHasAnimateForm )
1474 : {
1475 : if( pTextGroup->getAnimateForm() != bAnimateForm )
1476 : {
1477 : pEffectSequence->setAnimateForm( pTextGroup, bAnimateForm );
1478 : bChanged = true;
1479 : }
1480 : }
1481 :
1482 : In setTextGrouping, there are three case:
1483 : 1. Create new text effects for empty TextGroup
1484 : 2. Remove all text effects of TextGroup (nTextGrouping == -1)
1485 : 3. Change all the text effects\A1\AF start type
1486 :
1487 : So here is the right logic:
1488 : If set the animation from text to shape and remove text animation,
1489 : should do setAnimateForm first, then do setTextGrouping.
1490 : Other case,do setTextGrouping first, then do setAnimateForm.
1491 :
1492 : */
1493 : /************************************************************************/
1494 :
1495 0 : bool bDoSetAnimateFormFirst = false;
1496 0 : bool bNeedDoSetAnimateForm = false;
1497 :
1498 0 : if( bHasAnimateForm )
1499 : {
1500 0 : if( pTextGroup->getAnimateForm() != bAnimateForm )
1501 : {
1502 0 : if( (pTextGroup->getTextGrouping() >= 0) && (nTextGrouping == -1 ) )
1503 : {
1504 0 : bDoSetAnimateFormFirst = true;
1505 : }
1506 0 : bNeedDoSetAnimateForm = true;
1507 : }
1508 : }
1509 :
1510 0 : if (bDoSetAnimateFormFirst)
1511 : {
1512 0 : pEffectSequence->setAnimateForm( pTextGroup, bAnimateForm );
1513 0 : bChanged = true;
1514 : }
1515 :
1516 0 : if( bHasTextGrouping )
1517 : {
1518 0 : if( (pTextGroup->getTextGrouping() != nTextGrouping) )
1519 : {
1520 0 : pEffectSequence->setTextGrouping( pTextGroup, nTextGrouping );
1521 0 : bChanged = true;
1522 : }
1523 : }
1524 :
1525 0 : if (!bDoSetAnimateFormFirst&&bNeedDoSetAnimateForm)
1526 : {
1527 0 : pEffectSequence->setAnimateForm( pTextGroup, bAnimateForm );
1528 0 : bChanged = true;
1529 : }
1530 :
1531 0 : if( bHasTextGroupingAuto )
1532 : {
1533 0 : if( pTextGroup->getTextGroupingAuto() != fTextGroupingAuto )
1534 : {
1535 0 : pEffectSequence->setTextGroupingAuto( pTextGroup, fTextGroupingAuto );
1536 0 : bChanged = true;
1537 : }
1538 : }
1539 :
1540 0 : if( bHasTextReverse )
1541 : {
1542 0 : if( pTextGroup->getTextReverse() != bTextReverse )
1543 : {
1544 0 : pEffectSequence->setTextReverse( pTextGroup, bTextReverse );
1545 0 : bChanged = true;
1546 : }
1547 : }
1548 0 : }
1549 : }
1550 :
1551 0 : if( bChanged )
1552 : {
1553 0 : mpMainSequence->rebuild();
1554 0 : updateControls();
1555 0 : mrBase.GetDocShell()->SetModified();
1556 0 : }
1557 0 : }
1558 :
1559 0 : void CustomAnimationPane::showOptions(const OString& sPage)
1560 : {
1561 0 : STLPropertySet* pSet = createSelectionSet();
1562 :
1563 0 : CustomAnimationDialog* pDlg = new CustomAnimationDialog(this, pSet, sPage);
1564 0 : if( pDlg->Execute() )
1565 : {
1566 0 : addUndo();
1567 0 : changeSelection( pDlg->getResultSet(), pSet );
1568 0 : updateControls();
1569 : }
1570 :
1571 0 : delete pDlg;
1572 0 : }
1573 :
1574 0 : void CustomAnimationPane::onChangeCurrentPage()
1575 : {
1576 0 : if( mxView.is() ) try
1577 : {
1578 0 : Reference< XDrawPage > xNewPage( mxView->getCurrentPage() );
1579 0 : if( xNewPage != mxCurrentPage )
1580 : {
1581 0 : mxCurrentPage = xNewPage;
1582 0 : SdPage* pPage = SdPage::getImplementation( mxCurrentPage );
1583 0 : if( pPage )
1584 : {
1585 0 : mpMainSequence = pPage->getMainSequence();
1586 0 : mpCustomAnimationList->update( mpMainSequence );
1587 : }
1588 0 : updateControls();
1589 0 : }
1590 : }
1591 0 : catch( Exception& )
1592 : {
1593 : OSL_FAIL( "sd::CustomAnimationPane::onChangeCurrentPage(), exception caught!" );
1594 : }
1595 0 : }
1596 :
1597 0 : bool getTextSelection( const Any& rSelection, Reference< XShape >& xShape, std::list< sal_Int16 >& rParaList )
1598 : {
1599 0 : Reference< XTextRange > xSelectedText;
1600 0 : rSelection >>= xSelectedText;
1601 0 : if( xSelectedText.is() ) try
1602 : {
1603 0 : xShape.set( xSelectedText->getText(), UNO_QUERY_THROW );
1604 :
1605 0 : Reference< XTextRangeCompare > xTextRangeCompare( xShape, UNO_QUERY_THROW );
1606 0 : Reference< XEnumerationAccess > xParaEnumAccess( xShape, UNO_QUERY_THROW );
1607 0 : Reference< XEnumeration > xParaEnum( xParaEnumAccess->createEnumeration(), UNO_QUERY_THROW );
1608 0 : Reference< XTextRange > xRange;
1609 0 : Reference< XTextRange > xStart( xSelectedText->getStart() );
1610 0 : Reference< XTextRange > xEnd( xSelectedText->getEnd() );
1611 :
1612 0 : if( xTextRangeCompare->compareRegionEnds( xStart, xEnd ) < 0 )
1613 : {
1614 0 : Reference< XTextRange > xTemp( xStart );
1615 0 : xStart = xEnd;
1616 0 : xEnd = xTemp;
1617 : }
1618 :
1619 0 : sal_Int16 nPara = 0;
1620 0 : while( xParaEnum->hasMoreElements() )
1621 : {
1622 0 : xParaEnum->nextElement() >>= xRange;
1623 :
1624 : // break if start of selection is prior to end of current paragraph
1625 0 : if( xRange.is() && (xTextRangeCompare->compareRegionEnds( xStart, xRange ) >= 0 ) )
1626 0 : break;
1627 :
1628 0 : nPara++;
1629 : }
1630 :
1631 0 : while( xRange.is() )
1632 : {
1633 0 : if( xRange.is() && !xRange->getString().isEmpty() )
1634 0 : rParaList.push_back( nPara );
1635 :
1636 : // break if end of selection is before or at end of current paragraph
1637 0 : if( xRange.is() && xTextRangeCompare->compareRegionEnds( xEnd, xRange ) >= 0 )
1638 0 : break;
1639 :
1640 0 : nPara++;
1641 :
1642 0 : if( xParaEnum->hasMoreElements() )
1643 0 : xParaEnum->nextElement() >>= xRange;
1644 : else
1645 0 : xRange.clear();
1646 : }
1647 :
1648 0 : return true;
1649 : }
1650 0 : catch( Exception& )
1651 : {
1652 : OSL_FAIL( "sd::CustomAnimationPane::getTextSelection(), exception caught!" );
1653 : }
1654 :
1655 0 : return false;
1656 : }
1657 :
1658 0 : void CustomAnimationPane::onChange( bool bCreate )
1659 : {
1660 0 : bool bHasText = true;
1661 :
1662 : // first create vector of targets for dialog preview
1663 0 : std::vector< Any > aTargets;
1664 0 : OUString sPresetId;
1665 0 : double fDuration = 2.0f;
1666 :
1667 0 : if( bCreate )
1668 : {
1669 : // gather shapes from the selection
1670 0 : Reference< XSelectionSupplier > xSel( mxView, UNO_QUERY_THROW );
1671 0 : maViewSelection = xSel->getSelection();
1672 :
1673 0 : if( maViewSelection.getValueType() == ::getCppuType((const Reference< XShapes >*)0) )
1674 : {
1675 0 : Reference< XIndexAccess > xShapes;
1676 0 : maViewSelection >>= xShapes;
1677 :
1678 0 : sal_Int32 nCount = xShapes->getCount();
1679 : sal_Int32 nIndex;
1680 0 : for( nIndex = 0; nIndex < nCount; nIndex++ )
1681 : {
1682 0 : Any aTarget( xShapes->getByIndex( nIndex ) );
1683 0 : aTargets.push_back( aTarget );
1684 0 : if( bHasText )
1685 : {
1686 0 : Reference< XText > xText;
1687 0 : aTarget >>= xText;
1688 0 : if( !xText.is() || xText->getString().isEmpty() )
1689 0 : bHasText = false;
1690 : }
1691 0 : }
1692 : }
1693 0 : else if ( maViewSelection.getValueType() == ::getCppuType((const Reference< XShape >*)0) )
1694 : {
1695 0 : aTargets.push_back( maViewSelection );
1696 0 : Reference< XText > xText;
1697 0 : maViewSelection >>= xText;
1698 0 : if( !xText.is() || xText->getString().isEmpty() )
1699 0 : bHasText = false;
1700 : }
1701 0 : else if ( maViewSelection.getValueType() == ::getCppuType((const Reference< XTextCursor >*)0) )
1702 : {
1703 0 : Reference< XShape > xShape;
1704 0 : std::list< sal_Int16 > aParaList;
1705 0 : if( getTextSelection( maViewSelection, xShape, aParaList ) )
1706 : {
1707 0 : ParagraphTarget aParaTarget;
1708 0 : aParaTarget.Shape = xShape;
1709 :
1710 0 : std::list< sal_Int16 >::iterator aIter( aParaList.begin() );
1711 0 : for( ; aIter != aParaList.end(); ++aIter )
1712 : {
1713 0 : aParaTarget.Paragraph = (*aIter);
1714 0 : aTargets.push_back( makeAny( aParaTarget ) );
1715 0 : }
1716 0 : }
1717 : }
1718 : else
1719 : {
1720 : OSL_FAIL("sd::CustomAnimationPane::onChange(), unknown view selection!" );
1721 0 : return;
1722 0 : }
1723 : }
1724 : else
1725 : {
1726 : // get selected effect
1727 0 : EffectSequence::iterator aIter( maListSelection.begin() );
1728 0 : const EffectSequence::iterator aEnd( maListSelection.end() );
1729 0 : while( aIter != aEnd )
1730 : {
1731 0 : if( !bHasText || !(*aIter)->hasText() )
1732 0 : bHasText = false;
1733 :
1734 0 : if( sPresetId.isEmpty() )
1735 : {
1736 0 : sPresetId = (*aIter)->getPresetId();
1737 0 : fDuration = (*aIter)->getDuration();
1738 : }
1739 :
1740 0 : aTargets.push_back( (*aIter++)->getTarget() );
1741 : }
1742 : }
1743 :
1744 0 : CustomAnimationCreateDialog* pDlg = new CustomAnimationCreateDialog( this, this, aTargets, bHasText, sPresetId, fDuration );
1745 0 : if( pDlg->Execute() )
1746 : {
1747 0 : addUndo();
1748 0 : fDuration = pDlg->getSelectedDuration();
1749 0 : CustomAnimationPresetPtr pDescriptor = pDlg->getSelectedPreset();
1750 0 : if( pDescriptor.get() )
1751 : {
1752 0 : if( bCreate )
1753 : {
1754 0 : mpCustomAnimationList->SelectAll( false );
1755 :
1756 : // gather shapes from the selection
1757 0 : std::vector< Any >::iterator aIter( aTargets.begin() );
1758 0 : const std::vector< Any >::iterator aEnd( aTargets.end() );
1759 0 : bool bFirst = true;
1760 0 : for( ; aIter != aEnd; ++aIter )
1761 : {
1762 0 : CustomAnimationEffectPtr pCreated = mpMainSequence->append( pDescriptor, (*aIter), fDuration );
1763 :
1764 : // if only one shape with text and no fill or outline is selected, animate only by first level paragraphs
1765 0 : if( bHasText && (aTargets.size() == 1) )
1766 : {
1767 0 : Reference< XShape > xShape( (*aIter), UNO_QUERY );
1768 0 : if( xShape.is() && !hasVisibleShape( xShape ) )
1769 : {
1770 0 : mpMainSequence->createTextGroup( pCreated, 1, -1.0, sal_False, sal_False );
1771 0 : }
1772 : }
1773 :
1774 0 : if( bFirst )
1775 0 : bFirst = false;
1776 : else
1777 0 : pCreated->setNodeType( EffectNodeType::WITH_PREVIOUS );
1778 :
1779 0 : if( pCreated.get() )
1780 : {
1781 0 : mpCustomAnimationList->select( pCreated );
1782 : }
1783 0 : }
1784 : }
1785 : else
1786 : {
1787 0 : MainSequenceRebuildGuard aGuard( mpMainSequence );
1788 :
1789 : // get selected effect
1790 0 : EffectSequence::iterator aIter( maListSelection.begin() );
1791 0 : const EffectSequence::iterator aEnd( maListSelection.end() );
1792 0 : while( aIter != aEnd )
1793 : {
1794 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
1795 :
1796 0 : EffectSequenceHelper* pEffectSequence = pEffect->getEffectSequence();
1797 0 : if( !pEffectSequence )
1798 0 : pEffectSequence = mpMainSequence.get();
1799 :
1800 0 : pEffectSequence->replace( pEffect, pDescriptor, fDuration );
1801 0 : }
1802 : }
1803 : }
1804 : else
1805 : {
1806 0 : PathKind eKind = pDlg->getCreatePathKind();
1807 0 : if( eKind != NONE )
1808 0 : createPath( eKind, aTargets, fDuration );
1809 : }
1810 0 : mrBase.GetDocShell()->SetModified();
1811 : }
1812 :
1813 0 : delete pDlg;
1814 :
1815 0 : updateControls();
1816 :
1817 : // stop running preview from dialog
1818 0 : SlideShow::Stop( mrBase );
1819 : }
1820 :
1821 0 : void CustomAnimationPane::createPath( PathKind eKind, std::vector< Any >& rTargets, double fDuration)
1822 : {
1823 0 : sal_uInt16 nSID = 0;
1824 :
1825 0 : switch( eKind )
1826 : {
1827 0 : case CURVE: nSID = SID_DRAW_BEZIER_NOFILL; break;
1828 0 : case POLYGON: nSID = SID_DRAW_POLYGON_NOFILL; break;
1829 0 : case FREEFORM: nSID = SID_DRAW_FREELINE_NOFILL; break;
1830 0 : default: break;
1831 : }
1832 :
1833 0 : if( nSID )
1834 : {
1835 : DrawViewShell* pViewShell = dynamic_cast< DrawViewShell* >(
1836 0 : FrameworkHelper::Instance(mrBase)->GetViewShell(FrameworkHelper::msCenterPaneURL).get());
1837 :
1838 0 : if( pViewShell )
1839 : {
1840 0 : DrawView* pView = pViewShell->GetDrawView();
1841 0 : if( pView )
1842 0 : pView->UnmarkAllObj();
1843 :
1844 0 : std::vector< Any > aTargets( 1, Any( fDuration ) );
1845 0 : aTargets.insert( aTargets.end(), rTargets.begin(), rTargets.end() );
1846 0 : Sequence< Any > aTargetSequence( comphelper::containerToSequence( aTargets ) );
1847 0 : const SfxUnoAnyItem aItem( SID_ADD_MOTION_PATH, Any( aTargetSequence ) );
1848 0 : pViewShell->GetViewFrame()->GetDispatcher()->Execute( nSID, SFX_CALLMODE_ASYNCHRON, &aItem, 0 );
1849 : }
1850 : }
1851 0 : }
1852 :
1853 0 : void CustomAnimationPane::onRemove()
1854 : {
1855 0 : if( !maListSelection.empty() )
1856 : {
1857 0 : addUndo();
1858 :
1859 0 : MainSequenceRebuildGuard aGuard( mpMainSequence );
1860 :
1861 0 : EffectSequence aList( maListSelection );
1862 :
1863 0 : EffectSequence::iterator aIter( aList.begin() );
1864 0 : const EffectSequence::iterator aEnd( aList.end() );
1865 0 : while( aIter != aEnd )
1866 : {
1867 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
1868 0 : if( pEffect->getEffectSequence() )
1869 0 : pEffect->getEffectSequence()->remove( pEffect );
1870 0 : }
1871 :
1872 0 : maListSelection.clear();
1873 0 : mrBase.GetDocShell()->SetModified();
1874 : }
1875 0 : }
1876 :
1877 0 : void CustomAnimationPane::remove( CustomAnimationEffectPtr& pEffect )
1878 : {
1879 0 : if( pEffect->getEffectSequence() )
1880 : {
1881 0 : addUndo();
1882 0 : pEffect->getEffectSequence()->remove( pEffect );
1883 0 : mrBase.GetDocShell()->SetModified();
1884 : }
1885 0 : }
1886 :
1887 0 : void CustomAnimationPane::onChangeStart()
1888 : {
1889 0 : if( mpLBStart->GetSelectEntryCount() == 1 )
1890 : {
1891 : sal_Int16 nNodeType;
1892 0 : sal_uInt16 nPos= mpLBStart->GetSelectEntryPos();
1893 0 : switch( nPos )
1894 : {
1895 0 : case 0: nNodeType = EffectNodeType::ON_CLICK; break;
1896 0 : case 1: nNodeType = EffectNodeType::WITH_PREVIOUS; break;
1897 0 : case 2: nNodeType = EffectNodeType::AFTER_PREVIOUS; break;
1898 : default:
1899 0 : return;
1900 : }
1901 :
1902 0 : onChangeStart( nNodeType );
1903 : }
1904 : }
1905 :
1906 0 : void CustomAnimationPane::onChangeStart( sal_Int16 nNodeType )
1907 : {
1908 0 : addUndo();
1909 :
1910 0 : MainSequenceRebuildGuard aGuard( mpMainSequence );
1911 :
1912 0 : bool bNeedRebuild = false;
1913 :
1914 0 : EffectSequence::iterator aIter( maListSelection.begin() );
1915 0 : const EffectSequence::iterator aEnd( maListSelection.end() );
1916 0 : while( aIter != aEnd )
1917 : {
1918 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
1919 0 : if( pEffect->getNodeType() != nNodeType )
1920 : {
1921 0 : pEffect->setNodeType( nNodeType );
1922 0 : bNeedRebuild = true;
1923 : }
1924 0 : }
1925 :
1926 0 : if( bNeedRebuild )
1927 : {
1928 0 : mpMainSequence->rebuild();
1929 0 : updateControls();
1930 0 : mrBase.GetDocShell()->SetModified();
1931 0 : }
1932 0 : }
1933 :
1934 0 : void CustomAnimationPane::onChangeProperty()
1935 : {
1936 0 : if( mpLBProperty->getSubControl() )
1937 : {
1938 0 : addUndo();
1939 :
1940 0 : MainSequenceRebuildGuard aGuard( mpMainSequence );
1941 :
1942 0 : const Any aValue( mpLBProperty->getSubControl()->getValue() );
1943 :
1944 0 : bool bNeedUpdate = false;
1945 :
1946 : // change selected effect
1947 0 : EffectSequence::iterator aIter( maListSelection.begin() );
1948 0 : const EffectSequence::iterator aEnd( maListSelection.end() );
1949 0 : while( aIter != aEnd )
1950 : {
1951 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
1952 :
1953 0 : if( setProperty1Value( mnPropertyType, pEffect, aValue ) )
1954 0 : bNeedUpdate = true;
1955 0 : }
1956 :
1957 0 : if( bNeedUpdate )
1958 : {
1959 0 : mpMainSequence->rebuild();
1960 0 : updateControls();
1961 0 : mrBase.GetDocShell()->SetModified();
1962 : }
1963 :
1964 0 : onPreview( false );
1965 : }
1966 0 : }
1967 :
1968 0 : void CustomAnimationPane::onChangeSpeed()
1969 : {
1970 0 : if( mpCBSpeed->GetSelectEntryCount() == 1 )
1971 : {
1972 0 : addUndo();
1973 :
1974 0 : MainSequenceRebuildGuard aGuard( mpMainSequence );
1975 :
1976 : double fDuration;
1977 :
1978 0 : sal_uInt16 nPos= mpCBSpeed->GetSelectEntryPos();
1979 :
1980 0 : switch( nPos )
1981 : {
1982 0 : case 0: fDuration = 5.0; break;
1983 0 : case 1: fDuration = 3.0; break;
1984 0 : case 2: fDuration = 2.0; break;
1985 0 : case 3: fDuration = 1.0; break;
1986 0 : case 4: fDuration = 0.5; break;
1987 : default:
1988 0 : return;
1989 : }
1990 :
1991 : // change selected effect
1992 0 : EffectSequence::iterator aIter( maListSelection.begin() );
1993 0 : const EffectSequence::iterator aEnd( maListSelection.end() );
1994 0 : while( aIter != aEnd )
1995 : {
1996 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
1997 0 : pEffect->setDuration( fDuration );
1998 0 : }
1999 :
2000 0 : mpMainSequence->rebuild();
2001 0 : updateControls();
2002 0 : mrBase.GetDocShell()->SetModified();
2003 :
2004 0 : onPreview( false );
2005 : }
2006 : }
2007 :
2008 : /// this link is called when the property box is modified by the user
2009 0 : IMPL_LINK_NOARG(CustomAnimationPane, implPropertyHdl)
2010 : {
2011 0 : onChangeProperty();
2012 0 : return 0;
2013 : }
2014 :
2015 : /// this link is called when one of the controls is modified
2016 0 : IMPL_LINK( CustomAnimationPane, implControlHdl, Control*, pControl )
2017 : {
2018 0 : if( pControl == mpPBAddEffect )
2019 0 : onChange(true);
2020 0 : else if( pControl == mpPBChangeEffect )
2021 0 : onChange(false);
2022 0 : else if( pControl == mpPBRemoveEffect )
2023 0 : onRemove();
2024 0 : else if( pControl == mpLBStart )
2025 0 : onChangeStart();
2026 0 : else if( pControl == mpCBSpeed )
2027 0 : onChangeSpeed();
2028 0 : else if( pControl == mpPBPropertyMore )
2029 0 : showOptions();
2030 0 : else if( pControl == mpPBMoveUp )
2031 0 : moveSelection( true );
2032 0 : else if( pControl == mpPBMoveDown )
2033 0 : moveSelection( false );
2034 0 : else if( pControl == mpPBPlay )
2035 0 : onPreview( true );
2036 0 : else if( pControl == mpCBAutoPreview )
2037 : {
2038 0 : SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
2039 0 : pOptions->SetPreviewChangedEffects( mpCBAutoPreview->IsChecked() ? sal_True : sal_False );
2040 : }
2041 :
2042 0 : updateControls();
2043 :
2044 0 : return 0;
2045 : }
2046 :
2047 0 : IMPL_LINK_NOARG(CustomAnimationPane, lateInitCallback)
2048 : {
2049 : // Call getPresets() to initiate the (expensive) construction of the
2050 : // presets list.
2051 0 : getPresets();
2052 :
2053 : // update selection and control states
2054 0 : onSelectionChanged();
2055 :
2056 0 : return 0;
2057 : }
2058 :
2059 0 : void CustomAnimationPane::moveSelection( bool bUp )
2060 : {
2061 0 : if( maListSelection.empty() )
2062 0 : return;
2063 :
2064 0 : EffectSequenceHelper* pSequence = maListSelection.front()->getEffectSequence();
2065 0 : if( pSequence == 0 )
2066 0 : return;
2067 :
2068 0 : addUndo();
2069 :
2070 0 : bool bChanged = false;
2071 :
2072 0 : MainSequenceRebuildGuard aGuard( mpMainSequence );
2073 0 : EffectSequence& rEffectSequence = pSequence->getSequence();
2074 :
2075 0 : if( bUp )
2076 : {
2077 0 : EffectSequence::iterator aIter( maListSelection.begin() );
2078 0 : const EffectSequence::iterator aEnd( maListSelection.end() );
2079 :
2080 0 : while( aIter != aEnd )
2081 : {
2082 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
2083 :
2084 0 : EffectSequence::iterator aEffectPos( pSequence->find( pEffect ) );
2085 0 : if( aEffectPos != rEffectSequence.end() )
2086 : {
2087 0 : EffectSequence::iterator aInsertPos( rEffectSequence.erase( aEffectPos ) );
2088 :
2089 0 : if( aInsertPos != rEffectSequence.begin() )
2090 : {
2091 0 : --aInsertPos;
2092 0 : while( (aInsertPos != rEffectSequence.begin()) && !mpCustomAnimationList->isExpanded(*aInsertPos))
2093 0 : --aInsertPos;
2094 :
2095 0 : rEffectSequence.insert( aInsertPos, pEffect );
2096 : }
2097 : else
2098 : {
2099 0 : rEffectSequence.push_front( pEffect );
2100 : }
2101 0 : bChanged = true;
2102 : }
2103 0 : }
2104 : }
2105 : else
2106 : {
2107 0 : EffectSequence::reverse_iterator aIter( maListSelection.rbegin() );
2108 0 : const EffectSequence::reverse_iterator aEnd( maListSelection.rend() );
2109 :
2110 0 : while( aIter != aEnd )
2111 : {
2112 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
2113 :
2114 0 : EffectSequence::iterator aEffectPos( pSequence->find( pEffect ) );
2115 0 : if( aEffectPos != rEffectSequence.end() )
2116 : {
2117 0 : EffectSequence::iterator aInsertPos( rEffectSequence.erase( aEffectPos ) );
2118 :
2119 0 : if( aInsertPos != rEffectSequence.end() )
2120 : {
2121 0 : ++aInsertPos;
2122 0 : while( (aInsertPos != rEffectSequence.end()) && !mpCustomAnimationList->isExpanded(*aInsertPos))
2123 0 : ++aInsertPos;
2124 :
2125 0 : rEffectSequence.insert( aInsertPos, pEffect );
2126 : }
2127 : else
2128 : {
2129 0 : rEffectSequence.push_back( pEffect );
2130 : }
2131 0 : bChanged = true;
2132 : }
2133 0 : }
2134 : }
2135 :
2136 0 : if( bChanged )
2137 : {
2138 0 : mpMainSequence->rebuild();
2139 0 : updateControls();
2140 0 : mrBase.GetDocShell()->SetModified();
2141 0 : }
2142 : }
2143 :
2144 0 : void CustomAnimationPane::onPreview( bool bForcePreview )
2145 : {
2146 0 : if( !bForcePreview && !mpCBAutoPreview->IsChecked() )
2147 0 : return;
2148 :
2149 0 : if( maListSelection.empty() )
2150 : {
2151 0 : rtl::Reference< MotionPathTag > xMotionPathTag;
2152 0 : MotionPathTagVector::iterator aIter;
2153 0 : for( aIter = maMotionPathTags.begin(); aIter != maMotionPathTags.end(); ++aIter )
2154 : {
2155 0 : if( (*aIter)->isSelected() )
2156 : {
2157 0 : xMotionPathTag = (*aIter);
2158 0 : break;
2159 : }
2160 : }
2161 :
2162 0 : if( xMotionPathTag.is() )
2163 : {
2164 0 : MainSequencePtr pSequence( new MainSequence() );
2165 0 : pSequence->append( xMotionPathTag->getEffect()->clone() );
2166 0 : preview( pSequence->getRootNode() );
2167 : }
2168 : else
2169 : {
2170 0 : Reference< XAnimationNodeSupplier > xNodeSupplier( mxCurrentPage, UNO_QUERY );
2171 0 : if( !xNodeSupplier.is() )
2172 0 : return;
2173 :
2174 0 : preview( xNodeSupplier->getAnimationNode() );
2175 0 : }
2176 : }
2177 : else
2178 : {
2179 0 : MainSequencePtr pSequence( new MainSequence() );
2180 :
2181 0 : EffectSequence::iterator aIter( maListSelection.begin() );
2182 0 : const EffectSequence::iterator aEnd( maListSelection.end() );
2183 :
2184 0 : while( aIter != aEnd )
2185 : {
2186 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
2187 0 : pSequence->append( pEffect->clone() );
2188 0 : }
2189 :
2190 0 : preview( pSequence->getRootNode() );
2191 : }
2192 : }
2193 :
2194 0 : void CustomAnimationPane::preview( const Reference< XAnimationNode >& xAnimationNode )
2195 : {
2196 0 : Reference< XParallelTimeContainer > xRoot = ParallelTimeContainer::create( ::comphelper::getProcessComponentContext() );
2197 0 : Sequence< ::com::sun::star::beans::NamedValue > aUserData( 1 );
2198 0 : aUserData[0].Name = "node-type";
2199 0 : aUserData[0].Value <<= ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT;
2200 0 : xRoot->setUserData( aUserData );
2201 0 : xRoot->appendChild( xAnimationNode );
2202 :
2203 0 : SlideShow::StartPreview( mrBase, mxCurrentPage, xRoot );
2204 0 : }
2205 :
2206 :
2207 : // ICustomAnimationListController
2208 0 : void CustomAnimationPane::onSelect()
2209 : {
2210 0 : maListSelection = mpCustomAnimationList->getSelection();
2211 0 : updateControls();
2212 0 : markShapesFromSelectedEffects();
2213 0 : }
2214 :
2215 :
2216 :
2217 :
2218 0 : const CustomAnimationPresets& CustomAnimationPane::getPresets (void)
2219 : {
2220 0 : if (mpCustomAnimationPresets == NULL)
2221 0 : mpCustomAnimationPresets = &CustomAnimationPresets::getCustomAnimationPresets();
2222 0 : return *mpCustomAnimationPresets;
2223 : }
2224 :
2225 :
2226 :
2227 0 : void CustomAnimationPane::markShapesFromSelectedEffects()
2228 : {
2229 0 : if( !maSelectionLock.isLocked() )
2230 : {
2231 0 : ScopeLockGuard aGuard( maSelectionLock );
2232 : DrawViewShell* pViewShell = dynamic_cast< DrawViewShell* >(
2233 0 : FrameworkHelper::Instance(mrBase)->GetViewShell(FrameworkHelper::msCenterPaneURL).get());
2234 0 : DrawView* pView = pViewShell ? pViewShell->GetDrawView() : NULL;
2235 :
2236 0 : if( pView )
2237 : {
2238 0 : pView->UnmarkAllObj();
2239 0 : EffectSequence::iterator aIter( maListSelection.begin() );
2240 0 : const EffectSequence::iterator aEnd( maListSelection.end() );
2241 0 : while( aIter != aEnd )
2242 : {
2243 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
2244 :
2245 0 : Reference< XShape > xShape( pEffect->getTargetShape() );
2246 0 : SdrObject* pObj = GetSdrObjectFromXShape( xShape );
2247 0 : if( pObj )
2248 0 : pView->MarkObj(pObj, pView->GetSdrPageView(), false, false);
2249 0 : }
2250 0 : }
2251 : }
2252 0 : }
2253 :
2254 :
2255 0 : void CustomAnimationPane::updatePathFromMotionPathTag( const rtl::Reference< MotionPathTag >& xTag )
2256 : {
2257 0 : MainSequenceRebuildGuard aGuard( mpMainSequence );
2258 0 : if( xTag.is() )
2259 : {
2260 0 : SdrPathObj* pPathObj = xTag->getPathObj();
2261 0 : CustomAnimationEffectPtr pEffect = xTag->getEffect();
2262 0 : if( (pPathObj != 0) && pEffect.get() != 0 )
2263 : {
2264 0 : ::svl::IUndoManager* pManager = mrBase.GetDocShell()->GetUndoManager();
2265 0 : if( pManager )
2266 : {
2267 0 : SdPage* pPage = SdPage::getImplementation( mxCurrentPage );
2268 0 : if( pPage )
2269 0 : pManager->AddUndoAction( new UndoAnimationPath( mrBase.GetDocShell()->GetDoc(), pPage, pEffect->getNode() ) );
2270 : }
2271 :
2272 0 : pEffect->updatePathFromSdrPathObj( *pPathObj );
2273 0 : }
2274 0 : }
2275 0 : }
2276 :
2277 :
2278 :
2279 :
2280 0 : ::Window * createCustomAnimationPanel( ::Window* pParent, ViewShellBase& rBase, const cssu::Reference<css::frame::XFrame>& rxFrame )
2281 : {
2282 0 : ::Window* pWindow = 0;
2283 :
2284 0 : DrawDocShell* pDocSh = rBase.GetDocShell();
2285 0 : if( pDocSh )
2286 : {
2287 0 : const Size aMinSize( pParent->LogicToPixel( Size( 80, 256 ), MAP_APPFONT ) );
2288 0 : pWindow = new CustomAnimationPane( pParent, rBase, rxFrame, aMinSize );
2289 : }
2290 :
2291 0 : return pWindow;
2292 : }
2293 :
2294 :
2295 0 : }
2296 :
2297 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|