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