LibreOffice Module svx (master)  1
fmvwimp.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
21 #include <memory>
23 #include <fmobj.hxx>
24 #include <fmpgeimp.hxx>
25 #include <fmprop.hxx>
26 #include <svx/strings.hrc>
27 #include <fmservs.hxx>
28 #include <fmshimp.hxx>
29 #include <svx/fmtools.hxx>
30 #include <fmvwimp.hxx>
31 #include <formcontrolfactory.hxx>
32 #include <svx/sdrpaintwindow.hxx>
33 #include <svx/svditer.hxx>
35 #include <svx/dialmgr.hxx>
36 #include <svx/svdobjkind.hxx>
37 #include <svx/fmmodel.hxx>
38 #include <svx/fmpage.hxx>
39 #include <svx/fmshell.hxx>
40 #include <svx/fmview.hxx>
41 #include <svx/sdrpagewindow.hxx>
42 #include <svx/svdogrp.hxx>
43 #include <svx/svdpagv.hxx>
44 #include <svx/xmlexchg.hxx>
46 
47 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
48 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
49 #include <com/sun/star/sdbc/XRowSet.hpp>
50 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
51 #include <com/sun/star/util/XNumberFormats.hpp>
52 #include <com/sun/star/sdb/CommandType.hpp>
53 #include <com/sun/star/sdbc/DataType.hpp>
54 #include <com/sun/star/form/FormComponentType.hpp>
55 #include <com/sun/star/form/FormButtonType.hpp>
56 #include <com/sun/star/form/binding/XBindableValue.hpp>
57 #include <com/sun/star/form/binding/XValueBinding.hpp>
58 #include <com/sun/star/form/runtime/FormController.hpp>
59 #include <com/sun/star/form/submission/XSubmissionSupplier.hpp>
60 #include <com/sun/star/awt/XTabControllerModel.hpp>
61 #include <com/sun/star/awt/XControlContainer.hpp>
62 #include <com/sun/star/awt/XTabController.hpp>
63 #include <com/sun/star/container/XIndexAccess.hpp>
64 #include <com/sun/star/awt/XControl.hpp>
65 #include <com/sun/star/sdbc/SQLException.hpp>
66 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
67 #include <com/sun/star/container/XContainer.hpp>
68 
70 #include <comphelper/property.hxx>
72 #include <comphelper/types.hxx>
73 #include <cppuhelper/exc_hlp.hxx>
75 #include <tools/debug.hxx>
76 #include <tools/diagnose_ex.h>
77 #include <sal/log.hxx>
78 #include <vcl/svapp.hxx>
79 #include <vcl/stdtext.hxx>
80 #include <vcl/window.hxx>
81 #include <connectivity/dbtools.hxx>
82 
83 #include <algorithm>
84 
85 using namespace ::comphelper;
86 using namespace ::svx;
87 using namespace ::svxform;
88 using namespace ::dbtools;
89 
90  using namespace ::com::sun::star;
91  using ::com::sun::star::uno::Exception;
92  using ::com::sun::star::uno::XInterface;
93  using ::com::sun::star::uno::Sequence;
94  using ::com::sun::star::uno::UNO_QUERY;
95  using ::com::sun::star::uno::UNO_QUERY_THROW;
96  using ::com::sun::star::uno::UNO_SET_THROW;
97  using ::com::sun::star::uno::Type;
98  using ::com::sun::star::uno::Reference;
99  using ::com::sun::star::uno::Any;
100  using ::com::sun::star::uno::makeAny;
101  using ::com::sun::star::uno::XComponentContext;
102  using ::com::sun::star::form::FormButtonType_SUBMIT;
103  using ::com::sun::star::form::binding::XValueBinding;
104  using ::com::sun::star::form::binding::XBindableValue;
105  using ::com::sun::star::lang::XComponent;
106  using ::com::sun::star::container::XIndexAccess;
107  using ::com::sun::star::form::runtime::FormController;
108  using ::com::sun::star::form::runtime::XFormController;
109  using ::com::sun::star::script::XEventAttacherManager;
110  using ::com::sun::star::awt::XTabControllerModel;
111  using ::com::sun::star::container::XChild;
112  using ::com::sun::star::task::XInteractionHandler;
113  using ::com::sun::star::awt::XTabController;
114  using ::com::sun::star::awt::XControlContainer;
115  using ::com::sun::star::awt::XControl;
116  using ::com::sun::star::form::XFormComponent;
117  using ::com::sun::star::form::XForm;
118  using ::com::sun::star::lang::IndexOutOfBoundsException;
119  using ::com::sun::star::container::XContainer;
120  using ::com::sun::star::container::ContainerEvent;
121  using ::com::sun::star::lang::EventObject;
122  using ::com::sun::star::sdb::SQLErrorEvent;
123  using ::com::sun::star::sdbc::XRowSet;
125  using ::com::sun::star::container::XElementAccess;
126  using ::com::sun::star::awt::XWindow;
127  using ::com::sun::star::awt::FocusEvent;
128  using ::com::sun::star::ui::dialogs::XExecutableDialog;
129  using ::com::sun::star::sdbc::XDataSource;
130  using ::com::sun::star::container::XIndexContainer;
131  using ::com::sun::star::sdbc::XConnection;
132  using ::com::sun::star::container::XNameAccess;
133  using ::com::sun::star::sdbc::SQLException;
134  using ::com::sun::star::util::XNumberFormatsSupplier;
135  using ::com::sun::star::util::XNumberFormats;
136  using ::com::sun::star::beans::XPropertySetInfo;
137 
138  namespace FormComponentType = ::com::sun::star::form::FormComponentType;
139  namespace CommandType = ::com::sun::star::sdb::CommandType;
140  namespace DataType = ::com::sun::star::sdbc::DataType;
141 
142 
144 {
146 public:
147  explicit ObjectRemoveListener( FmXFormView* pParent );
148  virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
149 };
150 
151 FormViewPageWindowAdapter::FormViewPageWindowAdapter( const css::uno::Reference<css::uno::XComponentContext>& _rContext, const SdrPageWindow& _rWindow, FmXFormView* _pViewImpl )
152 : m_xControlContainer( _rWindow.GetControlContainer() ),
153  m_xContext( _rContext ),
154  m_pViewImpl( _pViewImpl ),
155  m_pWindow( dynamic_cast< vcl::Window* >( &_rWindow.GetPaintWindow().GetOutputDevice() ) )
156 {
157 
158  // create an XFormController for every form
159  FmFormPage* pFormPage = dynamic_cast< FmFormPage* >( _rWindow.GetPageView().GetPage() );
160  DBG_ASSERT( pFormPage, "FormViewPageWindowAdapter::FormViewPageWindowAdapter: no FmFormPage found!" );
161  if ( !pFormPage )
162  return;
163 
164  try
165  {
166  Reference< XIndexAccess > xForms( pFormPage->GetForms(), UNO_QUERY_THROW );
167  sal_uInt32 nLength = xForms->getCount();
168  for (sal_uInt32 i = 0; i < nLength; i++)
169  {
170  Reference< XForm > xForm( xForms->getByIndex(i), UNO_QUERY );
171  if ( xForm.is() )
172  setController( xForm, nullptr );
173  }
174  }
175  catch (const Exception&)
176  {
178  }
179 }
180 
182 {
183 }
184 
186 {
187  for ( ::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin();
188  i != m_aControllerList.end();
189  ++i
190  )
191  {
192  try
193  {
194  Reference< XFormController > xController( *i, UNO_SET_THROW );
195 
196  // detaching the events
197  Reference< XChild > xControllerModel( xController->getModel(), UNO_QUERY );
198  if ( xControllerModel.is() )
199  {
200  Reference< XEventAttacherManager > xEventManager( xControllerModel->getParent(), UNO_QUERY_THROW );
201  Reference< XInterface > xControllerNormalized( xController, UNO_QUERY_THROW );
202  xEventManager->detach( i - m_aControllerList.begin(), xControllerNormalized );
203  }
204 
205  // dispose the formcontroller
206  xController->dispose();
207  }
208  catch (const Exception&)
209  {
211  }
212  }
213 
214  m_aControllerList.clear();
215 }
216 
218 {
219  return getCount() != 0;
220 }
221 
223 {
225 }
226 
227 // XIndexAccess
229 {
230  return m_aControllerList.size();
231 }
232 
233 Any SAL_CALL FormViewPageWindowAdapter::getByIndex(sal_Int32 nIndex)
234 {
235  if (nIndex < 0 ||
236  nIndex >= getCount())
237  throw IndexOutOfBoundsException();
238 
239  Any aElement;
240  aElement <<= m_aControllerList[nIndex];
241  return aElement;
242 }
243 
244 void SAL_CALL FormViewPageWindowAdapter::makeVisible( const Reference< XControl >& Control )
245 {
246  SolarMutexGuard aSolarGuard;
247 
248  Reference< XWindow > xWindow( Control, UNO_QUERY );
249  if ( xWindow.is() && m_pViewImpl->getView() && m_pWindow )
250  {
251  awt::Rectangle aRect = xWindow->getPosSize();
252  ::tools::Rectangle aNewRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height );
253  aNewRect = m_pWindow->PixelToLogic( aNewRect );
254  m_pViewImpl->getView()->MakeVisible( aNewRect, *m_pWindow );
255  }
256 }
257 
258 static Reference< XFormController > getControllerSearchChildren( const Reference< XIndexAccess > & xIndex, const Reference< XTabControllerModel > & xModel)
259 {
260  if (xIndex.is() && xIndex->getCount())
261  {
262  Reference< XFormController > xController;
263 
264  for (sal_Int32 n = xIndex->getCount(); n-- && !xController.is(); )
265  {
266  xIndex->getByIndex(n) >>= xController;
267  if (xModel.get() == xController->getModel().get())
268  return xController;
269  else
270  {
271  xController = getControllerSearchChildren(xController, xModel);
272  if ( xController.is() )
273  return xController;
274  }
275  }
276  }
277  return Reference< XFormController > ();
278 }
279 
280 // Search the according controller
281 Reference< XFormController > FormViewPageWindowAdapter::getController( const Reference< XForm > & xForm ) const
282 {
283  Reference< XTabControllerModel > xModel(xForm, UNO_QUERY);
284  for (const auto& rpController : m_aControllerList)
285  {
286  if (rpController->getModel().get() == xModel.get())
287  return rpController;
288 
289  // the current-round controller isn't the right one. perhaps one of its children ?
290  Reference< XFormController > xChildSearch = getControllerSearchChildren(Reference< XIndexAccess > (rpController, UNO_QUERY), xModel);
291  if (xChildSearch.is())
292  return xChildSearch;
293  }
294  return Reference< XFormController > ();
295 }
296 
297 
298 void FormViewPageWindowAdapter::setController(const Reference< XForm > & xForm, const Reference< XFormController >& _rxParentController )
299 {
300  DBG_ASSERT( xForm.is(), "FormViewPageWindowAdapter::setController: there should be a form!" );
301  Reference< XIndexAccess > xFormCps(xForm, UNO_QUERY);
302  if (!xFormCps.is())
303  return;
304 
305  Reference< XTabControllerModel > xTabOrder(xForm, UNO_QUERY);
306 
307  // create a form controller
308  Reference< XFormController > xController( FormController::create(m_xContext) );
309 
311  if ( _rxParentController.is() )
312  xHandler = _rxParentController->getInteractionHandler();
313  else
314  {
315  // TODO: should we create a default handler? Not really necessary, since the
316  // FormController itself has a default fallback
317  }
318  if ( xHandler.is() )
319  xController->setInteractionHandler( xHandler );
320 
321  xController->setContext( this );
322 
323  xController->setModel( xTabOrder );
324  xController->setContainer( m_xControlContainer );
325  xController->activateTabOrder();
326  xController->addActivateListener( m_pViewImpl );
327 
328  if ( _rxParentController.is() )
329  _rxParentController->addChildController( xController );
330  else
331  {
332  m_aControllerList.push_back(xController);
333 
334  xController->setParent( *this );
335 
336  // attaching the events
337  Reference< XEventAttacherManager > xEventManager( xForm->getParent(), UNO_QUERY );
338  xEventManager->attach(m_aControllerList.size() - 1, Reference<XInterface>( xController, UNO_QUERY ), makeAny(xController) );
339  }
340 
341  // now go through the subforms
342  sal_uInt32 nLength = xFormCps->getCount();
343  Reference< XForm > xSubForm;
344  for (sal_uInt32 i = 0; i < nLength; i++)
345  {
346  if ( xFormCps->getByIndex(i) >>= xSubForm )
347  setController( xSubForm, xController );
348  }
349 }
350 
351 
352 void FormViewPageWindowAdapter::updateTabOrder( const Reference< XForm >& _rxForm )
353 {
354  OSL_PRECOND( _rxForm.is(), "FormViewPageWindowAdapter::updateTabOrder: illegal argument!" );
355  if ( !_rxForm.is() )
356  return;
357 
358  try
359  {
360  Reference< XTabController > xTabCtrl( getController( _rxForm ) );
361  if ( xTabCtrl.is() )
362  { // if there already is a TabController for this form, then delegate the "updateTabOrder" request
363  xTabCtrl->activateTabOrder();
364  }
365  else
366  { // otherwise, create a TabController
367 
368  // if it's a sub form, then we must ensure there exist TabControllers
369  // for all its ancestors, too
370  Reference< XForm > xParentForm( _rxForm->getParent(), UNO_QUERY );
371  // there is a parent form -> look for the respective controller
372  Reference< XFormController > xParentController;
373  if ( xParentForm.is() )
374  xParentController = getController( xParentForm );
375 
376  setController( _rxForm, xParentController );
377  }
378  }
379  catch (const Exception&)
380  {
382  }
383 }
384 
385 
387  :m_pMarkedGrid(nullptr)
388  ,m_pView(_pView)
389  ,m_nActivationEvent(nullptr)
390  ,m_nErrorMessageEvent( nullptr )
391  ,m_nAutoFocusEvent( nullptr )
392  ,m_nControlWizardEvent( nullptr )
393  ,m_bFirstActivation( true )
394  ,m_isTabOrderUpdateSuspended( false )
395 {
396 }
397 
398 
400 {
401  if ( m_nActivationEvent )
402  {
404  m_nActivationEvent = nullptr;
405  }
406 
407  if ( m_nErrorMessageEvent )
408  {
410  m_nErrorMessageEvent = nullptr;
411  }
412 
413  if ( m_nAutoFocusEvent )
414  {
416  m_nAutoFocusEvent = nullptr;
417  }
418 
419  if ( m_nControlWizardEvent )
420  {
422  m_nControlWizardEvent = nullptr;
423  }
424 }
425 
426 
428 {
429  DBG_ASSERT( m_pView, "FmXFormView::notifyViewDying: my view already died!" );
430  m_pView = nullptr;
431  cancelEvents();
432 }
433 
434 
436 {
437  DBG_ASSERT( m_aPageWindowAdapters.empty(), "FmXFormView::~FmXFormView: Window list not empty!" );
438  for (const auto& rpAdapter : m_aPageWindowAdapters)
439  {
440  rpAdapter->dispose();
441  }
442 
443  cancelEvents();
444 }
445 
446 // EventListener
447 
448 void SAL_CALL FmXFormView::disposing(const EventObject& Source)
449 {
450  if ( m_xWindow.is() && Source.Source == m_xWindow )
451  {
452  m_xWindow->removeFocusListener(this);
453  if ( m_pView )
454  {
456  }
457  m_xWindow = nullptr;
458  }
459 }
460 
461 // XFormControllerListener
462 
463 void SAL_CALL FmXFormView::formActivated(const EventObject& rEvent)
464 {
466  m_pView->GetFormShell()->GetImpl()->formActivated( rEvent );
467 }
468 
469 
470 void SAL_CALL FmXFormView::formDeactivated(const EventObject& rEvent)
471 {
473  m_pView->GetFormShell()->GetImpl()->formDeactivated( rEvent );
474 }
475 
476 // XContainerListener
477 
478 void SAL_CALL FmXFormView::elementInserted(const ContainerEvent& evt)
479 {
480  try
481  {
482  Reference< XControlContainer > xControlContainer( evt.Source, UNO_QUERY_THROW );
483  Reference< XControl > xControl( evt.Element, UNO_QUERY_THROW );
484  Reference< XFormComponent > xControlModel( xControl->getModel(), UNO_QUERY_THROW );
485  Reference< XForm > xForm( xControlModel->getParent(), UNO_QUERY_THROW );
486 
488  {
489  // remember the container and the control, so we can update the tab order on resumeTabOrderUpdate
490  m_aNeedTabOrderUpdate[ xControlContainer ].insert( xForm );
491  }
492  else
493  {
494  PFormViewPageWindowAdapter pAdapter = findWindow( xControlContainer );
495  if ( pAdapter.is() )
496  pAdapter->updateTabOrder( xForm );
497  }
498  }
499  catch (const Exception&)
500  {
502  }
503 }
504 
505 
506 void SAL_CALL FmXFormView::elementReplaced(const ContainerEvent& evt)
507 {
508  elementInserted(evt);
509 }
510 
511 
512 void SAL_CALL FmXFormView::elementRemoved(const ContainerEvent& /*evt*/)
513 {
514 }
515 
516 
517 PFormViewPageWindowAdapter FmXFormView::findWindow( const Reference< XControlContainer >& _rxCC ) const
518 {
519  auto i = std::find_if(m_aPageWindowAdapters.begin(), m_aPageWindowAdapters.end(),
520  [&_rxCC](const PFormViewPageWindowAdapter& rpAdapter) { return _rxCC == rpAdapter->getControlContainer(); });
521  if (i != m_aPageWindowAdapters.end())
522  return *i;
523  return nullptr;
524 }
525 
526 
528 {
529  FmFormPage* pFormPage = dynamic_cast<FmFormPage*>( rWindow.GetPageView().GetPage() );
530  if ( !pFormPage )
531  return;
532 
533  const Reference< XControlContainer >& xCC = rWindow.GetControlContainer();
534  if ( xCC.is()
535  && ( !findWindow( xCC ).is() )
536  )
537  {
539  m_aPageWindowAdapters.push_back( pAdapter );
540 
541  // listen at the ControlContainer to notice changes
542  Reference< XContainer > xContainer( xCC, UNO_QUERY );
543  if ( xContainer.is() )
544  xContainer->addContainerListener( this );
545  }
546 }
547 
548 
549 void FmXFormView::removeWindow( const Reference< XControlContainer >& _rxCC )
550 {
551  // Is called if
552  // - the design mode is being switched to
553  // - a window is deleted while in the design mode
554  // - the control container for a window is removed while the active mode is on
555 
556  auto i = std::find_if(m_aPageWindowAdapters.begin(), m_aPageWindowAdapters.end(),
557  [&_rxCC](const PFormViewPageWindowAdapter& rpAdapter) { return _rxCC == rpAdapter->getControlContainer(); });
558  if (i != m_aPageWindowAdapters.end())
559  {
560  Reference< XContainer > xContainer( _rxCC, UNO_QUERY );
561  if ( xContainer.is() )
562  xContainer->removeContainerListener( this );
563 
564  (*i)->dispose();
565  m_aPageWindowAdapters.erase( i );
566  }
567 }
568 
569 void FmXFormView::displayAsyncErrorMessage( const SQLErrorEvent& _rEvent )
570 {
571  DBG_ASSERT( nullptr == m_nErrorMessageEvent, "FmXFormView::displayAsyncErrorMessage: not too fast, please!" );
572  // This should not happen - usually, the PostUserEvent is faster than any possible user
573  // interaction which could trigger a new error. If it happens, we need a queue for the events.
574  m_aAsyncError = _rEvent;
575  m_nErrorMessageEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnDelayedErrorMessage ) );
576 }
577 
578 IMPL_LINK_NOARG(FmXFormView, OnDelayedErrorMessage, void*, void)
579 {
580  m_nErrorMessageEvent = nullptr;
581  displayException(m_aAsyncError, GetParentWindow());
582 }
583 
585 {
586  if ( _pDocModel && _pDocModel->GetAutoControlFocus() )
588 }
589 
591 {
592  OSL_ENSURE( !m_isTabOrderUpdateSuspended, "FmXFormView::suspendTabOrderUpdate: nesting not allowed!" );
594 }
595 
597 {
598  OSL_ENSURE( m_isTabOrderUpdateSuspended, "FmXFormView::resumeTabOrderUpdate: not suspended!" );
600 
601  // update the tab orders for all components which were collected since the suspendTabOrderUpdate call.
602  for (const auto& rContainer : m_aNeedTabOrderUpdate)
603  {
604  PFormViewPageWindowAdapter pAdapter = findWindow( rContainer.first );
605  if ( !pAdapter.is() )
606  continue;
607 
608  for (const auto& rForm : rContainer.second)
609  {
610  pAdapter->updateTabOrder( rForm );
611  }
612  }
613  m_aNeedTabOrderUpdate.clear();
614 }
615 
616 namespace
617 {
618  bool isActivableDatabaseForm(const Reference< XFormController > &xController)
619  {
620  // only database forms are to be activated
621  Reference< XRowSet > xForm(xController->getModel(), UNO_QUERY);
622  if ( !xForm.is() || !getConnection( xForm ).is() )
623  return false;
624 
625  Reference< XPropertySet > xFormSet( xForm, UNO_QUERY );
626  if ( !xFormSet.is() )
627  {
628  SAL_WARN( "svx.form", "FmXFormView::OnActivate: a form which does not have properties?" );
629  return false;
630  }
631 
632  const OUString aSource = ::comphelper::getString( xFormSet->getPropertyValue( FM_PROP_COMMAND ) );
633 
634  return !aSource.isEmpty();
635  }
636 
637  class find_active_databaseform
638  {
639  const Reference< XFormController > xActiveController;
640 
641  public:
642 
643  explicit find_active_databaseform( const Reference< XFormController >& _xActiveController )
644  : xActiveController(_xActiveController )
645  {}
646 
647  Reference < XFormController > operator() (const Reference< XFormController > &xController)
648  {
649  if(xController == xActiveController && isActivableDatabaseForm(xController))
650  return xController;
651 
652  if ( !xController.is() )
653  {
654  SAL_WARN( "svx.form", "FmXFormView::OnActivate: a form controller which does not have children?" );
655  return nullptr;
656  }
657 
658  for(sal_Int32 i = 0; i < xController->getCount(); ++i)
659  {
660  const Any a(xController->getByIndex(i));
661  Reference < XFormController > xI;
662  if ((a >>= xI) && xI.is())
663  {
664  Reference < XFormController > xRes(operator()(xI));
665  if (xRes.is())
666  return xRes;
667  }
668  }
669 
670  return nullptr;
671  }
672  };
673 }
674 
675 
676 IMPL_LINK_NOARG(FmXFormView, OnActivate, void*, void)
677 {
678  m_nActivationEvent = nullptr;
679 
680  if ( !m_pView )
681  {
682  OSL_FAIL( "FmXFormView::OnActivate: well... seems we have a timing problem (the view already died)!" );
683  return;
684  }
685 
686  // setting the controller to activate
687  if (!(m_pView->GetFormShell() && m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW))
688  return;
689 
690  FmXFormShell* const pShImpl = m_pView->GetFormShell()->GetImpl();
691 
692  if(!pShImpl)
693  return;
694 
695  find_active_databaseform fad(pShImpl->getActiveController_Lock());
696 
697  vcl::Window* pWindow = const_cast<vcl::Window*>(static_cast<const vcl::Window*>(m_pView->GetActualOutDev()));
698  PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? nullptr : m_aPageWindowAdapters[0];
699  for (const auto& rpPageWindowAdapter : m_aPageWindowAdapters)
700  {
701  if ( pWindow == rpPageWindowAdapter->getWindow() )
702  pAdapter = rpPageWindowAdapter;
703  }
704 
705  if ( !pAdapter.is() )
706  return;
707 
708  Reference< XFormController > xControllerToActivate;
709  for (const Reference< XFormController > & xController : pAdapter->GetList())
710  {
711  if ( !xController.is() )
712  continue;
713 
714  {
715  Reference< XFormController > xActiveController(fad(xController));
716  if (xActiveController.is())
717  {
718  xControllerToActivate = xActiveController;
719  break;
720  }
721  }
722 
723  if(xControllerToActivate.is() || !isActivableDatabaseForm(xController))
724  continue;
725 
726  xControllerToActivate = xController;
727  }
728  pShImpl->setActiveController_Lock(xControllerToActivate);
729 }
730 
731 
732 void FmXFormView::Activate(bool bSync)
733 {
734  if (m_nActivationEvent)
735  {
737  m_nActivationEvent = nullptr;
738  }
739 
740  if (bSync)
741  {
742  LINK(this,FmXFormView,OnActivate).Call(nullptr);
743  }
744  else
746 }
747 
748 
749 void FmXFormView::Deactivate(bool bDeactivateController)
750 {
751  if (m_nActivationEvent)
752  {
754  m_nActivationEvent = nullptr;
755  }
756 
757  FmXFormShell* pShImpl = m_pView->GetFormShell() ? m_pView->GetFormShell()->GetImpl() : nullptr;
758  if (pShImpl && bDeactivateController)
759  pShImpl->setActiveController_Lock(nullptr);
760 }
761 
762 
764 {
765  return m_pView ? m_pView->GetFormShell() : nullptr;
766 }
767 
769 {
770  if (m_nAutoFocusEvent)
772 
774 }
775 
776 
777 bool FmXFormView::isFocusable( const Reference< XControl >& i_rControl )
778 {
779  if ( !i_rControl.is() )
780  return false;
781 
782  try
783  {
784  Reference< XPropertySet > xModelProps( i_rControl->getModel(), UNO_QUERY_THROW );
785 
786  // only enabled controls are allowed to participate
787  bool bEnabled = false;
788  OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_ENABLED ) >>= bEnabled );
789  if ( !bEnabled )
790  return false;
791 
792  // check the class id of the control model
793  sal_Int16 nClassId = FormComponentType::CONTROL;
794  OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
795 
796  // controls which are not focussable
797  if ( ( FormComponentType::CONTROL != nClassId )
798  && ( FormComponentType::IMAGEBUTTON != nClassId )
799  && ( FormComponentType::GROUPBOX != nClassId )
800  && ( FormComponentType::FIXEDTEXT != nClassId )
801  && ( FormComponentType::HIDDENCONTROL != nClassId )
802  && ( FormComponentType::IMAGECONTROL != nClassId )
803  && ( FormComponentType::SCROLLBAR != nClassId )
804  && ( FormComponentType::SPINBUTTON!= nClassId )
805  )
806  {
807  return true;
808  }
809  }
810  catch (const Exception&)
811  {
813  }
814  return false;
815 }
816 
817 
818 static Reference< XControl > lcl_firstFocussableControl( const Sequence< Reference< XControl > >& _rControls )
819 {
820  Reference< XControl > xReturn;
821 
822  // loop through all the controls
823  for ( auto const & control : _rControls )
824  {
825  if ( !control.is() )
826  continue;
827 
829  {
830  xReturn = control;
831  break;
832  }
833  }
834 
835  if ( !xReturn.is() && _rControls.hasElements() )
836  xReturn = _rControls[0];
837 
838  return xReturn;
839 }
840 
841 
842 namespace
843 {
844 
845  void lcl_ensureControlsOfFormExist_nothrow( const SdrPage& _rPage, const SdrView& _rView, const vcl::Window& _rWindow, const Reference< XForm >& _rxForm )
846  {
847  try
848  {
849  Reference< XInterface > xNormalizedForm( _rxForm, UNO_QUERY_THROW );
850 
851  SdrObjListIter aSdrObjectLoop( &_rPage, SdrIterMode::DeepNoGroups );
852  while ( aSdrObjectLoop.IsMore() )
853  {
854  FmFormObj* pFormObject = FmFormObj::GetFormObject( aSdrObjectLoop.Next() );
855  if ( !pFormObject )
856  continue;
857 
858  Reference< XChild > xModel( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
859  Reference< XInterface > xModelParent( xModel->getParent(), UNO_QUERY );
860 
861  if ( xNormalizedForm.get() != xModelParent.get() )
862  continue;
863 
864  pFormObject->GetUnoControl( _rView, _rWindow );
865  }
866  }
867  catch (const Exception&)
868  {
870  }
871  }
872 }
873 
874 
875 Reference< XFormController > FmXFormView::getFormController( const Reference< XForm >& _rxForm, const OutputDevice& _rDevice ) const
876 {
877  Reference< XFormController > xController;
878 
879  for (const PFormViewPageWindowAdapter& pAdapter : m_aPageWindowAdapters)
880  {
881  if ( !pAdapter )
882  {
883  SAL_WARN( "svx.form", "FmXFormView::getFormController: invalid page window adapter!" );
884  continue;
885  }
886 
887  if ( pAdapter->getWindow() != &_rDevice )
888  // wrong device
889  continue;
890 
891  xController = pAdapter->getController( _rxForm );
892  if ( xController.is() )
893  break;
894  }
895  return xController;
896 }
897 
898 
899 IMPL_LINK_NOARG(FmXFormView, OnAutoFocus, void*, void)
900 {
901  m_nAutoFocusEvent = nullptr;
902 
903  // go to the first form of our page, examine it's TabController, go to its first (in terms of the tab order)
904  // control, give it the focus
905 
906  SdrPageView *pPageView = m_pView ? m_pView->GetSdrPageView() : nullptr;
907  SdrPage *pSdrPage = pPageView ? pPageView->GetPage() : nullptr;
908  // get the forms collection of the page we belong to
909  FmFormPage* pPage = dynamic_cast<FmFormPage*>( pSdrPage );
910  Reference< XIndexAccess > xForms( pPage ? Reference< XIndexAccess >( pPage->GetForms() ) : Reference< XIndexAccess >() );
911 
912  const PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? nullptr : m_aPageWindowAdapters[0];
913  const vcl::Window* pWindow = pAdapter ? pAdapter->getWindow() : nullptr;
914 
915  ENSURE_OR_RETURN_VOID( xForms.is() && pWindow, "FmXFormView::OnAutoFocus: could not collect all essentials!" );
916 
917  try
918  {
919  // go for the tab controller of the first form
920  if ( !xForms->getCount() )
921  return;
922  Reference< XForm > xForm( xForms->getByIndex( 0 ), UNO_QUERY_THROW );
923  Reference< XTabController > xTabController( pAdapter->getController( xForm ), UNO_QUERY_THROW );
924 
925  // go for the first control of the controller
926  Sequence< Reference< XControl > > aControls( xTabController->getControls() );
927  if ( !aControls.hasElements() )
928  {
929  Reference< XElementAccess > xFormElementAccess( xForm, UNO_QUERY_THROW );
930  if (xFormElementAccess->hasElements() && pPage && m_pView)
931  {
932  // there are control models in the form, but no controls, yet.
933  // Well, since some time controls are created on demand only. In particular,
934  // they're normally created when they're first painted.
935  // Unfortunately, the FormController does not have any way to
936  // trigger the creation itself, so we must hack this ...
937  lcl_ensureControlsOfFormExist_nothrow( *pPage, *m_pView, *pWindow, xForm );
938  aControls = xTabController->getControls();
939  OSL_ENSURE( aControls.hasElements(), "FmXFormView::OnAutoFocus: no controls at all!" );
940  }
941  }
942 
943  // set the focus to this first control
944  Reference< XWindow > xControlWindow( lcl_firstFocussableControl( aControls ), UNO_QUERY );
945  if ( !xControlWindow.is() )
946  return;
947 
948  xControlWindow->setFocus();
949 
950  // ensure that the control is visible
951  // 80210 - 12/07/00 - FS
952  const vcl::Window* pCurrentWindow = m_pView ? dynamic_cast<const vcl::Window*>(m_pView->GetActualOutDev()) : nullptr;
953  if ( pCurrentWindow )
954  {
955  awt::Rectangle aRect = xControlWindow->getPosSize();
956  ::tools::Rectangle aNonUnoRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height );
957  m_pView->MakeVisible( pCurrentWindow->PixelToLogic( aNonUnoRect ), *const_cast< vcl::Window* >( pCurrentWindow ) );
958  }
959  }
960  catch (const Exception&)
961  {
963  }
964 }
965 
966 
967 void FmXFormView::onCreatedFormObject( FmFormObj const & _rFormObject )
968 {
969  FmFormShell* pShell = m_pView ? m_pView->GetFormShell() : nullptr;
970  FmXFormShell* pShellImpl = pShell ? pShell->GetImpl() : nullptr;
971  OSL_ENSURE( pShellImpl, "FmXFormView::onCreatedFormObject: no form shell!" );
972  if ( !pShellImpl )
973  return;
974 
975  // it is valid that the form shell's forms collection is not initialized, yet
976  pShellImpl->UpdateForms_Lock(true);
977 
978  m_xLastCreatedControlModel.set( _rFormObject.GetUnoControlModel(), UNO_QUERY );
979  if ( !m_xLastCreatedControlModel.is() )
980  return;
981 
982  // some initial property defaults
983  FormControlFactory aControlFactory;
984  aControlFactory.initializeControlModel(pShellImpl->getDocumentType_Lock(), _rFormObject);
985 
986  if (!pShellImpl->GetWizardUsing_Lock())
987  return;
988 
989  // #i31958# don't call wizards in XForms mode
990  if (pShellImpl->isEnhancedForm_Lock())
991  return;
992 
993  // #i46898# no wizards if there is no Base installed - currently, all wizards are
994  // database related
996  return;
997 
998  if ( m_nControlWizardEvent )
1000  m_nControlWizardEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnStartControlWizard ) );
1001 }
1002 
1004 {
1005  if (m_nControlWizardEvent != nullptr)
1006  {
1008  m_nControlWizardEvent = nullptr;
1009  }
1011 }
1012 
1013 Reference<XWindow> FmXFormView::GetParentWindow()
1014 {
1015  const vcl::Window* pCurrentWindow = m_pView ? dynamic_cast<const vcl::Window*>(m_pView->GetActualOutDev()) : nullptr;
1016  return VCLUnoHelper::GetInterface(const_cast<vcl::Window*>(pCurrentWindow));
1017 }
1018 
1019 IMPL_LINK_NOARG( FmXFormView, OnStartControlWizard, void*, void )
1020 {
1021  m_nControlWizardEvent = nullptr;
1022  OSL_PRECOND( m_xLastCreatedControlModel.is(), "FmXFormView::OnStartControlWizard: illegal call!" );
1023  if ( !m_xLastCreatedControlModel.is() )
1024  return;
1025 
1026  sal_Int16 nClassId = FormComponentType::CONTROL;
1027  try
1028  {
1029  OSL_VERIFY( m_xLastCreatedControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
1030  }
1031  catch (const Exception&)
1032  {
1033  DBG_UNHANDLED_EXCEPTION("svx");
1034  }
1035 
1036  const char* pWizardAsciiName = nullptr;
1037  switch ( nClassId )
1038  {
1039  case FormComponentType::GRIDCONTROL:
1040  pWizardAsciiName = "com.sun.star.sdb.GridControlAutoPilot";
1041  break;
1042  case FormComponentType::LISTBOX:
1043  case FormComponentType::COMBOBOX:
1044  pWizardAsciiName = "com.sun.star.sdb.ListComboBoxAutoPilot";
1045  break;
1046  case FormComponentType::GROUPBOX:
1047  pWizardAsciiName = "com.sun.star.sdb.GroupBoxAutoPilot";
1048  break;
1049  }
1050 
1051  if ( pWizardAsciiName )
1052  {
1053  // build the argument list
1055  aWizardArgs.put("ObjectModel", m_xLastCreatedControlModel);
1056  aWizardArgs.put("ParentWindow", GetParentWindow());
1057 
1058  // create the wizard object
1059  Reference< XExecutableDialog > xWizard;
1060  try
1061  {
1063  xWizard.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext( OUString::createFromAscii(pWizardAsciiName), aWizardArgs.getWrappedPropertyValues(), xContext ), UNO_QUERY);
1064  }
1065  catch (const Exception&)
1066  {
1067  DBG_UNHANDLED_EXCEPTION("svx");
1068  }
1069 
1070  if ( !xWizard.is() )
1071  {
1072  ShowServiceNotAvailableError( nullptr, OUString::createFromAscii(pWizardAsciiName), true );
1073  }
1074  else
1075  {
1076  // execute the wizard
1077  try
1078  {
1079  xWizard->execute();
1080  }
1081  catch (const Exception&)
1082  {
1083  DBG_UNHANDLED_EXCEPTION("svx");
1084  }
1085  }
1086  }
1087 
1088  m_xLastCreatedControlModel.clear();
1089 }
1090 
1091 
1092 namespace
1093 {
1094  void lcl_insertIntoFormComponentHierarchy_throw( const FmFormView& _rView, const SdrUnoObj& _rSdrObj,
1095  const Reference< XDataSource >& _rxDataSource, const OUString& _rDataSourceName,
1096  const OUString& _rCommand, const sal_Int32 _nCommandType )
1097  {
1098  FmFormPage& rPage = static_cast< FmFormPage& >( *_rView.GetSdrPageView()->GetPage() );
1099 
1100  Reference< XFormComponent > xFormComponent( _rSdrObj.GetUnoControlModel(), UNO_QUERY_THROW );
1101  Reference< XForm > xTargetForm(
1102  rPage.GetImpl().findPlaceInFormComponentHierarchy( xFormComponent, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType ),
1103  UNO_SET_THROW );
1104 
1105  FmFormPageImpl::setUniqueName( xFormComponent, xTargetForm );
1106 
1107  Reference< XIndexContainer > xFormAsContainer( xTargetForm, UNO_QUERY_THROW );
1108  xFormAsContainer->insertByIndex( xFormAsContainer->getCount(), makeAny( xFormComponent ) );
1109  }
1110 }
1111 
1112 
1114 {
1115  // not if we're in design mode
1116  if ( !m_pView->IsDesignMode() )
1117  return nullptr;
1118 
1119  OUString sCommand, sFieldName;
1120  sal_Int32 nCommandType = CommandType::COMMAND;
1121  SharedConnection xConnection;
1122 
1123  OUString sDataSource = _rColumnDescriptor.getDataSource();
1124  _rColumnDescriptor[ DataAccessDescriptorProperty::Command ] >>= sCommand;
1125  _rColumnDescriptor[ DataAccessDescriptorProperty::ColumnName ] >>= sFieldName;
1126  _rColumnDescriptor[ DataAccessDescriptorProperty::CommandType ] >>= nCommandType;
1127  {
1128  Reference< XConnection > xExternalConnection;
1129  _rColumnDescriptor[ DataAccessDescriptorProperty::Connection ] >>= xExternalConnection;
1130  xConnection.reset( xExternalConnection, SharedConnection::NoTakeOwnership );
1131  }
1132 
1133  if ( sCommand.isEmpty()
1134  || sFieldName.isEmpty()
1135  || ( sDataSource.isEmpty()
1136  && !xConnection.is()
1137  )
1138  )
1139  {
1140  OSL_FAIL( "FmXFormView::implCreateFieldControl: nonsense!" );
1141  }
1142 
1143  Reference< XDataSource > xDataSource;
1144  SQLErrorEvent aError;
1145  try
1146  {
1147  if ( xConnection.is() && !xDataSource.is() && sDataSource.isEmpty() )
1148  {
1149  Reference< XChild > xChild( xConnection, UNO_QUERY );
1150  if ( xChild.is() )
1151  xDataSource.set(xChild->getParent(), css::uno::UNO_QUERY);
1152  }
1153 
1154  // obtain the data source
1155  if ( !xDataSource.is() )
1156  xDataSource = getDataSource( sDataSource, comphelper::getProcessComponentContext() );
1157 
1158  // and the connection, if necessary
1159  if ( !xConnection.is() )
1160  xConnection.reset( getConnection_withFeedback(
1161  sDataSource,
1162  OUString(),
1163  OUString(),
1165  nullptr
1166  ) );
1167  }
1168  catch (const SQLException&)
1169  {
1170  aError.Reason = ::cppu::getCaughtException();
1171  }
1172  catch (const Exception& )
1173  {
1174  /* will be asserted below */
1175  }
1176  if (aError.Reason.hasValue())
1177  {
1178  displayAsyncErrorMessage( aError );
1179  return nullptr;
1180  }
1181 
1182  // need a data source and a connection here
1183  if (!xDataSource.is() || !xConnection.is())
1184  {
1185  OSL_FAIL("FmXFormView::implCreateFieldControl : could not retrieve the data source or the connection!");
1186  return nullptr;
1187  }
1188 
1189  Reference< XComponent > xKeepFieldsAlive;
1190  // go
1191  try
1192  {
1193  // determine the table/query field which we should create a control for
1195 
1197  xConnection, nCommandType, sCommand, xKeepFieldsAlive );
1198 
1199  if (xFields.is() && xFields->hasByName(sFieldName))
1200  xFields->getByName(sFieldName) >>= xField;
1201  if ( !xField.is() )
1202  return nullptr;
1203 
1204  Reference< XNumberFormatsSupplier > xSupplier( getNumberFormats( xConnection ), UNO_SET_THROW );
1205  Reference< XNumberFormats > xNumberFormats( xSupplier->getNumberFormats(), UNO_SET_THROW );
1206 
1207  OUString sLabelPostfix;
1208 
1209 
1210  // only for text size
1211  OutputDevice* pOutDev = nullptr;
1213  pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev());
1214  else
1215  {// find OutDev
1216  if (SdrPageView* pPageView = m_pView->GetSdrPageView())
1217  {
1218  // const SdrPageViewWinList& rWinList = pPageView->GetWinList();
1219  // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows();
1220 
1221  for( sal_uInt32 i = 0; i < pPageView->PageWindowCount(); i++ )
1222  {
1223  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i);
1224 
1225  if( rPageWindow.GetPaintWindow().OutputToWindow())
1226  {
1227  pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice();
1228  break;
1229  }
1230  }
1231  }
1232  }
1233 
1234  if ( !pOutDev )
1235  return nullptr;
1236 
1237  sal_Int32 nDataType = ::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE));
1238  if ((DataType::BINARY == nDataType) || (DataType::VARBINARY == nDataType))
1239  return nullptr;
1240 
1241 
1242  // determine the control type by examining the data type of the bound column
1243  SdrObjKind nOBJID = OBJ_NONE;
1244  bool bDateNTimeField = false;
1245 
1246  bool bIsCurrency = false;
1248  bIsCurrency = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISCURRENCY));
1249 
1250  if (bIsCurrency)
1251  nOBJID = OBJ_FM_CURRENCYFIELD;
1252  else
1253  switch (nDataType)
1254  {
1255  case DataType::BLOB:
1256  case DataType::LONGVARBINARY:
1257  nOBJID = OBJ_FM_IMAGECONTROL;
1258  break;
1259  case DataType::LONGVARCHAR:
1260  case DataType::CLOB:
1261  nOBJID = OBJ_FM_EDIT;
1262  break;
1263  case DataType::BINARY:
1264  case DataType::VARBINARY:
1265  return nullptr;
1266  case DataType::BIT:
1267  case DataType::BOOLEAN:
1268  nOBJID = OBJ_FM_CHECKBOX;
1269  break;
1270  case DataType::TINYINT:
1271  case DataType::SMALLINT:
1272  case DataType::INTEGER:
1273  nOBJID = OBJ_FM_NUMERICFIELD;
1274  break;
1275  case DataType::REAL:
1276  case DataType::DOUBLE:
1277  case DataType::NUMERIC:
1278  case DataType::DECIMAL:
1279  nOBJID = OBJ_FM_FORMATTEDFIELD;
1280  break;
1281  case DataType::TIMESTAMP:
1282  bDateNTimeField = true;
1283  sLabelPostfix = SvxResId(RID_STR_POSTFIX_DATE);
1284  [[fallthrough]];
1285  case DataType::DATE:
1286  nOBJID = OBJ_FM_DATEFIELD;
1287  break;
1288  case DataType::TIME:
1289  nOBJID = OBJ_FM_TIMEFIELD;
1290  break;
1291  case DataType::CHAR:
1292  case DataType::VARCHAR:
1293  default:
1294  nOBJID = OBJ_FM_EDIT;
1295  break;
1296  }
1297  if (!nOBJID)
1298  return nullptr;
1299 
1300  std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> pLabel;
1301  std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> pControl;
1302  if ( !createControlLabelPair( *pOutDev, 0, 0, xField, xNumberFormats, nOBJID, sLabelPostfix,
1303  pLabel, pControl, xDataSource, sDataSource, sCommand, nCommandType )
1304  )
1305  {
1306  return nullptr;
1307  }
1308 
1309 
1310  // group objects
1311  bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID );
1312  OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateFieldControl: why was there a label created for a check box?" );
1313  if ( bCheckbox )
1314  return SdrObjectUniquePtr(pControl.release());
1315 
1316  SdrObjGroup* pGroup = new SdrObjGroup(getView()->getSdrModelFromSdrView());
1317  SdrObjList* pObjList = pGroup->GetSubList();
1318  pObjList->InsertObject( pLabel.release() );
1319  pObjList->InsertObject( pControl.release() );
1320 
1321  if ( bDateNTimeField )
1322  { // so far we created a date field only, but we also need a time field
1323  if ( createControlLabelPair( *pOutDev, 0, 1000, xField, xNumberFormats, OBJ_FM_TIMEFIELD,
1324  SvxResId(RID_STR_POSTFIX_TIME), pLabel, pControl,
1325  xDataSource, sDataSource, sCommand, nCommandType )
1326  )
1327  {
1328  pObjList->InsertObject( pLabel.release() );
1329  pObjList->InsertObject( pControl.release() );
1330  }
1331  }
1332 
1333  return SdrObjectUniquePtr(pGroup); // and done
1334  }
1335  catch (const Exception&)
1336  {
1337  DBG_UNHANDLED_EXCEPTION("svx");
1338  }
1339 
1340 
1341  return nullptr;
1342 }
1343 
1344 
1346 {
1347  // not if we're in design mode
1348  if ( !m_pView->IsDesignMode() )
1349  return nullptr;
1350 
1351  // go
1352  try
1353  {
1354  // determine the table/query field which we should create a control for
1355  Reference< XNumberFormats > xNumberFormats;
1356  OUString sLabelPostfix = _rDesc.szName;
1357 
1358 
1359  // only for text size
1360  OutputDevice* pOutDev = nullptr;
1362  pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev());
1363  else
1364  {// find OutDev
1365  if (SdrPageView* pPageView = m_pView->GetSdrPageView())
1366  {
1367  // const SdrPageViewWinList& rWinList = pPageView->GetWinList();
1368  // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows();
1369 
1370  for( sal_uInt32 i = 0; i < pPageView->PageWindowCount(); i++ )
1371  {
1372  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i);
1373 
1374  if( rPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType() == OUTDEV_WINDOW)
1375  {
1376  pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice();
1377  break;
1378  }
1379  }
1380  }
1381  }
1382 
1383  if ( !pOutDev )
1384  return nullptr;
1385 
1386 
1387  // The service name decides which control should be created
1388  SdrObjKind nOBJID = OBJ_FM_EDIT;
1390  nOBJID = OBJ_FM_NUMERICFIELD;
1392  nOBJID = OBJ_FM_CHECKBOX;
1394  nOBJID = OBJ_FM_BUTTON;
1395 
1396  Reference< css::form::submission::XSubmission > xSubmission(_rDesc.xPropSet, UNO_QUERY);
1397 
1398  // xform control or submission button?
1399  if ( !xSubmission.is() )
1400  {
1401  std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> pLabel;
1402  std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> pControl;
1403  if ( !createControlLabelPair( *pOutDev, 0, 0, nullptr, xNumberFormats, nOBJID, sLabelPostfix,
1404  pLabel, pControl, nullptr, "", "", -1 )
1405  )
1406  {
1407  return nullptr;
1408  }
1409 
1410 
1411  // Now build the connection between the control and the data item.
1412  Reference< XValueBinding > xValueBinding(_rDesc.xPropSet,UNO_QUERY);
1413  Reference< XBindableValue > xBindableValue(pControl->GetUnoControlModel(),UNO_QUERY);
1414 
1415  DBG_ASSERT( xBindableValue.is(), "FmXFormView::implCreateXFormsControl: control's not bindable!" );
1416  if ( xBindableValue.is() )
1417  xBindableValue->setValueBinding(xValueBinding);
1418 
1419  bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID );
1420  OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateXFormsControl: why was there a label created for a check box?" );
1421  if ( bCheckbox )
1422  return SdrObjectUniquePtr(pControl.release());
1423 
1424 
1425  // group objects
1426  SdrObjGroup* pGroup = new SdrObjGroup(getView()->getSdrModelFromSdrView());
1427  SdrObjList* pObjList = pGroup->GetSubList();
1428  pObjList->InsertObject(pLabel.release());
1429  pObjList->InsertObject(pControl.release());
1430 
1431  return SdrObjectUniquePtr(pGroup);
1432  }
1433  else {
1434 
1435  // create a button control
1436  const MapMode& eTargetMode( pOutDev->GetMapMode() );
1437  const MapMode eSourceMode(MapUnit::Map100thMM);
1438  const SdrObjKind nObjID = OBJ_FM_BUTTON;
1439  ::Size controlSize(4000, 500);
1440  FmFormObj *pControl = static_cast<FmFormObj*>(
1442  getView()->getSdrModelFromSdrView(),
1444  nObjID));
1445  controlSize.setWidth( tools::Long(controlSize.Width() * eTargetMode.GetScaleX()) );
1446  controlSize.setHeight( tools::Long(controlSize.Height() * eTargetMode.GetScaleY()) );
1447  ::Point controlPos( OutputDevice::LogicToLogic( ::Point( controlSize.Width(), 0 ), eSourceMode, eTargetMode ) );
1448  ::tools::Rectangle controlRect( controlPos, OutputDevice::LogicToLogic( controlSize, eSourceMode, eTargetMode ) );
1449  pControl->SetLogicRect(controlRect);
1450 
1451  // set the button label
1452  Reference< XPropertySet > xControlSet(pControl->GetUnoControlModel(), UNO_QUERY);
1453  xControlSet->setPropertyValue(FM_PROP_LABEL, makeAny(_rDesc.szName));
1454 
1455  // connect the submission with the submission supplier (aka the button)
1456  xControlSet->setPropertyValue( FM_PROP_BUTTON_TYPE,
1457  makeAny( FormButtonType_SUBMIT ) );
1458  Reference< css::form::submission::XSubmissionSupplier > xSubmissionSupplier(pControl->GetUnoControlModel(), UNO_QUERY);
1459  xSubmissionSupplier->setSubmission(xSubmission);
1460 
1461  return SdrObjectUniquePtr(pControl);
1462  }
1463  }
1464  catch (const Exception&)
1465  {
1466  TOOLS_WARN_EXCEPTION("svx.form", "caught an exception while creating the control !");
1467  }
1468 
1469 
1470  return nullptr;
1471 }
1472 
1473 bool FmXFormView::createControlLabelPair( OutputDevice const & _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM,
1474  const Reference< XPropertySet >& _rxField, const Reference< XNumberFormats >& _rxNumberFormats,
1475  SdrObjKind _nControlObjectID, std::u16string_view _rFieldPostfix,
1476  std::unique_ptr<SdrUnoObj, SdrObjectFreeOp>& _rpLabel,
1477  std::unique_ptr<SdrUnoObj, SdrObjectFreeOp>& _rpControl,
1478  const Reference< XDataSource >& _rxDataSource, const OUString& _rDataSourceName,
1479  const OUString& _rCommand, const sal_Int32 _nCommandType )
1480 {
1482  _rOutDev,
1483  _nXOffsetMM,
1484  _nYOffsetMM,
1485  _rxField,
1486  _rxNumberFormats,
1487  _nControlObjectID,
1488  _rFieldPostfix,
1491 
1492  // tdf#118963 Hand over a SdrModel to SdrObject-creation. It uses the local m_pView
1493  // and already returning false when nullptr == getView() could be done, but m_pView
1494  // is already dereferenced here in many places (see below), so just use it for now.
1495  getView()->getSdrModelFromSdrView(),
1496 
1497  _rpLabel,
1498  _rpControl))
1499  {
1500  return false;
1501  }
1502 
1503  // insert the control model(s) into the form component hierarchy
1504  if ( _rpLabel )
1505  lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpLabel, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType );
1506  lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpControl, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType );
1507 
1508  // some context-dependent initializations
1509  FormControlFactory aControlFactory;
1510  if ( _rpLabel )
1511  aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpLabel );
1512  aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpControl );
1513 
1514  return true;
1515 }
1516 
1517 
1518 bool FmXFormView::createControlLabelPair( OutputDevice const & _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM,
1519  const Reference< XPropertySet >& _rxField,
1520  const Reference< XNumberFormats >& _rxNumberFormats, SdrObjKind _nControlObjectID,
1521  std::u16string_view _rFieldPostfix, SdrInventor _nInventor, SdrObjKind _nLabelObjectID,
1522  SdrModel& _rModel,
1523  std::unique_ptr<SdrUnoObj, SdrObjectFreeOp>& _rpLabel, std::unique_ptr<SdrUnoObj, SdrObjectFreeOp>& _rpControl)
1524 {
1525  sal_Int32 nDataType = 0;
1526  OUString sFieldName;
1527  Any aFieldName;
1528  if ( _rxField.is() )
1529  {
1530  nDataType = ::comphelper::getINT32(_rxField->getPropertyValue(FM_PROP_FIELDTYPE));
1531  aFieldName = _rxField->getPropertyValue(FM_PROP_NAME);
1532  aFieldName >>= sFieldName;
1533  }
1534 
1535  // calculate the positions, respecting the settings of the target device
1536  ::Size aTextSize( _rOutDev.GetTextWidth(sFieldName + _rFieldPostfix), _rOutDev.GetTextHeight() );
1537 
1538  MapMode eTargetMode( _rOutDev.GetMapMode() ),
1539  eSourceMode( MapUnit::Map100thMM );
1540 
1541  // text width is at least 4 centimeters
1542  // text height is always half a centimeter
1543  ::Size aDefTxtSize(4000, 500);
1544  ::Size aDefSize(4000, 500);
1545  ::Size aDefImageSize(4000, 4000);
1546 
1547  ::Size aRealSize = OutputDevice::LogicToLogic(aTextSize, eTargetMode, eSourceMode);
1548  aRealSize.setWidth( std::max(aRealSize.Width(), aDefTxtSize.Width()) );
1549  aRealSize.setHeight( aDefSize.Height() );
1550 
1551  // adjust to scaling of the target device (#53523#)
1552  aRealSize.setWidth( tools::Long(Fraction(aRealSize.Width(), 1) * eTargetMode.GetScaleX()) );
1553  aRealSize.setHeight( tools::Long(Fraction(aRealSize.Height(), 1) * eTargetMode.GetScaleY()) );
1554 
1555  // for boolean fields, we do not create a label, but just a checkbox
1556  bool bNeedLabel = ( _nControlObjectID != OBJ_FM_CHECKBOX );
1557 
1558  // the label
1559  ::std::unique_ptr< SdrUnoObj, SdrObjectFreeOp > pLabel;
1560  Reference< XPropertySet > xLabelModel;
1561 
1562  if ( bNeedLabel )
1563  {
1564  pLabel.reset( dynamic_cast< SdrUnoObj* >(
1566  _rModel,
1567  _nInventor,
1568  _nLabelObjectID)));
1569 
1570  OSL_ENSURE(pLabel, "FmXFormView::createControlLabelPair: could not create the label!");
1571 
1572  if (!pLabel)
1573  return false;
1574 
1575  xLabelModel.set( pLabel->GetUnoControlModel(), UNO_QUERY );
1576  if ( xLabelModel.is() )
1577  {
1578  OUString sLabel;
1579  if ( _rxField.is() && _rxField->getPropertySetInfo()->hasPropertyByName(FM_PROP_LABEL) )
1580  _rxField->getPropertyValue(FM_PROP_LABEL) >>= sLabel;
1581  if ( sLabel.isEmpty() )
1582  sLabel = sFieldName;
1583 
1584  xLabelModel->setPropertyValue( FM_PROP_LABEL, makeAny( sLabel + _rFieldPostfix ) );
1585  OUString sObjectLabel(SvxResId(RID_STR_OBJECT_LABEL).replaceAll("#object#", sFieldName));
1586  xLabelModel->setPropertyValue(FM_PROP_NAME, makeAny(sObjectLabel));
1587  }
1588 
1589  pLabel->SetLogicRect( ::tools::Rectangle(
1590  OutputDevice::LogicToLogic( ::Point( _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ),
1591  OutputDevice::LogicToLogic( aRealSize, eSourceMode, eTargetMode )
1592  ) );
1593  }
1594 
1595  // the control
1596  ::std::unique_ptr< SdrUnoObj, SdrObjectFreeOp > pControl( dynamic_cast< SdrUnoObj* >(
1598  _rModel,
1599  _nInventor,
1600  _nControlObjectID)));
1601 
1602  OSL_ENSURE(pControl, "FmXFormView::createControlLabelPair: could not create the control!");
1603 
1604  if (!pControl)
1605  return false;
1606 
1607  Reference< XPropertySet > xControlSet( pControl->GetUnoControlModel(), UNO_QUERY );
1608  if ( !xControlSet.is() )
1609  return false;
1610 
1611  // size of the control
1612  ::Size aControlSize( aDefSize );
1613  switch ( nDataType )
1614  {
1615  case DataType::BIT:
1616  case DataType::BOOLEAN:
1617  aControlSize = aDefSize;
1618  break;
1619  case DataType::LONGVARCHAR:
1620  case DataType::CLOB:
1621  case DataType::LONGVARBINARY:
1622  case DataType::BLOB:
1623  aControlSize = aDefImageSize;
1624  break;
1625  }
1626 
1627  if ( OBJ_FM_IMAGECONTROL == _nControlObjectID )
1628  aControlSize = aDefImageSize;
1629 
1630  aControlSize.setWidth( tools::Long(Fraction(aControlSize.Width(), 1) * eTargetMode.GetScaleX()) );
1631  aControlSize.setHeight( tools::Long(Fraction(aControlSize.Height(), 1) * eTargetMode.GetScaleY()) );
1632 
1633  pControl->SetLogicRect( ::tools::Rectangle(
1634  OutputDevice::LogicToLogic( ::Point( aRealSize.Width() + _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ),
1635  OutputDevice::LogicToLogic( aControlSize, eSourceMode, eTargetMode )
1636  ) );
1637 
1638  // some initializations
1639  Reference< XPropertySetInfo > xControlPropInfo = xControlSet->getPropertySetInfo();
1640 
1641  if ( aFieldName.hasValue() )
1642  {
1643  xControlSet->setPropertyValue( FM_PROP_CONTROLSOURCE, aFieldName );
1644  xControlSet->setPropertyValue( FM_PROP_NAME, aFieldName );
1645  if ( !bNeedLabel )
1646  {
1647  // no dedicated label control => use the label property
1648  if ( xControlPropInfo->hasPropertyByName( FM_PROP_LABEL ) )
1649  xControlSet->setPropertyValue( FM_PROP_LABEL, makeAny( sFieldName + _rFieldPostfix ) );
1650  else
1651  OSL_FAIL( "FmXFormView::createControlLabelPair: can't set a label for the control!" );
1652  }
1653  }
1654 
1655  if ( (nDataType == DataType::LONGVARCHAR || nDataType == DataType::CLOB) && xControlPropInfo->hasPropertyByName( FM_PROP_MULTILINE ) )
1656  {
1657  xControlSet->setPropertyValue( FM_PROP_MULTILINE, makeAny( true ) );
1658  }
1659 
1660  // announce the label to the control
1661  if ( xControlPropInfo->hasPropertyByName( FM_PROP_CONTROLLABEL ) && xLabelModel.is() )
1662  {
1663  try
1664  {
1665  xControlSet->setPropertyValue( FM_PROP_CONTROLLABEL, makeAny( xLabelModel ) );
1666  }
1667  catch (const Exception&)
1668  {
1669  DBG_UNHANDLED_EXCEPTION("svx");
1670  }
1671  }
1672 
1673  if ( _rxField.is() )
1674  {
1675  FormControlFactory::initializeFieldDependentProperties( _rxField, xControlSet, _rxNumberFormats );
1676  }
1677 
1678  _rpLabel = std::move(pLabel);
1679  _rpControl = std::move(pControl);
1680  return true;
1681 }
1682 
1683 
1685  :m_pParent( pParent )
1686 {
1687 }
1688 
1689 
1691 {
1692  if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
1693  return;
1694  const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
1695  if (pSdrHint->GetKind() == SdrHintKind::ObjectRemoved)
1696  m_pParent->ObjectRemovedInAliveMode(pSdrHint->GetObject());
1697 }
1698 
1699 
1701 {
1702  // if the remote object in my MarkList, which I have memorized when switching to the
1703  // Alive mode, I have to take it out now, because I otherwise try to set the mark
1704  // again when switching back (interestingly, this fails only with grouped objects
1705  // (when accessing their ObjList GPF), not with individual ones)
1706 
1707  const size_t nCount = m_aMark.GetMarkCount();
1708  for (size_t i = 0; i < nCount; ++i)
1709  {
1710  SdrMark* pMark = m_aMark.GetMark(i);
1711  SdrObject* pCurrent = pMark->GetMarkedSdrObj();
1712  if (pObject == pCurrent)
1713  {
1714  m_aMark.DeleteMark(i);
1715  return;
1716  }
1717  // I do not need to descend into GroupObjects: if an object is deleted there,
1718  // then the pointer, which I have, to the GroupObject still remains valid ...
1719  }
1720 }
1721 
1722 
1724 {
1725  if ( m_pWatchStoredList )
1726  {
1727  m_pWatchStoredList->EndListeningAll();
1728  m_pWatchStoredList.reset();
1729  }
1730 }
1731 
1732 
1734 {
1735  if ( !m_pWatchStoredList )
1736  {
1737  FmFormModel* pModel = GetFormShell() ? GetFormShell()->GetFormModel() : nullptr;
1738  DBG_ASSERT( pModel != nullptr, "FmXFormView::startMarkListWatching: shell has no model!" );
1739  if (pModel)
1740  {
1741  m_pWatchStoredList.reset(new ObjectRemoveListener( this ));
1742  m_pWatchStoredList->StartListening( *static_cast< SfxBroadcaster* >( pModel ) );
1743  }
1744  }
1745  else
1746  {
1747  OSL_FAIL( "FmXFormView::startMarkListWatching: already listening!" );
1748  }
1749 }
1750 
1752 {
1753  if ( m_pView )
1754  {
1756  const size_t nCount = m_aMark.GetMarkCount( );
1757  for ( size_t i = 0; i < nCount; ++i )
1758  {
1759  SdrMark* pMark = m_aMark.GetMark(i);
1760  SdrObject* pObj = pMark->GetMarkedSdrObj();
1761 
1762  if ( m_pView->IsObjMarked( pObj ) )
1763  {
1764  if ( pObj->IsGroupObject() )
1765  {
1766  SdrObjListIter aIter( pObj->GetSubList() );
1767  bool bMixed = false;
1768  while ( aIter.IsMore() && !bMixed )
1769  bMixed = ( aIter.Next()->GetObjInventor() != SdrInventor::FmForm );
1770 
1771  if ( !bMixed )
1772  {
1773  // all objects in the group are form objects
1774  m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), true /* unmark! */ );
1775  }
1776  }
1777  else
1778  {
1779  if ( pObj->GetObjInventor() == SdrInventor::FmForm )
1780  { // this is a form layer object
1781  m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), true /* unmark! */ );
1782  }
1783  }
1784  }
1785  }
1786  }
1787  else
1788  {
1789  OSL_FAIL( "FmXFormView::saveMarkList: invalid view!" );
1790  m_aMark.Clear();
1791  }
1792 }
1793 
1794 static bool lcl_hasObject( SdrObjListIter& rIter, SdrObject const * pObj )
1795 {
1796  bool bFound = false;
1797  while (rIter.IsMore() && !bFound)
1798  bFound = pObj == rIter.Next();
1799 
1800  rIter.Reset();
1801  return bFound;
1802 }
1803 
1804 
1805 void FmXFormView::restoreMarkList( SdrMarkList& _rRestoredMarkList )
1806 {
1807  if ( !m_pView )
1808  return;
1809 
1810  _rRestoredMarkList.Clear();
1811 
1812  const SdrMarkList& rCurrentList = m_pView->GetMarkedObjectList();
1813  FmFormPage* pPage = GetFormShell() ? GetFormShell()->GetCurPage() : nullptr;
1814  if (!pPage)
1815  return;
1816 
1817  if (rCurrentList.GetMarkCount())
1818  { // there is a current mark ... hmm. Is it a subset of the mark we remembered in saveMarkList?
1819  bool bMisMatch = false;
1820 
1821  // loop through all current marks
1822  const size_t nCurrentCount = rCurrentList.GetMarkCount();
1823  for ( size_t i=0; i<nCurrentCount && !bMisMatch; ++i )
1824  {
1825  const SdrObject* pCurrentMarked = rCurrentList.GetMark( i )->GetMarkedSdrObj();
1826 
1827  // loop through all saved marks, check for equality
1828  bool bFound = false;
1829  const size_t nSavedCount = m_aMark.GetMarkCount();
1830  for ( size_t j=0; j<nSavedCount && !bFound; ++j )
1831  {
1832  if ( m_aMark.GetMark( j )->GetMarkedSdrObj() == pCurrentMarked )
1833  bFound = true;
1834  }
1835 
1836  // did not find a current mark in the saved marks
1837  if ( !bFound )
1838  bMisMatch = true;
1839  }
1840 
1841  if ( bMisMatch )
1842  {
1843  m_aMark.Clear();
1844  _rRestoredMarkList = rCurrentList;
1845  return;
1846  }
1847  }
1848  // it is important that the objects of the mark list are not accessed,
1849  // because they can be already destroyed
1850  SdrPageView* pCurPageView = m_pView->GetSdrPageView();
1851  SdrObjListIter aPageIter( pPage );
1852  bool bFound = true;
1853 
1854  // do all objects still exist
1855  const size_t nCount = m_aMark.GetMarkCount();
1856  for (size_t i = 0; i < nCount && bFound; ++i)
1857  {
1858  SdrMark* pMark = m_aMark.GetMark(i);
1859  SdrObject* pObj = pMark->GetMarkedSdrObj();
1860  if (pObj->IsGroupObject())
1861  {
1862  SdrObjListIter aIter(pObj->GetSubList());
1863  while (aIter.IsMore() && bFound)
1864  bFound = lcl_hasObject(aPageIter, aIter.Next());
1865  }
1866  else
1867  bFound = lcl_hasObject(aPageIter, pObj);
1868 
1869  bFound = bFound && pCurPageView == pMark->GetPageView();
1870  }
1871 
1872  if (bFound)
1873  {
1874  // evaluate the LastObject
1875  if (nCount) // now mark the objects
1876  {
1877  for (size_t i = 0; i < nCount; ++i)
1878  {
1879  SdrMark* pMark = m_aMark.GetMark(i);
1880  SdrObject* pObj = pMark->GetMarkedSdrObj();
1881  if ( pObj->GetObjInventor() == SdrInventor::FmForm )
1882  if ( !m_pView->IsObjMarked( pObj ) )
1883  m_pView->MarkObj( pObj, pMark->GetPageView() );
1884  }
1885 
1886  _rRestoredMarkList = m_aMark;
1887  }
1888  }
1889  m_aMark.Clear();
1890 }
1891 
1892 void SAL_CALL FmXFormView::focusGained( const FocusEvent& /*e*/ )
1893 {
1894  if ( m_xWindow.is() && m_pView )
1895  {
1897  }
1898 }
1899 
1900 void SAL_CALL FmXFormView::focusLost( const FocusEvent& /*e*/ )
1901 {
1902  // when switch the focus outside the office the mark didn't change
1903  // so we can not remove us as focus listener
1904  if ( m_xWindow.is() && m_pView )
1905  {
1907  }
1908 }
1909 
1911 {
1912  if ( GetFormShell() && GetFormShell()->GetImpl() )
1913  return GetFormShell()->GetImpl()->getDocumentType_Lock();
1914  return eUnknownDocumentType;
1915 }
1916 
1917 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ObjectRemoveListener(FmXFormView *pParent)
Definition: fmvwimp.cxx:1684
void stopMarkListWatching()
Definition: fmvwimp.cxx:1723
ImplSVEvent * m_nControlWizardEvent
Definition: fmvwimp.hxx:155
#define ENSURE_OR_RETURN_VOID(c, m)
Type
OutDevType GetOutDevType() const
void displayAsyncErrorMessage(const css::sdb::SQLErrorEvent &_rEvent)
Definition: fmvwimp.cxx:569
void saveMarkList()
Definition: fmvwimp.cxx:1751
Reference< XInterface > getDataSource(const Reference< XInterface > &_rxDependentObject)
css::uno::Reference< css::awt::XWindow > GetParentWindow()
Definition: fmvwimp.cxx:1013
ImplSVEvent * m_nActivationEvent
Definition: fmvwimp.hxx:152
css::uno::Reference< css::awt::XControlContainer > m_xControlContainer
Definition: fmvwimp.hxx:94
void removeWindow(const css::uno::Reference< css::awt::XControlContainer > &_rxCC)
Definition: fmvwimp.cxx:549
void cancelEvents()
Definition: fmvwimp.cxx:399
virtual ~FormViewPageWindowAdapter() override
Definition: fmvwimp.cxx:181
css::uno::Sequence< css::uno::Any > getWrappedPropertyValues() const
SdrHintKind GetKind() const
Definition: svdmodel.hxx:124
size_t GetMarkCount() const
Definition: svdmark.hxx:180
css::uno::Reference< css::form::runtime::XFormController > getController(const css::uno::Reference< css::form::XForm > &xForm) const
Definition: fmvwimp.cxx:281
css::uno::Reference< css::awt::XWindow > m_xWindow
Definition: fmvwimp.hxx:147
exports com.sun.star.form. control
void setWidth(tools::Long nWidth)
css::uno::Reference< css::form::XForm > findPlaceInFormComponentHierarchy(const css::uno::Reference< css::form::XFormComponent > &rContent, const css::uno::Reference< css::sdbc::XDataSource > &rDatabase=css::uno::Reference< css::sdbc::XDataSource >(), const OUString &rDBTitle=OUString(), const OUString &rCursorSource=OUString(), sal_Int32 nCommandType=0)
finds a place in the form component hierarchy where to insert the given component ...
Definition: fmpgeimp.cxx:443
void resumeTabOrderUpdate()
resumes calls to activateTabOrder, and also does all pending calls which were collected since the las...
Definition: fmvwimp.cxx:596
#define FM_PROP_FIELDTYPE
Definition: fmprop.hxx:75
FmXFormShell * GetImpl() const
Definition: fmshell.hxx:118
static OUString setUniqueName(const css::uno::Reference< css::form::XFormComponent > &xFormComponent, const css::uno::Reference< css::form::XForm > &xControls)
Definition: fmpgeimp.cxx:618
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
SVX_DLLPRIVATE const OutputDevice * GetActualOutDev() const
Definition: fmview.hxx:145
#define FM_COMPONENT_COMMANDBUTTON
Definition: fmservs.hxx:36
virtual void SAL_CALL focusLost(const css::awt::FocusEvent &e) override
Definition: fmvwimp.cxx:1900
#define FM_PROP_COMMAND
Definition: fmprop.hxx:117
void startMarkListWatching()
Definition: fmvwimp.cxx:1733
#define FM_PROP_ISCURRENCY
Definition: fmprop.hxx:126
bool IsModuleInstalled(EModule eModule) const
long Long
void onFirstViewActivation(const FmFormModel *_pDocModel)
Definition: fmvwimp.cxx:584
bool IsDesignMode() const
Definition: svdmrkv.hxx:236
bool getBOOL(const Any &_rAny)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: fmvwimp.cxx:1690
sal_Int64 n
#define FM_PROP_LABEL
Definition: fmprop.hxx:40
#define FM_PROP_MULTILINE
Definition: fmprop.hxx:51
css::uno::Reference< css::awt::XControlContainer > const & GetControlContainer(bool _bCreateIfNecessary=true) const
void notifyViewDying()
Definition: fmvwimp.cxx:427
SVX_DLLPRIVATE FmFormShell * GetFormShell() const
Definition: fmview.hxx:132
FmFormPage * GetCurPage() const
Definition: fmshell.cxx:1132
static SdrObject * MakeNewObject(SdrModel &rSdrModel, SdrInventor nInventor, SdrObjKind nObjIdentifier, const tools::Rectangle *pSnapRect=nullptr)
Definition: svdobj.cxx:3134
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
const MapMode & GetMapMode() const
::std::vector< css::uno::Reference< css::form::runtime::XFormController > > m_aControllerList
Definition: fmvwimp.hxx:93
SdrInventor
Definition: svdobj.hxx:98
void setController(const css::uno::Reference< css::form::XForm > &xForm, const css::uno::Reference< css::form::runtime::XFormController > &_rxParentController)
Definition: fmvwimp.cxx:298
SdrMark * GetMark(size_t nNum) const
Definition: svdmark.cxx:230
void Clear()
Definition: svdmark.cxx:201
bool GetAutoControlFocus() const
Definition: fmmodel.hxx:64
Reference< XNumberFormatsSupplier > getNumberFormats(const Reference< XConnection > &_rxConn, bool _bAlloweDefault, const Reference< XComponentContext > &_rxContext)
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
Definition: svdpage.cxx:338
FmFormView * getView() const
Definition: fmvwimp.hxx:208
void DeleteMark(size_t nNum)
Definition: svdmark.cxx:316
void ObjectRemovedInAliveMode(const SdrObject *pObject)
Definition: fmvwimp.cxx:1700
virtual SdrObjList * GetSubList() const
Definition: svdobj.cxx:721
SdrObjKind
Definition: svdobjkind.hxx:24
SdrObjectUniquePtr implCreateFieldControl(const svx::ODataAccessDescriptor &_rColumnDescriptor)
Definition: fmvwimp.cxx:1113
SfxHintId GetId() const
void restoreMarkList(SdrMarkList &_rRestoredMarkList)
Definition: fmvwimp.cxx:1805
FmFormModel * GetFormModel() const
Definition: fmshell.hxx:116
#define FM_PROP_NAME
Definition: fmprop.hxx:29
constexpr tools::Long Width() const
virtual ~FmXFormView() override
Definition: fmvwimp.cxx:435
css::uno::Reference< css::beans::XPropertySet > xPropSet
Definition: xmlexchg.hxx:43
Reference< XController > xController
bool IsMore() const
Definition: svditer.hxx:62
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:25
DataType
OUTDEV_WINDOW
bool OutputToWindow() const
ImplSVEvent * m_nAutoFocusEvent
Definition: fmvwimp.hxx:154
static bool isFocusable(const css::uno::Reference< css::awt::XControl > &i_rControl)
Definition: fmvwimp.cxx:777
int nCount
#define FM_PROP_CLASSID
Definition: fmprop.hxx:30
virtual void SAL_CALL formActivated(const css::lang::EventObject &rEvent) override
Definition: fmvwimp.cxx:463
void AutoFocus()
the auto focus to the first (in terms of the tab order) control
Definition: fmvwimp.cxx:768
css::sdb::SQLErrorEvent m_aAsyncError
Definition: fmvwimp.hxx:158
FmFormPageImpl & GetImpl() const
Definition: fmpage.hxx:62
virtual sal_Int32 SAL_CALL getCount() override
Definition: fmvwimp.cxx:228
void onCreatedFormObject(FmFormObj const &_rFormObject)
Definition: fmvwimp.cxx:967
virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
Definition: fmvwimp.cxx:233
friend class FormViewPageWindowAdapter
Definition: fmvwimp.hxx:143
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
SdrObject * GetMarkedSdrObj() const
Definition: svdmark.hxx:68
Everything a View needs to know about a selected object.
Definition: svdmark.hxx:44
DocumentType
#define DBG_UNHANDLED_EXCEPTION(...)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_ASSERT(sCon, aError)
int i
uno_Any a
virtual void SAL_CALL makeVisible(const css::uno::Reference< css::awt::XControl > &Control) override
Definition: fmvwimp.cxx:244
class SAL_NO_VTABLE XPropertySet
Definition: xmlexchg.hxx:28
IMPL_LINK_NOARG(FmXFormView, OnDelayedErrorMessage, void *, void)
Definition: fmvwimp.cxx:578
virtual void MakeVisible(const tools::Rectangle &rRect, vcl::Window &rWin)
Definition: svdpntv.cxx:1005
css::uno::Reference< css::form::runtime::XFormController > getFormController(const css::uno::Reference< css::form::XForm > &_rxForm, const OutputDevice &_rDevice) const
Definition: fmvwimp.cxx:875
MapControlContainerToSetOfForms m_aNeedTabOrderUpdate
Definition: fmvwimp.hxx:163
const SdrMarkList & GetMarkedObjectList() const
Definition: svdmrkv.hxx:252
SdrPageView * GetPageView() const
Definition: svdmark.hxx:70
friend class ObjectRemoveListener
Definition: fmvwimp.hxx:144
void suspendTabOrderUpdate()
suspends the calls to activateTabOrder, which normally happen whenever for any ControlContainer of th...
Definition: fmvwimp.cxx:590
virtual css::uno::Type SAL_CALL getElementType() override
Definition: fmvwimp.cxx:222
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
Definition: fmvwimp.cxx:448
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: fmvwimp.hxx:95
void SetMoveOutside(bool _bMoveOutside, ImplAccess)
Definition: fmview.hxx:138
unsigned char sal_Bool
void addWindow(const SdrPageWindow &)
Definition: fmvwimp.cxx:527
static Reference< XControl > lcl_firstFocussableControl(const Sequence< Reference< XControl > > &_rControls)
Definition: fmvwimp.cxx:818
bool IsGroupObject() const
Definition: svdobj.cxx:716
FmFormShell * GetFormShell() const
Definition: fmvwimp.cxx:763
css::uno::Type const & get()
#define FM_SUN_COMPONENT_CHECKBOX
Definition: fmservs.hxx:62
::svxform::DocumentType impl_getDocumentType() const
Definition: fmvwimp.cxx:1910
Abstract DrawObject.
Definition: svdobj.hxx:258
void breakCreateFormObject()
Definition: fmvwimp.cxx:1003
virtual SdrInventor GetObjInventor() const
Definition: svdobj.cxx:627
Point PixelToLogic(const Point &rDevicePt) const
void Activate(bool bSync=false)
Definition: fmvwimp.cxx:732
OUString getDataSource() const
returns either the data source name if given or the database location
SdrObject * Next()
Definition: svditer.hxx:63
Reference< XConnection > getConnection_withFeedback(const OUString &_rDataSourceName, const OUString &_rUser, const OUString &_rPwd, const Reference< XComponentContext > &_rxContext, const Reference< XWindow > &_rxParent)
std::vector< PFormViewPageWindowAdapter > m_aPageWindowAdapters
Definition: fmvwimp.hxx:161
bool m_isTabOrderUpdateSuspended
Definition: fmvwimp.hxx:171
class encapsulating the css::sdb::DataAccessDescriptor service.
virtual void SAL_CALL elementInserted(const css::container::ContainerEvent &rEvent) override
Definition: fmvwimp.cxx:478
css::uno::Reference< css::beans::XPropertySet > m_xLastCreatedControlModel
Definition: fmvwimp.hxx:148
virtual void SAL_CALL focusGained(const css::awt::FocusEvent &e) override
Definition: fmvwimp.cxx:1892
#define FM_PROP_BUTTON_TYPE
Definition: fmprop.hxx:142
constexpr tools::Long Height() const
SdrPage * GetPage() const
Definition: svdpagv.hxx:171
sal_Int32 nDataType
void updateTabOrder(const css::uno::Reference< css::form::XForm > &_rxForm)
Definition: fmvwimp.cxx:352
tools::Long GetTextHeight() const
SdrPaintWindow & GetPaintWindow() const
bool put(const char *_pAsciiValueName, const VALUE_TYPE &_rValue)
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
virtual sal_Bool SAL_CALL hasElements() override
Definition: fmvwimp.cxx:217
Reference< XComponentContext > getProcessComponentContext()
ImplSVEvent * m_nErrorMessageEvent
Definition: fmvwimp.hxx:153
virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent &rEvent) override
Definition: fmvwimp.cxx:512
virtual void SAL_CALL formDeactivated(const css::lang::EventObject &rEvent) override
Definition: fmvwimp.cxx:470
SdrMarkList m_aMark
Definition: fmvwimp.hxx:166
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
Definition: svdobj.hxx:96
virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent &rEvent) override
Definition: fmvwimp.cxx:506
SdrPageView * GetSdrPageView() const
Definition: svdpntv.hxx:304
Reference< XConnection > getConnection(const Reference< XRowSet > &_rxRowSet)
const css::uno::Reference< css::awt::XControlModel > & GetUnoControlModel() const
Definition: svdouno.hxx:92
#define FM_SUN_COMPONENT_NUMERICFIELD
Definition: fmservs.hxx:68
void setHeight(tools::Long nHeight)
bool hasProperty(const OUString &_rName, const Reference< XPropertySet > &_rxSet)
VclPtr< vcl::Window > m_pWindow
Definition: fmvwimp.hxx:97
FormViewPageWindowAdapter(const css::uno::Reference< css::uno::XComponentContext > &_rContext, const SdrPageWindow &, FmXFormView *pView)
Definition: fmvwimp.cxx:151
FmFormView * m_pView
Definition: fmvwimp.hxx:151
#define SAL_WARN(area, stream)
Reference< XModel > xModel
class FmSearchEngine - Impl class for FmSearchDialog
PFormViewPageWindowAdapter findWindow(const css::uno::Reference< css::awt::XControlContainer > &_rxCC) const
Definition: fmvwimp.cxx:517
bool MarkObj(const Point &rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false)
Definition: svdmrkv.cxx:1863
void reset(const css::uno::Reference< INTERFACE > &_rxComponent, AssignmentMode _eMode=TakeOwnership)
void ShowServiceNotAvailableError(weld::Widget *pParent, std::u16string_view rServiceName, bool bError)
sal_Int32 nLength
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:365
const css::uno::Reference< css::form::XForms > & GetForms(bool _bForceCreate=true) const
Definition: fmpage.cxx:86
Reference< XComponentContext > m_xContext
void Reset()
Definition: svditer.hxx:61
SdrObjectUniquePtr implCreateXFormsControl(const svx::OXFormsDescriptor &_rDesc)
Definition: fmvwimp.cxx:1345
Reference< XNameAccess > getFieldsByCommandDescriptor(const Reference< XConnection > &_rxConnection, const sal_Int32 _nCommandType, const OUString &_rCommand, Reference< XComponent > &_rxKeepFieldsAlive, SQLExceptionInfo *_pErrorInfo)
static css::uno::Reference< css::awt::XWindow > GetInterface(vcl::Window *pWindow)
#define FM_PROP_CONTROLLABEL
Definition: fmprop.hxx:110
FmXFormView(FmFormView *_pView)
Definition: fmvwimp.cxx:386
static Reference< XFormController > getControllerSearchChildren(const Reference< XIndexAccess > &xIndex, const Reference< XTabControllerModel > &xModel)
Definition: fmvwimp.cxx:258
OutputDevice & GetOutputDevice() const
FmXFormView * m_pViewImpl
Definition: fmvwimp.hxx:96
void Deactivate(bool bDeactivateController=true)
Definition: fmvwimp.cxx:749
static bool createControlLabelPair(OutputDevice const &_rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM, const css::uno::Reference< css::beans::XPropertySet > &_rxField, const css::uno::Reference< css::util::XNumberFormats > &_rxNumberFormats, SdrObjKind _nControlObjectID, std::u16string_view _rFieldPostfix, SdrInventor _nInventor, SdrObjKind _nLabelObjectID, SdrModel &_rModel, std::unique_ptr< SdrUnoObj, SdrObjectFreeOp > &_rpLabel, std::unique_ptr< SdrUnoObj, SdrObjectFreeOp > &_rpControl)
void displayException(const Any &_rExcept, const css::uno::Reference< css::awt::XWindow > &rParent)
Definition: fmtools.cxx:86
static bool lcl_hasObject(SdrObjListIter &rIter, SdrObject const *pObj)
Definition: fmvwimp.cxx:1794
#define FM_PROP_ENABLED
Definition: fmprop.hxx:44
SdrPageView & GetPageView() const
std::unique_ptr< ObjectRemoveListener > m_pWatchStoredList
Definition: fmvwimp.hxx:168
bool IsObjMarked(SdrObject const *pObj) const
Definition: svdmrkv.cxx:2130
const SdrObject * GetObject() const
Definition: svdmodel.hxx:123
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)