Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/animations/XAnimationNode.hpp>
21 :
22 : #include "SlideTransitionPane.hxx"
23 : #include "CustomAnimation.hrc"
24 :
25 : #include "TransitionPreset.hxx"
26 : #include "sdresid.hxx"
27 : #include "ViewShellBase.hxx"
28 : #include "DrawDocShell.hxx"
29 : #include "SlideSorterViewShell.hxx"
30 : #include "drawdoc.hxx"
31 : #include "filedlg.hxx"
32 : #include "strings.hrc"
33 : #include "DrawController.hxx"
34 : #include <com/sun/star/beans/XPropertySet.hpp>
35 :
36 : #include <svtools/controldims.hrc>
37 : #include <svx/gallery.hxx>
38 : #include <unotools/pathoptions.hxx>
39 : #include <vcl/msgbox.hxx>
40 : #include <tools/urlobj.hxx>
41 : #include "DrawViewShell.hxx"
42 : #include "slideshow.hxx"
43 : #include "drawview.hxx"
44 : #include "sdundogr.hxx"
45 : #include "undoanim.hxx"
46 : #include "optsitem.hxx"
47 : #include "sddll.hxx"
48 : #include "framework/FrameworkHelper.hxx"
49 :
50 : #include <sfx2/sidebar/Theme.hxx>
51 :
52 : #include <algorithm>
53 :
54 :
55 : using namespace ::com::sun::star;
56 :
57 : using ::com::sun::star::uno::Reference;
58 : using ::com::sun::star::uno::Sequence;
59 : using ::com::sun::star::uno::RuntimeException;
60 :
61 : using ::sd::framework::FrameworkHelper;
62 :
63 :
64 :
65 : // ::sd::impl::TransitionEffect
66 : namespace sd
67 : {
68 : namespace impl
69 : {
70 0 : struct TransitionEffect
71 : {
72 0 : TransitionEffect() :
73 : mnType( 0 ),
74 : mnSubType( 0 ),
75 : mbDirection( sal_True ),
76 0 : mnFadeColor( 0 )
77 : {
78 0 : init();
79 0 : }
80 0 : explicit TransitionEffect( const ::sd::TransitionPreset & rPreset ) :
81 0 : mnType( rPreset.getTransition()),
82 0 : mnSubType( rPreset.getSubtype()),
83 0 : mbDirection( rPreset.getDirection()),
84 0 : mnFadeColor( rPreset.getFadeColor())
85 : {
86 0 : init();
87 0 : }
88 : explicit TransitionEffect( sal_Int16 nType, sal_Int16 nSubType,
89 : sal_Bool bDirection, sal_Int32 nFadeColor ) :
90 : mnType( nType),
91 : mnSubType( nSubType ),
92 : mbDirection( bDirection ),
93 : mnFadeColor( nFadeColor )
94 : {
95 : init();
96 : }
97 0 : explicit TransitionEffect( const SdPage & rPage ) :
98 0 : mnType( rPage.getTransitionType() ),
99 0 : mnSubType( rPage.getTransitionSubtype() ),
100 0 : mbDirection( rPage.getTransitionDirection() ),
101 0 : mnFadeColor( rPage.getTransitionFadeColor() )
102 : {
103 0 : init();
104 :
105 0 : mfDuration = rPage.getTransitionDuration();
106 0 : mfTime = rPage.GetTime();
107 0 : mePresChange = rPage.GetPresChange();
108 0 : mbSoundOn = rPage.IsSoundOn();
109 0 : maSound = rPage.GetSoundFile();
110 0 : mbLoopSound = rPage.IsLoopSound();
111 0 : mbStopSound = rPage.IsStopSound();
112 0 : }
113 :
114 0 : void init()
115 : {
116 0 : mfDuration = 2.0;
117 0 : mfTime = 0.0;
118 0 : mePresChange = PRESCHANGE_MANUAL;
119 0 : mbSoundOn = sal_False;
120 0 : mbLoopSound = false;
121 0 : mbStopSound = false;
122 :
123 0 : mbEffectAmbiguous = false;
124 0 : mbDurationAmbiguous = false;
125 0 : mbTimeAmbiguous = false;
126 0 : mbPresChangeAmbiguous = false;
127 0 : mbSoundAmbiguous = false;
128 0 : mbLoopSoundAmbiguous = false;
129 0 : }
130 :
131 0 : void setAllAmbiguous()
132 : {
133 0 : mbEffectAmbiguous = true;
134 0 : mbDurationAmbiguous = true;
135 0 : mbTimeAmbiguous = true;
136 0 : mbPresChangeAmbiguous = true;
137 0 : mbSoundAmbiguous = true;
138 0 : mbLoopSoundAmbiguous = true;
139 0 : }
140 :
141 0 : bool operator == ( const ::sd::TransitionPreset & rPreset ) const
142 : {
143 : return
144 0 : (mnType == rPreset.getTransition()) &&
145 0 : (mnSubType == rPreset.getSubtype()) &&
146 0 : (mbDirection == rPreset.getDirection()) &&
147 0 : (mnFadeColor == rPreset.getFadeColor());
148 : }
149 :
150 0 : void applyTo( SdPage & rOutPage ) const
151 : {
152 0 : if( ! mbEffectAmbiguous )
153 : {
154 0 : rOutPage.setTransitionType( mnType );
155 0 : rOutPage.setTransitionSubtype( mnSubType );
156 0 : rOutPage.setTransitionDirection( mbDirection );
157 0 : rOutPage.setTransitionFadeColor( mnFadeColor );
158 : }
159 :
160 0 : if( ! mbDurationAmbiguous )
161 0 : rOutPage.setTransitionDuration( mfDuration );
162 0 : if( ! mbTimeAmbiguous )
163 0 : rOutPage.SetTime( mfTime );
164 0 : if( ! mbPresChangeAmbiguous )
165 0 : rOutPage.SetPresChange( mePresChange );
166 0 : if( ! mbSoundAmbiguous )
167 : {
168 0 : if( mbStopSound )
169 : {
170 0 : rOutPage.SetStopSound( true );
171 0 : rOutPage.SetSound( sal_False );
172 : }
173 : else
174 : {
175 0 : rOutPage.SetStopSound( false );
176 0 : rOutPage.SetSound( mbSoundOn );
177 0 : rOutPage.SetSoundFile( maSound );
178 : }
179 : }
180 0 : if( ! mbLoopSoundAmbiguous )
181 0 : rOutPage.SetLoopSound( mbLoopSound );
182 0 : }
183 :
184 0 : void compareWith( const SdPage & rPage )
185 : {
186 0 : TransitionEffect aOtherEffect( rPage );
187 0 : mbEffectAmbiguous = mbEffectAmbiguous || aOtherEffect.mbEffectAmbiguous
188 0 : || (mnType != aOtherEffect.mnType)
189 0 : || (mnSubType != aOtherEffect.mnSubType)
190 0 : || (mbDirection != aOtherEffect.mbDirection)
191 0 : || (mnFadeColor != aOtherEffect.mnFadeColor);
192 :
193 0 : mbDurationAmbiguous = mbDurationAmbiguous || aOtherEffect.mbDurationAmbiguous || mfDuration != aOtherEffect.mfDuration;
194 0 : mbTimeAmbiguous = mbTimeAmbiguous || aOtherEffect.mbTimeAmbiguous || mfTime != aOtherEffect.mfTime;
195 0 : mbPresChangeAmbiguous = mbPresChangeAmbiguous || aOtherEffect.mbPresChangeAmbiguous || mePresChange != aOtherEffect.mePresChange;
196 0 : mbSoundAmbiguous = mbSoundAmbiguous || aOtherEffect.mbSoundAmbiguous || mbSoundOn != aOtherEffect.mbSoundOn;
197 : #if 0
198 : // Weird leftover isolated expression with no effect, introduced in 2007 in
199 : // CWS impress122. Ifdeffed out to avoid compiler warning, kept here in case
200 : // somebody who understands this code notices and understands what the
201 : // "right" thing to do might be.
202 : (!mbStopSound && !aOtherEffect.mbStopSound && maSound != aOtherEffect.maSound) || (mbStopSound != aOtherEffect.mbStopSound);
203 : #endif
204 0 : mbLoopSoundAmbiguous = mbLoopSoundAmbiguous || aOtherEffect.mbLoopSoundAmbiguous || mbLoopSound != aOtherEffect.mbLoopSound;
205 0 : }
206 :
207 : // effect
208 : sal_Int16 mnType;
209 : sal_Int16 mnSubType;
210 : sal_Bool mbDirection;
211 : sal_Int32 mnFadeColor;
212 :
213 : // other settings
214 : double mfDuration;
215 : double mfTime;
216 : PresChange mePresChange;
217 : sal_Bool mbSoundOn;
218 : OUString maSound;
219 : bool mbLoopSound;
220 : bool mbStopSound;
221 :
222 : bool mbEffectAmbiguous;
223 : bool mbDurationAmbiguous;
224 : bool mbTimeAmbiguous;
225 : bool mbPresChangeAmbiguous;
226 : bool mbSoundAmbiguous;
227 : bool mbLoopSoundAmbiguous;
228 : };
229 :
230 : } // namespace impl
231 : } // namespace sd
232 :
233 :
234 :
235 : // Local Helper Functions
236 : namespace
237 : {
238 :
239 0 : void lcl_ApplyToPages(
240 : const ::sd::slidesorter::SharedPageSelection& rpPages,
241 : const ::sd::impl::TransitionEffect & rEffect )
242 : {
243 0 : ::std::vector< SdPage * >::const_iterator aIt( rpPages->begin());
244 0 : const ::std::vector< SdPage * >::const_iterator aEndIt( rpPages->end());
245 0 : for( ; aIt != aEndIt; ++aIt )
246 : {
247 0 : rEffect.applyTo( *(*aIt) );
248 : }
249 0 : }
250 :
251 0 : void lcl_CreateUndoForPages(
252 : const ::sd::slidesorter::SharedPageSelection& rpPages,
253 : ::sd::ViewShellBase& rBase )
254 : {
255 0 : ::sd::DrawDocShell* pDocSh = rBase.GetDocShell();
256 0 : if (!pDocSh)
257 0 : return;
258 0 : ::svl::IUndoManager* pManager = pDocSh->GetUndoManager();
259 0 : if (!pManager)
260 0 : return;
261 0 : SdDrawDocument* pDoc = pDocSh->GetDoc();
262 0 : if (!pDoc)
263 0 : return;
264 :
265 0 : OUString aComment( SdResId(STR_UNDO_SLIDE_PARAMS) );
266 0 : pManager->EnterListAction(aComment, aComment);
267 0 : SdUndoGroup* pUndoGroup = new SdUndoGroup( pDoc );
268 0 : pUndoGroup->SetComment( aComment );
269 :
270 0 : ::std::vector< SdPage * >::const_iterator aIt( rpPages->begin());
271 0 : const ::std::vector< SdPage * >::const_iterator aEndIt( rpPages->end());
272 0 : for( ; aIt != aEndIt; ++aIt )
273 : {
274 0 : pUndoGroup->AddAction( new sd::UndoTransition( pDoc, (*aIt) ) );
275 : }
276 :
277 0 : pManager->AddUndoAction( pUndoGroup );
278 0 : pManager->LeaveListAction();
279 : }
280 :
281 0 : sal_Int32 lcl_getTransitionEffectIndex(
282 : SdDrawDocument * pDoc,
283 : const ::sd::impl::TransitionEffect & rTransition )
284 : {
285 : // first entry: "<none>"
286 0 : sal_Int32 nResultIndex = LISTBOX_ENTRY_NOTFOUND;
287 :
288 0 : if( pDoc )
289 : {
290 0 : sal_Int32 nCurrentIndex = 0;
291 0 : const ::sd::TransitionPresetList & rPresetList = ::sd::TransitionPreset::getTransitionPresetList();
292 0 : ::sd::TransitionPresetList::const_iterator aIt( rPresetList.begin());
293 0 : const ::sd::TransitionPresetList::const_iterator aEndIt( rPresetList.end());
294 0 : for( ; aIt != aEndIt; ++aIt, ++nCurrentIndex )
295 : {
296 0 : if( rTransition.operator==( *(*aIt) ))
297 : {
298 0 : nResultIndex = nCurrentIndex;
299 0 : break;
300 : }
301 : }
302 : }
303 :
304 0 : return nResultIndex;
305 : }
306 :
307 0 : ::sd::TransitionPresetPtr lcl_getTransitionPresetByUIName(
308 : SdDrawDocument * pDoc,
309 : const OUString & rUIName )
310 : {
311 0 : ::sd::TransitionPresetPtr pResult;
312 0 : if( pDoc )
313 : {
314 0 : const ::sd::TransitionPresetList& rPresetList = ::sd::TransitionPreset::getTransitionPresetList();
315 0 : ::sd::TransitionPresetList::const_iterator aIter( rPresetList.begin() );
316 0 : const ::sd::TransitionPresetList::const_iterator aEnd( rPresetList.end() );
317 0 : for( ; aIter != aEnd; ++aIter )
318 : {
319 0 : if( (*aIter)->getUIName().equals( rUIName ))
320 : {
321 0 : pResult = *aIter;
322 0 : break;
323 : }
324 : }
325 : }
326 :
327 0 : return pResult;
328 : }
329 :
330 0 : struct lcl_EqualsSoundFileName : public ::std::unary_function< OUString, bool >
331 : {
332 0 : explicit lcl_EqualsSoundFileName( const OUString & rStr ) :
333 0 : maStr( rStr )
334 0 : {}
335 :
336 0 : bool operator() ( const OUString & rStr ) const
337 : {
338 : // note: formerly this was a case insensitive search for all
339 : // platforms. It seems more sensible to do this platform-dependent
340 : #if defined( WNT )
341 : return maStr.equalsIgnoreAsciiCase( rStr );
342 : #else
343 0 : return maStr == rStr;
344 : #endif
345 : }
346 :
347 : private:
348 : OUString maStr;
349 : };
350 :
351 : // returns -1 if no object was found
352 0 : bool lcl_findSoundInList( const ::std::vector< OUString > & rSoundList,
353 : const OUString & rFileName,
354 : ::std::vector< OUString >::size_type & rOutPosition )
355 : {
356 : ::std::vector< OUString >::const_iterator aIt =
357 : ::std::find_if( rSoundList.begin(), rSoundList.end(),
358 0 : lcl_EqualsSoundFileName( rFileName ));
359 0 : if( aIt != rSoundList.end())
360 : {
361 0 : rOutPosition = ::std::distance( rSoundList.begin(), aIt );
362 0 : return true;
363 : }
364 :
365 0 : return false;
366 : }
367 :
368 0 : OUString lcl_getSoundFileURL(
369 : const ::std::vector< OUString > & rSoundList,
370 : const ListBox* rListBox )
371 : {
372 0 : if( rListBox->GetSelectEntryCount() > 0 )
373 : {
374 0 : sal_Int32 nPos = rListBox->GetSelectEntryPos();
375 : // the first three entries are no actual sounds
376 0 : if( nPos >= 3 )
377 : {
378 : DBG_ASSERT( (sal_uInt32)(rListBox->GetEntryCount() - 3) == rSoundList.size(),
379 : "Sound list-box is not synchronized to sound list" );
380 0 : nPos -= 3;
381 0 : if( rSoundList.size() > static_cast<size_t>(nPos) )
382 0 : return rSoundList[ nPos ];
383 : }
384 : }
385 :
386 0 : return OUString();
387 : }
388 :
389 : struct lcl_AppendSoundToListBox : public ::std::unary_function< OUString, void >
390 : {
391 0 : lcl_AppendSoundToListBox( ListBox* rListBox ) :
392 0 : mrListBox( rListBox )
393 0 : {}
394 :
395 0 : void operator() ( const OUString & rString ) const
396 : {
397 0 : INetURLObject aURL( rString );
398 0 : mrListBox->InsertEntry( aURL.GetBase(), LISTBOX_APPEND );
399 0 : }
400 :
401 : private:
402 : ListBox* mrListBox;
403 : };
404 :
405 0 : void lcl_FillSoundListBox(
406 : const ::std::vector< OUString > & rSoundList,
407 : ListBox* rOutListBox )
408 : {
409 0 : sal_Int32 nCount = rOutListBox->GetEntryCount();
410 :
411 : // keep first three entries
412 0 : for( sal_Int32 i=nCount - 1; i>=3; --i )
413 0 : rOutListBox->RemoveEntry( i );
414 :
415 : ::std::for_each( rSoundList.begin(), rSoundList.end(),
416 0 : lcl_AppendSoundToListBox( rOutListBox ));
417 0 : }
418 :
419 : } // anonymous namespace
420 :
421 : namespace sd
422 : {
423 :
424 :
425 :
426 : // SlideTransitionPane
427 0 : SlideTransitionPane::SlideTransitionPane(
428 : ::Window * pParent,
429 : ViewShellBase & rBase,
430 : const Size& rMinSize,
431 : SdDrawDocument* pDoc,
432 : const cssu::Reference<css::frame::XFrame>& rxFrame ) :
433 : PanelLayout( pParent, "SlideTransitionsPanel", "modules/simpress/ui/slidetransitionspanel.ui", rxFrame ),
434 :
435 : mrBase( rBase ),
436 : mpDrawDoc( pDoc ),
437 : maMinSize( rMinSize ),
438 : mbHasSelection( false ),
439 : mbUpdatingControls( false ),
440 : mbIsMainViewChangePending( false ),
441 0 : maLateInitTimer()
442 : {
443 0 : get(mpLB_SLIDE_TRANSITIONS, "transitions_list");
444 0 : get(mpFT_SPEED, "speed_label");
445 0 : get(mpLB_SPEED, "speed_list");
446 0 : get(mpFT_SOUND, "sound_label");
447 0 : get(mpLB_SOUND, "sound_list");
448 0 : get(mpCB_LOOP_SOUND, "loop_sound" );
449 0 : get(mpRB_ADVANCE_ON_MOUSE, "rb_mouse_click");
450 0 : get(mpRB_ADVANCE_AUTO, "rb_auto_after");
451 0 : get(mpMF_ADVANCE_AUTO_AFTER, "auto_after_value");
452 0 : get(mpPB_APPLY_TO_ALL, "apply_to_all");
453 0 : get(mpPB_PLAY, "play");
454 0 : get(mpPB_SLIDE_SHOW, "slide_show");
455 0 : get(mpCB_AUTO_PREVIEW, "auto_preview");
456 :
457 0 : mpLB_SLIDE_TRANSITIONS->set_width_request(mpLB_SLIDE_TRANSITIONS->approximate_char_width() * 16);
458 0 : mpLB_SLIDE_TRANSITIONS->SetDropDownLineCount(4);
459 :
460 0 : if( pDoc )
461 0 : mxModel.set( pDoc->getUnoModel(), uno::UNO_QUERY );
462 : // TODO: get correct view
463 0 : if( mxModel.is())
464 0 : mxView.set( mxModel->getCurrentController(), uno::UNO_QUERY );
465 :
466 : // fill list box of slide transitions
467 0 : mpLB_SLIDE_TRANSITIONS->InsertEntry( SD_RESSTR( STR_SLIDETRANSITION_NONE ) );
468 :
469 : // set defaults
470 0 : mpCB_AUTO_PREVIEW->Check(); // automatic preview on
471 :
472 : // update control states before adding handlers
473 0 : updateControls();
474 :
475 : // set handlers
476 0 : mpPB_APPLY_TO_ALL->SetClickHdl( LINK( this, SlideTransitionPane, ApplyToAllButtonClicked ));
477 0 : mpPB_PLAY->SetClickHdl( LINK( this, SlideTransitionPane, PlayButtonClicked ));
478 0 : mpPB_SLIDE_SHOW->SetClickHdl( LINK( this, SlideTransitionPane, SlideShowButtonClicked ));
479 :
480 0 : mpLB_SLIDE_TRANSITIONS->SetSelectHdl( LINK( this, SlideTransitionPane, TransitionSelected ));
481 :
482 0 : mpLB_SPEED->SetSelectHdl( LINK( this, SlideTransitionPane, SpeedListBoxSelected ));
483 0 : mpLB_SOUND->SetSelectHdl( LINK( this, SlideTransitionPane, SoundListBoxSelected ));
484 0 : mpCB_LOOP_SOUND->SetClickHdl( LINK( this, SlideTransitionPane, LoopSoundBoxChecked ));
485 :
486 0 : mpRB_ADVANCE_ON_MOUSE->SetToggleHdl( LINK( this, SlideTransitionPane, AdvanceSlideRadioButtonToggled ));
487 0 : mpRB_ADVANCE_AUTO->SetToggleHdl( LINK( this, SlideTransitionPane, AdvanceSlideRadioButtonToggled ));
488 0 : mpMF_ADVANCE_AUTO_AFTER->SetModifyHdl( LINK( this, SlideTransitionPane, AdvanceTimeModified ));
489 0 : mpCB_AUTO_PREVIEW->SetClickHdl( LINK( this, SlideTransitionPane, AutoPreviewClicked ));
490 0 : addListener();
491 :
492 0 : maLateInitTimer.SetTimeout(200);
493 0 : maLateInitTimer.SetTimeoutHdl(LINK(this, SlideTransitionPane, LateInitCallback));
494 0 : maLateInitTimer.Start();
495 :
496 0 : UpdateLook();
497 0 : }
498 :
499 0 : SlideTransitionPane::~SlideTransitionPane()
500 : {
501 0 : maLateInitTimer.Stop();
502 0 : removeListener();
503 0 : }
504 :
505 :
506 0 : void SlideTransitionPane::DataChanged (const DataChangedEvent& rEvent)
507 : {
508 : (void)rEvent;
509 0 : UpdateLook();
510 0 : }
511 :
512 :
513 :
514 :
515 0 : void SlideTransitionPane::UpdateLook (void)
516 : {
517 0 : SetBackground(::sfx2::sidebar::Theme::GetWallpaper(::sfx2::sidebar::Theme::Paint_PanelBackground));
518 0 : mpFT_SPEED->SetBackground(Wallpaper());
519 0 : mpFT_SOUND->SetBackground(Wallpaper());
520 0 : }
521 :
522 :
523 0 : void SlideTransitionPane::onSelectionChanged()
524 : {
525 0 : updateControls();
526 0 : }
527 :
528 0 : void SlideTransitionPane::onChangeCurrentPage()
529 : {
530 0 : updateControls();
531 0 : }
532 :
533 0 : ::sd::slidesorter::SharedPageSelection SlideTransitionPane::getSelectedPages (void) const
534 : {
535 : ::sd::slidesorter::SlideSorterViewShell * pSlideSorterViewShell
536 0 : = ::sd::slidesorter::SlideSorterViewShell::GetSlideSorter(mrBase);
537 0 : ::boost::shared_ptr<sd::slidesorter::SlideSorterViewShell::PageSelection> pSelection;
538 :
539 0 : if( pSlideSorterViewShell )
540 : {
541 0 : pSelection = pSlideSorterViewShell->GetPageSelection();
542 : }
543 : else
544 : {
545 0 : pSelection.reset(new sd::slidesorter::SlideSorterViewShell::PageSelection());
546 0 : if( mxView.is() )
547 : {
548 0 : SdPage* pPage = SdPage::getImplementation( mxView->getCurrentPage() );
549 0 : if( pPage )
550 0 : pSelection->push_back(pPage);
551 : }
552 : }
553 :
554 0 : return pSelection;
555 : }
556 :
557 0 : void SlideTransitionPane::updateControls()
558 : {
559 0 : ::sd::slidesorter::SharedPageSelection pSelectedPages(getSelectedPages());
560 0 : if( pSelectedPages->empty())
561 : {
562 0 : mbHasSelection = false;
563 0 : return;
564 : }
565 0 : mbHasSelection = true;
566 :
567 : DBG_ASSERT( ! mbUpdatingControls, "Multiple Control Updates" );
568 0 : mbUpdatingControls = true;
569 :
570 : // get model data for first page
571 0 : SdPage * pFirstPage = pSelectedPages->front();
572 : DBG_ASSERT( pFirstPage, "Invalid Page" );
573 :
574 0 : impl::TransitionEffect aEffect( *pFirstPage );
575 :
576 : // merge with other pages
577 : ::sd::slidesorter::SlideSorterViewShell::PageSelection::const_iterator aIt(
578 0 : pSelectedPages->begin());
579 : ::sd::slidesorter::SlideSorterViewShell::PageSelection::const_iterator aEndIt(
580 0 : pSelectedPages->end());
581 :
582 : // start with second page (note aIt != aEndIt, because ! aSelectedPages.empty())
583 0 : for( ++aIt ;aIt != aEndIt; ++aIt )
584 : {
585 0 : if( *aIt )
586 0 : aEffect.compareWith( *(*aIt) );
587 : }
588 :
589 : // detect current slide effect
590 0 : if( aEffect.mbEffectAmbiguous )
591 0 : mpLB_SLIDE_TRANSITIONS->SetNoSelection();
592 : else
593 : {
594 : // ToDo: That 0 is "no transition" is documented nowhere except in the
595 : // CTOR of sdpage
596 0 : if( aEffect.mnType == 0 )
597 0 : mpLB_SLIDE_TRANSITIONS->SelectEntryPos( 0 );
598 : else
599 : {
600 0 : sal_Int32 nEntry = lcl_getTransitionEffectIndex( mpDrawDoc, aEffect );
601 0 : if( nEntry == LISTBOX_ENTRY_NOTFOUND )
602 0 : mpLB_SLIDE_TRANSITIONS->SetNoSelection();
603 : else
604 : {
605 : // first entry in list is "none", so add 1 after translation
606 0 : if( m_aPresetIndexes.find( nEntry ) != m_aPresetIndexes.end())
607 0 : mpLB_SLIDE_TRANSITIONS->SelectEntryPos( m_aPresetIndexes[ nEntry ] + 1 );
608 : else
609 0 : mpLB_SLIDE_TRANSITIONS->SetNoSelection();
610 : }
611 : }
612 : }
613 :
614 0 : if( aEffect.mbDurationAmbiguous )
615 0 : mpLB_SPEED->SetNoSelection();
616 : else
617 : mpLB_SPEED->SelectEntryPos(
618 0 : (aEffect.mfDuration > 2.0 )
619 0 : ? 0 : (aEffect.mfDuration < 2.0)
620 0 : ? 2 : 1 ); // else FADE_SPEED_FAST
621 :
622 0 : if( aEffect.mbSoundAmbiguous )
623 : {
624 0 : mpLB_SOUND->SetNoSelection();
625 0 : maCurrentSoundFile = "";
626 : }
627 : else
628 : {
629 0 : maCurrentSoundFile = "";
630 0 : if( aEffect.mbStopSound )
631 : {
632 0 : mpLB_SOUND->SelectEntryPos( 1 );
633 : }
634 0 : else if( aEffect.mbSoundOn && !aEffect.maSound.isEmpty() )
635 : {
636 0 : tSoundListType::size_type nPos = 0;
637 0 : if( lcl_findSoundInList( maSoundList, aEffect.maSound, nPos ))
638 : {
639 : // skip first three entries
640 0 : mpLB_SOUND->SelectEntryPos( nPos + 3 );
641 0 : maCurrentSoundFile = aEffect.maSound;
642 : }
643 : }
644 : else
645 : {
646 0 : mpLB_SOUND->SelectEntryPos( 0 );
647 : }
648 : }
649 :
650 0 : if( aEffect.mbLoopSoundAmbiguous )
651 : {
652 0 : mpCB_LOOP_SOUND->SetState( TRISTATE_INDET );
653 : }
654 : else
655 : {
656 0 : mpCB_LOOP_SOUND->Check( aEffect.mbLoopSound );
657 : }
658 :
659 0 : if( aEffect.mbPresChangeAmbiguous )
660 : {
661 0 : mpRB_ADVANCE_ON_MOUSE->Check( false );
662 0 : mpRB_ADVANCE_AUTO->Check( false );
663 : }
664 : else
665 : {
666 0 : mpRB_ADVANCE_ON_MOUSE->Check( aEffect.mePresChange == PRESCHANGE_MANUAL );
667 0 : mpRB_ADVANCE_AUTO->Check( aEffect.mePresChange == PRESCHANGE_AUTO );
668 0 : mpMF_ADVANCE_AUTO_AFTER->SetValue( aEffect.mfTime * 100.0);
669 : }
670 :
671 0 : SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
672 0 : mpCB_AUTO_PREVIEW->Check( pOptions->IsPreviewTransitions() == sal_True );
673 :
674 0 : mbUpdatingControls = false;
675 :
676 0 : updateControlState();
677 : }
678 :
679 0 : void SlideTransitionPane::updateControlState()
680 : {
681 0 : mpLB_SLIDE_TRANSITIONS->Enable( mbHasSelection );
682 0 : mpLB_SPEED->Enable( mbHasSelection );
683 0 : mpLB_SOUND->Enable( mbHasSelection );
684 0 : mpCB_LOOP_SOUND->Enable( mbHasSelection && (mpLB_SOUND->GetSelectEntryPos() > 2));
685 0 : mpRB_ADVANCE_ON_MOUSE->Enable( mbHasSelection );
686 0 : mpRB_ADVANCE_AUTO->Enable( mbHasSelection );
687 0 : mpMF_ADVANCE_AUTO_AFTER->Enable( mbHasSelection && mpRB_ADVANCE_AUTO->IsChecked());
688 :
689 0 : mpPB_APPLY_TO_ALL->Enable( mbHasSelection );
690 0 : mpPB_PLAY->Enable( mbHasSelection );
691 0 : mpCB_AUTO_PREVIEW->Enable( mbHasSelection );
692 0 : }
693 :
694 0 : void SlideTransitionPane::updateSoundList()
695 : {
696 0 : maSoundList.clear();
697 :
698 0 : GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, maSoundList );
699 0 : GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, maSoundList );
700 :
701 0 : lcl_FillSoundListBox( maSoundList, mpLB_SOUND );
702 0 : }
703 :
704 0 : void SlideTransitionPane::openSoundFileDialog()
705 : {
706 0 : if( ! mpLB_SOUND->IsEnabled())
707 0 : return;
708 :
709 0 : SdOpenSoundFileDialog aFileDialog;
710 :
711 0 : OUString aFile;
712 : DBG_ASSERT( mpLB_SOUND->GetSelectEntryPos() == 2,
713 : "Dialog should only open when \"Other sound\" is selected" );
714 0 : aFile = SvtPathOptions().GetGraphicPath();
715 :
716 0 : aFileDialog.SetPath( aFile );
717 :
718 0 : bool bValidSoundFile( false );
719 0 : bool bQuitLoop( false );
720 :
721 0 : while( ! bQuitLoop &&
722 0 : aFileDialog.Execute() == ERRCODE_NONE )
723 : {
724 0 : aFile = aFileDialog.GetPath();
725 0 : tSoundListType::size_type nPos = 0;
726 0 : bValidSoundFile = lcl_findSoundInList( maSoundList, aFile, nPos );
727 :
728 0 : if( bValidSoundFile )
729 : {
730 0 : bQuitLoop = true;
731 : }
732 : else // not in sound list
733 : {
734 : // try to insert into gallery
735 0 : if( GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aFile ) )
736 : {
737 0 : updateSoundList();
738 0 : bValidSoundFile = lcl_findSoundInList( maSoundList, aFile, nPos );
739 : DBG_ASSERT( bValidSoundFile, "Adding sound to gallery failed" );
740 :
741 0 : bQuitLoop = true;
742 : }
743 : else
744 : {
745 0 : OUString aStrWarning(SD_RESSTR(STR_WARNING_NOSOUNDFILE));
746 0 : aStrWarning = aStrWarning.replaceFirst("%", aFile);
747 0 : WarningBox aWarningBox( NULL, WB_3DLOOK | WB_RETRY_CANCEL, aStrWarning );
748 0 : aWarningBox.SetModalInputMode (true);
749 0 : bQuitLoop = (aWarningBox.Execute() != RET_RETRY);
750 :
751 0 : bValidSoundFile = false;
752 : }
753 : }
754 :
755 0 : if( bValidSoundFile )
756 : // skip first three entries in list
757 0 : mpLB_SOUND->SelectEntryPos( nPos + 3 );
758 : }
759 :
760 0 : if( ! bValidSoundFile )
761 : {
762 0 : if( !maCurrentSoundFile.isEmpty() )
763 : {
764 0 : tSoundListType::size_type nPos = 0;
765 0 : if( lcl_findSoundInList( maSoundList, maCurrentSoundFile, nPos ))
766 0 : mpLB_SOUND->SelectEntryPos( nPos + 3 );
767 : else
768 0 : mpLB_SOUND->SelectEntryPos( 0 ); // NONE
769 : }
770 : else
771 0 : mpLB_SOUND->SelectEntryPos( 0 ); // NONE
772 0 : }
773 : }
774 :
775 0 : impl::TransitionEffect SlideTransitionPane::getTransitionEffectFromControls() const
776 : {
777 0 : impl::TransitionEffect aResult;
778 0 : aResult.setAllAmbiguous();
779 :
780 : // check first (aResult might be overwritten)
781 0 : if( mpLB_SLIDE_TRANSITIONS->IsEnabled() &&
782 0 : mpLB_SLIDE_TRANSITIONS->GetSelectEntryCount() > 0 )
783 : {
784 : TransitionPresetPtr pPreset = lcl_getTransitionPresetByUIName(
785 0 : mpDrawDoc, OUString( mpLB_SLIDE_TRANSITIONS->GetSelectEntry()));
786 :
787 0 : if( pPreset.get())
788 : {
789 0 : aResult = impl::TransitionEffect( *pPreset );
790 0 : aResult.setAllAmbiguous();
791 : }
792 : else
793 : {
794 0 : aResult.mnType = 0;
795 : }
796 0 : aResult.mbEffectAmbiguous = false;
797 : }
798 :
799 : // speed
800 0 : if( mpLB_SPEED->IsEnabled() &&
801 0 : mpLB_SPEED->GetSelectEntryCount() > 0 )
802 : {
803 0 : sal_Int32 nPos = mpLB_SPEED->GetSelectEntryPos();
804 : aResult.mfDuration = (nPos == 0)
805 : ? 3.0
806 : : (nPos == 1)
807 : ? 2.0
808 0 : : 1.0; // nPos == 2
809 : DBG_ASSERT( aResult.mfDuration != 1.0 || nPos == 2, "Invalid Listbox Entry" );
810 :
811 0 : aResult.mbDurationAmbiguous = false;
812 : }
813 :
814 : // slide-advance mode
815 0 : if( mpRB_ADVANCE_ON_MOUSE->IsEnabled() && mpRB_ADVANCE_AUTO->IsEnabled() &&
816 0 : (mpRB_ADVANCE_ON_MOUSE->IsChecked() || mpRB_ADVANCE_AUTO->IsChecked()))
817 : {
818 0 : if( mpRB_ADVANCE_ON_MOUSE->IsChecked())
819 0 : aResult.mePresChange = PRESCHANGE_MANUAL;
820 : else
821 : {
822 0 : aResult.mePresChange = PRESCHANGE_AUTO;
823 0 : if( mpMF_ADVANCE_AUTO_AFTER->IsEnabled())
824 : {
825 0 : aResult.mfTime = static_cast<double>(mpMF_ADVANCE_AUTO_AFTER->GetValue() ) / 100.0 ;
826 0 : aResult.mbTimeAmbiguous = false;
827 : }
828 : }
829 :
830 0 : aResult.mbPresChangeAmbiguous = false;
831 : }
832 :
833 : // sound
834 0 : if( mpLB_SOUND->IsEnabled())
835 : {
836 0 : maCurrentSoundFile = "";
837 0 : if( mpLB_SOUND->GetSelectEntryCount() > 0 )
838 : {
839 0 : sal_Int32 nPos = mpLB_SOUND->GetSelectEntryPos();
840 0 : aResult.mbStopSound = nPos == 1;
841 0 : aResult.mbSoundOn = nPos > 1;
842 0 : if( aResult.mbStopSound )
843 : {
844 0 : aResult.maSound = OUString();
845 0 : aResult.mbSoundAmbiguous = false;
846 : }
847 : else
848 : {
849 0 : aResult.maSound = lcl_getSoundFileURL( maSoundList, mpLB_SOUND );
850 0 : aResult.mbSoundAmbiguous = false;
851 0 : maCurrentSoundFile = aResult.maSound;
852 : }
853 : }
854 : }
855 :
856 : // sound loop
857 0 : if( mpCB_LOOP_SOUND->IsEnabled() )
858 : {
859 0 : aResult.mbLoopSound = mpCB_LOOP_SOUND->IsChecked();
860 0 : aResult.mbLoopSoundAmbiguous = false;
861 : }
862 :
863 0 : return aResult;
864 : }
865 :
866 0 : void SlideTransitionPane::applyToSelectedPages()
867 : {
868 0 : if( ! mbUpdatingControls )
869 : {
870 0 : ::sd::slidesorter::SharedPageSelection pSelectedPages( getSelectedPages());
871 0 : impl::TransitionEffect aEffect = getTransitionEffectFromControls();
872 0 : if( ! pSelectedPages->empty())
873 : {
874 0 : lcl_CreateUndoForPages( pSelectedPages, mrBase );
875 0 : lcl_ApplyToPages( pSelectedPages, aEffect );
876 0 : mrBase.GetDocShell()->SetModified();
877 : }
878 0 : if( mpCB_AUTO_PREVIEW->IsEnabled() &&
879 0 : mpCB_AUTO_PREVIEW->IsChecked())
880 : {
881 0 : if (aEffect.mnType) // mnType = 0 denotes no transition
882 0 : playCurrentEffect();
883 : else
884 0 : stopEffects();
885 0 : }
886 : }
887 0 : }
888 :
889 0 : void SlideTransitionPane::playCurrentEffect()
890 : {
891 0 : if( mxView.is() )
892 : {
893 :
894 0 : Reference< ::com::sun::star::animations::XAnimationNode > xNode;
895 0 : SlideShow::StartPreview( mrBase, mxView->getCurrentPage(), xNode );
896 : }
897 0 : }
898 :
899 0 : void SlideTransitionPane::stopEffects()
900 : {
901 0 : if( mxView.is() )
902 : {
903 0 : SlideShow::Stop( mrBase );
904 : }
905 0 : }
906 :
907 0 : void SlideTransitionPane::addListener()
908 : {
909 0 : Link aLink( LINK(this,SlideTransitionPane,EventMultiplexerListener) );
910 : mrBase.GetEventMultiplexer()->AddEventListener (
911 : aLink,
912 : tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
913 : | tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION
914 : | tools::EventMultiplexerEvent::EID_CURRENT_PAGE
915 : | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
916 : | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
917 0 : | tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED);
918 0 : }
919 :
920 0 : void SlideTransitionPane::removeListener()
921 : {
922 0 : Link aLink( LINK(this,SlideTransitionPane,EventMultiplexerListener) );
923 0 : mrBase.GetEventMultiplexer()->RemoveEventListener( aLink );
924 0 : }
925 :
926 0 : IMPL_LINK(SlideTransitionPane,EventMultiplexerListener,
927 : tools::EventMultiplexerEvent*,pEvent)
928 : {
929 0 : switch (pEvent->meEventId)
930 : {
931 : case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION:
932 0 : onSelectionChanged();
933 0 : break;
934 :
935 : case tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
936 : case tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION:
937 0 : onChangeCurrentPage();
938 0 : break;
939 :
940 : case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
941 0 : mxView = Reference<drawing::XDrawView>();
942 0 : onSelectionChanged();
943 0 : onChangeCurrentPage();
944 0 : break;
945 :
946 : case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
947 0 : mbIsMainViewChangePending = true;
948 0 : break;
949 :
950 : case tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
951 0 : if (mbIsMainViewChangePending)
952 : {
953 0 : mbIsMainViewChangePending = false;
954 :
955 : // At this moment the controller may not yet been set at
956 : // model or ViewShellBase. Take it from the view shell
957 : // passed with the event.
958 0 : if (mrBase.GetMainViewShell() != 0)
959 : {
960 0 : mxView = Reference<drawing::XDrawView>::query(mrBase.GetController());
961 0 : onSelectionChanged();
962 0 : onChangeCurrentPage();
963 : }
964 : }
965 0 : break;
966 :
967 : default:
968 0 : break;
969 : }
970 0 : return 0;
971 : }
972 :
973 0 : IMPL_LINK_NOARG(SlideTransitionPane, ApplyToAllButtonClicked)
974 : {
975 : DBG_ASSERT( mpDrawDoc, "Invalid Draw Document!" );
976 0 : if( !mpDrawDoc )
977 0 : return 0;
978 :
979 : ::sd::slidesorter::SharedPageSelection pPages (
980 0 : new ::sd::slidesorter::SlideSorterViewShell::PageSelection());
981 :
982 0 : sal_uInt16 nPageCount = mpDrawDoc->GetSdPageCount( PK_STANDARD );
983 0 : pPages->reserve( nPageCount );
984 0 : for( sal_uInt16 i=0; i<nPageCount; ++i )
985 : {
986 0 : SdPage * pPage = mpDrawDoc->GetSdPage( i, PK_STANDARD );
987 0 : if( pPage )
988 0 : pPages->push_back( pPage );
989 : }
990 :
991 0 : if( ! pPages->empty())
992 : {
993 0 : lcl_CreateUndoForPages( pPages, mrBase );
994 0 : lcl_ApplyToPages( pPages, getTransitionEffectFromControls() );
995 : }
996 :
997 0 : return 0;
998 : }
999 :
1000 :
1001 0 : IMPL_LINK_NOARG(SlideTransitionPane, PlayButtonClicked)
1002 : {
1003 0 : playCurrentEffect();
1004 0 : return 0;
1005 : }
1006 :
1007 0 : IMPL_LINK_NOARG(SlideTransitionPane, SlideShowButtonClicked)
1008 : {
1009 0 : mrBase.StartPresentation();
1010 0 : return 0;
1011 : }
1012 :
1013 0 : IMPL_LINK_NOARG(SlideTransitionPane, TransitionSelected)
1014 : {
1015 0 : applyToSelectedPages();
1016 0 : return 0;
1017 : }
1018 :
1019 0 : IMPL_LINK_NOARG(SlideTransitionPane, AdvanceSlideRadioButtonToggled)
1020 : {
1021 0 : updateControlState();
1022 0 : applyToSelectedPages();
1023 0 : return 0;
1024 : }
1025 :
1026 0 : IMPL_LINK_NOARG(SlideTransitionPane, AdvanceTimeModified)
1027 : {
1028 0 : applyToSelectedPages();
1029 0 : return 0;
1030 : }
1031 :
1032 0 : IMPL_LINK_NOARG(SlideTransitionPane, SpeedListBoxSelected)
1033 : {
1034 0 : applyToSelectedPages();
1035 0 : return 0;
1036 : }
1037 :
1038 0 : IMPL_LINK_NOARG(SlideTransitionPane, SoundListBoxSelected)
1039 : {
1040 0 : if( mpLB_SOUND->GetSelectEntryCount() )
1041 : {
1042 0 : sal_Int32 nPos = mpLB_SOUND->GetSelectEntryPos();
1043 0 : if( nPos == 2 )
1044 : {
1045 : // other sound...
1046 0 : openSoundFileDialog();
1047 : }
1048 : }
1049 0 : updateControlState();
1050 0 : applyToSelectedPages();
1051 0 : return 0;
1052 : }
1053 :
1054 0 : IMPL_LINK_NOARG(SlideTransitionPane, LoopSoundBoxChecked)
1055 : {
1056 0 : applyToSelectedPages();
1057 0 : return 0;
1058 : }
1059 :
1060 0 : IMPL_LINK_NOARG(SlideTransitionPane, AutoPreviewClicked)
1061 : {
1062 0 : SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
1063 0 : pOptions->SetPreviewTransitions( mpCB_AUTO_PREVIEW->IsChecked() ? sal_True : sal_False );
1064 0 : return 0;
1065 : }
1066 :
1067 0 : IMPL_LINK_NOARG(SlideTransitionPane, LateInitCallback)
1068 : {
1069 0 : const TransitionPresetList& rPresetList = TransitionPreset::getTransitionPresetList();
1070 0 : TransitionPresetList::const_iterator aIter( rPresetList.begin() );
1071 0 : const TransitionPresetList::const_iterator aEnd( rPresetList.end() );
1072 0 : sal_uInt16 nIndex = 0;
1073 0 : ::std::size_t nUIIndex = 0;
1074 0 : while( aIter != aEnd )
1075 : {
1076 0 : TransitionPresetPtr pPreset = (*aIter++);
1077 0 : const OUString aUIName( pPreset->getUIName() );
1078 0 : if( !aUIName.isEmpty() )
1079 : {
1080 0 : mpLB_SLIDE_TRANSITIONS->InsertEntry( aUIName );
1081 0 : m_aPresetIndexes[ nIndex ] = (sal_uInt16)nUIIndex;
1082 0 : ++nUIIndex;
1083 : }
1084 0 : ++nIndex;
1085 0 : }
1086 :
1087 0 : updateSoundList();
1088 0 : updateControls();
1089 :
1090 0 : return 0;
1091 : }
1092 :
1093 0 : ::Window * createSlideTransitionPanel( ::Window* pParent, ViewShellBase& rBase, const cssu::Reference<css::frame::XFrame>& rxFrame )
1094 : {
1095 0 : ::Window* pWindow = 0;
1096 :
1097 0 : DrawDocShell* pDocSh = rBase.GetDocShell();
1098 0 : if( pDocSh )
1099 : {
1100 0 : Size aMinSize( pParent->LogicToPixel( Size( 72, 216 ), MAP_APPFONT ) );
1101 0 : pWindow = new SlideTransitionPane( pParent, rBase, aMinSize, pDocSh->GetDoc(), rxFrame );
1102 : }
1103 :
1104 0 : return pWindow;
1105 : }
1106 :
1107 0 : } // namespace sd
1108 :
1109 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|