bump product version to 4.1.6.2
[LibreOffice.git] / fpicker / source / win32 / filepicker / FilePicker.cxx
blob8c98a07e15f3dad735b41b676e55a6bb9841e2a9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tchar.h>
21 #include <com/sun/star/lang/DisposedException.hpp>
22 #include <cppuhelper/interfacecontainer.h>
23 #include <osl/diagnose.h>
25 #include "FilePicker.hxx"
26 #include "WinFileOpenImpl.hxx"
28 #include "FPServiceInfo.hxx"
29 #include "../misc/WinImplHelper.hxx"
30 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
31 #include "filepickereventnotification.hxx"
33 #include <comphelper/sequenceasvector.hxx>
35 //------------------------------------------------------------------------
36 // namespace directives
37 //------------------------------------------------------------------------
39 using namespace com::sun::star;
41 using namespace ::com::sun::star::ui::dialogs;
42 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
44 #define FILE_PICKER_DLL_NAME TEXT("fps.dll")
46 //------------------------------------------------------------------------
47 // helper functions
48 //------------------------------------------------------------------------
50 namespace
52 // controling event notifications
53 const bool STARTUP_SUSPENDED = true;
54 const bool STARTUP_ALIVE = false;
56 uno::Sequence<OUString> SAL_CALL FilePicker_getSupportedServiceNames()
58 uno::Sequence<OUString> aRet(2);
59 aRet[0] = OUString("com.sun.star.ui.dialogs.FilePicker");
60 aRet[1] = OUString("com.sun.star.ui.dialogs.SystemFilePicker");
61 return aRet;
65 //-----------------------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------------------
69 CFilePicker::CFilePicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr) :
70 CFilePicker_Base(m_rbHelperMtx),
71 m_xServiceMgr(xServiceMgr),
72 m_aAsyncEventNotifier(rBHelper)
74 HINSTANCE hInstance = GetModuleHandle(FILE_PICKER_DLL_NAME);
75 OSL_POSTCOND( hInstance, "The name of the service dll must have changed" );
77 // create a default FileOpen dialog without any additional ui elements
78 m_pImpl = std::auto_ptr< CWinFileOpenImpl >(
79 new CWinFileOpenImpl(
80 this,
81 true,
84 hInstance ) );
87 //------------------------------------------------------------------------------------
88 // XFPEventListenerManager
89 //------------------------------------------------------------------------------------
91 void SAL_CALL CFilePicker::addFilePickerListener(const uno::Reference<XFilePickerListener>& xListener)
92 throw(uno::RuntimeException)
94 if ( rBHelper.bDisposed )
95 throw lang::DisposedException(
96 OUString( "object is already disposed" ),
97 static_cast< XFilePicker2* >( this ) );
99 if ( !rBHelper.bInDispose && !rBHelper.bDisposed )
100 rBHelper.aLC.addInterface( getCppuType( &xListener ), xListener );
103 //-----------------------------------------------------------------------------------------
105 //-----------------------------------------------------------------------------------------
107 void SAL_CALL CFilePicker::removeFilePickerListener(const uno::Reference<XFilePickerListener>& xListener )
108 throw(uno::RuntimeException)
110 if ( rBHelper.bDisposed )
111 throw lang::DisposedException(
112 OUString( "object is already disposed" ),
113 static_cast< XFilePicker2* >( this ) );
115 rBHelper.aLC.removeInterface( getCppuType( &xListener ), xListener );
118 // -------------------------------------------------
119 // XEventListener
120 // -------------------------------------------------
122 void SAL_CALL CFilePicker::disposing(const lang::EventObject& aEvent) throw(uno::RuntimeException)
124 uno::Reference<XFilePickerListener> xFilePickerListener(aEvent.Source, ::com::sun::star::uno::UNO_QUERY);
126 if (xFilePickerListener.is())
127 removeFilePickerListener(xFilePickerListener);
130 //-----------------------------------------------------------------------------------------
132 //-----------------------------------------------------------------------------------------
134 void SAL_CALL CFilePicker::fileSelectionChanged(FilePickerEvent aEvent)
136 aEvent.Source = uno::Reference<uno::XInterface>(static_cast<XFilePickerNotifier*>(this));
137 m_aAsyncEventNotifier.notifyEvent(
138 new CFilePickerParamEventNotification(&XFilePickerListener::fileSelectionChanged,aEvent));
141 //-----------------------------------------------------------------------------------------
143 //-----------------------------------------------------------------------------------------
145 void SAL_CALL CFilePicker::directoryChanged(FilePickerEvent aEvent)
147 aEvent.Source = uno::Reference<uno::XInterface>(static_cast<XFilePickerNotifier*>(this));
148 m_aAsyncEventNotifier.notifyEvent(
149 new CFilePickerParamEventNotification(&XFilePickerListener::directoryChanged,aEvent));
152 //-----------------------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------------------
156 void SAL_CALL CFilePicker::controlStateChanged(FilePickerEvent aEvent)
158 aEvent.Source = uno::Reference<uno::XInterface>(static_cast<XFilePickerNotifier*>(this));
159 m_aAsyncEventNotifier.notifyEvent(
160 new CFilePickerParamEventNotification(&XFilePickerListener::controlStateChanged,aEvent));
163 //-----------------------------------------------------------------------------------------
165 //-----------------------------------------------------------------------------------------
167 void SAL_CALL CFilePicker::dialogSizeChanged()
169 m_aAsyncEventNotifier.notifyEvent(
170 new CFilePickerEventNotification(&XFilePickerListener::dialogSizeChanged));
173 //-----------------------------------------------------------------------------------------
174 // If there are more then one listener the return value of the last one wins
175 //-----------------------------------------------------------------------------------------
177 OUString SAL_CALL CFilePicker::helpRequested(FilePickerEvent aEvent) const
179 OUString aHelpText;
181 ::cppu::OInterfaceContainerHelper* pICHelper =
182 rBHelper.getContainer( getCppuType((uno::Reference<XFilePickerListener>*)0));
184 if (pICHelper)
186 ::cppu::OInterfaceIteratorHelper iter(*pICHelper);
188 while(iter.hasMoreElements())
193 if there are multiple listeners responding
194 to this notification the next response
195 overwrittes the one before if it is not empty
198 OUString temp;
200 uno::Reference<XFilePickerListener> xFPListener(iter.next(), uno::UNO_QUERY);
201 if (xFPListener.is())
203 temp = xFPListener->helpRequested(aEvent);
204 if (temp.getLength())
205 aHelpText = temp;
209 catch(uno::RuntimeException&)
211 OSL_FAIL( "RuntimeException during event dispatching" );
216 return aHelpText;
219 //-------------------------------------
221 //-------------------------------------
223 bool CFilePicker::startupEventNotification(bool bStartupSuspended)
225 return m_aAsyncEventNotifier.startup(bStartupSuspended);
228 //-------------------------------------
230 //-------------------------------------
232 void CFilePicker::shutdownEventNotification()
234 m_aAsyncEventNotifier.shutdown();
237 //-------------------------------------
239 //-------------------------------------
241 void CFilePicker::suspendEventNotification()
243 m_aAsyncEventNotifier.suspend();
246 //-------------------------------------
248 //-------------------------------------
250 void CFilePicker::resumeEventNotification()
252 m_aAsyncEventNotifier.resume();
255 //------------------------------------------------------------------------------------
256 // XFilePicker functions
257 //------------------------------------------------------------------------------------
259 void SAL_CALL CFilePicker::setMultiSelectionMode(sal_Bool bMode) throw(uno::RuntimeException)
261 OSL_ASSERT(0 != m_pImpl.get());
262 osl::MutexGuard aGuard(m_aMutex);
263 m_pImpl->setMultiSelectionMode(bMode);
266 //-----------------------------------------------------------------------------------------
268 //-----------------------------------------------------------------------------------------
270 void SAL_CALL CFilePicker::setTitle(const OUString& aTitle) throw(uno::RuntimeException)
272 OSL_ASSERT(0 != m_pImpl.get());
273 osl::MutexGuard aGuard(m_aMutex);
274 m_pImpl->setTitle(aTitle);
277 //-----------------------------------------------------------------------------------------
279 //-----------------------------------------------------------------------------------------
281 void SAL_CALL CFilePicker::appendFilter(const OUString& aTitle, const OUString& aFilter)
282 throw(lang::IllegalArgumentException, uno::RuntimeException)
284 OSL_ASSERT(0 != m_pImpl.get());
285 osl::MutexGuard aGuard(m_aMutex);
286 m_pImpl->appendFilter(aTitle, aFilter);
289 //-----------------------------------------------------------------------------------------
291 //-----------------------------------------------------------------------------------------
293 void SAL_CALL CFilePicker::setCurrentFilter(const OUString& aTitle)
294 throw(lang::IllegalArgumentException, uno::RuntimeException)
296 OSL_ASSERT(0 != m_pImpl.get());
297 osl::MutexGuard aGuard(m_aMutex);
298 m_pImpl->setCurrentFilter(aTitle);
301 //-----------------------------------------------------------------------------------------
303 //-----------------------------------------------------------------------------------------
305 OUString SAL_CALL CFilePicker::getCurrentFilter() throw(uno::RuntimeException)
307 OSL_ASSERT(0 != m_pImpl.get());
308 osl::MutexGuard aGuard(m_aMutex);
309 return m_pImpl->getCurrentFilter();
312 //-----------------------------------------------------------------------------------------
314 //-----------------------------------------------------------------------------------------
316 void SAL_CALL CFilePicker::appendFilterGroup(const OUString& sGroupTitle, const uno::Sequence<beans::StringPair>& aFilters)
317 throw (lang::IllegalArgumentException, uno::RuntimeException)
319 OSL_ASSERT(0 != m_pImpl.get());
320 osl::MutexGuard aGuard(m_aMutex);
321 m_pImpl->appendFilterGroup(sGroupTitle, aFilters);
324 //-----------------------------------------------------------------------------------------
326 //-----------------------------------------------------------------------------------------
328 void SAL_CALL CFilePicker::setDefaultName(const OUString& aName)
329 throw(uno::RuntimeException)
331 OSL_ASSERT(0 != m_pImpl.get());
332 osl::MutexGuard aGuard(m_aMutex);
333 m_pImpl->setDefaultName(aName);
336 //-----------------------------------------------------------------------------------------
338 //-----------------------------------------------------------------------------------------
340 void SAL_CALL CFilePicker::setDisplayDirectory(const OUString& aDirectory)
341 throw(lang::IllegalArgumentException, uno::RuntimeException)
343 OSL_ASSERT(0 != m_pImpl.get());
344 osl::MutexGuard aGuard(m_aMutex);
345 m_pImpl->setDisplayDirectory(aDirectory);
348 //-----------------------------------------------------------------------------------------
350 //-----------------------------------------------------------------------------------------
352 OUString SAL_CALL CFilePicker::getDisplayDirectory() throw(uno::RuntimeException)
354 OSL_ASSERT(0 != m_pImpl.get());
355 osl::MutexGuard aGuard(m_aMutex);
356 return m_pImpl->getDisplayDirectory();
359 //-----------------------------------------------------------------------------------------
361 //-----------------------------------------------------------------------------------------
363 uno::Sequence<OUString> SAL_CALL CFilePicker::getFiles() throw(uno::RuntimeException)
365 OSL_ASSERT(0 != m_pImpl.get());
366 osl::MutexGuard aGuard(m_aMutex);
367 return m_pImpl->getFiles();
370 //-----------------------------------------------------------------------------------------
372 //-----------------------------------------------------------------------------------------
373 uno::Sequence< OUString > SAL_CALL CFilePicker::getSelectedFiles() throw (uno::RuntimeException)
375 OSL_ASSERT(0 != m_pImpl.get());
376 osl::MutexGuard aGuard(m_aMutex);
378 const uno::Sequence< OUString > lSource = m_pImpl->getFiles();
379 const ::sal_Int32 c = lSource.getLength();
380 if (c < 2)
381 return lSource;
383 const OUString sPath = lSource[0];
384 ::comphelper::SequenceAsVector< OUString > lTarget;
385 ::sal_Int32 i = 1;
386 for (i=1; i<c; ++i)
388 const OUString sFile = lSource[i];
389 if (sFile.indexOf ('/') > 0)
391 // a) file contains own path !
392 lTarget.push_back(sFile);
394 else
396 // b) file is relative to given path
397 OUStringBuffer sFull(256);
399 sFull.append (sPath);
400 sFull.appendAscii("/" );
401 sFull.append (sFile);
403 lTarget.push_back(sFull.makeStringAndClear());
407 return lTarget.getAsConstList();
410 //-----------------------------------------------------------------------------------------
412 //-----------------------------------------------------------------------------------------
414 sal_Int16 SAL_CALL CFilePicker::execute() throw(uno::RuntimeException)
416 OSL_ASSERT(0 != m_pImpl.get());
418 sal_Int16 ret;
420 if (startupEventNotification(STARTUP_SUSPENDED))
422 // we should not block in this call else
423 // in the case of an event the client can't
424 // call another function an we run into a
425 // deadlock !!!!!
426 ret = m_pImpl->execute( );
428 shutdownEventNotification();
430 else
432 OSL_FAIL("Could not start event notifier thread!");
434 throw uno::RuntimeException(
435 OUString("Error executing dialog"),
436 static_cast<XFilePicker2*>(this));
439 return ret;
442 //------------------------------------------------------------------------------------
443 // XFilePicker functions
444 //------------------------------------------------------------------------------------
446 void SAL_CALL CFilePicker::setValue(sal_Int16 aControlId, sal_Int16 aControlAction, const uno::Any& aValue)
447 throw(uno::RuntimeException)
449 OSL_ASSERT(0 != m_pImpl.get());
451 osl::MutexGuard aGuard(m_aMutex);
452 m_pImpl->setValue(aControlId, aControlAction, aValue);
455 //-----------------------------------------------------------------------------------------
457 //-----------------------------------------------------------------------------------------
459 uno::Any SAL_CALL CFilePicker::getValue(sal_Int16 aControlId, sal_Int16 aControlAction)
460 throw(uno::RuntimeException)
462 OSL_ASSERT(0 != m_pImpl.get());
464 osl::MutexGuard aGuard(m_aMutex);
465 return m_pImpl->getValue(aControlId, aControlAction);
468 //-----------------------------------------------------------------------------------------
470 //-----------------------------------------------------------------------------------------
472 void SAL_CALL CFilePicker::enableControl(sal_Int16 aControlId, sal_Bool bEnable)
473 throw(uno::RuntimeException)
475 OSL_ASSERT( 0 != m_pImpl.get( ) );
477 osl::MutexGuard aGuard( m_aMutex );
478 m_pImpl->enableControl( aControlId, bEnable );
481 //-----------------------------------------------------------------------------------------
483 //-----------------------------------------------------------------------------------------
485 void SAL_CALL CFilePicker::setLabel(sal_Int16 aControlId, const OUString& aLabel)
486 throw (uno::RuntimeException)
488 OSL_ASSERT(0 != m_pImpl.get());
490 osl::MutexGuard aGuard(m_aMutex);
491 m_pImpl->setLabel(aControlId, aLabel);
494 //-----------------------------------------------------------------------------------------
496 //-----------------------------------------------------------------------------------------
498 OUString SAL_CALL CFilePicker::getLabel(sal_Int16 aControlId)
499 throw (uno::RuntimeException)
501 OSL_ASSERT(0 != m_pImpl.get());
503 osl::MutexGuard aGuard(m_aMutex);
504 return m_pImpl->getLabel(aControlId);
507 //------------------------------------------------------------------------------------
509 //------------------------------------------------------------------------------------
511 uno::Sequence<sal_Int16> SAL_CALL CFilePicker::getSupportedImageFormats() throw (uno::RuntimeException)
513 OSL_ASSERT(0 != m_pImpl.get());
515 osl::MutexGuard aGuard(m_aMutex);
516 return m_pImpl->getSupportedImageFormats();
519 //------------------------------------------------------------------------------------
521 //------------------------------------------------------------------------------------
523 sal_Int32 SAL_CALL CFilePicker::getTargetColorDepth() throw (uno::RuntimeException)
525 OSL_ASSERT(0 != m_pImpl.get());
527 osl::MutexGuard aGuard(m_aMutex);
528 return m_pImpl->getTargetColorDepth();
531 //------------------------------------------------------------------------------------
533 //------------------------------------------------------------------------------------
535 sal_Int32 SAL_CALL CFilePicker::getAvailableWidth() throw (uno::RuntimeException)
537 OSL_ASSERT(0 != m_pImpl.get());
539 osl::MutexGuard aGuard(m_aMutex);
540 return m_pImpl->getAvailableWidth();
543 //------------------------------------------------------------------------------------
545 //------------------------------------------------------------------------------------
547 sal_Int32 SAL_CALL CFilePicker::getAvailableHeight() throw (uno::RuntimeException)
549 OSL_ASSERT(0 != m_pImpl.get());
551 osl::MutexGuard aGuard(m_aMutex);
552 return m_pImpl->getAvailableHeight();
555 //------------------------------------------------------------------------------------
557 //------------------------------------------------------------------------------------
559 void SAL_CALL CFilePicker::setImage(sal_Int16 aImageFormat, const uno::Any& aImage)
560 throw (lang::IllegalArgumentException, uno::RuntimeException)
562 OSL_ASSERT(0 != m_pImpl.get());
564 osl::MutexGuard aGuard(m_aMutex);
565 m_pImpl->setImage(aImageFormat, aImage);
568 //------------------------------------------------------------------------------------
570 //------------------------------------------------------------------------------------
572 sal_Bool SAL_CALL CFilePicker::setShowState(sal_Bool bShowState) throw (uno::RuntimeException)
574 OSL_ASSERT(0 != m_pImpl.get());
576 osl::MutexGuard aGuard(m_aMutex);
577 return m_pImpl->setShowState(bShowState);
580 //------------------------------------------------------------------------------------
582 //------------------------------------------------------------------------------------
584 sal_Bool SAL_CALL CFilePicker::getShowState() throw (uno::RuntimeException)
586 OSL_ASSERT(0 != m_pImpl.get());
588 osl::MutexGuard aGuard(m_aMutex);
589 return m_pImpl->getShowState();
592 //------------------------------------------------------------------------------------
594 //------------------------------------------------------------------------------------
596 void SAL_CALL CFilePicker::initialize(const uno::Sequence<uno::Any>& aArguments)
597 throw( uno::Exception, uno::RuntimeException)
599 // parameter checking
600 uno::Any aAny;
601 if ( 0 == aArguments.getLength( ) )
602 throw lang::IllegalArgumentException(
603 OUString( "no arguments" ),
604 static_cast<XFilePicker2*>(this), 1);
606 aAny = aArguments[0];
608 if ( (aAny.getValueType() != ::getCppuType((sal_Int16*)0)) &&
609 (aAny.getValueType() != ::getCppuType((sal_Int8*)0)) )
610 throw lang::IllegalArgumentException(
611 OUString("invalid argument type"),
612 static_cast<XFilePicker2*>(this), 1);
614 sal_Int16 templateId = -1;
615 aAny >>= templateId;
617 sal_Bool bFileOpenDialog = sal_True;
618 sal_uInt32 winResTemplateId = 0;
620 switch ( templateId )
622 case FILEOPEN_SIMPLE:
623 bFileOpenDialog = sal_True;
624 break;
626 case FILESAVE_SIMPLE:
627 bFileOpenDialog = sal_False;
628 break;
630 case FILESAVE_AUTOEXTENSION_PASSWORD:
631 bFileOpenDialog = sal_False;
632 winResTemplateId = TMPL2000_FILESAVE_AUTOEXT_PASSWORD_BOX_ID;
633 break;
635 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
636 bFileOpenDialog = sal_False;
637 winResTemplateId = TMPL2000_AUTOEXT_PASSWORD_FILTEROPTION_BOX;
638 break;
640 case FILESAVE_AUTOEXTENSION_SELECTION:
641 bFileOpenDialog = sal_False;
642 winResTemplateId = TMPL2000_AUTOEXT_SELECTION_BOX;
643 break;
645 case FILESAVE_AUTOEXTENSION_TEMPLATE:
646 bFileOpenDialog = sal_False;
647 winResTemplateId = TMPL2000_FILEOPEN_AUTOEXT_TEMPLATE_BOX_ID;
648 break;
650 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
651 winResTemplateId = TMPL2000_FILEOPEN_LINK_PREVIEW_BOX_ID;
652 break;
654 case FILEOPEN_PLAY:
655 winResTemplateId = TMPL2000_PLAY_PUSHBUTTON;
656 break;
658 case FILEOPEN_READONLY_VERSION:
659 winResTemplateId = TMPL2000_FILEOPEN_READONLY_VERSION_BOX_ID;
660 break;
662 case FILEOPEN_LINK_PREVIEW:
663 winResTemplateId = TMPL2000_FILEOPEN_LINK_PREVIEW_BOX_SIMPLE_ID;
664 break;
666 case FILESAVE_AUTOEXTENSION:
667 bFileOpenDialog = sal_False;
668 winResTemplateId = TMPL2000_FILESAVE_AUTOEXT;
669 break;
671 default:
672 throw lang::IllegalArgumentException(
673 OUString( "Unknown template" ),
674 static_cast< XFilePicker2* >( this ),
675 1 );
678 HINSTANCE hInstance = GetModuleHandle( FILE_PICKER_DLL_NAME );
679 OSL_POSTCOND( hInstance, "The name of the service dll must have changed" );
681 // create a new impl-class here based on the
682 // given string, if the given string is empty
683 // we do nothing
684 m_pImpl = std::auto_ptr< CWinFileOpenImpl >(
685 new CWinFileOpenImpl(
686 this,
687 bFileOpenDialog,
689 winResTemplateId,
690 hInstance ) );
693 //------------------------------------------------------------------------------------
695 //------------------------------------------------------------------------------------
697 void SAL_CALL CFilePicker::cancel()
698 throw(uno::RuntimeException)
700 OSL_ASSERT(m_pImpl.get());
702 osl::MutexGuard aGuard(m_aMutex);
703 m_pImpl->cancel();
706 // -------------------------------------------------
707 // XServiceInfo
708 // -------------------------------------------------
710 OUString SAL_CALL CFilePicker::getImplementationName()
711 throw(uno::RuntimeException)
713 return OUString(RTL_CONSTASCII_USTRINGPARAM(FILE_PICKER_IMPL_NAME));
716 // -------------------------------------------------
717 // XServiceInfo
718 // -------------------------------------------------
720 sal_Bool SAL_CALL CFilePicker::supportsService(const OUString& ServiceName)
721 throw(uno::RuntimeException )
723 uno::Sequence <OUString> SupportedServicesNames = FilePicker_getSupportedServiceNames();
725 for (sal_Int32 n = SupportedServicesNames.getLength(); n--;)
726 if (SupportedServicesNames[n] == ServiceName)
727 return sal_True;
729 return sal_False;
732 // -------------------------------------------------
733 // XServiceInfo
734 // -------------------------------------------------
736 uno::Sequence<OUString> SAL_CALL CFilePicker::getSupportedServiceNames()
737 throw(uno::RuntimeException)
739 return FilePicker_getSupportedServiceNames();
742 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */