Update ooo320-m1
[ooovba.git] / fpicker / source / win32 / filepicker / VistaFilePickerEventHandler.cxx
blob6814f797614b707bd112bce44d34d2dbf40d9409
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: VistaFilePickerEventHandler.cxx,v $
10 * $Revision: 1.6 $
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 //------------------------------------------------------------------------
35 // includes
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;
61 namespace fpicker{
62 namespace win32{
63 namespace vista{
65 //------------------------------------------------------------------------
66 // defines
67 //------------------------------------------------------------------------
69 //-----------------------------------------------------------------------------------------
70 VistaFilePickerEventHandler::VistaFilePickerEventHandler(IVistaFilePickerInternalNotify* pInternalNotify)
71 : m_nRefCount (0 )
72 , m_nListenerHandle (0 )
73 , m_pDialog ( )
74 , m_lListener (m_aMutex)
75 , m_pInternalNotify (pInternalNotify)
79 //-----------------------------------------------------------------------------------------
80 VistaFilePickerEventHandler::~VistaFilePickerEventHandler()
84 //-----------------------------------------------------------------------------------------
85 HRESULT STDMETHODCALLTYPE VistaFilePickerEventHandler::QueryInterface(REFIID rIID ,
86 void** ppObject)
88 *ppObject=NULL;
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();
102 return S_OK;
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 )
119 delete this;
121 return nReturn;
124 //-----------------------------------------------------------------------------------------
125 STDMETHODIMP VistaFilePickerEventHandler::OnFileOk(IFileDialog* /*pDialog*/)
127 return E_NOTIMPL;
130 //-----------------------------------------------------------------------------------------
131 STDMETHODIMP VistaFilePickerEventHandler::OnFolderChanging(IFileDialog* pDialog,
132 IShellItem* pFolder)
134 return E_NOTIMPL;
137 //-----------------------------------------------------------------------------------------
138 STDMETHODIMP VistaFilePickerEventHandler::OnFolderChange(IFileDialog* pDialog)
140 impl_sendEvent(E_DIRECTORY_CHANGED, 0);
141 return S_OK;
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 );
153 if ( FAILED(hr) )
155 eConversion = SIGDN_URL;
156 hr = pItem->GetDisplayName ( eConversion, &pStr );
158 if ( FAILED(hr) )
159 return ::rtl::OUString();
161 sURL = ::rtl::OUString(reinterpret_cast<sal_Unicode*>(pStr));
163 else
165 ::osl::FileBase::getFileURLFromSystemPath( reinterpret_cast<sal_Unicode*>(pStr), sURL );
168 CoTaskMemFree (pStr);
169 return sURL;
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;
182 #ifdef __MINGW32__
183 iDialog->QueryInterface(IID_IFileOpenDialog, (void**)(&iOpen));
184 iDialog->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustomize));
185 #else
186 iDialog.query(&iOpen );
187 iDialog.query(&iCustomize);
188 #endif
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;
198 if (iOpen.is())
200 hResult = iOpen->GetSelectedItems(&iItems);
201 if (FAILED(hResult))
202 return;
204 DWORD nCount;
205 hResult = iItems->GetCount(&nCount);
206 if ( FAILED(hResult) )
207 return;
209 // we can show one version list only within control
210 if (nCount != 1)
211 return;
213 hResult = iItems->GetItemAt(0, &iItem);
215 else
216 if (iDialog.is())
217 hResult = iDialog->GetCurrentSelection(&iItem);
219 if ( FAILED(hResult) )
220 return;
222 const ::rtl::OUString sURL = lcl_getURLFromShellItem2(iItem);
223 if (sURL.getLength() < 1)
224 return;
226 INetURLObject aURL(sURL);
227 if (aURL.GetProtocol() != INET_PROT_FILE)
228 return;
230 ::rtl::OUString sMain = aURL.GetMainURL(INetURLObject::NO_DECODE);
231 if ( ! ::utl::UCBContentHelper::IsDocument(sURL))
232 return;
236 css::uno::Reference< css::embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(sURL, css::embed::ElementModes::READ);
237 if ( ! xStorage.is() )
238 return;
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);
260 return S_OK;
263 //-----------------------------------------------------------------------------------------
264 STDMETHODIMP VistaFilePickerEventHandler::OnShareViolation(IFileDialog* pDialog ,
265 IShellItem* pItem ,
266 FDE_SHAREVIOLATION_RESPONSE* pResponse)
268 impl_sendEvent(E_CONTROL_STATE_CHANGED, css::ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER);
269 return S_OK;
272 //-----------------------------------------------------------------------------------------
273 STDMETHODIMP VistaFilePickerEventHandler::OnTypeChange(IFileDialog* pDialog)
276 IFileDialogCustomize *iCustomize;
277 pDialog->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustomize));
279 BOOL bValue = FALSE;
280 HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
282 if ( bValue )
284 UINT nIndex;
286 pDialog->GetFileTypeIndex( &nIndex );
288 LPCWSTR lpFilterExt = lFilters[nIndex].pszSpec;
290 lpFilterExt = wcschr( lpFilterExt, '.' );
291 if ( lpFilterExt )
292 lpFilterExt++;
293 pDialog->SetDefaultExtension( lpFilterExt );
295 return S_OK;
299 impl_sendEvent(E_CONTROL_STATE_CHANGED, css::ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER);
301 return S_OK;
304 //-----------------------------------------------------------------------------------------
305 STDMETHODIMP VistaFilePickerEventHandler::OnOverwrite(IFileDialog* pDialog ,
306 IShellItem* pItem ,
307 FDE_OVERWRITE_RESPONSE* pResponse)
309 return E_NOTIMPL;
312 //-----------------------------------------------------------------------------------------
313 STDMETHODIMP VistaFilePickerEventHandler::OnItemSelected(IFileDialogCustomize* pCustomize,
314 DWORD nIDCtl ,
315 DWORD nIDItem )
317 impl_sendEvent(E_CONTROL_STATE_CHANGED, nIDCtl);
318 return S_OK;
321 //-----------------------------------------------------------------------------------------
322 STDMETHODIMP VistaFilePickerEventHandler::OnButtonClicked(IFileDialogCustomize* pCustomize,
323 DWORD nIDCtl )
325 impl_sendEvent(E_CONTROL_STATE_CHANGED, nIDCtl);
326 return S_OK;
329 //-----------------------------------------------------------------------------------------
330 STDMETHODIMP VistaFilePickerEventHandler::OnCheckButtonToggled(IFileDialogCustomize* pCustomize,
331 DWORD nIDCtl ,
332 BOOL bChecked )
335 if (nIDCtl == css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION)
337 LPCWSTR lpFilterExt = 0;
338 if ( bChecked )
340 UINT nIndex;
341 if (m_pDialog)
343 m_pDialog->GetFileTypeIndex( &nIndex );
344 lpFilterExt = lFilters[nIndex].pszSpec;
345 lpFilterExt = wcschr( lpFilterExt, '.' );
346 if ( lpFilterExt )
347 lpFilterExt++;
351 if (m_pDialog)
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);
360 return S_OK;
363 //-----------------------------------------------------------------------------------------
364 STDMETHODIMP VistaFilePickerEventHandler::OnControlActivating(IFileDialogCustomize* pCustomize,
365 DWORD nIDCtl )
367 impl_sendEvent(E_CONTROL_STATE_CHANGED, nIDCtl);
368 return S_OK;
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;
391 if (m_pDialog.is())
392 return;
394 m_pDialog = pBroadcaster;
395 m_pDialog->Advise(this, &m_nListenerHandle);
398 //-----------------------------------------------------------------------------------------
399 void VistaFilePickerEventHandler::stopListening()
401 if (m_pDialog.is())
403 m_pDialog->Unadvise(m_nListenerHandle);
404 m_pDialog.release();
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
414 public:
416 AsyncPickerEvents()
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())
432 return;
434 css::ui::dialogs::FilePickerEvent aEvent;
435 aEvent.ElementId = nControlID;
437 switch (nEventID)
439 case VistaFilePickerEventHandler::E_FILE_SELECTION_CHANGED :
440 xListener->fileSelectionChanged(aEvent);
441 break;
443 case VistaFilePickerEventHandler::E_DIRECTORY_CHANGED :
444 xListener->directoryChanged(aEvent);
445 break;
447 case VistaFilePickerEventHandler::E_HELP_REQUESTED :
448 xListener->helpRequested(aEvent);
449 break;
451 case VistaFilePickerEventHandler::E_CONTROL_STATE_CHANGED :
452 xListener->controlStateChanged(aEvent);
453 break;
455 case VistaFilePickerEventHandler::E_DIALOG_SIZE_CHANGED :
456 xListener->dialogSizeChanged();
457 break;
459 // no default here. Let compiler detect changes on enum set !
463 virtual void after()
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 ) );
474 if ( ! pContainer)
475 return;
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);
487 if ( nControlID )
488 rRequest->setArgument(PROP_CONTROL_ID, nControlID);
490 aNotify.triggerRequestDirectly(rRequest);
491 //aNotify.triggerRequestNonBlocked(rRequest);
493 catch(const css::uno::RuntimeException&)
495 pIterator.remove();
500 } // namespace vista
501 } // namespace win32
502 } // namespace fpicker