docthemes: Save themes def. to a file when added to ColorSets
[LibreOffice.git] / sw / source / uibase / uno / unodispatch.cxx
blob7a8876d20a20ca99b78de9f9a6e4facc2447138c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
21 #include <config_fuzzers.h>
23 #include <com/sun/star/frame/XFrame.hpp>
24 #include <com/sun/star/view/XSelectionSupplier.hpp>
26 #include <sfx2/viewfrm.hxx>
27 #include <sfx2/dispatch.hxx>
28 #include <svx/dataaccessdescriptor.hxx>
29 #include <comphelper/servicehelper.hxx>
30 #include <osl/diagnose.h>
31 #include <unodispatch.hxx>
32 #include <view.hxx>
33 #include <cmdid.h>
34 #include <wrtsh.hxx>
35 #include <dbmgr.hxx>
37 using namespace ::com::sun::star;
39 const char cURLFormLetter[] = ".uno:DataSourceBrowser/FormLetter";
40 const char cURLInsertContent[] = ".uno:DataSourceBrowser/InsertContent";//data into fields
41 const char cURLInsertColumns[] = ".uno:DataSourceBrowser/InsertColumns";//data into text
42 const char cURLDocumentDataSource[] = ".uno:DataSourceBrowser/DocumentDataSource";//current data source of the document
43 const char cInternalDBChangeNotification[] = ".uno::Writer/DataSourceChanged";
45 SwXDispatchProviderInterceptor::SwXDispatchProviderInterceptor(SwView& rVw) :
46 m_pView(&rVw)
48 uno::Reference< frame::XFrame> xUnoFrame = m_pView->GetViewFrame().GetFrame().GetFrameInterface();
49 m_xIntercepted.set(xUnoFrame, uno::UNO_QUERY);
50 if(m_xIntercepted.is())
52 osl_atomic_increment(&m_refCount);
53 m_xIntercepted->registerDispatchProviderInterceptor(static_cast<frame::XDispatchProviderInterceptor*>(this));
54 // this should make us the top-level dispatch-provider for the component, via a call to our
55 // setDispatchProvider we should have got a fallback for requests we (i.e. our master) cannot fulfill
56 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
57 if (xInterceptedComponent.is())
58 xInterceptedComponent->addEventListener(static_cast<lang::XEventListener*>(this));
59 osl_atomic_decrement(&m_refCount);
63 SwXDispatchProviderInterceptor::~SwXDispatchProviderInterceptor()
67 uno::Reference< frame::XDispatch > SwXDispatchProviderInterceptor::queryDispatch(
68 const util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags )
70 DispatchMutexLock_Impl aLock;
71 uno::Reference< frame::XDispatch> xResult;
72 // create some dispatch ...
73 if(m_pView && aURL.Complete.startsWith(".uno:DataSourceBrowser/"))
75 if(aURL.Complete == cURLFormLetter ||
76 aURL.Complete == cURLInsertContent ||
77 aURL.Complete == cURLInsertColumns ||
78 aURL.Complete == cURLDocumentDataSource)
80 if(!m_xDispatch.is())
81 m_xDispatch = new SwXDispatch(*m_pView);
82 xResult = m_xDispatch;
86 // ask our slave provider
87 if (!xResult.is() && m_xSlaveDispatcher.is())
88 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
90 return xResult;
93 uno::Sequence<OUString> SAL_CALL SwXDispatchProviderInterceptor::getInterceptedURLs()
95 uno::Sequence<OUString> aRet =
97 u".uno:DataSourceBrowser/*"_ustr
100 return aRet;
103 uno::Sequence< uno::Reference< frame::XDispatch > > SwXDispatchProviderInterceptor::queryDispatches(
104 const uno::Sequence< frame::DispatchDescriptor >& aDescripts )
106 DispatchMutexLock_Impl aLock;
107 uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
108 std::transform(aDescripts.begin(), aDescripts.end(), aReturn.getArray(),
109 [this](const frame::DispatchDescriptor& rDescr) -> uno::Reference<frame::XDispatch> {
110 return queryDispatch(rDescr.FeatureURL, rDescr.FrameName, rDescr.SearchFlags); });
111 return aReturn;
114 uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getSlaveDispatchProvider( )
116 DispatchMutexLock_Impl aLock;
117 return m_xSlaveDispatcher;
120 void SwXDispatchProviderInterceptor::setSlaveDispatchProvider(
121 const uno::Reference< frame::XDispatchProvider >& xNewDispatchProvider )
123 DispatchMutexLock_Impl aLock;
124 m_xSlaveDispatcher = xNewDispatchProvider;
127 uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getMasterDispatchProvider( )
129 DispatchMutexLock_Impl aLock;
130 return m_xMasterDispatcher;
133 void SwXDispatchProviderInterceptor::setMasterDispatchProvider(
134 const uno::Reference< frame::XDispatchProvider >& xNewSupplier )
136 DispatchMutexLock_Impl aLock;
137 m_xMasterDispatcher = xNewSupplier;
140 void SwXDispatchProviderInterceptor::disposing( const lang::EventObject& )
142 DispatchMutexLock_Impl aLock;
143 if (m_xIntercepted.is())
145 m_xIntercepted->releaseDispatchProviderInterceptor(static_cast<frame::XDispatchProviderInterceptor*>(this));
146 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
147 if (xInterceptedComponent.is())
148 xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
149 m_xDispatch = nullptr;
151 m_xIntercepted = nullptr;
154 void SwXDispatchProviderInterceptor::Invalidate()
156 DispatchMutexLock_Impl aLock;
157 if (m_xIntercepted.is())
159 m_xIntercepted->releaseDispatchProviderInterceptor(static_cast<frame::XDispatchProviderInterceptor*>(this));
160 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
161 if (xInterceptedComponent.is())
162 xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
163 m_xDispatch = nullptr;
165 m_xIntercepted = nullptr;
166 m_pView = nullptr;
169 SwXDispatch::SwXDispatch(SwView& rVw) :
170 m_pView(&rVw),
171 m_bOldEnable(false),
172 m_bListenerAdded(false)
176 SwXDispatch::~SwXDispatch()
178 if(m_bListenerAdded && m_pView)
180 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
181 uno::Reference<view::XSelectionChangeListener> xThis = this;
182 xSupplier->removeSelectionChangeListener(xThis);
186 void SwXDispatch::dispatch(const util::URL& aURL,
187 const uno::Sequence< beans::PropertyValue >& aArgs)
189 if(!m_pView)
190 throw uno::RuntimeException();
191 #if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
192 (void) aArgs;
193 if (false)
196 #else
197 SwWrtShell& rSh = m_pView->GetWrtShell();
198 SwDBManager* pDBManager = rSh.GetDBManager();
199 if(aURL.Complete == cURLInsertContent)
201 svx::ODataAccessDescriptor aDescriptor(aArgs);
202 SwMergeDescriptor aMergeDesc( DBMGR_MERGE, rSh, aDescriptor );
203 pDBManager->Merge(aMergeDesc);
205 else if(aURL.Complete == cURLInsertColumns)
207 SwDBManager::InsertText(rSh, aArgs);
209 else if(aURL.Complete == cURLFormLetter)
211 SfxUnoAnyItem aDBProperties(FN_PARAM_DATABASE_PROPERTIES, uno::Any(aArgs));
212 m_pView->GetViewFrame().GetDispatcher()->ExecuteList(
213 FN_MAILMERGE_WIZARD,
214 SfxCallMode::ASYNCHRON,
215 { &aDBProperties });
217 #endif
218 else if(aURL.Complete == cURLDocumentDataSource)
220 OSL_FAIL("SwXDispatch::dispatch: this URL is not to be dispatched!");
222 else if(aURL.Complete == cInternalDBChangeNotification)
224 frame::FeatureStateEvent aEvent;
225 aEvent.Source = getXWeak();
227 const SwDBData& rData = m_pView->GetWrtShell().GetDBData();
228 svx::ODataAccessDescriptor aDescriptor;
229 aDescriptor.setDataSource(rData.sDataSource);
230 aDescriptor[svx::DataAccessDescriptorProperty::Command] <<= rData.sCommand;
231 aDescriptor[svx::DataAccessDescriptorProperty::CommandType] <<= rData.nCommandType;
233 aEvent.State <<= aDescriptor.createPropertyValueSequence();
234 aEvent.IsEnabled = !rData.sDataSource.isEmpty();
236 // calls to statusChanged may call addStatusListener or removeStatusListener
237 // so copy m_aStatusListenerVector on stack
238 auto copyStatusListenerVector = m_aStatusListenerVector;
239 for (auto & status : copyStatusListenerVector)
241 if(status.aURL.Complete == cURLDocumentDataSource)
243 aEvent.FeatureURL = status.aURL;
244 status.xListener->statusChanged( aEvent );
248 else
249 throw uno::RuntimeException();
253 void SwXDispatch::addStatusListener(
254 const uno::Reference< frame::XStatusListener >& xControl, const util::URL& aURL )
256 if(!m_pView)
257 throw uno::RuntimeException();
258 ShellMode eMode = m_pView->GetShellMode();
259 bool bEnable = ShellMode::Text == eMode ||
260 ShellMode::ListText == eMode ||
261 ShellMode::TableText == eMode ||
262 ShellMode::TableListText == eMode;
264 m_bOldEnable = bEnable;
265 frame::FeatureStateEvent aEvent;
266 aEvent.IsEnabled = bEnable;
267 aEvent.Source = getXWeak();
268 aEvent.FeatureURL = aURL;
270 // one of the URLs requires a special state...
271 if (aURL.Complete == cURLDocumentDataSource)
273 const SwDBData& rData = m_pView->GetWrtShell().GetDBData();
275 svx::ODataAccessDescriptor aDescriptor;
276 aDescriptor.setDataSource(rData.sDataSource);
277 aDescriptor[svx::DataAccessDescriptorProperty::Command] <<= rData.sCommand;
278 aDescriptor[svx::DataAccessDescriptorProperty::CommandType] <<= rData.nCommandType;
280 aEvent.State <<= aDescriptor.createPropertyValueSequence();
281 aEvent.IsEnabled = !rData.sDataSource.isEmpty();
284 xControl->statusChanged( aEvent );
286 StatusStruct_Impl aStatus;
287 aStatus.xListener = xControl;
288 aStatus.aURL = aURL;
289 m_aStatusListenerVector.emplace_back(aStatus);
291 if(!m_bListenerAdded)
293 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
294 uno::Reference<view::XSelectionChangeListener> xThis = this;
295 xSupplier->addSelectionChangeListener(xThis);
296 m_bListenerAdded = true;
300 void SwXDispatch::removeStatusListener(
301 const uno::Reference< frame::XStatusListener >& xControl, const util::URL& )
303 std::erase_if(
304 m_aStatusListenerVector,
305 [&](const StatusStruct_Impl& status) { return status.xListener.get() == xControl.get(); });
306 if(m_aStatusListenerVector.empty() && m_pView)
308 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
309 uno::Reference<view::XSelectionChangeListener> xThis = this;
310 xSupplier->removeSelectionChangeListener(xThis);
311 m_bListenerAdded = false;
315 void SwXDispatch::selectionChanged( const lang::EventObject& )
317 ShellMode eMode = m_pView->GetShellMode();
318 bool bEnable = ShellMode::Text == eMode ||
319 ShellMode::ListText == eMode ||
320 ShellMode::TableText == eMode ||
321 ShellMode::TableListText == eMode;
322 if(bEnable == m_bOldEnable)
323 return;
325 m_bOldEnable = bEnable;
326 frame::FeatureStateEvent aEvent;
327 aEvent.IsEnabled = bEnable;
328 aEvent.Source = getXWeak();
330 // calls to statusChanged may call addStatusListener or removeStatusListener
331 // so copy m_aStatusListenerVector on stack
332 auto copyStatusListenerVector = m_aStatusListenerVector;
333 for (auto & status : copyStatusListenerVector)
335 aEvent.FeatureURL = status.aURL;
336 if (status.aURL.Complete != cURLDocumentDataSource)
337 // the document's data source does not depend on the selection, so it's state does not change here
338 status.xListener->statusChanged( aEvent );
342 void SwXDispatch::disposing( const lang::EventObject& rSource )
344 uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
345 uno::Reference<view::XSelectionChangeListener> xThis = this;
346 xSupplier->removeSelectionChangeListener(xThis);
347 m_bListenerAdded = false;
349 lang::EventObject aObject;
350 aObject.Source = getXWeak();
351 // calls to statusChanged may call addStatusListener or removeStatusListener
352 // so copy m_aStatusListenerVector on stack
353 auto copyStatusListenerVector = m_aStatusListenerVector;
354 for (auto & status : copyStatusListenerVector)
356 status.xListener->disposing(aObject);
358 m_pView = nullptr;
361 const char* SwXDispatch::GetDBChangeURL()
363 return cInternalDBChangeNotification;
366 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::DispatchMutexLock_Impl()
370 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::~DispatchMutexLock_Impl()
374 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */