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 fullfill
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