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