1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 #include <tools/debug.hxx>
27 #include <cppuhelper/implbase1.hxx>
28 #include <comphelper/processfactory.hxx>
29 #include <com/sun/star/lang/XInitialization.hpp>
30 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
31 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
32 #include <com/sun/star/ui/dialogs/ListboxControlActions.hpp>
33 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
34 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
35 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
36 #include <com/sun/star/ui/dialogs/XFilePickerListener.hpp>
37 #include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp>
38 #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
39 #include <vcl/msgbox.hxx>
40 #include <sal/types.h>
41 #include <tools/urlobj.hxx>
42 #include <vos/thread.hxx>
43 #include <vos/mutex.hxx>
44 #include <vcl/svapp.hxx>
45 #include <sfx2/filedlghelper.hxx>
46 #include <avmedia/mediawindow.hxx>
47 #include "filedlg.hxx"
48 #include "sdresid.hxx"
49 #include "strings.hrc"
50 #include <svtools/filter.hxx>
51
52
53 //-----------------------------------------------------------------------------
54
55 namespace css = ::com::sun::star;
56
57
58 // --------------------------------------------------------------------
59 // ----------- SdFileDialog_Imp ---------------------------
60 // --------------------------------------------------------------------
61 class SdFileDialog_Imp : public sfx2::FileDialogHelper
62 {
63 private:
64 #if defined __SUNPRO_CC
65 using sfx2::FileDialogHelper::Execute;
66 #endif
67
68 friend class SdOpenSoundFileDialog;
69
70 css::uno::Reference< css::ui::dialogs::XFilePickerControlAccess > mxControlAccess;
71
72 css::uno::Reference< css::media::XPlayer > mxPlayer;
73 sal_uLong mnPlaySoundEvent;
74 sal_Bool mbUsableSelection;
75 sal_Bool mbLabelPlaying;
76
77 void CheckSelectionState();
78
79 DECL_LINK( PlayMusicHdl, void * );
80
81 Timer maUpdateTimer;
82
83 DECL_LINK( IsMusicStoppedHdl, void * );
84
85 public:
86 SdFileDialog_Imp( const short nDialogType, sal_Bool bUsableSelection );
87 ~SdFileDialog_Imp();
88
89 ErrCode Execute();
90
91 // overwritten from FileDialogHelper, to receive user feedback
92 virtual void SAL_CALL ControlStateChanged( const css::ui::dialogs::FilePickerEvent& aEvent );
93 };
94
95 // ------------------------------------------------------------------------
ControlStateChanged(const css::ui::dialogs::FilePickerEvent & aEvent)96 void SAL_CALL SdFileDialog_Imp::ControlStateChanged( const css::ui::dialogs::FilePickerEvent& aEvent )
97 {
98 ::vos::OGuard aGuard( Application::GetSolarMutex() );
99
100 switch( aEvent.ElementId )
101 {
102 case css::ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER:
103 CheckSelectionState();
104 break;
105
106 case css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY:
107 if( mxControlAccess.is() )
108 {
109 if( mnPlaySoundEvent )
110 Application::RemoveUserEvent( mnPlaySoundEvent );
111
112 mnPlaySoundEvent = Application::PostUserEvent( LINK( this, SdFileDialog_Imp, PlayMusicHdl ) );
113 }
114 break;
115 }
116 }
117
118 // ------------------------------------------------------------------------
IMPL_LINK(SdFileDialog_Imp,PlayMusicHdl,void *,EMPTYARG)119 IMPL_LINK( SdFileDialog_Imp, PlayMusicHdl, void *, EMPTYARG )
120 {
121 maUpdateTimer.Stop();
122 mnPlaySoundEvent = 0;
123
124 if (mxPlayer.is())
125 {
126 if (mxPlayer->isPlaying())
127 mxPlayer->stop();
128 mxPlayer.clear();
129 }
130
131 if( mbLabelPlaying )
132 {
133 try
134 {
135 mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY,
136 String( SdResId( STR_PLAY ) ) );
137
138 mbLabelPlaying = sal_False;
139 }
140 catch( css::lang::IllegalArgumentException )
141 {
142 #ifdef DBG_UTIL
143 DBG_ERROR( "Cannot access play button" );
144 #endif
145 }
146 }
147 else
148 {
149 rtl::OUString aUrl( GetPath() );
150 if ( aUrl.getLength() )
151 {
152 try
153 {
154 mxPlayer.set( avmedia::MediaWindow::createPlayer( aUrl ), css::uno::UNO_QUERY_THROW );
155 mxPlayer->start();
156 maUpdateTimer.SetTimeout( 100 );
157 maUpdateTimer.Start();
158 }
159 catch( css::uno::Exception& e )
160 {
161 (void)e;
162 mxPlayer.clear();
163 }
164
165 if (mxPlayer.is())
166 {
167 try
168 {
169 mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY,
170 String( SdResId( STR_STOP ) ) );
171
172 mbLabelPlaying = sal_True;
173 }
174 catch( css::lang::IllegalArgumentException )
175 {
176 #ifdef DBG_UTIL
177 DBG_ERROR( "Cannot access play button" );
178 #endif
179 }
180 }
181 }
182 }
183
184 return 0;
185 }
186
187 // ------------------------------------------------------------------------
IMPL_LINK(SdFileDialog_Imp,IsMusicStoppedHdl,void *,EMPTYARG)188 IMPL_LINK( SdFileDialog_Imp, IsMusicStoppedHdl, void *, EMPTYARG )
189 {
190 ::vos::OGuard aGuard( Application::GetSolarMutex() );
191
192 if (
193 mxPlayer.is() && mxPlayer->isPlaying() &&
194 mxPlayer->getMediaTime() < mxPlayer->getDuration()
195 )
196 {
197 maUpdateTimer.Start();
198 return 0L;
199 }
200
201
202 if( mxControlAccess.is() )
203 {
204 try
205 {
206 mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY,
207 String( SdResId( STR_PLAY ) ) );
208 mbLabelPlaying = sal_False;
209 }
210 catch( css::lang::IllegalArgumentException )
211 {
212 #ifdef DBG_UTIL
213 DBG_ERROR( "Cannot access play button" );
214 #endif
215 }
216 }
217
218 return( 0L );
219 }
220
221 // check whether to disable the "selection" checkbox
CheckSelectionState()222 void SdFileDialog_Imp::CheckSelectionState()
223 {
224 if( mbUsableSelection && mxControlAccess.is() )
225 {
226 String aCurrFilter( GetCurrentFilter() );
227
228 try
229 {
230 if( !aCurrFilter.Len() || ( aCurrFilter == String( SdResId( STR_EXPORT_HTML_NAME ) ) ) )
231 mxControlAccess->enableControl( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION, sal_False );
232 else
233 mxControlAccess->enableControl( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION, sal_True );
234 }
235 catch( css::lang::IllegalArgumentException )
236 {
237 #ifdef DBG_UTIL
238 DBG_ERROR( "Cannot access \"selection\" checkbox" );
239 #endif
240 }
241 }
242 }
243
244 //-----------------------------------------------------------------------------
SdFileDialog_Imp(const short nDialogType,sal_Bool bUsableSelection)245 SdFileDialog_Imp::SdFileDialog_Imp( const short nDialogType,
246 sal_Bool bUsableSelection ) :
247 FileDialogHelper( nDialogType, 0 ),
248 mnPlaySoundEvent( 0 ),
249 mbUsableSelection( bUsableSelection ),
250 mbLabelPlaying(sal_False)
251 {
252 maUpdateTimer.SetTimeoutHdl(LINK(this, SdFileDialog_Imp, IsMusicStoppedHdl));
253
254 css::uno::Reference < ::com::sun::star::ui::dialogs::XFilePicker > xFileDlg = GetFilePicker();
255
256 // get the control access
257 mxControlAccess = css::uno::Reference< css::ui::dialogs::XFilePickerControlAccess > ( xFileDlg, css::uno::UNO_QUERY );
258
259 if( mxControlAccess.is() )
260 {
261 if( nDialogType ==
262 css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY )
263 {
264 try
265 {
266 mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY,
267 String( SdResId( STR_PLAY ) ) );
268 }
269 catch( css::lang::IllegalArgumentException )
270 {
271 #ifdef DBG_UTIL
272 DBG_ERROR( "Cannot set play button label" );
273 #endif
274 }
275 }
276 else if( mbUsableSelection != sal_True )
277 {
278 try
279 {
280 mxControlAccess->enableControl( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION, sal_False );
281 }
282 catch( css::lang::IllegalArgumentException )
283 {
284 #ifdef DBG_UTIL
285 DBG_ERROR( "Cannot disable selection checkbox" );
286 #endif
287 }
288 }
289 }
290 }
291
292
293 // ------------------------------------------------------------------------
~SdFileDialog_Imp()294 SdFileDialog_Imp::~SdFileDialog_Imp()
295 {
296 if( mnPlaySoundEvent )
297 Application::RemoveUserEvent( mnPlaySoundEvent );
298 }
299
300 // ------------------------------------------------------------------------
Execute()301 ErrCode SdFileDialog_Imp::Execute()
302 {
303 // make sure selection checkbox is disabled if
304 // HTML is current filter!
305 CheckSelectionState();
306 return FileDialogHelper::Execute();
307 }
308
309 // --------------------------------------------------------------------
310 // ----------- SdOpenSoundFileDialog -----------------------
311 // --------------------------------------------------------------------
312
313 // these are simple forwarders
SdOpenSoundFileDialog()314 SdOpenSoundFileDialog::SdOpenSoundFileDialog() :
315 mpImpl(
316 new SdFileDialog_Imp(
317 css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY, sal_False ) )
318 {
319 String aDescr;
320 aDescr = String(SdResId(STR_ALL_FILES));
321 mpImpl->AddFilter( aDescr, UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "*.*" ) ) );
322
323 // setup filter
324 #if defined UNX
325 aDescr = String(SdResId(STR_AU_FILE));
326 mpImpl->AddFilter( aDescr, UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "*.au;*.snd" ) ) );
327 aDescr = String(SdResId(STR_VOC_FILE));
328 mpImpl->AddFilter( aDescr, UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "*.voc" ) ) );
329 aDescr = String(SdResId(STR_WAV_FILE));
330 mpImpl->AddFilter( aDescr, UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "*.wav" ) ) );
331 aDescr = String(SdResId(STR_AIFF_FILE));
332 mpImpl->AddFilter( aDescr, UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "*.aiff" ) ) );
333 aDescr = String(SdResId(STR_SVX_FILE));
334 mpImpl->AddFilter( aDescr, UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "*.svx" ) ) );
335 #else
336 aDescr = String(SdResId(STR_WAV_FILE));
337 mpImpl->AddFilter( aDescr, UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "*.wav;*.mp3;*.m4a;*.ogg" ) ) );
338 aDescr = String(SdResId(STR_MIDI_FILE));
339 mpImpl->AddFilter( aDescr, UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "*.mid" ) ) );
340 #endif
341 }
342
343 // ------------------------------------------------------------------------
~SdOpenSoundFileDialog()344 SdOpenSoundFileDialog::~SdOpenSoundFileDialog()
345 {
346 }
347
348 // ------------------------------------------------------------------------
Execute()349 ErrCode SdOpenSoundFileDialog::Execute()
350 {
351 return mpImpl->Execute();
352 }
353
354 // ------------------------------------------------------------------------
GetPath() const355 String SdOpenSoundFileDialog::GetPath() const
356 {
357 return mpImpl->GetPath();
358 }
359
360 // ------------------------------------------------------------------------
SetPath(const String & rPath)361 void SdOpenSoundFileDialog::SetPath( const String& rPath )
362 {
363 mpImpl->SetDisplayDirectory( rPath );
364 }
365