| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sw.hxx" |
| |
| #include <vcl/svapp.hxx> |
| #include <sfx2/viewfrm.hxx> |
| #include <sfx2/dispatch.hxx> |
| #include <svx/dataaccessdescriptor.hxx> |
| |
| #include <unodispatch.hxx> |
| #include <unobaseclass.hxx> |
| #include <view.hxx> |
| #include <cmdid.h> |
| #include "wrtsh.hxx" |
| #include "dbmgr.hxx" |
| |
| |
| using namespace ::com::sun::star; |
| using namespace rtl; |
| using namespace vos; |
| |
| const char* cURLStart = ".uno:DataSourceBrowser/"; |
| const char* cURLFormLetter = ".uno:DataSourceBrowser/FormLetter"; |
| const char* cURLInsertContent = ".uno:DataSourceBrowser/InsertContent";//data into fields |
| const char* cURLInsertColumns = ".uno:DataSourceBrowser/InsertColumns";//data into text |
| const char* cURLDocumentDataSource = ".uno:DataSourceBrowser/DocumentDataSource";//current data source of the document |
| const sal_Char* cInternalDBChangeNotification = ".uno::Writer/DataSourceChanged"; |
| /*-- 07.11.00 13:25:51--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| SwXDispatchProviderInterceptor::SwXDispatchProviderInterceptor(SwView& rVw) : |
| m_pView(&rVw) |
| { |
| uno::Reference< frame::XFrame> xUnoFrame = m_pView->GetViewFrame()->GetFrame().GetFrameInterface(); |
| m_xIntercepted = uno::Reference< frame::XDispatchProviderInterception>(xUnoFrame, uno::UNO_QUERY); |
| if(m_xIntercepted.is()) |
| { |
| m_refCount++; |
| m_xIntercepted->registerDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this); |
| // this should make us the top-level dispatch-provider for the component, via a call to our |
| // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill |
| uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY); |
| if (xInterceptedComponent.is()) |
| xInterceptedComponent->addEventListener((lang::XEventListener*)this); |
| m_refCount--; |
| } |
| } |
| /*-- 07.11.00 13:25:51--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| SwXDispatchProviderInterceptor::~SwXDispatchProviderInterceptor() |
| { |
| } |
| /*-- 07.11.00 13:25:51--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| uno::Reference< frame::XDispatch > SwXDispatchProviderInterceptor::queryDispatch( |
| const util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags ) |
| throw(uno::RuntimeException) |
| { |
| DispatchMutexLock_Impl aLock(*this); |
| uno::Reference< frame::XDispatch> xResult; |
| // create some dispatch ... |
| if(m_pView && !aURL.Complete.compareToAscii(cURLStart, 23)) |
| { |
| if(!aURL.Complete.compareToAscii(cURLFormLetter) || |
| !aURL.Complete.compareToAscii(cURLInsertContent) || |
| !aURL.Complete.compareToAscii(cURLInsertColumns)|| |
| !aURL.Complete.compareToAscii(cURLDocumentDataSource)) |
| { |
| if(!m_xDispatch.is()) |
| m_xDispatch = new SwXDispatch(*m_pView); |
| xResult = m_xDispatch; |
| } |
| } |
| |
| // ask our slave provider |
| if (!xResult.is() && m_xSlaveDispatcher.is()) |
| xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags); |
| |
| return xResult; |
| } |
| /*-- 07.11.00 13:25:52--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| uno::Sequence< uno::Reference< frame::XDispatch > > SwXDispatchProviderInterceptor::queryDispatches( |
| const uno::Sequence< frame::DispatchDescriptor >& aDescripts ) throw(uno::RuntimeException) |
| { |
| DispatchMutexLock_Impl aLock(*this); |
| uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength()); |
| uno::Reference< frame::XDispatch>* pReturn = aReturn.getArray(); |
| const frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray(); |
| for (sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts) |
| { |
| *pReturn = queryDispatch(pDescripts->FeatureURL, |
| pDescripts->FrameName, pDescripts->SearchFlags); |
| } |
| return aReturn; |
| } |
| /*-- 07.11.00 13:25:52--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getSlaveDispatchProvider( ) |
| throw(uno::RuntimeException) |
| { |
| DispatchMutexLock_Impl aLock(*this); |
| return m_xSlaveDispatcher; |
| } |
| /*-- 07.11.00 13:25:52--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| void SwXDispatchProviderInterceptor::setSlaveDispatchProvider( |
| const uno::Reference< frame::XDispatchProvider >& xNewDispatchProvider ) throw(uno::RuntimeException) |
| { |
| DispatchMutexLock_Impl aLock(*this); |
| m_xSlaveDispatcher = xNewDispatchProvider; |
| } |
| /*-- 07.11.00 13:25:52--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getMasterDispatchProvider( ) |
| throw(uno::RuntimeException) |
| { |
| DispatchMutexLock_Impl aLock(*this); |
| return m_xMasterDispatcher; |
| } |
| /*-- 07.11.00 13:25:52--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| void SwXDispatchProviderInterceptor::setMasterDispatchProvider( |
| const uno::Reference< frame::XDispatchProvider >& xNewSupplier ) throw(uno::RuntimeException) |
| { |
| DispatchMutexLock_Impl aLock(*this); |
| m_xMasterDispatcher = xNewSupplier; |
| } |
| /*-- 07.11.00 13:25:53--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| void SwXDispatchProviderInterceptor::disposing( const lang::EventObject& ) |
| throw(uno::RuntimeException) |
| { |
| DispatchMutexLock_Impl aLock(*this); |
| if (m_xIntercepted.is()) |
| { |
| m_xIntercepted->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this); |
| uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY); |
| if (xInterceptedComponent.is()) |
| xInterceptedComponent->removeEventListener((lang::XEventListener*)this); |
| m_xDispatch = 0; |
| } |
| m_xIntercepted = NULL; |
| } |
| /* -----------------------------01.10.2001 14:31------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| const uno::Sequence< sal_Int8 > & SwXDispatchProviderInterceptor::getUnoTunnelId() |
| { |
| static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId(); |
| return aSeq; |
| } |
| /* -----------------------------01.10.2001 14:31------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Int64 SwXDispatchProviderInterceptor::getSomething( |
| const uno::Sequence< sal_Int8 >& aIdentifier ) |
| throw(uno::RuntimeException) |
| { |
| if( aIdentifier.getLength() == 16 |
| && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), |
| aIdentifier.getConstArray(), 16 ) ) |
| { |
| return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this )); |
| } |
| return 0; |
| } |
| /* -----------------------------01.10.2001 14:32------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| void SwXDispatchProviderInterceptor::Invalidate() |
| { |
| DispatchMutexLock_Impl aLock(*this); |
| if (m_xIntercepted.is()) |
| { |
| m_xIntercepted->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this); |
| uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY); |
| if (xInterceptedComponent.is()) |
| xInterceptedComponent->removeEventListener((lang::XEventListener*)this); |
| m_xDispatch = 0; |
| } |
| m_xIntercepted = NULL; |
| m_pView = 0; |
| } |
| /* -----------------------------07.11.00 14:26-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| SwXDispatch::SwXDispatch(SwView& rVw) : |
| m_pView(&rVw), |
| m_bOldEnable(sal_False), |
| m_bListenerAdded(sal_False) |
| { |
| } |
| /*-- 07.11.00 14:26:13--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| SwXDispatch::~SwXDispatch() |
| { |
| if(m_bListenerAdded && m_pView) |
| { |
| uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject(); |
| uno::Reference<view::XSelectionChangeListener> xThis = this; |
| xSupplier->removeSelectionChangeListener(xThis); |
| } |
| } |
| /*-- 07.11.00 14:26:13--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| void SwXDispatch::dispatch( |
| const util::URL& aURL, const uno::Sequence< beans::PropertyValue >& aArgs ) throw(uno::RuntimeException) |
| { |
| if(!m_pView) |
| throw uno::RuntimeException(); |
| SwWrtShell& rSh = m_pView->GetWrtShell(); |
| SwNewDBMgr* pNewDBMgr = rSh.GetNewDBMgr(); |
| if(!aURL.Complete.compareToAscii(cURLInsertContent)) |
| { |
| ::svx::ODataAccessDescriptor aDescriptor(aArgs); |
| SwMergeDescriptor aMergeDesc( DBMGR_MERGE, rSh, aDescriptor ); |
| pNewDBMgr->MergeNew(aMergeDesc); |
| } |
| else if(!aURL.Complete.compareToAscii(cURLInsertColumns)) |
| { |
| pNewDBMgr->InsertText(rSh, aArgs); |
| } |
| else if(!aURL.Complete.compareToAscii(cURLFormLetter)) |
| { |
| SfxUsrAnyItem aDBProperties(FN_PARAM_DATABASE_PROPERTIES, uno::makeAny(aArgs)); |
| m_pView->GetViewFrame()->GetDispatcher()->Execute( |
| FN_MAILMERGE_WIZARD, |
| SFX_CALLMODE_ASYNCHRON, |
| &aDBProperties, 0L); |
| // pNewDBMgr->ExecuteFormLetter(rSh, aArgs); |
| } |
| else if(!aURL.Complete.compareToAscii(cURLDocumentDataSource)) |
| { |
| OSL_ENSURE(sal_False, "SwXDispatch::dispatch: this URL is not to be dispatched!"); |
| } |
| else if(!aURL.Complete.compareToAscii(cInternalDBChangeNotification)) |
| { |
| frame::FeatureStateEvent aEvent; |
| aEvent.IsEnabled = sal_True; |
| aEvent.Source = *(cppu::OWeakObject*)this; |
| |
| const SwDBData& rData = m_pView->GetWrtShell().GetDBDesc(); |
| ::svx::ODataAccessDescriptor aDescriptor; |
| aDescriptor.setDataSource(rData.sDataSource); |
| aDescriptor[::svx::daCommand] <<= rData.sCommand; |
| aDescriptor[::svx::daCommandType] <<= rData.nCommandType; |
| |
| aEvent.State <<= aDescriptor.createPropertyValueSequence(); |
| aEvent.IsEnabled = rData.sDataSource.getLength() > 0; |
| |
| StatusListenerList::iterator aListIter = m_aListenerList.begin(); |
| for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter) |
| { |
| StatusStruct_Impl aStatus = *aListIter; |
| if(!aStatus.aURL.Complete.compareToAscii(cURLDocumentDataSource)) |
| { |
| aEvent.FeatureURL = aStatus.aURL; |
| aStatus.xListener->statusChanged( aEvent ); |
| } |
| } |
| } |
| else |
| throw uno::RuntimeException(); |
| |
| } |
| /*-- 07.11.00 14:26:13--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| void SwXDispatch::addStatusListener( |
| const uno::Reference< frame::XStatusListener >& xControl, const util::URL& aURL ) throw(uno::RuntimeException) |
| { |
| if(!m_pView) |
| throw uno::RuntimeException(); |
| ShellModes eMode = m_pView->GetShellMode(); |
| sal_Bool bEnable = SHELL_MODE_TEXT == eMode || |
| SHELL_MODE_LIST_TEXT == eMode || |
| SHELL_MODE_TABLE_TEXT == eMode || |
| SHELL_MODE_TABLE_LIST_TEXT == eMode; |
| |
| m_bOldEnable = bEnable; |
| frame::FeatureStateEvent aEvent; |
| aEvent.IsEnabled = bEnable; |
| aEvent.Source = *(cppu::OWeakObject*)this; |
| aEvent.FeatureURL = aURL; |
| |
| // one of the URLs requires a special state .... |
| if (!aURL.Complete.compareToAscii(cURLDocumentDataSource)) |
| { |
| const SwDBData& rData = m_pView->GetWrtShell().GetDBDesc(); |
| |
| ::svx::ODataAccessDescriptor aDescriptor; |
| aDescriptor.setDataSource(rData.sDataSource); |
| aDescriptor[::svx::daCommand] <<= rData.sCommand; |
| aDescriptor[::svx::daCommandType] <<= rData.nCommandType; |
| |
| aEvent.State <<= aDescriptor.createPropertyValueSequence(); |
| aEvent.IsEnabled = rData.sDataSource.getLength() > 0; |
| } |
| |
| |
| xControl->statusChanged( aEvent ); |
| |
| StatusListenerList::iterator aListIter = m_aListenerList.begin(); |
| StatusStruct_Impl aStatus; |
| aStatus.xListener = xControl; |
| aStatus.aURL = aURL; |
| m_aListenerList.insert(aListIter, aStatus); |
| |
| if(!m_bListenerAdded) |
| { |
| uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject(); |
| uno::Reference<view::XSelectionChangeListener> xThis = this; |
| xSupplier->addSelectionChangeListener(xThis); |
| m_bListenerAdded = sal_True; |
| } |
| } |
| /*-- 07.11.00 14:26:15--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| void SwXDispatch::removeStatusListener( |
| const uno::Reference< frame::XStatusListener >& xControl, const util::URL& ) throw(uno::RuntimeException) |
| { |
| StatusListenerList::iterator aListIter = m_aListenerList.begin(); |
| for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter) |
| { |
| StatusStruct_Impl aStatus = *aListIter; |
| if(aStatus.xListener.get() == xControl.get()) |
| { |
| m_aListenerList.erase(aListIter); |
| break; |
| } |
| } |
| if(m_aListenerList.empty() && m_pView) |
| { |
| uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject(); |
| uno::Reference<view::XSelectionChangeListener> xThis = this; |
| xSupplier->removeSelectionChangeListener(xThis); |
| m_bListenerAdded = sal_False; |
| } |
| } |
| /* -----------------------------07.03.01 10:27-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| void SwXDispatch::selectionChanged( const lang::EventObject& ) throw(uno::RuntimeException) |
| { |
| ShellModes eMode = m_pView->GetShellMode(); |
| sal_Bool bEnable = SHELL_MODE_TEXT == eMode || |
| SHELL_MODE_LIST_TEXT == eMode || |
| SHELL_MODE_TABLE_TEXT == eMode || |
| SHELL_MODE_TABLE_LIST_TEXT == eMode; |
| if(bEnable != m_bOldEnable) |
| { |
| m_bOldEnable = bEnable; |
| frame::FeatureStateEvent aEvent; |
| aEvent.IsEnabled = bEnable; |
| aEvent.Source = *(cppu::OWeakObject*)this; |
| |
| StatusListenerList::iterator aListIter = m_aListenerList.begin(); |
| for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter) |
| { |
| StatusStruct_Impl aStatus = *aListIter; |
| aEvent.FeatureURL = aStatus.aURL; |
| if (0 != aStatus.aURL.Complete.compareToAscii(cURLDocumentDataSource)) |
| // the document's data source does not depend on the selection, so it's state does not change here |
| aStatus.xListener->statusChanged( aEvent ); |
| } |
| } |
| } |
| /* -----------------------------07.03.01 10:46-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| void SwXDispatch::disposing( const lang::EventObject& rSource ) throw(uno::RuntimeException) |
| { |
| uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY); |
| uno::Reference<view::XSelectionChangeListener> xThis = this; |
| xSupplier->removeSelectionChangeListener(xThis); |
| m_bListenerAdded = sal_False; |
| |
| lang::EventObject aObject; |
| aObject.Source = (cppu::OWeakObject*)this; |
| StatusListenerList::iterator aListIter = m_aListenerList.begin(); |
| for(; aListIter != m_aListenerList.end(); ++aListIter) |
| { |
| StatusStruct_Impl aStatus = *aListIter; |
| aStatus.xListener->disposing(aObject); |
| } |
| m_pView = 0; |
| } |
| /* -----------------------------12.07.01 13:30-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| const sal_Char* SwXDispatch::GetDBChangeURL() |
| { |
| return cInternalDBChangeNotification; |
| } |
| /* -----------------------------09.09.2002 08:48------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::DispatchMutexLock_Impl( |
| SwXDispatchProviderInterceptor& ) : |
| // aGuard(rInterceptor.m_aMutex) #102295# solar mutex has to be used currently |
| aGuard(Application::GetSolarMutex()) |
| { |
| } |
| /* -----------------------------09.09.2002 08:48------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::~DispatchMutexLock_Impl() |
| { |
| } |
| |