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