bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / animations / SlideTransitionPane.cxx
blob86f2afd1f2ca99c4ad6328461f0ba6ce5b96d37a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/animations/XAnimationNode.hpp>
22 #include "SlideTransitionPane.hxx"
23 #include "CustomAnimation.hrc"
24 #include "createslidetransitionpanel.hxx"
26 #include "TransitionPreset.hxx"
27 #include "sdresid.hxx"
28 #include "ViewShellBase.hxx"
29 #include "DrawDocShell.hxx"
30 #include "SlideSorterViewShell.hxx"
31 #include "drawdoc.hxx"
32 #include "filedlg.hxx"
33 #include "strings.hrc"
34 #include "DrawController.hxx"
35 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <svtools/controldims.hrc>
38 #include <svx/gallery.hxx>
39 #include <unotools/pathoptions.hxx>
40 #include <vcl/msgbox.hxx>
41 #include <tools/urlobj.hxx>
42 #include "DrawViewShell.hxx"
43 #include "slideshow.hxx"
44 #include "drawview.hxx"
45 #include "sdundogr.hxx"
46 #include "undoanim.hxx"
47 #include "optsitem.hxx"
48 #include "sddll.hxx"
49 #include "framework/FrameworkHelper.hxx"
51 #include <sfx2/sidebar/Theme.hxx>
53 #include <algorithm>
55 using namespace ::com::sun::star;
57 using ::com::sun::star::uno::Reference;
58 using ::com::sun::star::uno::Sequence;
59 using ::com::sun::star::uno::RuntimeException;
61 using ::sd::framework::FrameworkHelper;
63 // ::sd::impl::TransitionEffect
64 namespace sd
66 namespace impl
68 struct TransitionEffect
70 TransitionEffect() :
71 mnType( 0 ),
72 mnSubType( 0 ),
73 mbDirection( true ),
74 mnFadeColor( 0 )
76 init();
78 explicit TransitionEffect( const ::sd::TransitionPreset & rPreset ) :
79 mnType( rPreset.getTransition()),
80 mnSubType( rPreset.getSubtype()),
81 mbDirection( rPreset.getDirection()),
82 mnFadeColor( rPreset.getFadeColor())
84 init();
86 explicit TransitionEffect( const SdPage & rPage ) :
87 mnType( rPage.getTransitionType() ),
88 mnSubType( rPage.getTransitionSubtype() ),
89 mbDirection( rPage.getTransitionDirection() ),
90 mnFadeColor( rPage.getTransitionFadeColor() )
92 init();
94 mfDuration = rPage.getTransitionDuration();
95 mfTime = rPage.GetTime();
96 mePresChange = rPage.GetPresChange();
97 mbSoundOn = rPage.IsSoundOn();
98 maSound = rPage.GetSoundFile();
99 mbLoopSound = rPage.IsLoopSound();
100 mbStopSound = rPage.IsStopSound();
103 void init()
105 mfDuration = 2.0;
106 mfTime = 0.0;
107 mePresChange = PRESCHANGE_MANUAL;
108 mbSoundOn = false;
109 mbLoopSound = false;
110 mbStopSound = false;
112 mbEffectAmbiguous = false;
113 mbDurationAmbiguous = false;
114 mbTimeAmbiguous = false;
115 mbPresChangeAmbiguous = false;
116 mbSoundAmbiguous = false;
117 mbLoopSoundAmbiguous = false;
120 void setAllAmbiguous()
122 mbEffectAmbiguous = true;
123 mbDurationAmbiguous = true;
124 mbTimeAmbiguous = true;
125 mbPresChangeAmbiguous = true;
126 mbSoundAmbiguous = true;
127 mbLoopSoundAmbiguous = true;
130 bool operator == ( const ::sd::TransitionPreset & rPreset ) const
132 return
133 (mnType == rPreset.getTransition()) &&
134 (mnSubType == rPreset.getSubtype()) &&
135 (mbDirection == rPreset.getDirection()) &&
136 (mnFadeColor == rPreset.getFadeColor());
139 void applyTo( SdPage & rOutPage ) const
141 if( ! mbEffectAmbiguous )
143 rOutPage.setTransitionType( mnType );
144 rOutPage.setTransitionSubtype( mnSubType );
145 rOutPage.setTransitionDirection( mbDirection );
146 rOutPage.setTransitionFadeColor( mnFadeColor );
149 if( ! mbDurationAmbiguous )
150 rOutPage.setTransitionDuration( mfDuration );
151 if( ! mbTimeAmbiguous )
152 rOutPage.SetTime( mfTime );
153 if( ! mbPresChangeAmbiguous )
154 rOutPage.SetPresChange( mePresChange );
155 if( ! mbSoundAmbiguous )
157 if( mbStopSound )
159 rOutPage.SetStopSound( true );
160 rOutPage.SetSound( false );
162 else
164 rOutPage.SetStopSound( false );
165 rOutPage.SetSound( mbSoundOn );
166 rOutPage.SetSoundFile( maSound );
169 if( ! mbLoopSoundAmbiguous )
170 rOutPage.SetLoopSound( mbLoopSound );
173 void compareWith( const SdPage & rPage )
175 TransitionEffect aOtherEffect( rPage );
176 mbEffectAmbiguous = mbEffectAmbiguous || aOtherEffect.mbEffectAmbiguous
177 || (mnType != aOtherEffect.mnType)
178 || (mnSubType != aOtherEffect.mnSubType)
179 || (mbDirection != aOtherEffect.mbDirection)
180 || (mnFadeColor != aOtherEffect.mnFadeColor);
182 mbDurationAmbiguous = mbDurationAmbiguous || aOtherEffect.mbDurationAmbiguous || mfDuration != aOtherEffect.mfDuration;
183 mbTimeAmbiguous = mbTimeAmbiguous || aOtherEffect.mbTimeAmbiguous || mfTime != aOtherEffect.mfTime;
184 mbPresChangeAmbiguous = mbPresChangeAmbiguous || aOtherEffect.mbPresChangeAmbiguous || mePresChange != aOtherEffect.mePresChange;
185 mbSoundAmbiguous = mbSoundAmbiguous || aOtherEffect.mbSoundAmbiguous || mbSoundOn != aOtherEffect.mbSoundOn;
186 #if 0
187 // Weird leftover isolated expression with no effect, introduced in 2007 in
188 // CWS impress122. Ifdeffed out to avoid compiler warning, kept here in case
189 // somebody who understands this code notices and understands what the
190 // "right" thing to do might be.
191 (!mbStopSound && !aOtherEffect.mbStopSound && maSound != aOtherEffect.maSound) || (mbStopSound != aOtherEffect.mbStopSound);
192 #endif
193 mbLoopSoundAmbiguous = mbLoopSoundAmbiguous || aOtherEffect.mbLoopSoundAmbiguous || mbLoopSound != aOtherEffect.mbLoopSound;
196 // effect
197 sal_Int16 mnType;
198 sal_Int16 mnSubType;
199 bool mbDirection;
200 sal_Int32 mnFadeColor;
202 // other settings
203 double mfDuration;
204 double mfTime;
205 PresChange mePresChange;
206 bool mbSoundOn;
207 OUString maSound;
208 bool mbLoopSound;
209 bool mbStopSound;
211 bool mbEffectAmbiguous;
212 bool mbDurationAmbiguous;
213 bool mbTimeAmbiguous;
214 bool mbPresChangeAmbiguous;
215 bool mbSoundAmbiguous;
216 bool mbLoopSoundAmbiguous;
219 } // namespace impl
220 } // namespace sd
222 // Local Helper Functions
223 namespace
226 void lcl_ApplyToPages(
227 const ::sd::slidesorter::SharedPageSelection& rpPages,
228 const ::sd::impl::TransitionEffect & rEffect )
230 ::std::vector< SdPage * >::const_iterator aIt( rpPages->begin());
231 const ::std::vector< SdPage * >::const_iterator aEndIt( rpPages->end());
232 for( ; aIt != aEndIt; ++aIt )
234 rEffect.applyTo( *(*aIt) );
238 void lcl_CreateUndoForPages(
239 const ::sd::slidesorter::SharedPageSelection& rpPages,
240 ::sd::ViewShellBase& rBase )
242 ::sd::DrawDocShell* pDocSh = rBase.GetDocShell();
243 if (!pDocSh)
244 return;
245 ::svl::IUndoManager* pManager = pDocSh->GetUndoManager();
246 if (!pManager)
247 return;
248 SdDrawDocument* pDoc = pDocSh->GetDoc();
249 if (!pDoc)
250 return;
252 OUString aComment( SdResId(STR_UNDO_SLIDE_PARAMS) );
253 pManager->EnterListAction(aComment, aComment);
254 SdUndoGroup* pUndoGroup = new SdUndoGroup( pDoc );
255 pUndoGroup->SetComment( aComment );
257 ::std::vector< SdPage * >::const_iterator aIt( rpPages->begin());
258 const ::std::vector< SdPage * >::const_iterator aEndIt( rpPages->end());
259 for( ; aIt != aEndIt; ++aIt )
261 pUndoGroup->AddAction( new sd::UndoTransition( pDoc, (*aIt) ) );
264 pManager->AddUndoAction( pUndoGroup );
265 pManager->LeaveListAction();
268 sal_Int32 lcl_getTransitionEffectIndex(
269 SdDrawDocument * pDoc,
270 const ::sd::impl::TransitionEffect & rTransition )
272 // first entry: "<none>"
273 sal_Int32 nResultIndex = LISTBOX_ENTRY_NOTFOUND;
275 if( pDoc )
277 sal_Int32 nCurrentIndex = 0;
278 const ::sd::TransitionPresetList & rPresetList = ::sd::TransitionPreset::getTransitionPresetList();
279 ::sd::TransitionPresetList::const_iterator aIt( rPresetList.begin());
280 const ::sd::TransitionPresetList::const_iterator aEndIt( rPresetList.end());
281 for( ; aIt != aEndIt; ++aIt, ++nCurrentIndex )
283 if( rTransition.operator==( *(*aIt) ))
285 nResultIndex = nCurrentIndex;
286 break;
291 return nResultIndex;
294 ::sd::TransitionPresetPtr lcl_getTransitionPresetByUIName(
295 SdDrawDocument * pDoc,
296 const OUString & rUIName )
298 ::sd::TransitionPresetPtr pResult;
299 if( pDoc )
301 const ::sd::TransitionPresetList& rPresetList = ::sd::TransitionPreset::getTransitionPresetList();
302 ::sd::TransitionPresetList::const_iterator aIter( rPresetList.begin() );
303 const ::sd::TransitionPresetList::const_iterator aEnd( rPresetList.end() );
304 for( ; aIter != aEnd; ++aIter )
306 if( (*aIter)->getUIName().equals( rUIName ))
308 pResult = *aIter;
309 break;
314 return pResult;
317 struct lcl_EqualsSoundFileName : public ::std::unary_function< OUString, bool >
319 explicit lcl_EqualsSoundFileName( const OUString & rStr ) :
320 maStr( rStr )
323 bool operator() ( const OUString & rStr ) const
325 // note: formerly this was a case insensitive search for all
326 // platforms. It seems more sensible to do this platform-dependent
327 #if defined( WNT )
328 return maStr.equalsIgnoreAsciiCase( rStr );
329 #else
330 return maStr == rStr;
331 #endif
334 private:
335 OUString maStr;
338 // returns -1 if no object was found
339 bool lcl_findSoundInList( const ::std::vector< OUString > & rSoundList,
340 const OUString & rFileName,
341 ::std::vector< OUString >::size_type & rOutPosition )
343 ::std::vector< OUString >::const_iterator aIt =
344 ::std::find_if( rSoundList.begin(), rSoundList.end(),
345 lcl_EqualsSoundFileName( rFileName ));
346 if( aIt != rSoundList.end())
348 rOutPosition = ::std::distance( rSoundList.begin(), aIt );
349 return true;
352 return false;
355 OUString lcl_getSoundFileURL(
356 const ::std::vector< OUString > & rSoundList,
357 const ListBox* rListBox )
359 if( rListBox->GetSelectEntryCount() > 0 )
361 sal_Int32 nPos = rListBox->GetSelectEntryPos();
362 // the first three entries are no actual sounds
363 if( nPos >= 3 )
365 DBG_ASSERT( (sal_uInt32)(rListBox->GetEntryCount() - 3) == rSoundList.size(),
366 "Sound list-box is not synchronized to sound list" );
367 nPos -= 3;
368 if( rSoundList.size() > static_cast<size_t>(nPos) )
369 return rSoundList[ nPos ];
373 return OUString();
376 struct lcl_AppendSoundToListBox : public ::std::unary_function< OUString, void >
378 lcl_AppendSoundToListBox( ListBox* rListBox ) :
379 mrListBox( rListBox )
382 void operator() ( const OUString & rString ) const
384 INetURLObject aURL( rString );
385 mrListBox->InsertEntry( aURL.GetBase(), LISTBOX_APPEND );
388 private:
389 VclPtr<ListBox> mrListBox;
392 void lcl_FillSoundListBox(
393 const ::std::vector< OUString > & rSoundList,
394 ListBox* rOutListBox )
396 sal_Int32 nCount = rOutListBox->GetEntryCount();
398 // keep first three entries
399 for( sal_Int32 i=nCount - 1; i>=3; --i )
400 rOutListBox->RemoveEntry( i );
402 ::std::for_each( rSoundList.begin(), rSoundList.end(),
403 lcl_AppendSoundToListBox( rOutListBox ));
406 } // anonymous namespace
408 namespace sd
411 // SlideTransitionPane
412 SlideTransitionPane::SlideTransitionPane(
413 Window * pParent,
414 ViewShellBase & rBase,
415 const Size& rMinSize,
416 SdDrawDocument* pDoc,
417 const css::uno::Reference<css::frame::XFrame>& rxFrame ) :
418 PanelLayout( pParent, "SlideTransitionsPanel", "modules/simpress/ui/slidetransitionspanel.ui", rxFrame ),
420 mrBase( rBase ),
421 mpDrawDoc( pDoc ),
422 maMinSize( rMinSize ),
423 mbHasSelection( false ),
424 mbUpdatingControls( false ),
425 mbIsMainViewChangePending( false ),
426 maLateInitTimer()
428 get(mpLB_SLIDE_TRANSITIONS, "transitions_list");
429 get(mpFT_SPEED, "speed_label");
430 get(mpLB_SPEED, "speed_list");
431 get(mpFT_SOUND, "sound_label");
432 get(mpLB_SOUND, "sound_list");
433 get(mpCB_LOOP_SOUND, "loop_sound" );
434 get(mpRB_ADVANCE_ON_MOUSE, "rb_mouse_click");
435 get(mpRB_ADVANCE_AUTO, "rb_auto_after");
436 get(mpMF_ADVANCE_AUTO_AFTER, "auto_after_value");
437 get(mpPB_APPLY_TO_ALL, "apply_to_all");
438 get(mpPB_PLAY, "play");
439 get(mpCB_AUTO_PREVIEW, "auto_preview");
441 mpLB_SLIDE_TRANSITIONS->set_width_request(mpLB_SLIDE_TRANSITIONS->approximate_char_width() * 16);
442 mpLB_SLIDE_TRANSITIONS->SetDropDownLineCount(4);
444 if( pDoc )
445 mxModel.set( pDoc->getUnoModel(), uno::UNO_QUERY );
446 // TODO: get correct view
447 if( mxModel.is())
448 mxView.set( mxModel->getCurrentController(), uno::UNO_QUERY );
450 // fill list box of slide transitions
451 mpLB_SLIDE_TRANSITIONS->InsertEntry( SD_RESSTR( STR_SLIDETRANSITION_NONE ) );
453 // set defaults
454 mpCB_AUTO_PREVIEW->Check(); // automatic preview on
456 // update control states before adding handlers
457 updateControls();
459 // set handlers
460 mpPB_APPLY_TO_ALL->SetClickHdl( LINK( this, SlideTransitionPane, ApplyToAllButtonClicked ));
461 mpPB_PLAY->SetClickHdl( LINK( this, SlideTransitionPane, PlayButtonClicked ));
463 mpLB_SLIDE_TRANSITIONS->SetSelectHdl( LINK( this, SlideTransitionPane, TransitionSelected ));
465 mpLB_SPEED->SetSelectHdl( LINK( this, SlideTransitionPane, SpeedListBoxSelected ));
466 mpLB_SOUND->SetSelectHdl( LINK( this, SlideTransitionPane, SoundListBoxSelected ));
467 mpCB_LOOP_SOUND->SetClickHdl( LINK( this, SlideTransitionPane, LoopSoundBoxChecked ));
469 mpRB_ADVANCE_ON_MOUSE->SetToggleHdl( LINK( this, SlideTransitionPane, AdvanceSlideRadioButtonToggled ));
470 mpRB_ADVANCE_AUTO->SetToggleHdl( LINK( this, SlideTransitionPane, AdvanceSlideRadioButtonToggled ));
471 mpMF_ADVANCE_AUTO_AFTER->SetModifyHdl( LINK( this, SlideTransitionPane, AdvanceTimeModified ));
472 mpCB_AUTO_PREVIEW->SetClickHdl( LINK( this, SlideTransitionPane, AutoPreviewClicked ));
473 addListener();
475 maLateInitTimer.SetTimeout(200);
476 maLateInitTimer.SetTimeoutHdl(LINK(this, SlideTransitionPane, LateInitCallback));
477 maLateInitTimer.Start();
479 UpdateLook();
482 SlideTransitionPane::~SlideTransitionPane()
484 disposeOnce();
487 void SlideTransitionPane::dispose()
489 maLateInitTimer.Stop();
490 removeListener();
491 mpLB_SLIDE_TRANSITIONS.clear();
492 mpFT_SPEED.clear();
493 mpLB_SPEED.clear();
494 mpFT_SOUND.clear();
495 mpLB_SOUND.clear();
496 mpCB_LOOP_SOUND.clear();
497 mpRB_ADVANCE_ON_MOUSE.clear();
498 mpRB_ADVANCE_AUTO.clear();
499 mpMF_ADVANCE_AUTO_AFTER.clear();
500 mpPB_APPLY_TO_ALL.clear();
501 mpPB_PLAY.clear();
502 mpCB_AUTO_PREVIEW.clear();
503 PanelLayout::dispose();
506 void SlideTransitionPane::DataChanged (const DataChangedEvent& rEvent)
508 (void)rEvent;
509 UpdateLook();
512 void SlideTransitionPane::UpdateLook()
514 SetBackground(::sfx2::sidebar::Theme::GetWallpaper(::sfx2::sidebar::Theme::Paint_PanelBackground));
515 mpFT_SPEED->SetBackground(Wallpaper());
516 mpFT_SOUND->SetBackground(Wallpaper());
519 void SlideTransitionPane::onSelectionChanged()
521 updateControls();
524 void SlideTransitionPane::onChangeCurrentPage()
526 updateControls();
529 ::sd::slidesorter::SharedPageSelection SlideTransitionPane::getSelectedPages() const
531 ::sd::slidesorter::SlideSorterViewShell * pSlideSorterViewShell
532 = ::sd::slidesorter::SlideSorterViewShell::GetSlideSorter(mrBase);
533 ::boost::shared_ptr<sd::slidesorter::SlideSorterViewShell::PageSelection> pSelection;
535 if( pSlideSorterViewShell )
537 pSelection = pSlideSorterViewShell->GetPageSelection();
539 else
541 pSelection.reset(new sd::slidesorter::SlideSorterViewShell::PageSelection());
542 if( mxView.is() )
544 SdPage* pPage = SdPage::getImplementation( mxView->getCurrentPage() );
545 if( pPage )
546 pSelection->push_back(pPage);
550 return pSelection;
553 void SlideTransitionPane::updateControls()
555 ::sd::slidesorter::SharedPageSelection pSelectedPages(getSelectedPages());
556 if( pSelectedPages->empty())
558 mbHasSelection = false;
559 return;
561 mbHasSelection = true;
563 DBG_ASSERT( ! mbUpdatingControls, "Multiple Control Updates" );
564 mbUpdatingControls = true;
566 // get model data for first page
567 SdPage * pFirstPage = pSelectedPages->front();
568 DBG_ASSERT( pFirstPage, "Invalid Page" );
570 impl::TransitionEffect aEffect( *pFirstPage );
572 // merge with other pages
573 ::sd::slidesorter::SlideSorterViewShell::PageSelection::const_iterator aIt(
574 pSelectedPages->begin());
575 ::sd::slidesorter::SlideSorterViewShell::PageSelection::const_iterator aEndIt(
576 pSelectedPages->end());
578 // start with second page (note aIt != aEndIt, because ! aSelectedPages.empty())
579 for( ++aIt ;aIt != aEndIt; ++aIt )
581 if( *aIt )
582 aEffect.compareWith( *(*aIt) );
585 // detect current slide effect
586 if( aEffect.mbEffectAmbiguous )
587 mpLB_SLIDE_TRANSITIONS->SetNoSelection();
588 else
590 // ToDo: That 0 is "no transition" is documented nowhere except in the
591 // CTOR of sdpage
592 if( aEffect.mnType == 0 )
593 mpLB_SLIDE_TRANSITIONS->SelectEntryPos( 0 );
594 else
596 sal_Int32 nEntry = lcl_getTransitionEffectIndex( mpDrawDoc, aEffect );
597 if( nEntry == LISTBOX_ENTRY_NOTFOUND )
598 mpLB_SLIDE_TRANSITIONS->SetNoSelection();
599 else
601 // first entry in list is "none", so add 1 after translation
602 if( m_aPresetIndexes.find( nEntry ) != m_aPresetIndexes.end())
603 mpLB_SLIDE_TRANSITIONS->SelectEntryPos( m_aPresetIndexes[ nEntry ] + 1 );
604 else
605 mpLB_SLIDE_TRANSITIONS->SetNoSelection();
610 if( aEffect.mbDurationAmbiguous )
611 mpLB_SPEED->SetNoSelection();
612 else
613 mpLB_SPEED->SelectEntryPos(
614 (aEffect.mfDuration > 2.0 )
615 ? 0 : (aEffect.mfDuration < 2.0)
616 ? 2 : 1 ); // else FADE_SPEED_FAST
618 if( aEffect.mbSoundAmbiguous )
620 mpLB_SOUND->SetNoSelection();
621 maCurrentSoundFile.clear();
623 else
625 maCurrentSoundFile.clear();
626 if( aEffect.mbStopSound )
628 mpLB_SOUND->SelectEntryPos( 1 );
630 else if( aEffect.mbSoundOn && !aEffect.maSound.isEmpty() )
632 tSoundListType::size_type nPos = 0;
633 if( lcl_findSoundInList( maSoundList, aEffect.maSound, nPos ))
635 // skip first three entries
636 mpLB_SOUND->SelectEntryPos( nPos + 3 );
637 maCurrentSoundFile = aEffect.maSound;
640 else
642 mpLB_SOUND->SelectEntryPos( 0 );
646 if( aEffect.mbLoopSoundAmbiguous )
648 mpCB_LOOP_SOUND->SetState( TRISTATE_INDET );
650 else
652 mpCB_LOOP_SOUND->Check( aEffect.mbLoopSound );
655 if( aEffect.mbPresChangeAmbiguous )
657 mpRB_ADVANCE_ON_MOUSE->Check( false );
658 mpRB_ADVANCE_AUTO->Check( false );
660 else
662 mpRB_ADVANCE_ON_MOUSE->Check( aEffect.mePresChange == PRESCHANGE_MANUAL );
663 mpRB_ADVANCE_AUTO->Check( aEffect.mePresChange == PRESCHANGE_AUTO );
664 mpMF_ADVANCE_AUTO_AFTER->SetValue( aEffect.mfTime * 100.0);
667 SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
668 mpCB_AUTO_PREVIEW->Check( pOptions->IsPreviewTransitions() );
670 mbUpdatingControls = false;
672 updateControlState();
675 void SlideTransitionPane::updateControlState()
677 mpLB_SLIDE_TRANSITIONS->Enable( mbHasSelection );
678 mpLB_SPEED->Enable( mbHasSelection );
679 mpLB_SOUND->Enable( mbHasSelection );
680 mpCB_LOOP_SOUND->Enable( mbHasSelection && (mpLB_SOUND->GetSelectEntryPos() > 2));
681 mpRB_ADVANCE_ON_MOUSE->Enable( mbHasSelection );
682 mpRB_ADVANCE_AUTO->Enable( mbHasSelection );
683 mpMF_ADVANCE_AUTO_AFTER->Enable( mbHasSelection && mpRB_ADVANCE_AUTO->IsChecked());
685 mpPB_APPLY_TO_ALL->Enable( mbHasSelection );
686 mpPB_PLAY->Enable( mbHasSelection );
687 mpCB_AUTO_PREVIEW->Enable( mbHasSelection );
690 void SlideTransitionPane::updateSoundList()
692 maSoundList.clear();
694 GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, maSoundList );
695 GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, maSoundList );
697 lcl_FillSoundListBox( maSoundList, mpLB_SOUND );
700 void SlideTransitionPane::openSoundFileDialog()
702 if( ! mpLB_SOUND->IsEnabled())
703 return;
705 SdOpenSoundFileDialog aFileDialog;
707 OUString aFile;
708 DBG_ASSERT( mpLB_SOUND->GetSelectEntryPos() == 2,
709 "Dialog should only open when \"Other sound\" is selected" );
710 aFile = SvtPathOptions().GetGraphicPath();
712 aFileDialog.SetPath( aFile );
714 bool bValidSoundFile( false );
715 bool bQuitLoop( false );
717 while( ! bQuitLoop &&
718 aFileDialog.Execute() == ERRCODE_NONE )
720 aFile = aFileDialog.GetPath();
721 tSoundListType::size_type nPos = 0;
722 bValidSoundFile = lcl_findSoundInList( maSoundList, aFile, nPos );
724 if( bValidSoundFile )
726 bQuitLoop = true;
728 else // not in sound list
730 // try to insert into gallery
731 if( GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aFile ) )
733 updateSoundList();
734 bValidSoundFile = lcl_findSoundInList( maSoundList, aFile, nPos );
735 DBG_ASSERT( bValidSoundFile, "Adding sound to gallery failed" );
737 bQuitLoop = true;
739 else
741 OUString aStrWarning(SD_RESSTR(STR_WARNING_NOSOUNDFILE));
742 aStrWarning = aStrWarning.replaceFirst("%", aFile);
743 ScopedVclPtrInstance< WarningBox > aWarningBox( nullptr, WB_3DLOOK | WB_RETRY_CANCEL, aStrWarning );
744 aWarningBox->SetModalInputMode (true);
745 bQuitLoop = (aWarningBox->Execute() != RET_RETRY);
747 bValidSoundFile = false;
751 if( bValidSoundFile )
752 // skip first three entries in list
753 mpLB_SOUND->SelectEntryPos( nPos + 3 );
756 if( ! bValidSoundFile )
758 if( !maCurrentSoundFile.isEmpty() )
760 tSoundListType::size_type nPos = 0;
761 if( lcl_findSoundInList( maSoundList, maCurrentSoundFile, nPos ))
762 mpLB_SOUND->SelectEntryPos( nPos + 3 );
763 else
764 mpLB_SOUND->SelectEntryPos( 0 ); // NONE
766 else
767 mpLB_SOUND->SelectEntryPos( 0 ); // NONE
771 impl::TransitionEffect SlideTransitionPane::getTransitionEffectFromControls() const
773 impl::TransitionEffect aResult;
774 aResult.setAllAmbiguous();
776 // check first (aResult might be overwritten)
777 if( mpLB_SLIDE_TRANSITIONS->IsEnabled() &&
778 mpLB_SLIDE_TRANSITIONS->GetSelectEntryCount() > 0 )
780 TransitionPresetPtr pPreset = lcl_getTransitionPresetByUIName(
781 mpDrawDoc, OUString( mpLB_SLIDE_TRANSITIONS->GetSelectEntry()));
783 if( pPreset.get())
785 aResult = impl::TransitionEffect( *pPreset );
786 aResult.setAllAmbiguous();
788 else
790 aResult.mnType = 0;
792 aResult.mbEffectAmbiguous = false;
795 // speed
796 if( mpLB_SPEED->IsEnabled() &&
797 mpLB_SPEED->GetSelectEntryCount() > 0 )
799 sal_Int32 nPos = mpLB_SPEED->GetSelectEntryPos();
800 aResult.mfDuration = (nPos == 0)
801 ? 3.0
802 : (nPos == 1)
803 ? 2.0
804 : 1.0; // nPos == 2
805 DBG_ASSERT( aResult.mfDuration != 1.0 || nPos == 2, "Invalid Listbox Entry" );
807 aResult.mbDurationAmbiguous = false;
810 // slide-advance mode
811 if( mpRB_ADVANCE_ON_MOUSE->IsEnabled() && mpRB_ADVANCE_AUTO->IsEnabled() &&
812 (mpRB_ADVANCE_ON_MOUSE->IsChecked() || mpRB_ADVANCE_AUTO->IsChecked()))
814 if( mpRB_ADVANCE_ON_MOUSE->IsChecked())
815 aResult.mePresChange = PRESCHANGE_MANUAL;
816 else
818 aResult.mePresChange = PRESCHANGE_AUTO;
819 if( mpMF_ADVANCE_AUTO_AFTER->IsEnabled())
821 aResult.mfTime = static_cast<double>(mpMF_ADVANCE_AUTO_AFTER->GetValue() ) / 100.0 ;
822 aResult.mbTimeAmbiguous = false;
826 aResult.mbPresChangeAmbiguous = false;
829 // sound
830 if( mpLB_SOUND->IsEnabled())
832 maCurrentSoundFile.clear();
833 if( mpLB_SOUND->GetSelectEntryCount() > 0 )
835 sal_Int32 nPos = mpLB_SOUND->GetSelectEntryPos();
836 aResult.mbStopSound = nPos == 1;
837 aResult.mbSoundOn = nPos > 1;
838 if( aResult.mbStopSound )
840 aResult.maSound.clear();
841 aResult.mbSoundAmbiguous = false;
843 else
845 aResult.maSound = lcl_getSoundFileURL( maSoundList, mpLB_SOUND );
846 aResult.mbSoundAmbiguous = false;
847 maCurrentSoundFile = aResult.maSound;
852 // sound loop
853 if( mpCB_LOOP_SOUND->IsEnabled() )
855 aResult.mbLoopSound = mpCB_LOOP_SOUND->IsChecked();
856 aResult.mbLoopSoundAmbiguous = false;
859 return aResult;
862 void SlideTransitionPane::applyToSelectedPages()
864 if( ! mbUpdatingControls )
866 Window *pFocusWindow = Application::GetFocusWindow();
868 ::sd::slidesorter::SharedPageSelection pSelectedPages( getSelectedPages());
869 impl::TransitionEffect aEffect = getTransitionEffectFromControls();
870 if( ! pSelectedPages->empty())
872 lcl_CreateUndoForPages( pSelectedPages, mrBase );
873 lcl_ApplyToPages( pSelectedPages, aEffect );
874 mrBase.GetDocShell()->SetModified();
876 if( mpCB_AUTO_PREVIEW->IsEnabled() &&
877 mpCB_AUTO_PREVIEW->IsChecked())
879 if (aEffect.mnType) // mnType = 0 denotes no transition
880 playCurrentEffect();
881 else
882 stopEffects();
885 if (pFocusWindow)
886 pFocusWindow->GrabFocus();
890 void SlideTransitionPane::playCurrentEffect()
892 if( mxView.is() )
895 Reference< ::com::sun::star::animations::XAnimationNode > xNode;
896 SlideShow::StartPreview( mrBase, mxView->getCurrentPage(), xNode );
900 void SlideTransitionPane::stopEffects()
902 if( mxView.is() )
904 SlideShow::Stop( mrBase );
908 void SlideTransitionPane::addListener()
910 Link<> aLink( LINK(this,SlideTransitionPane,EventMultiplexerListener) );
911 mrBase.GetEventMultiplexer()->AddEventListener (
912 aLink,
913 tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
914 | tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION
915 | tools::EventMultiplexerEvent::EID_CURRENT_PAGE
916 | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
917 | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
918 | tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED);
921 void SlideTransitionPane::removeListener()
923 Link<> aLink( LINK(this,SlideTransitionPane,EventMultiplexerListener) );
924 mrBase.GetEventMultiplexer()->RemoveEventListener( aLink );
927 IMPL_LINK(SlideTransitionPane,EventMultiplexerListener,
928 tools::EventMultiplexerEvent*,pEvent)
930 switch (pEvent->meEventId)
932 case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION:
933 onSelectionChanged();
934 break;
936 case tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
937 case tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION:
938 onChangeCurrentPage();
939 break;
941 case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
942 mxView = Reference<drawing::XDrawView>();
943 onSelectionChanged();
944 onChangeCurrentPage();
945 break;
947 case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
948 mbIsMainViewChangePending = true;
949 break;
951 case tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
952 if (mbIsMainViewChangePending)
954 mbIsMainViewChangePending = false;
956 // At this moment the controller may not yet been set at
957 // model or ViewShellBase. Take it from the view shell
958 // passed with the event.
959 if (mrBase.GetMainViewShell() != 0)
961 mxView = Reference<drawing::XDrawView>::query(mrBase.GetController());
962 onSelectionChanged();
963 onChangeCurrentPage();
966 break;
968 default:
969 break;
971 return 0;
974 IMPL_LINK_NOARG(SlideTransitionPane, ApplyToAllButtonClicked)
976 DBG_ASSERT( mpDrawDoc, "Invalid Draw Document!" );
977 if( !mpDrawDoc )
978 return 0;
980 ::sd::slidesorter::SharedPageSelection pPages (
981 new ::sd::slidesorter::SlideSorterViewShell::PageSelection());
983 sal_uInt16 nPageCount = mpDrawDoc->GetSdPageCount( PK_STANDARD );
984 pPages->reserve( nPageCount );
985 for( sal_uInt16 i=0; i<nPageCount; ++i )
987 SdPage * pPage = mpDrawDoc->GetSdPage( i, PK_STANDARD );
988 if( pPage )
989 pPages->push_back( pPage );
992 if( ! pPages->empty())
994 lcl_CreateUndoForPages( pPages, mrBase );
995 lcl_ApplyToPages( pPages, getTransitionEffectFromControls() );
998 return 0;
1001 IMPL_LINK_NOARG(SlideTransitionPane, PlayButtonClicked)
1003 playCurrentEffect();
1004 return 0;
1007 IMPL_LINK_NOARG(SlideTransitionPane, TransitionSelected)
1009 applyToSelectedPages();
1010 return 0;
1013 IMPL_LINK_NOARG(SlideTransitionPane, AdvanceSlideRadioButtonToggled)
1015 updateControlState();
1016 applyToSelectedPages();
1017 return 0;
1020 IMPL_LINK_NOARG(SlideTransitionPane, AdvanceTimeModified)
1022 applyToSelectedPages();
1023 return 0;
1026 IMPL_LINK_NOARG(SlideTransitionPane, SpeedListBoxSelected)
1028 applyToSelectedPages();
1029 return 0;
1032 IMPL_LINK_NOARG(SlideTransitionPane, SoundListBoxSelected)
1034 if( mpLB_SOUND->GetSelectEntryCount() )
1036 sal_Int32 nPos = mpLB_SOUND->GetSelectEntryPos();
1037 if( nPos == 2 )
1039 // other sound...
1040 openSoundFileDialog();
1043 updateControlState();
1044 applyToSelectedPages();
1045 return 0;
1048 IMPL_LINK_NOARG(SlideTransitionPane, LoopSoundBoxChecked)
1050 applyToSelectedPages();
1051 return 0;
1054 IMPL_LINK_NOARG(SlideTransitionPane, AutoPreviewClicked)
1056 SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
1057 pOptions->SetPreviewTransitions( mpCB_AUTO_PREVIEW->IsChecked() );
1058 return 0;
1061 IMPL_LINK_NOARG_TYPED(SlideTransitionPane, LateInitCallback, Timer *, void)
1063 const TransitionPresetList& rPresetList = TransitionPreset::getTransitionPresetList();
1064 TransitionPresetList::const_iterator aIter( rPresetList.begin() );
1065 const TransitionPresetList::const_iterator aEnd( rPresetList.end() );
1066 sal_uInt16 nIndex = 0;
1067 ::std::size_t nUIIndex = 0;
1068 while( aIter != aEnd )
1070 TransitionPresetPtr pPreset = (*aIter++);
1071 const OUString aUIName( pPreset->getUIName() );
1072 if( !aUIName.isEmpty() )
1074 mpLB_SLIDE_TRANSITIONS->InsertEntry( aUIName );
1075 m_aPresetIndexes[ nIndex ] = (sal_uInt16)nUIIndex;
1076 ++nUIIndex;
1078 ++nIndex;
1081 updateSoundList();
1082 updateControls();
1085 vcl::Window * createSlideTransitionPanel( vcl::Window* pParent, ViewShellBase& rBase, const css::uno::Reference<css::frame::XFrame>& rxFrame )
1087 vcl::Window* pWindow = 0;
1089 DrawDocShell* pDocSh = rBase.GetDocShell();
1090 if( pDocSh )
1092 Size aMinSize( pParent->LogicToPixel( Size( 72, 216 ), MAP_APPFONT ) );
1093 pWindow = VclPtr<SlideTransitionPane>::Create( pParent, rBase, aMinSize, pDocSh->GetDoc(), rxFrame );
1096 return pWindow;
1099 } // namespace sd
1101 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */