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: unodispatch.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_sw.hxx"
35 #include <vcl/svapp.hxx>
36 #include <sfx2/viewfrm.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <unodispatch.hxx>
44 #include <svx/dataaccessdescriptor.hxx>
46 using namespace ::com::sun::star
;
50 const char* cURLStart
= ".uno:DataSourceBrowser/";
51 const char* cURLFormLetter
= ".uno:DataSourceBrowser/FormLetter";
52 const char* cURLInsertContent
= ".uno:DataSourceBrowser/InsertContent";//data into fields
53 const char* cURLInsertColumns
= ".uno:DataSourceBrowser/InsertColumns";//data into text
54 const char* cURLDocumentDataSource
= ".uno:DataSourceBrowser/DocumentDataSource";//current data source of the document
55 const sal_Char
* cInternalDBChangeNotification
= ".uno::Writer/DataSourceChanged";
56 /*-- 07.11.00 13:25:51---------------------------------------------------
58 -----------------------------------------------------------------------*/
59 SwXDispatchProviderInterceptor::SwXDispatchProviderInterceptor(SwView
& rVw
) :
62 SfxFrame
* pFrame
= m_pView
->GetViewFrame()->GetFrame();
63 uno::Reference
< frame::XFrame
> xUnoFrame
= pFrame
->GetFrameInterface();
64 m_xIntercepted
= uno::Reference
< frame::XDispatchProviderInterception
>(xUnoFrame
, uno::UNO_QUERY
);
65 if(m_xIntercepted
.is())
68 m_xIntercepted
->registerDispatchProviderInterceptor((frame::XDispatchProviderInterceptor
*)this);
69 // this should make us the top-level dispatch-provider for the component, via a call to our
70 // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill
71 uno::Reference
< lang::XComponent
> xInterceptedComponent(m_xIntercepted
, uno::UNO_QUERY
);
72 if (xInterceptedComponent
.is())
73 xInterceptedComponent
->addEventListener((lang::XEventListener
*)this);
77 /*-- 07.11.00 13:25:51---------------------------------------------------
79 -----------------------------------------------------------------------*/
80 SwXDispatchProviderInterceptor::~SwXDispatchProviderInterceptor()
83 /*-- 07.11.00 13:25:51---------------------------------------------------
85 -----------------------------------------------------------------------*/
86 uno::Reference
< frame::XDispatch
> SwXDispatchProviderInterceptor::queryDispatch(
87 const util::URL
& aURL
, const OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
)
88 throw(uno::RuntimeException
)
90 DispatchMutexLock_Impl
aLock(*this);
91 uno::Reference
< frame::XDispatch
> xResult
;
92 // create some dispatch ...
93 if(m_pView
&& !aURL
.Complete
.compareToAscii(cURLStart
, 23))
95 if(!aURL
.Complete
.compareToAscii(cURLFormLetter
) ||
96 !aURL
.Complete
.compareToAscii(cURLInsertContent
) ||
97 !aURL
.Complete
.compareToAscii(cURLInsertColumns
)||
98 !aURL
.Complete
.compareToAscii(cURLDocumentDataSource
))
100 if(!m_xDispatch
.is())
101 m_xDispatch
= new SwXDispatch(*m_pView
);
102 xResult
= m_xDispatch
;
106 // ask our slave provider
107 if (!xResult
.is() && m_xSlaveDispatcher
.is())
108 xResult
= m_xSlaveDispatcher
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
112 /*-- 07.11.00 13:25:52---------------------------------------------------
114 -----------------------------------------------------------------------*/
115 uno::Sequence
< uno::Reference
< frame::XDispatch
> > SwXDispatchProviderInterceptor::queryDispatches(
116 const uno::Sequence
< frame::DispatchDescriptor
>& aDescripts
) throw(uno::RuntimeException
)
118 DispatchMutexLock_Impl
aLock(*this);
119 uno::Sequence
< uno::Reference
< frame::XDispatch
> > aReturn(aDescripts
.getLength());
120 uno::Reference
< frame::XDispatch
>* pReturn
= aReturn
.getArray();
121 const frame::DispatchDescriptor
* pDescripts
= aDescripts
.getConstArray();
122 for (sal_Int16 i
=0; i
<aDescripts
.getLength(); ++i
, ++pReturn
, ++pDescripts
)
124 *pReturn
= queryDispatch(pDescripts
->FeatureURL
,
125 pDescripts
->FrameName
, pDescripts
->SearchFlags
);
129 /*-- 07.11.00 13:25:52---------------------------------------------------
131 -----------------------------------------------------------------------*/
132 uno::Reference
< frame::XDispatchProvider
> SwXDispatchProviderInterceptor::getSlaveDispatchProvider( )
133 throw(uno::RuntimeException
)
135 DispatchMutexLock_Impl
aLock(*this);
136 return m_xSlaveDispatcher
;
138 /*-- 07.11.00 13:25:52---------------------------------------------------
140 -----------------------------------------------------------------------*/
141 void SwXDispatchProviderInterceptor::setSlaveDispatchProvider(
142 const uno::Reference
< frame::XDispatchProvider
>& xNewDispatchProvider
) throw(uno::RuntimeException
)
144 DispatchMutexLock_Impl
aLock(*this);
145 m_xSlaveDispatcher
= xNewDispatchProvider
;
147 /*-- 07.11.00 13:25:52---------------------------------------------------
149 -----------------------------------------------------------------------*/
150 uno::Reference
< frame::XDispatchProvider
> SwXDispatchProviderInterceptor::getMasterDispatchProvider( )
151 throw(uno::RuntimeException
)
153 DispatchMutexLock_Impl
aLock(*this);
154 return m_xMasterDispatcher
;
156 /*-- 07.11.00 13:25:52---------------------------------------------------
158 -----------------------------------------------------------------------*/
159 void SwXDispatchProviderInterceptor::setMasterDispatchProvider(
160 const uno::Reference
< frame::XDispatchProvider
>& xNewSupplier
) throw(uno::RuntimeException
)
162 DispatchMutexLock_Impl
aLock(*this);
163 m_xMasterDispatcher
= xNewSupplier
;
165 /*-- 07.11.00 13:25:53---------------------------------------------------
167 -----------------------------------------------------------------------*/
168 void SwXDispatchProviderInterceptor::disposing( const lang::EventObject
& )
169 throw(uno::RuntimeException
)
171 DispatchMutexLock_Impl
aLock(*this);
172 if (m_xIntercepted
.is())
174 m_xIntercepted
->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor
*)this);
175 uno::Reference
< lang::XComponent
> xInterceptedComponent(m_xIntercepted
, uno::UNO_QUERY
);
176 if (xInterceptedComponent
.is())
177 xInterceptedComponent
->removeEventListener((lang::XEventListener
*)this);
180 m_xIntercepted
= NULL
;
182 /* -----------------------------01.10.2001 14:31------------------------------
184 ---------------------------------------------------------------------------*/
185 const uno::Sequence
< sal_Int8
> & SwXDispatchProviderInterceptor::getUnoTunnelId()
187 static uno::Sequence
< sal_Int8
> aSeq
= ::CreateUnoTunnelId();
190 /* -----------------------------01.10.2001 14:31------------------------------
192 ---------------------------------------------------------------------------*/
193 sal_Int64
SwXDispatchProviderInterceptor::getSomething(
194 const uno::Sequence
< sal_Int8
>& aIdentifier
)
195 throw(uno::RuntimeException
)
197 if( aIdentifier
.getLength() == 16
198 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
199 aIdentifier
.getConstArray(), 16 ) )
201 return sal::static_int_cast
< sal_Int64
>( reinterpret_cast< sal_IntPtr
>( this ));
205 /* -----------------------------01.10.2001 14:32------------------------------
207 ---------------------------------------------------------------------------*/
208 void SwXDispatchProviderInterceptor::Invalidate()
210 DispatchMutexLock_Impl
aLock(*this);
211 if (m_xIntercepted
.is())
213 m_xIntercepted
->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor
*)this);
214 uno::Reference
< lang::XComponent
> xInterceptedComponent(m_xIntercepted
, uno::UNO_QUERY
);
215 if (xInterceptedComponent
.is())
216 xInterceptedComponent
->removeEventListener((lang::XEventListener
*)this);
219 m_xIntercepted
= NULL
;
222 /* -----------------------------07.11.00 14:26--------------------------------
224 ---------------------------------------------------------------------------*/
225 SwXDispatch::SwXDispatch(SwView
& rVw
) :
227 m_bOldEnable(sal_False
),
228 m_bListenerAdded(sal_False
)
231 /*-- 07.11.00 14:26:13---------------------------------------------------
233 -----------------------------------------------------------------------*/
234 SwXDispatch::~SwXDispatch()
236 if(m_bListenerAdded
&& m_pView
)
238 uno::Reference
<view::XSelectionSupplier
> xSupplier
= m_pView
->GetUNOObject();
239 uno::Reference
<view::XSelectionChangeListener
> xThis
= this;
240 xSupplier
->removeSelectionChangeListener(xThis
);
243 /*-- 07.11.00 14:26:13---------------------------------------------------
245 -----------------------------------------------------------------------*/
246 void SwXDispatch::dispatch(
247 const util::URL
& aURL
, const uno::Sequence
< beans::PropertyValue
>& aArgs
) throw(uno::RuntimeException
)
250 throw uno::RuntimeException();
251 SwWrtShell
& rSh
= m_pView
->GetWrtShell();
252 SwNewDBMgr
* pNewDBMgr
= rSh
.GetNewDBMgr();
253 if(!aURL
.Complete
.compareToAscii(cURLInsertContent
))
255 ::svx::ODataAccessDescriptor
aDescriptor(aArgs
);
256 SwMergeDescriptor
aMergeDesc( DBMGR_MERGE
, rSh
, aDescriptor
);
257 pNewDBMgr
->MergeNew(aMergeDesc
);
259 else if(!aURL
.Complete
.compareToAscii(cURLInsertColumns
))
261 pNewDBMgr
->InsertText(rSh
, aArgs
);
263 else if(!aURL
.Complete
.compareToAscii(cURLFormLetter
))
265 SfxUsrAnyItem
aDBProperties(FN_PARAM_DATABASE_PROPERTIES
, uno::makeAny(aArgs
));
266 m_pView
->GetViewFrame()->GetDispatcher()->Execute(
268 SFX_CALLMODE_ASYNCHRON
,
270 // pNewDBMgr->ExecuteFormLetter(rSh, aArgs);
272 else if(!aURL
.Complete
.compareToAscii(cURLDocumentDataSource
))
274 OSL_ENSURE(sal_False
, "SwXDispatch::dispatch: this URL is not to be dispatched!");
276 else if(!aURL
.Complete
.compareToAscii(cInternalDBChangeNotification
))
278 frame::FeatureStateEvent aEvent
;
279 aEvent
.IsEnabled
= sal_True
;
280 aEvent
.Source
= *(cppu::OWeakObject
*)this;
282 const SwDBData
& rData
= m_pView
->GetWrtShell().GetDBDesc();
283 ::svx::ODataAccessDescriptor aDescriptor
;
284 aDescriptor
.setDataSource(rData
.sDataSource
);
285 aDescriptor
[::svx::daCommand
] <<= rData
.sCommand
;
286 aDescriptor
[::svx::daCommandType
] <<= rData
.nCommandType
;
288 aEvent
.State
<<= aDescriptor
.createPropertyValueSequence();
289 aEvent
.IsEnabled
= rData
.sDataSource
.getLength() > 0;
291 StatusListenerList::iterator aListIter
= m_aListenerList
.begin();
292 for(aListIter
= m_aListenerList
.begin(); aListIter
!= m_aListenerList
.end(); ++aListIter
)
294 StatusStruct_Impl aStatus
= *aListIter
;
295 if(!aStatus
.aURL
.Complete
.compareToAscii(cURLDocumentDataSource
))
297 aEvent
.FeatureURL
= aStatus
.aURL
;
298 aStatus
.xListener
->statusChanged( aEvent
);
303 throw uno::RuntimeException();
306 /*-- 07.11.00 14:26:13---------------------------------------------------
308 -----------------------------------------------------------------------*/
309 void SwXDispatch::addStatusListener(
310 const uno::Reference
< frame::XStatusListener
>& xControl
, const util::URL
& aURL
) throw(uno::RuntimeException
)
313 throw uno::RuntimeException();
314 ShellModes eMode
= m_pView
->GetShellMode();
315 sal_Bool bEnable
= SHELL_MODE_TEXT
== eMode
||
316 SHELL_MODE_LIST_TEXT
== eMode
||
317 SHELL_MODE_TABLE_TEXT
== eMode
||
318 SHELL_MODE_TABLE_LIST_TEXT
== eMode
;
320 m_bOldEnable
= bEnable
;
321 frame::FeatureStateEvent aEvent
;
322 aEvent
.IsEnabled
= bEnable
;
323 aEvent
.Source
= *(cppu::OWeakObject
*)this;
324 aEvent
.FeatureURL
= aURL
;
326 // one of the URLs requires a special state ....
327 if (!aURL
.Complete
.compareToAscii(cURLDocumentDataSource
))
329 const SwDBData
& rData
= m_pView
->GetWrtShell().GetDBDesc();
331 ::svx::ODataAccessDescriptor aDescriptor
;
332 aDescriptor
.setDataSource(rData
.sDataSource
);
333 aDescriptor
[::svx::daCommand
] <<= rData
.sCommand
;
334 aDescriptor
[::svx::daCommandType
] <<= rData
.nCommandType
;
336 aEvent
.State
<<= aDescriptor
.createPropertyValueSequence();
337 aEvent
.IsEnabled
= rData
.sDataSource
.getLength() > 0;
341 xControl
->statusChanged( aEvent
);
343 StatusListenerList::iterator aListIter
= m_aListenerList
.begin();
344 StatusStruct_Impl aStatus
;
345 aStatus
.xListener
= xControl
;
347 m_aListenerList
.insert(aListIter
, aStatus
);
349 if(!m_bListenerAdded
)
351 uno::Reference
<view::XSelectionSupplier
> xSupplier
= m_pView
->GetUNOObject();
352 uno::Reference
<view::XSelectionChangeListener
> xThis
= this;
353 xSupplier
->addSelectionChangeListener(xThis
);
354 m_bListenerAdded
= sal_True
;
357 /*-- 07.11.00 14:26:15---------------------------------------------------
359 -----------------------------------------------------------------------*/
360 void SwXDispatch::removeStatusListener(
361 const uno::Reference
< frame::XStatusListener
>& xControl
, const util::URL
& ) throw(uno::RuntimeException
)
363 StatusListenerList::iterator aListIter
= m_aListenerList
.begin();
364 for(aListIter
= m_aListenerList
.begin(); aListIter
!= m_aListenerList
.end(); ++aListIter
)
366 StatusStruct_Impl aStatus
= *aListIter
;
367 if(aStatus
.xListener
.get() == xControl
.get())
369 m_aListenerList
.erase(aListIter
);
373 if(m_aListenerList
.empty() && m_pView
)
375 uno::Reference
<view::XSelectionSupplier
> xSupplier
= m_pView
->GetUNOObject();
376 uno::Reference
<view::XSelectionChangeListener
> xThis
= this;
377 xSupplier
->removeSelectionChangeListener(xThis
);
378 m_bListenerAdded
= sal_False
;
381 /* -----------------------------07.03.01 10:27--------------------------------
383 ---------------------------------------------------------------------------*/
384 void SwXDispatch::selectionChanged( const lang::EventObject
& ) throw(uno::RuntimeException
)
386 ShellModes eMode
= m_pView
->GetShellMode();
387 sal_Bool bEnable
= SHELL_MODE_TEXT
== eMode
||
388 SHELL_MODE_LIST_TEXT
== eMode
||
389 SHELL_MODE_TABLE_TEXT
== eMode
||
390 SHELL_MODE_TABLE_LIST_TEXT
== eMode
;
391 if(bEnable
!= m_bOldEnable
)
393 m_bOldEnable
= bEnable
;
394 frame::FeatureStateEvent aEvent
;
395 aEvent
.IsEnabled
= bEnable
;
396 aEvent
.Source
= *(cppu::OWeakObject
*)this;
398 StatusListenerList::iterator aListIter
= m_aListenerList
.begin();
399 for(aListIter
= m_aListenerList
.begin(); aListIter
!= m_aListenerList
.end(); ++aListIter
)
401 StatusStruct_Impl aStatus
= *aListIter
;
402 aEvent
.FeatureURL
= aStatus
.aURL
;
403 if (0 != aStatus
.aURL
.Complete
.compareToAscii(cURLDocumentDataSource
))
404 // the document's data source does not depend on the selection, so it's state does not change here
405 aStatus
.xListener
->statusChanged( aEvent
);
409 /* -----------------------------07.03.01 10:46--------------------------------
411 ---------------------------------------------------------------------------*/
412 void SwXDispatch::disposing( const lang::EventObject
& rSource
) throw(uno::RuntimeException
)
414 uno::Reference
<view::XSelectionSupplier
> xSupplier(rSource
.Source
, uno::UNO_QUERY
);
415 uno::Reference
<view::XSelectionChangeListener
> xThis
= this;
416 xSupplier
->removeSelectionChangeListener(xThis
);
417 m_bListenerAdded
= sal_False
;
419 lang::EventObject aObject
;
420 aObject
.Source
= (cppu::OWeakObject
*)this;
421 StatusListenerList::iterator aListIter
= m_aListenerList
.begin();
422 for(; aListIter
!= m_aListenerList
.end(); ++aListIter
)
424 StatusStruct_Impl aStatus
= *aListIter
;
425 aStatus
.xListener
->disposing(aObject
);
429 /* -----------------------------12.07.01 13:30--------------------------------
431 ---------------------------------------------------------------------------*/
432 const sal_Char
* SwXDispatch::GetDBChangeURL()
434 return cInternalDBChangeNotification
;
436 /* -----------------------------09.09.2002 08:48------------------------------
438 ---------------------------------------------------------------------------*/
439 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::DispatchMutexLock_Impl(
440 SwXDispatchProviderInterceptor
& ) :
441 // aGuard(rInterceptor.m_aMutex) #102295# solar mutex has to be used currently
442 aGuard(Application::GetSolarMutex())
445 /* -----------------------------09.09.2002 08:48------------------------------
447 ---------------------------------------------------------------------------*/
448 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::~DispatchMutexLock_Impl()