xref: /trunk/main/sw/source/ui/uno/unodispatch.cxx (revision 86e1cf34)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <vcl/svapp.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <sfx2/dispatch.hxx>
30 #include <svx/dataaccessdescriptor.hxx>
31 
32 #include <unodispatch.hxx>
33 #include <unobaseclass.hxx>
34 #include <view.hxx>
35 #include <cmdid.h>
36 #include "wrtsh.hxx"
37 #include "dbmgr.hxx"
38 
39 
40 using namespace ::com::sun::star;
41 using namespace rtl;
42 using namespace vos;
43 
44 const char* cURLStart 			= ".uno:DataSourceBrowser/";
45 const char* cURLFormLetter 		= ".uno:DataSourceBrowser/FormLetter";
46 const char* cURLInsertContent 	= ".uno:DataSourceBrowser/InsertContent";//data into fields
47 const char* cURLInsertColumns 	= ".uno:DataSourceBrowser/InsertColumns";//data into text
48 const char* cURLDocumentDataSource  = ".uno:DataSourceBrowser/DocumentDataSource";//current data source of the document
49 const sal_Char* cInternalDBChangeNotification = ".uno::Writer/DataSourceChanged";
50 /*-- 07.11.00 13:25:51---------------------------------------------------
51 
52   -----------------------------------------------------------------------*/
SwXDispatchProviderInterceptor(SwView & rVw)53 SwXDispatchProviderInterceptor::SwXDispatchProviderInterceptor(SwView& rVw) :
54     m_pView(&rVw)
55 {
56 	uno::Reference< frame::XFrame> xUnoFrame = m_pView->GetViewFrame()->GetFrame().GetFrameInterface();
57 	m_xIntercepted = uno::Reference< frame::XDispatchProviderInterception>(xUnoFrame, uno::UNO_QUERY);
58 	if(m_xIntercepted.is())
59 	{
60 		m_refCount++;
61 		m_xIntercepted->registerDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this);
62 		// this should make us the top-level dispatch-provider for the component, via a call to our
63 		// setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fulfill
64 		uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
65 		if (xInterceptedComponent.is())
66 			xInterceptedComponent->addEventListener((lang::XEventListener*)this);
67 		m_refCount--;
68 	}
69 }
70 /*-- 07.11.00 13:25:51---------------------------------------------------
71 
72   -----------------------------------------------------------------------*/
~SwXDispatchProviderInterceptor()73 SwXDispatchProviderInterceptor::~SwXDispatchProviderInterceptor()
74 {
75 }
76 /*-- 07.11.00 13:25:51---------------------------------------------------
77 
78   -----------------------------------------------------------------------*/
queryDispatch(const util::URL & aURL,const OUString & aTargetFrameName,sal_Int32 nSearchFlags)79 uno::Reference< frame::XDispatch > SwXDispatchProviderInterceptor::queryDispatch(
80 	const util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags )
81 		throw(uno::RuntimeException)
82 {
83     DispatchMutexLock_Impl aLock(*this);
84 	uno::Reference< frame::XDispatch> xResult;
85 	// create some dispatch ...
86     if(m_pView && !aURL.Complete.compareToAscii(cURLStart, 23))
87 	{
88         if(!aURL.Complete.compareToAscii(cURLFormLetter) ||
89             !aURL.Complete.compareToAscii(cURLInsertContent) ||
90                 !aURL.Complete.compareToAscii(cURLInsertColumns)||
91                     !aURL.Complete.compareToAscii(cURLDocumentDataSource))
92         {
93             if(!m_xDispatch.is())
94                 m_xDispatch = new SwXDispatch(*m_pView);
95             xResult = m_xDispatch;
96 		}
97     }
98 
99 	// ask our slave provider
100 	if (!xResult.is() && m_xSlaveDispatcher.is())
101 		xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
102 
103 	return xResult;
104 }
105 /*-- 07.11.00 13:25:52---------------------------------------------------
106 
107   -----------------------------------------------------------------------*/
queryDispatches(const uno::Sequence<frame::DispatchDescriptor> & aDescripts)108 uno::Sequence< uno::Reference< frame::XDispatch > > SwXDispatchProviderInterceptor::queryDispatches(
109 	const uno::Sequence< frame::DispatchDescriptor >& aDescripts ) throw(uno::RuntimeException)
110 {
111     DispatchMutexLock_Impl aLock(*this);
112     uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
113 	uno::Reference< frame::XDispatch>* pReturn = aReturn.getArray();
114 	const frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray();
115 	for (sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts)
116 	{
117 		*pReturn = queryDispatch(pDescripts->FeatureURL,
118 				pDescripts->FrameName, pDescripts->SearchFlags);
119 	}
120 	return aReturn;
121 }
122 /*-- 07.11.00 13:25:52---------------------------------------------------
123 
124   -----------------------------------------------------------------------*/
getSlaveDispatchProvider()125 uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getSlaveDispatchProvider(  )
126 		throw(uno::RuntimeException)
127 {
128     DispatchMutexLock_Impl aLock(*this);
129     return m_xSlaveDispatcher;
130 }
131 /*-- 07.11.00 13:25:52---------------------------------------------------
132 
133   -----------------------------------------------------------------------*/
setSlaveDispatchProvider(const uno::Reference<frame::XDispatchProvider> & xNewDispatchProvider)134 void SwXDispatchProviderInterceptor::setSlaveDispatchProvider(
135 	const uno::Reference< frame::XDispatchProvider >& xNewDispatchProvider ) throw(uno::RuntimeException)
136 {
137     DispatchMutexLock_Impl aLock(*this);
138     m_xSlaveDispatcher = xNewDispatchProvider;
139 }
140 /*-- 07.11.00 13:25:52---------------------------------------------------
141 
142   -----------------------------------------------------------------------*/
getMasterDispatchProvider()143 uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getMasterDispatchProvider(  )
144 		throw(uno::RuntimeException)
145 {
146     DispatchMutexLock_Impl aLock(*this);
147     return m_xMasterDispatcher;
148 }
149 /*-- 07.11.00 13:25:52---------------------------------------------------
150 
151   -----------------------------------------------------------------------*/
setMasterDispatchProvider(const uno::Reference<frame::XDispatchProvider> & xNewSupplier)152 void SwXDispatchProviderInterceptor::setMasterDispatchProvider(
153 	const uno::Reference< frame::XDispatchProvider >& xNewSupplier ) throw(uno::RuntimeException)
154 {
155     DispatchMutexLock_Impl aLock(*this);
156     m_xMasterDispatcher = xNewSupplier;
157 }
158 /*-- 07.11.00 13:25:53---------------------------------------------------
159 
160   -----------------------------------------------------------------------*/
disposing(const lang::EventObject &)161 void SwXDispatchProviderInterceptor::disposing( const lang::EventObject& )
162 	throw(uno::RuntimeException)
163 {
164     DispatchMutexLock_Impl aLock(*this);
165     if (m_xIntercepted.is())
166 	{
167 		m_xIntercepted->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this);
168 		uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
169 		if (xInterceptedComponent.is())
170 			xInterceptedComponent->removeEventListener((lang::XEventListener*)this);
171         m_xDispatch       = 0;
172 	}
173 	m_xIntercepted = NULL;
174 }
175 /* -----------------------------01.10.2001 14:31------------------------------
176 
177  ---------------------------------------------------------------------------*/
getUnoTunnelId()178 const uno::Sequence< sal_Int8 > & SwXDispatchProviderInterceptor::getUnoTunnelId()
179 {
180     static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
181 	return aSeq;
182 }
183 /* -----------------------------01.10.2001 14:31------------------------------
184 
185  ---------------------------------------------------------------------------*/
getSomething(const uno::Sequence<sal_Int8> & aIdentifier)186 sal_Int64 SwXDispatchProviderInterceptor::getSomething(
187     const uno::Sequence< sal_Int8 >& aIdentifier )
188         throw(uno::RuntimeException)
189 {
190     if( aIdentifier.getLength() == 16
191         && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
192                                         aIdentifier.getConstArray(), 16 ) )
193     {
194             return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
195     }
196 	return 0;
197 }
198 /* -----------------------------01.10.2001 14:32------------------------------
199 
200  ---------------------------------------------------------------------------*/
Invalidate()201 void    SwXDispatchProviderInterceptor::Invalidate()
202 {
203     DispatchMutexLock_Impl aLock(*this);
204     if (m_xIntercepted.is())
205 	{
206 		m_xIntercepted->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this);
207 		uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
208 		if (xInterceptedComponent.is())
209 			xInterceptedComponent->removeEventListener((lang::XEventListener*)this);
210         m_xDispatch       = 0;
211 	}
212 	m_xIntercepted = NULL;
213     m_pView = 0;
214 }
215 /* -----------------------------07.11.00 14:26--------------------------------
216 
217  ---------------------------------------------------------------------------*/
SwXDispatch(SwView & rVw)218 SwXDispatch::SwXDispatch(SwView& rVw) :
219     m_pView(&rVw),
220     m_bOldEnable(sal_False),
221     m_bListenerAdded(sal_False)
222 {
223 }
224 /*-- 07.11.00 14:26:13---------------------------------------------------
225 
226   -----------------------------------------------------------------------*/
~SwXDispatch()227 SwXDispatch::~SwXDispatch()
228 {
229     if(m_bListenerAdded && m_pView)
230     {
231         uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
232         uno::Reference<view::XSelectionChangeListener> xThis = this;
233         xSupplier->removeSelectionChangeListener(xThis);
234     }
235 }
236 /*-- 07.11.00 14:26:13---------------------------------------------------
237 
238   -----------------------------------------------------------------------*/
dispatch(const util::URL & aURL,const uno::Sequence<beans::PropertyValue> & aArgs)239 void SwXDispatch::dispatch(
240 	const util::URL& aURL, const uno::Sequence< beans::PropertyValue >& aArgs ) throw(uno::RuntimeException)
241 {
242     if(!m_pView)
243         throw uno::RuntimeException();
244     SwWrtShell& rSh = m_pView->GetWrtShell();
245 	SwNewDBMgr* pNewDBMgr = rSh.GetNewDBMgr();
246 	if(!aURL.Complete.compareToAscii(cURLInsertContent))
247 	{
248 		::svx::ODataAccessDescriptor aDescriptor(aArgs);
249         SwMergeDescriptor aMergeDesc( DBMGR_MERGE, rSh, aDescriptor );
250         pNewDBMgr->MergeNew(aMergeDesc);
251 	}
252 	else if(!aURL.Complete.compareToAscii(cURLInsertColumns))
253 	{
254 		pNewDBMgr->InsertText(rSh, aArgs);
255 	}
256 	else if(!aURL.Complete.compareToAscii(cURLFormLetter))
257 	{
258         SfxUsrAnyItem aDBProperties(FN_PARAM_DATABASE_PROPERTIES, uno::makeAny(aArgs));
259         m_pView->GetViewFrame()->GetDispatcher()->Execute(
260             FN_MAILMERGE_WIZARD,
261             SFX_CALLMODE_ASYNCHRON,
262             &aDBProperties, 0L);
263 //      pNewDBMgr->ExecuteFormLetter(rSh, aArgs);
264 	}
265     else if(!aURL.Complete.compareToAscii(cURLDocumentDataSource))
266 	{
267 		OSL_ENSURE(sal_False, "SwXDispatch::dispatch: this URL is not to be dispatched!");
268 	}
269     else if(!aURL.Complete.compareToAscii(cInternalDBChangeNotification))
270 	{
271         frame::FeatureStateEvent aEvent;
272         aEvent.IsEnabled = sal_True;
273         aEvent.Source = *(cppu::OWeakObject*)this;
274 
275         const SwDBData& rData = m_pView->GetWrtShell().GetDBDesc();
276         ::svx::ODataAccessDescriptor aDescriptor;
277         aDescriptor.setDataSource(rData.sDataSource);
278         aDescriptor[::svx::daCommand]       <<= rData.sCommand;
279         aDescriptor[::svx::daCommandType]   <<= rData.nCommandType;
280 
281         aEvent.State <<= aDescriptor.createPropertyValueSequence();
282         aEvent.IsEnabled = rData.sDataSource.getLength() > 0;
283 
284         StatusListenerList::iterator aListIter = m_aListenerList.begin();
285         for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter)
286         {
287             StatusStruct_Impl aStatus = *aListIter;
288             if(!aStatus.aURL.Complete.compareToAscii(cURLDocumentDataSource))
289             {
290                 aEvent.FeatureURL = aStatus.aURL;
291                 aStatus.xListener->statusChanged( aEvent );
292             }
293         }
294     }
295     else
296 		throw uno::RuntimeException();
297 
298 }
299 /*-- 07.11.00 14:26:13---------------------------------------------------
300 
301   -----------------------------------------------------------------------*/
addStatusListener(const uno::Reference<frame::XStatusListener> & xControl,const util::URL & aURL)302 void SwXDispatch::addStatusListener(
303 	const uno::Reference< frame::XStatusListener >& xControl, const util::URL& aURL ) throw(uno::RuntimeException)
304 {
305     if(!m_pView)
306         throw uno::RuntimeException();
307     ShellModes eMode = m_pView->GetShellMode();
308     sal_Bool bEnable = SHELL_MODE_TEXT == eMode  ||
309                        SHELL_MODE_LIST_TEXT == eMode  ||
310                        SHELL_MODE_TABLE_TEXT == eMode  ||
311                        SHELL_MODE_TABLE_LIST_TEXT == eMode;
312 
313     m_bOldEnable = bEnable;
314     frame::FeatureStateEvent aEvent;
315     aEvent.IsEnabled = bEnable;
316 	aEvent.Source = *(cppu::OWeakObject*)this;
317 	aEvent.FeatureURL = aURL;
318 
319     // one of the URLs requires a special state ....
320 	if (!aURL.Complete.compareToAscii(cURLDocumentDataSource))
321 	{
322         const SwDBData& rData = m_pView->GetWrtShell().GetDBDesc();
323 
324         ::svx::ODataAccessDescriptor aDescriptor;
325         aDescriptor.setDataSource(rData.sDataSource);
326         aDescriptor[::svx::daCommand]       <<= rData.sCommand;
327         aDescriptor[::svx::daCommandType]   <<= rData.nCommandType;
328 
329 		aEvent.State <<= aDescriptor.createPropertyValueSequence();
330         aEvent.IsEnabled = rData.sDataSource.getLength() > 0;
331 	}
332 
333 
334     xControl->statusChanged( aEvent );
335 
336     StatusListenerList::iterator aListIter = m_aListenerList.begin();
337     StatusStruct_Impl aStatus;
338     aStatus.xListener = xControl;
339     aStatus.aURL = aURL;
340     m_aListenerList.insert(aListIter, aStatus);
341 
342     if(!m_bListenerAdded)
343     {
344         uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
345         uno::Reference<view::XSelectionChangeListener> xThis = this;
346         xSupplier->addSelectionChangeListener(xThis);
347         m_bListenerAdded = sal_True;
348     }
349 }
350 /*-- 07.11.00 14:26:15---------------------------------------------------
351 
352   -----------------------------------------------------------------------*/
removeStatusListener(const uno::Reference<frame::XStatusListener> & xControl,const util::URL &)353 void SwXDispatch::removeStatusListener(
354     const uno::Reference< frame::XStatusListener >& xControl, const util::URL&  ) throw(uno::RuntimeException)
355 {
356     StatusListenerList::iterator aListIter = m_aListenerList.begin();
357     for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter)
358 	{
359         StatusStruct_Impl aStatus = *aListIter;
360         if(aStatus.xListener.get() == xControl.get())
361 		{
362             m_aListenerList.erase(aListIter);
363 			break;
364 		}
365 	}
366     if(m_aListenerList.empty() && m_pView)
367     {
368         uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
369         uno::Reference<view::XSelectionChangeListener> xThis = this;
370         xSupplier->removeSelectionChangeListener(xThis);
371         m_bListenerAdded = sal_False;
372     }
373 }
374 /* -----------------------------07.03.01 10:27--------------------------------
375 
376  ---------------------------------------------------------------------------*/
selectionChanged(const lang::EventObject &)377 void SwXDispatch::selectionChanged( const lang::EventObject&  ) throw(uno::RuntimeException)
378 {
379     ShellModes eMode = m_pView->GetShellMode();
380     sal_Bool bEnable = SHELL_MODE_TEXT == eMode  ||
381                        SHELL_MODE_LIST_TEXT == eMode  ||
382                        SHELL_MODE_TABLE_TEXT == eMode  ||
383                        SHELL_MODE_TABLE_LIST_TEXT == eMode;
384     if(bEnable != m_bOldEnable)
385     {
386         m_bOldEnable = bEnable;
387         frame::FeatureStateEvent aEvent;
388         aEvent.IsEnabled = bEnable;
389         aEvent.Source = *(cppu::OWeakObject*)this;
390 
391         StatusListenerList::iterator aListIter = m_aListenerList.begin();
392         for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter)
393         {
394             StatusStruct_Impl aStatus = *aListIter;
395             aEvent.FeatureURL = aStatus.aURL;
396             if (0 != aStatus.aURL.Complete.compareToAscii(cURLDocumentDataSource))
397 				// the document's data source does not depend on the selection, so it's state does not change here
398                 aStatus.xListener->statusChanged( aEvent );
399         }
400     }
401 }
402 /* -----------------------------07.03.01 10:46--------------------------------
403 
404  ---------------------------------------------------------------------------*/
disposing(const lang::EventObject & rSource)405 void SwXDispatch::disposing( const lang::EventObject& rSource ) throw(uno::RuntimeException)
406 {
407     uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
408     uno::Reference<view::XSelectionChangeListener> xThis = this;
409     xSupplier->removeSelectionChangeListener(xThis);
410     m_bListenerAdded = sal_False;
411 
412     lang::EventObject aObject;
413     aObject.Source = (cppu::OWeakObject*)this;
414     StatusListenerList::iterator aListIter = m_aListenerList.begin();
415     for(; aListIter != m_aListenerList.end(); ++aListIter)
416 	{
417         StatusStruct_Impl aStatus = *aListIter;
418         aStatus.xListener->disposing(aObject);
419 	}
420     m_pView = 0;
421 }
422 /* -----------------------------12.07.01 13:30--------------------------------
423 
424  ---------------------------------------------------------------------------*/
GetDBChangeURL()425 const sal_Char* SwXDispatch::GetDBChangeURL()
426 {
427     return cInternalDBChangeNotification;
428 }
429 /* -----------------------------09.09.2002 08:48------------------------------
430 
431  ---------------------------------------------------------------------------*/
DispatchMutexLock_Impl(SwXDispatchProviderInterceptor &)432 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::DispatchMutexLock_Impl(
433                                                  SwXDispatchProviderInterceptor& ) :
434 //    aGuard(rInterceptor.m_aMutex) #102295# solar mutex has to be used currently
435     aGuard(Application::GetSolarMutex())
436 {
437 }
438 /* -----------------------------09.09.2002 08:48------------------------------
439 
440  ---------------------------------------------------------------------------*/
~DispatchMutexLock_Impl()441 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::~DispatchMutexLock_Impl()
442 {
443 }
444 
445