1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_fpicker.hxx"
31 //------------------------------------------------------------------------
33 //------------------------------------------------------------------------
35 #include "VistaFilePickerEventHandler.hxx"
36 #include "asyncrequests.hxx"
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/embed/XStorage.hpp>
40 #include <com/sun/star/document/XDocumentRevisionListPersistence.hpp>
41 #include <com/sun/star/util/RevisionTag.hpp>
42 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
43 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
45 #include <comphelper/processfactory.hxx>
46 #include <comphelper/storagehelper.hxx>
47 //#include <tools/urlobj.hxx>
48 //#include <unotools/ucbhelper.hxx>
50 #include <osl/file.hxx>
52 //------------------------------------------------------------------------
53 // namespace directives
54 //------------------------------------------------------------------------
56 namespace css
= ::com::sun::star
;
62 //------------------------------------------------------------------------
64 //------------------------------------------------------------------------
66 //-----------------------------------------------------------------------------------------
67 VistaFilePickerEventHandler::VistaFilePickerEventHandler(IVistaFilePickerInternalNotify
* pInternalNotify
)
69 , m_nListenerHandle (0 )
71 , m_lListener (m_aMutex
)
72 , m_pInternalNotify (pInternalNotify
)
76 //-----------------------------------------------------------------------------------------
77 VistaFilePickerEventHandler::~VistaFilePickerEventHandler()
81 //-----------------------------------------------------------------------------------------
82 HRESULT STDMETHODCALLTYPE
VistaFilePickerEventHandler::QueryInterface(REFIID rIID
,
87 if ( rIID
== IID_IUnknown
)
88 *ppObject
= (IUnknown
*)(IFileDialogEvents
*)this;
90 if ( rIID
== IID_IFileDialogEvents
)
91 *ppObject
= (IFileDialogEvents
*)this;
93 if ( rIID
== IID_IFileDialogControlEvents
)
94 *ppObject
= (IFileDialogControlEvents
*)this;
96 if ( *ppObject
!= NULL
)
98 ((IUnknown
*)*ppObject
)->AddRef();
102 return E_NOINTERFACE
;
105 //-----------------------------------------------------------------------------------------
106 ULONG STDMETHODCALLTYPE
VistaFilePickerEventHandler::AddRef()
108 return osl_incrementInterlockedCount(&m_nRefCount
);
111 //-----------------------------------------------------------------------------------------
112 ULONG STDMETHODCALLTYPE
VistaFilePickerEventHandler::Release()
114 ULONG nReturn
= --m_nRefCount
;
115 if ( m_nRefCount
== 0 )
121 //-----------------------------------------------------------------------------------------
122 STDMETHODIMP
VistaFilePickerEventHandler::OnFileOk(IFileDialog
* /*pDialog*/)
127 //-----------------------------------------------------------------------------------------
128 STDMETHODIMP
VistaFilePickerEventHandler::OnFolderChanging(IFileDialog
* /*pDialog*/,
129 IShellItem
* /*pFolder*/)
134 //-----------------------------------------------------------------------------------------
135 STDMETHODIMP
VistaFilePickerEventHandler::OnFolderChange(IFileDialog
* /*pDialog*/)
137 impl_sendEvent(E_DIRECTORY_CHANGED
, 0);
141 //-----------------------------------------------------------------------------
142 ::rtl::OUString
lcl_getURLFromShellItem2 (IShellItem
* pItem
)
144 LPOLESTR pStr
= NULL
;
145 ::rtl::OUString sURL
;
147 SIGDN eConversion
= SIGDN_FILESYSPATH
;
148 HRESULT hr
= pItem
->GetDisplayName ( eConversion
, &pStr
);
152 eConversion
= SIGDN_URL
;
153 hr
= pItem
->GetDisplayName ( eConversion
, &pStr
);
156 return ::rtl::OUString();
158 sURL
= ::rtl::OUString(reinterpret_cast<sal_Unicode
*>(pStr
));
162 ::osl::FileBase::getFileURLFromSystemPath( reinterpret_cast<sal_Unicode
*>(pStr
), sURL
);
165 CoTaskMemFree (pStr
);
169 //-----------------------------------------------------------------------------------------
170 void lcl_updateVersionListDirectly(IFileDialog
* pDialog
)
172 static const ::rtl::OUString SERVICENAME_REVISIONPERSISTENCE
= ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence");
173 static const ::sal_Int16 CONTROL_VERSIONLIST
= css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION
;
175 TFileDialog
iDialog (pDialog
);
176 TFileOpenDialog iOpen
;
177 TFileDialogCustomize iCustomize
;
180 iDialog
->QueryInterface(IID_IFileOpenDialog
, (void**)(&iOpen
));
181 iDialog
->QueryInterface(IID_IFileDialogCustomize
, (void**)(&iCustomize
));
183 iDialog
.query(&iOpen
);
184 iDialog
.query(&iCustomize
);
187 // make sure version list match to the current selection always ...
188 // at least an empty version list will be better then the wrong one .-)
189 iCustomize
->RemoveAllControlItems(CONTROL_VERSIONLIST
);
191 HRESULT hResult
= E_FAIL
;
192 ComPtr
< IShellItemArray
> iItems
;
193 ComPtr
< IShellItem
> iItem
;
197 hResult
= iOpen
->GetSelectedItems(&iItems
);
202 hResult
= iItems
->GetCount(&nCount
);
203 if ( FAILED(hResult
) )
206 // we can show one version list only within control
210 hResult
= iItems
->GetItemAt(0, &iItem
);
214 hResult
= iDialog
->GetCurrentSelection(&iItem
);
216 if ( FAILED(hResult
) )
219 const ::rtl::OUString sURL
= lcl_getURLFromShellItem2(iItem
);
220 if (sURL
.getLength() < 1)
223 INetURLObject aURL(sURL);
224 if (aURL.GetProtocol() != INET_PROT_FILE)
227 ::rtl::OUString sMain = aURL.GetMainURL(INetURLObject::NO_DECODE);
228 if ( ! ::utl::UCBContentHelper::IsDocument(sURL))
233 css::uno::Reference
< css::embed::XStorage
> xStorage
= ::comphelper::OStorageHelper::GetStorageFromURL(sURL
, css::embed::ElementModes::READ
);
234 if ( ! xStorage
.is() )
237 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= ::comphelper::getProcessServiceFactory();
238 css::uno::Reference
< css::document::XDocumentRevisionListPersistence
> xReader (xSMGR
->createInstance(SERVICENAME_REVISIONPERSISTENCE
), css::uno::UNO_QUERY_THROW
);
239 css::uno::Sequence
< css::util::RevisionTag
> lVersions
= xReader
->load(xStorage
);
241 for (::sal_Int32 i
=0; i
<lVersions
.getLength(); ++i
)
243 const css::util::RevisionTag
& aTag
= lVersions
[i
];
244 iCustomize
->AddControlItem(CONTROL_VERSIONLIST
, i
, reinterpret_cast<LPCTSTR
>(aTag
.Identifier
.getStr()));
246 iCustomize
->SetSelectedControlItem(CONTROL_VERSIONLIST
, 0);
248 catch(const css::uno::Exception
&)
252 //-----------------------------------------------------------------------------------------
253 STDMETHODIMP
VistaFilePickerEventHandler::OnSelectionChange(IFileDialog
* /*pDialog*/)
255 impl_sendEvent(E_FILE_SELECTION_CHANGED
, 0);
256 //lcl_updateVersionListDirectly(pDialog);
260 //-----------------------------------------------------------------------------------------
261 STDMETHODIMP
VistaFilePickerEventHandler::OnShareViolation(IFileDialog
* /*pDialog*/ ,
263 IShellItem
* /*pItem*/ ,
265 FDE_SHAREVIOLATION_RESPONSE
* /*pResponse*/)
267 impl_sendEvent(E_CONTROL_STATE_CHANGED
, css::ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER
);
271 //-----------------------------------------------------------------------------------------
272 STDMETHODIMP
VistaFilePickerEventHandler::OnTypeChange(IFileDialog
* /*pDialog*/)
275 IFileDialogCustomize *iCustomize;
276 pDialog->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustomize));
279 HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
285 pDialog->GetFileTypeIndex( &nIndex );
287 LPCWSTR lpFilterExt = lFilters[nIndex].pszSpec;
289 lpFilterExt = wcschr( lpFilterExt, '.' );
292 pDialog->SetDefaultExtension( lpFilterExt );
298 impl_sendEvent(E_CONTROL_STATE_CHANGED
, css::ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER
);
303 //-----------------------------------------------------------------------------------------
304 STDMETHODIMP
VistaFilePickerEventHandler::OnOverwrite(IFileDialog
* /*pDialog*/ ,
305 IShellItem
* /*pItem*/ ,
306 FDE_OVERWRITE_RESPONSE
* /*pResponse*/)
311 //-----------------------------------------------------------------------------------------
312 STDMETHODIMP
VistaFilePickerEventHandler::OnItemSelected(IFileDialogCustomize
* /*pCustomize*/,
319 impl_sendEvent(E_CONTROL_STATE_CHANGED
, static_cast<sal_Int16
>( nIDCtl
));
323 //-----------------------------------------------------------------------------------------
324 STDMETHODIMP
VistaFilePickerEventHandler::OnButtonClicked(IFileDialogCustomize
* /*pCustomize*/,
328 impl_sendEvent(E_CONTROL_STATE_CHANGED
, static_cast<sal_Int16
>( nIDCtl
));
332 //-----------------------------------------------------------------------------------------
333 STDMETHODIMP
VistaFilePickerEventHandler::OnCheckButtonToggled(IFileDialogCustomize
* /*pCustomize*/,
338 if (nIDCtl == css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION)
340 LPCWSTR lpFilterExt = 0;
346 m_pDialog->GetFileTypeIndex( &nIndex );
347 lpFilterExt = lFilters[nIndex].pszSpec;
348 lpFilterExt = wcschr( lpFilterExt, '.' );
355 m_pDialog->SetDefaultExtension( lpFilterExt );
359 if (nIDCtl
== css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION
)
360 m_pInternalNotify
->onAutoExtensionChanged(bChecked
);
363 impl_sendEvent(E_CONTROL_STATE_CHANGED
, static_cast<sal_Int16
>( nIDCtl
));
368 //-----------------------------------------------------------------------------------------
369 STDMETHODIMP
VistaFilePickerEventHandler::OnControlActivating(IFileDialogCustomize
* /*pCustomize*/,
372 impl_sendEvent(E_CONTROL_STATE_CHANGED
, static_cast<sal_Int16
>( nIDCtl
));
376 //-----------------------------------------------------------------------------------------
377 void SAL_CALL
VistaFilePickerEventHandler::addFilePickerListener( const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>& xListener
)
378 throw( css::uno::RuntimeException
)
380 m_lListener
.addInterface(::getCppuType( (const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>*)NULL
), xListener
);
383 //-----------------------------------------------------------------------------------------
384 void SAL_CALL
VistaFilePickerEventHandler::removeFilePickerListener( const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>& xListener
)
385 throw( css::uno::RuntimeException
)
387 m_lListener
.removeInterface(::getCppuType( (const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>*)NULL
), xListener
);
390 //-----------------------------------------------------------------------------------------
391 void VistaFilePickerEventHandler::startListening( const TFileDialog
& pBroadcaster
)
393 static const sal_Bool STARTUP_SUSPENDED
= sal_True
;
394 static const sal_Bool STARTUP_WORKING
= sal_False
;
399 m_pDialog
= pBroadcaster
;
400 m_pDialog
->Advise(this, &m_nListenerHandle
);
403 //-----------------------------------------------------------------------------------------
404 void VistaFilePickerEventHandler::stopListening()
408 m_pDialog
->Unadvise(m_nListenerHandle
);
413 static const ::rtl::OUString PROP_CONTROL_ID
= ::rtl::OUString::createFromAscii("control_id");
414 static const ::rtl::OUString PROP_PICKER_LISTENER
= ::rtl::OUString::createFromAscii("picker_listener");
416 //-----------------------------------------------------------------------------------------
417 class AsyncPickerEvents
: public RequestHandler
424 virtual ~AsyncPickerEvents()
427 virtual void before()
430 virtual void doRequest(const RequestRef
& rRequest
)
432 const ::sal_Int32 nEventID
= rRequest
->getRequest();
433 const ::sal_Int16 nControlID
= rRequest
->getArgumentOrDefault(PROP_CONTROL_ID
, (::sal_Int16
)0);
434 const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
> xListener
= rRequest
->getArgumentOrDefault(PROP_PICKER_LISTENER
, css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>());
436 if ( ! xListener
.is())
439 css::ui::dialogs::FilePickerEvent aEvent
;
440 aEvent
.ElementId
= nControlID
;
444 case VistaFilePickerEventHandler::E_FILE_SELECTION_CHANGED
:
445 xListener
->fileSelectionChanged(aEvent
);
448 case VistaFilePickerEventHandler::E_DIRECTORY_CHANGED
:
449 xListener
->directoryChanged(aEvent
);
452 case VistaFilePickerEventHandler::E_HELP_REQUESTED
:
453 xListener
->helpRequested(aEvent
);
456 case VistaFilePickerEventHandler::E_CONTROL_STATE_CHANGED
:
457 xListener
->controlStateChanged(aEvent
);
460 case VistaFilePickerEventHandler::E_DIALOG_SIZE_CHANGED
:
461 xListener
->dialogSizeChanged();
464 // no default here. Let compiler detect changes on enum set !
472 //-----------------------------------------------------------------------------------------
473 void VistaFilePickerEventHandler::impl_sendEvent( EEventType eEventType
,
474 ::sal_Int16 nControlID
)
476 static AsyncRequests
aNotify(RequestHandlerRef(new AsyncPickerEvents()));
478 ::cppu::OInterfaceContainerHelper
* pContainer
= m_lListener
.getContainer( ::getCppuType( ( const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>*) NULL
) );
482 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
483 while (pIterator
.hasMoreElements())
487 css::uno::Reference
< css::ui::dialogs::XFilePickerListener
> xListener (pIterator
.next(), css::uno::UNO_QUERY
);
489 RequestRef
rRequest(new Request());
490 rRequest
->setRequest (eEventType
);
491 rRequest
->setArgument(PROP_PICKER_LISTENER
, xListener
);
493 rRequest
->setArgument(PROP_CONTROL_ID
, nControlID
);
495 aNotify
.triggerRequestDirectly(rRequest
);
496 //aNotify.triggerRequestNonBlocked(rRequest);
498 catch(const css::uno::RuntimeException
&)
507 } // namespace fpicker