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 //------------------------------------------------------------------------ 25 // includes 26 //------------------------------------------------------------------------ 27 28 #include <com/sun/star/lang/DisposedException.hpp> 29 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 30 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> 31 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> 32 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> 33 #include <cppuhelper/interfacecontainer.h> 34 #include <osl/diagnose.h> 35 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> 36 #include <com/sun/star/ui/dialogs/ControlActions.hpp> 37 #include <com/sun/star/uno/Any.hxx> 38 #include <FPServiceInfo.hxx> 39 #include <vos/mutex.hxx> 40 #include <vcl/svapp.hxx> 41 42 #ifndef _TOOLS_URLOBJ_HXX 43 #include <tools/urlobj.hxx> 44 #endif 45 #include "resourceprovider.hxx" 46 47 #ifndef _SV_RC_H 48 #include <tools/rc.hxx> 49 #endif 50 #include <osl/file.hxx> 51 #include "CFStringUtilities.hxx" 52 #include "NSString_OOoAdditions.hxx" 53 #include "NSURL_OOoAdditions.hxx" 54 55 #include <iostream> 56 57 #include "SalAquaFilePicker.hxx" 58 59 60 #pragma mark DEFINES 61 62 #define LABEL_TOGGLE( elem ) \ 63 case elem : \ 64 aLabel = aResProvider.getResString( CHECKBOX_##elem ); \ 65 setLabel( CHECKBOX_##elem, aLabel ); \ 66 break 67 68 #define CLASS_NAME "SalAquaFilePicker" 69 70 //------------------------------------------------------------------------ 71 // namespace directives 72 //------------------------------------------------------------------------ 73 74 using namespace ::com::sun::star; 75 using namespace ::com::sun::star::ui::dialogs; 76 using namespace ::com::sun::star::ui::dialogs::TemplateDescription; 77 using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds; 78 using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds; 79 using namespace ::com::sun::star::lang; 80 using namespace ::com::sun::star::beans; 81 using namespace ::com::sun::star::uno; 82 83 //------------------------------------------------------------------------ 84 // helper functions 85 //------------------------------------------------------------------------ 86 87 namespace 88 { 89 // controlling event notifications 90 const bool STARTUP_SUSPENDED = true; 91 const bool STARTUP_ALIVE = false; 92 93 uno::Sequence<rtl::OUString> SAL_CALL FilePicker_getSupportedServiceNames() 94 { 95 uno::Sequence<rtl::OUString> aRet(3); 96 aRet[0] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.FilePicker" ); 97 aRet[1] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.SystemFilePicker" ); 98 aRet[2] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.AquaFilePicker" ); 99 return aRet; 100 } 101 } 102 103 #pragma mark Constructor 104 //----------------------------------------------------------------------------------------- 105 // constructor 106 //----------------------------------------------------------------------------------------- 107 108 SalAquaFilePicker::SalAquaFilePicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr ) : 109 cppu::WeakComponentImplHelper8<XFilterManager, XFilterGroupManager, XFilePickerControlAccess, XFilePickerNotifier, 110 lang::XInitialization, util::XCancellable, lang::XEventListener, lang::XServiceInfo>( m_rbHelperMtx ) 111 , m_xServiceMgr( xServiceMgr ) 112 , m_pFilterHelper( NULL ) 113 { 114 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 115 116 m_pDelegate = [[AquaFilePickerDelegate alloc] initWithFilePicker:this]; 117 m_pControlHelper->setFilePickerDelegate(m_pDelegate); 118 119 DBG_PRINT_EXIT(CLASS_NAME, __func__); 120 } 121 122 SalAquaFilePicker::~SalAquaFilePicker() 123 { 124 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 125 126 if (NULL != m_pFilterHelper) 127 delete m_pFilterHelper; 128 129 [m_pDelegate release]; 130 131 DBG_PRINT_EXIT(CLASS_NAME, __func__); 132 } 133 134 135 #pragma mark XFilePickerNotifier 136 //------------------------------------------------------------------------------------ 137 // XFilePickerNotifier 138 //------------------------------------------------------------------------------------ 139 140 void SAL_CALL SalAquaFilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener ) 141 { 142 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 143 144 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 145 m_xListener = xListener; 146 147 DBG_PRINT_EXIT(CLASS_NAME, __func__); 148 } 149 150 void SAL_CALL SalAquaFilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& ) 151 { 152 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 153 154 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 155 m_xListener.clear(); 156 157 DBG_PRINT_EXIT(CLASS_NAME, __func__); 158 } 159 160 #pragma mark XAsynchronousExecutableDialog 161 //----------------------------------------------------------------------------------------- 162 // XExecutableDialog functions 163 //----------------------------------------------------------------------------------------- 164 void SAL_CALL SalAquaFilePicker::setTitle( const rtl::OUString& aTitle ) 165 { 166 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle); 167 168 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 169 implsetTitle(aTitle); 170 171 DBG_PRINT_EXIT(CLASS_NAME, __func__); 172 } 173 174 sal_Int16 SAL_CALL SalAquaFilePicker::execute() 175 { 176 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 177 178 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 179 180 sal_Int16 retVal = 0; 181 182 implInitialize(); 183 184 // if m_pDialog is nil after initialization, something must have gone wrong before 185 // or there was no initialization (see issue http://www.openoffice.org/issues/show_bug.cgi?id=100214) 186 if (m_pDialog == nil) { 187 //throw uno::RuntimeException(rtl::OUString::createFromAscii("The dialog was not properly initialized!"), static_cast< XFilePicker* >( this )); 188 m_nDialogType = NAVIGATIONSERVICES_OPEN; 189 } 190 191 if (m_pFilterHelper) { 192 m_pFilterHelper->SetFilters(); 193 } 194 195 if (m_nDialogType == NAVIGATIONSERVICES_SAVE) { 196 if (m_sSaveFileName.getLength() == 0) { 197 //if no filename is set, NavigationServices will set the name to "untitled". We don't want this! 198 //So let's try to get the window title to get the real untitled name 199 NSWindow *frontWindow = [NSApp keyWindow]; 200 if (NULL != frontWindow) { 201 NSString *windowTitle = [frontWindow title]; 202 if (windowTitle != nil) { 203 rtl::OUString ouName = [windowTitle OUString]; 204 //a window title will typically be something like "Untitled1 - OpenOffice.org Writer" 205 //but we only want the "Untitled1" part of it 206 sal_Int32 indexOfDash = ouName.indexOf(rtl::OUString::createFromAscii(" - ")); 207 if (indexOfDash > -1) { 208 m_sSaveFileName = ouName.copy(0,indexOfDash); 209 if (m_sSaveFileName.getLength() > 0) { 210 setDefaultName(m_sSaveFileName); 211 } 212 } else { 213 OSL_TRACE("no dash present in window title"); 214 } 215 } else { 216 OSL_TRACE("couldn't get window title"); 217 } 218 } else { 219 OSL_TRACE("no front window found"); 220 } 221 } 222 } 223 224 //Set the delegate to be notified of certain events 225 [m_pDialog setDelegate:m_pDelegate]; 226 227 int nStatus = runandwaitforresult(); 228 229 [m_pDialog setDelegate:nil]; 230 231 switch( nStatus ) 232 { 233 case NSOKButton: 234 OSL_TRACE("The dialog returned OK"); 235 retVal = ExecutableDialogResults::OK; 236 break; 237 238 case NSCancelButton: 239 OSL_TRACE("The dialog was cancelled by the user!"); 240 retVal = ExecutableDialogResults::CANCEL; 241 break; 242 243 default: 244 throw uno::RuntimeException(rtl::OUString::createFromAscii("The dialog returned with an unknown result!"), static_cast< XFilePicker* >( this )); 245 break; 246 } 247 248 DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal); 249 250 return retVal; 251 } 252 253 254 #pragma mark XFilePicker 255 //----------------------------------------------------------------------------------------- 256 // XFilePicker functions 257 //----------------------------------------------------------------------------------------- 258 259 void SAL_CALL SalAquaFilePicker::setMultiSelectionMode( sal_Bool bMode ) 260 { 261 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "multiSelectable?", bMode); 262 263 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 264 265 if (m_nDialogType == NAVIGATIONSERVICES_OPEN) { 266 [(NSOpenPanel*)m_pDialog setAllowsMultipleSelection:YES]; 267 OSL_TRACE("dialog allows multi-selection? %d", [(NSOpenPanel*)m_pDialog allowsMultipleSelection]); 268 } 269 270 DBG_PRINT_EXIT(CLASS_NAME, __func__); 271 } 272 273 void SAL_CALL SalAquaFilePicker::setDefaultName( const rtl::OUString& aName ) 274 { 275 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "name", aName); 276 277 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 278 279 m_sSaveFileName = aName; 280 281 DBG_PRINT_EXIT(CLASS_NAME, __func__); 282 } 283 284 void SAL_CALL SalAquaFilePicker::setDisplayDirectory( const rtl::OUString& rDirectory ) 285 { 286 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "directory", rDirectory); 287 288 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 289 290 implsetDisplayDirectory(rDirectory); 291 292 DBG_PRINT_EXIT(CLASS_NAME, __func__); 293 } 294 295 rtl::OUString SAL_CALL SalAquaFilePicker::getDisplayDirectory() 296 { 297 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 298 299 rtl::OUString retVal = implgetDisplayDirectory(); 300 301 DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal); 302 return retVal; 303 } 304 305 uno::Sequence<rtl::OUString> SAL_CALL SalAquaFilePicker::getFiles() 306 { 307 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 308 309 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 310 311 // OSL_TRACE("starting work"); 312 /* 313 * If more than one file is selected in an OpenDialog, then the first result 314 * is the directory and the remaining results contain just the files' names 315 * without the basedir path. 316 */ 317 NSArray *files = nil; 318 if (m_nDialogType == NAVIGATIONSERVICES_OPEN) { 319 files = [(NSOpenPanel*)m_pDialog URLs]; 320 } 321 else if (m_nDialogType == NAVIGATIONSERVICES_SAVE) { 322 files = [NSArray arrayWithObjects:[m_pDialog URL], nil]; 323 } 324 325 long nFiles = [files count]; 326 OSL_TRACE("# of items: %d", nFiles); 327 328 uno::Sequence< rtl::OUString > aSelectedFiles(nFiles > 1 ? nFiles + 1 : nFiles); 329 330 for(int nIndex = 0; nIndex < nFiles; nIndex += 1) 331 { 332 NSURL *url = [files objectAtIndex:nIndex]; 333 OSL_TRACE("handling %s", [[url description] UTF8String]); 334 InfoType info = FULLPATH; 335 if (nFiles > 1) { 336 //just get the file's name (only in OpenDialog) 337 info = FILENAME; 338 } 339 OUString sFileOrDirURL = [url OUStringForInfo:info]; 340 341 //get the directory information, only on the first file processed 342 if (nIndex == 0) { 343 OUString sDirectoryURL = [url OUStringForInfo:PATHWITHOUTLASTCOMPONENT]; 344 345 if (nFiles > 1) { 346 aSelectedFiles[0] = OUString(sDirectoryURL); 347 } 348 } 349 350 short nSequenceIndex = nFiles > 1 ? nIndex + 1 : nIndex; 351 aSelectedFiles[nSequenceIndex] = sFileOrDirURL; 352 353 OSL_TRACE("Returned file in getFiles: \"%s\".", OUStringToOString(sFileOrDirURL, RTL_TEXTENCODING_UTF8).getStr()); 354 } 355 356 DBG_PRINT_EXIT(CLASS_NAME, __func__); 357 return aSelectedFiles; 358 } 359 360 #pragma mark XFilterManager 361 //----------------------------------------------------------------------------------------- 362 // XFilterManager functions 363 //----------------------------------------------------------------------------------------- 364 365 void SAL_CALL SalAquaFilePicker::appendFilter( const rtl::OUString& aTitle, const rtl::OUString& aFilter ) 366 { 367 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 368 369 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 370 371 ensureFilterHelper(); 372 m_pFilterHelper->appendFilter( aTitle, aFilter ); 373 m_pControlHelper->setFilterControlNeeded(YES); 374 375 DBG_PRINT_EXIT(CLASS_NAME, __func__); 376 } 377 378 void SAL_CALL SalAquaFilePicker::setCurrentFilter( const rtl::OUString& aTitle ) 379 { 380 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 381 OSL_TRACE( "Setting current filter to %s", 382 OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ).getStr() ); 383 384 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 385 386 ensureFilterHelper(); 387 m_pFilterHelper->setCurrentFilter(aTitle); 388 updateFilterUI(); 389 390 updateSaveFileNameExtension(); 391 392 DBG_PRINT_EXIT(CLASS_NAME, __func__); 393 } 394 395 rtl::OUString SAL_CALL SalAquaFilePicker::getCurrentFilter() 396 { 397 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 398 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 399 400 ensureFilterHelper(); 401 402 DBG_PRINT_EXIT(CLASS_NAME, __func__); 403 return m_pFilterHelper->getCurrentFilter(); 404 } 405 406 #pragma mark XFilterGroupManager 407 //----------------------------------------------------------------------------------------- 408 // XFilterGroupManager functions 409 //----------------------------------------------------------------------------------------- 410 411 void SAL_CALL SalAquaFilePicker::appendFilterGroup( const rtl::OUString& sGroupTitle, const uno::Sequence<beans::StringPair>& aFilters ) 412 { 413 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 414 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 415 416 ensureFilterHelper(); 417 m_pFilterHelper->appendFilterGroup(sGroupTitle, aFilters); 418 m_pControlHelper->setFilterControlNeeded(YES); 419 DBG_PRINT_EXIT(CLASS_NAME, __func__); 420 } 421 422 #pragma mark XFilePickerControlAccess 423 //------------------------------------------------------------------------------------ 424 // XFilePickerControlAccess functions 425 //------------------------------------------------------------------------------------ 426 427 void SAL_CALL SalAquaFilePicker::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any& rValue ) 428 { 429 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 430 431 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 432 433 m_pControlHelper->setValue(nControlId, nControlAction, rValue); 434 435 if (nControlId == ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION && m_nDialogType == NAVIGATIONSERVICES_SAVE) { 436 updateSaveFileNameExtension(); 437 } 438 439 DBG_PRINT_EXIT(CLASS_NAME, __func__); 440 } 441 442 uno::Any SAL_CALL SalAquaFilePicker::getValue( sal_Int16 nControlId, sal_Int16 nControlAction ) 443 { 444 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 445 446 uno::Any aValue = m_pControlHelper->getValue(nControlId, nControlAction); 447 448 DBG_PRINT_EXIT(CLASS_NAME, __func__); 449 return aValue; 450 } 451 452 void SAL_CALL SalAquaFilePicker::enableControl( sal_Int16 nControlId, sal_Bool bEnable ) 453 { 454 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 455 456 m_pControlHelper->enableControl(nControlId, bEnable); 457 458 DBG_PRINT_EXIT(CLASS_NAME, __func__); 459 } 460 461 void SAL_CALL SalAquaFilePicker::setLabel( sal_Int16 nControlId, const ::rtl::OUString& aLabel ) 462 { 463 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 464 465 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 466 467 NSString* sLabel = [NSString stringWithOUString:aLabel]; 468 m_pControlHelper->setLabel( nControlId, sLabel ) ; 469 470 DBG_PRINT_EXIT(CLASS_NAME, __func__); 471 } 472 473 rtl::OUString SAL_CALL SalAquaFilePicker::getLabel( sal_Int16 nControlId ) 474 { 475 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 476 DBG_PRINT_EXIT(CLASS_NAME, __func__); 477 478 return m_pControlHelper->getLabel(nControlId); 479 } 480 481 #pragma mark XInitialization 482 //------------------------------------------------------------------------------------ 483 // XInitialization 484 //------------------------------------------------------------------------------------ 485 486 void SAL_CALL SalAquaFilePicker::initialize( const uno::Sequence<uno::Any>& aArguments ) 487 { 488 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "arguments size", aArguments.getLength()); 489 490 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 491 492 // parameter checking 493 uno::Any aAny; 494 if( 0 == aArguments.getLength() ) 495 throw lang::IllegalArgumentException(rtl::OUString::createFromAscii( "no arguments" ), 496 static_cast<XFilePicker*>( this ), 1 ); 497 498 aAny = aArguments[0]; 499 500 if( ( aAny.getValueType() != ::getCppuType( ( sal_Int16* )0 ) ) && 501 (aAny.getValueType() != ::getCppuType( ( sal_Int8* )0 ) ) ) 502 throw lang::IllegalArgumentException(rtl::OUString::createFromAscii( "invalid argument type" ), 503 static_cast<XFilePicker*>( this ), 1 ); 504 505 sal_Int16 templateId = -1; 506 aAny >>= templateId; 507 508 switch( templateId ) 509 { 510 case FILEOPEN_SIMPLE: 511 m_nDialogType = NAVIGATIONSERVICES_OPEN; 512 OSL_TRACE( "Template: FILEOPEN_SIMPLE" ); 513 break; 514 case FILESAVE_SIMPLE: 515 m_nDialogType = NAVIGATIONSERVICES_SAVE; 516 OSL_TRACE( "Template: FILESAVE_SIMPLE" ); 517 break; 518 case FILESAVE_AUTOEXTENSION_PASSWORD: 519 m_nDialogType = NAVIGATIONSERVICES_SAVE; 520 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_PASSWORD" ); 521 break; 522 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS: 523 m_nDialogType = NAVIGATIONSERVICES_SAVE; 524 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS" ); 525 break; 526 case FILESAVE_AUTOEXTENSION_SELECTION: 527 m_nDialogType = NAVIGATIONSERVICES_SAVE; 528 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_SELECTION" ); 529 break; 530 case FILESAVE_AUTOEXTENSION_TEMPLATE: 531 m_nDialogType = NAVIGATIONSERVICES_SAVE; 532 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_TEMPLATE" ); 533 break; 534 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE: 535 m_nDialogType = NAVIGATIONSERVICES_OPEN; 536 OSL_TRACE( "Template: FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE" ); 537 break; 538 case FILEOPEN_PLAY: 539 m_nDialogType = NAVIGATIONSERVICES_OPEN; 540 OSL_TRACE( "Template: FILEOPEN_PLAY" ); 541 break; 542 case FILEOPEN_READONLY_VERSION: 543 m_nDialogType = NAVIGATIONSERVICES_OPEN; 544 OSL_TRACE( "Template: FILEOPEN_READONLY_VERSION" ); 545 break; 546 case FILEOPEN_LINK_PREVIEW: 547 m_nDialogType = NAVIGATIONSERVICES_OPEN; 548 OSL_TRACE( "Template: FILEOPEN_LINK_PREVIEW" ); 549 break; 550 case FILESAVE_AUTOEXTENSION: 551 m_nDialogType = NAVIGATIONSERVICES_SAVE; 552 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION" ); 553 break; 554 default: 555 throw lang::IllegalArgumentException(rtl::OUString::createFromAscii( "Unknown template" ), 556 static_cast< XFilePicker* >( this ), 557 1 ); 558 } 559 560 m_pControlHelper->initialize(templateId); 561 562 implInitialize(); 563 564 DBG_PRINT_EXIT(CLASS_NAME, __func__); 565 } 566 567 #pragma mark XCancellable 568 //------------------------------------------------------------------------------------ 569 // XCancellable 570 //------------------------------------------------------------------------------------ 571 572 void SAL_CALL SalAquaFilePicker::cancel() 573 { 574 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 575 576 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 577 578 if (m_pDialog != nil) { 579 [m_pDialog cancel:nil]; 580 } 581 582 DBG_PRINT_EXIT(CLASS_NAME, __func__); 583 } 584 585 #pragma mark XEventListener 586 //------------------------------------------------ 587 // XEventListener 588 //------------------------------------------------ 589 590 void SAL_CALL SalAquaFilePicker::disposing( const lang::EventObject& aEvent ) 591 { 592 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 593 594 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 595 596 uno::Reference<XFilePickerListener> xFilePickerListener( aEvent.Source, ::com::sun::star::uno::UNO_QUERY ); 597 598 if( xFilePickerListener.is() ) 599 removeFilePickerListener( xFilePickerListener ); 600 601 DBG_PRINT_EXIT(CLASS_NAME, __func__); 602 } 603 604 #pragma mark XServiceInfo 605 // ------------------------------------------------- 606 // XServiceInfo 607 // ------------------------------------------------- 608 609 rtl::OUString SAL_CALL SalAquaFilePicker::getImplementationName() 610 { 611 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 612 613 rtl::OUString retVal = rtl::OUString::createFromAscii( FILE_PICKER_IMPL_NAME ); 614 615 DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal); 616 617 return retVal; 618 } 619 620 sal_Bool SAL_CALL SalAquaFilePicker::supportsService( const rtl::OUString& sServiceName ) 621 { 622 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "service name", sServiceName); 623 624 sal_Bool retVal = sal_False; 625 626 uno::Sequence <rtl::OUString> supportedServicesNames = FilePicker_getSupportedServiceNames(); 627 628 for( sal_Int32 n = supportedServicesNames.getLength(); n--; ) { 629 if( supportedServicesNames[n].compareTo( sServiceName ) == 0) { 630 retVal = sal_True; 631 break; 632 } 633 } 634 635 DBG_PRINT_EXIT(CLASS_NAME, __func__); 636 637 return retVal; 638 } 639 640 uno::Sequence<rtl::OUString> SAL_CALL SalAquaFilePicker::getSupportedServiceNames() 641 { 642 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 643 DBG_PRINT_EXIT(CLASS_NAME, __func__); 644 645 return FilePicker_getSupportedServiceNames(); 646 } 647 648 #pragma mark Misc/Private 649 //----------------------------------------------------------------------------------------- 650 // FilePicker Event functions 651 //----------------------------------------------------------------------------------------- 652 653 void SAL_CALL SalAquaFilePicker::fileSelectionChanged( FilePickerEvent aEvent ) 654 { 655 OSL_TRACE( "file selection changed"); 656 if (m_xListener.is()) 657 m_xListener->fileSelectionChanged( aEvent ); 658 } 659 660 void SAL_CALL SalAquaFilePicker::directoryChanged( FilePickerEvent aEvent ) 661 { 662 OSL_TRACE("directory changed"); 663 if (m_xListener.is()) 664 m_xListener->directoryChanged( aEvent ); 665 } 666 667 void SAL_CALL SalAquaFilePicker::controlStateChanged( FilePickerEvent aEvent ) 668 { 669 OSL_TRACE("control state changed"); 670 if (m_xListener.is()) 671 m_xListener->controlStateChanged( aEvent ); 672 } 673 674 void SAL_CALL SalAquaFilePicker::dialogSizeChanged() 675 { 676 OSL_TRACE("dialog size changed"); 677 if (m_xListener.is()) 678 m_xListener->dialogSizeChanged(); 679 } 680 681 //------------------------------------------------------------------------------------ 682 683 #define MAP_TOGGLE( elem ) \ 684 case ExtendedFilePickerElementIds::CHECKBOX_##elem: \ 685 pWidget = m_pToggles[elem]; \ 686 break 687 688 #define MAP_BUTTON( elem ) \ 689 case ExtendedFilePickerElementIds::PUSHBUTTON_##elem: \ 690 pWidget = m_pButtons[elem]; \ 691 break 692 #undef MAP_LIST 693 #define MAP_LIST( elem ) \ 694 case ExtendedFilePickerElementIds::LISTBOX_##elem: \ 695 pWidget = m_pListControls[elem]; if (isAList != NULL) *isAList = sal_True; \ 696 break 697 698 #define MAP_LIST_LABEL( elem ) \ 699 case ExtendedFilePickerElementIds::LISTBOX_##elem##_LABEL: \ 700 pWidget = m_pListControls[elem]; \ 701 break 702 703 //-------------------------------------------------- 704 // Misc 705 //------------------------------------------------- 706 void SalAquaFilePicker::ensureFilterHelper() { 707 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 708 709 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 710 711 if (NULL == m_pFilterHelper) { 712 m_pFilterHelper = new FilterHelper; 713 m_pControlHelper->setFilterHelper(m_pFilterHelper); 714 [m_pDelegate setFilterHelper:m_pFilterHelper]; 715 } 716 717 DBG_PRINT_EXIT(CLASS_NAME, __func__); 718 } 719 720 void SalAquaFilePicker::implInitialize() 721 { 722 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 723 724 //call super 725 SalAquaPicker::implInitialize(); 726 727 DBG_PRINT_EXIT(CLASS_NAME, __func__); 728 } 729 730 void SalAquaFilePicker::updateFilterUI() { 731 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 732 733 m_pControlHelper->updateFilterUI(); 734 735 DBG_PRINT_EXIT(CLASS_NAME, __func__); 736 } 737 738 void SalAquaFilePicker::updateSaveFileNameExtension() { 739 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 740 741 if (m_nDialogType != NAVIGATIONSERVICES_SAVE) { 742 return; 743 } 744 745 // we need to set this here again because initial setting does 746 //[m_pDialog setExtensionHidden:YES]; 747 748 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 749 750 if (m_pControlHelper->isAutoExtensionEnabled() == false) { 751 OSL_TRACE("allowing other file types"); 752 [m_pDialog setAllowedFileTypes:nil]; 753 [m_pDialog setAllowsOtherFileTypes:YES]; 754 } else { 755 ensureFilterHelper(); 756 757 OUStringList aStringList = m_pFilterHelper->getCurrentFilterSuffixList(); 758 if( aStringList.empty()) // #i9328# 759 return; 760 761 rtl::OUString suffix = (*(aStringList.begin())).copy(1); 762 NSString *requiredFileType = [NSString stringWithOUString:suffix]; 763 764 [m_pDialog setRequiredFileType:requiredFileType]; 765 766 OSL_TRACE("disallowing other file types"); 767 [m_pDialog setAllowsOtherFileTypes:NO]; 768 } 769 770 DBG_PRINT_EXIT(CLASS_NAME, __func__); 771 } 772 773 void SalAquaFilePicker::filterControlChanged() { 774 DBG_PRINT_ENTRY(CLASS_NAME, __func__); 775 776 if (m_pDialog == nil) { 777 return; 778 } 779 780 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 781 782 updateSaveFileNameExtension(); 783 784 [m_pDialog validateVisibleColumns]; 785 786 FilePickerEvent evt; 787 evt.ElementId = LISTBOX_FILTER; 788 controlStateChanged( evt ); 789 790 DBG_PRINT_EXIT(CLASS_NAME, __func__); 791 } 792