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