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