merged tag ooo/DEV300_m102
[LibreOffice.git] / fpicker / source / win32 / filepicker / VistaFilePickerEventHandler.cxx
blob2fadaa6bfdffc5ea3670a9ca625db17dff42096d
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 //------------------------------------------------------------------------
32 // includes
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;
58 namespace fpicker{
59 namespace win32{
60 namespace vista{
62 //------------------------------------------------------------------------
63 // defines
64 //------------------------------------------------------------------------
66 //-----------------------------------------------------------------------------------------
67 VistaFilePickerEventHandler::VistaFilePickerEventHandler(IVistaFilePickerInternalNotify* pInternalNotify)
68 : m_nRefCount (0 )
69 , m_nListenerHandle (0 )
70 , m_pDialog ( )
71 , m_lListener (m_aMutex)
72 , m_pInternalNotify (pInternalNotify)
76 //-----------------------------------------------------------------------------------------
77 VistaFilePickerEventHandler::~VistaFilePickerEventHandler()
81 //-----------------------------------------------------------------------------------------
82 HRESULT STDMETHODCALLTYPE VistaFilePickerEventHandler::QueryInterface(REFIID rIID ,
83 void** ppObject)
85 *ppObject=NULL;
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();
99 return S_OK;
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 )
116 delete this;
118 return nReturn;
121 //-----------------------------------------------------------------------------------------
122 STDMETHODIMP VistaFilePickerEventHandler::OnFileOk(IFileDialog* /*pDialog*/)
124 return E_NOTIMPL;
127 //-----------------------------------------------------------------------------------------
128 STDMETHODIMP VistaFilePickerEventHandler::OnFolderChanging(IFileDialog* /*pDialog*/,
129 IShellItem* /*pFolder*/)
131 return E_NOTIMPL;
134 //-----------------------------------------------------------------------------------------
135 STDMETHODIMP VistaFilePickerEventHandler::OnFolderChange(IFileDialog* /*pDialog*/)
137 impl_sendEvent(E_DIRECTORY_CHANGED, 0);
138 return S_OK;
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 );
150 if ( FAILED(hr) )
152 eConversion = SIGDN_URL;
153 hr = pItem->GetDisplayName ( eConversion, &pStr );
155 if ( FAILED(hr) )
156 return ::rtl::OUString();
158 sURL = ::rtl::OUString(reinterpret_cast<sal_Unicode*>(pStr));
160 else
162 ::osl::FileBase::getFileURLFromSystemPath( reinterpret_cast<sal_Unicode*>(pStr), sURL );
165 CoTaskMemFree (pStr);
166 return sURL;
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;
179 #ifdef __MINGW32__
180 iDialog->QueryInterface(IID_IFileOpenDialog, (void**)(&iOpen));
181 iDialog->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustomize));
182 #else
183 iDialog.query(&iOpen );
184 iDialog.query(&iCustomize);
185 #endif
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;
195 if (iOpen.is())
197 hResult = iOpen->GetSelectedItems(&iItems);
198 if (FAILED(hResult))
199 return;
201 DWORD nCount;
202 hResult = iItems->GetCount(&nCount);
203 if ( FAILED(hResult) )
204 return;
206 // we can show one version list only within control
207 if (nCount != 1)
208 return;
210 hResult = iItems->GetItemAt(0, &iItem);
212 else
213 if (iDialog.is())
214 hResult = iDialog->GetCurrentSelection(&iItem);
216 if ( FAILED(hResult) )
217 return;
219 const ::rtl::OUString sURL = lcl_getURLFromShellItem2(iItem);
220 if (sURL.getLength() < 1)
221 return;
223 INetURLObject aURL(sURL);
224 if (aURL.GetProtocol() != INET_PROT_FILE)
225 return;
227 ::rtl::OUString sMain = aURL.GetMainURL(INetURLObject::NO_DECODE);
228 if ( ! ::utl::UCBContentHelper::IsDocument(sURL))
229 return;
233 css::uno::Reference< css::embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(sURL, css::embed::ElementModes::READ);
234 if ( ! xStorage.is() )
235 return;
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);
257 return S_OK;
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);
268 return S_OK;
271 //-----------------------------------------------------------------------------------------
272 STDMETHODIMP VistaFilePickerEventHandler::OnTypeChange(IFileDialog* /*pDialog*/)
275 IFileDialogCustomize *iCustomize;
276 pDialog->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustomize));
278 BOOL bValue = FALSE;
279 HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
281 if ( bValue )
283 UINT nIndex;
285 pDialog->GetFileTypeIndex( &nIndex );
287 LPCWSTR lpFilterExt = lFilters[nIndex].pszSpec;
289 lpFilterExt = wcschr( lpFilterExt, '.' );
290 if ( lpFilterExt )
291 lpFilterExt++;
292 pDialog->SetDefaultExtension( lpFilterExt );
294 return S_OK;
298 impl_sendEvent(E_CONTROL_STATE_CHANGED, css::ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER);
300 return S_OK;
303 //-----------------------------------------------------------------------------------------
304 STDMETHODIMP VistaFilePickerEventHandler::OnOverwrite(IFileDialog* /*pDialog*/ ,
305 IShellItem* /*pItem*/ ,
306 FDE_OVERWRITE_RESPONSE* /*pResponse*/)
308 return E_NOTIMPL;
311 //-----------------------------------------------------------------------------------------
312 STDMETHODIMP VistaFilePickerEventHandler::OnItemSelected(IFileDialogCustomize* /*pCustomize*/,
314 DWORD nIDCtl ,
316 DWORD /*nIDItem*/ )
319 impl_sendEvent(E_CONTROL_STATE_CHANGED, static_cast<sal_Int16>( nIDCtl ));
320 return S_OK;
323 //-----------------------------------------------------------------------------------------
324 STDMETHODIMP VistaFilePickerEventHandler::OnButtonClicked(IFileDialogCustomize* /*pCustomize*/,
325 DWORD nIDCtl )
328 impl_sendEvent(E_CONTROL_STATE_CHANGED, static_cast<sal_Int16>( nIDCtl));
329 return S_OK;
332 //-----------------------------------------------------------------------------------------
333 STDMETHODIMP VistaFilePickerEventHandler::OnCheckButtonToggled(IFileDialogCustomize* /*pCustomize*/,
334 DWORD nIDCtl ,
335 BOOL bChecked )
338 if (nIDCtl == css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION)
340 LPCWSTR lpFilterExt = 0;
341 if ( bChecked )
343 UINT nIndex;
344 if (m_pDialog)
346 m_pDialog->GetFileTypeIndex( &nIndex );
347 lpFilterExt = lFilters[nIndex].pszSpec;
348 lpFilterExt = wcschr( lpFilterExt, '.' );
349 if ( lpFilterExt )
350 lpFilterExt++;
354 if (m_pDialog)
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));
365 return S_OK;
368 //-----------------------------------------------------------------------------------------
369 STDMETHODIMP VistaFilePickerEventHandler::OnControlActivating(IFileDialogCustomize* /*pCustomize*/,
370 DWORD nIDCtl )
372 impl_sendEvent(E_CONTROL_STATE_CHANGED, static_cast<sal_Int16>( nIDCtl));
373 return S_OK;
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;
396 if (m_pDialog.is())
397 return;
399 m_pDialog = pBroadcaster;
400 m_pDialog->Advise(this, &m_nListenerHandle);
403 //-----------------------------------------------------------------------------------------
404 void VistaFilePickerEventHandler::stopListening()
406 if (m_pDialog.is())
408 m_pDialog->Unadvise(m_nListenerHandle);
409 m_pDialog.release();
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
419 public:
421 AsyncPickerEvents()
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())
437 return;
439 css::ui::dialogs::FilePickerEvent aEvent;
440 aEvent.ElementId = nControlID;
442 switch (nEventID)
444 case VistaFilePickerEventHandler::E_FILE_SELECTION_CHANGED :
445 xListener->fileSelectionChanged(aEvent);
446 break;
448 case VistaFilePickerEventHandler::E_DIRECTORY_CHANGED :
449 xListener->directoryChanged(aEvent);
450 break;
452 case VistaFilePickerEventHandler::E_HELP_REQUESTED :
453 xListener->helpRequested(aEvent);
454 break;
456 case VistaFilePickerEventHandler::E_CONTROL_STATE_CHANGED :
457 xListener->controlStateChanged(aEvent);
458 break;
460 case VistaFilePickerEventHandler::E_DIALOG_SIZE_CHANGED :
461 xListener->dialogSizeChanged();
462 break;
464 // no default here. Let compiler detect changes on enum set !
468 virtual void after()
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 ) );
479 if ( ! pContainer)
480 return;
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);
492 if ( nControlID )
493 rRequest->setArgument(PROP_CONTROL_ID, nControlID);
495 aNotify.triggerRequestDirectly(rRequest);
496 //aNotify.triggerRequestNonBlocked(rRequest);
498 catch(const css::uno::RuntimeException&)
500 pIterator.remove();
505 } // namespace vista
506 } // namespace win32
507 } // namespace fpicker