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