xref: /trunk/main/sd/source/ui/dlg/filedlg.cxx (revision eca41011)
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