/src/libreoffice/sd/source/ui/animations/SlideTransitionPane.cxx
Line | Count | Source (jump to first uncovered line) |
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/drawing/XDrawView.hpp> |
21 | | #include <SlideTransitionPane.hxx> |
22 | | |
23 | | #include <TransitionPreset.hxx> |
24 | | #include <sdresid.hxx> |
25 | | #include <ViewShellBase.hxx> |
26 | | #include <DrawDocShell.hxx> |
27 | | #include <SlideSorterViewShell.hxx> |
28 | | #include <unomodel.hxx> |
29 | | #include <drawdoc.hxx> |
30 | | #include <sdmod.hxx> |
31 | | #include <sdpage.hxx> |
32 | | #include <filedlg.hxx> |
33 | | #include <strings.hrc> |
34 | | #include <EventMultiplexer.hxx> |
35 | | |
36 | | #include <comphelper/lok.hxx> |
37 | | #include <sal/log.hxx> |
38 | | #include <tools/debug.hxx> |
39 | | #include <svx/gallery.hxx> |
40 | | #include <utility> |
41 | | #include <vcl/stdtext.hxx> |
42 | | #include <vcl/svapp.hxx> |
43 | | #include <vcl/weld.hxx> |
44 | | #include <tools/urlobj.hxx> |
45 | | #include <slideshow.hxx> |
46 | | #include <sdundogr.hxx> |
47 | | #include <undoanim.hxx> |
48 | | #include <optsitem.hxx> |
49 | | |
50 | | #include <o3tl/safeint.hxx> |
51 | | |
52 | | #include <algorithm> |
53 | | |
54 | | using namespace ::com::sun::star; |
55 | | |
56 | | using ::com::sun::star::uno::Reference; |
57 | | |
58 | | |
59 | | namespace sd::impl |
60 | | { |
61 | | struct TransitionEffect |
62 | | { |
63 | | TransitionEffect() : |
64 | 0 | mnType( 0 ), |
65 | 0 | mnSubType( 0 ), |
66 | 0 | mbDirection( true ), |
67 | 0 | mnFadeColor( 0 ) |
68 | 0 | { |
69 | 0 | init(); |
70 | 0 | } |
71 | | explicit TransitionEffect( const ::sd::TransitionPreset & rPreset ) : |
72 | 0 | mnType( rPreset.getTransition()), |
73 | 0 | mnSubType( rPreset.getSubtype()), |
74 | 0 | mbDirection( rPreset.getDirection()), |
75 | 0 | mnFadeColor( rPreset.getFadeColor()) |
76 | 0 | { |
77 | 0 | init(); |
78 | 0 | } |
79 | | explicit TransitionEffect( const SdPage & rPage ) : |
80 | 0 | mnType( rPage.getTransitionType() ), |
81 | 0 | mnSubType( rPage.getTransitionSubtype() ), |
82 | 0 | mbDirection( rPage.getTransitionDirection() ), |
83 | 0 | mnFadeColor( rPage.getTransitionFadeColor() ) |
84 | 0 | { |
85 | 0 | init(); |
86 | |
|
87 | 0 | mfDuration = rPage.getTransitionDuration(); |
88 | 0 | mfTime = rPage.GetTime(); |
89 | 0 | mePresChange = rPage.GetPresChange(); |
90 | 0 | mbSoundOn = rPage.IsSoundOn(); |
91 | 0 | maSound = rPage.GetSoundFile(); |
92 | 0 | mbLoopSound = rPage.IsLoopSound(); |
93 | 0 | mbStopSound = rPage.IsStopSound(); |
94 | 0 | } |
95 | | |
96 | | void init() |
97 | 0 | { |
98 | 0 | mfDuration = 2.0; |
99 | 0 | mfTime = 0.0; |
100 | 0 | mePresChange = PresChange::Manual; |
101 | 0 | mbSoundOn = false; |
102 | 0 | mbLoopSound = false; |
103 | 0 | mbStopSound = false; |
104 | |
|
105 | 0 | mbEffectAmbiguous = false; |
106 | 0 | mbDurationAmbiguous = false; |
107 | 0 | mbTimeAmbiguous = false; |
108 | 0 | mbPresChangeAmbiguous = false; |
109 | 0 | mbSoundAmbiguous = false; |
110 | 0 | mbLoopSoundAmbiguous = false; |
111 | 0 | } |
112 | | |
113 | | void setAllAmbiguous() |
114 | 0 | { |
115 | 0 | mbEffectAmbiguous = true; |
116 | 0 | mbDurationAmbiguous = true; |
117 | 0 | mbTimeAmbiguous = true; |
118 | 0 | mbPresChangeAmbiguous = true; |
119 | 0 | mbSoundAmbiguous = true; |
120 | 0 | mbLoopSoundAmbiguous = true; |
121 | 0 | } |
122 | | |
123 | | bool operator == ( const ::sd::TransitionPreset & rPreset ) const |
124 | 0 | { |
125 | 0 | return |
126 | 0 | (mnType == rPreset.getTransition()) && |
127 | 0 | (mnSubType == rPreset.getSubtype()) && |
128 | 0 | (mbDirection == rPreset.getDirection()) && |
129 | 0 | (mnFadeColor == rPreset.getFadeColor()); |
130 | 0 | } |
131 | | |
132 | | void applyTo( SdPage & rOutPage ) const |
133 | 0 | { |
134 | 0 | if( ! mbEffectAmbiguous ) |
135 | 0 | { |
136 | 0 | rOutPage.setTransitionType( mnType ); |
137 | 0 | rOutPage.setTransitionSubtype( mnSubType ); |
138 | 0 | rOutPage.setTransitionDirection( mbDirection ); |
139 | 0 | rOutPage.setTransitionFadeColor( mnFadeColor ); |
140 | 0 | } |
141 | |
|
142 | 0 | if( ! mbDurationAmbiguous ) |
143 | 0 | rOutPage.setTransitionDuration( mfDuration ); |
144 | 0 | if( ! mbTimeAmbiguous ) |
145 | 0 | rOutPage.SetTime( mfTime ); |
146 | 0 | if( ! mbPresChangeAmbiguous ) |
147 | 0 | rOutPage.SetPresChange( mePresChange ); |
148 | 0 | if( ! mbSoundAmbiguous ) |
149 | 0 | { |
150 | 0 | if( mbStopSound ) |
151 | 0 | { |
152 | 0 | rOutPage.SetStopSound( true ); |
153 | 0 | rOutPage.SetSound( false ); |
154 | 0 | } |
155 | 0 | else |
156 | 0 | { |
157 | 0 | rOutPage.SetStopSound( false ); |
158 | 0 | rOutPage.SetSound( mbSoundOn ); |
159 | 0 | rOutPage.SetSoundFile( maSound ); |
160 | 0 | } |
161 | 0 | } |
162 | 0 | if( ! mbLoopSoundAmbiguous ) |
163 | 0 | rOutPage.SetLoopSound( mbLoopSound ); |
164 | 0 | } |
165 | | |
166 | | void compareWith( const SdPage & rPage ) |
167 | 0 | { |
168 | 0 | TransitionEffect aOtherEffect( rPage ); |
169 | 0 | mbEffectAmbiguous = mbEffectAmbiguous || aOtherEffect.mbEffectAmbiguous |
170 | 0 | || (mnType != aOtherEffect.mnType) |
171 | 0 | || (mnSubType != aOtherEffect.mnSubType) |
172 | 0 | || (mbDirection != aOtherEffect.mbDirection) |
173 | 0 | || (mnFadeColor != aOtherEffect.mnFadeColor); |
174 | |
|
175 | 0 | mbDurationAmbiguous = mbDurationAmbiguous || aOtherEffect.mbDurationAmbiguous || mfDuration != aOtherEffect.mfDuration; |
176 | 0 | mbTimeAmbiguous = mbTimeAmbiguous || aOtherEffect.mbTimeAmbiguous || mfTime != aOtherEffect.mfTime; |
177 | 0 | mbPresChangeAmbiguous = mbPresChangeAmbiguous || aOtherEffect.mbPresChangeAmbiguous || mePresChange != aOtherEffect.mePresChange; |
178 | 0 | mbSoundAmbiguous = mbSoundAmbiguous || aOtherEffect.mbSoundAmbiguous || mbSoundOn != aOtherEffect.mbSoundOn; |
179 | | #if 0 |
180 | | // Weird leftover isolated expression with no effect, introduced in 2007 in |
181 | | // CWS impress122. Ifdeffed out to avoid compiler warning, kept here in case |
182 | | // somebody who understands this code notices and understands what the |
183 | | // "right" thing to do might be. |
184 | | (!mbStopSound && !aOtherEffect.mbStopSound && maSound != aOtherEffect.maSound) || (mbStopSound != aOtherEffect.mbStopSound); |
185 | | #endif |
186 | 0 | mbLoopSoundAmbiguous = mbLoopSoundAmbiguous || aOtherEffect.mbLoopSoundAmbiguous || mbLoopSound != aOtherEffect.mbLoopSound; |
187 | 0 | } |
188 | | |
189 | | // effect |
190 | | sal_Int16 mnType; |
191 | | sal_Int16 mnSubType; |
192 | | bool mbDirection; |
193 | | sal_Int32 mnFadeColor; |
194 | | |
195 | | // other settings |
196 | | double mfDuration; |
197 | | double mfTime; |
198 | | PresChange mePresChange; |
199 | | bool mbSoundOn; |
200 | | OUString maSound; |
201 | | bool mbLoopSound; |
202 | | bool mbStopSound; |
203 | | |
204 | | bool mbEffectAmbiguous; |
205 | | bool mbDurationAmbiguous; |
206 | | bool mbTimeAmbiguous; |
207 | | bool mbPresChangeAmbiguous; |
208 | | bool mbSoundAmbiguous; |
209 | | bool mbLoopSoundAmbiguous; |
210 | | }; |
211 | | |
212 | | } // namespace sd::impl |
213 | | |
214 | | namespace sd |
215 | | { |
216 | | |
217 | | // Local Helper Functions |
218 | | namespace |
219 | | { |
220 | | |
221 | | void lcl_ApplyToPages( |
222 | | const ::sd::slidesorter::SharedPageSelection& rpPages, |
223 | | const ::sd::impl::TransitionEffect & rEffect ) |
224 | 0 | { |
225 | 0 | for( const auto& rpPage : *rpPages ) |
226 | 0 | { |
227 | 0 | rEffect.applyTo( *rpPage ); |
228 | 0 | } |
229 | 0 | } |
230 | | |
231 | | void lcl_CreateUndoForPages( |
232 | | const ::sd::slidesorter::SharedPageSelection& rpPages, |
233 | | ::sd::ViewShellBase const & rBase ) |
234 | 0 | { |
235 | 0 | ::sd::DrawDocShell* pDocSh = rBase.GetDocShell(); |
236 | 0 | if (!pDocSh) |
237 | 0 | return; |
238 | 0 | SfxUndoManager* pManager = pDocSh->GetUndoManager(); |
239 | 0 | if (!pManager) |
240 | 0 | return; |
241 | 0 | SdDrawDocument* pDoc = pDocSh->GetDoc(); |
242 | 0 | if (!pDoc) |
243 | 0 | return; |
244 | | |
245 | 0 | OUString aComment( SdResId(STR_UNDO_SLIDE_PARAMS) ); |
246 | 0 | pManager->EnterListAction(aComment, aComment, 0, rBase.GetViewShellId()); |
247 | 0 | std::unique_ptr<SdUndoGroup> pUndoGroup(new SdUndoGroup( *pDoc )); |
248 | 0 | pUndoGroup->SetComment( aComment ); |
249 | |
|
250 | 0 | for( const auto& rpPage : *rpPages ) |
251 | 0 | { |
252 | 0 | pUndoGroup->AddAction( new sd::UndoTransition( *pDoc, rpPage ) ); |
253 | 0 | } |
254 | |
|
255 | 0 | pManager->AddUndoAction( std::move(pUndoGroup) ); |
256 | 0 | pManager->LeaveListAction(); |
257 | 0 | } |
258 | | |
259 | | struct lcl_EqualsSoundFileName |
260 | | { |
261 | | explicit lcl_EqualsSoundFileName( OUString aStr ) : |
262 | 0 | maStr(std::move( aStr )) |
263 | 0 | {} |
264 | | |
265 | | bool operator() ( const OUString & rStr ) const |
266 | 0 | { |
267 | | // note: formerly this was a case insensitive search for all |
268 | | // platforms. It seems more sensible to do this platform-dependent |
269 | 0 | INetURLObject aURL(rStr); |
270 | | #if defined(_WIN32) |
271 | | return maStr.equalsIgnoreAsciiCase( aURL.GetBase() ); |
272 | | #else |
273 | 0 | return maStr == aURL.GetBase(); |
274 | 0 | #endif |
275 | 0 | } |
276 | | |
277 | | private: |
278 | | OUString maStr; |
279 | | }; |
280 | | |
281 | | // returns -1 if no object was found |
282 | | bool lcl_findSoundInList( const ::std::vector< OUString > & rSoundList, |
283 | | std::u16string_view rFileName, |
284 | | ::std::vector< OUString >::size_type & rOutPosition ) |
285 | 0 | { |
286 | 0 | INetURLObject aURL(rFileName); |
287 | 0 | ::std::vector< OUString >::const_iterator aIt = |
288 | 0 | ::std::find_if( rSoundList.begin(), rSoundList.end(), |
289 | 0 | lcl_EqualsSoundFileName( aURL.GetBase())); |
290 | 0 | if( aIt != rSoundList.end()) |
291 | 0 | { |
292 | 0 | rOutPosition = ::std::distance( rSoundList.begin(), aIt ); |
293 | 0 | return true; |
294 | 0 | } |
295 | | |
296 | 0 | return false; |
297 | 0 | } |
298 | | |
299 | | OUString lcl_getSoundFileURL( |
300 | | const ::std::vector< OUString > & rSoundList, |
301 | | const weld::ComboBox& rListBox ) |
302 | 0 | { |
303 | 0 | sal_Int32 nPos = rListBox.get_active(); |
304 | | // the first three entries are no actual sounds |
305 | 0 | if( nPos >= 3 ) |
306 | 0 | { |
307 | 0 | DBG_ASSERT( static_cast<sal_uInt32>(rListBox.get_count() - 3) == rSoundList.size(), |
308 | 0 | "Sound list-box is not synchronized to sound list" ); |
309 | 0 | nPos -= 3; |
310 | 0 | if( rSoundList.size() > o3tl::make_unsigned(nPos) ) |
311 | 0 | return rSoundList[ nPos ]; |
312 | 0 | } |
313 | | |
314 | 0 | return OUString(); |
315 | 0 | } |
316 | | |
317 | | struct lcl_AppendSoundToListBox |
318 | | { |
319 | | explicit lcl_AppendSoundToListBox(weld::ComboBox& rListBox) |
320 | 0 | : mrListBox( rListBox ) |
321 | 0 | {} |
322 | | |
323 | | void operator() ( std::u16string_view rString ) const |
324 | 0 | { |
325 | 0 | INetURLObject aURL( rString ); |
326 | 0 | mrListBox.append_text( aURL.GetBase() ); |
327 | 0 | } |
328 | | |
329 | | private: |
330 | | weld::ComboBox& mrListBox; |
331 | | }; |
332 | | |
333 | | void lcl_FillSoundListBox( |
334 | | const ::std::vector< OUString > & rSoundList, |
335 | | weld::ComboBox& rOutListBox ) |
336 | 0 | { |
337 | 0 | sal_Int32 nCount = rOutListBox.get_count(); |
338 | | |
339 | | // keep first three entries |
340 | 0 | for( sal_Int32 i=nCount - 1; i>=3; --i ) |
341 | 0 | rOutListBox.remove( i ); |
342 | |
|
343 | 0 | ::std::for_each( rSoundList.begin(), rSoundList.end(), |
344 | 0 | lcl_AppendSoundToListBox( rOutListBox )); |
345 | 0 | } |
346 | | |
347 | | /// Returns an offset into the list of transition presets |
348 | | sd::TransitionPresetPtr getPreset(const sd::impl::TransitionEffect &rEffect) |
349 | 0 | { |
350 | 0 | const sd::TransitionPresetList& rPresetList = sd::TransitionPreset::getTransitionPresetList(); |
351 | |
|
352 | 0 | for (const auto& pPreset: rPresetList) |
353 | 0 | { |
354 | 0 | if (rEffect.operator==(*pPreset)) |
355 | 0 | return pPreset; |
356 | 0 | } |
357 | 0 | return sd::TransitionPresetPtr(); |
358 | 0 | } |
359 | | |
360 | | } // anonymous namespace |
361 | | |
362 | | // SlideTransitionPane |
363 | | SlideTransitionPane::SlideTransitionPane( |
364 | | weld::Widget* pParent, |
365 | | ViewShellBase & rBase) : |
366 | 0 | PanelLayout( pParent, u"SlideTransitionsPanel"_ustr, u"modules/simpress/ui/slidetransitionspanel.ui"_ustr ), |
367 | 0 | mrBase( rBase ), |
368 | 0 | mpDrawDoc( rBase.GetDocShell() ? rBase.GetDocShell()->GetDoc() : nullptr ), |
369 | 0 | mxTransitionsIconView(m_xBuilder->weld_icon_view("transitions_icons")), |
370 | 0 | mxTransitionsScrollWindow(m_xBuilder->weld_scrolled_window("transitions_icons_scrolled_window")), |
371 | 0 | mxRepeatAutoFrame(m_xBuilder->weld_frame("repeat_after_frame")), |
372 | 0 | mbHasSelection( false ), |
373 | 0 | mbUpdatingControls( false ), |
374 | 0 | mbIsMainViewChangePending( false ), |
375 | 0 | maLateInitTimer("sd SlideTransitionPane maLateInitTimer") |
376 | 0 | { |
377 | 0 | Initialize(mpDrawDoc); |
378 | 0 | } |
379 | | |
380 | | css::ui::LayoutSize SlideTransitionPane::GetHeightForWidth(const sal_Int32 /*nWidth*/) |
381 | 0 | { |
382 | 0 | sal_Int32 nMinimumHeight = get_preferred_size().Height(); |
383 | 0 | return css::ui::LayoutSize(nMinimumHeight, -1, nMinimumHeight); |
384 | 0 | } |
385 | | |
386 | | void SlideTransitionPane::Initialize(SdDrawDocument* pDoc) |
387 | 0 | { |
388 | 0 | mxLB_VARIANT = m_xBuilder->weld_combo_box(u"variant_list"_ustr); |
389 | 0 | mxCBX_duration = m_xBuilder->weld_metric_spin_button(u"transition_duration"_ustr, FieldUnit::SECOND); |
390 | 0 | mxFT_SOUND = m_xBuilder->weld_label(u"sound_label"_ustr); |
391 | 0 | mxLB_SOUND = m_xBuilder->weld_combo_box(u"sound_list"_ustr); |
392 | 0 | mxCB_LOOP_SOUND = m_xBuilder->weld_check_button(u"loop_sound"_ustr); |
393 | 0 | mxRB_ADVANCE_ON_MOUSE = m_xBuilder->weld_radio_button(u"rb_mouse_click"_ustr); |
394 | 0 | mxRB_ADVANCE_AUTO = m_xBuilder->weld_radio_button(u"rb_auto_after"_ustr); |
395 | 0 | mxMF_ADVANCE_AUTO_AFTER = m_xBuilder->weld_metric_spin_button(u"auto_after_value"_ustr, FieldUnit::SECOND); |
396 | 0 | mxRB_REPEAT_DISABLED = m_xBuilder->weld_radio_button(u"rb_disabled"_ustr); |
397 | 0 | mxRB_REPEAT_AUTO = m_xBuilder->weld_radio_button(u"rb_auto_repeat"_ustr); |
398 | 0 | mxMF_REPEAT_AUTO_AFTER = m_xBuilder->weld_metric_spin_button(u"rb_auto_repeat_value"_ustr, FieldUnit::SECOND); |
399 | 0 | mxPB_APPLY_TO_ALL = m_xBuilder->weld_button(u"apply_to_all"_ustr); |
400 | 0 | mxPB_PLAY = m_xBuilder->weld_button(u"play"_ustr); |
401 | 0 | mxCB_AUTO_PREVIEW = m_xBuilder->weld_check_button(u"auto_preview"_ustr); |
402 | |
|
403 | 0 | auto nMax = mxMF_ADVANCE_AUTO_AFTER->get_max(FieldUnit::SECOND); |
404 | 0 | mxMF_ADVANCE_AUTO_AFTER->set_max(99, FieldUnit::SECOND); |
405 | 0 | int nWidthChars = mxMF_ADVANCE_AUTO_AFTER->get_width_chars(); |
406 | 0 | mxMF_ADVANCE_AUTO_AFTER->set_max(nMax, FieldUnit::SECOND); |
407 | 0 | mxMF_ADVANCE_AUTO_AFTER->set_width_chars(nWidthChars); |
408 | 0 | mxMF_REPEAT_AUTO_AFTER->set_max(nMax, FieldUnit::SECOND); |
409 | 0 | mxMF_REPEAT_AUTO_AFTER->set_width_chars(nWidthChars); |
410 | 0 | mxCBX_duration->set_width_chars(nWidthChars); |
411 | |
|
412 | 0 | if( pDoc ) |
413 | 0 | mxModel = pDoc->getUnoModel(); |
414 | | // TODO: get correct view |
415 | 0 | if( mxModel.is()) |
416 | 0 | mxView.set( mxModel->getCurrentController(), uno::UNO_QUERY ); |
417 | | |
418 | | // set defaults |
419 | 0 | mxCB_AUTO_PREVIEW->set_active(true); // automatic preview on |
420 | | |
421 | | // update control states before adding handlers |
422 | 0 | updateControls(); |
423 | | |
424 | | // set handlers |
425 | 0 | mxPB_APPLY_TO_ALL->connect_clicked( LINK( this, SlideTransitionPane, ApplyToAllButtonClicked )); |
426 | 0 | mxPB_PLAY->connect_clicked( LINK( this, SlideTransitionPane, PlayButtonClicked )); |
427 | |
|
428 | 0 | mxTransitionsIconView->connect_item_activated(LINK(this, SlideTransitionPane, TransitionSelected)); |
429 | |
|
430 | 0 | mxLB_VARIANT->connect_changed( LINK( this, SlideTransitionPane, VariantListBoxSelected )); |
431 | 0 | mxCBX_duration->connect_value_changed(LINK( this, SlideTransitionPane, DurationModifiedHdl)); |
432 | 0 | mxCBX_duration->connect_focus_out(LINK( this, SlideTransitionPane, DurationLoseFocusHdl)); |
433 | 0 | mxLB_SOUND->connect_changed( LINK( this, SlideTransitionPane, SoundListBoxSelected )); |
434 | 0 | mxCB_LOOP_SOUND->connect_toggled( LINK( this, SlideTransitionPane, LoopSoundBoxChecked )); |
435 | |
|
436 | 0 | mxRB_ADVANCE_ON_MOUSE->connect_toggled( LINK( this, SlideTransitionPane, AdvanceSlideRadioButtonToggled )); |
437 | 0 | mxRB_ADVANCE_AUTO->connect_toggled( LINK( this, SlideTransitionPane, AdvanceSlideRadioButtonToggled )); |
438 | 0 | mxMF_ADVANCE_AUTO_AFTER->connect_value_changed( LINK( this, SlideTransitionPane, AdvanceTimeModified )); |
439 | 0 | mxRB_REPEAT_DISABLED->connect_toggled( LINK( this, SlideTransitionPane, RepeatAfterRadioButtonToggled )); |
440 | 0 | mxRB_REPEAT_AUTO->connect_toggled( LINK( this, SlideTransitionPane, RepeatAfterRadioButtonToggled )); |
441 | 0 | mxMF_REPEAT_AUTO_AFTER->connect_value_changed( LINK( this, SlideTransitionPane, RepeatAfterTimeModified )); |
442 | 0 | mxCB_AUTO_PREVIEW->connect_toggled( LINK( this, SlideTransitionPane, AutoPreviewClicked )); |
443 | 0 | addListener(); |
444 | |
|
445 | 0 | mxRB_REPEAT_DISABLED->set_active( true ); |
446 | |
|
447 | 0 | maLateInitTimer.SetTimeout(200); |
448 | 0 | maLateInitTimer.SetInvokeHandler(LINK(this, SlideTransitionPane, LateInitCallback)); |
449 | 0 | maLateInitTimer.Start(); |
450 | 0 | } |
451 | | |
452 | | SlideTransitionPane::~SlideTransitionPane() |
453 | 0 | { |
454 | 0 | maLateInitTimer.Stop(); |
455 | 0 | removeListener(); |
456 | 0 | mxTransitionsScrollWindow.reset(); |
457 | 0 | mxTransitionsIconView.reset(); |
458 | 0 | mxRepeatAutoFrame.reset(); |
459 | 0 | mxLB_VARIANT.reset(); |
460 | 0 | mxCBX_duration.reset(); |
461 | 0 | mxFT_SOUND.reset(); |
462 | 0 | mxLB_SOUND.reset(); |
463 | 0 | mxCB_LOOP_SOUND.reset(); |
464 | 0 | mxRB_ADVANCE_ON_MOUSE.reset(); |
465 | 0 | mxRB_ADVANCE_AUTO.reset(); |
466 | 0 | mxMF_ADVANCE_AUTO_AFTER.reset(); |
467 | 0 | mxRB_REPEAT_DISABLED.reset(); |
468 | 0 | mxRB_REPEAT_AUTO.reset(); |
469 | 0 | mxMF_REPEAT_AUTO_AFTER.reset(); |
470 | 0 | mxPB_APPLY_TO_ALL.reset(); |
471 | 0 | mxPB_PLAY.reset(); |
472 | 0 | mxCB_AUTO_PREVIEW.reset(); |
473 | 0 | } |
474 | | |
475 | | void SlideTransitionPane::onSelectionChanged() |
476 | 0 | { |
477 | 0 | updateControls(); |
478 | 0 | } |
479 | | |
480 | | void SlideTransitionPane::onChangeCurrentPage() |
481 | 0 | { |
482 | 0 | updateControls(); |
483 | 0 | } |
484 | | |
485 | | ::sd::slidesorter::SharedPageSelection SlideTransitionPane::getSelectedPages() const |
486 | 0 | { |
487 | 0 | ::sd::slidesorter::SlideSorterViewShell * pSlideSorterViewShell |
488 | 0 | = ::sd::slidesorter::SlideSorterViewShell::GetSlideSorter(mrBase); |
489 | 0 | std::shared_ptr<sd::slidesorter::SlideSorterViewShell::PageSelection> pSelection; |
490 | |
|
491 | 0 | if( pSlideSorterViewShell ) |
492 | 0 | { |
493 | 0 | pSelection = pSlideSorterViewShell->GetPageSelection(); |
494 | 0 | } |
495 | 0 | else |
496 | 0 | { |
497 | 0 | pSelection = std::make_shared<sd::slidesorter::SlideSorterViewShell::PageSelection>(); |
498 | 0 | if( mxView.is() ) |
499 | 0 | { |
500 | 0 | SdPage* pPage = SdPage::getImplementation( mxView->getCurrentPage() ); |
501 | 0 | if( pPage ) |
502 | 0 | pSelection->push_back(pPage); |
503 | 0 | } |
504 | 0 | } |
505 | |
|
506 | 0 | return pSelection; |
507 | 0 | } |
508 | | |
509 | | void SlideTransitionPane::updateControls() |
510 | 0 | { |
511 | 0 | ::sd::slidesorter::SharedPageSelection pSelectedPages(getSelectedPages()); |
512 | 0 | if( pSelectedPages->empty()) |
513 | 0 | { |
514 | 0 | mbHasSelection = false; |
515 | 0 | return; |
516 | 0 | } |
517 | 0 | mbHasSelection = true; |
518 | |
|
519 | 0 | DBG_ASSERT( ! mbUpdatingControls, "Multiple Control Updates" ); |
520 | 0 | mbUpdatingControls = true; |
521 | | |
522 | | // get model data for first page |
523 | 0 | SdPage * pFirstPage = pSelectedPages->front(); |
524 | 0 | DBG_ASSERT( pFirstPage, "Invalid Page" ); |
525 | |
|
526 | 0 | impl::TransitionEffect aEffect( *pFirstPage ); |
527 | | |
528 | | // merge with other pages |
529 | | |
530 | | // start with second page (note aIt != aEndIt, because ! aSelectedPages.empty()) |
531 | 0 | for( const auto& rpPage : *pSelectedPages ) |
532 | 0 | { |
533 | 0 | if( rpPage ) |
534 | 0 | aEffect.compareWith( *rpPage ); |
535 | 0 | } |
536 | | |
537 | | // detect current slide effect |
538 | 0 | if( aEffect.mbEffectAmbiguous ) |
539 | 0 | { |
540 | 0 | SAL_WARN( "sd.transitions", "Unusual, ambiguous transition effect" ); |
541 | 0 | mxTransitionsIconView->select(0); |
542 | 0 | } |
543 | 0 | else |
544 | 0 | { |
545 | | // ToDo: That 0 is "no transition" is documented nowhere except in the |
546 | | // CTOR of sdpage |
547 | 0 | if( aEffect.mnType == 0 ) |
548 | 0 | mxTransitionsIconView->select(0); |
549 | 0 | else |
550 | 0 | updateVariants(getPreset(aEffect)); |
551 | 0 | } |
552 | | |
553 | 0 | if( aEffect.mbDurationAmbiguous ) |
554 | 0 | { |
555 | 0 | mxCBX_duration->set_text(u""_ustr); |
556 | | //TODO mxCBX_duration->SetNoSelection(); |
557 | 0 | } |
558 | 0 | else |
559 | 0 | { |
560 | 0 | mxCBX_duration->set_value( (aEffect.mfDuration)*100.0, FieldUnit::SECOND ); |
561 | 0 | } |
562 | |
|
563 | 0 | if( aEffect.mbSoundAmbiguous ) |
564 | 0 | { |
565 | 0 | mxLB_SOUND->set_active(-1); |
566 | 0 | maCurrentSoundFile.clear(); |
567 | 0 | } |
568 | 0 | else |
569 | 0 | { |
570 | 0 | maCurrentSoundFile.clear(); |
571 | 0 | if( aEffect.mbStopSound ) |
572 | 0 | { |
573 | 0 | mxLB_SOUND->set_active( 1 ); |
574 | 0 | } |
575 | 0 | else if( aEffect.mbSoundOn && !aEffect.maSound.isEmpty() ) |
576 | 0 | { |
577 | 0 | std::vector<OUString>::size_type nPos = 0; |
578 | 0 | if( lcl_findSoundInList( maSoundList, aEffect.maSound, nPos )) |
579 | 0 | { |
580 | 0 | mxLB_SOUND->set_active( nPos + 3 ); |
581 | 0 | maCurrentSoundFile = aEffect.maSound; |
582 | 0 | } |
583 | 0 | } |
584 | 0 | else |
585 | 0 | { |
586 | 0 | mxLB_SOUND->set_active( 0 ); |
587 | 0 | } |
588 | 0 | } |
589 | |
|
590 | 0 | if( aEffect.mbLoopSoundAmbiguous ) |
591 | 0 | { |
592 | 0 | mxCB_LOOP_SOUND->set_state(TRISTATE_INDET); |
593 | 0 | } |
594 | 0 | else |
595 | 0 | { |
596 | 0 | mxCB_LOOP_SOUND->set_active(aEffect.mbLoopSound); |
597 | 0 | } |
598 | |
|
599 | 0 | if( aEffect.mbPresChangeAmbiguous ) |
600 | 0 | { |
601 | 0 | mxRB_ADVANCE_ON_MOUSE->set_active( false ); |
602 | 0 | mxRB_ADVANCE_AUTO->set_active( false ); |
603 | 0 | } |
604 | 0 | else |
605 | 0 | { |
606 | 0 | mxRB_ADVANCE_ON_MOUSE->set_active( aEffect.mePresChange == PresChange::Manual ); |
607 | 0 | mxRB_ADVANCE_AUTO->set_active( aEffect.mePresChange == PresChange::Auto ); |
608 | 0 | mxMF_ADVANCE_AUTO_AFTER->set_value(aEffect.mfTime * 100.0, FieldUnit::SECOND); |
609 | 0 | } |
610 | |
|
611 | 0 | sd::PresentationSettings& rSettings = mpDrawDoc->getPresentationSettings(); |
612 | |
|
613 | 0 | if ( !rSettings.mbEndless ) |
614 | 0 | { |
615 | 0 | mxRB_REPEAT_DISABLED->set_active( true ); |
616 | 0 | mxRB_REPEAT_AUTO->set_active( false ); |
617 | 0 | } |
618 | 0 | else |
619 | 0 | { |
620 | 0 | mxRB_REPEAT_DISABLED->set_active( false ); |
621 | 0 | mxRB_REPEAT_AUTO->set_active( true ); |
622 | 0 | mxMF_REPEAT_AUTO_AFTER->set_value(rSettings.mnPauseTimeout * 100.0, FieldUnit::SECOND); |
623 | 0 | } |
624 | |
|
625 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
626 | 0 | { |
627 | 0 | mxPB_PLAY->hide(); |
628 | 0 | mxCB_AUTO_PREVIEW->set_active(false); |
629 | 0 | mxCB_AUTO_PREVIEW->hide(); |
630 | 0 | mxFT_SOUND->hide(); |
631 | 0 | mxLB_SOUND->hide(); |
632 | 0 | mxCB_LOOP_SOUND->hide(); |
633 | 0 | } |
634 | 0 | else |
635 | 0 | { |
636 | 0 | mxRepeatAutoFrame->hide(); |
637 | 0 | SdOptions* pOptions = SdModule::get()->GetSdOptions(DocumentType::Impress); |
638 | 0 | mxCB_AUTO_PREVIEW->set_active( pOptions->IsPreviewTransitions() ); |
639 | 0 | } |
640 | |
|
641 | 0 | mbUpdatingControls = false; |
642 | |
|
643 | 0 | updateControlState(); |
644 | 0 | } |
645 | | |
646 | | void SlideTransitionPane::updateControlState() |
647 | 0 | { |
648 | 0 | if (mxTransitionsScrollWindow) |
649 | 0 | mxTransitionsScrollWindow->set_sensitive(mbHasSelection); |
650 | 0 | mxLB_VARIANT->set_sensitive( mbHasSelection && mxLB_VARIANT->get_count() > 0 ); |
651 | 0 | mxCBX_duration->set_sensitive( mbHasSelection ); |
652 | 0 | mxLB_SOUND->set_sensitive( mbHasSelection ); |
653 | 0 | mxCB_LOOP_SOUND->set_sensitive( mbHasSelection && (mxLB_SOUND->get_active() > 2)); |
654 | 0 | mxRB_ADVANCE_ON_MOUSE->set_sensitive( mbHasSelection ); |
655 | 0 | mxRB_ADVANCE_AUTO->set_sensitive( mbHasSelection ); |
656 | 0 | mxMF_ADVANCE_AUTO_AFTER->set_sensitive( mbHasSelection && mxRB_ADVANCE_AUTO->get_active()); |
657 | 0 | mxRB_REPEAT_DISABLED->set_sensitive( mbHasSelection ); |
658 | 0 | mxRB_REPEAT_AUTO->set_sensitive( mbHasSelection ); |
659 | 0 | mxMF_REPEAT_AUTO_AFTER->set_sensitive( mbHasSelection && mxRB_REPEAT_AUTO->get_active()); |
660 | |
|
661 | 0 | mxPB_APPLY_TO_ALL->set_sensitive( mbHasSelection ); |
662 | 0 | mxPB_PLAY->set_sensitive( mbHasSelection ); |
663 | 0 | mxCB_AUTO_PREVIEW->set_sensitive( mbHasSelection ); |
664 | 0 | } |
665 | | |
666 | | void SlideTransitionPane::updateSoundList() |
667 | 0 | { |
668 | 0 | maSoundList.clear(); |
669 | |
|
670 | 0 | GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, maSoundList ); |
671 | 0 | GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, maSoundList ); |
672 | |
|
673 | 0 | lcl_FillSoundListBox( maSoundList, *mxLB_SOUND ); |
674 | 0 | } |
675 | | |
676 | | void SlideTransitionPane::openSoundFileDialog() |
677 | 0 | { |
678 | 0 | if( ! mxLB_SOUND->get_sensitive()) |
679 | 0 | return; |
680 | | |
681 | 0 | weld::Window* pDialogParent(GetFrameWeld()); |
682 | 0 | SdOpenSoundFileDialog aFileDialog(pDialogParent); |
683 | |
|
684 | 0 | DBG_ASSERT( mxLB_SOUND->get_active() == 2, |
685 | 0 | "Dialog should only open when \"Other sound\" is selected" ); |
686 | |
|
687 | 0 | bool bValidSoundFile( false ); |
688 | 0 | bool bQuitLoop( false ); |
689 | |
|
690 | 0 | while( ! bQuitLoop && |
691 | 0 | aFileDialog.Execute() == ERRCODE_NONE ) |
692 | 0 | { |
693 | 0 | OUString aFile = aFileDialog.GetPath(); |
694 | 0 | std::vector<OUString>::size_type nPos = 0; |
695 | 0 | bValidSoundFile = lcl_findSoundInList( maSoundList, aFile, nPos ); |
696 | |
|
697 | 0 | if( bValidSoundFile ) |
698 | 0 | { |
699 | 0 | bQuitLoop = true; |
700 | 0 | } |
701 | 0 | else // not in sound list |
702 | 0 | { |
703 | | // try to insert into gallery |
704 | 0 | if( GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aFile ) ) |
705 | 0 | { |
706 | 0 | updateSoundList(); |
707 | 0 | bValidSoundFile = lcl_findSoundInList( maSoundList, aFile, nPos ); |
708 | 0 | DBG_ASSERT( bValidSoundFile, "Adding sound to gallery failed" ); |
709 | |
|
710 | 0 | bQuitLoop = true; |
711 | 0 | } |
712 | 0 | else |
713 | 0 | { |
714 | 0 | OUString aStrWarning(SdResId(STR_WARNING_NOSOUNDFILE)); |
715 | 0 | aStrWarning = aStrWarning.replaceFirst("%", aFile); |
716 | 0 | std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pDialogParent, |
717 | 0 | VclMessageType::Warning, VclButtonsType::NONE, |
718 | 0 | aStrWarning)); |
719 | 0 | xWarn->add_button(GetStandardText(StandardButtonType::Retry), RET_RETRY); |
720 | 0 | xWarn->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL); |
721 | 0 | bQuitLoop = (xWarn->run() != RET_RETRY); |
722 | |
|
723 | 0 | bValidSoundFile = false; |
724 | 0 | } |
725 | 0 | } |
726 | |
|
727 | 0 | if( bValidSoundFile ) |
728 | | // skip first three entries in list |
729 | 0 | mxLB_SOUND->set_active( nPos + 3 ); |
730 | 0 | } |
731 | |
|
732 | 0 | if( bValidSoundFile ) |
733 | 0 | return; |
734 | | |
735 | 0 | if( !maCurrentSoundFile.isEmpty() ) |
736 | 0 | { |
737 | 0 | std::vector<OUString>::size_type nPos = 0; |
738 | 0 | if( lcl_findSoundInList( maSoundList, maCurrentSoundFile, nPos )) |
739 | 0 | mxLB_SOUND->set_active( nPos + 3 ); |
740 | 0 | else |
741 | 0 | mxLB_SOUND->set_active( 0 ); // NONE |
742 | 0 | } |
743 | 0 | else |
744 | 0 | mxLB_SOUND->set_active( 0 ); // NONE |
745 | 0 | } |
746 | | |
747 | | impl::TransitionEffect SlideTransitionPane::getTransitionEffectFromControls() const |
748 | 0 | { |
749 | 0 | impl::TransitionEffect aResult; |
750 | 0 | aResult.setAllAmbiguous(); |
751 | |
|
752 | 0 | OUString sSelectedId = mxTransitionsIconView->get_selected_id(); |
753 | 0 | auto* pTransitionEntry = weld::fromId<TransitionEntry*>(sSelectedId); |
754 | 0 | if (!pTransitionEntry) |
755 | 0 | return aResult; |
756 | | |
757 | 0 | const sd::TransitionPresetList& rPresetList = sd::TransitionPreset::getTransitionPresetList(); |
758 | |
|
759 | 0 | if (pTransitionEntry->mpPreset) |
760 | 0 | { |
761 | 0 | auto pSelectedPreset = pTransitionEntry->mpPreset; |
762 | |
|
763 | 0 | if (mxLB_VARIANT->get_active() == -1) |
764 | 0 | { |
765 | | // Transition with just one effect. |
766 | 0 | aResult = impl::TransitionEffect(*pSelectedPreset); |
767 | 0 | aResult.setAllAmbiguous(); |
768 | 0 | } |
769 | 0 | else |
770 | 0 | { |
771 | 0 | int nVariant = 0; |
772 | 0 | bool bFound = false; |
773 | 0 | for(const auto& rPreset: rPresetList) |
774 | 0 | { |
775 | 0 | if (rPreset->getSetId() == pSelectedPreset->getSetId() ) |
776 | 0 | { |
777 | 0 | if( mxLB_VARIANT->get_active() == nVariant) |
778 | 0 | { |
779 | 0 | aResult = impl::TransitionEffect(*rPreset); |
780 | 0 | aResult.setAllAmbiguous(); |
781 | 0 | bFound = true; |
782 | 0 | break; |
783 | 0 | } |
784 | 0 | else |
785 | 0 | { |
786 | 0 | nVariant++; |
787 | 0 | } |
788 | 0 | } |
789 | 0 | } |
790 | 0 | if( !bFound ) |
791 | 0 | { |
792 | 0 | aResult.mnType = 0; |
793 | 0 | } |
794 | 0 | } |
795 | 0 | aResult.mbEffectAmbiguous = false; |
796 | 0 | } |
797 | 0 | else |
798 | 0 | { |
799 | 0 | aResult.mbEffectAmbiguous = false; |
800 | 0 | } |
801 | | |
802 | | //duration |
803 | |
|
804 | 0 | if( mxCBX_duration->get_sensitive() && (!(mxCBX_duration->get_text()).isEmpty()) ) |
805 | 0 | { |
806 | 0 | aResult.mfDuration = static_cast<double>(mxCBX_duration->get_value(FieldUnit::SECOND))/100.0; |
807 | 0 | aResult.mbDurationAmbiguous = false; |
808 | 0 | } |
809 | | |
810 | | // slide-advance mode |
811 | 0 | if( mxRB_ADVANCE_ON_MOUSE->get_sensitive() && mxRB_ADVANCE_AUTO->get_sensitive() && |
812 | 0 | (mxRB_ADVANCE_ON_MOUSE->get_active() || mxRB_ADVANCE_AUTO->get_active())) |
813 | 0 | { |
814 | 0 | if( mxRB_ADVANCE_ON_MOUSE->get_active()) |
815 | 0 | aResult.mePresChange = PresChange::Manual; |
816 | 0 | else |
817 | 0 | { |
818 | 0 | aResult.mePresChange = PresChange::Auto; |
819 | 0 | if( mxMF_ADVANCE_AUTO_AFTER->get_sensitive()) |
820 | 0 | { |
821 | 0 | aResult.mfTime = static_cast<double>(mxMF_ADVANCE_AUTO_AFTER->get_value(FieldUnit::SECOND) ) / 100.0 ; |
822 | 0 | aResult.mbTimeAmbiguous = false; |
823 | 0 | } |
824 | 0 | } |
825 | |
|
826 | 0 | aResult.mbPresChangeAmbiguous = false; |
827 | 0 | } |
828 | | |
829 | | // transition repeat after |
830 | 0 | if (mxRB_REPEAT_DISABLED->get_sensitive() && mxRB_REPEAT_AUTO->get_sensitive() |
831 | 0 | && (mxRB_REPEAT_DISABLED->get_active() || mxRB_REPEAT_AUTO->get_active())) |
832 | 0 | { |
833 | 0 | sd::PresentationSettings& rSettings = mpDrawDoc->getPresentationSettings(); |
834 | |
|
835 | 0 | if ( mxRB_REPEAT_DISABLED->get_active() ) |
836 | 0 | { |
837 | 0 | rSettings.mbEndless = false; |
838 | 0 | rSettings.mnPauseTimeout = 0; |
839 | 0 | } |
840 | 0 | else |
841 | 0 | { |
842 | 0 | if ( mxMF_REPEAT_AUTO_AFTER->get_sensitive() ) |
843 | 0 | { |
844 | 0 | rSettings.mbEndless = true; |
845 | 0 | rSettings.mnPauseTimeout = static_cast<sal_uInt32>(mxMF_REPEAT_AUTO_AFTER->get_value(FieldUnit::SECOND) / 100.0) ; |
846 | 0 | } |
847 | 0 | } |
848 | 0 | } |
849 | | |
850 | | // sound |
851 | 0 | if( mxLB_SOUND->get_sensitive()) |
852 | 0 | { |
853 | 0 | maCurrentSoundFile.clear(); |
854 | 0 | sal_Int32 nPos = mxLB_SOUND->get_active(); |
855 | 0 | if (nPos != -1) |
856 | 0 | { |
857 | 0 | aResult.mbStopSound = nPos == 1; |
858 | 0 | aResult.mbSoundOn = nPos > 1; |
859 | 0 | if( aResult.mbStopSound ) |
860 | 0 | { |
861 | 0 | aResult.maSound.clear(); |
862 | 0 | aResult.mbSoundAmbiguous = false; |
863 | 0 | } |
864 | 0 | else |
865 | 0 | { |
866 | 0 | aResult.maSound = lcl_getSoundFileURL(maSoundList, *mxLB_SOUND); |
867 | 0 | aResult.mbSoundAmbiguous = false; |
868 | 0 | maCurrentSoundFile = aResult.maSound; |
869 | 0 | } |
870 | 0 | } |
871 | 0 | } |
872 | | |
873 | | // sound loop |
874 | 0 | if( mxCB_LOOP_SOUND->get_sensitive() ) |
875 | 0 | { |
876 | 0 | aResult.mbLoopSound = mxCB_LOOP_SOUND->get_active(); |
877 | 0 | aResult.mbLoopSoundAmbiguous = false; |
878 | 0 | } |
879 | |
|
880 | 0 | return aResult; |
881 | 0 | } |
882 | | |
883 | | void SlideTransitionPane::applyToSelectedPages(bool bPreview = true) |
884 | 0 | { |
885 | 0 | if( mbUpdatingControls ) |
886 | 0 | return; |
887 | | |
888 | 0 | vcl::Window *pFocusWindow = Application::GetFocusWindow(); |
889 | |
|
890 | 0 | ::sd::slidesorter::SharedPageSelection pSelectedPages( getSelectedPages()); |
891 | 0 | impl::TransitionEffect aEffect = getTransitionEffectFromControls(); |
892 | 0 | if( ! pSelectedPages->empty()) |
893 | 0 | { |
894 | 0 | lcl_CreateUndoForPages( pSelectedPages, mrBase ); |
895 | 0 | lcl_ApplyToPages( pSelectedPages, aEffect ); |
896 | 0 | mrBase.GetDocShell()->SetModified(); |
897 | 0 | } |
898 | 0 | if( mxCB_AUTO_PREVIEW->get_sensitive() && |
899 | 0 | mxCB_AUTO_PREVIEW->get_active() && bPreview) |
900 | 0 | { |
901 | 0 | if (aEffect.mnType) // mnType = 0 denotes no transition |
902 | 0 | playCurrentEffect(); |
903 | 0 | else if( mxView.is() && !SlideShow::IsInteractiveSlideshow(&mrBase)) // IASS |
904 | 0 | SlideShow::Stop( mrBase ); |
905 | 0 | } |
906 | |
|
907 | 0 | if (pFocusWindow) |
908 | 0 | pFocusWindow->GrabFocus(); |
909 | 0 | } |
910 | | |
911 | | void SlideTransitionPane::playCurrentEffect() |
912 | 0 | { |
913 | 0 | if( mxView.is() ) |
914 | 0 | { |
915 | |
|
916 | 0 | Reference< css::animations::XAnimationNode > xNode; |
917 | 0 | SlideShow::StartPreview( mrBase, mxView->getCurrentPage(), xNode ); |
918 | 0 | } |
919 | 0 | } |
920 | | |
921 | | void SlideTransitionPane::addListener() |
922 | 0 | { |
923 | 0 | Link<tools::EventMultiplexerEvent&,void> aLink( LINK(this,SlideTransitionPane,EventMultiplexerListener) ); |
924 | 0 | mrBase.GetEventMultiplexer()->AddEventListener( aLink ); |
925 | 0 | } |
926 | | |
927 | | void SlideTransitionPane::removeListener() |
928 | 0 | { |
929 | 0 | Link<tools::EventMultiplexerEvent&,void> aLink( LINK(this,SlideTransitionPane,EventMultiplexerListener) ); |
930 | 0 | mrBase.GetEventMultiplexer()->RemoveEventListener( aLink ); |
931 | 0 | } |
932 | | |
933 | | IMPL_LINK(SlideTransitionPane,EventMultiplexerListener, |
934 | | tools::EventMultiplexerEvent&, rEvent, void) |
935 | 0 | { |
936 | 0 | switch (rEvent.meEventId) |
937 | 0 | { |
938 | 0 | case EventMultiplexerEventId::EditViewSelection: |
939 | 0 | onSelectionChanged(); |
940 | 0 | break; |
941 | | |
942 | 0 | case EventMultiplexerEventId::CurrentPageChanged: |
943 | 0 | case EventMultiplexerEventId::SlideSortedSelection: |
944 | 0 | onChangeCurrentPage(); |
945 | 0 | break; |
946 | | |
947 | 0 | case EventMultiplexerEventId::MainViewRemoved: |
948 | 0 | mxView.clear(); |
949 | 0 | onSelectionChanged(); |
950 | 0 | onChangeCurrentPage(); |
951 | 0 | break; |
952 | | |
953 | 0 | case EventMultiplexerEventId::MainViewAdded: |
954 | 0 | mbIsMainViewChangePending = true; |
955 | 0 | break; |
956 | | |
957 | 0 | case EventMultiplexerEventId::ConfigurationUpdated: |
958 | 0 | if (mbIsMainViewChangePending) |
959 | 0 | { |
960 | 0 | mbIsMainViewChangePending = false; |
961 | | |
962 | | // At this moment the controller may not yet been set at |
963 | | // model or ViewShellBase. Take it from the view shell |
964 | | // passed with the event. |
965 | 0 | if (mrBase.GetMainViewShell() != nullptr) |
966 | 0 | { |
967 | 0 | mxView.set(mrBase.GetController(), css::uno::UNO_QUERY); |
968 | 0 | onSelectionChanged(); |
969 | 0 | onChangeCurrentPage(); |
970 | 0 | } |
971 | 0 | } |
972 | 0 | break; |
973 | | |
974 | 0 | default: |
975 | 0 | if (rEvent.meEventId != EventMultiplexerEventId::Disposing) |
976 | 0 | { |
977 | 0 | onSelectionChanged(); |
978 | 0 | onChangeCurrentPage(); |
979 | 0 | } |
980 | 0 | break; |
981 | 0 | } |
982 | 0 | } |
983 | | |
984 | | IMPL_LINK_NOARG(SlideTransitionPane, ApplyToAllButtonClicked, weld::Button&, void) |
985 | 0 | { |
986 | 0 | DBG_ASSERT( mpDrawDoc, "Invalid Draw Document!" ); |
987 | 0 | if( !mpDrawDoc ) |
988 | 0 | return; |
989 | | |
990 | 0 | ::sd::slidesorter::SharedPageSelection pPages = |
991 | 0 | std::make_shared<::sd::slidesorter::SlideSorterViewShell::PageSelection>(); |
992 | |
|
993 | 0 | sal_uInt16 nPageCount = mpDrawDoc->GetSdPageCount( PageKind::Standard ); |
994 | 0 | pPages->reserve( nPageCount ); |
995 | 0 | for( sal_uInt16 i=0; i<nPageCount; ++i ) |
996 | 0 | { |
997 | 0 | SdPage * pPage = mpDrawDoc->GetSdPage( i, PageKind::Standard ); |
998 | 0 | if( pPage ) |
999 | 0 | pPages->push_back( pPage ); |
1000 | 0 | } |
1001 | |
|
1002 | 0 | if( ! pPages->empty()) |
1003 | 0 | { |
1004 | 0 | lcl_CreateUndoForPages( pPages, mrBase ); |
1005 | 0 | lcl_ApplyToPages( pPages, getTransitionEffectFromControls() ); |
1006 | 0 | } |
1007 | 0 | } |
1008 | | |
1009 | | IMPL_LINK_NOARG(SlideTransitionPane, PlayButtonClicked, weld::Button&, void) |
1010 | 0 | { |
1011 | 0 | playCurrentEffect(); |
1012 | 0 | } |
1013 | | |
1014 | | IMPL_LINK_NOARG(SlideTransitionPane, TransitionSelected, weld::IconView&, bool) |
1015 | 0 | { |
1016 | 0 | OUString sSelectedId = mxTransitionsIconView->get_selected_id(); |
1017 | 0 | auto* pTransitionEntry = weld::fromId<TransitionEntry*>(sSelectedId); |
1018 | 0 | updateVariants(pTransitionEntry->mpPreset); |
1019 | 0 | applyToSelectedPages(); |
1020 | 0 | return true; |
1021 | 0 | } |
1022 | | |
1023 | | /// we use an integer offset into the list of transition presets |
1024 | | void SlideTransitionPane::updateVariants(TransitionPresetPtr const& pPreset) |
1025 | 0 | { |
1026 | 0 | mxLB_VARIANT->clear(); |
1027 | 0 | mxLB_VARIANT->set_sensitive(false); |
1028 | 0 | mxLB_VARIANT->set_active(0); |
1029 | |
|
1030 | 0 | if (!pPreset) |
1031 | 0 | { |
1032 | 0 | mxTransitionsIconView->select(0); |
1033 | 0 | } |
1034 | 0 | else |
1035 | 0 | { |
1036 | 0 | auto iterator = maTranstionMap.find(pPreset->getSetId()); |
1037 | 0 | if (iterator != maTranstionMap.end()) |
1038 | 0 | { |
1039 | 0 | auto& pTransitionEntry = iterator->second; |
1040 | 0 | if (!pTransitionEntry->mnVariants.empty()) |
1041 | 0 | { |
1042 | 0 | for (OUString const& rCurrentVariant : pTransitionEntry->mnVariants) |
1043 | 0 | { |
1044 | 0 | mxLB_VARIANT->append_text(rCurrentVariant); |
1045 | 0 | if (pPreset->getVariantLabel() == rCurrentVariant) |
1046 | 0 | mxLB_VARIANT->set_active(mxLB_VARIANT->get_count() - 1); |
1047 | 0 | } |
1048 | 0 | mxLB_VARIANT->set_sensitive(true); |
1049 | 0 | } |
1050 | |
|
1051 | 0 | mxTransitionsIconView->select(pTransitionEntry->mnIndex); |
1052 | 0 | } |
1053 | 0 | } |
1054 | 0 | } |
1055 | | |
1056 | | IMPL_LINK_NOARG(SlideTransitionPane, AdvanceSlideRadioButtonToggled, weld::Toggleable&, void) |
1057 | 0 | { |
1058 | 0 | updateControlState(); |
1059 | 0 | applyToSelectedPages(false); |
1060 | 0 | } |
1061 | | |
1062 | | IMPL_LINK_NOARG(SlideTransitionPane, RepeatAfterRadioButtonToggled, weld::Toggleable&, void) |
1063 | 0 | { |
1064 | 0 | updateControlState(); |
1065 | 0 | applyToSelectedPages(false); |
1066 | 0 | } |
1067 | | |
1068 | | IMPL_LINK_NOARG(SlideTransitionPane, AdvanceTimeModified, weld::MetricSpinButton&, void) |
1069 | 0 | { |
1070 | 0 | applyToSelectedPages(false); |
1071 | 0 | } |
1072 | | |
1073 | | IMPL_LINK_NOARG(SlideTransitionPane, RepeatAfterTimeModified, weld::MetricSpinButton&, void) |
1074 | 0 | { |
1075 | 0 | applyToSelectedPages(false); |
1076 | 0 | } |
1077 | | |
1078 | | IMPL_LINK_NOARG(SlideTransitionPane, VariantListBoxSelected, weld::ComboBox&, void) |
1079 | 0 | { |
1080 | 0 | applyToSelectedPages(); |
1081 | 0 | } |
1082 | | |
1083 | | IMPL_LINK_NOARG(SlideTransitionPane, DurationModifiedHdl, weld::MetricSpinButton&, void) |
1084 | 0 | { |
1085 | 0 | double duration_value = static_cast<double>(mxCBX_duration->get_value(FieldUnit::SECOND)); |
1086 | 0 | if (duration_value <= 0.0) |
1087 | 0 | mxCBX_duration->set_value(0, FieldUnit::SECOND); |
1088 | 0 | else |
1089 | 0 | mxCBX_duration->set_value(duration_value, FieldUnit::SECOND); |
1090 | |
|
1091 | 0 | applyToSelectedPages(); |
1092 | 0 | } |
1093 | | |
1094 | | IMPL_LINK_NOARG(SlideTransitionPane, DurationLoseFocusHdl, weld::Widget&, void) |
1095 | 0 | { |
1096 | 0 | applyToSelectedPages(); |
1097 | 0 | } |
1098 | | |
1099 | | IMPL_LINK_NOARG(SlideTransitionPane, SoundListBoxSelected, weld::ComboBox&, void) |
1100 | 0 | { |
1101 | 0 | sal_Int32 nPos = mxLB_SOUND->get_active(); |
1102 | 0 | if( nPos == 2 ) |
1103 | 0 | { |
1104 | | // other sound... |
1105 | 0 | openSoundFileDialog(); |
1106 | 0 | } |
1107 | 0 | updateControlState(); |
1108 | 0 | applyToSelectedPages(); |
1109 | 0 | } |
1110 | | |
1111 | | IMPL_LINK_NOARG(SlideTransitionPane, LoopSoundBoxChecked, weld::Toggleable&, void) |
1112 | 0 | { |
1113 | 0 | applyToSelectedPages(); |
1114 | 0 | } |
1115 | | |
1116 | | IMPL_LINK_NOARG(SlideTransitionPane, AutoPreviewClicked, weld::Toggleable&, void) |
1117 | 0 | { |
1118 | 0 | SdOptions* pOptions = SdModule::get()->GetSdOptions(DocumentType::Impress); |
1119 | 0 | pOptions->SetPreviewTransitions( mxCB_AUTO_PREVIEW->get_active() ); |
1120 | 0 | } |
1121 | | |
1122 | | IMPL_LINK_NOARG(SlideTransitionPane, LateInitCallback, Timer *, void) |
1123 | 0 | { |
1124 | 0 | mxTransitionsIconView->freeze(); |
1125 | |
|
1126 | 0 | { |
1127 | 0 | auto pTransition = std::make_unique<TransitionEntry>(); |
1128 | 0 | const OUString aId = weld::toId(pTransition.get()); |
1129 | 0 | pTransition->msIcon = u"sd/cmd/transition-none.png"_ustr; |
1130 | 0 | pTransition->msLabel = SdResId(STR_SLIDETRANSITION_NONE); |
1131 | 0 | pTransition->mnIndex = 0; |
1132 | 0 | mxTransitionsIconView->append(aId, pTransition->msLabel, pTransition->msIcon); |
1133 | 0 | maTranstionMap.emplace(u"None"_ustr, std::move(pTransition)); |
1134 | 0 | } |
1135 | |
|
1136 | 0 | const TransitionPresetList& rPresetList = TransitionPreset::getTransitionPresetList(); |
1137 | 0 | size_t nIndex = 1; |
1138 | 0 | for (TransitionPresetPtr const& pPreset: rPresetList) |
1139 | 0 | { |
1140 | 0 | const OUString aLabel = pPreset->getSetLabel(); |
1141 | 0 | if (!aLabel.isEmpty()) |
1142 | 0 | { |
1143 | 0 | auto aIterator = maTranstionMap.find(pPreset->getSetId()); |
1144 | 0 | if (aIterator == maTranstionMap.end()) |
1145 | 0 | { |
1146 | 0 | auto pTransition = std::make_unique<TransitionEntry>(); |
1147 | 0 | const OUString aId = weld::toId(pTransition.get()); |
1148 | |
|
1149 | 0 | pTransition->msIcon = u"sd/cmd/transition-"_ustr + pPreset->getSetId() + u".png"_ustr; |
1150 | 0 | pTransition->msLabel = aLabel; |
1151 | 0 | pTransition->mpPreset = pPreset; |
1152 | 0 | if (!pPreset->getVariantLabel().isEmpty()) |
1153 | 0 | pTransition->mnVariants.push_back(pPreset->getVariantLabel()); |
1154 | 0 | pTransition->mnIndex = nIndex; |
1155 | 0 | nIndex++; |
1156 | |
|
1157 | 0 | mxTransitionsIconView->append(aId, pTransition->msLabel, pTransition->msIcon); |
1158 | 0 | maTranstionMap.emplace(pPreset->getSetId(), std::move(pTransition)); |
1159 | 0 | } |
1160 | 0 | else |
1161 | 0 | { |
1162 | 0 | auto& pTransition = aIterator->second; |
1163 | 0 | pTransition->mnVariants.push_back(pPreset->getVariantLabel()); |
1164 | 0 | } |
1165 | 0 | } |
1166 | 0 | } |
1167 | 0 | mxTransitionsIconView->set_size_request(0, 0); |
1168 | 0 | mxTransitionsIconView->thaw(); |
1169 | |
|
1170 | 0 | updateSoundList(); |
1171 | 0 | updateControls(); |
1172 | 0 | } |
1173 | | |
1174 | | } // namespace sd |
1175 | | |
1176 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |