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