blob: 2b28af390277ce8970ed3c412695d252ad5e7289 [file] [log] [blame]
/**************************************************************
*
* 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()
{
}