1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 #include <com/sun/star/animations/XAnimationNode.hpp>
27 
28 #include "SlideTransitionPane.hxx"
29 #include "SlideTransitionPane.hrc"
30 #include "CustomAnimation.hrc"
31 
32 #include "TransitionPreset.hxx"
33 #include "sdresid.hxx"
34 #include "ViewShellBase.hxx"
35 #include "DrawDocShell.hxx"
36 #include "SlideSorterViewShell.hxx"
37 #include "drawdoc.hxx"
38 #include "filedlg.hxx"
39 #include "strings.hrc"
40 #include "DrawController.hxx"
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 
43 #ifndef _SVT_CONTROLDIMS_HRC_
44 #include <svtools/controldims.hrc>
45 #endif
46 #include <svx/gallery.hxx>
47 #include <unotools/pathoptions.hxx>
48 #include <vcl/msgbox.hxx>
49 #include <tools/urlobj.hxx>
50 #include "DrawViewShell.hxx"
51 #include "slideshow.hxx"
52 #include "drawview.hxx"
53 #include "sdundogr.hxx"
54 #include "undoanim.hxx"
55 #include "optsitem.hxx"
56 #include "sddll.hxx"
57 #include "framework/FrameworkHelper.hxx"
58 
59 #include "DialogListBox.hxx"
60 #include <sfx2/sidebar/Theme.hxx>
61 
62 #include <algorithm>
63 #include <memory>
64 
65 
66 using namespace ::com::sun::star;
67 
68 using ::com::sun::star::uno::Reference;
69 using ::com::sun::star::uno::Sequence;
70 using ::rtl::OUString;
71 using ::com::sun::star::uno::RuntimeException;
72 
73 using ::sd::framework::FrameworkHelper;
74 
75 // ____________________________
76 //
77 // ::sd::impl::TransitionEffect
78 // ____________________________
79 
80 namespace sd
81 {
82 namespace impl
83 {
84 struct TransitionEffect
85 {
86     TransitionEffect() :
87             mnType( 0 ),
88             mnSubType( 0 ),
89             mbDirection( sal_True ),
90             mnFadeColor( 0 )
91     {
92         init();
93     }
94     explicit TransitionEffect( const ::sd::TransitionPreset & rPreset ) :
95             mnType( rPreset.getTransition()),
96             mnSubType( rPreset.getSubtype()),
97             mbDirection( rPreset.getDirection()),
98             mnFadeColor( rPreset.getFadeColor())
99     {
100         init();
101     }
102     explicit TransitionEffect( sal_Int16 nType, sal_Int16 nSubType,
103                                sal_Bool  bDirection, sal_Int32 nFadeColor ) :
104             mnType( nType),
105             mnSubType( nSubType ),
106             mbDirection( bDirection ),
107             mnFadeColor( nFadeColor )
108     {
109         init();
110     }
111     explicit TransitionEffect( const SdPage & rPage ) :
112             mnType( rPage.getTransitionType() ),
113             mnSubType( rPage.getTransitionSubtype() ),
114             mbDirection( rPage.getTransitionDirection() ),
115             mnFadeColor( rPage.getTransitionFadeColor() )
116     {
117         init();
118 
119         mfDuration = rPage.getTransitionDuration();
120         mnTime = rPage.GetTime();
121         mePresChange = rPage.GetPresChange();
122         mbSoundOn = rPage.IsSoundOn();
123         maSound = rPage.GetSoundFile();
124 		mbLoopSound = rPage.IsLoopSound();
125 		mbStopSound = rPage.IsStopSound();
126     }
127 
128     void init()
129     {
130         mfDuration = 2.0;
131         mnTime = 0;
132         mePresChange = PRESCHANGE_MANUAL;
133         mbSoundOn = sal_False;
134 		mbLoopSound = sal_False;
135 		mbStopSound = sal_False;
136 
137         mbEffectAmbiguous = false;
138         mbDurationAmbiguous = false;
139         mbTimeAmbiguous = false;
140         mbPresChangeAmbiguous = false;
141         mbSoundAmbiguous = false;
142         mbLoopSoundAmbiguous = false;
143     }
144 
145     void setAllAmbiguous()
146     {
147         mbEffectAmbiguous = true;
148         mbDurationAmbiguous = true;
149         mbTimeAmbiguous = true;
150         mbPresChangeAmbiguous = true;
151         mbSoundAmbiguous = true;
152 		mbLoopSoundAmbiguous = true;
153     }
154 
155     bool operator == ( const ::sd::TransitionPreset & rPreset ) const
156     {
157         return
158             (mnType == rPreset.getTransition()) &&
159             (mnSubType == rPreset.getSubtype()) &&
160             (mbDirection == rPreset.getDirection()) &&
161             (mnFadeColor ==  rPreset.getFadeColor());
162     }
163 
164     void applyTo( SdPage & rOutPage ) const
165     {
166         if( ! mbEffectAmbiguous )
167         {
168 			rOutPage.setTransitionType( mnType );
169 			rOutPage.setTransitionSubtype( mnSubType );
170             rOutPage.setTransitionDirection( mbDirection );
171             rOutPage.setTransitionFadeColor( mnFadeColor );
172         }
173 
174         if( ! mbDurationAmbiguous )
175             rOutPage.setTransitionDuration( mfDuration );
176         if( ! mbTimeAmbiguous )
177             rOutPage.SetTime( mnTime );
178         if( ! mbPresChangeAmbiguous )
179             rOutPage.SetPresChange( mePresChange );
180         if( ! mbSoundAmbiguous )
181 		{
182 			if( mbStopSound )
183 			{
184 				rOutPage.SetStopSound( sal_True );
185 	            rOutPage.SetSound( sal_False );
186 			}
187 			else
188 			{
189 				rOutPage.SetStopSound( sal_False );
190 	            rOutPage.SetSound( mbSoundOn );
191 		        rOutPage.SetSoundFile( maSound );
192 			}
193 		}
194 		if( ! mbLoopSoundAmbiguous )
195 			rOutPage.SetLoopSound( mbLoopSound );
196     }
197 
198     void compareWith( const SdPage & rPage )
199     {
200         TransitionEffect aOtherEffect( rPage );
201         mbEffectAmbiguous = mbEffectAmbiguous || aOtherEffect.mbEffectAmbiguous
202 											  || (mnType != aOtherEffect.mnType)
203 											  || (mnSubType != aOtherEffect.mnSubType)
204 											  || (mbDirection != aOtherEffect.mbDirection)
205 											  || (mnFadeColor != aOtherEffect.mnFadeColor);
206 
207         mbDurationAmbiguous = mbDurationAmbiguous || aOtherEffect.mbDurationAmbiguous || mfDuration != aOtherEffect.mfDuration;
208         mbTimeAmbiguous = mbTimeAmbiguous || aOtherEffect.mbTimeAmbiguous || mnTime != aOtherEffect.mnTime;
209         mbPresChangeAmbiguous = mbPresChangeAmbiguous || aOtherEffect.mbPresChangeAmbiguous || mePresChange != aOtherEffect.mePresChange;
210         mbSoundAmbiguous = mbSoundAmbiguous || aOtherEffect.mbSoundAmbiguous || mbSoundOn != aOtherEffect.mbSoundOn;
211 						(!mbStopSound && !aOtherEffect.mbStopSound && maSound != aOtherEffect.maSound) || (mbStopSound != aOtherEffect.mbStopSound);
212 		mbLoopSoundAmbiguous = mbLoopSoundAmbiguous || aOtherEffect.mbLoopSoundAmbiguous || mbLoopSound != aOtherEffect.mbLoopSound;
213     }
214 
215     // effect
216     sal_Int16 mnType;
217     sal_Int16 mnSubType;
218     sal_Bool  mbDirection;
219     sal_Int32 mnFadeColor;
220 
221     // other settings
222     double		mfDuration;
223     sal_uLong       mnTime;
224     PresChange  mePresChange;
225     sal_Bool        mbSoundOn;
226     String      maSound;
227 	bool		mbLoopSound;
228 	bool		mbStopSound;
229 
230     bool mbEffectAmbiguous;
231     bool mbDurationAmbiguous;
232     bool mbTimeAmbiguous;
233     bool mbPresChangeAmbiguous;
234     bool mbSoundAmbiguous;
235     bool mbLoopSoundAmbiguous;
236 };
237 
238 } // namespace impl
239 } // namespace sd
240 
241 // ______________________
242 //
243 // Local Helper Functions
244 // ______________________
245 
246 namespace
247 {
248 
249 void lcl_ApplyToPages(
250     const ::sd::slidesorter::SharedPageSelection& rpPages,
251     const ::sd::impl::TransitionEffect & rEffect )
252 {
253     ::std::vector< SdPage * >::const_iterator aIt( rpPages->begin());
254     const ::std::vector< SdPage * >::const_iterator aEndIt( rpPages->end());
255     for( ; aIt != aEndIt; ++aIt )
256     {
257         rEffect.applyTo( *(*aIt) );
258     }
259 }
260 
261 void lcl_CreateUndoForPages(
262     const ::sd::slidesorter::SharedPageSelection& rpPages,
263     ::sd::ViewShellBase& rBase )
264 {
265 	::sd::DrawDocShell* pDocSh	    = rBase.GetDocShell();
266 	::svl::IUndoManager* pManager   = pDocSh->GetUndoManager();
267 	SdDrawDocument*	pDoc		    = pDocSh->GetDoc();
268 	if( pManager && pDocSh && pDoc )
269 	{
270 		String aComment( SdResId(STR_UNDO_SLIDE_PARAMS) );
271 		pManager->EnterListAction(aComment, aComment);
272 		SdUndoGroup* pUndoGroup = new SdUndoGroup( pDoc );
273 		pUndoGroup->SetComment( aComment );
274 
275 		::std::vector< SdPage * >::const_iterator aIt( rpPages->begin());
276 		const ::std::vector< SdPage * >::const_iterator aEndIt( rpPages->end());
277 		for( ; aIt != aEndIt; ++aIt )
278 		{
279 			pUndoGroup->AddAction( new sd::UndoTransition( pDoc, (*aIt) ) );
280 		}
281 
282 		pManager->AddUndoAction( pUndoGroup );
283 		pManager->LeaveListAction();
284 	}
285 }
286 
287 sal_uInt16 lcl_getTransitionEffectIndex(
288     SdDrawDocument * pDoc,
289     const ::sd::impl::TransitionEffect & rTransition )
290 {
291     // first entry: "<none>"
292     sal_uInt16 nResultIndex = LISTBOX_ENTRY_NOTFOUND;
293 
294     if( pDoc )
295     {
296         sal_uInt16 nCurrentIndex = 0;
297 		const ::sd::TransitionPresetList & rPresetList = ::sd::TransitionPreset::getTransitionPresetList();
298         ::sd::TransitionPresetList::const_iterator aIt( rPresetList.begin());
299         const ::sd::TransitionPresetList::const_iterator aEndIt( rPresetList.end());
300         for( ; aIt != aEndIt; ++aIt, ++nCurrentIndex )
301         {
302             if( rTransition.operator==( *(*aIt) ))
303             {
304                 nResultIndex = nCurrentIndex;
305                 break;
306             }
307         }
308     }
309 
310     return nResultIndex;
311 }
312 
313 ::sd::TransitionPresetPtr lcl_getTransitionPresetByUIName(
314     SdDrawDocument * pDoc,
315     const OUString & rUIName )
316 {
317     ::sd::TransitionPresetPtr pResult;
318     if( pDoc )
319     {
320 		const ::sd::TransitionPresetList& rPresetList = ::sd::TransitionPreset::getTransitionPresetList();
321         ::sd::TransitionPresetList::const_iterator aIter( rPresetList.begin() );
322         const ::sd::TransitionPresetList::const_iterator aEnd( rPresetList.end() );
323         for( ; aIter != aEnd; ++aIter )
324         {
325             if( (*aIter)->getUIName().equals( rUIName ))
326             {
327                 pResult = *aIter;
328                 break;
329             }
330         }
331     }
332 
333     return pResult;
334 }
335 
336 struct lcl_EqualsSoundFileName : public ::std::unary_function< String, bool >
337 {
338     explicit lcl_EqualsSoundFileName( const String & rStr ) :
339             maStr( rStr )
340     {}
341 
342     bool operator() ( const String & rStr ) const
343     {
344         // note: formerly this was a case insensitive search for all
345         // platforms. It seems more sensible to do this platform-dependent
346 #if defined( WNT )
347         return maStr.EqualsIgnoreCaseAscii( rStr );
348 #else
349         return maStr.Equals( rStr );
350 #endif
351     }
352 
353 private:
354     String maStr;
355 };
356 
357 // returns -1 if no object was found
358 bool lcl_findSoundInList( const ::std::vector< String > & rSoundList,
359                           const String & rFileName,
360                           ::std::vector< String >::size_type & rOutPosition )
361 {
362     ::std::vector< String >::const_iterator aIt =
363           ::std::find_if( rSoundList.begin(), rSoundList.end(),
364                           lcl_EqualsSoundFileName( rFileName ));
365     if( aIt != rSoundList.end())
366     {
367         rOutPosition = ::std::distance( rSoundList.begin(), aIt );
368         return true;
369     }
370 
371     return false;
372 }
373 
374 String lcl_getSoundFileURL(
375     const ::std::vector< String > & rSoundList,
376     const ListBox & rListBox )
377 {
378     String aResult;
379 
380     if( rListBox.GetSelectEntryCount() > 0 )
381     {
382         sal_uInt16 nPos = rListBox.GetSelectEntryPos();
383         // the first three entries are no actual sounds
384         if( nPos >= 3 )
385         {
386             DBG_ASSERT( (sal_uInt32)(rListBox.GetEntryCount() - 3) == rSoundList.size(),
387                         "Sound list-box is not synchronized to sound list" );
388             nPos -= 3;
389             if( rSoundList.size() > nPos )
390                 aResult = rSoundList[ nPos ];
391         }
392     }
393 
394     return aResult;
395 }
396 
397 struct lcl_AppendSoundToListBox : public ::std::unary_function< String, void >
398 {
399     lcl_AppendSoundToListBox( ListBox & rListBox ) :
400             mrListBox( rListBox )
401     {}
402 
403     void operator() ( const String & rString ) const
404     {
405         INetURLObject aURL( rString );
406         mrListBox.InsertEntry( aURL.GetBase(), LISTBOX_APPEND );
407     }
408 
409 private:
410     ListBox & mrListBox;
411 };
412 
413 void lcl_FillSoundListBox(
414     const ::std::vector< String > & rSoundList,
415     ListBox & rOutListBox )
416 {
417     sal_uInt16 nCount = rOutListBox.GetEntryCount();
418 
419     // keep first three entries
420     for( sal_uInt16 i=nCount - 1; i>=3; --i )
421         rOutListBox.RemoveEntry( i );
422 
423     ::std::for_each( rSoundList.begin(), rSoundList.end(),
424                      lcl_AppendSoundToListBox( rOutListBox ));
425 }
426 
427 } // anonymous namespace
428 
429 namespace sd
430 {
431 
432 // ___________________
433 //
434 // SlideTransitionPane
435 // ___________________
436 
437 SlideTransitionPane::SlideTransitionPane(
438     ::Window * pParent,
439     ViewShellBase & rBase,
440     const Size& rMinSize,
441     SdDrawDocument* pDoc ) :
442         Control( pParent, SdResId( DLG_SLIDE_TRANSITION_PANE ) ),
443 
444         mrBase( rBase ),
445         mpDrawDoc( pDoc ),
446         maMinSize( rMinSize ),
447         maFL_APPLY_TRANSITION( this, SdResId( FL_APPLY_TRANSITION ) ),
448         maLB_SLIDE_TRANSITIONS( this, SdResId( LB_SLIDE_TRANSITIONS ) ),
449         maFL_MODIFY_TRANSITION( this, SdResId( FL_MODIFY_TRANSITION ) ),
450         maFT_SPEED( this, SdResId( FT_SPEED ) ),
451         maLB_SPEED( this, SdResId( LB_SPEED ) ),
452         maFT_SOUND( this, SdResId( FT_SOUND ) ),
453         maLB_SOUND( this, SdResId( LB_SOUND ) ),
454         maCB_LOOP_SOUND( this, SdResId( CB_LOOP_SOUND ) ),
455         maFL_ADVANCE_SLIDE( this, SdResId( FL_ADVANCE_SLIDE ) ),
456         maRB_ADVANCE_ON_MOUSE( this, SdResId( RB_ADVANCE_ON_MOUSE ) ),
457         maRB_ADVANCE_AUTO( this, SdResId( RB_ADVANCE_AUTO ) ),
458         maMF_ADVANCE_AUTO_AFTER( this, SdResId( MF_ADVANCE_AUTO_AFTER ) ),
459         maFL_EMPTY1( this, SdResId( FL_EMPTY1 ) ),
460         maPB_APPLY_TO_ALL( this, SdResId( PB_APPLY_TO_ALL ) ),
461         maPB_PLAY( this, SdResId( PB_PLAY ) ),
462         maPB_SLIDE_SHOW( this, SdResId( PB_SLIDE_SHOW ) ),
463         maFL_EMPTY2( this, SdResId( FL_EMPTY2 ) ),
464         maCB_AUTO_PREVIEW( this, SdResId( CB_AUTO_PREVIEW ) ),
465 
466         maSTR_NO_TRANSITION( SdResId( STR_NO_TRANSITION ) ),
467         mbHasSelection( false ),
468         mbUpdatingControls( false ),
469         mbIsMainViewChangePending( false ),
470         maLateInitTimer()
471 {
472     // use no resource ids from here on
473     FreeResource();
474 
475     // use bold font for group headings (same font for all fixed lines):
476     Font font( maFL_APPLY_TRANSITION.GetFont() );
477     font.SetWeight( WEIGHT_BOLD );
478     maFL_APPLY_TRANSITION.SetFont( font );
479     maFL_MODIFY_TRANSITION.SetFont( font );
480     maFL_ADVANCE_SLIDE.SetFont( font );
481 
482     if( pDoc )
483         mxModel.set( pDoc->getUnoModel(), uno::UNO_QUERY );
484     // TODO: get correct view
485     if( mxModel.is())
486         mxView.set( mxModel->getCurrentController(), uno::UNO_QUERY );
487 
488     // fill list box of slide transitions
489     maLB_SLIDE_TRANSITIONS.InsertEntry( maSTR_NO_TRANSITION );
490 
491     // set defaults
492     maCB_AUTO_PREVIEW.Check();      // automatic preview on
493 
494     // update control states before adding handlers
495     updateLayout();
496     //    updateSoundList();
497     updateControls();
498 
499     // set handlers
500     maPB_APPLY_TO_ALL.SetClickHdl( LINK( this, SlideTransitionPane, ApplyToAllButtonClicked ));
501     maPB_PLAY.SetClickHdl( LINK( this, SlideTransitionPane, PlayButtonClicked ));
502     maPB_SLIDE_SHOW.SetClickHdl( LINK( this, SlideTransitionPane, SlideShowButtonClicked ));
503 
504     maLB_SLIDE_TRANSITIONS.SetSelectHdl( LINK( this, SlideTransitionPane, TransitionSelected ));
505 
506     maLB_SPEED.SetSelectHdl( LINK( this, SlideTransitionPane, SpeedListBoxSelected ));
507     maLB_SOUND.SetSelectHdl( LINK( this, SlideTransitionPane, SoundListBoxSelected ));
508     maCB_LOOP_SOUND.SetClickHdl( LINK( this, SlideTransitionPane, LoopSoundBoxChecked ));
509 
510     maRB_ADVANCE_ON_MOUSE.SetToggleHdl( LINK( this, SlideTransitionPane, AdvanceSlideRadioButtonToggled ));
511     maRB_ADVANCE_AUTO.SetToggleHdl( LINK( this, SlideTransitionPane, AdvanceSlideRadioButtonToggled ));
512     maMF_ADVANCE_AUTO_AFTER.SetModifyHdl( LINK( this, SlideTransitionPane, AdvanceTimeModified ));
513 	maCB_AUTO_PREVIEW.SetClickHdl( LINK( this, SlideTransitionPane, AutoPreviewClicked ));
514     addListener();
515 
516     maLateInitTimer.SetTimeout(200);
517     maLateInitTimer.SetTimeoutHdl(LINK(this, SlideTransitionPane, LateInitCallback));
518     maLateInitTimer.Start();
519 
520     UpdateLook();
521 }
522 
523 SlideTransitionPane::~SlideTransitionPane()
524 {
525     maLateInitTimer.Stop();
526 	removeListener();
527 }
528 
529 void SlideTransitionPane::Resize()
530 {
531 	updateLayout();
532 }
533 
534 
535 
536 
537 void SlideTransitionPane::DataChanged (const DataChangedEvent& rEvent)
538 {
539     (void)rEvent;
540     UpdateLook();
541 }
542 
543 
544 
545 
546 void SlideTransitionPane::UpdateLook (void)
547 {
548     SetBackground(::sfx2::sidebar::Theme::GetWallpaper(::sfx2::sidebar::Theme::Paint_PanelBackground));
549     maFL_APPLY_TRANSITION.SetBackground(Wallpaper());
550     maFL_MODIFY_TRANSITION.SetBackground(Wallpaper());;
551     maFT_SPEED.SetBackground(Wallpaper());
552     maFT_SOUND.SetBackground(Wallpaper());
553     maFL_ADVANCE_SLIDE.SetBackground(Wallpaper());
554     maFL_EMPTY1.SetBackground(Wallpaper());
555     maFL_EMPTY2.SetBackground(Wallpaper());
556 }
557 
558 
559 
560 
561 void SlideTransitionPane::onSelectionChanged()
562 {
563     updateControls();
564 }
565 
566 void SlideTransitionPane::onChangeCurrentPage()
567 {
568     updateControls();
569 }
570 
571 ::sd::slidesorter::SharedPageSelection SlideTransitionPane::getSelectedPages (void) const
572 {
573     ::sd::slidesorter::SlideSorterViewShell * pSlideSorterViewShell
574         = ::sd::slidesorter::SlideSorterViewShell::GetSlideSorter(mrBase);
575 //    DBG_ASSERT( pSlideSorterViewShell, "No Slide-Sorter available" );
576     ::boost::shared_ptr<sd::slidesorter::SlideSorterViewShell::PageSelection> pSelection;
577 
578     if( pSlideSorterViewShell )
579     {
580         pSelection = pSlideSorterViewShell->GetPageSelection();
581     }
582 	else
583     {
584         pSelection.reset(new sd::slidesorter::SlideSorterViewShell::PageSelection());
585         if( mxView.is() )
586         {
587             SdPage* pPage = SdPage::getImplementation( mxView->getCurrentPage() );
588             if( pPage )
589                 pSelection->push_back(pPage);
590         }
591 	}
592 
593     return pSelection;
594 }
595 
596 void SlideTransitionPane::updateLayout()
597 {
598 	::Size aPaneSize( GetSizePixel() );
599 	if( aPaneSize.Width() < maMinSize.Width() )
600 		aPaneSize.Width() = maMinSize.Width();
601 
602 	if( aPaneSize.Height() < maMinSize.Height() )
603 		aPaneSize.Height() = maMinSize.Height();
604 
605     // start layouting elements from bottom to top.  The remaining space is used
606     // for the topmost list box
607 	::Point aOffset( LogicToPixel( Point( 3, 3 ), MAP_APPFONT ) );
608     long nOffsetX = aOffset.getX();
609     long nOffsetY = aOffset.getY();
610     long nOffsetBtnX = LogicToPixel( Point( 6, 1 ), MAP_APPFONT ).getX();
611 
612     const long nMinCtrlWidth = LogicToPixel( ::Point( 32, 1 ), MAP_APPFONT ).getX();
613     const long nTextIndent = LogicToPixel( ::Point( RSC_SP_CHK_TEXTINDENT, 1 ), MAP_APPFONT ).getX();
614 
615 	::Point aUpperLeft( nOffsetX, aPaneSize.getHeight() - nOffsetY );
616     long nMaxWidth = aPaneSize.getWidth() - 2 * nOffsetX;
617 
618     // auto preview check-box
619     ::Size aCtrlSize = maCB_AUTO_PREVIEW.GetSizePixel();
620     aCtrlSize.setWidth( maCB_AUTO_PREVIEW.CalcMinimumSize( nMaxWidth ).getWidth());
621     aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight());
622     maCB_AUTO_PREVIEW.SetPosSizePixel( aUpperLeft, aCtrlSize );
623 
624     // fixed line above check-box
625     aCtrlSize = maFL_EMPTY2.GetSizePixel();
626     aCtrlSize.setWidth( nMaxWidth );
627     aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight());
628     maFL_EMPTY2.SetPosSizePixel( aUpperLeft, aCtrlSize );
629 
630     // buttons "Play" and "Slide Show"
631     long nPlayButtonWidth = maPB_PLAY.CalcMinimumSize().getWidth() + 2 * nOffsetBtnX;
632     long nSlideShowButtonWidth = maPB_SLIDE_SHOW.CalcMinimumSize().getWidth() + 2 * nOffsetBtnX;
633 
634     if( (nPlayButtonWidth + nSlideShowButtonWidth + nOffsetX) <= nMaxWidth )
635     {
636         // place buttons side by side
637         aCtrlSize = maPB_PLAY.GetSizePixel();
638         aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight());
639         aCtrlSize.setWidth( nPlayButtonWidth );
640         maPB_PLAY.SetPosSizePixel( aUpperLeft, aCtrlSize );
641 
642         aUpperLeft.setX( aUpperLeft.getX() + nPlayButtonWidth + nOffsetX );
643         aCtrlSize.setWidth( nSlideShowButtonWidth );
644         maPB_SLIDE_SHOW.SetPosSizePixel( aUpperLeft, aCtrlSize );
645         aUpperLeft.setX( nOffsetX );
646     }
647     else
648     {
649         // place buttons on top of each other
650         aCtrlSize = maPB_SLIDE_SHOW.GetSizePixel();
651         aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight());
652         aCtrlSize.setWidth( nSlideShowButtonWidth );
653         maPB_SLIDE_SHOW.SetPosSizePixel( aUpperLeft, aCtrlSize );
654 
655         aCtrlSize = maPB_PLAY.GetSizePixel();
656         aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY );
657         aCtrlSize.setWidth( nPlayButtonWidth );
658         maPB_PLAY.SetPosSizePixel( aUpperLeft, aCtrlSize );
659     }
660 
661     // "Apply to All Slides" button
662     aCtrlSize = maPB_APPLY_TO_ALL.GetSizePixel();
663     aCtrlSize.setWidth( maPB_APPLY_TO_ALL.CalcMinimumSize( nMaxWidth ).getWidth() + 2 * nOffsetBtnX );
664     aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY );
665     maPB_APPLY_TO_ALL.SetPosSizePixel( aUpperLeft, aCtrlSize );
666 
667     // fixed line above "Apply to All Slides" button
668     aCtrlSize = maFL_EMPTY1.GetSizePixel();
669     aCtrlSize.setWidth( nMaxWidth );
670     aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight());
671     maFL_EMPTY1.SetPosSizePixel( aUpperLeft, aCtrlSize );
672 
673     // advance automatically after ... seconds
674     long nItemWidth = maRB_ADVANCE_AUTO.CalcMinimumSize().getWidth();
675 
676     if( (nItemWidth + nMinCtrlWidth + nOffsetX) <= nMaxWidth )
677     {
678         long nBase = aUpperLeft.getY();
679 
680         // place controls side by side
681         aCtrlSize = maRB_ADVANCE_AUTO.GetSizePixel();
682         aUpperLeft.setY( nBase - aCtrlSize.getHeight());
683         aCtrlSize.setWidth( nItemWidth );
684         maRB_ADVANCE_AUTO.SetPosSizePixel( aUpperLeft, aCtrlSize );
685 
686         aCtrlSize = maMF_ADVANCE_AUTO_AFTER.GetSizePixel();
687         aUpperLeft.setY( nBase - aCtrlSize.getHeight() );
688         aUpperLeft.setX( aUpperLeft.getX() + nItemWidth + nOffsetX );
689         aCtrlSize.setWidth( nMinCtrlWidth );
690         maMF_ADVANCE_AUTO_AFTER.SetPosSizePixel( aUpperLeft, aCtrlSize );
691         aUpperLeft.setX( nOffsetX );
692     }
693     else
694     {
695         // place controls on top of each other
696         aCtrlSize = maMF_ADVANCE_AUTO_AFTER.GetSizePixel();
697         aUpperLeft.setX( nOffsetX + nTextIndent );
698         aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight());
699         aCtrlSize.setWidth( nMinCtrlWidth );
700         maMF_ADVANCE_AUTO_AFTER.SetPosSizePixel( aUpperLeft, aCtrlSize );
701 
702         aCtrlSize = maRB_ADVANCE_AUTO.GetSizePixel();
703         aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY );
704         aUpperLeft.setX( nOffsetX );
705         aCtrlSize.setWidth( nItemWidth );
706         maRB_ADVANCE_AUTO.SetPosSizePixel( aUpperLeft, aCtrlSize );
707         aUpperLeft.setX( nOffsetX );
708     }
709 
710     // check box "On mouse click"
711     aCtrlSize = maRB_ADVANCE_ON_MOUSE.GetSizePixel();
712     aCtrlSize.setWidth( nMaxWidth );
713     aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY );
714     maRB_ADVANCE_ON_MOUSE.SetPosSizePixel( aUpperLeft, aCtrlSize );
715 
716     // fixed line "Advance slide"
717     aCtrlSize = maFL_ADVANCE_SLIDE.GetSizePixel();
718     aCtrlSize.setWidth( nMaxWidth );
719     aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY );
720     maFL_ADVANCE_SLIDE.SetPosSizePixel( aUpperLeft, aCtrlSize );
721 
722     // check box "Loop until next sound"
723     long nFTSpeedWidth = maFT_SPEED.CalcMinimumSize().getWidth() + 2 * nOffsetX;
724     long nFTSoundWidth = maFT_SOUND.CalcMinimumSize().getWidth() + 2 * nOffsetX;
725     long nIndent = ::std::max( nFTSoundWidth, nFTSpeedWidth );
726 
727     bool bStack = ( (nIndent + nMinCtrlWidth + nOffsetX) > nMaxWidth );
728 
729     if( bStack )
730         nIndent = nTextIndent;
731 
732     aCtrlSize = maCB_LOOP_SOUND.GetSizePixel();
733     aCtrlSize.setWidth( nMaxWidth - nIndent );
734     aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY );
735     aUpperLeft.setX( nIndent );
736     maCB_LOOP_SOUND.SetPosSizePixel( aUpperLeft, aCtrlSize );
737 
738     aCtrlSize = maLB_SOUND.GetSizePixel();
739     aCtrlSize.setWidth( ::std::max( nMaxWidth - nIndent, nMinCtrlWidth ) );
740     aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY );
741     maLB_SOUND.SetPosSizePixel( aUpperLeft, aCtrlSize );
742     maLB_SOUND.SetDropDownLineCount( 8 );
743     aUpperLeft.setX( nOffsetX );
744 
745     aCtrlSize = maFT_SOUND.GetSizePixel();
746     if( bStack )
747         aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight());
748     aCtrlSize.setWidth( nFTSoundWidth );
749     maFT_SOUND.SetPosSizePixel( aUpperLeft, aCtrlSize );
750 
751     aUpperLeft.setX( nIndent );
752     aCtrlSize = maLB_SPEED.GetSizePixel();
753     aCtrlSize.setWidth( ::std::max( nMaxWidth - nIndent, nMinCtrlWidth ) );
754     aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY );
755     maLB_SPEED.SetPosSizePixel( aUpperLeft, aCtrlSize );
756     maLB_SPEED.SetDropDownLineCount( 3 );
757     aUpperLeft.setX( nOffsetX );
758 
759     aCtrlSize = maFT_SPEED.GetSizePixel();
760     if( bStack )
761         aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight());
762     aCtrlSize.setWidth( nFTSpeedWidth );
763     maFT_SPEED.SetPosSizePixel( aUpperLeft, aCtrlSize );
764 
765     // fixed line "Modify Transition"
766     aCtrlSize = maFL_MODIFY_TRANSITION.GetSizePixel();
767     aCtrlSize.setWidth( nMaxWidth );
768     aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY );
769     maFL_MODIFY_TRANSITION.SetPosSizePixel( aUpperLeft, aCtrlSize );
770 
771     // fixed line "Apply to selected slides"
772     aCtrlSize = maFL_APPLY_TRANSITION.GetSizePixel();
773     aCtrlSize.setWidth( nMaxWidth );
774     ::Point aUpperLeftCorner( nOffsetX, nOffsetY );
775     maFL_APPLY_TRANSITION.SetPosSizePixel( aUpperLeftCorner, aCtrlSize );
776     aUpperLeftCorner.setY( aUpperLeftCorner.getY() + aCtrlSize.getHeight() + nOffsetY );
777     aUpperLeft.setY( aUpperLeft.getY() - nOffsetY );
778 
779     // list box slide transitions
780     aCtrlSize.setWidth( nMaxWidth );
781     aCtrlSize.setHeight( aUpperLeft.getY() - aUpperLeftCorner.getY() );
782     maLB_SLIDE_TRANSITIONS.SetPosSizePixel( aUpperLeftCorner, aCtrlSize );
783 }
784 
785 void SlideTransitionPane::updateControls()
786 {
787     ::sd::slidesorter::SharedPageSelection pSelectedPages(getSelectedPages());
788     if( pSelectedPages->empty())
789     {
790         mbHasSelection = false;
791         return;
792     }
793     mbHasSelection = true;
794 
795     DBG_ASSERT( ! mbUpdatingControls, "Multiple Control Updates" );
796     mbUpdatingControls = true;
797 
798     // get model data for first page
799     SdPage * pFirstPage = pSelectedPages->front();
800     DBG_ASSERT( pFirstPage, "Invalid Page" );
801 
802     impl::TransitionEffect aEffect( *pFirstPage );
803 
804     // merge with other pages
805     ::sd::slidesorter::SlideSorterViewShell::PageSelection::const_iterator aIt(
806         pSelectedPages->begin());
807     ::sd::slidesorter::SlideSorterViewShell::PageSelection::const_iterator aEndIt(
808         pSelectedPages->end());
809 
810     // start with second page (note aIt != aEndIt, because ! aSelectedPages.empty())
811     for( ++aIt ;aIt != aEndIt; ++aIt )
812     {
813         if( *aIt )
814             aEffect.compareWith( *(*aIt) );
815     }
816 
817     // detect current slide effect
818     if( aEffect.mbEffectAmbiguous )
819         maLB_SLIDE_TRANSITIONS.SetNoSelection();
820     else
821     {
822         // ToDo: That 0 is "no transition" is documented nowhere except in the
823         // CTOR of sdpage
824         if( aEffect.mnType == 0 )
825             maLB_SLIDE_TRANSITIONS.SelectEntryPos( 0 );
826         else
827         {
828             sal_uInt16 nEntry = lcl_getTransitionEffectIndex( mpDrawDoc, aEffect );
829             if( nEntry == LISTBOX_ENTRY_NOTFOUND )
830                 maLB_SLIDE_TRANSITIONS.SetNoSelection();
831             else
832             {
833                 // first entry in list is "none", so add 1 after translation
834                 if( m_aPresetIndexes.find( nEntry ) != m_aPresetIndexes.end())
835                     maLB_SLIDE_TRANSITIONS.SelectEntryPos( m_aPresetIndexes[ nEntry ] + 1 );
836                 else
837                     maLB_SLIDE_TRANSITIONS.SetNoSelection();
838             }
839         }
840     }
841 
842     if( aEffect.mbDurationAmbiguous )
843         maLB_SPEED.SetNoSelection();
844     else
845         maLB_SPEED.SelectEntryPos(
846             (aEffect.mfDuration > 2.0 )
847             ? 0 : (aEffect.mfDuration < 2.0)
848             ? 2 : 1 );       // else FADE_SPEED_FAST
849 
850     if( aEffect.mbSoundAmbiguous )
851     {
852         maLB_SOUND.SetNoSelection();
853         maCurrentSoundFile.Erase();
854     }
855     else
856     {
857 		maCurrentSoundFile.Erase();
858 		if( aEffect.mbStopSound )
859 		{
860 			maLB_SOUND.SelectEntryPos( 1 );
861 		}
862 		else if( aEffect.mbSoundOn && aEffect.maSound.Len() > 0 )
863         {
864             tSoundListType::size_type nPos = 0;
865             if( lcl_findSoundInList( maSoundList, aEffect.maSound, nPos ))
866             {
867                 // skip first three entries
868                 maLB_SOUND.SelectEntryPos( (sal_uInt16)nPos + 3 );
869                 maCurrentSoundFile = aEffect.maSound;
870             }
871         }
872         else
873         {
874             maLB_SOUND.SelectEntryPos( 0 );
875         }
876     }
877 
878 	if( aEffect.mbLoopSoundAmbiguous )
879 	{
880 		maCB_LOOP_SOUND.SetState( STATE_DONTKNOW );
881 	}
882 	else
883 	{
884 		maCB_LOOP_SOUND.Check( aEffect.mbLoopSound );
885 	}
886 
887     if( aEffect.mbPresChangeAmbiguous )
888     {
889         maRB_ADVANCE_ON_MOUSE.Check( sal_False );
890         maRB_ADVANCE_AUTO.Check( sal_False );
891     }
892     else
893     {
894         maRB_ADVANCE_ON_MOUSE.Check( aEffect.mePresChange == PRESCHANGE_MANUAL );
895         maRB_ADVANCE_AUTO.Check( aEffect.mePresChange == PRESCHANGE_AUTO );
896         maMF_ADVANCE_AUTO_AFTER.SetValue( aEffect.mnTime );
897     }
898 
899 	SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
900 	maCB_AUTO_PREVIEW.Check( pOptions->IsPreviewTransitions() == sal_True );
901 
902     mbUpdatingControls = false;
903 
904     updateControlState();
905 }
906 
907 void SlideTransitionPane::updateControlState()
908 {
909     maLB_SLIDE_TRANSITIONS.Enable( mbHasSelection );
910     maLB_SPEED.Enable( mbHasSelection );
911     maLB_SOUND.Enable( mbHasSelection );
912     maCB_LOOP_SOUND.Enable( mbHasSelection && (maLB_SOUND.GetSelectEntryPos() > 2));
913     maRB_ADVANCE_ON_MOUSE.Enable( mbHasSelection );
914     maRB_ADVANCE_AUTO.Enable( mbHasSelection );
915     maMF_ADVANCE_AUTO_AFTER.Enable( mbHasSelection && maRB_ADVANCE_AUTO.IsChecked());
916 
917     maPB_APPLY_TO_ALL.Enable( mbHasSelection );
918     maPB_PLAY.Enable( mbHasSelection );
919 //     maPB_SLIDE_SHOW.Enable( sal_True );
920     maCB_AUTO_PREVIEW.Enable( mbHasSelection );
921 }
922 
923 void SlideTransitionPane::updateSoundList()
924 {
925     List aSoundList;
926 
927     GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, aSoundList );
928     GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, aSoundList );
929 
930     sal_uInt32 nCount = aSoundList.Count();
931     maSoundList.clear();
932     maSoundList.reserve( nCount );
933     for( sal_uInt32 i=0; i<nCount; ++i )
934     {
935         String * pEntry = reinterpret_cast< String * >( aSoundList.GetObject( i ));
936         if( pEntry )
937         {
938             // store copy of string in member list
939             maSoundList.push_back( *pEntry );
940             // delete pointer in temporary List
941             delete pEntry;
942         }
943     }
944 
945     lcl_FillSoundListBox( maSoundList, maLB_SOUND );
946 }
947 
948 void SlideTransitionPane::openSoundFileDialog()
949 {
950     if( ! maLB_SOUND.IsEnabled())
951         return;
952 
953     SdOpenSoundFileDialog aFileDialog;
954 
955 	String aFile;
956     DBG_ASSERT( maLB_SOUND.GetSelectEntryPos() == 2,
957                 "Dialog should only open when \"Other sound\" is selected" );
958     aFile = SvtPathOptions().GetGraphicPath();
959 
960 	aFileDialog.SetPath( aFile );
961 
962 	bool bValidSoundFile( false );
963 	bool bQuitLoop( false );
964 
965 	while( ! bQuitLoop &&
966 		   aFileDialog.Execute() == ERRCODE_NONE )
967 	{
968 		aFile = aFileDialog.GetPath();
969         tSoundListType::size_type nPos = 0;
970         bValidSoundFile = lcl_findSoundInList( maSoundList, aFile, nPos );
971 
972         if( bValidSoundFile )
973 		{
974 			bQuitLoop = true;
975 		}
976 		else // not in sound list
977 		{
978 			// try to insert into gallery
979 			if( GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aFile, SGA_FORMAT_SOUND ) )
980 			{
981                 updateSoundList();
982                 bValidSoundFile = lcl_findSoundInList( maSoundList, aFile, nPos );
983 				DBG_ASSERT( bValidSoundFile, "Adding sound to gallery failed" );
984 
985 				bQuitLoop = true;
986 			}
987 			else
988 			{
989 				String aStrWarning(SdResId(STR_WARNING_NOSOUNDFILE));
990 				String aStr( sal_Unicode( '%' ));
991 				aStrWarning.SearchAndReplace( aStr , aFile );
992 				WarningBox aWarningBox( NULL, WB_3DLOOK | WB_RETRY_CANCEL, aStrWarning );
993 				aWarningBox.SetModalInputMode (sal_True);
994 				bQuitLoop = (aWarningBox.Execute() != RET_RETRY);
995 
996 				bValidSoundFile = false;
997 			}
998 		}
999 
1000 		if( bValidSoundFile )
1001             // skip first three entries in list
1002             maLB_SOUND.SelectEntryPos( (sal_uInt16)nPos + 3 );
1003 	}
1004 
1005     if( ! bValidSoundFile )
1006     {
1007         if( maCurrentSoundFile.Len() > 0 )
1008         {
1009             tSoundListType::size_type nPos = 0;
1010             if( lcl_findSoundInList( maSoundList, maCurrentSoundFile, nPos ))
1011                 maLB_SOUND.SelectEntryPos( (sal_uInt16)nPos + 3 );
1012 	        else
1013 		        maLB_SOUND.SelectEntryPos( 0 );  // NONE
1014         }
1015         else
1016             maLB_SOUND.SelectEntryPos( 0 );  // NONE
1017     }
1018 }
1019 
1020 impl::TransitionEffect SlideTransitionPane::getTransitionEffectFromControls() const
1021 {
1022     impl::TransitionEffect aResult;
1023     aResult.setAllAmbiguous();
1024 
1025     // check first (aResult might be overwritten)
1026     if( maLB_SLIDE_TRANSITIONS.IsEnabled() &&
1027         maLB_SLIDE_TRANSITIONS.GetSelectEntryCount() > 0 )
1028     {
1029         TransitionPresetPtr pPreset = lcl_getTransitionPresetByUIName(
1030             mpDrawDoc, OUString( maLB_SLIDE_TRANSITIONS.GetSelectEntry()));
1031 
1032         if( pPreset.get())
1033         {
1034             aResult = impl::TransitionEffect( *pPreset );
1035 		    aResult.setAllAmbiguous();
1036         }
1037         else
1038         {
1039             aResult.mnType = 0;
1040         }
1041         aResult.mbEffectAmbiguous = false;
1042     }
1043 
1044     // speed
1045     if( maLB_SPEED.IsEnabled() &&
1046         maLB_SPEED.GetSelectEntryCount() > 0 )
1047     {
1048         sal_uInt16 nPos = maLB_SPEED.GetSelectEntryPos();
1049         aResult.mfDuration = (nPos == 0)
1050             ? 3.0
1051             : (nPos == 1)
1052             ? 2.0
1053             : 1.0;   // nPos == 2
1054         DBG_ASSERT( aResult.mfDuration != 1.0 || nPos == 2, "Invalid Listbox Entry" );
1055 
1056         aResult.mbDurationAmbiguous = false;
1057     }
1058 
1059     // slide-advance mode
1060     if( maRB_ADVANCE_ON_MOUSE.IsEnabled() && maRB_ADVANCE_AUTO.IsEnabled() &&
1061         (maRB_ADVANCE_ON_MOUSE.IsChecked() || maRB_ADVANCE_AUTO.IsChecked()))
1062     {
1063         if( maRB_ADVANCE_ON_MOUSE.IsChecked())
1064             aResult.mePresChange = PRESCHANGE_MANUAL;
1065         else
1066         {
1067             aResult.mePresChange = PRESCHANGE_AUTO;
1068             if( maMF_ADVANCE_AUTO_AFTER.IsEnabled())
1069             {
1070 //                 sal_uInt16 nDigits = maMF_ADVANCE_AUTO_AFTER.GetDecimalDigits();
1071                 aResult.mnTime = static_cast<long>(maMF_ADVANCE_AUTO_AFTER.GetValue());
1072                 // / static_cast< sal_uInt16 >( pow( 10.0, static_cast< double >( nDigits )));
1073                 aResult.mbTimeAmbiguous = false;
1074             }
1075         }
1076 
1077         aResult.mbPresChangeAmbiguous = false;
1078     }
1079 
1080     // sound
1081     if( maLB_SOUND.IsEnabled())
1082     {
1083 		maCurrentSoundFile.Erase();
1084 		if( maLB_SOUND.GetSelectEntryCount() > 0 )
1085         {
1086 			sal_uInt16 nPos = maLB_SOUND.GetSelectEntryPos();
1087 			aResult.mbStopSound = nPos == 1;
1088 			aResult.mbSoundOn = nPos > 1;
1089 			if( aResult.mbStopSound )
1090 			{
1091 				aResult.maSound = OUString();
1092 				aResult.mbSoundAmbiguous = false;
1093 			}
1094 			else
1095 			{
1096 				aResult.maSound = lcl_getSoundFileURL( maSoundList, maLB_SOUND );
1097 				aResult.mbSoundAmbiguous = false;
1098 				maCurrentSoundFile = aResult.maSound;
1099 			}
1100         }
1101     }
1102 
1103 	// sound loop
1104 	if( maCB_LOOP_SOUND.IsEnabled() )
1105 	{
1106 		aResult.mbLoopSound = maCB_LOOP_SOUND.IsChecked();
1107 		aResult.mbLoopSoundAmbiguous = false;
1108 	}
1109 
1110     return aResult;
1111 }
1112 
1113 void SlideTransitionPane::applyToSelectedPages()
1114 {
1115     if( ! mbUpdatingControls )
1116     {
1117         ::sd::slidesorter::SharedPageSelection pSelectedPages( getSelectedPages());
1118         if( ! pSelectedPages->empty())
1119         {
1120 			lcl_CreateUndoForPages( pSelectedPages, mrBase );
1121             lcl_ApplyToPages( pSelectedPages, getTransitionEffectFromControls() );
1122 			mrBase.GetDocShell()->SetModified();
1123         }
1124         if( maCB_AUTO_PREVIEW.IsEnabled() &&
1125             maCB_AUTO_PREVIEW.IsChecked())
1126         {
1127             playCurrentEffect();
1128         }
1129     }
1130 }
1131 
1132 void SlideTransitionPane::playCurrentEffect()
1133 {
1134 	if( mxView.is() )
1135 	{
1136 
1137 		Reference< ::com::sun::star::animations::XAnimationNode > xNode;
1138 		SlideShow::StartPreview( mrBase, mxView->getCurrentPage(), xNode );
1139 	}
1140 }
1141 
1142 void SlideTransitionPane::addListener()
1143 {
1144 	Link aLink( LINK(this,SlideTransitionPane,EventMultiplexerListener) );
1145     mrBase.GetEventMultiplexer()->AddEventListener (
1146         aLink,
1147         tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
1148         | tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION
1149         | tools::EventMultiplexerEvent::EID_CURRENT_PAGE
1150         | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
1151         | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
1152         | tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED);
1153 }
1154 
1155 void SlideTransitionPane::removeListener()
1156 {
1157 	Link aLink( LINK(this,SlideTransitionPane,EventMultiplexerListener) );
1158     mrBase.GetEventMultiplexer()->RemoveEventListener( aLink );
1159 }
1160 
1161 IMPL_LINK(SlideTransitionPane,EventMultiplexerListener,
1162     tools::EventMultiplexerEvent*,pEvent)
1163 {
1164     switch (pEvent->meEventId)
1165     {
1166         case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION:
1167             onSelectionChanged();
1168             break;
1169 
1170         case tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
1171         case tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION:
1172             onChangeCurrentPage();
1173             break;
1174 
1175         case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
1176             mxView = Reference<drawing::XDrawView>();
1177             onSelectionChanged();
1178             onChangeCurrentPage();
1179             break;
1180 
1181         case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
1182             mbIsMainViewChangePending = true;
1183             break;
1184 
1185         case tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
1186             if (mbIsMainViewChangePending)
1187             {
1188                 mbIsMainViewChangePending = false;
1189 
1190                 // At this moment the controller may not yet been set at
1191                 // model or ViewShellBase.  Take it from the view shell
1192                 // passed with the event.
1193                 if (mrBase.GetMainViewShell() != NULL)
1194                 {
1195                     mxView = Reference<drawing::XDrawView>::query(mrBase.GetController());
1196                     onSelectionChanged();
1197                     onChangeCurrentPage();
1198                 }
1199             }
1200             break;
1201 
1202         default:
1203             break;
1204     }
1205     return 0;
1206 }
1207 
1208 IMPL_LINK( SlideTransitionPane, ApplyToAllButtonClicked, void *, EMPTYARG )
1209 {
1210     DBG_ASSERT( mpDrawDoc, "Invalid Draw Document!" );
1211     if( !mpDrawDoc )
1212         return 0;
1213 
1214     ::sd::slidesorter::SharedPageSelection pPages (
1215         new ::sd::slidesorter::SlideSorterViewShell::PageSelection());
1216 
1217     sal_uInt16 nPageCount = mpDrawDoc->GetSdPageCount( PK_STANDARD );
1218     pPages->reserve( nPageCount );
1219     for( sal_uInt16 i=0; i<nPageCount; ++i )
1220     {
1221         SdPage * pPage = mpDrawDoc->GetSdPage( i, PK_STANDARD );
1222         if( pPage )
1223             pPages->push_back( pPage );
1224     }
1225 
1226     if( ! pPages->empty())
1227 	{
1228 		lcl_CreateUndoForPages( pPages, mrBase );
1229         lcl_ApplyToPages( pPages, getTransitionEffectFromControls() );
1230 	}
1231 
1232     return 0;
1233 }
1234 
1235 
1236 IMPL_LINK( SlideTransitionPane, PlayButtonClicked, void *, EMPTYARG )
1237 {
1238     playCurrentEffect();
1239     return 0;
1240 }
1241 
1242 IMPL_LINK( SlideTransitionPane, SlideShowButtonClicked, void *, EMPTYARG )
1243 {
1244 	mrBase.StartPresentation();
1245     return 0;
1246 }
1247 
1248 IMPL_LINK( SlideTransitionPane, TransitionSelected, void *, EMPTYARG )
1249 {
1250     applyToSelectedPages();
1251     return 0;
1252 }
1253 
1254 IMPL_LINK( SlideTransitionPane, AdvanceSlideRadioButtonToggled, void *, EMPTYARG )
1255 {
1256     updateControlState();
1257     applyToSelectedPages();
1258     return 0;
1259 }
1260 
1261 IMPL_LINK( SlideTransitionPane, AdvanceTimeModified, void *, EMPTYARG )
1262 {
1263     applyToSelectedPages();
1264     return 0;
1265 }
1266 
1267 IMPL_LINK( SlideTransitionPane, SpeedListBoxSelected, void *, EMPTYARG )
1268 {
1269     applyToSelectedPages();
1270     return 0;
1271 }
1272 
1273 IMPL_LINK( SlideTransitionPane, SoundListBoxSelected, void *, EMPTYARG )
1274 {
1275     if( maLB_SOUND.GetSelectEntryCount() )
1276     {
1277         sal_uInt16 nPos = maLB_SOUND.GetSelectEntryPos();
1278         if( nPos == 2 )
1279         {
1280             // other sound ...
1281             openSoundFileDialog();
1282         }
1283     }
1284     updateControlState();
1285     applyToSelectedPages();
1286     return 0;
1287 }
1288 
1289 IMPL_LINK( SlideTransitionPane, LoopSoundBoxChecked, void *, EMPTYARG )
1290 {
1291     applyToSelectedPages();
1292     return 0;
1293 }
1294 
1295 IMPL_LINK( SlideTransitionPane, AutoPreviewClicked, void *, EMPTYARG )
1296 {
1297 	SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
1298 	pOptions->SetPreviewTransitions( maCB_AUTO_PREVIEW.IsChecked() ? sal_True : sal_False );
1299     return 0;
1300 }
1301 
1302 IMPL_LINK( SlideTransitionPane, LateInitCallback, Timer*, EMPTYARG )
1303 {
1304 	const TransitionPresetList& rPresetList = TransitionPreset::getTransitionPresetList();
1305 	TransitionPresetList::const_iterator aIter( rPresetList.begin() );
1306 	const TransitionPresetList::const_iterator aEnd( rPresetList.end() );
1307     sal_uInt16 nIndex = 0;
1308     ::std::size_t nUIIndex = 0;
1309 	while( aIter != aEnd )
1310 	{
1311 		TransitionPresetPtr pPreset = (*aIter++);
1312 		const OUString aUIName( pPreset->getUIName() );
1313  		if( aUIName.getLength() )
1314         {
1315             maLB_SLIDE_TRANSITIONS.InsertEntry( aUIName );
1316             m_aPresetIndexes[ nIndex ] = (sal_uInt16)nUIIndex;
1317             ++nUIIndex;
1318         }
1319         ++nIndex;
1320 	}
1321 
1322     updateSoundList();
1323     updateControls();
1324 
1325     return 0;
1326 }
1327 
1328 ::Window * createSlideTransitionPanel( ::Window* pParent, ViewShellBase& rBase )
1329 {
1330 	DialogListBox* pWindow = 0;
1331 
1332 	DrawDocShell* pDocSh = rBase.GetDocShell();
1333     if( pDocSh )
1334     {
1335         pWindow = new DialogListBox( pParent, WB_CLIPCHILDREN|WB_TABSTOP|WB_AUTOHSCROLL );
1336 
1337 		Size aMinSize( pWindow->LogicToPixel( Size( 72, 216 ), MAP_APPFONT ) );
1338 		::Window* pPaneWindow = new SlideTransitionPane( pWindow, rBase, aMinSize, pDocSh->GetDoc() );
1339 		pWindow->SetChildWindow( pPaneWindow, aMinSize );
1340 		pWindow->SetText( pPaneWindow->GetText() );
1341     }
1342 
1343 	return pWindow;
1344 }
1345 
1346 
1347 
1348 
1349 sal_Int32 getSlideTransitionPanelMinimumHeight (::Window* pDialog)
1350 {
1351     if (pDialog != NULL)
1352 		return pDialog->LogicToPixel(Size( 72, 216 ), MAP_APPFONT).Height();
1353     else
1354         return 0;
1355 }
1356 
1357 
1358 } //  namespace sd
1359