1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: VistaFilePickerEventHandler.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_fpicker.hxx"
34 //------------------------------------------------------------------------
36 //------------------------------------------------------------------------
38 #include "VistaFilePickerEventHandler.hxx"
39 #include "asyncrequests.hxx"
41 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
42 #include <com/sun/star/embed/XStorage.hpp>
43 #include <com/sun/star/document/XDocumentRevisionListPersistence.hpp>
44 #include <com/sun/star/util/RevisionTag.hpp>
45 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
46 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
48 #include <comphelper/processfactory.hxx>
49 #include <comphelper/storagehelper.hxx>
50 //#include <tools/urlobj.hxx>
51 //#include <unotools/ucbhelper.hxx>
53 #include <osl/file.hxx>
55 //------------------------------------------------------------------------
56 // namespace directives
57 //------------------------------------------------------------------------
59 namespace css
= ::com::sun::star
;
65 //------------------------------------------------------------------------
67 //------------------------------------------------------------------------
69 //-----------------------------------------------------------------------------------------
70 VistaFilePickerEventHandler::VistaFilePickerEventHandler(IVistaFilePickerInternalNotify
* pInternalNotify
)
72 , m_nListenerHandle (0 )
74 , m_lListener (m_aMutex
)
75 , m_pInternalNotify (pInternalNotify
)
79 //-----------------------------------------------------------------------------------------
80 VistaFilePickerEventHandler::~VistaFilePickerEventHandler()
84 //-----------------------------------------------------------------------------------------
85 HRESULT STDMETHODCALLTYPE
VistaFilePickerEventHandler::QueryInterface(REFIID rIID
,
90 if ( rIID
== IID_IUnknown
)
91 *ppObject
= (IUnknown
*)(IFileDialogEvents
*)this;
93 if ( rIID
== IID_IFileDialogEvents
)
94 *ppObject
= (IFileDialogEvents
*)this;
96 if ( rIID
== IID_IFileDialogControlEvents
)
97 *ppObject
= (IFileDialogControlEvents
*)this;
99 if ( *ppObject
!= NULL
)
101 ((IUnknown
*)*ppObject
)->AddRef();
105 return E_NOINTERFACE
;
108 //-----------------------------------------------------------------------------------------
109 ULONG STDMETHODCALLTYPE
VistaFilePickerEventHandler::AddRef()
111 return osl_incrementInterlockedCount(&m_nRefCount
);
114 //-----------------------------------------------------------------------------------------
115 ULONG STDMETHODCALLTYPE
VistaFilePickerEventHandler::Release()
117 ULONG nReturn
= --m_nRefCount
;
118 if ( m_nRefCount
== 0 )
124 //-----------------------------------------------------------------------------------------
125 STDMETHODIMP
VistaFilePickerEventHandler::OnFileOk(IFileDialog
* /*pDialog*/)
130 //-----------------------------------------------------------------------------------------
131 STDMETHODIMP
VistaFilePickerEventHandler::OnFolderChanging(IFileDialog
* pDialog
,
137 //-----------------------------------------------------------------------------------------
138 STDMETHODIMP
VistaFilePickerEventHandler::OnFolderChange(IFileDialog
* pDialog
)
140 impl_sendEvent(E_DIRECTORY_CHANGED
, 0);
144 //-----------------------------------------------------------------------------
145 ::rtl::OUString
lcl_getURLFromShellItem2 (IShellItem
* pItem
)
147 LPOLESTR pStr
= NULL
;
148 ::rtl::OUString sURL
;
150 SIGDN eConversion
= SIGDN_FILESYSPATH
;
151 HRESULT hr
= pItem
->GetDisplayName ( eConversion
, &pStr
);
155 eConversion
= SIGDN_URL
;
156 hr
= pItem
->GetDisplayName ( eConversion
, &pStr
);
159 return ::rtl::OUString();
161 sURL
= ::rtl::OUString(reinterpret_cast<sal_Unicode
*>(pStr
));
165 ::osl::FileBase::getFileURLFromSystemPath( reinterpret_cast<sal_Unicode
*>(pStr
), sURL
);
168 CoTaskMemFree (pStr
);
172 //-----------------------------------------------------------------------------------------
173 void lcl_updateVersionListDirectly(IFileDialog
* pDialog
)
175 static const ::rtl::OUString SERVICENAME_REVISIONPERSISTENCE
= ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence");
176 static const ::sal_Int16 CONTROL_VERSIONLIST
= css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION
;
178 TFileDialog
iDialog (pDialog
);
179 TFileOpenDialog iOpen
;
180 TFileDialogCustomize iCustomize
;
183 iDialog
->QueryInterface(IID_IFileOpenDialog
, (void**)(&iOpen
));
184 iDialog
->QueryInterface(IID_IFileDialogCustomize
, (void**)(&iCustomize
));
186 iDialog
.query(&iOpen
);
187 iDialog
.query(&iCustomize
);
190 // make sure version list match to the current selection always ...
191 // at least an empty version list will be better then the wrong one .-)
192 iCustomize
->RemoveAllControlItems(CONTROL_VERSIONLIST
);
194 HRESULT hResult
= E_FAIL
;
195 ComPtr
< IShellItemArray
> iItems
;
196 ComPtr
< IShellItem
> iItem
;
200 hResult
= iOpen
->GetSelectedItems(&iItems
);
205 hResult
= iItems
->GetCount(&nCount
);
206 if ( FAILED(hResult
) )
209 // we can show one version list only within control
213 hResult
= iItems
->GetItemAt(0, &iItem
);
217 hResult
= iDialog
->GetCurrentSelection(&iItem
);
219 if ( FAILED(hResult
) )
222 const ::rtl::OUString sURL
= lcl_getURLFromShellItem2(iItem
);
223 if (sURL
.getLength() < 1)
226 INetURLObject aURL(sURL);
227 if (aURL.GetProtocol() != INET_PROT_FILE)
230 ::rtl::OUString sMain = aURL.GetMainURL(INetURLObject::NO_DECODE);
231 if ( ! ::utl::UCBContentHelper::IsDocument(sURL))
236 css::uno::Reference
< css::embed::XStorage
> xStorage
= ::comphelper::OStorageHelper::GetStorageFromURL(sURL
, css::embed::ElementModes::READ
);
237 if ( ! xStorage
.is() )
240 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= ::comphelper::getProcessServiceFactory();
241 css::uno::Reference
< css::document::XDocumentRevisionListPersistence
> xReader (xSMGR
->createInstance(SERVICENAME_REVISIONPERSISTENCE
), css::uno::UNO_QUERY_THROW
);
242 css::uno::Sequence
< css::util::RevisionTag
> lVersions
= xReader
->load(xStorage
);
244 for (::sal_Int32 i
=0; i
<lVersions
.getLength(); ++i
)
246 const css::util::RevisionTag
& aTag
= lVersions
[i
];
247 iCustomize
->AddControlItem(CONTROL_VERSIONLIST
, i
, reinterpret_cast<LPCTSTR
>(aTag
.Identifier
.getStr()));
249 iCustomize
->SetSelectedControlItem(CONTROL_VERSIONLIST
, 0);
251 catch(const css::uno::Exception
&)
255 //-----------------------------------------------------------------------------------------
256 STDMETHODIMP
VistaFilePickerEventHandler::OnSelectionChange(IFileDialog
* pDialog
)
258 impl_sendEvent(E_FILE_SELECTION_CHANGED
, 0);
259 //lcl_updateVersionListDirectly(pDialog);
263 //-----------------------------------------------------------------------------------------
264 STDMETHODIMP
VistaFilePickerEventHandler::OnShareViolation(IFileDialog
* pDialog
,
266 FDE_SHAREVIOLATION_RESPONSE
* pResponse
)
268 impl_sendEvent(E_CONTROL_STATE_CHANGED
, css::ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER
);
272 //-----------------------------------------------------------------------------------------
273 STDMETHODIMP
VistaFilePickerEventHandler::OnTypeChange(IFileDialog
* pDialog
)
276 IFileDialogCustomize *iCustomize;
277 pDialog->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustomize));
280 HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
286 pDialog->GetFileTypeIndex( &nIndex );
288 LPCWSTR lpFilterExt = lFilters[nIndex].pszSpec;
290 lpFilterExt = wcschr( lpFilterExt, '.' );
293 pDialog->SetDefaultExtension( lpFilterExt );
299 impl_sendEvent(E_CONTROL_STATE_CHANGED
, css::ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER
);
304 //-----------------------------------------------------------------------------------------
305 STDMETHODIMP
VistaFilePickerEventHandler::OnOverwrite(IFileDialog
* pDialog
,
307 FDE_OVERWRITE_RESPONSE
* pResponse
)
312 //-----------------------------------------------------------------------------------------
313 STDMETHODIMP
VistaFilePickerEventHandler::OnItemSelected(IFileDialogCustomize
* pCustomize
,
317 impl_sendEvent(E_CONTROL_STATE_CHANGED
, nIDCtl
);
321 //-----------------------------------------------------------------------------------------
322 STDMETHODIMP
VistaFilePickerEventHandler::OnButtonClicked(IFileDialogCustomize
* pCustomize
,
325 impl_sendEvent(E_CONTROL_STATE_CHANGED
, nIDCtl
);
329 //-----------------------------------------------------------------------------------------
330 STDMETHODIMP
VistaFilePickerEventHandler::OnCheckButtonToggled(IFileDialogCustomize
* pCustomize
,
335 if (nIDCtl == css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION)
337 LPCWSTR lpFilterExt = 0;
343 m_pDialog->GetFileTypeIndex( &nIndex );
344 lpFilterExt = lFilters[nIndex].pszSpec;
345 lpFilterExt = wcschr( lpFilterExt, '.' );
352 m_pDialog->SetDefaultExtension( lpFilterExt );
356 if (nIDCtl
== css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION
)
357 m_pInternalNotify
->onAutoExtensionChanged(bChecked
);
359 impl_sendEvent(E_CONTROL_STATE_CHANGED
, nIDCtl
);
363 //-----------------------------------------------------------------------------------------
364 STDMETHODIMP
VistaFilePickerEventHandler::OnControlActivating(IFileDialogCustomize
* pCustomize
,
367 impl_sendEvent(E_CONTROL_STATE_CHANGED
, nIDCtl
);
371 //-----------------------------------------------------------------------------------------
372 void SAL_CALL
VistaFilePickerEventHandler::addFilePickerListener( const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>& xListener
)
373 throw( css::uno::RuntimeException
)
375 m_lListener
.addInterface(::getCppuType( (const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>*)NULL
), xListener
);
378 //-----------------------------------------------------------------------------------------
379 void SAL_CALL
VistaFilePickerEventHandler::removeFilePickerListener( const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>& xListener
)
380 throw( css::uno::RuntimeException
)
382 m_lListener
.removeInterface(::getCppuType( (const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>*)NULL
), xListener
);
385 //-----------------------------------------------------------------------------------------
386 void VistaFilePickerEventHandler::startListening( const TFileDialog
& pBroadcaster
)
388 static const sal_Bool STARTUP_SUSPENDED
= sal_True
;
389 static const sal_Bool STARTUP_WORKING
= sal_False
;
394 m_pDialog
= pBroadcaster
;
395 m_pDialog
->Advise(this, &m_nListenerHandle
);
398 //-----------------------------------------------------------------------------------------
399 void VistaFilePickerEventHandler::stopListening()
403 m_pDialog
->Unadvise(m_nListenerHandle
);
408 static const ::rtl::OUString PROP_CONTROL_ID
= ::rtl::OUString::createFromAscii("control_id");
409 static const ::rtl::OUString PROP_PICKER_LISTENER
= ::rtl::OUString::createFromAscii("picker_listener");
411 //-----------------------------------------------------------------------------------------
412 class AsyncPickerEvents
: public RequestHandler
419 virtual ~AsyncPickerEvents()
422 virtual void before()
425 virtual void doRequest(const RequestRef
& rRequest
)
427 const ::sal_Int32 nEventID
= rRequest
->getRequest();
428 const ::sal_Int16 nControlID
= rRequest
->getArgumentOrDefault(PROP_CONTROL_ID
, (::sal_Int16
)0);
429 const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
> xListener
= rRequest
->getArgumentOrDefault(PROP_PICKER_LISTENER
, css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>());
431 if ( ! xListener
.is())
434 css::ui::dialogs::FilePickerEvent aEvent
;
435 aEvent
.ElementId
= nControlID
;
439 case VistaFilePickerEventHandler::E_FILE_SELECTION_CHANGED
:
440 xListener
->fileSelectionChanged(aEvent
);
443 case VistaFilePickerEventHandler::E_DIRECTORY_CHANGED
:
444 xListener
->directoryChanged(aEvent
);
447 case VistaFilePickerEventHandler::E_HELP_REQUESTED
:
448 xListener
->helpRequested(aEvent
);
451 case VistaFilePickerEventHandler::E_CONTROL_STATE_CHANGED
:
452 xListener
->controlStateChanged(aEvent
);
455 case VistaFilePickerEventHandler::E_DIALOG_SIZE_CHANGED
:
456 xListener
->dialogSizeChanged();
459 // no default here. Let compiler detect changes on enum set !
467 //-----------------------------------------------------------------------------------------
468 void VistaFilePickerEventHandler::impl_sendEvent( EEventType eEventType
,
469 ::sal_Int16 nControlID
)
471 static AsyncRequests
aNotify(RequestHandlerRef(new AsyncPickerEvents()));
473 ::cppu::OInterfaceContainerHelper
* pContainer
= m_lListener
.getContainer( ::getCppuType( ( const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>*) NULL
) );
477 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
478 while (pIterator
.hasMoreElements())
482 css::uno::Reference
< css::ui::dialogs::XFilePickerListener
> xListener (pIterator
.next(), css::uno::UNO_QUERY
);
484 RequestRef
rRequest(new Request());
485 rRequest
->setRequest (eEventType
);
486 rRequest
->setArgument(PROP_PICKER_LISTENER
, xListener
);
488 rRequest
->setArgument(PROP_CONTROL_ID
, nControlID
);
490 aNotify
.triggerRequestDirectly(rRequest
);
491 //aNotify.triggerRequestNonBlocked(rRequest);
493 catch(const css::uno::RuntimeException
&)
502 } // namespace fpicker