tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / dbaccess / source / ui / browser / exsrcbrw.cxx
blobffcf40e3c91d0bab85ac456f0cd3349ed8c76eb0
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 <exsrcbrw.hxx>
21 #include <com/sun/star/util/XURLTransformer.hpp>
22 #include <com/sun/star/form/XGridColumnFactory.hpp>
23 #include <com/sun/star/form/XLoadable.hpp>
24 #include <com/sun/star/frame/FrameSearchFlag.hpp>
25 #include <formadapter.hxx>
26 #include <strings.hxx>
27 #include <o3tl/any.hxx>
28 #include <comphelper/diagnose_ex.hxx>
29 #include <sal/log.hxx>
31 using namespace ::com::sun::star::uno;
32 using namespace ::com::sun::star::sdbc;
33 using namespace ::com::sun::star::sdbcx;
34 using namespace ::com::sun::star::beans;
35 using namespace ::com::sun::star::container;
36 using namespace ::com::sun::star::lang;
37 using namespace ::com::sun::star::form;
38 using namespace ::com::sun::star::frame;
39 using namespace dbaui;
41 // SbaExternalSourceBrowser
42 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
43 org_openoffice_comp_dbu_OFormGridView_get_implementation(
44 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
46 return cppu::acquire(new SbaExternalSourceBrowser(context));
49 Any SAL_CALL SbaExternalSourceBrowser::queryInterface(const Type& _rType)
51 Any aRet = SbaXDataBrowserController::queryInterface(_rType);
52 if(!aRet.hasValue())
53 aRet = ::cppu::queryInterface(_rType,
54 static_cast<css::util::XModifyBroadcaster*>(this),
55 static_cast<css::form::XLoadListener*>(this));
57 return aRet;
60 SbaExternalSourceBrowser::SbaExternalSourceBrowser(const Reference< css::uno::XComponentContext >& _rM)
61 :SbaXDataBrowserController(_rM)
62 ,m_aModifyListeners(getMutex())
63 ,m_bInQueryDispatch( false )
68 SbaExternalSourceBrowser::~SbaExternalSourceBrowser()
72 css::uno::Sequence<OUString> SAL_CALL SbaExternalSourceBrowser::getSupportedServiceNames()
74 return { u"com.sun.star.sdb.FormGridView"_ustr };
77 OUString SAL_CALL SbaExternalSourceBrowser::getImplementationName()
79 return u"org.openoffice.comp.dbu.OFormGridView"_ustr;
82 Reference< XRowSet > SbaExternalSourceBrowser::CreateForm()
84 m_pDataSourceImpl = new SbaXFormAdapter();
85 return m_pDataSourceImpl;
88 bool SbaExternalSourceBrowser::InitializeForm(const Reference< XPropertySet > & /*i_formProperties*/)
90 return true;
93 bool SbaExternalSourceBrowser::LoadForm()
95 // as we don't have a main form (yet), we have nothing to do
96 // we don't call FormLoaded, because this expects a working data source
97 return true;
100 void SbaExternalSourceBrowser::modified(const css::lang::EventObject& aEvent)
102 SbaXDataBrowserController::modified(aEvent);
104 // multiplex this event to all my listeners
105 css::lang::EventObject aEvt(*this);
106 m_aModifyListeners.notifyEach( &css::util::XModifyListener::modified, aEvt );
109 void SAL_CALL SbaExternalSourceBrowser::dispatch(const css::util::URL& aURL, const Sequence< css::beans::PropertyValue>& aArgs)
111 if ( aURL.Complete == ".uno:FormSlots/AddGridColumn" )
113 // search the argument describing the column to create
114 OUString sControlType;
115 sal_Int32 nControlPos = -1;
116 Sequence< css::beans::PropertyValue> aControlProps;
117 for ( const css::beans::PropertyValue& rArgument : aArgs )
119 if ( rArgument.Name == "ColumnType" )
121 auto s = o3tl::tryAccess<OUString>(rArgument.Value);
122 OSL_ENSURE(s, "invalid type for argument \"ColumnType\" !");
123 if (s)
124 sControlType = *s;
126 else if ( rArgument.Name == "ColumnPosition" )
128 auto n = o3tl::tryAccess<sal_Int16>(rArgument.Value);
129 OSL_ENSURE(n, "invalid type for argument \"ColumnPosition\" !");
130 if (n)
131 nControlPos = *n;
133 else if ( rArgument.Name == "ColumnProperties" )
135 auto s = o3tl::tryAccess<Sequence<css::beans::PropertyValue>>(
136 rArgument.Value);
137 OSL_ENSURE(s, "invalid type for argument \"ColumnProperties\" !");
138 if (s)
139 aControlProps = *s;
141 else
142 SAL_WARN("dbaccess.ui", "SbaExternalSourceBrowser::dispatch(AddGridColumn) : unknown argument (" << rArgument.Name << ") !");
144 if (sControlType.isEmpty())
146 SAL_WARN("dbaccess.ui", "SbaExternalSourceBrowser::dispatch(AddGridColumn) : missing argument (ColumnType) !");
147 sControlType = "TextField";
149 OSL_ENSURE(aControlProps.hasElements(), "SbaExternalSourceBrowser::dispatch(AddGridColumn) : missing argument (ColumnProperties) !");
151 // create the col
152 Reference< css::form::XGridColumnFactory > xColFactory(getControlModel(), UNO_QUERY);
153 Reference< css::beans::XPropertySet > xNewCol = xColFactory->createColumn(sControlType);
154 Reference< XPropertySetInfo > xNewColProperties;
155 if (xNewCol.is())
156 xNewColProperties = xNewCol->getPropertySetInfo();
157 // set its properties
158 if (xNewColProperties.is())
160 for (const css::beans::PropertyValue& rControlProp : aControlProps)
164 if (xNewColProperties->hasPropertyByName(rControlProp.Name))
165 xNewCol->setPropertyValue(rControlProp.Name, rControlProp.Value);
167 catch (const Exception&)
169 SAL_WARN("dbaccess.ui", "SbaExternalSourceBrowser::dispatch : could not set a column property (" << rControlProp.Name << ")!");
174 // correct the position
175 Reference< css::container::XIndexContainer > xColContainer(getControlModel(), UNO_QUERY);
177 if (nControlPos > xColContainer->getCount())
178 nControlPos = xColContainer->getCount();
179 if (nControlPos < 0)
180 nControlPos = 0;
182 // append the column
183 xColContainer->insertByIndex(nControlPos, Any(xNewCol));
185 else if ( aURL.Complete == ".uno:FormSlots/ClearView" )
187 ClearView();
189 else if ( aURL.Complete == ".uno:FormSlots/AttachToForm" )
191 if (!m_pDataSourceImpl)
192 return;
194 Reference< XRowSet > xMasterForm;
195 // search the arguments for the master form
196 for (const css::beans::PropertyValue& rArgument : aArgs)
198 if ( (rArgument.Name == "MasterForm") && (rArgument.Value.getValueTypeClass() == TypeClass_INTERFACE) )
200 xMasterForm.set(rArgument.Value, UNO_QUERY);
201 break;
204 if (!xMasterForm.is())
206 SAL_WARN("dbaccess.ui", "SbaExternalSourceBrowser::dispatch(FormSlots/AttachToForm) : please specify a form to attach to as argument !");
207 return;
210 Attach(xMasterForm);
212 else
213 SbaXDataBrowserController::dispatch(aURL, aArgs);
216 Reference< css::frame::XDispatch > SAL_CALL SbaExternalSourceBrowser::queryDispatch(const css::util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags)
218 Reference< css::frame::XDispatch > xReturn;
219 if (m_bInQueryDispatch)
220 return xReturn;
222 m_bInQueryDispatch = true;
224 if ( ( aURL.Complete == ".uno:FormSlots/AttachToForm" )
225 // attach a new external form
226 || ( aURL.Complete == ".uno:FormSlots/AddGridColumn" )
227 // add a column to the grid
228 || ( aURL.Complete == ".uno:FormSlots/ClearView" )
229 // clear the grid
231 xReturn = static_cast<css::frame::XDispatch*>(this);
233 if ( !xReturn.is()
234 && ( (aURL.Complete == ".uno:FormSlots/moveToFirst" ) || (aURL.Complete == ".uno:FormSlots/moveToPrev" )
235 || (aURL.Complete == ".uno:FormSlots/moveToNext" ) || (aURL.Complete == ".uno:FormSlots/moveToLast" )
236 || (aURL.Complete == ".uno:FormSlots/moveToNew" ) || (aURL.Complete == ".uno:FormSlots/undoRecord" )
240 OSL_ENSURE(aURL.Mark.isEmpty(), "SbaExternalSourceBrowser::queryDispatch : the css::util::URL shouldn't have a mark !");
241 css::util::URL aNewUrl = aURL;
243 // split the css::util::URL
244 OSL_ENSURE( m_xUrlTransformer.is(), "SbaExternalSourceBrowser::queryDispatch : could not create a URLTransformer !" );
245 if ( m_xUrlTransformer.is() )
246 m_xUrlTransformer->parseStrict( aNewUrl );
248 // set a new mark
249 aNewUrl.Mark = "DB/FormGridView";
250 // this controller is instantiated when somebody dispatches the ".component:DB/FormGridView" in any
251 // frame, so we use "FormGridView" as mark that a dispatch request came from this view
253 if (m_xUrlTransformer.is())
254 m_xUrlTransformer->assemble(aNewUrl);
256 Reference< XDispatchProvider > xFrameDispatcher( getFrame(), UNO_QUERY );
257 if (xFrameDispatcher.is())
258 xReturn = xFrameDispatcher->queryDispatch(aNewUrl, aTargetFrameName, FrameSearchFlag::PARENT);
262 if (!xReturn.is())
263 xReturn = SbaXDataBrowserController::queryDispatch(aURL, aTargetFrameName, nSearchFlags);
265 m_bInQueryDispatch = false;
266 return xReturn;
269 void SAL_CALL SbaExternalSourceBrowser::disposing()
271 // say our modify listeners goodbye
272 css::lang::EventObject aEvt;
273 aEvt.Source = static_cast<XWeak*>(this);
274 m_aModifyListeners.disposeAndClear(aEvt);
276 stopListening();
278 SbaXDataBrowserController::disposing();
281 void SAL_CALL SbaExternalSourceBrowser::addModifyListener(const Reference< css::util::XModifyListener > & aListener)
283 m_aModifyListeners.addInterface(aListener);
286 void SAL_CALL SbaExternalSourceBrowser::removeModifyListener(const Reference< css::util::XModifyListener > & aListener)
288 m_aModifyListeners.removeInterface(aListener);
291 void SAL_CALL SbaExternalSourceBrowser::unloading(const css::lang::EventObject& aEvent)
293 if (m_pDataSourceImpl && (m_pDataSourceImpl->getAttachedForm() == aEvent.Source))
295 ClearView();
298 SbaXDataBrowserController::unloading(aEvent);
301 void SbaExternalSourceBrowser::Attach(const Reference< XRowSet > & xMaster)
303 Any aOldPos;
304 bool bWasInsertRow = false;
305 bool bBeforeFirst = true;
306 bool bAfterLast = true;
307 Reference< XRowLocate > xCursor(xMaster, UNO_QUERY);
308 Reference< XPropertySet > xMasterProps(xMaster, UNO_QUERY);
312 // switch the control to design mode
313 if (getBrowserView() && getBrowserView()->getGridControl().is())
314 getBrowserView()->getGridControl()->setDesignMode(true);
316 // the grid will move the form's cursor to the first record, but we want the form to remain unchanged
317 // restore the old position
318 if (xCursor.is() && xMaster.is())
320 bBeforeFirst = xMaster->isBeforeFirst();
321 bAfterLast = xMaster->isAfterLast();
322 if(!bBeforeFirst && !bAfterLast)
323 aOldPos = xCursor->getBookmark();
326 if (xMasterProps.is())
327 xMasterProps->getPropertyValue(PROPERTY_ISNEW) >>= bWasInsertRow;
329 catch( const Exception& )
331 DBG_UNHANDLED_EXCEPTION("dbaccess");
334 onStartLoading( Reference< XLoadable >( xMaster, UNO_QUERY ) );
336 stopListening();
337 m_pDataSourceImpl->AttachForm(xMaster);
338 startListening();
340 if (!xMaster.is())
341 return;
343 // at this point we have to reset the formatter for the new form
344 initFormatter();
345 // assume that the master form is already loaded
346 #if OSL_DEBUG_LEVEL > 0
348 Reference< XLoadable > xLoadable( xMaster, UNO_QUERY );
349 OSL_ENSURE( xLoadable.is() && xLoadable->isLoaded(), "SbaExternalSourceBrowser::Attach: master is not loaded!" );
351 #endif
353 LoadFinished(true);
355 Reference< XResultSetUpdate > xUpdate(xMaster, UNO_QUERY);
358 if (bWasInsertRow && xUpdate.is())
359 xUpdate->moveToInsertRow();
360 else if (xCursor.is() && aOldPos.hasValue())
361 xCursor->moveToBookmark(aOldPos);
362 else if(bBeforeFirst && xMaster.is())
363 xMaster->beforeFirst();
364 else if(bAfterLast && xMaster.is())
365 xMaster->afterLast();
367 catch(Exception&)
369 SAL_WARN("dbaccess.ui", "SbaExternalSourceBrowser::Attach : couldn't restore the cursor position !");
373 void SbaExternalSourceBrowser::ClearView()
375 // set a new (empty) datasource
376 Attach(Reference< XRowSet > ());
378 // clear all cols in the grid
379 Reference< css::container::XIndexContainer > xColContainer(getControlModel(), UNO_QUERY);
380 while (xColContainer->getCount() > 0)
381 xColContainer->removeByIndex(0);
384 void SAL_CALL SbaExternalSourceBrowser::disposing(const css::lang::EventObject& Source)
386 if (m_pDataSourceImpl && (m_pDataSourceImpl->getAttachedForm() == Source.Source))
388 ClearView();
391 SbaXDataBrowserController::disposing(Source);
394 void SbaExternalSourceBrowser::startListening()
396 if (m_pDataSourceImpl && m_pDataSourceImpl->getAttachedForm().is())
398 Reference< css::form::XLoadable > xLoadable(m_pDataSourceImpl->getAttachedForm(), UNO_QUERY);
399 xLoadable->addLoadListener(static_cast<css::form::XLoadListener*>(this));
403 void SbaExternalSourceBrowser::stopListening()
405 if (m_pDataSourceImpl && m_pDataSourceImpl->getAttachedForm().is())
407 Reference< css::form::XLoadable > xLoadable(m_pDataSourceImpl->getAttachedForm(), UNO_QUERY);
408 xLoadable->removeLoadListener(static_cast<css::form::XLoadListener*>(this));
412 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */