LibreOffice Module svx (master)  1
fmshimp.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 <sal/macros.h>
22 #include <sal/log.hxx>
23 #include <fmobj.hxx>
24 #include <fmpgeimp.hxx>
25 #include <svx/fmtools.hxx>
26 #include <fmprop.hxx>
27 #include <fmservs.hxx>
28 #include <fmshimp.hxx>
29 #include <fmtextcontrolshell.hxx>
30 #include <fmundo.hxx>
31 #include <fmurl.hxx>
32 #include <fmvwimp.hxx>
33 #include <formtoolbars.hxx>
34 #include <gridcols.hxx>
35 #include <svx/svditer.hxx>
36 #include <svx/dialmgr.hxx>
37 #include <svx/strings.hrc>
38 #include <svx/fmglob.hxx>
39 #include <svx/fmmodel.hxx>
40 #include <svx/fmpage.hxx>
41 #include <svx/fmshell.hxx>
42 #include <svx/fmview.hxx>
43 #include <svx/obj3d.hxx>
44 #include <svx/sdrpagewindow.hxx>
45 #include <svx/svdpagv.hxx>
46 #include <svx/svxdlg.hxx>
47 #include <svx/svxids.hrc>
48 #include <bitmaps.hlst>
49 
50 #include <com/sun/star/awt/XWindow2.hpp>
51 #include <com/sun/star/awt/XCheckBox.hpp>
52 #include <com/sun/star/awt/XListBox.hpp>
53 #include <com/sun/star/awt/XTextComponent.hpp>
54 #include <com/sun/star/beans/theIntrospection.hpp>
55 #include <com/sun/star/beans/NamedValue.hpp>
56 #include <com/sun/star/beans/PropertyAttribute.hpp>
57 #include <com/sun/star/beans/XPropertyState.hpp>
58 #include <com/sun/star/container/XContainer.hpp>
59 #include <com/sun/star/container/XEnumeration.hpp>
60 #include <com/sun/star/container/XEnumerationAccess.hpp>
61 #include <com/sun/star/container/XIndexAccess.hpp>
62 #include <com/sun/star/container/XNamed.hpp>
63 #include <com/sun/star/form/ListSourceType.hpp>
64 #include <com/sun/star/form/TabOrderDialog.hpp>
65 #include <com/sun/star/form/XBoundComponent.hpp>
66 #include <com/sun/star/form/XBoundControl.hpp>
67 #include <com/sun/star/form/XGrid.hpp>
68 #include <com/sun/star/form/XGridPeer.hpp>
69 #include <com/sun/star/form/XLoadable.hpp>
70 #include <com/sun/star/form/XReset.hpp>
71 #include <com/sun/star/form/binding/XBindableValue.hpp>
72 #include <com/sun/star/form/binding/XListEntrySink.hpp>
73 #include <com/sun/star/frame/FrameSearchFlag.hpp>
74 #include <com/sun/star/script/XEventAttacherManager.hpp>
75 #include <com/sun/star/sdbc/SQLException.hpp>
76 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
77 #include <com/sun/star/util/XCancellable.hpp>
78 #include <com/sun/star/util/XModeSelector.hpp>
79 #include <com/sun/star/util/XModifyBroadcaster.hpp>
80 #include <com/sun/star/util/XNumberFormatter.hpp>
81 #include <com/sun/star/view/XSelectionSupplier.hpp>
82 
85 #include <comphelper/property.hxx>
86 #include <comphelper/sequence.hxx>
88 #include <comphelper/string.hxx>
89 #include <comphelper/types.hxx>
90 #include <connectivity/dbtools.hxx>
91 #include <sfx2/dispatch.hxx>
92 #include <sfx2/docfile.hxx>
93 #include <sfx2/frame.hxx>
94 #include <sfx2/objsh.hxx>
95 #include <sfx2/viewfrm.hxx>
96 #include <sfx2/viewsh.hxx>
98 #include <tools/debug.hxx>
99 #include <tools/diagnose_ex.h>
100 #include <vcl/image.hxx>
101 #include <vcl/weld.hxx>
102 #include <vcl/settings.hxx>
103 #include <vcl/svapp.hxx>
104 
105 #include <algorithm>
106 #include <functional>
107 #include <map>
108 #include <memory>
109 #include <vector>
110 
111 // is used for Invalidate -> maintain it as well
112 static const sal_uInt16 DatabaseSlotMap[] =
113 {
114  SID_FM_RECORD_FIRST,
115  SID_FM_RECORD_NEXT,
116  SID_FM_RECORD_PREV,
117  SID_FM_RECORD_LAST,
118  SID_FM_RECORD_NEW,
119  SID_FM_RECORD_DELETE,
120  SID_FM_RECORD_ABSOLUTE,
121  SID_FM_RECORD_TOTAL,
122  SID_FM_RECORD_SAVE,
123  SID_FM_RECORD_UNDO,
124  SID_FM_REMOVE_FILTER_SORT,
125  SID_FM_SORTUP,
126  SID_FM_SORTDOWN,
127  SID_FM_ORDERCRIT,
128  SID_FM_AUTOFILTER,
129  SID_FM_FORM_FILTERED,
130  SID_FM_REFRESH,
131  SID_FM_REFRESH_FORM_CONTROL,
132  SID_FM_SEARCH,
133  SID_FM_FILTER_START,
134  SID_FM_VIEW_AS_GRID,
135  0
136 };
137 
138 // is used for Invalidate -> maintain it as well
139 // sort ascending !!!!!!
140 static const sal_Int16 DlgSlotMap[] = // slots of the controller
141 {
142  SID_FM_CTL_PROPERTIES,
143  SID_FM_PROPERTIES,
144  SID_FM_TAB_DIALOG,
145  SID_FM_ADD_FIELD,
146  SID_FM_SHOW_FMEXPLORER,
147  SID_FM_FIELDS_CONTROL,
148  SID_FM_SHOW_PROPERTIES,
149  SID_FM_PROPERTY_CONTROL,
150  SID_FM_FMEXPLORER_CONTROL,
151  SID_FM_SHOW_DATANAVIGATOR,
152  SID_FM_DATANAVIGATOR_CONTROL,
153  0
154 };
155 
156 static const sal_Int16 SelObjectSlotMap[] = // slots depending on the SelObject
157 {
158  SID_FM_CONVERTTO_EDIT,
159  SID_FM_CONVERTTO_BUTTON,
160  SID_FM_CONVERTTO_FIXEDTEXT,
161  SID_FM_CONVERTTO_LISTBOX,
162  SID_FM_CONVERTTO_CHECKBOX,
163  SID_FM_CONVERTTO_RADIOBUTTON,
164  SID_FM_CONVERTTO_GROUPBOX,
165  SID_FM_CONVERTTO_COMBOBOX,
166  SID_FM_CONVERTTO_IMAGEBUTTON,
167  SID_FM_CONVERTTO_FILECONTROL,
168  SID_FM_CONVERTTO_DATE,
169  SID_FM_CONVERTTO_TIME,
170  SID_FM_CONVERTTO_NUMERIC,
171  SID_FM_CONVERTTO_CURRENCY,
172  SID_FM_CONVERTTO_PATTERN,
173  SID_FM_CONVERTTO_IMAGECONTROL,
174  SID_FM_CONVERTTO_FORMATTED,
175  SID_FM_CONVERTTO_SCROLLBAR,
176  SID_FM_CONVERTTO_SPINBUTTON,
177  SID_FM_CONVERTTO_NAVIGATIONBAR,
178 
179  SID_FM_FMEXPLORER_CONTROL,
180  SID_FM_DATANAVIGATOR_CONTROL,
181 
182  0
183 };
184 
185 // the following arrays must be consistent, i.e., corresponding entries should
186 // be at the same relative position within their respective arrays
187 static const char* aConvertSlots[] =
188 {
189  "ConvertToEdit",
190  "ConvertToButton",
191  "ConvertToFixed",
192  "ConvertToList",
193  "ConvertToCheckBox",
194  "ConvertToRadio",
195  "ConvertToGroup",
196  "ConvertToCombo",
197  "ConvertToImageBtn",
198  "ConvertToFileControl",
199  "ConvertToDate",
200  "ConvertToTime",
201  "ConvertToNumeric",
202  "ConvertToCurrency",
203  "ConvertToPattern",
204  "ConvertToImageControl",
205  "ConvertToFormatted",
206  "ConvertToScrollBar",
207  "ConvertToSpinButton",
208  "ConvertToNavigationBar"
209 };
210 
211 static const OUStringLiteral aImgIds[] =
212 {
213  RID_SVXBMP_EDITBOX,
214  RID_SVXBMP_BUTTON,
215  RID_SVXBMP_FIXEDTEXT,
216  RID_SVXBMP_LISTBOX,
217  RID_SVXBMP_CHECKBOX,
218  RID_SVXBMP_RADIOBUTTON,
219  RID_SVXBMP_GROUPBOX,
220  RID_SVXBMP_COMBOBOX,
221  RID_SVXBMP_IMAGEBUTTON,
222  RID_SVXBMP_FILECONTROL,
223  RID_SVXBMP_DATEFIELD,
224  RID_SVXBMP_TIMEFIELD,
225  RID_SVXBMP_NUMERICFIELD,
226  RID_SVXBMP_CURRENCYFIELD,
227  RID_SVXBMP_PATTERNFIELD,
228  RID_SVXBMP_IMAGECONTROL,
229  RID_SVXBMP_FORMATTEDFIELD,
230  RID_SVXBMP_SCROLLBAR,
231  RID_SVXBMP_SPINBUTTON,
232  RID_SVXBMP_NAVIGATIONBAR
233 };
234 
235 static const sal_Int16 nObjectTypes[] =
236 {
237  OBJ_FM_EDIT,
257 };
258 
259 using namespace ::com::sun::star;
260 using namespace ::com::sun::star::ui;
261 using namespace ::com::sun::star::uno;
262 using namespace ::com::sun::star::sdb;
263 using namespace ::com::sun::star::sdbc;
264 using namespace ::com::sun::star::sdbcx;
265 using namespace ::com::sun::star::beans;
266 using namespace ::com::sun::star::container;
267 using namespace ::com::sun::star::form;
268 using namespace ::com::sun::star::form::binding;
269 using namespace ::com::sun::star::form::runtime;
270 using namespace ::com::sun::star::awt;
271 using namespace ::com::sun::star::view;
272 using namespace ::com::sun::star::util;
273 using namespace ::com::sun::star::script;
274 using namespace ::svxform;
275 using namespace ::svx;
276 using namespace ::dbtools;
277 
278 
279 //= helper
280 
281 namespace
282 {
283 
284  void collectInterfacesFromMarkList( const SdrMarkList& _rMarkList, InterfaceBag& /* [out] */ _rInterfaces )
285  {
286  _rInterfaces.clear();
287 
288  const size_t nMarkCount = _rMarkList.GetMarkCount();
289  for ( size_t i = 0; i < nMarkCount; ++i)
290  {
291  SdrObject* pCurrent = _rMarkList.GetMark( i )->GetMarkedSdrObj();
292 
293  std::unique_ptr<SdrObjListIter> pGroupIterator;
294  if ( pCurrent->IsGroupObject() )
295  {
296  pGroupIterator.reset(new SdrObjListIter( pCurrent->GetSubList() ));
297  pCurrent = pGroupIterator->IsMore() ? pGroupIterator->Next() : nullptr;
298  }
299 
300  while ( pCurrent )
301  {
302  FmFormObj* pAsFormObject = FmFormObj::GetFormObject( pCurrent );
303  // note this will de-reference virtual objects, if necessary/possible
304  if ( pAsFormObject )
305  {
306  Reference< XInterface > xControlModel( pAsFormObject->GetUnoControlModel(), UNO_QUERY );
307  // the UNO_QUERY is important for normalization
308  if ( xControlModel.is() )
309  _rInterfaces.insert( xControlModel );
310  }
311 
312  // next element
313  pCurrent = pGroupIterator && pGroupIterator->IsMore() ? pGroupIterator->Next() : nullptr;
314  }
315  }
316  }
317 
318 
319  sal_Int32 GridView2ModelPos(const Reference< XIndexAccess>& rColumns, sal_Int16 nViewPos)
320  {
321  try
322  {
323  if (rColumns.is())
324  {
325  // loop through all columns
326  sal_Int32 i;
327  Reference< XPropertySet> xCur;
328  for (i=0; i<rColumns->getCount(); ++i)
329  {
330  rColumns->getByIndex(i) >>= xCur;
331  if (!::comphelper::getBOOL(xCur->getPropertyValue(FM_PROP_HIDDEN)))
332  {
333  // for every visible col : if nViewPos is greater zero, decrement it, else we
334  // have found the model position
335  if (!nViewPos)
336  break;
337  else
338  --nViewPos;
339  }
340  }
341  if (i<rColumns->getCount())
342  return i;
343  }
344  }
345  catch(const Exception&)
346  {
348  }
349  return -1;
350  }
351 
352 
353  void TransferEventScripts(const Reference< XControlModel>& xModel, const Reference< XControl>& xControl,
354  const Sequence< ScriptEventDescriptor>& rTransferIfAvailable)
355  {
356  // first check if we have a XEventAttacherManager for the model
357  Reference< XChild> xModelChild(xModel, UNO_QUERY);
358  if (!xModelChild.is())
359  return; // nothing to do
360 
361  Reference< XEventAttacherManager> xEventManager(xModelChild->getParent(), UNO_QUERY);
362  if (!xEventManager.is())
363  return; // nothing to do
364 
365  if (!rTransferIfAvailable.hasElements())
366  return; // nothing to do
367 
368  // check for the index of the model within its parent
369  Reference< XIndexAccess> xParentIndex(xModelChild->getParent(), UNO_QUERY);
370  if (!xParentIndex.is())
371  return; // nothing to do
372  sal_Int32 nIndex = getElementPos(xParentIndex, xModel);
373  if (nIndex<0 || nIndex>=xParentIndex->getCount())
374  return; // nothing to do
375 
376  // then we need information about the listeners supported by the control and the model
377  Sequence< Type> aModelListeners;
378  Sequence< Type> aControlListeners;
379 
380  Reference< XIntrospection> xIntrospection = theIntrospection::get(::comphelper::getProcessComponentContext());
381 
382  if (xModel.is())
383  {
384  Any aModel(makeAny(xModel));
385  aModelListeners = xIntrospection->inspect(aModel)->getSupportedListeners();
386  }
387 
388  if (xControl.is())
389  {
390  Any aControl(makeAny(xControl));
391  aControlListeners = xIntrospection->inspect(aControl)->getSupportedListeners();
392  }
393 
394  sal_Int32 nMaxNewLen = aModelListeners.getLength() + aControlListeners.getLength();
395  if (!nMaxNewLen)
396  return; // the model and the listener don't support any listeners (or we were unable to retrieve these infos)
397 
398  Sequence< ScriptEventDescriptor> aTransferable(nMaxNewLen);
399  ScriptEventDescriptor* pTransferable = aTransferable.getArray();
400 
401  for (const ScriptEventDescriptor& rCurrent : rTransferIfAvailable)
402  {
403  // search the model/control idl classes for the event described by pCurrent
404  for (const Sequence< Type>* pCurrentArray : { &aModelListeners, &aControlListeners })
405  {
406  for (const Type& rCurrentListener : *pCurrentArray)
407  {
408  OUString aListener = rCurrentListener.getTypeName();
409  if (!aListener.isEmpty())
410  aListener = aListener.copy(aListener.lastIndexOf('.')+1);
411 
412  if (aListener == rCurrent.ListenerType)
413  // the current ScriptEventDescriptor doesn't match the current listeners class
414  continue;
415 
416  // now check the methods
417  Sequence< OUString> aMethodsNames = ::comphelper::getEventMethodsForType(rCurrentListener);
418 
419  if (comphelper::findValue(aMethodsNames, rCurrent.EventMethod) != -1)
420  {
421  // we can transfer the script event : the model (control) supports it
422  *pTransferable = rCurrent;
423  ++pTransferable;
424  break;
425  }
426  }
427  }
428  }
429 
430  sal_Int32 nRealNewLen = pTransferable - aTransferable.getArray();
431  aTransferable.realloc(nRealNewLen);
432 
433  xEventManager->registerScriptEvents(nIndex, aTransferable);
434  }
435 
436 
437  OUString getServiceNameByControlType(sal_Int16 nType)
438  {
439  switch (nType)
440  {
441  case OBJ_FM_EDIT : return FM_COMPONENT_TEXTFIELD;
444  case OBJ_FM_LISTBOX : return FM_COMPONENT_LISTBOX;
463  }
464  return OUString();
465  }
466 
467 }
468 
469 
470 // check if the control has one of the interfaces we can use for searching
471 // *_pCurrentText will be filled with the current text of the control (as used when searching this control)
472 bool IsSearchableControl( const css::uno::Reference< css::uno::XInterface>& _rxControl,
473  OUString* _pCurrentText )
474 {
475  if ( !_rxControl.is() )
476  return false;
477 
478  Reference< XTextComponent > xAsText( _rxControl, UNO_QUERY );
479  if ( xAsText.is() )
480  {
481  if ( _pCurrentText )
482  *_pCurrentText = xAsText->getText();
483  return true;
484  }
485 
486  Reference< XListBox > xListBox( _rxControl, UNO_QUERY );
487  if ( xListBox.is() )
488  {
489  if ( _pCurrentText )
490  *_pCurrentText = xListBox->getSelectedItem();
491  return true;
492  }
493 
494  Reference< XCheckBox > xCheckBox( _rxControl, UNO_QUERY );
495  if ( xCheckBox.is() )
496  {
497  if ( _pCurrentText )
498  {
499  switch ( static_cast<::TriState>(xCheckBox->getState()) )
500  {
501  case TRISTATE_FALSE: *_pCurrentText = "0"; break;
502  case TRISTATE_TRUE: *_pCurrentText = "1"; break;
503  default: _pCurrentText->clear(); break;
504  }
505  }
506  return true;
507  }
508 
509  return false;
510 }
511 
512 
514 {
515  if (_rContainer == m_xStartingPoint)
516  // would be quite stupid to step over the root...
517  return true;
518 
519  return Reference< XControlModel>(_rContainer, UNO_QUERY).is();
520 }
521 
522 
524 {
525  if (!_rElement.is())
526  // NULL element
527  return false;
528 
529  if (Reference< XForm>(_rElement, UNO_QUERY).is() || Reference< XGrid>(_rElement, UNO_QUERY).is())
530  // a forms or a grid
531  return false;
532 
533  Reference< XPropertySet> xSet(_rElement, UNO_QUERY);
534  if (!xSet.is() || !::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
535  // no "BoundField" property
536  return false;
537 
538  Any aVal( xSet->getPropertyValue(FM_PROP_BOUNDFIELD) );
539  if (aVal.getValueTypeClass() != TypeClass_INTERFACE)
540  // void or invalid property value
541  return false;
542 
543  return aVal.hasValue();
544 }
545 
546 
547 static bool isControlList(const SdrMarkList& rMarkList)
548 {
549  // the list contains only controls and at least one control
550  const size_t nMarkCount = rMarkList.GetMarkCount();
551  bool bControlList = nMarkCount != 0;
552 
553  bool bHadAnyLeafs = false;
554 
555  for (size_t i = 0; i < nMarkCount && bControlList; ++i)
556  {
557  SdrObject *pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
558  E3dObject* pAs3DObject = dynamic_cast< E3dObject* >( pObj);
559  // E3dObject's do not contain any 2D-objects (by definition)
560  // we need this extra check here : an E3dObject->IsGroupObject says "YES", but an SdrObjListIter working
561  // with an E3dObject doesn't give me any Nodes (E3dObject has a sub list, but no members in that list,
562  // cause there implementation differs from the one of "normal" SdrObject's. Unfortunally SdrObject::IsGroupObject
563  // doesn't check the element count of the sub list, which is simply a bug in IsGroupObject we can't fix at the moment).
564  // So at the end of this function bControlList would have the same value it was initialized with above : sal_True
565  // And this would be wrong :)
566  // 03.02.00 - 72529 - FS
567  if (!pAs3DObject)
568  {
569  if (pObj->IsGroupObject())
570  {
571  SdrObjListIter aIter(pObj->GetSubList());
572  while (aIter.IsMore() && bControlList)
573  {
574  bControlList = SdrInventor::FmForm == aIter.Next()->GetObjInventor();
575  bHadAnyLeafs = true;
576  }
577  }
578  else
579  {
580  bHadAnyLeafs = true;
581  bControlList = SdrInventor::FmForm == pObj->GetObjInventor();
582  }
583  }
584  }
585 
586  return bControlList && bHadAnyLeafs;
587 }
588 
589 
590 static Reference< XForm > GetForm(const Reference< XInterface>& _rxElement)
591 {
592  Reference< XForm > xForm( _rxElement, UNO_QUERY );
593  if ( xForm.is() )
594  return xForm;
595 
596  Reference< XChild > xChild( _rxElement, UNO_QUERY );
597  if ( xChild.is() )
598  return GetForm( xChild->getParent() );
599 
600  return Reference< XForm >();
601 }
602 
604  :FmXFormShell_BD_BASE( _rMutex )
605 {
606 }
607 
610  ,FmXFormShell_CFGBASE("Office.Common/Misc", ConfigItemMode::NONE)
611  ,m_eNavigate( NavigationBarMode_NONE )
612  ,m_nInvalidationEvent( nullptr )
613  ,m_nActivationEvent( nullptr )
614  ,m_pShell( &_rShell )
615  ,m_pTextShell( new svx::FmTextControlShell( _pViewFrame ) )
617  ,m_aNavControllerFeatures( this )
621  ,m_bTrackProperties( true )
622  ,m_bUseWizards( true )
623  ,m_bDatabaseBar( false )
624  ,m_bInActivate( false )
625  ,m_bSetFocus( false )
626  ,m_bFilterMode( false )
627  ,m_bChangingDesignMode( false )
628  ,m_bPreparedClose( false )
629  ,m_bFirstActivation( true )
630 {
632  m_aMarkTimer.SetInvokeHandler(LINK(this, FmXFormShell, OnTimeOut_Lock));
633  m_aMarkTimer.SetDebugName("svx::FmXFormShell m_aMarkTimer");
634 
635  m_xAttachedFrame = _pViewFrame->GetFrame().GetFrameInterface();
636 
637  // to prevent deletion of this we acquire our refcounter once
638  osl_atomic_increment(&m_refCount);
639 
640  // correct the refcounter
641  osl_atomic_decrement(&m_refCount);
642 
643  // cache the current configuration settings we're interested in
645  // and register for changes on this settings
646  Sequence< OUString > aNames { "FormControlPilotsEnabled" };
647  EnableNotification(aNames);
648 }
649 
650 
652 {
653 }
654 
655 
656 Reference< css::frame::XModel > FmXFormShell::getContextDocument_Lock() const
657 {
658  Reference< css::frame::XModel > xModel;
659 
660  // determine the type of document we live in
661  try
662  {
663  Reference< css::frame::XController > xController;
664  if ( m_xAttachedFrame.is() )
665  xController = m_xAttachedFrame->getController();
666  if ( xController.is() )
667  xModel = xController->getModel();
668  }
669  catch( const Exception& )
670  {
672  }
673  return xModel;
674 }
675 
676 
678 {
680 }
681 
682 
684 {
686  if ( !m_pShell )
687  {
688  OSL_FAIL( "FmXFormShell::impl_checkDisposed: already disposed!" );
689  return true;
690  }
691  return false;
692 }
693 
694 
696 {
698  return m_eDocumentType;
699 
700  // determine the type of document we live in
701  Reference<css::frame::XModel> xModel = getContextDocument_Lock();
702  if ( xModel.is() )
703  m_eDocumentType = DocumentClassification::classifyDocument( xModel );
704  else
705  {
706  OSL_FAIL( "FmXFormShell::getDocumentType: can't determine the document type!" );
708  // fallback, just to have a defined state
709  }
710 
711  return m_eDocumentType;
712 }
713 
714 
716 {
718  return true;
719 
720  FmFormModel* pModel = m_pShell->GetFormModel();
721  if ( pModel && pModel->GetObjectShell() )
722  return pModel->GetObjectShell()->IsReadOnly() || pModel->GetObjectShell()->IsReadOnlyUI();
723  return true;
724 }
725 
726 // EventListener
727 
728 void SAL_CALL FmXFormShell::disposing(const lang::EventObject& e)
729 {
730  SolarMutexGuard g;
731 
732  if (m_xActiveController == e.Source)
733  {
734  // the controller will release, then release everything
736  m_xActiveForm = nullptr;
737  m_xActiveController = nullptr;
738  m_xNavigationController = nullptr;
739 
742 
743  if ( m_pShell )
745  }
746 
747  if (e.Source == m_xExternalViewController)
748  {
749  Reference< runtime::XFormController > xFormController( m_xExternalViewController, UNO_QUERY );
750  OSL_ENSURE( xFormController.is(), "FmXFormShell::disposing: invalid external view controller!" );
751  if (xFormController.is())
752  xFormController->removeActivateListener(static_cast<XFormControllerListener*>(this));
753 
754  if (m_xExternalViewController.is())
755  m_xExternalViewController->removeEventListener(static_cast<XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
756 
757  m_xExternalViewController = nullptr;
758  m_xExternalDisplayedForm = nullptr;
759  m_xExtViewTriggerController = nullptr;
760 
761  InvalidateSlot_Lock( SID_FM_VIEW_AS_GRID, false );
762  }
763 }
764 
765 
766 void SAL_CALL FmXFormShell::propertyChange(const PropertyChangeEvent& evt)
767 {
768  SolarMutexGuard g;
769 
771  return;
772 
773  if (evt.PropertyName == FM_PROP_ROWCOUNT)
774  {
775  // The update following this forces a re-painting of the corresponding
776  // slots. But if I am not in the MainThread of the application (because,
777  // for example, a cursor is counting data sets at the moment and always
778  // gives me this PropertyChanges), this can clash with normal paints in
779  // the MainThread of the application. (Such paints happen, for example,
780  // if one simply places another application over the office and switches
781  // back again).
782  // Therefore the use of the SolarMutex, which safeguards that.
784  if (rSolarSafety.tryToAcquire())
785  {
786  m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_RECORD_TOTAL, true);
787  m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Update(SID_FM_RECORD_TOTAL);
788  rSolarSafety.release();
789  }
790  else
791  {
792  // with the following the slot is invalidated asynchron
794  InvalidateSlot_Lock(SID_FM_RECORD_TOTAL, false);
796  }
797  }
798 
799  // this may be called from a non-main-thread so invalidate the shell asynchronously
801  InvalidateSlot_Lock(0, false); // special meaning : invalidate m_pShell
803 }
804 
805 
806 void FmXFormShell::invalidateFeatures( const ::std::vector< sal_Int32 >& _rFeatures )
807 {
808  SolarMutexGuard g;
809 
811  return;
812 
813  OSL_ENSURE( !_rFeatures.empty(), "FmXFormShell::invalidateFeatures: invalid arguments!" );
814 
816  {
817  // unfortunately, SFX requires sal_uInt16
818  ::std::vector< sal_uInt16 > aSlotIds;
819  aSlotIds.reserve( _rFeatures.size() );
820  ::std::copy( _rFeatures.begin(),
821  _rFeatures.end(),
822  ::std::insert_iterator< ::std::vector< sal_uInt16 > >( aSlotIds, aSlotIds.begin() )
823  );
824 
825  // furthermore, SFX wants a terminating 0
826  aSlotIds.push_back( 0 );
827 
828  // and, last but not least, SFX wants the ids to be sorted
829  ::std::sort( aSlotIds.begin(), aSlotIds.end() - 1 );
830 
831  sal_uInt16 *pSlotIds = aSlotIds.data();
833  }
834 }
835 
836 
837 void SAL_CALL FmXFormShell::formActivated(const lang::EventObject& rEvent)
838 {
839  SolarMutexGuard g;
840 
842  return;
843 
844  Reference< runtime::XFormController > xController( rEvent.Source, UNO_QUERY_THROW );
845  m_pTextShell->formActivated( xController );
846  setActiveController_Lock(xController);
847 }
848 
849 
850 void SAL_CALL FmXFormShell::formDeactivated(const lang::EventObject& rEvent)
851 {
852  SolarMutexGuard g;
853 
855  return;
856 
857  Reference< runtime::XFormController > xController( rEvent.Source, UNO_QUERY_THROW );
858  m_pTextShell->formDeactivated( xController );
859 }
860 
861 
863 {
864  SolarMutexGuard g;
865 
866  FmXFormShell_BASE::disposing();
867 
868  if ( m_pShell && !m_pShell->IsDesignMode() )
869  setActiveController_Lock(nullptr, true);
870  // do NOT save the content of the old form (the second parameter tells this)
871  // if we're here, then we expect that PrepareClose has been called, and thus the user
872  // got a chance to commit or reject any changes. So in case we're here and there
873  // are still uncommitted changes, the user explicitly wanted this.
874 
875  m_pTextShell->dispose();
876 
877  m_xAttachedFrame = nullptr;
878 
880 
881  while ( !m_aLoadingPages.empty() )
882  {
883  Application::RemoveUserEvent( m_aLoadingPages.front().nEventId );
884  m_aLoadingPages.pop();
885  }
886 
887  {
889  {
891  m_nInvalidationEvent = nullptr;
892  }
893  if ( m_nActivationEvent )
894  {
896  m_nActivationEvent = nullptr;
897  }
898  }
899 
900  {
901  DBG_ASSERT(!m_nInvalidationEvent, "FmXFormShell::~FmXFormShell : still have an invalidation event !");
902  // should have been deleted while being disposed
903 
904  m_aMarkTimer.Stop();
905  }
906 
908 
910  m_xForms.clear();
911 
913  m_xActiveController = nullptr;
914  m_xActiveForm = nullptr;
915 
916  m_pShell = nullptr;
917  m_xNavigationController = nullptr;
918  m_xCurrentForm = nullptr;
919  m_xLastGridFound = nullptr;
920  m_xAttachedFrame = nullptr;
921  m_xExternalViewController = nullptr;
922  m_xExtViewTriggerController = nullptr;
923  m_xExternalDisplayedForm = nullptr;
924 
925  InterfaceBag aEmpty;
926  m_aCurrentSelection.swap( aEmpty );
927 
930 }
931 
932 
933 void FmXFormShell::UpdateSlot_Lock(sal_Int16 _nId)
934 {
936  return;
937 
939  {
940  OSL_FAIL( "FmXFormShell::UpdateSlot: cannot update if invalidation is currently locked!" );
941  InvalidateSlot_Lock(_nId, false);
942  }
943  else
944  {
945  OSL_ENSURE( _nId, "FmXFormShell::UpdateSlot: can't update the complete shell!" );
946  m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate( _nId, true, true );
948  }
949 }
950 
951 
952 void FmXFormShell::InvalidateSlot_Lock(sal_Int16 nId, bool bWithId)
953 {
955  return;
956 
958  {
959  sal_uInt8 nFlags = ( bWithId ? 0x01 : 0 );
960  m_arrInvalidSlots.emplace_back(nId, nFlags );
961  }
962  else
963  if (nId)
964  m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(nId, true, bWithId);
965  else
967 }
968 
969 
971 {
973  return;
974 
975  DBG_ASSERT(bLock || m_nLockSlotInvalidation>0, "FmXFormShell::LockSlotInvalidation : invalid call !");
976 
977  if (bLock)
979  else if (!--m_nLockSlotInvalidation)
980  {
981  // (asynchronously) invalidate everything accumulated during the locked phase
983  m_nInvalidationEvent = Application::PostUserEvent(LINK(this, FmXFormShell, OnInvalidateSlots_Lock));
984  }
985 }
986 
987 
988 IMPL_LINK_NOARG(FmXFormShell, OnInvalidateSlots_Lock, void*,void)
989 {
991  return;
992 
993  m_nInvalidationEvent = nullptr;
994 
995  for (const auto& rInvalidSlot : m_arrInvalidSlots)
996  {
997  if (rInvalidSlot.id)
998  m_pShell->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(rInvalidSlot.id, true, (rInvalidSlot.flags & 0x01));
999  else
1001  }
1002  m_arrInvalidSlots.clear();
1003 }
1004 
1005 
1007 {
1009  return;
1010 
1012  {
1013  m_aMarkTimer.Stop();
1014 
1015  // optionally turn off the invalidation of slots which is implicitly done by SetSelection
1017 
1019 
1021  }
1022 }
1023 
1024 std::unique_ptr<VclBuilder> FmXFormShell::GetConversionMenu_Lock()
1025 {
1026  std::unique_ptr<VclBuilder> pBuilder(new VclBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "svx/ui/convertmenu.ui", ""));
1027  VclPtr<PopupMenu> pNewMenu(pBuilder->get_menu("menu"));
1028  for (size_t i = 0; i < SAL_N_ELEMENTS(aConvertSlots); ++i)
1029  {
1030  // the corresponding image at it
1031  pNewMenu->SetItemImage(pNewMenu->GetItemId(aConvertSlots[i]), Image(StockImage::Yes, aImgIds[i]));
1032  }
1033  return pBuilder;
1034 }
1035 
1036 OString FmXFormShell::SlotToIdent(sal_uInt16 nSlot)
1037 {
1039 
1040  for (size_t i = 0; i < SAL_N_ELEMENTS(aConvertSlots); ++i)
1041  {
1042  if (nSlot == SelObjectSlotMap[i])
1043  return aConvertSlots[i];
1044  }
1045 
1046  return OString();
1047 }
1048 
1049 bool FmXFormShell::isControlConversionSlot(const OString& rIdent)
1050 {
1051  for (const auto& rConvertSlot : aConvertSlots)
1052  if (rIdent == rConvertSlot)
1053  return true;
1054  return false;
1055 }
1056 
1058 {
1059  OSL_PRECOND( canConvertCurrentSelectionToControl_Lock(rIdent), "FmXFormShell::executeControlConversionSlot: illegal call!" );
1060  InterfaceBag::const_iterator aSelectedElement = m_aCurrentSelection.begin();
1061  if ( aSelectedElement == m_aCurrentSelection.end() )
1062  return;
1063 
1064  executeControlConversionSlot_Lock(Reference<XFormComponent>(*aSelectedElement, UNO_QUERY), rIdent);
1065 }
1066 
1067 bool FmXFormShell::executeControlConversionSlot_Lock(const Reference<XFormComponent>& _rxObject, const OString& rIdent)
1068 {
1070  return false;
1071 
1072  OSL_ENSURE( _rxObject.is(), "FmXFormShell::executeControlConversionSlot: invalid object!" );
1073  if ( !_rxObject.is() )
1074  return false;
1075 
1076  SdrPage* pPage = m_pShell->GetCurPage();
1077  FmFormPage* pFormPage = dynamic_cast< FmFormPage* >( pPage );
1078  OSL_ENSURE( pFormPage, "FmXFormShell::executeControlConversionSlot: no current (form) page!" );
1079  if ( !pFormPage )
1080  return false;
1081 
1082  OSL_ENSURE( isSolelySelected_Lock(_rxObject),
1083  "FmXFormShell::executeControlConversionSlot: hmm ... shouldn't this parameter be redundant?" );
1084 
1085  for (size_t lookupSlot = 0; lookupSlot < SAL_N_ELEMENTS(aConvertSlots); ++lookupSlot)
1086  {
1087  if (rIdent == aConvertSlots[lookupSlot])
1088  {
1089  Reference< XInterface > xNormalizedObject( _rxObject, UNO_QUERY );
1090 
1091  FmFormObj* pFormObject = nullptr;
1092  SdrObjListIter aPageIter( pFormPage );
1093  while ( aPageIter.IsMore() )
1094  {
1095  SdrObject* pCurrent = aPageIter.Next();
1096  pFormObject = FmFormObj::GetFormObject( pCurrent );
1097  if ( !pFormObject )
1098  continue;
1099 
1100  Reference< XInterface > xCurrentNormalized( pFormObject->GetUnoControlModel(), UNO_QUERY );
1101  if ( xCurrentNormalized.get() == xNormalizedObject.get() )
1102  break;
1103 
1104  pFormObject = nullptr;
1105  }
1106 
1107  if ( !pFormObject )
1108  return false;
1109 
1110  OUString sNewName( getServiceNameByControlType( nObjectTypes[ lookupSlot ] ) );
1112  Reference< XControlModel> xNewModel( xContext->getServiceManager()->createInstanceWithContext(sNewName, xContext), UNO_QUERY );
1113  if (!xNewModel.is())
1114  return false;
1115 
1116  Reference< XControlModel> xOldModel( pFormObject->GetUnoControlModel() );
1117 
1118  // transfer properties
1119  Reference< XPropertySet> xOldSet(xOldModel, UNO_QUERY);
1120  Reference< XPropertySet> xNewSet(xNewModel, UNO_QUERY);
1121 
1122 
1123  lang::Locale aNewLanguage = Application::GetSettings().GetUILanguageTag().getLocale();
1124  TransferFormComponentProperties(xOldSet, xNewSet, aNewLanguage);
1125 
1126  Sequence< css::script::ScriptEventDescriptor> aOldScripts;
1127  Reference< XChild> xChild(xOldModel, UNO_QUERY);
1128  if (xChild.is())
1129  {
1130  Reference< XIndexAccess> xParent(xChild->getParent(), UNO_QUERY);
1131 
1132  // remember old script events
1133  Reference< css::script::XEventAttacherManager> xEvManager(xChild->getParent(), UNO_QUERY);
1134  if (xParent.is() && xEvManager.is())
1135  {
1136  sal_Int32 nIndex = getElementPos(xParent, xOldModel);
1137  if (nIndex>=0 && nIndex<xParent->getCount())
1138  aOldScripts = xEvManager->getScriptEvents(nIndex);
1139  }
1140 
1141  // replace the model within the parent container
1142  Reference< XIndexContainer> xIndexParent(xChild->getParent(), UNO_QUERY);
1143  if (xIndexParent.is())
1144  {
1145  // the form container works with FormComponents
1146  Reference< XFormComponent> xComponent(xNewModel, UNO_QUERY);
1147  DBG_ASSERT(xComponent.is(), "FmXFormShell::executeControlConversionSlot: the new model is no form component !");
1148  Any aNewModel(makeAny(xComponent));
1149  try
1150  {
1151 
1152  sal_Int32 nIndex = getElementPos(xParent, xOldModel);
1153  if (nIndex>=0 && nIndex<xParent->getCount())
1154  xIndexParent->replaceByIndex(nIndex, aNewModel);
1155  else
1156  {
1157  OSL_FAIL("FmXFormShell::executeControlConversionSlot: could not replace the model !");
1158  Reference< css::lang::XComponent> xNewComponent(xNewModel, UNO_QUERY);
1159  if (xNewComponent.is())
1160  xNewComponent->dispose();
1161  return false;
1162  }
1163  }
1164  catch(Exception&)
1165  {
1166  OSL_FAIL("FmXFormShell::executeControlConversionSlot: could not replace the model !");
1167  Reference< css::lang::XComponent> xNewComponent(xNewModel, UNO_QUERY);
1168  if (xNewComponent.is())
1169  xNewComponent->dispose();
1170  return false;
1171  }
1172 
1173  }
1174  }
1175 
1176  // special handling for the LabelControl-property : can only be set when the model is placed
1177  // within the forms hierarchy
1179  {
1180  try
1181  {
1182  xNewSet->setPropertyValue(FM_PROP_CONTROLLABEL, xOldSet->getPropertyValue(FM_PROP_CONTROLLABEL));
1183  }
1184  catch(Exception&)
1185  {
1186  }
1187 
1188  }
1189 
1190  // set new model
1191  pFormObject->SetChanged();
1192  pFormObject->SetUnoControlModel(xNewModel);
1193 
1194  // transfer script events
1195  // (do this _after_ SetUnoControlModel as we need the new (implicitly created) control)
1196  if (aOldScripts.hasElements())
1197  {
1198  // find the control for the model
1199  Reference<XControlContainer> xControlContainer(getControlContainerForView_Lock());
1200 
1201  Sequence< Reference< XControl> > aControls( xControlContainer->getControls() );
1202 
1203  Reference< XControl> xControl;
1204  auto pControl = std::find_if(aControls.begin(), aControls.end(),
1205  [&xNewModel](const Reference< XControl>& rControl) { return rControl->getModel() == xNewModel; });
1206  if (pControl != aControls.end())
1207  xControl = *pControl;
1208  TransferEventScripts(xNewModel, xControl, aOldScripts);
1209  }
1210 
1211  // transfer value bindings, if possible
1212  {
1213  Reference< XBindableValue > xOldBindable( xOldModel, UNO_QUERY );
1214  Reference< XBindableValue > xNewBindable( xNewModel, UNO_QUERY );
1215  if ( xOldBindable.is() )
1216  {
1217  try
1218  {
1219  if ( xNewBindable.is() )
1220  xNewBindable->setValueBinding( xOldBindable->getValueBinding() );
1221  xOldBindable->setValueBinding( nullptr );
1222  }
1223  catch(const Exception&)
1224  {
1225  DBG_UNHANDLED_EXCEPTION("svx");
1226  }
1227  }
1228  }
1229  // same for list entry sources
1230  {
1231  Reference< XListEntrySink > xOldSink( xOldModel, UNO_QUERY );
1232  Reference< XListEntrySink > xNewSink( xNewModel, UNO_QUERY );
1233  if ( xOldSink.is() )
1234  {
1235  try
1236  {
1237  if ( xNewSink.is() )
1238  xNewSink->setListEntrySource( xOldSink->getListEntrySource() );
1239  xOldSink->setListEntrySource( nullptr );
1240  }
1241  catch(const Exception&)
1242  {
1243  DBG_UNHANDLED_EXCEPTION("svx");
1244  }
1245  }
1246  }
1247 
1248  // create an undo action
1249  FmFormModel* pModel = m_pShell->GetFormModel();
1250  DBG_ASSERT(pModel != nullptr, "FmXFormShell::executeControlConversionSlot: my shell has no model !");
1251  if (pModel && pModel->IsUndoEnabled() )
1252  {
1253  pModel->AddUndo(std::make_unique<FmUndoModelReplaceAction>(*pModel, pFormObject, xOldModel));
1254  }
1255  else
1256  {
1258  }
1259 
1260  return true;
1261  }
1262  }
1263  return false;
1264 }
1265 
1267 {
1268  if ( m_aCurrentSelection.empty() )
1269  return false;
1270 
1271  InterfaceBag::const_iterator aCheck = m_aCurrentSelection.begin();
1272  Reference< lang::XServiceInfo > xElementInfo( *aCheck, UNO_QUERY );
1273  if ( !xElementInfo.is() )
1274  // no service info -> cannot determine this
1275  return false;
1276 
1277  if ( ++aCheck != m_aCurrentSelection.end() )
1278  // more than one element
1279  return false;
1280 
1281  if ( Reference< XForm >::query( xElementInfo ).is() )
1282  // it's a form
1283  return false;
1284 
1285  sal_Int16 nObjectType = getControlTypeByObject( xElementInfo );
1286 
1287  if ( ( OBJ_FM_HIDDEN == nObjectType )
1288  || ( OBJ_FM_CONTROL == nObjectType )
1289  || ( OBJ_FM_GRID == nObjectType )
1290  )
1291  return false; // those types cannot be converted
1292 
1294  "FmXFormShell::canConvertCurrentSelectionToControl: aConvertSlots & nObjectTypes must have the same size !");
1295 
1296  for (size_t i = 0; i < SAL_N_ELEMENTS(aConvertSlots); ++i)
1297  if (rIdent == aConvertSlots[i])
1298  return nObjectTypes[i] != nObjectType;
1299 
1300  return true; // all other slots: assume "yes"
1301 }
1302 
1304 {
1305  for (sal_uInt16 i = 0; i < rMenu.GetItemCount(); ++i)
1306  {
1307  // the context is already of a type that corresponds to the entry -> disable
1308  const sal_uInt16 nId = rMenu.GetItemId(i);
1310  }
1311 }
1312 
1314 {
1316  return;
1317 
1318  Reference< XIndexContainer> xControlModels(m_xActiveForm, UNO_QUERY);
1319  if (xControlModels.is())
1320  {
1321  for (sal_Int32 i=0; i<xControlModels->getCount(); ++i)
1322  {
1323  Reference< XPropertySet> xModelSet;
1324  xControlModels->getByIndex(i) >>= xModelSet;
1325  if (!xModelSet.is())
1326  continue;
1327 
1328  if (!::comphelper::hasProperty(FM_PROP_CLASSID, xModelSet))
1329  continue;
1330  sal_Int16 nClassId = ::comphelper::getINT16(xModelSet->getPropertyValue(FM_PROP_CLASSID));
1331  if (FormComponentType::GRIDCONTROL != nClassId)
1332  continue;
1333 
1334  if (!::comphelper::hasProperty(FM_PROP_CURSORCOLOR, xModelSet) || !::comphelper::hasProperty(FM_PROP_ALWAYSSHOWCURSOR, xModelSet) || !::comphelper::hasProperty(FM_PROP_DISPLAYSYNCHRON, xModelSet))
1335  continue;
1336 
1337  switch (nSync)
1338  {
1340  {
1341  xModelSet->setPropertyValue(FM_PROP_DISPLAYSYNCHRON, Any(false));
1342  }
1343  break;
1345  {
1346  Any aOldVal( xModelSet->getPropertyValue(FM_PROP_DISPLAYSYNCHRON) );
1347  xModelSet->setPropertyValue(FM_PROP_DISPLAYSYNCHRON, Any(true));
1348  xModelSet->setPropertyValue(FM_PROP_DISPLAYSYNCHRON, aOldVal);
1349  }
1350  break;
1352  {
1353  xModelSet->setPropertyValue(FM_PROP_DISPLAYSYNCHRON, Any(true));
1354  }
1355  break;
1356  }
1357 
1358  if (nFlags & LoopGridsFlags::DISABLE_ROCTRLR)
1359  {
1360  xModelSet->setPropertyValue(FM_PROP_ALWAYSSHOWCURSOR, Any(false));
1361  Reference< XPropertyState> xModelPropState(xModelSet, UNO_QUERY);
1362  if (xModelPropState.is())
1363  xModelPropState->setPropertyToDefault(FM_PROP_CURSORCOLOR);
1364  else
1365  xModelSet->setPropertyValue(FM_PROP_CURSORCOLOR, Any()); // this should be the default
1366  }
1367  }
1368  }
1369 }
1370 
1371 
1372 Reference< XControlContainer > FmXFormShell::getControlContainerForView_Lock() const
1373 {
1375  return nullptr;
1376 
1377  SdrPageView* pPageView = nullptr;
1378  if ( m_pShell && m_pShell->GetFormView() )
1379  pPageView = m_pShell->GetFormView()->GetSdrPageView();
1380 
1381  Reference< XControlContainer> xControlContainer;
1382  if ( pPageView )
1383  xControlContainer = pPageView->GetPageWindow(0)->GetControlContainer();
1384 
1385  return xControlContainer;
1386 }
1387 
1388 
1389 void FmXFormShell::ExecuteTabOrderDialog_Lock(const Reference<XTabControllerModel>& _rxForForm)
1390 {
1392  return;
1393 
1394  OSL_PRECOND( _rxForForm.is(), "FmXFormShell::ExecuteTabOrderDialog: invalid tabbing model!" );
1395  if ( !_rxForForm.is() )
1396  return;
1397 
1398  try
1399  {
1400  Reference< XWindow > xParentWindow;
1403 
1404  Reference< dialogs::XExecutableDialog > xDialog = form::TabOrderDialog::createWithModel(
1406  _rxForForm, getControlContainerForView_Lock(), xParentWindow
1407  );
1408 
1409  xDialog->execute();
1410  }
1411  catch( const Exception& )
1412  {
1413  OSL_FAIL( "FmXFormShell::ExecuteTabOrderDialog: caught an exception!" );
1414  }
1415 }
1416 
1417 
1419 {
1421  return;
1422 
1423  // a collection of all (logical) forms
1424  FmFormArray aEmpty;
1425  m_aSearchForms.swap( aEmpty );
1426  ::std::vector< OUString > aContextNames;
1428  m_pShell->GetCurPage()->GetForms(), OUString(),
1429  m_aSearchForms, aContextNames);
1430 
1431  if ( m_aSearchForms.size() != aContextNames.size() )
1432  {
1433  SAL_WARN ( "svx.form", "FmXFormShell::ExecuteSearch: nonsense!" );
1434  return;
1435  }
1436 
1437  // filter out the forms which do not contain valid controls at all
1438  {
1439  FmFormArray aValidForms;
1440  ::std::vector< OUString > aValidContexts;
1441  FmFormArray::const_iterator form = m_aSearchForms.begin();
1442  ::std::vector< OUString >::const_iterator contextName = aContextNames.begin();
1443  for ( ; form != m_aSearchForms.end(); ++form, ++contextName )
1444  {
1445  FmSearchContext aTestContext;
1446  aTestContext.nContext = static_cast< sal_Int16 >( form - m_aSearchForms.begin() );
1447  sal_uInt32 nValidControls = OnSearchContextRequest_Lock(aTestContext);
1448  if ( nValidControls > 0 )
1449  {
1450  aValidForms.push_back( *form );
1451  aValidContexts.push_back( *contextName );
1452  }
1453  }
1454 
1455  m_aSearchForms.swap( aValidForms );
1456  aContextNames.swap( aValidContexts );
1457  }
1458 
1459  if (m_aSearchForms.empty() )
1460  {
1461  // there are no controls that meet all the conditions for a search
1462  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
1463  VclMessageType::Warning, VclButtonsType::Ok,
1464  SvxResId(RID_STR_NODATACONTROLS)));
1465  xBox->run();
1466  return;
1467  }
1468 
1469  // now I need another 'initial context'
1470  sal_Int16 nInitialContext = 0;
1471  Reference<XForm> xActiveForm(getActiveForm_Lock());
1472  for ( size_t i=0; i<m_aSearchForms.size(); ++i )
1473  {
1474  if (m_aSearchForms.at(i) == xActiveForm)
1475  {
1476  nInitialContext = static_cast<sal_Int16>(i);
1477  break;
1478  }
1479  }
1480 
1481  // If the dialog should initially offer the text of the active control,
1482  // this must have an XTextComponent interface. An addition, this makes
1483  // sense only if the current field is also bound to a table (or whatever) field.
1484  OUString strActiveField;
1485  OUString strInitialText;
1486  // ... this I get from my FormController
1487  DBG_ASSERT(m_xActiveController.is(), "FmXFormShell::ExecuteSearch : no active controller !");
1488  Reference< XControl> xActiveControl( m_xActiveController->getCurrentControl());
1489  if (xActiveControl.is())
1490  {
1491  // the control can tell me its model ...
1492  Reference< XControlModel> xActiveModel( xActiveControl->getModel());
1493  DBG_ASSERT(xActiveModel.is(), "FmXFormShell::ExecuteSearch : active control has no model !");
1494 
1495  // I ask the model for the ControlSource property ...
1496  Reference< XPropertySet> xProperties(xActiveControl->getModel(), UNO_QUERY);
1497  if (::comphelper::hasProperty(FM_PROP_CONTROLSOURCE, xProperties) && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xProperties))
1498  {
1499  Reference< XPropertySet> xField;
1500  xProperties->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
1501  if (xField.is()) // (only when the thing is really bound)
1502  {
1503  // and the control itself for a TextComponent interface (so that I can pick up the text there)
1504  Reference< XTextComponent> xText(xActiveControl, UNO_QUERY);
1505  if (xText.is())
1506  {
1507  strActiveField = getLabelName(xProperties);
1508  strInitialText = xText->getText();
1509  }
1510  }
1511  }
1512  else
1513  {
1514  // the control itself has no ControlSource, but maybe it is a GridControl
1515  Reference< XGrid> xGrid(xActiveControl, UNO_QUERY);
1516  if (xGrid.is())
1517  {
1518  // for strActiveField I need the ControlSource of the column,
1519  // for that the columns container, for that the GridPeer
1520  Reference< XGridPeer> xGridPeer(xActiveControl->getPeer(), UNO_QUERY);
1521  Reference< XIndexAccess> xColumns;
1522  if (xGridPeer.is())
1523  xColumns = xGridPeer->getColumns();
1524 
1525  sal_Int16 nViewCol = xGrid->getCurrentColumnPosition();
1526  sal_Int32 nModelCol = GridView2ModelPos(xColumns, nViewCol);
1527  Reference< XPropertySet> xCurrentCol;
1528  if(xColumns.is())
1529  xColumns->getByIndex(nModelCol) >>= xCurrentCol;
1530  if (xCurrentCol.is())
1531  strActiveField = ::comphelper::getString(xCurrentCol->getPropertyValue(FM_PROP_LABEL));
1532 
1533  // the text of the current column
1534  Reference< XIndexAccess> xColControls(xGridPeer, UNO_QUERY);
1535  Reference< XInterface> xCurControl;
1536  xColControls->getByIndex(nViewCol) >>= xCurControl;
1537  OUString sInitialText;
1538  if (IsSearchableControl(xCurControl, &sInitialText))
1539  strInitialText = sInitialText;
1540  }
1541  }
1542  }
1543 
1544  // taking care of possible GridControls that I know
1546 
1547  // Now I am ready for the dialogue.
1548  // When the potential deadlocks caused by the use of the solar mutex in
1549  // MTs VCLX... classes are eventually cleared, an SM_USETHREAD should be
1550  // placed here, because the search in a separate thread is nevertheless
1551  // somewhat more fluid. Should be, however, somehow made dependent of the
1552  // underlying cursor. DAO for example is not thread-safe.
1555  pFact->CreateFmSearchDialog(
1557  strInitialText, aContextNames, nInitialContext,
1558  LINK(this, FmXFormShell, OnSearchContextRequest_Lock) ));
1559  pDialog->SetActiveField( strActiveField );
1560  pDialog->SetFoundHandler(LINK(this, FmXFormShell, OnFoundData_Lock));
1561  pDialog->SetCanceledNotFoundHdl(LINK(this, FmXFormShell, OnCanceledNotFound_Lock));
1562  pDialog->Execute();
1563  pDialog.disposeAndClear();
1564 
1565  // restore GridControls again
1567 
1569  // because I marked controls in OnFoundData (if I was there)
1570 }
1571 
1572 
1574 {
1576  return false;
1577 
1578  if (m_pShell->IsDesignMode())
1579  // in the design mode (without active controls) the main document is to take care of it
1580  return false;
1581 
1582  Reference<XForm> xForm(getActiveForm_Lock());
1583  if (!xForm.is())
1584  // no current form (in particular no current control) -> the main document is to take care
1585  return false;
1586 
1587  Reference< XRowSet> xDB(xForm, UNO_QUERY);
1588  DBG_ASSERT(xDB.is(), "FmXFormShell::GetY2KState : current form has no dbform-interface !");
1589 
1590  Reference< XNumberFormatsSupplier> xSupplier( getNumberFormats(getConnection(xDB)));
1591  if (xSupplier.is())
1592  {
1593  Reference< XPropertySet> xSet(xSupplier->getNumberFormatSettings());
1594  if (xSet.is())
1595  {
1596  try
1597  {
1598  Any aVal( xSet->getPropertyValue("TwoDigitDateStart") );
1599  aVal >>= n;
1600  return true;
1601  }
1602  catch(Exception&)
1603  {
1604  }
1605 
1606  }
1607  }
1608  return false;
1609 }
1610 
1611 
1613 {
1615  return;
1616 
1617  Reference<XForm> xActiveForm(getActiveForm_Lock());
1618  Reference< XRowSet > xActiveRowSet( xActiveForm, UNO_QUERY );
1619  if ( xActiveRowSet.is() )
1620  {
1621  Reference< XNumberFormatsSupplier > xSupplier( getNumberFormats( getConnection( xActiveRowSet ) ) );
1622  if (xSupplier.is())
1623  {
1624  Reference< XPropertySet> xSet(xSupplier->getNumberFormatSettings());
1625  if (xSet.is())
1626  {
1627  try
1628  {
1629  xSet->setPropertyValue("TwoDigitDateStart", makeAny<sal_uInt16>(n));
1630  }
1631  catch(Exception&)
1632  {
1633  OSL_FAIL("FmXFormShell::SetY2KState: Exception occurred!");
1634  }
1635 
1636  }
1637  return;
1638  }
1639  }
1640 
1641  // no active form found -> iterate through all current forms
1642  Reference< XIndexAccess> xCurrentForms( m_xForms);
1643  if (!xCurrentForms.is())
1644  { // in the alive mode, my forms are not set, but the ones on the page are
1645  if (m_pShell->GetCurPage())
1646  xCurrentForms = m_pShell->GetCurPage()->GetForms( false );
1647  }
1648  if (!xCurrentForms.is())
1649  return;
1650 
1651  ::comphelper::IndexAccessIterator aIter(xCurrentForms);
1652  Reference< XInterface> xCurrentElement( aIter.Next());
1653  while (xCurrentElement.is())
1654  {
1655  // is the current element a DatabaseForm?
1656  Reference< XRowSet> xElementAsRowSet( xCurrentElement, UNO_QUERY );
1657  if ( xElementAsRowSet.is() )
1658  {
1659  Reference< XNumberFormatsSupplier > xSupplier( getNumberFormats( getConnection( xElementAsRowSet ) ) );
1660  if (!xSupplier.is())
1661  continue;
1662 
1663  Reference< XPropertySet> xSet(xSupplier->getNumberFormatSettings());
1664  if (xSet.is())
1665  {
1666  try
1667  {
1668  xSet->setPropertyValue("TwoDigitDateStart", makeAny<sal_uInt16>(n));
1669  }
1670  catch(Exception&)
1671  {
1672  OSL_FAIL("FmXFormShell::SetY2KState: Exception occurred!");
1673  }
1674 
1675  }
1676  }
1677  xCurrentElement = aIter.Next();
1678  }
1679 }
1680 
1681 
1683 {
1685  return;
1686 
1687  if (!m_xExternalViewController.is())
1688  return;
1689 
1690  Reference< css::frame::XFrame> xExternalViewFrame( m_xExternalViewController->getFrame());
1691  Reference< css::frame::XDispatchProvider> xCommLink(xExternalViewFrame, UNO_QUERY);
1692  if (!xCommLink.is())
1693  return;
1694 
1695  xExternalViewFrame->setComponent(nullptr,nullptr);
1696  ::comphelper::disposeComponent(xExternalViewFrame);
1697  m_xExternalViewController = nullptr;
1698  m_xExtViewTriggerController = nullptr;
1699  m_xExternalDisplayedForm = nullptr;
1700 }
1701 
1702 
1703 Reference<XResultSet> FmXFormShell::getInternalForm_Lock(const Reference<XResultSet>& _xForm) const
1704 {
1706  return nullptr;
1707 
1708  Reference< runtime::XFormController> xExternalCtrlr(m_xExternalViewController, UNO_QUERY);
1709  if (xExternalCtrlr.is() && (_xForm == xExternalCtrlr->getModel()))
1710  {
1711  DBG_ASSERT(m_xExternalDisplayedForm.is(), "FmXFormShell::getInternalForm : invalid external form !");
1712  return m_xExternalDisplayedForm;
1713  }
1714  return _xForm;
1715 }
1716 
1717 
1718 Reference<XForm> FmXFormShell::getInternalForm_Lock(const Reference<XForm>& _xForm) const
1719 {
1721  return nullptr;
1722 
1723  Reference< runtime::XFormController > xExternalCtrlr(m_xExternalViewController, UNO_QUERY);
1724  if (xExternalCtrlr.is() && (_xForm == xExternalCtrlr->getModel()))
1725  {
1726  DBG_ASSERT(m_xExternalDisplayedForm.is(), "FmXFormShell::getInternalForm : invalid external form !");
1727  return Reference< XForm>(m_xExternalDisplayedForm, UNO_QUERY);
1728  }
1729  return _xForm;
1730 }
1731 
1732 
1733 namespace
1734 {
1735  bool lcl_isNavigationRelevant( sal_Int32 _nWhich )
1736  {
1737  return ( _nWhich == SID_FM_RECORD_FIRST )
1738  || ( _nWhich == SID_FM_RECORD_PREV )
1739  || ( _nWhich == SID_FM_RECORD_NEXT )
1740  || ( _nWhich == SID_FM_RECORD_LAST )
1741  || ( _nWhich == SID_FM_RECORD_NEW );
1742  }
1743 }
1744 
1745 
1746 bool FmXFormShell::IsFormSlotEnabled( sal_Int32 _nSlot, FeatureState* _pCompleteState )
1747 {
1748  const svx::ControllerFeatures& rController =
1749  lcl_isNavigationRelevant( _nSlot )
1752 
1753  if ( !_pCompleteState )
1754  return rController->isEnabled( _nSlot );
1755 
1756  rController->getState( _nSlot, *_pCompleteState );
1757  return _pCompleteState->Enabled;
1758 }
1759 
1760 
1761 void FmXFormShell::ExecuteFormSlot_Lock( sal_Int32 _nSlot )
1762 {
1763  const svx::ControllerFeatures& rController =
1764  lcl_isNavigationRelevant( _nSlot )
1767 
1768  rController->execute( _nSlot );
1769 
1770  if ( _nSlot == SID_FM_RECORD_UNDO )
1771  {
1772  // if we're doing an UNDO, *and* if the affected form is the form which we also display
1773  // as external view, then we need to reset the controls of the external form, too
1775  {
1776  Reference< XIndexAccess > xContainer( m_xExternalDisplayedForm, UNO_QUERY );
1777  if ( xContainer.is() )
1778  {
1779  Reference< XReset > xReset;
1780  for ( sal_Int32 i = 0; i < xContainer->getCount(); ++i )
1781  {
1782  if ( ( xContainer->getByIndex( i ) >>= xReset ) && xReset.is() )
1783  {
1784  // no resets on sub forms
1785  Reference< XForm > xAsForm( xReset, UNO_QUERY );
1786  if ( !xAsForm.is() )
1787  xReset->reset();
1788  }
1789  }
1790  }
1791  }
1792  }
1793 }
1794 
1795 
1797 {
1798  if ( !m_xActiveController.is() )
1799  return;
1800 
1801  if ( _bListen )
1802  m_xActiveController->addEventListener( static_cast<XFormControllerListener*>(this) );
1803  else
1804  m_xActiveController->removeEventListener( static_cast<XFormControllerListener*>(this) );
1805 }
1806 
1807 
1808 void FmXFormShell::setActiveController_Lock(const Reference<runtime::XFormController>& xController, bool _bNoSaveOldContent)
1809 {
1811  return;
1812 
1814  return;
1815  DBG_ASSERT(!m_pShell->IsDesignMode(), "only to be used in alive mode");
1816 
1817  // if the routine has been called a second time,
1818  // the focus should no longer be transferred
1819  if (m_bInActivate)
1820  {
1821  m_bSetFocus = xController != m_xActiveController;
1822  return;
1823  }
1824 
1825  if (xController == m_xActiveController)
1826  return;
1827 
1828  // switch all nav dispatchers belonging to the form of the current nav controller to 'non active'
1829  Reference< XResultSet> xNavigationForm;
1830  if (m_xNavigationController.is())
1831  xNavigationForm.set(m_xNavigationController->getModel(), UNO_QUERY);
1832 
1833  m_bInActivate = true;
1834 
1835  // check if the 2 controllers serve different forms
1836  Reference< XResultSet> xOldForm;
1837  if (m_xActiveController.is())
1838  xOldForm.set(m_xActiveController->getModel(), UNO_QUERY);
1839  Reference< XResultSet> xNewForm;
1840  if (xController.is())
1841  xNewForm = Reference< XResultSet>(xController->getModel(), UNO_QUERY);
1842  xOldForm = getInternalForm_Lock(xOldForm);
1843  xNewForm = getInternalForm_Lock(xNewForm);
1844 
1845  bool bDifferentForm = ( xOldForm.get() != xNewForm.get() );
1846  bool bNeedSave = bDifferentForm && !_bNoSaveOldContent;
1847  // we save the content of the old form if we move to a new form, and saving old content is allowed
1848 
1849  if ( m_xActiveController.is() && bNeedSave )
1850  {
1851  // save content on change of the controller; a commit has already been executed
1853  {
1854  m_bSetFocus = true;
1856  {
1859  if ( !bResult && m_bSetFocus )
1860  {
1861  // if we couldn't save the current record, set the focus back to the
1862  // current control
1863  Reference< XWindow > xWindow( m_xActiveController->getCurrentControl(), UNO_QUERY );
1864  if ( xWindow.is() )
1865  xWindow->setFocus();
1866  m_bInActivate = false;
1867  return;
1868  }
1869  else if ( bResult && bIsNew )
1870  {
1871  Reference< XResultSet > xCursor( m_aActiveControllerFeatures->getCursor().get() );
1872  if ( xCursor.is() )
1873  {
1874  DO_SAFE( xCursor->last(); );
1875  }
1876  }
1877  }
1878  }
1879  }
1880 
1882 
1884 
1886  m_xActiveController = xController;
1887  if ( m_xActiveController.is() )
1889 
1891 
1892  if ( m_xActiveController.is() )
1893  m_xActiveForm = getInternalForm_Lock(Reference<XForm>(m_xActiveController->getModel(), UNO_QUERY));
1894  else
1895  m_xActiveForm = nullptr;
1896 
1898 
1899  // activate all dispatchers belonging to form of the new navigation controller
1900  xNavigationForm = nullptr;
1901  if (m_xNavigationController.is())
1902  xNavigationForm.set(m_xNavigationController->getModel(), UNO_QUERY);
1903 
1904  m_bInActivate = false;
1905 
1908 
1909  InvalidateSlot_Lock(SID_FM_FILTER_NAVIGATOR_CONTROL, true);
1910 }
1911 
1912 
1913 void FmXFormShell::getCurrentSelection_Lock(InterfaceBag& /* [out] */ _rSelection) const
1914 {
1915  _rSelection = m_aCurrentSelection;
1916 }
1917 
1918 
1920 {
1922 
1923  if ( ( _rMarkList.GetMarkCount() > 0 ) && isControlList( _rMarkList ) )
1924  collectInterfacesFromMarkList( _rMarkList, m_aLastKnownMarkedControls );
1925 
1927 }
1928 
1929 
1931 {
1933 }
1934 
1935 
1937 {
1939  return false;
1940 
1941  DBG_ASSERT( m_pShell->IsDesignMode(), "FmXFormShell::setCurrentSelection: only to be used in design mode!" );
1942 
1943  if ( _rSelection.empty() && m_aCurrentSelection.empty() )
1944  // nothing to do
1945  return false;
1946 
1947  if ( _rSelection.size() == m_aCurrentSelection.size() )
1948  {
1949  InterfaceBag::const_iterator aNew = _rSelection.begin();
1950  InterfaceBag::const_iterator aOld = m_aCurrentSelection.begin();
1951  for ( ; aNew != _rSelection.end(); ++aNew, ++aOld )
1952  {
1953  OSL_ENSURE( Reference< XInterface >( *aNew, UNO_QUERY ).get() == aNew->get(), "FmXFormShell::setCurrentSelection: new interface not normalized!" );
1954  OSL_ENSURE( Reference< XInterface >( *aOld, UNO_QUERY ).get() == aOld->get(), "FmXFormShell::setCurrentSelection: old interface not normalized!" );
1955 
1956  if ( aNew->get() != aOld->get() )
1957  break;
1958  }
1959 
1960  if ( aNew == _rSelection.end() )
1961  // both bags equal
1962  return false;
1963  }
1964 
1965  // the following is some strange code to ensure that when you have two grid controls in a document,
1966  // only one of them can have a selected column.
1967  // TODO: this should happen elsewhere, but not here - shouldn't it?
1968  if ( !m_aCurrentSelection.empty() )
1969  {
1970  Reference< XChild > xCur; if ( m_aCurrentSelection.size() == 1 ) xCur.set(*m_aCurrentSelection.begin(), css::uno::UNO_QUERY);
1971  Reference< XChild > xNew; if ( _rSelection.size() == 1 ) xNew.set(*_rSelection.begin(), css::uno::UNO_QUERY);
1972 
1973  // is there nothing to be selected, or the parents differ, and the parent of the current object
1974  // is a selection supplier, then deselect
1975  if ( xCur.is() && ( !xNew.is() || ( xCur->getParent() != xNew->getParent() ) ) )
1976  {
1977  Reference< XSelectionSupplier > xSel( xCur->getParent(), UNO_QUERY );
1978  if ( xSel.is() )
1979  xSel->select( Any() );
1980  }
1981  }
1982 
1983  m_aCurrentSelection = _rSelection;
1984 
1985  // determine the form which all the selected objects belong to, if any
1986  Reference< XForm > xNewCurrentForm;
1987  for (const auto& rpSelection : m_aCurrentSelection)
1988  {
1989  Reference< XForm > xThisRoundsForm( GetForm( rpSelection ) );
1990  OSL_ENSURE( xThisRoundsForm.is(), "FmXFormShell::setCurrentSelection: *everything* should belong to a form!" );
1991 
1992  if ( !xNewCurrentForm.is() )
1993  { // the first form we encountered
1994  xNewCurrentForm = xThisRoundsForm;
1995  }
1996  else if ( xNewCurrentForm != xThisRoundsForm )
1997  { // different forms -> no "current form" at all
1998  xNewCurrentForm.clear();
1999  break;
2000  }
2001  }
2002 
2003  if ( !m_aCurrentSelection.empty() )
2004  impl_updateCurrentForm_Lock(xNewCurrentForm);
2005 
2006  // ensure some slots are updated
2007  for (sal_Int16 i : SelObjectSlotMap)
2008  InvalidateSlot_Lock(i, false);
2009 
2010  return true;
2011 }
2012 
2013 
2015 {
2016  return ( m_aCurrentSelection.size() == 1 ) && ( *m_aCurrentSelection.begin() == _rxObject );
2017 }
2018 
2019 
2021 {
2022  if ( !m_xCurrentForm.is() )
2023  return;
2024 
2025  // reset ...
2026  impl_updateCurrentForm_Lock(nullptr);
2027 
2028  // ... and try finding a new current form
2029  // #i88186# / 2008-04-12 / frank.schoenheit@sun.com
2031 }
2032 
2033 
2034 void FmXFormShell::impl_updateCurrentForm_Lock(const Reference<XForm>& _rxNewCurForm)
2035 {
2037  return;
2038 
2039  m_xCurrentForm = _rxNewCurForm;
2040 
2041  // propagate to the FormPage(Impl)
2042  FmFormPage* pPage = m_pShell->GetCurPage();
2043  if ( pPage )
2044  pPage->GetImpl().setCurForm( m_xCurrentForm );
2045 
2046  // ensure the UI which depends on the current form is up-to-date
2047  for (sal_Int16 i : DlgSlotMap)
2048  InvalidateSlot_Lock(i, false);
2049 }
2050 
2051 
2053 {
2055  return;
2056 
2057  Reference< XRowSet> xDatabaseForm(m_xActiveForm, UNO_QUERY);
2058  if (xDatabaseForm.is() && getConnection(xDatabaseForm).is())
2059  {
2060  Reference< XPropertySet> xActiveFormSet(m_xActiveForm, UNO_QUERY);
2061  if (xActiveFormSet.is())
2062  {
2063  // if there is a data source, then build the listener
2064  // TODO: this is strange - shouldn't this depend on a isLoaded instead of
2065  // a "has command value"? Finally, the command value only means that it was
2066  // intended to be loaded, not that it actually *is* loaded
2067  OUString aSource = ::comphelper::getString(xActiveFormSet->getPropertyValue(FM_PROP_COMMAND));
2068  if (!aSource.isEmpty())
2069  {
2070  m_bDatabaseBar = true;
2071 
2072  xActiveFormSet->getPropertyValue(FM_PROP_NAVIGATION) >>= m_eNavigate;
2073 
2074  switch (m_eNavigate)
2075  {
2076  case NavigationBarMode_PARENT:
2077  {
2078  // search for the controller via which navigation is possible
2079  Reference< XChild> xChild = m_xActiveController;
2080  Reference< runtime::XFormController > xParent;
2081  while (xChild.is())
2082  {
2083  xChild.set(xChild->getParent(), UNO_QUERY);
2084  xParent.set(xChild, UNO_QUERY);
2085  Reference< XPropertySet> xParentSet;
2086  if (xParent.is())
2087  xParentSet.set(xParent->getModel(), UNO_QUERY);
2088  if (xParentSet.is())
2089  {
2090  xParentSet->getPropertyValue(FM_PROP_NAVIGATION) >>= m_eNavigate;
2091  if (m_eNavigate == NavigationBarMode_CURRENT)
2092  break;
2093  }
2094  }
2095  m_xNavigationController = xParent;
2096  }
2097  break;
2098 
2099  case NavigationBarMode_CURRENT:
2101  break;
2102 
2103  default:
2104  m_xNavigationController = nullptr;
2105  m_bDatabaseBar = false;
2106  }
2107 
2111 
2112  // because of RecordCount, listen at the controller which controls the navigation
2113  Reference< XPropertySet> xNavigationSet;
2114  if (m_xNavigationController.is())
2115  {
2116  xNavigationSet.set(m_xNavigationController->getModel(), UNO_QUERY);
2117  if (xNavigationSet.is())
2118  xNavigationSet->addPropertyChangeListener(FM_PROP_ROWCOUNT,this);
2119  }
2120  return;
2121  }
2122  }
2123  }
2124 
2125  m_eNavigate = NavigationBarMode_NONE;
2126  m_bDatabaseBar = false;
2127  m_xNavigationController = nullptr;
2128 }
2129 
2130 
2132 {
2134  return;
2135 
2136  Reference< XRowSet> xDatabaseForm(m_xActiveForm, UNO_QUERY);
2137  if ( xDatabaseForm.is() )
2138  {
2139  if (m_xNavigationController.is())
2140  {
2141  Reference< XPropertySet> xSet(m_xNavigationController->getModel(), UNO_QUERY);
2142  if (xSet.is())
2143  xSet->removePropertyChangeListener(FM_PROP_ROWCOUNT, this);
2144 
2145  }
2146  }
2147 
2148  m_bDatabaseBar = false;
2149  m_eNavigate = NavigationBarMode_NONE;
2150  m_xNavigationController = nullptr;
2151 }
2152 
2153 
2155 {
2157  return;
2158 
2159  // if the window is already visible, only update the state
2160  bool bHasChild = m_pShell->GetViewShell()->GetViewFrame()->HasChildWindow( SID_FM_SHOW_PROPERTIES );
2161  if ( bHasChild && bShow )
2162  UpdateSlot_Lock(SID_FM_PROPERTY_CONTROL);
2163 
2164  // else toggle state
2165  else
2166  m_pShell->GetViewShell()->GetViewFrame()->ToggleChildWindow(SID_FM_SHOW_PROPERTIES);
2167 
2168  InvalidateSlot_Lock(SID_FM_PROPERTIES, false);
2169  InvalidateSlot_Lock(SID_FM_CTL_PROPERTIES, false);
2170 }
2171 
2172 
2173 IMPL_LINK(FmXFormShell, OnFoundData_Lock, FmFoundRecordInformation&, rfriWhere, void)
2174 {
2176  return;
2177 
2178  DBG_ASSERT((rfriWhere.nContext >= 0) && (rfriWhere.nContext < static_cast<sal_Int16>(m_aSearchForms.size())),
2179  "FmXFormShell::OnFoundData : invalid context!");
2180  Reference< XForm> xForm( m_aSearchForms.at(rfriWhere.nContext));
2181  DBG_ASSERT(xForm.is(), "FmXFormShell::OnFoundData : invalid form!");
2182 
2183  Reference< XRowLocate> xCursor(xForm, UNO_QUERY);
2184  if (!xCursor.is())
2185  return; // what should I do there?
2186 
2187  // to the record
2188  try
2189  {
2190  xCursor->moveToBookmark(rfriWhere.aPosition);
2191  }
2192  catch(const SQLException&)
2193  {
2194  OSL_FAIL("Can position on bookmark!");
2195  }
2196 
2198 
2199  // and to the field (for that, I collected the XVclComponent interfaces before the start of the search)
2200  SAL_WARN_IF(static_cast<size_t>(rfriWhere.nFieldPos) >=
2201  m_arrSearchedControls.size(),
2202  "svx.form", "FmXFormShell::OnFoundData : invalid index!");
2203  SdrObject* pObject = m_arrSearchedControls.at(rfriWhere.nFieldPos);
2204 
2207 
2208  FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject );
2209  Reference< XControlModel > xControlModel( pFormObject ? pFormObject->GetUnoControlModel() : Reference< XControlModel >() );
2210  DBG_ASSERT( xControlModel.is(), "FmXFormShell::OnFoundData: invalid control!" );
2211  if ( !xControlModel.is() )
2212  return;
2213 
2214  // disable the permanent cursor for the last grid we found a record
2215  if (m_xLastGridFound.is() && (m_xLastGridFound != xControlModel))
2216  {
2217  Reference< XPropertySet> xOldSet(m_xLastGridFound, UNO_QUERY);
2218  xOldSet->setPropertyValue(FM_PROP_ALWAYSSHOWCURSOR, makeAny( false ) );
2219  Reference< XPropertyState> xOldSetState(xOldSet, UNO_QUERY);
2220  if (xOldSetState.is())
2221  xOldSetState->setPropertyToDefault(FM_PROP_CURSORCOLOR);
2222  else
2223  xOldSet->setPropertyValue(FM_PROP_CURSORCOLOR, Any());
2224  }
2225 
2226  // if the field is in a GridControl, I have to additionally go into the corresponding column there
2227  sal_Int32 nGridColumn = m_arrRelativeGridColumn[rfriWhere.nFieldPos];
2228  if (nGridColumn != -1)
2229  { // unfortunately, I have to first get the control again
2230  Reference<XControl> xControl(pFormObject ? impl_getControl_Lock(xControlModel, *pFormObject) : Reference<XControl>());
2231  Reference< XGrid> xGrid(xControl, UNO_QUERY);
2232  DBG_ASSERT(xGrid.is(), "FmXFormShell::OnFoundData : invalid control!");
2233  // if one of the asserts fires, I probably did something wrong on building of m_arrSearchedControls
2234 
2235  // enable a permanent cursor for the grid so we can see the found text
2236  Reference< XPropertySet> xModelSet(xControlModel, UNO_QUERY);
2237  DBG_ASSERT(xModelSet.is(), "FmXFormShell::OnFoundData : invalid control model (no property set) !");
2238  xModelSet->setPropertyValue( FM_PROP_ALWAYSSHOWCURSOR, makeAny( true ) );
2239  xModelSet->setPropertyValue( FM_PROP_CURSORCOLOR, makeAny( COL_LIGHTRED ) );
2240  m_xLastGridFound = xControlModel;
2241 
2242  if ( xGrid.is() )
2243  xGrid->setCurrentColumnPosition(static_cast<sal_Int16>(nGridColumn));
2244  }
2245 
2246  // As the cursor has been repositioned, I have (in positioned) invalidated
2247  // my form bar slots. But that does not take effect here unfortunately, as
2248  // generally the (modal) search dialog is of course at the top ... So, force ...
2249  sal_uInt16 nPos = 0;
2250  while (DatabaseSlotMap[nPos])
2252  // unfortunately the update goes against the invalidate with only individual slots
2253 }
2254 
2255 
2256 IMPL_LINK(FmXFormShell, OnCanceledNotFound_Lock, FmFoundRecordInformation&, rfriWhere, void)
2257 {
2259  return;
2260 
2261  DBG_ASSERT((rfriWhere.nContext >= 0) && (rfriWhere.nContext < static_cast<sal_Int16>(m_aSearchForms.size())),
2262  "FmXFormShell::OnCanceledNotFound : invalid context!");
2263  Reference< XForm> xForm( m_aSearchForms.at(rfriWhere.nContext));
2264  DBG_ASSERT(xForm.is(), "FmXFormShell::OnCanceledNotFound : invalid form!");
2265 
2266  Reference< XRowLocate> xCursor(xForm, UNO_QUERY);
2267  if (!xCursor.is())
2268  return; // what should I do there?
2269 
2270  // to the record
2271  try
2272  {
2273  xCursor->moveToBookmark(rfriWhere.aPosition);
2274  }
2275  catch(const SQLException&)
2276  {
2277  OSL_FAIL("Can position on bookmark!");
2278  }
2279 
2280 
2282 }
2283 
2284 
2285 IMPL_LINK(FmXFormShell, OnSearchContextRequest_Lock, FmSearchContext&, rfmscContextInfo, sal_uInt32)
2286 {
2288  return 0;
2289 
2290  DBG_ASSERT(rfmscContextInfo.nContext < static_cast<sal_Int16>(m_aSearchForms.size()), "FmXFormShell::OnSearchContextRequest : invalid parameter !");
2291  Reference< XForm> xForm( m_aSearchForms.at(rfmscContextInfo.nContext));
2292  DBG_ASSERT(xForm.is(), "FmXFormShell::OnSearchContextRequest : unexpected : invalid context !");
2293 
2294  Reference< XResultSet> xIter(xForm, UNO_QUERY);
2295  DBG_ASSERT(xIter.is(), "FmXFormShell::OnSearchContextRequest : unexpected : context has no iterator !");
2296 
2297 
2298  // assemble the list of fields to involve (that is, the ControlSources of all fields that have such a property)
2299  OUString strFieldList, sFieldDisplayNames;
2300  m_arrSearchedControls.clear();
2301  m_arrRelativeGridColumn.clear();
2302 
2303  // small problem: To mark found fields, I need SdrObjects. To determine which controls
2304  // to include in the search, I need Controls (that is, XControl interfaces). So I have
2305  // to iterate over one of them and get the other in some way. Unfortunately, there is
2306  // no direct connection between the two worlds (except from a GetUnoControl to a
2307  // SdrUnoObject, but this requires an OutputDevice I can not do anything with.
2308  // However I can get to the Model from the Control and also from the SdrObject, and in
2309  // this way the assignment SdrObject<->Control is possible with a double loop.
2310  // The alternative to this (ugly but certainly not entirely fixable) solution would be
2311  // to renounce the caching of the SdrObjects, which would lead to significant extra
2312  // work in OnFoundData (since there I'd have to get the SdrObject first thing every
2313  // time). But since OnFoundData is usually called more often than ExecuteSearch, I'll
2314  // do that here.
2315 
2316  Reference< XNameAccess> xValidFormFields;
2317  Reference< XColumnsSupplier> xSupplyCols(xIter, UNO_QUERY);
2318  DBG_ASSERT(xSupplyCols.is(), "FmXFormShell::OnSearchContextRequest : invalid cursor : no columns supplier !");
2319  if (xSupplyCols.is())
2320  xValidFormFields = xSupplyCols->getColumns();
2321  DBG_ASSERT(xValidFormFields.is(), "FmXFormShell::OnSearchContextRequest : form has no fields !");
2322 
2323  // current Page/Controller
2324  FmFormPage* pCurrentPage = m_pShell->GetCurPage();
2325  assert(pCurrentPage && "FmXFormShell::OnSearchContextRequest : no page !");
2326  // Search all SdrControls of this page...
2327  OUString sControlSource, aName;
2328 
2329  SdrObjListIter aPageIter( pCurrentPage );
2330  while ( aPageIter.IsMore() )
2331  {
2332  SdrObject* pCurrent = aPageIter.Next();
2333  FmFormObj* pFormObject = FmFormObj::GetFormObject( pCurrent );
2334  // note that in case pCurrent is a virtual object, pFormObject points to the referenced object
2335 
2336  if ( !pFormObject )
2337  continue;
2338 
2339  // the current object's model, in different tastes
2340  Reference< XControlModel> xControlModel( pFormObject->GetUnoControlModel() );
2341  Reference< XFormComponent > xCurrentFormComponent( xControlModel, UNO_QUERY );
2342  DBG_ASSERT( xCurrentFormComponent.is(), "FmXFormShell::OnSearchContextRequest: invalid objects!" );
2343  if ( !xCurrentFormComponent.is() )
2344  continue;
2345 
2346  // does the component belong to the form which we're interested in?
2347  if ( xCurrentFormComponent->getParent() != xForm )
2348  continue;
2349 
2350  // ... ask for the ControlSource property
2351  SearchableControlIterator iter( xCurrentFormComponent );
2352  Reference< XControl> xControl;
2353  // the control that has model xControlModel
2354  // (the following while can be passed through several times, without the Control
2355  // being modified, so I don't have to search every time from scratch)
2356 
2357  Reference< XInterface > xSearchable( iter.Next() );
2358  while ( xSearchable.is() )
2359  {
2360  sControlSource = iter.getCurrentValue();
2361  if ( sControlSource.isEmpty() )
2362  {
2363  // the current element has no ControlSource, so it is a GridControl (that
2364  // is the only thing that still permits the SearchableControlIteratore)
2365  xControl = impl_getControl_Lock(xControlModel, *pFormObject);
2366  DBG_ASSERT(xControl.is(), "FmXFormShell::OnSearchContextRequest : didn't ::std::find a control with requested model !");
2367 
2368  Reference< XGridPeer> xGridPeer;
2369  if ( xControl.is() )
2370  xGridPeer.set( xControl->getPeer(), UNO_QUERY );
2371  do
2372  {
2373  if (!xGridPeer.is())
2374  break;
2375 
2376  Reference< XIndexAccess> xPeerContainer(xGridPeer, UNO_QUERY);
2377  if (!xPeerContainer.is())
2378  break;
2379 
2380  Reference< XIndexAccess> xModelColumns = xGridPeer->getColumns();
2381  DBG_ASSERT(xModelColumns.is(), "FmXFormShell::OnSearchContextRequest : there is a grid control without columns !");
2382  // the case 'no columns' should be indicated with an empty container, I think ...
2383  DBG_ASSERT(xModelColumns->getCount() >= xPeerContainer->getCount(), "FmXFormShell::OnSearchContextRequest : impossible : have more view than model columns !");
2384 
2385  Reference< XInterface> xCurrentColumn;
2386  for (sal_Int32 nViewPos=0; nViewPos<xPeerContainer->getCount(); ++nViewPos)
2387  {
2388  xPeerContainer->getByIndex(nViewPos) >>= xCurrentColumn;
2389  if (!xCurrentColumn.is())
2390  continue;
2391 
2392  // can we use this column control for searching ?
2393  if (!IsSearchableControl(xCurrentColumn))
2394  continue;
2395 
2396  sal_Int32 nModelPos = GridView2ModelPos(xModelColumns, nViewPos);
2397  Reference< XPropertySet> xCurrentColModel;
2398  xModelColumns->getByIndex(nModelPos) >>= xCurrentColModel;
2399  aName = ::comphelper::getString(xCurrentColModel->getPropertyValue(FM_PROP_CONTROLSOURCE));
2400  // the cursor has a field matching the control source ?
2401  if (xValidFormFields->hasByName(aName))
2402  {
2403  strFieldList += aName + ";";
2404 
2405  sFieldDisplayNames +=
2406  ::comphelper::getString(xCurrentColModel->getPropertyValue(FM_PROP_LABEL)) +
2407  ";";
2408 
2409  rfmscContextInfo.arrFields.push_back(xCurrentColumn);
2410 
2411  // and the SdrOject to the Field
2412  m_arrSearchedControls.push_back(pCurrent);
2413  // the number of the column
2414  m_arrRelativeGridColumn.push_back(nViewPos);
2415  }
2416  }
2417  } while (false);
2418  }
2419  else
2420  {
2421  if (!sControlSource.isEmpty() && xValidFormFields->hasByName(sControlSource))
2422  {
2423  // now I need the Control to SdrObject
2424  if (!xControl.is())
2425  {
2426  xControl = impl_getControl_Lock(xControlModel, *pFormObject);
2427  DBG_ASSERT(xControl.is(), "FmXFormShell::OnSearchContextRequest : didn't ::std::find a control with requested model !");
2428  }
2429 
2430  if (IsSearchableControl(xControl))
2431  {
2432  // all tests passed -> take along in the list
2433  strFieldList += sControlSource + ";";
2434 
2435  // the label which should appear for the control :
2436  sFieldDisplayNames +=
2437  getLabelName(Reference< XPropertySet>(xControlModel, UNO_QUERY)) +
2438  ";";
2439 
2440  // mark the SdrObject (accelerates the treatment in OnFoundData)
2441  m_arrSearchedControls.push_back(pCurrent);
2442 
2443  // the number of the column (here a dummy, since it is only interesting for GridControls)
2444  m_arrRelativeGridColumn.push_back(-1);
2445 
2446  // and for the formatted search...
2447  rfmscContextInfo.arrFields.emplace_back( xControl, UNO_QUERY );
2448  }
2449  }
2450  }
2451 
2452  xSearchable = iter.Next();
2453  }
2454  }
2455 
2456  strFieldList = comphelper::string::stripEnd(strFieldList, ';');
2457  sFieldDisplayNames = comphelper::string::stripEnd(sFieldDisplayNames, ';');
2458 
2459  if (rfmscContextInfo.arrFields.empty())
2460  {
2461  rfmscContextInfo.arrFields.clear();
2462  rfmscContextInfo.xCursor = nullptr;
2463  rfmscContextInfo.strUsedFields.clear();
2464  return 0L;
2465  }
2466 
2467  rfmscContextInfo.xCursor = xIter;
2468  rfmscContextInfo.strUsedFields = strFieldList;
2469  rfmscContextInfo.sFieldDisplayNames = sFieldDisplayNames;
2470 
2471  // 66463 - 31.05.99 - FS
2472  // when the cursor is a non-STANDARD RecordMode, set it back
2473  Reference< XPropertySet> xCursorSet(rfmscContextInfo.xCursor, UNO_QUERY);
2474  Reference< XResultSetUpdate> xUpdateCursor(rfmscContextInfo.xCursor, UNO_QUERY);
2475  if (xUpdateCursor.is() && xCursorSet.is())
2476  {
2477  if (::comphelper::getBOOL(xCursorSet->getPropertyValue(FM_PROP_ISNEW)))
2478  xUpdateCursor->moveToCurrentRow();
2479  else if (::comphelper::getBOOL(xCursorSet->getPropertyValue(FM_PROP_ISMODIFIED)))
2480  xUpdateCursor->cancelRowUpdates();
2481  }
2482 
2483  return rfmscContextInfo.arrFields.size();
2484 }
2485 
2486  // XContainerListener
2487 
2488 void SAL_CALL FmXFormShell::elementInserted(const ContainerEvent& evt)
2489 {
2490  SolarMutexGuard g;
2491 
2493  return;
2494 
2495  // new object to listen to
2496  Reference< XInterface> xTemp;
2497  evt.Element >>= xTemp;
2498  AddElement_Lock(xTemp);
2499 
2500  m_pShell->DetermineForms(true);
2501 }
2502 
2503 
2504 void SAL_CALL FmXFormShell::elementReplaced(const ContainerEvent& evt)
2505 {
2506  SolarMutexGuard g;
2507 
2508  if (impl_checkDisposed_Lock() )
2509  return;
2510 
2511  Reference< XInterface> xTemp;
2512  evt.ReplacedElement >>= xTemp;
2513  RemoveElement_Lock(xTemp);
2514  evt.Element >>= xTemp;
2515  AddElement_Lock(xTemp);
2516 }
2517 
2518 
2519 void SAL_CALL FmXFormShell::elementRemoved(const ContainerEvent& evt)
2520 {
2521  SolarMutexGuard g;
2522 
2524  return;
2525 
2526  Reference< XInterface> xTemp;
2527  evt.Element >>= xTemp;
2528  RemoveElement_Lock(xTemp);
2529 
2530  m_pShell->DetermineForms(true);
2531 }
2532 
2533 
2534 void FmXFormShell::UpdateForms_Lock(bool _bInvalidate)
2535 {
2537  return;
2538 
2539  Reference< XIndexAccess > xForms;
2540 
2541  FmFormPage* pPage = m_pShell->GetCurPage();
2542  if ( pPage && m_pShell->m_bDesignMode )
2543  xForms = pPage->GetForms( false );
2544 
2545  if ( m_xForms != xForms )
2546  {
2548  m_xForms = xForms;
2550  }
2551 
2552  SolarMutexGuard g;
2553  m_pShell->DetermineForms( _bInvalidate );
2554 }
2555 
2556 
2558 {
2560  return;
2561  impl_AddElement_nothrow(_xElement);
2562 }
2563 
2565 {
2566  // listen at the container
2567  const Reference< XIndexContainer> xContainer(Element, UNO_QUERY);
2568  if (xContainer.is())
2569  {
2570  const sal_uInt32 nCount = xContainer->getCount();
2571  Reference< XInterface> xElement;
2572  for (sal_uInt32 i = 0; i < nCount; ++i)
2573  {
2574  xElement.set(xContainer->getByIndex(i),UNO_QUERY);
2575  impl_AddElement_nothrow(xElement);
2576  }
2577 
2578  const Reference< XContainer> xCont(Element, UNO_QUERY);
2579  if (xCont.is())
2580  xCont->addContainerListener(this);
2581  }
2582 
2583  const Reference< css::view::XSelectionSupplier> xSelSupplier(Element, UNO_QUERY);
2584  if (xSelSupplier.is())
2585  xSelSupplier->addSelectionChangeListener(this);
2586 }
2587 
2588 
2590 {
2592  return;
2594 }
2595 
2597 {
2598  const Reference< css::view::XSelectionSupplier> xSelSupplier(Element, UNO_QUERY);
2599  if (xSelSupplier.is())
2600  xSelSupplier->removeSelectionChangeListener(this);
2601 
2602  // remove connection to children
2603  const Reference< XIndexContainer> xContainer(Element, UNO_QUERY);
2604  if (xContainer.is())
2605  {
2606  const Reference< XContainer> xCont(Element, UNO_QUERY);
2607  if (xCont.is())
2608  xCont->removeContainerListener(this);
2609 
2610  const sal_uInt32 nCount = xContainer->getCount();
2611  Reference< XInterface> xElement;
2612  for (sal_uInt32 i = 0; i < nCount; i++)
2613  {
2614  xElement.set(xContainer->getByIndex(i),UNO_QUERY);
2616  }
2617  }
2618 
2619  InterfaceBag::iterator wasSelectedPos = m_aCurrentSelection.find( Element );
2620  if ( wasSelectedPos != m_aCurrentSelection.end() )
2621  m_aCurrentSelection.erase( wasSelectedPos );
2622 }
2623 
2624 
2625 void SAL_CALL FmXFormShell::selectionChanged(const lang::EventObject& rEvent)
2626 {
2627  SolarMutexGuard g;
2628 
2630  return;
2631 
2632  Reference< XSelectionSupplier > xSupplier( rEvent.Source, UNO_QUERY );
2633  Reference< XInterface > xSelObj( xSupplier->getSelection(), UNO_QUERY );
2634  // a selection was removed, this can only be done by the shell
2635  if ( !xSelObj.is() )
2636  return;
2637 
2639 
2640  bool bMarkChanged = m_pShell->GetFormView()->checkUnMarkAll(rEvent.Source);
2641  Reference< XForm > xNewForm( GetForm( rEvent.Source ) );
2642 
2644  aNewSelection.insert( Reference<XInterface>( xSelObj, UNO_QUERY ) );
2645 
2646  if (setCurrentSelection_Lock(aNewSelection) && IsPropBrwOpen_Lock())
2648 
2650 
2651  if ( bMarkChanged )
2653 }
2654 
2655 
2656 IMPL_LINK_NOARG(FmXFormShell, OnTimeOut_Lock, Timer*, void)
2657 {
2659  return;
2660 
2663 }
2664 
2665 
2667 {
2669  return;
2670 
2672  m_aMarkTimer.Start();
2673 }
2674 
2675 
2677 {
2679  return;
2680 
2681  DetermineSelection_Lock(rMarkList);
2683 }
2684 
2685 
2687 {
2690 }
2691 
2692 
2694 {
2696  return false;
2697 
2699  && m_pShell->GetViewShell()->GetViewFrame()->HasChildWindow(SID_FM_SHOW_PROPERTIES);
2700 }
2701 
2702 
2704 {
2705 private:
2708 
2709 public:
2711  :m_rShell( _rShell )
2712  ,m_bEnabled( false )
2713  {
2714  if (m_rShell.IsTrackPropertiesEnabled_Lock())
2715  {
2716  m_rShell.EnableTrackProperties_Lock(false);
2717  m_bEnabled = true;
2718  }
2719  }
2720 
2722  {
2723  if ( m_bEnabled ) // note that ( false != m_bEnabled ) implies ( NULL != m_pShell )
2724  m_rShell.EnableTrackProperties_Lock(true);
2725  }
2726 };
2727 
2728 
2730 {
2732  return;
2733 
2734  DBG_ASSERT(m_pShell->GetFormView(), "FmXFormShell::SetDesignMode : invalid call (have no shell or no view) !");
2735  m_bChangingDesignMode = true;
2736 
2737  // 67506 - 15.07.99 - FS
2738  // if we're switching off the design mode we have to force the property browser to be closed
2739  // so it can commit it's changes _before_ we load the forms
2740  if (!bDesign)
2741  {
2744  m_pShell->GetViewShell()->GetViewFrame()->ToggleChildWindow(SID_FM_SHOW_PROPERTIES);
2745  }
2746 
2747  FmFormView* pFormView = m_pShell->GetFormView();
2748  if (bDesign)
2749  {
2750  // we are currently filtering, so stop filtering
2751  if (m_bFilterMode)
2752  stopFiltering_Lock(false);
2753 
2754  // unsubscribe from the objects of my MarkList
2755  pFormView->GetImpl()->stopMarkListWatching();
2756  }
2757  else
2758  {
2759  m_aMarkTimer.Stop();
2760 
2761  SuspendPropertyTracking aSuspend( *this );
2762  pFormView->GetImpl()->saveMarkList();
2763  }
2764 
2765  if (bDesign && m_xExternalViewController.is())
2767 
2768  pFormView->ChangeDesignMode(bDesign);
2769 
2770  // notify listeners
2771  FmDesignModeChangedHint aChangedHint( bDesign );
2772  m_pShell->Broadcast(aChangedHint);
2773 
2774  m_pShell->m_bDesignMode = bDesign;
2775  UpdateForms_Lock(false);
2776 
2777  m_pTextShell->designModeChanged();
2778 
2779  if (bDesign)
2780  {
2781  SdrMarkList aList;
2782  {
2783  // during changing the mark list, don't track the selected objects in the property browser
2784  SuspendPropertyTracking aSuspend( *this );
2785  // restore the marks
2786  pFormView->GetImpl()->restoreMarkList( aList );
2787  }
2788 
2789  // synchronize with the restored mark list
2790  if ( aList.GetMarkCount() )
2791  SetSelection_Lock(aList);
2792  }
2793  else
2794  {
2795  // subscribe to the model of the view (so that I'm informed when someone deletes
2796  // during the alive mode controls that I had saved in the saveMarklist (60343)
2797  pFormView->GetImpl()->startMarkListWatching();
2798  }
2799 
2801 
2802  // 67506 - 15.07.99 - FS
2803  if (bDesign && m_bHadPropertyBrowserInDesignMode)
2804  {
2805  // The UIFeatureChanged performs an update (a check of the available features) asynchronously.
2806  // So we can't call ShowSelectionProperties directly as the according feature isn't enabled yet.
2807  // That's why we use an asynchron execution on the dispatcher.
2808  // (And that's why this has to be done AFTER the UIFeatureChanged.)
2809  m_pShell->GetViewShell()->GetViewFrame()->GetDispatcher()->Execute( SID_FM_SHOW_PROPERTY_BROWSER, SfxCallMode::ASYNCHRON );
2810  }
2811  m_bChangingDesignMode = false;
2812 }
2813 
2814 
2815 Reference< XControl> FmXFormShell::impl_getControl_Lock(const Reference<XControlModel>& i_rxModel, const FmFormObj& i_rKnownFormObj)
2816 {
2818  return nullptr;
2819 
2820  Reference< XControl > xControl;
2821  try
2822  {
2823  Reference< XControlContainer> xControlContainer(getControlContainerForView_Lock(), UNO_SET_THROW);
2824 
2825  const Sequence< Reference< XControl > > seqControls( xControlContainer->getControls() );
2826  // ... that I can then search
2827  for (Reference< XControl > const & control : seqControls)
2828  {
2829  xControl.set( control, UNO_SET_THROW );
2830  Reference< XControlModel > xCurrentModel( xControl->getModel() );
2831  if ( xCurrentModel == i_rxModel )
2832  break;
2833  xControl.clear();
2834  }
2835 
2836  if ( !xControl.is() )
2837  {
2838  // fallback (some controls might not have been created, yet, since they were never visible so far)
2839  Reference< XControl > xContainerControl( xControlContainer, UNO_QUERY_THROW );
2840  const vcl::Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerControl->getPeer() );
2841  ENSURE_OR_THROW( pContainerWindow, "unexpected control container implementation" );
2842 
2843  const SdrView* pSdrView = m_pShell ? m_pShell->GetFormView() : nullptr;
2844  ENSURE_OR_THROW( pSdrView, "no current view" );
2845 
2846  xControl.set( i_rKnownFormObj.GetUnoControl( *pSdrView, *pContainerWindow ), UNO_SET_THROW );
2847  }
2848  }
2849  catch( const Exception& )
2850  {
2851  DBG_UNHANDLED_EXCEPTION("svx");
2852  }
2853 
2854  OSL_ENSURE( xControl.is(), "FmXFormShell::impl_getControl: no control found!" );
2855  return xControl;
2856 }
2857 
2858 // note: _out_rForms is a member so needs lock
2860  const OUString& _rCurrentLevelPrefix, FmFormArray& _out_rForms, ::std::vector< OUString >& _out_rNames )
2861 {
2862  try
2863  {
2864  Reference< XIndexAccess> xContainer( _rxStartingPoint, UNO_QUERY );
2865  if ( !xContainer.is() )
2866  return;
2867 
2868  sal_Int32 nCount( xContainer->getCount() );
2869  if ( nCount == 0 )
2870  return;
2871 
2872  OUString sCurrentFormName;
2873  OUStringBuffer aNextLevelPrefix;
2874  for ( sal_Int32 i=0; i<nCount; ++i )
2875  {
2876  // is the current child a form?
2877  Reference< XForm > xCurrentAsForm( xContainer->getByIndex(i), UNO_QUERY );
2878  if ( !xCurrentAsForm.is() )
2879  continue;
2880 
2881  Reference< XNamed > xNamed( xCurrentAsForm, UNO_QUERY_THROW );
2882  sCurrentFormName = xNamed->getName();
2883 
2884  // the name of the current form
2885  OUStringBuffer sCompleteCurrentName( sCurrentFormName );
2886  if ( !_rCurrentLevelPrefix.isEmpty() )
2887  {
2888  sCompleteCurrentName.append( " (" );
2889  sCompleteCurrentName.append ( _rCurrentLevelPrefix );
2890  sCompleteCurrentName.append( ")" );
2891  }
2892 
2893  // the prefix for the next level
2894  aNextLevelPrefix = _rCurrentLevelPrefix;
2895  if ( !_rCurrentLevelPrefix.isEmpty() )
2896  aNextLevelPrefix.append( '/' );
2897  aNextLevelPrefix.append( sCurrentFormName );
2898 
2899  // remember both the form and its "display name"
2900  _out_rForms.push_back( xCurrentAsForm );
2901  _out_rNames.push_back( sCompleteCurrentName.makeStringAndClear() );
2902 
2903  // and descend
2905  xCurrentAsForm, aNextLevelPrefix.makeStringAndClear(),
2906  _out_rForms, _out_rNames);
2907  }
2908  }
2909  catch( const Exception& )
2910  {
2911  DBG_UNHANDLED_EXCEPTION("svx");
2912  }
2913 }
2914 
2915 
2917 {
2919  return;
2920 
2921  // setting all forms in filter mode
2922  FmXFormView* pXView = m_pShell->GetFormView()->GetImpl();
2923 
2924  // if the active controller is our external one we have to use the trigger controller
2925  Reference< XControlContainer> xContainer;
2927  {
2928  DBG_ASSERT(m_xExtViewTriggerController.is(), "FmXFormShell::startFiltering : inconsistent : active external controller, but no one triggered this !");
2929  xContainer = m_xExtViewTriggerController->getContainer();
2930  }
2931  else
2932  xContainer = getActiveController_Lock()->getContainer();
2933 
2934  PFormViewPageWindowAdapter pAdapter = pXView->findWindow( xContainer );
2935  if ( pAdapter.is() )
2936  {
2937  const ::std::vector< Reference< runtime::XFormController> >& rControllerList = pAdapter->GetList();
2938  for (const auto& rpController : rControllerList)
2939  {
2940  Reference< XModeSelector> xModeSelector(rpController, UNO_QUERY);
2941  if (xModeSelector.is())
2942  xModeSelector->setMode( "FilterMode" );
2943  }
2944  }
2945 
2946  m_bFilterMode = true;
2947 
2949  SfxViewFrame* pViewFrame = m_pShell->GetViewShell()->GetViewFrame();
2950  pViewFrame->GetBindings().InvalidateShell( *m_pShell );
2951 
2952  if ( pViewFrame->KnowsChildWindow( SID_FM_FILTER_NAVIGATOR )
2953  && !pViewFrame->HasChildWindow( SID_FM_FILTER_NAVIGATOR )
2954  )
2955  {
2956  pViewFrame->ToggleChildWindow( SID_FM_FILTER_NAVIGATOR );
2957  }
2958 }
2959 
2960 
2961 static void saveFilter(const Reference< runtime::XFormController >& _rxController)
2962 {
2963  Reference< XPropertySet> xFormAsSet(_rxController->getModel(), UNO_QUERY);
2964  Reference< XPropertySet> xControllerAsSet(_rxController, UNO_QUERY);
2965 
2966  // call the subcontroller
2967  Reference< runtime::XFormController > xController;
2968  for (sal_Int32 i = 0, nCount = _rxController->getCount(); i < nCount; ++i)
2969  {
2970  _rxController->getByIndex(i) >>= xController;
2971  saveFilter(xController);
2972  }
2973 
2974  try
2975  {
2976 
2977  xFormAsSet->setPropertyValue(FM_PROP_FILTER, xControllerAsSet->getPropertyValue(FM_PROP_FILTER));
2978  xFormAsSet->setPropertyValue(FM_PROP_APPLYFILTER, makeAny( true ) );
2979  }
2980  catch (const Exception& )
2981  {
2982  DBG_UNHANDLED_EXCEPTION("svx");
2983  }
2984 
2985 }
2986 
2987 
2989 {
2991  return;
2992 
2993  m_bFilterMode = false;
2994 
2995  FmXFormView* pXView = m_pShell->GetFormView()->GetImpl();
2996 
2997  // if the active controller is our external one we have to use the trigger controller
2998  Reference< XControlContainer> xContainer;
3000  {
3001  DBG_ASSERT(m_xExtViewTriggerController.is(), "FmXFormShell::stopFiltering : inconsistent : active external controller, but no one triggered this !");
3002  xContainer = m_xExtViewTriggerController->getContainer();
3003  }
3004  else
3005  xContainer = getActiveController_Lock()->getContainer();
3006 
3007  PFormViewPageWindowAdapter pAdapter = pXView->findWindow(xContainer);
3008  if ( pAdapter.is() )
3009  {
3010  const ::std::vector< Reference< runtime::XFormController > >& rControllerList = pAdapter->GetList();
3011  ::std::vector < OUString > aOriginalFilters;
3012  ::std::vector < bool > aOriginalApplyFlags;
3013 
3014  if (bSave)
3015  {
3016  for (const auto& rpController : rControllerList)
3017  {
3018  // remember the current filter settings in case we're going to reload the forms below (which may fail)
3019  try
3020  {
3021  Reference< XPropertySet > xFormAsSet(rpController->getModel(), UNO_QUERY);
3022  aOriginalFilters.push_back(::comphelper::getString(xFormAsSet->getPropertyValue(FM_PROP_FILTER)));
3023  aOriginalApplyFlags.push_back(::comphelper::getBOOL(xFormAsSet->getPropertyValue(FM_PROP_APPLYFILTER)));
3024  }
3025  catch(Exception&)
3026  {
3027  OSL_FAIL("FmXFormShell::stopFiltering : could not get the original filter !");
3028  // put dummies into the arrays so the they have the right size
3029 
3030  if (aOriginalFilters.size() == aOriginalApplyFlags.size())
3031  // the first getPropertyValue failed -> use two dummies
3032  aOriginalFilters.emplace_back( );
3033  aOriginalApplyFlags.push_back( false );
3034  }
3035  saveFilter(rpController);
3036  }
3037  }
3038  for (const auto& rController : rControllerList)
3039  {
3040 
3041  Reference< XModeSelector> xModeSelector(rController, UNO_QUERY);
3042  if (xModeSelector.is())
3043  xModeSelector->setMode( "DataMode" );
3044  }
3045  if (bSave) // execute the filter
3046  {
3047  const ::std::vector< Reference< runtime::XFormController > > & rControllers = pAdapter->GetList();
3048  for (::std::vector< Reference< runtime::XFormController > > ::const_iterator j = rControllers.begin();
3049  j != rControllers.end(); ++j)
3050  {
3051  Reference< XLoadable> xReload((*j)->getModel(), UNO_QUERY);
3052  if (!xReload.is())
3053  continue;
3054  Reference< XPropertySet > xFormSet(xReload, UNO_QUERY);
3055 
3056  try
3057  {
3058  xReload->reload();
3059  }
3060  catch(Exception&)
3061  {
3062  OSL_FAIL("FmXFormShell::stopFiltering: Exception occurred!");
3063  }
3064 
3065  if (!isRowSetAlive(xFormSet))
3066  { // something went wrong -> restore the original state
3067  OUString sOriginalFilter = aOriginalFilters[ j - rControllers.begin() ];
3068  bool bOriginalApplyFlag = aOriginalApplyFlags[ j - rControllers.begin() ];
3069  try
3070  {
3071  xFormSet->setPropertyValue(FM_PROP_FILTER, makeAny(sOriginalFilter));
3072  xFormSet->setPropertyValue(FM_PROP_APPLYFILTER, makeAny(bOriginalApplyFlag));
3073  xReload->reload();
3074  }
3075  catch(const Exception&)
3076  {
3077  DBG_UNHANDLED_EXCEPTION("svx");
3078  }
3079  }
3080  }
3081  }
3082  }
3083 
3086 }
3087 
3088 
3090 {
3092  return;
3093 
3094  DBG_ASSERT(m_xAttachedFrame.is(), "FmXFormShell::CreateExternalView : no frame !");
3095 
3096  // the frame the external view is displayed in
3097  bool bAlreadyExistent = m_xExternalViewController.is();
3098  Reference< css::frame::XFrame> xExternalViewFrame;
3099  OUString sFrameName("_beamer");
3100 
3101  Reference<runtime::XFormController> xCurrentNavController(getNavController_Lock());
3102  // the creation of the "partwindow" may cause a deactivate of the document which will result in our nav controller to be set to NULL
3103 
3104  // _first_ check if we have any valid fields we can use for the grid view
3105  // FS - 21.10.99 - 69219
3106  {
3107  FmXBoundFormFieldIterator aModelIterator(xCurrentNavController->getModel());
3108  Reference< XPropertySet> xCurrentModelSet;
3109  bool bHaveUsableControls = false;
3110  while ((xCurrentModelSet = Reference< XPropertySet>(aModelIterator.Next(), UNO_QUERY)).is())
3111  {
3112  // the FmXBoundFormFieldIterator only supplies controls with a valid control source
3113  // so we just have to check the field type
3114  sal_Int16 nClassId = ::comphelper::getINT16(xCurrentModelSet->getPropertyValue(FM_PROP_CLASSID));
3115  switch (nClassId)
3116  {
3117  case FormComponentType::IMAGECONTROL:
3118  case FormComponentType::CONTROL:
3119  continue;
3120  }
3121  bHaveUsableControls = true;
3122  break;
3123  }
3124 
3125  if (!bHaveUsableControls)
3126  {
3127  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
3128  VclMessageType::Warning, VclButtonsType::Ok,
3129  SvxResId(RID_STR_NOCONTROLS_FOR_EXTERNALDISPLAY)));
3130  xBox->run();
3131  return;
3132  }
3133  }
3134 
3135  // load the component for external form views
3136  if (!bAlreadyExistent)
3137  {
3138  URL aWantToDispatch;
3139  aWantToDispatch.Complete = FMURL_COMPONENT_FORMGRIDVIEW;
3140 
3141  Reference< css::frame::XDispatchProvider> xProv(m_xAttachedFrame, UNO_QUERY);
3142  Reference< css::frame::XDispatch> xDisp;
3143  if (xProv.is())
3144  xDisp = xProv->queryDispatch(aWantToDispatch, sFrameName,
3145  css::frame::FrameSearchFlag::CHILDREN | css::frame::FrameSearchFlag::CREATE);
3146  if (xDisp.is())
3147  {
3148  xDisp->dispatch(aWantToDispatch, Sequence< PropertyValue>());
3149  }
3150 
3151  // with this the component should be loaded, now search the frame where it resides in
3152  xExternalViewFrame = m_xAttachedFrame->findFrame(sFrameName, css::frame::FrameSearchFlag::CHILDREN);
3153  if (xExternalViewFrame.is())
3154  {
3155  m_xExternalViewController = xExternalViewFrame->getController();
3156  if (m_xExternalViewController.is())
3157  m_xExternalViewController->addEventListener(static_cast<XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
3158  }
3159  }
3160  else
3161  {
3162  xExternalViewFrame = m_xExternalViewController->getFrame();
3163  Reference< css::frame::XDispatchProvider> xCommLink(xExternalViewFrame, UNO_QUERY);
3164 
3165  // if we display the active form we interpret the slot as "remove it"
3166  Reference< XForm> xCurrentModel(xCurrentNavController->getModel(), UNO_QUERY);
3167  if ((xCurrentModel == m_xExternalDisplayedForm) || (getInternalForm_Lock(xCurrentModel) == m_xExternalDisplayedForm))
3168  {
3170  {
3171  Reference< runtime::XFormController > xAsFormController( m_xExternalViewController, UNO_QUERY );
3172  ControllerFeatures aHelper( xAsFormController );
3173  (void)aHelper->commitCurrentControl();
3174  }
3175 
3176  Reference< runtime::XFormController > xNewController(m_xExtViewTriggerController);
3178  setActiveController_Lock(xNewController);
3179  return;
3180  }
3181 
3182  URL aClearURL;
3183  aClearURL.Complete = FMURL_GRIDVIEW_CLEARVIEW;
3184 
3185  Reference< css::frame::XDispatch> xClear( xCommLink->queryDispatch(aClearURL, OUString(), 0));
3186  if (xClear.is())
3187  xClear->dispatch(aClearURL, Sequence< PropertyValue>());
3188  }
3189 
3190  // TODO: We need an interceptor at the xSupplier, which forwards all queryDispatch requests to the FormController
3191  // instance for which this "external view" was triggered
3192 
3193  // get the dispatch interface of the frame so we can communicate (interceptable) with the controller
3194  Reference< css::frame::XDispatchProvider> xCommLink(xExternalViewFrame, UNO_QUERY);
3195 
3196  if (m_xExternalViewController.is())
3197  {
3198  DBG_ASSERT(xCommLink.is(), "FmXFormShell::CreateExternalView : the component doesn't have the necessary interfaces !");
3199  // collect the dispatchers we will need
3200  URL aAddColumnURL;
3201  aAddColumnURL.Complete = FMURL_GRIDVIEW_ADDCOLUMN;
3202  Reference< css::frame::XDispatch> xAddColumnDispatch( xCommLink->queryDispatch(aAddColumnURL, OUString(), 0));
3203  URL aAttachURL;
3204  aAttachURL.Complete = FMURL_GRIDVIEW_ATTACHTOFORM;
3205  Reference< css::frame::XDispatch> xAttachDispatch( xCommLink->queryDispatch(aAttachURL, OUString(), 0));
3206 
3207  if (xAddColumnDispatch.is() && xAttachDispatch.is())
3208  {
3209  DBG_ASSERT(xCurrentNavController.is(), "FmXFormShell::CreateExternalView : invalid call : have no nav controller !");
3210  // first : dispatch the descriptions for the columns to add
3211  sal_Int16 nAddedColumns = 0;
3212 
3213  // for radio buttons we need some special structures
3214  typedef std::map< OUString, Sequence< OUString> > MapUString2UstringSeq;
3215  typedef std::map< OUString, OUString > FmMapUString2UString;
3216  typedef std::map< OUString, sal_Int16 > FmMapUString2Int16;
3217 
3218  MapUString2UstringSeq aRadioValueLists;
3219  MapUString2UstringSeq aRadioListSources;
3220  FmMapUString2UString aRadioControlSources;
3221  FmMapUString2Int16 aRadioPositions;
3222 
3223  FmXBoundFormFieldIterator aModelIterator(xCurrentNavController->getModel());
3224  Reference< XPropertySet> xCurrentModelSet;
3225  OUString sColumnType,aGroupName,sControlSource;
3226  Sequence< Property> aProps;
3227  while ((xCurrentModelSet = Reference< XPropertySet>(aModelIterator.Next(), UNO_QUERY)).is())
3228  {
3229  OSL_ENSURE(xCurrentModelSet.is(),"xCurrentModelSet is null!");
3230  // create a description of the column to be created
3231  // first : determine it's type
3232 
3233  sal_Int16 nClassId = ::comphelper::getINT16(xCurrentModelSet->getPropertyValue(FM_PROP_CLASSID));
3234  switch (nClassId)
3235  {
3236  case FormComponentType::RADIOBUTTON:
3237  {
3238  // get the label of the button (this is the access key for our structures)
3239  aGroupName = getLabelName(xCurrentModelSet);
3240 
3241  // add the reference value of the radio button to the list source sequence
3242  Sequence< OUString>& aThisGroupLabels = aRadioListSources[aGroupName];
3243  sal_Int32 nNewSizeL = aThisGroupLabels.getLength() + 1;
3244  aThisGroupLabels.realloc(nNewSizeL);
3245  aThisGroupLabels.getArray()[nNewSizeL - 1] = ::comphelper::getString(xCurrentModelSet->getPropertyValue(FM_PROP_REFVALUE));
3246 
3247  // add the label to the value list sequence
3248  Sequence< OUString>& aThisGroupControlSources = aRadioValueLists[aGroupName];
3249  sal_Int32 nNewSizeC = aThisGroupControlSources.getLength() + 1;
3250  aThisGroupControlSources.realloc(nNewSizeC);
3251  aThisGroupControlSources.getArray()[nNewSizeC - 1] = ::comphelper::getString(xCurrentModelSet->getPropertyValue(FM_PROP_LABEL));
3252 
3253  // remember the controls source of the radio group
3254  sControlSource = ::comphelper::getString(xCurrentModelSet->getPropertyValue(FM_PROP_CONTROLSOURCE));
3255  if (aRadioControlSources.find(aGroupName) == aRadioControlSources.end())
3256  aRadioControlSources[aGroupName] = sControlSource;
3257 #ifdef DBG_UTIL
3258  else
3259  DBG_ASSERT(aRadioControlSources[aGroupName] == sControlSource,
3260  "FmXFormShell::CreateExternalView : inconsistent radio buttons detected !");
3261  // (radio buttons with the same name should have the same control source)
3262 #endif
3263  // remember the position within the columns
3264  if (aRadioPositions.find(aGroupName) == aRadioPositions.end())
3265  aRadioPositions[aGroupName] = nAddedColumns;
3266 
3267  // any further handling is done below
3268  }
3269  continue;
3270 
3271  case FormComponentType::IMAGECONTROL:
3272  case FormComponentType::CONTROL:
3273  // no grid columns for these types (though they have a control source)
3274  continue;
3275  case FormComponentType::CHECKBOX:
3276  sColumnType = FM_COL_CHECKBOX; break;
3277  case FormComponentType::LISTBOX:
3278  sColumnType = FM_COL_LISTBOX; break;
3279  case FormComponentType::COMBOBOX:
3280  sColumnType = FM_COL_COMBOBOX; break;
3281  case FormComponentType::DATEFIELD:
3282  sColumnType = FM_COL_DATEFIELD; break;
3283  case FormComponentType::TIMEFIELD:
3284  sColumnType = FM_COL_TIMEFIELD; break;
3285  case FormComponentType::NUMERICFIELD:
3286  sColumnType = FM_COL_NUMERICFIELD; break;
3287  case FormComponentType::CURRENCYFIELD:
3288  sColumnType = FM_COL_CURRENCYFIELD; break;
3289  case FormComponentType::PATTERNFIELD:
3290  sColumnType = FM_COL_PATTERNFIELD; break;
3291 
3292  case FormComponentType::TEXTFIELD:
3293  {
3294  sColumnType = FM_COL_TEXTFIELD;
3295  // we know at least two different controls which are TextFields : the basic edit field and the formatted
3296  // field. we distinguish them by their service name
3297  Reference< lang::XServiceInfo> xInfo(xCurrentModelSet, UNO_QUERY);
3298  if (xInfo.is())
3299  {
3300  sal_Int16 nObjectType = getControlTypeByObject(xInfo);
3301  if (OBJ_FM_FORMATTEDFIELD == nObjectType)
3302  sColumnType = FM_COL_FORMATTEDFIELD;
3303  }
3304  }
3305  break;
3306  default:
3307  sColumnType = FM_COL_TEXTFIELD; break;
3308  }
3309 
3310  const sal_Int16 nDispatchArgs = 3;
3311  Sequence< PropertyValue> aDispatchArgs(nDispatchArgs);
3312  PropertyValue* pDispatchArgs = aDispatchArgs.getArray();
3313 
3314  // properties describing "meta data" about the column
3315  // the type
3316  pDispatchArgs->Name = FMARG_ADDCOL_COLUMNTYPE;
3317  pDispatchArgs->Value <<= sColumnType;
3318  ++pDispatchArgs;
3319 
3320  // the pos : append the col
3321  pDispatchArgs->Name = FMARG_ADDCOL_COLUMNPOS;
3322  pDispatchArgs->Value <<= nAddedColumns;
3323  ++pDispatchArgs;
3324 
3325  // the properties to forward to the new column
3326  Sequence< PropertyValue> aColumnProps(1);
3327  PropertyValue* pColumnProps = aColumnProps.getArray();
3328 
3329  // the label
3330  pColumnProps->Name = FM_PROP_LABEL;
3331  pColumnProps->Value <<= getLabelName(xCurrentModelSet);
3332  ++pColumnProps;
3333 
3334  // for all other props : transfer them
3335  Reference< XPropertySetInfo> xControlModelInfo( xCurrentModelSet->getPropertySetInfo());
3336  DBG_ASSERT(xControlModelInfo.is(), "FmXFormShell::CreateExternalView : the control model has no property info ! This will crash !");
3337  aProps = xControlModelInfo->getProperties();
3338 
3339  // realloc the control description sequence
3340  sal_Int32 nExistentDescs = pColumnProps - aColumnProps.getArray();
3341  aColumnProps.realloc(nExistentDescs + aProps.getLength());
3342  pColumnProps = aColumnProps.getArray() + nExistentDescs;
3343 
3344  for (const Property& rProp : std::as_const(aProps))
3345  {
3346  if (rProp.Name == FM_PROP_LABEL)
3347  // already set
3348  continue;
3349  if (rProp.Name == FM_PROP_DEFAULTCONTROL)
3350  // allow the column's own "default control"
3351  continue;
3352  if (rProp.Attributes & PropertyAttribute::READONLY)
3353  // assume that properties which are readonly for the control are ro for the column to be created, too
3354  continue;
3355 
3356  pColumnProps->Name = rProp.Name;
3357  pColumnProps->Value = xCurrentModelSet->getPropertyValue(rProp.Name);
3358  ++pColumnProps;
3359  }
3360  aColumnProps.realloc(pColumnProps - aColumnProps.getArray());
3361 
3362  // columns props are a dispatch argument
3363  pDispatchArgs->Name = "ColumnProperties"; // TODO : fmurl.*
3364  pDispatchArgs->Value <<= aColumnProps;
3365  ++pDispatchArgs;
3366  DBG_ASSERT(nDispatchArgs == (pDispatchArgs - aDispatchArgs.getConstArray()),
3367  "FmXFormShell::CreateExternalView : forgot to adjust nDispatchArgs ?");
3368 
3369  // dispatch the "add column"
3370  xAddColumnDispatch->dispatch(aAddColumnURL, aDispatchArgs);
3371  ++nAddedColumns;
3372  }
3373 
3374  // now for the radio button handling
3375  sal_Int16 nOffset(0);
3376  // properties describing the "direct" column properties
3377  const sal_Int16 nListBoxDescription = 6;
3378  Sequence< PropertyValue> aListBoxDescription(nListBoxDescription);
3379  for (const auto& rCtrlSource : aRadioControlSources)
3380  {
3381  PropertyValue* pListBoxDescription = aListBoxDescription.getArray();
3382  // label
3383  pListBoxDescription->Name = FM_PROP_LABEL;
3384  pListBoxDescription->Value <<= rCtrlSource.first;
3385  ++pListBoxDescription;
3386 
3387  // control source
3388  pListBoxDescription->Name = FM_PROP_CONTROLSOURCE;
3389  pListBoxDescription->Value <<= rCtrlSource.second;
3390  ++pListBoxDescription;
3391 
3392  // bound column
3393  pListBoxDescription->Name = FM_PROP_BOUNDCOLUMN;
3394  pListBoxDescription->Value <<= sal_Int16(1);
3395  ++pListBoxDescription;
3396 
3397  // content type
3398  pListBoxDescription->Name = FM_PROP_LISTSOURCETYPE;
3399  pListBoxDescription->Value <<= ListSourceType_VALUELIST;
3400  ++pListBoxDescription;
3401 
3402  // list source
3403  MapUString2UstringSeq::const_iterator aCurrentListSource = aRadioListSources.find(rCtrlSource.first);
3404  DBG_ASSERT(aCurrentListSource != aRadioListSources.end(),
3405  "FmXFormShell::CreateExternalView : inconsistent radio descriptions !");
3406  pListBoxDescription->Name = FM_PROP_LISTSOURCE;
3407  pListBoxDescription->Value <<= (*aCurrentListSource).second;
3408  ++pListBoxDescription;
3409 
3410  // value list
3411  MapUString2UstringSeq::const_iterator aCurrentValueList = aRadioValueLists.find(rCtrlSource.first);
3412  DBG_ASSERT(aCurrentValueList != aRadioValueLists.end(),
3413  "FmXFormShell::CreateExternalView : inconsistent radio descriptions !");
3414  pListBoxDescription->Name = FM_PROP_STRINGITEMLIST;
3415  pListBoxDescription->Value <<= (*aCurrentValueList).second;
3416  ++pListBoxDescription;
3417 
3418  DBG_ASSERT(nListBoxDescription == (pListBoxDescription - aListBoxDescription.getConstArray()),
3419  "FmXFormShell::CreateExternalView : forgot to adjust nListBoxDescription ?");
3420 
3421  // properties describing the column "meta data"
3422  const sal_Int16 nDispatchArgs = 3;
3423  Sequence< PropertyValue> aDispatchArgs(nDispatchArgs);
3424  PropertyValue* pDispatchArgs = aDispatchArgs.getArray();
3425 
3426  // column type : listbox
3427  pDispatchArgs->Name = FMARG_ADDCOL_COLUMNTYPE;
3428  OUString fColName = FM_COL_LISTBOX;
3429  pDispatchArgs->Value <<= fColName;
3430 // pDispatchArgs->Value <<= (OUString)FM_COL_LISTBOX;
3431  ++pDispatchArgs;
3432 
3433  // column position
3434  pDispatchArgs->Name = FMARG_ADDCOL_COLUMNPOS;
3435  FmMapUString2Int16::const_iterator aOffset = aRadioPositions.find(rCtrlSource.first);
3436  DBG_ASSERT(aOffset != aRadioPositions.end(),
3437  "FmXFormShell::CreateExternalView : inconsistent radio descriptions !");
3438  sal_Int16 nPosition = (*aOffset).second;
3439  nPosition = nPosition + nOffset;
3440  // we already inserted nOffset additional columns...
3441  pDispatchArgs->Value <<= nPosition;
3442  ++pDispatchArgs;
3443 
3444  // the
3445  pDispatchArgs->Name = "ColumnProperties"; // TODO : fmurl.*
3446  pDispatchArgs->Value <<= aListBoxDescription;
3447  ++pDispatchArgs;
3448  DBG_ASSERT(nDispatchArgs == (pDispatchArgs - aDispatchArgs.getConstArray()),
3449  "FmXFormShell::CreateExternalView : forgot to adjust nDispatchArgs ?");
3450 
3451  // dispatch the "add column"
3452  xAddColumnDispatch->dispatch(aAddColumnURL, aDispatchArgs);
3453  ++nAddedColumns;
3454  ++nOffset;
3455  }
3456 
3457 
3458  DBG_ASSERT(nAddedColumns > 0, "FmXFormShell::CreateExternalView : no controls (inconsistent) !");
3459  // we should have checked if we have any usable controls (see above).
3460 
3461  // "load" the "form" of the external view
3462  PropertyValue aArg;
3463  aArg.Name = FMARG_ATTACHTO_MASTERFORM;
3464  Reference< XResultSet> xForm(xCurrentNavController->getModel(), UNO_QUERY);
3465  aArg.Value <<= xForm;
3466 
3467  m_xExternalDisplayedForm = xForm;
3468  // do this before dispatching the "attach" command, as the attach may result in a call to our queryDispatch (for the FormSlots)
3469  // which needs the m_xExternalDisplayedForm
3470 
3471  xAttachDispatch->dispatch(aAttachURL, Sequence< PropertyValue>(&aArg, 1));
3472 
3473  m_xExtViewTriggerController = xCurrentNavController;
3474 
3475  // we want to know modifications done in the external view
3476  // if the external controller is a XFormController we can use all our default handlings for it
3477  Reference< runtime::XFormController > xFormController( m_xExternalViewController, UNO_QUERY );
3478  OSL_ENSURE( xFormController.is(), "FmXFormShell::CreateExternalView:: invalid external view controller!" );
3479  if (xFormController.is())
3480  xFormController->addActivateListener(static_cast<XFormControllerListener*>(this));
3481  }
3482  }
3483 #ifdef DBG_UTIL
3484  else
3485  {
3486  OSL_FAIL("FmXFormShell::CreateExternalView : could not create the external form view !");
3487  }
3488 #endif
3489  InvalidateSlot_Lock(SID_FM_VIEW_AS_GRID, false);
3490 }
3491 
3492 
3494 {
3495  // get (cache) the wizard usage flag
3496  Sequence< OUString > aNames { "FormControlPilotsEnabled" };
3497  Sequence< Any > aFlags = GetProperties(aNames);
3498  if (1 == aFlags.getLength())
3499  m_bUseWizards = ::cppu::any2bool(aFlags[0]);
3500 }
3501 
3502 
3503 void FmXFormShell::Notify( const css::uno::Sequence< OUString >& _rPropertyNames)
3504 {
3507  return;
3508 
3509  for (const OUString& rName : _rPropertyNames)
3510  if (rName == "FormControlPilotsEnabled")
3511  {
3513  InvalidateSlot_Lock(SID_FM_USE_WIZARDS, true);
3514  }
3515 }
3516 
3518 {
3519 }
3520 
3521 
3523 {
3524  m_bUseWizards = _bUseThem;
3525 
3526  Sequence< OUString > aNames { "FormControlPilotsEnabled" };
3527  Sequence< Any > aValues(1);
3528  aValues[0] <<= m_bUseWizards;
3529  PutProperties(aNames, aValues);
3530 }
3531 
3532 
3533 void FmXFormShell::viewDeactivated_Lock(FmFormView& _rCurrentView, bool _bDeactivateController)
3534 {
3535 
3536  if ( _rCurrentView.GetImpl() && !_rCurrentView.IsDesignMode() )
3537  {
3538  _rCurrentView.GetImpl()->Deactivate( _bDeactivateController );
3539  }
3540 
3541  // if we have an async load operation pending for the 0-th page for this view,
3542  // we need to cancel this
3543  if (FmFormPage* pPage = _rCurrentView.GetCurPage())
3544  {
3545  // move all events from our queue to a new one, omit the events for the deactivated
3546  // page
3547  ::std::queue< FmLoadAction > aNewEvents;
3548  while ( !m_aLoadingPages.empty() )
3549  {
3550  FmLoadAction aAction = m_aLoadingPages.front();
3551  m_aLoadingPages.pop();
3552  if ( pPage != aAction.pPage )
3553  {
3554  aNewEvents.push( aAction );
3555  }
3556  else
3557  {
3559  }
3560  }
3561  m_aLoadingPages = aNewEvents;
3562 
3563  // remove callbacks at the page
3564  pPage->GetImpl().SetFormsCreationHdl( Link<FmFormPageImpl&,void>() );
3565  }
3566  UpdateForms_Lock(true);
3567 }
3568 
3569 
3570 IMPL_LINK_NOARG( FmXFormShell, OnFirstTimeActivation_Lock, void*, void )
3571 {
3572  if (impl_checkDisposed_Lock())
3573  return;
3574 
3575  m_nActivationEvent = nullptr;
3576  SfxObjectShell* pDocument = m_pShell->GetObjectShell();
3577 
3578  if ( pDocument && !pDocument->HasName() )
3579  {
3580  if (isEnhancedForm_Lock())
3581  {
3582  // show the data navigator
3583  if ( !m_pShell->GetViewShell()->GetViewFrame()->HasChildWindow( SID_FM_SHOW_DATANAVIGATOR ) )
3584  m_pShell->GetViewShell()->GetViewFrame()->ToggleChildWindow( SID_FM_SHOW_DATANAVIGATOR );
3585  }
3586  }
3587 }
3588 
3589 
3590 IMPL_LINK_NOARG( FmXFormShell, OnFormsCreated_Lock, FmFormPageImpl&, void )
3591 {
3592  UpdateForms_Lock(true);
3593 }
3594 
3595 
3596 void FmXFormShell::viewActivated_Lock(FmFormView& _rCurrentView, bool _bSyncAction)
3597 {
3598  FmFormPage* pPage = _rCurrentView.GetCurPage();
3599 
3600  // activate our view if we are activated ourself
3601  // FS - 30.06.99 - 67308
3602  if ( _rCurrentView.GetImpl() && !_rCurrentView.IsDesignMode() )
3603  {
3604  // load forms for the page the current view belongs to
3605  if ( pPage )
3606  {
3607  if ( !pPage->GetImpl().hasEverBeenActivated() )
3609  | (_bSyncAction ? LoadFormsFlags::Sync
3611  pPage->GetImpl().setHasBeenActivated( );
3612  }
3613 
3614  // first-time initializations for the views
3615  if ( !_rCurrentView.GetImpl()->hasEverBeenActivated( ) )
3616  {
3617  _rCurrentView.GetImpl()->onFirstViewActivation( dynamic_cast<FmFormModel*>( _rCurrentView.GetModel() ) );
3618  _rCurrentView.GetImpl()->setHasBeenActivated( );
3619  }
3620 
3621  // activate the current view
3622  _rCurrentView.GetImpl()->Activate( _bSyncAction );
3623  }
3624 
3625  // set callbacks at the page
3626  if ( pPage )
3627  {
3628  pPage->GetImpl().SetFormsCreationHdl(LINK(this, FmXFormShell, OnFormsCreated_Lock));
3629  }
3630 
3631  UpdateForms_Lock(true);
3632 
3633  if ( m_bFirstActivation )
3634  {
3635  m_nActivationEvent = Application::PostUserEvent(LINK(this, FmXFormShell, OnFirstTimeActivation_Lock));
3636  m_bFirstActivation = false;
3637  }
3638 
3639  // find a default "current form", if there is none, yet
3640  // #i88186# / 2008-04-12 / frank.schoenheit@sun.com
3642 }
3643 
3644 
3646 {
3648  return;
3649 
3650  if ( m_xCurrentForm.is() )
3651  // no action required
3652  return;
3653 
3654  FmFormView* pFormView = m_pShell->GetFormView();
3655  FmFormPage* pPage = pFormView ? pFormView->GetCurPage() : nullptr;
3656  if ( !pPage )
3657  return;
3658 
3659  try
3660  {
3661  Reference< XIndexAccess > xForms = pPage->GetForms( false );
3662  if ( !xForms.is() || !xForms->hasElements() )
3663  return;
3664 
3665  Reference< XForm > xNewCurrentForm( xForms->getByIndex(0), UNO_QUERY_THROW );
3666  impl_updateCurrentForm_Lock(xNewCurrentForm);
3667  }
3668  catch( const Exception& )
3669  {
3670  DBG_UNHANDLED_EXCEPTION("svx");
3671  }
3672 }
3673 
3674 
3675 void FmXFormShell::smartControlReset( const Reference< XIndexAccess >& _rxModels )
3676 {
3677  if (!_rxModels.is())
3678  {
3679  OSL_FAIL("FmXFormShell::smartControlReset: invalid container!");
3680  return;
3681  }
3682 
3683  static const OUString sClassIdPropertyName = FM_PROP_CLASSID;
3684  static const OUString sBoundFieldPropertyName = FM_PROP_BOUNDFIELD;
3685  sal_Int32 nCount = _rxModels->getCount();
3686  Reference< XPropertySet > xCurrent;
3687  Reference< XPropertySetInfo > xCurrentInfo;
3688  Reference< XPropertySet > xBoundField;
3689 
3690  for (sal_Int32 i=0; i<nCount; ++i)
3691  {
3692  _rxModels->getByIndex(i) >>= xCurrent;
3693  if (xCurrent.is())
3694  xCurrentInfo = xCurrent->getPropertySetInfo();
3695  else
3696  xCurrentInfo.clear();
3697  if (!xCurrentInfo.is())
3698  continue;
3699 
3700  if (xCurrentInfo->hasPropertyByName(sClassIdPropertyName))
3701  { // it's a control model
3702 
3703  // check if this control is bound to a living database field
3704  if (xCurrentInfo->hasPropertyByName(sBoundFieldPropertyName))
3705  xCurrent->getPropertyValue(sBoundFieldPropertyName) >>= xBoundField;
3706  else
3707  xBoundField.clear();
3708 
3709  // reset only if it's *not* bound
3710  bool bReset = !xBoundField.is();
3711 
3712  // and additionally, check if it has an external value binding
3713  Reference< XBindableValue > xBindable( xCurrent, UNO_QUERY );
3714  if ( xBindable.is() && xBindable->getValueBinding().is() )
3715  bReset = false;
3716 
3717  if ( bReset )
3718  {
3719  Reference< XReset > xControlReset( xCurrent, UNO_QUERY );
3720  if ( xControlReset.is() )
3721  xControlReset->reset();
3722  }
3723  }
3724  else
3725  {
3726  Reference< XIndexAccess > xContainer(xCurrent, UNO_QUERY);
3727  if (xContainer.is())
3728  smartControlReset(xContainer);
3729  }
3730  }
3731 }
3732 
3733 
3734 IMPL_LINK_NOARG( FmXFormShell, OnLoadForms_Lock, void*, void )
3735 {
3736  FmLoadAction aAction = m_aLoadingPages.front();
3737  m_aLoadingPages.pop();
3738 
3739  loadForms_Lock(aAction.pPage, aAction.nFlags & ~LoadFormsFlags::Async);
3740 }
3741 
3742 
3743 namespace
3744 {
3745  bool lcl_isLoadable( const Reference< XInterface >& _rxLoadable )
3746  {
3747  // determines whether a form should be loaded or not
3748  // if there is no datasource or connection there is no reason to load a form
3749  Reference< XPropertySet > xSet( _rxLoadable, UNO_QUERY );
3750  if ( !xSet.is() )
3751  return false;
3752  try
3753  {
3754  Reference< XConnection > xConn;
3755  if ( isEmbeddedInDatabase( _rxLoadable.get(), xConn ) )
3756  return true;
3757 
3758  // is there already an active connection
3759  xSet->getPropertyValue(FM_PROP_ACTIVE_CONNECTION) >>= xConn;
3760  if ( xConn.is() )
3761  return true;
3762 
3763  OUString sPropertyValue;
3764  OSL_VERIFY( xSet->getPropertyValue( FM_PROP_DATASOURCE ) >>= sPropertyValue );
3765  if ( !sPropertyValue.isEmpty() )
3766  return true;
3767 
3768  OSL_VERIFY( xSet->getPropertyValue( FM_PROP_URL ) >>= sPropertyValue );
3769  if ( !sPropertyValue.isEmpty() )
3770  return true;
3771  }
3772  catch(const Exception&)
3773  {
3774  DBG_UNHANDLED_EXCEPTION("svx");
3775  }
3776  return false;
3777  }
3778 }
3779 
3780 
3781 void FmXFormShell::loadForms_Lock(FmFormPage* _pPage, const LoadFormsFlags _nBehaviour /* LoadFormsFlags::Load | LoadFormsFlags::Sync */)
3782 {
3784  "FmXFormShell::loadForms: async loading not supported - this will heavily fail!" );
3785 
3786  if ( _nBehaviour & LoadFormsFlags::Async )
3787  {
3789  _pPage,
3790  _nBehaviour,
3791  Application::PostUserEvent(LINK(this, FmXFormShell, OnLoadForms_Lock), _pPage)
3792  ) );
3793  return;
3794  }
3795 
3796  DBG_ASSERT( _pPage, "FmXFormShell::loadForms: invalid page!" );
3797  if ( _pPage )
3798  {
3799  // lock the undo env so the forms can change non-transient properties while loading
3800  // (without this my doc's modified flag would be set)
3801  FmFormModel& rFmFormModel(dynamic_cast< FmFormModel& >(_pPage->getSdrModelFromSdrPage()));
3802  rFmFormModel.GetUndoEnv().Lock();
3803 
3804  // load all forms
3805  Reference< XIndexAccess > xForms = _pPage->GetForms( false );
3806 
3807  if ( xForms.is() )
3808  {
3809  Reference< XLoadable > xForm;
3810  for ( sal_Int32 j = 0, nCount = xForms->getCount(); j < nCount; ++j )
3811  {
3812  xForms->getByIndex( j ) >>= xForm;
3813  bool bFormWasLoaded = false;
3814  // a database form must be loaded for
3815  try
3816  {
3817  if ( !( _nBehaviour & LoadFormsFlags::Unload ) )
3818  {
3819  if ( lcl_isLoadable( xForm ) && !xForm->isLoaded() )
3820  xForm->load();
3821  }
3822  else
3823  {
3824  if ( xForm->isLoaded() )
3825  {
3826  bFormWasLoaded = true;
3827  xForm->unload();
3828  }
3829  }
3830  }
3831  catch( const Exception& )
3832  {
3833  DBG_UNHANDLED_EXCEPTION("svx");
3834  }
3835 
3836  // reset the form if it was loaded
3837  if ( bFormWasLoaded )
3838  {
3839  Reference< XIndexAccess > xContainer( xForm, UNO_QUERY );
3840  DBG_ASSERT( xContainer.is(), "FmXFormShell::loadForms: the form is no container!" );
3841  if ( xContainer.is() )
3842  smartControlReset( xContainer );
3843  }
3844  }
3845  }
3846 
3847  // unlock the environment
3848  rFmFormModel.GetUndoEnv().UnLock();
3849  }
3850 }
3851 
3852 
3854 {
3856  m_pTextShell->ExecuteTextAttribute( _rReq );
3857 }
3858 
3859 
3861 {
3863  m_pTextShell->GetTextAttributeState( _rSet );
3864 }
3865 
3866 
3867 bool FmXFormShell::IsActiveControl_Lock(bool _bCountRichTextOnly ) const
3868 {
3870  return m_pTextShell->IsActiveControl( _bCountRichTextOnly );
3871 }
3872 
3873 
3875 {
3877  m_pTextShell->ForgetActiveControl();
3878 }
3879 
3880 
3882 {
3884  m_pTextShell->SetControlActivationHandler( _rHdl );
3885 }
3886 
3888 {
3891 }
3892 
3893 
3895 {
3896  // catch simple double clicks
3897  if ( ( _rViewEvent.nMouseClicks == 2 ) && ( _rViewEvent.nMouseCode == MOUSE_LEFT ) )
3898  {
3899  if ( _rViewEvent.eHit == SdrHitKind::MarkedObject )
3900  {
3903  }
3904  }
3905 }
3906 
3907 
3909 {
3910  bool bHasControlFocus = false;
3911 
3912  try
3913  {
3914  Reference<runtime::XFormController> xController(getActiveController_Lock());
3915  Reference< XControl > xCurrentControl;
3916  if ( xController.is() )
3917  xCurrentControl.set( xController->getCurrentControl() );
3918  if ( xCurrentControl.is() )
3919  {
3920  Reference< XWindow2 > xPeerWindow( xCurrentControl->getPeer(), UNO_QUERY_THROW );
3921  bHasControlFocus = xPeerWindow->hasFocus();
3922  }
3923  }
3924  catch( const Exception& )
3925  {
3926  DBG_UNHANDLED_EXCEPTION("svx");
3927  }
3928 
3929  return bHasControlFocus;
3930 }
3931 
3932 
3934  :IndexAccessIterator(xStartingPoint)
3935 {
3936 }
3937 
3938 
3940 {
3941  // if the thing has a ControlSource and a BoundField property
3942  Reference< XPropertySet> xProperties(xElement, UNO_QUERY);
3944  {
3945  // and the BoundField is valid
3946  Reference< XPropertySet> xField;
3947  xProperties->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
3948  if (xField.is())
3949  {
3950  // we take it
3951  m_sCurrentValue = ::comphelper::getString(xProperties->getPropertyValue(FM_PROP_CONTROLSOURCE));
3952  return true;
3953  }
3954  }
3955 
3956  // if it is a grid control
3957  if (::comphelper::hasProperty(FM_PROP_CLASSID, xProperties))
3958  {
3959  Any aClassId( xProperties->getPropertyValue(FM_PROP_CLASSID) );
3960  if (::comphelper::getINT16(aClassId) == FormComponentType::GRIDCONTROL)
3961  {
3962  m_sCurrentValue.clear();
3963  return true;
3964  }
3965  }
3966 
3967  return false;
3968 }
3969 
3970 
3972 {
3973  return true;
3974 }
3975 
3976 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
svx::ControllerFeatures m_aNavControllerFeatures
Definition: fmshimp.hxx:199
void stopMarkListWatching()
Definition: fmvwimp.cxx:1732
SVX_DLLPRIVATE bool checkUnMarkAll(const css::uno::Reference< css::uno::XInterface > &_xSource)
Definition: fmview.cxx:519
virtual SAL_DLLPRIVATE void ImplCommit() override
Definition: fmshimp.cxx:3517
SfxViewFrame * GetViewFrame() const
#define FMARG_ADDCOL_COLUMNPOS
Definition: fmurl.hxx:49
virtual SAL_DLLPRIVATE void SAL_CALL formActivated(const css::lang::EventObject &rEvent) override
Definition: fmshimp.cxx:837
::std::set< css::uno::Reference< css::uno::XInterface > > InterfaceBag
Definition: fmtools.hxx:170
void UIFeatureChanged()
Type
SAL_DLLPRIVATE bool selectLastMarkedControls_Lock()
sets the new selection to the last known marked controls
Definition: fmshimp.cxx:1930
void saveMarkList()
Definition: fmvwimp.cxx:1760
css::uno::Reference< css::container::XIndexAccess > m_xForms
Definition: fmshimp.hxx:209
virtual SAL_DLLPRIVATE ~FmXFormShell() override
Definition: fmshimp.cxx:651
#define FMURL_GRIDVIEW_ATTACHTOFORM
Definition: fmurl.hxx:46
css::uno::Reference< css::awt::XControlModel > m_xLastGridFound
Definition: fmshimp.hxx:223
SAL_DLLPRIVATE const css::uno::Reference< css::form::XForm > & getActiveForm_Lock() const
Definition: fmshimp.hxx:351
css::uno::Reference< css::form::runtime::XFormController > m_xActiveController
Definition: fmshimp.hxx:203
sal_Int32 nIndex
OString stripEnd(const OString &rIn, sal_Char c)
SAL_DLLPRIVATE void viewActivated_Lock(FmFormView &_rCurrentView, bool _bSyncAction=false)
Definition: fmshimp.cxx:3596
void SetItemImage(sal_uInt16 nItemId, const Image &rImage)
SAL_DLLPRIVATE bool IsReadonlyDoc_Lock() const
determines whether our host document is currently read-only
Definition: fmshimp.cxx:715
SearchableControlIterator(css::uno::Reference< css::uno::XInterface > const &xStartingPoint)
Definition: fmshimp.cxx:3933
const OUString & getCurrentValue() const
Definition: fmshimp.hxx:554
virtual void SetActiveField(const OUString &strField)=0
SAL_DLLPRIVATE void UpdateForms_Lock(bool bInvalidate)
updates m_xForms, to be either , if we're in alive mode, or our current page's forms collection...
Definition: fmshimp.cxx:2534
size_t GetMarkCount() const
Definition: svdmark.hxx:179
virtual SAL_DLLPRIVATE void Notify(const css::uno::Sequence< OUString > &_rPropertyNames) override
Definition: fmshimp.cxx:3503
#define FM_PROP_LISTSOURCETYPE
Definition: fmprop.hxx:67
SAL_DLLPRIVATE void viewDeactivated_Lock(FmFormView &_rCurrentView, bool _bDeactivateController=true)
Definition: fmshimp.cxx:3533
SAL_DLLPRIVATE const svx::ControllerFeatures & getNavControllerFeatures_Lock() const
Definition: fmshimp.hxx:356
static comphelper::SolarMutex & GetSolarMutex()
std::vector< long > m_arrRelativeGridColumn
Definition: fmshimp.hxx:187
bool m_bDatabaseBar
Definition: fmshimp.hxx:241
easier access to a FormControllerHelper instance
SAL_DLLPRIVATE void ExecuteSearch_Lock()
Definition: fmshimp.cxx:1418
FmFormView * GetFormView() const
Definition: fmshell.hxx:115
void DetermineForms(bool bInvalidate)
Definition: fmshell.cxx:1189
SAL_DLLPRIVATE void implAdjustConfigCache_Lock()
Definition: fmshimp.cxx:3493
#define FM_COMPONENT_GRIDCONTROL
Definition: fmservs.hxx:41
SAL_DLLPRIVATE void InvalidateSlot_Lock(sal_Int16 nId, bool bWithId)
Definition: fmshimp.cxx:952
::cppu::WeakComponentImplHelper< css::beans::XPropertyChangeListener, css::container::XContainerListener, css::view::XSelectionChangeListener, css::form::XFormControllerListener > FmXFormShell_BD_BASE
Definition: fmshimp.hxx:127
SAL_DLLPRIVATE bool executeControlConversionSlot_Lock(const css::uno::Reference< css::form::XFormComponent > &_rxObject, const OString &rIdent)
executes a control conversion slot for a given object
#define FM_PROP_DISPLAYSYNCHRON
Definition: fmprop.hxx:113
bool isEnabled(sal_Int32 _nSlotId) const
const LanguageTag & GetUILanguageTag() const
css::uno::Reference< css::sdbc::XResultSet > m_xExternalDisplayedForm
Definition: fmshimp.hxx:229
sal_Int16 getControlTypeByObject(const Reference< css::lang::XServiceInfo > &_rxObject)
Definition: fmtools.cxx:330
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
#define FM_COMPONENT_COMMANDBUTTON
Definition: fmservs.hxx:38
ULONG m_refCount
#define FM_PROP_COMMAND
Definition: fmprop.hxx:117
void startMarkListWatching()
Definition: fmvwimp.cxx:1742
SAL_DLLPRIVATE void loadForms_Lock(FmFormPage *_pPage, const LoadFormsFlags _nBehaviour)
load or unload the forms on a page
Definition: fmshimp.cxx:3781
SfxDispatcher * GetDispatcher()
SAL_DLLPRIVATE void DetermineSelection_Lock(const SdrMarkList &rMarkList)
Definition: fmshimp.cxx:2686
void execute(sal_Int32 _nSlotId) const
std::vector< css::uno::Reference< css::form::XForm > > FmFormArray
Definition: fmshimp.hxx:67
ImplSVEvent * m_nActivationEvent
Definition: fmshimp.hxx:191
static SvxAbstractDialogFactory * Create()
Definition: svxdlg.cxx:23
#define FM_PROP_ISMODIFIED
Definition: fmprop.hxx:114
void disposeAndClear()
virtual SAL_DLLPRIVATE void invalidateFeatures(const ::std::vector< sal_Int32 > &_rFeatures) override
invalidates the given features
Definition: fmshimp.cxx:806
ConfigItemMode
static const AllSettings & GetSettings()
static VclPtr< vcl::Window > GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
sal_uInt16 nMouseClicks
Definition: svdview.hxx:110
void onFirstViewActivation(const FmFormModel *_pDocModel)
Definition: fmvwimp.cxx:595
bool IsDesignMode() const
Definition: svdmrkv.hxx:227
#define FM_COL_NUMERICFIELD
Definition: gridcols.hxx:30
#define FM_COMPONENT_FORMATTEDFIELD
Definition: fmservs.hxx:49
bool getBOOL(const Any &_rAny)
SAL_DLLPRIVATE void smartControlReset(const css::uno::Reference< css::container::XIndexAccess > &_rxModels)
Definition: fmshimp.cxx:3675
#define FM_COMPONENT_RADIOBUTTON
Definition: fmservs.hxx:35
#define FM_PROP_LABEL
Definition: fmprop.hxx:40
SAL_DLLPRIVATE void SetSelection_Lock(const SdrMarkList &rMarkList)
Definition: fmshimp.cxx:2676
css::uno::Reference< css::awt::XControlContainer > const & GetControlContainer(bool _bCreateIfNecessary=true) const
SAL_DLLPRIVATE const css::uno::Reference< css::form::runtime::XFormController > & getNavController_Lock() const
Definition: fmshimp.hxx:352
void NotifyMarkListChanged(FmFormView *)
Definition: fmshell.cxx:207
#define FM_PROP_ISNEW
Definition: fmprop.hxx:115
ImplSVEvent * m_nInvalidationEvent
Definition: fmshimp.hxx:190
const sal_uInt16 OBJ_FM_NAVIGATIONBAR
Definition: fmglob.hxx:48
sal_Int16 nId
FmFormPage * GetCurPage() const
Definition: fmshell.cxx:1150
SAL_DLLPRIVATE void ExecuteFormSlot_Lock(sal_Int32 _nSlot)
execute the given form slot
Definition: fmshimp.cxx:1761
sal_Int32 getElementPos(const Reference< css::container::XIndexAccess > &xCont, const Reference< XInterface > &xElement)
Definition: fmtools.cxx:161
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
bool m_bChangingDesignMode
Definition: fmshimp.hxx:245
bool m_bDesignMode
Definition: fmshell.hxx:83
static const sal_Int16 nObjectTypes[]
Definition: fmshimp.cxx:235
#define FM_COMPONENT_PATTERNFIELD
Definition: fmservs.hxx:48
SAL_DLLPRIVATE void impl_RemoveElement_nothrow_Lock(const css::uno::Reference< css::uno::XInterface > &Element)
remove an element
Definition: fmshimp.cxx:2596
bool m_bUseWizards
Definition: fmshimp.hxx:239
#define FM_COMPONENT_NUMERICFIELD
Definition: fmservs.hxx:46
SdrMark * GetMark(size_t nNum) const
Definition: svdmark.cxx:234
constexpr::Color COL_LIGHTRED(0xFF, 0x00, 0x00)
#define FM_COL_COMBOBOX
Definition: gridcols.hxx:26
static void saveFilter(const Reference< runtime::XFormController > &_rxController)
Definition: fmshimp.cxx:2961
virtual SAL_DLLPRIVATE void SAL_CALL elementReplaced(const css::container::ContainerEvent &rEvent) override
Definition: fmshimp.cxx:2504
const sal_uInt16 OBJ_FM_NUMERICFIELD
Definition: fmglob.hxx:40
std::vector< InvalidSlotInfo > m_arrInvalidSlots
Definition: fmshimp.hxx:178
void Invalidate(sal_uInt16 nId)
css::uno::Reference< css::frame::XController > m_xExternalViewController
Definition: fmshimp.hxx:227
Reference< XNumberFormatsSupplier > getNumberFormats(const Reference< XConnection > &_rxConn, bool _bAlloweDefault, const Reference< XComponentContext > &_rxContext)
SVX_DLLPRIVATE void ChangeDesignMode(bool bDesign)
Definition: fmview.cxx:218
virtual short Execute()=0
EmbeddedObjectRef * pObject
#define FM_PROP_STRINGITEMLIST
Definition: fmprop.hxx:59
TRISTATE_TRUE
#define FM_PROP_ALWAYSSHOWCURSOR
Definition: fmprop.hxx:112
bool IsReadOnlyUI() const
virtual SdrObjList * GetSubList() const
Definition: svdobj.cxx:674
SAL_DLLPRIVATE const css::uno::Reference< css::form::runtime::XFormController > & getActiveController_Lock() const
Definition: fmshimp.hxx:349
bool isRowSetAlive(const Reference< XInterface > &_rxRowSet)
Definition: fmtools.cxx:404
IMPL_LINK_NOARG(FmXFormShell, OnInvalidateSlots_Lock, void *, void)
Definition: fmshimp.cxx:988
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
#define FMURL_COMPONENT_FORMGRIDVIEW
Definition: fmurl.hxx:43
static const OUStringLiteral aImgIds[]
Definition: fmshimp.cxx:211
#define FM_COMPONENT_TEXTFIELD
Definition: fmservs.hxx:32
void restoreMarkList(SdrMarkList &_rRestoredMarkList)
Definition: fmvwimp.cxx:1814
FmFormModel * GetFormModel() const
Definition: fmshell.hxx:116
#define FM_COMPONENT_GROUPBOX
Definition: fmservs.hxx:36
NONE
bool IsActive() const
void ToggleChildWindow(sal_uInt16)
::osl::Mutex m_aMutex
Definition: fmshimp.hxx:189
weld::Window * GetFrameWeld() const
static const char * aConvertSlots[]
Definition: fmshimp.cxx:187
sal_uInt16 nMouseCode
Definition: svdview.hxx:112
vcl::Window & GetWindow() const
SAL_DLLPRIVATE void impl_AddElement_nothrow(const css::uno::Reference< css::uno::XInterface > &Element)
add an element
Definition: fmshimp.cxx:2564
SdrPageWindow * GetPageWindow(sal_uInt32 nIndex) const
Definition: svdpagv.cxx:93
ESelection aNewSelection(GetSelection())
Reference< XController > xController
SAL_DLLPRIVATE bool GetY2KState_Lock(sal_uInt16 &n)
Definition: fmshimp.cxx:1573
css::uno::Reference< css::form::runtime::XFormController > m_xExtViewTriggerController
Definition: fmshimp.hxx:228
SuspendPropertyTracking(FmXFormShell &_rShell)
Definition: fmshimp.cxx:2710
static bool isControlList(const SdrMarkList &rMarkList)
Definition: fmshimp.cxx:547
bool IsMore() const
Definition: svditer.hxx:62
css::uno::Reference< css::form::runtime::XFormController > m_xNavigationController
Definition: fmshimp.hxx:204
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
css::uno::Reference< css::form::XForm > m_xCurrentForm
the currently selected form, or the form which all currently selected controls belong to...
Definition: fmshimp.hxx:214
#define FM_COMPONENT_IMAGEBUTTON
Definition: fmservs.hxx:42
Timer m_aMarkTimer
Definition: fmshimp.hxx:168
SAL_DLLPRIVATE const svx::ControllerFeatures & getActiveControllerFeatures_Lock() const
Definition: fmshimp.hxx:354
const sal_uInt16 OBJ_FM_IMAGEBUTTON
Definition: fmglob.hxx:36
SAL_DLLPRIVATE css::uno::Reference< css::awt::XControl > impl_getControl_Lock(const css::uno::Reference< css::awt::XControlModel > &i_rxModel, const FmFormObj &i_rKnownFormObj)
Definition: fmshimp.cxx:2815
SAL_DLLPRIVATE void checkControlConversionSlotsForCurrentSelection_Lock(Menu &rMenu)
enables or disables all conversion slots in a menu, according to the current selection ...
Definition: fmshimp.cxx:1303
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: svdmodel.cxx:559
SfxFrame & GetFrame() const
int nCount
LoadFormsFlags
Definition: fmshimp.hxx:89
#define FM_PROP_CLASSID
Definition: fmprop.hxx:30
#define FMURL_GRIDVIEW_CLEARVIEW
Definition: fmurl.hxx:44
SAL_DLLPRIVATE void SetDesignMode_Lock(bool bDesign)
Definition: fmshimp.cxx:2729
virtual bool ShouldStepInto(const css::uno::Reference< css::uno::XInterface > &xContainer) const override
Definition: fmshimp.cxx:3971
#define FM_PROP_BOUNDFIELD
Definition: fmprop.hxx:101
SAL_DLLPRIVATE bool canConvertCurrentSelectionToControl_Lock(const OString &rIdent)
checks whether a given control conversion slot can be applied to the current selection ...
Definition: fmshimp.cxx:1266
#define FM_PROP_APPLYFILTER
Definition: fmprop.hxx:123
FmXUndoEnvironment & GetUndoEnv()
Definition: fmmodel.cxx:203
const sal_uInt16 OBJ_FM_CONTROL
Definition: fmglob.hxx:25
static void DisposeElement(const css::uno::Reference< css::awt::XControlModel > &xReplaced)
Definition: fmundo.cxx:1215
bool EnableNotification(const css::uno::Sequence< OUString > &rNames, bool bEnableInternalNotification=false)
SAL_DLLPRIVATE bool IsFormSlotEnabled(sal_Int32 _nSlot, css::form::runtime::FeatureState *_pCompleteState)
determines whether the current form slot is currently enabled
Definition: fmshimp.cxx:1746
virtual SAL_DLLPRIVATE void SAL_CALL elementInserted(const css::container::ContainerEvent &rEvent) override
Definition: fmshimp.cxx:2488
#define FM_COL_FORMATTEDFIELD
Definition: gridcols.hxx:34
const sal_uInt16 OBJ_FM_PATTERNFIELD
Definition: fmglob.hxx:42
const sal_uInt16 OBJ_FM_EDIT
Definition: fmglob.hxx:27
SAL_DLLPRIVATE bool isSolelySelected_Lock(const css::uno::Reference< css::uno::XInterface > &_rxObject)
determines whether the current selection consists of exactly the given object
Definition: fmshimp.cxx:2014
FmFormPageImpl & GetImpl() const
Definition: fmpage.hxx:62
#define FM_PROP_URL
Definition: fmprop.hxx:127
#define MOUSE_LEFT
sal_uInt32 release(bool bUnlockAll=false)
bool m_bFirstActivation
Definition: fmshimp.hxx:248
css::uno::Reference< css::lang::XComponent > xComponent
LoopGridsSync
Definition: fmshimp.hxx:72
sal_Int16 getINT16(const Any &_rAny)
SAL_DLLPRIVATE void AddElement_Lock(const css::uno::Reference< css::uno::XInterface > &Element)
Definition: fmshimp.cxx:2557
#define FM_PROP_NAVIGATION
Definition: fmprop.hxx:41
#define SAL_N_ELEMENTS(arr)
bool m_bTrackProperties
Definition: fmshimp.hxx:236
SAL_DLLPRIVATE css::uno::Reference< css::awt::XControlContainer > getControlContainerForView_Lock() const
Definition: fmshimp.cxx:1372
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
SdrObject * GetMarkedSdrObj() const
Definition: svdmark.hxx:67
#define FM_COMPONENT_COMBOBOX
Definition: fmservs.hxx:34
void assign(const css::uno::Reference< css::form::runtime::XFormController > &_rxController)
assign to a controller
#define FM_COL_TIMEFIELD
Definition: gridcols.hxx:28
#define DBG_UNHANDLED_EXCEPTION(...)
#define FM_COL_PATTERNFIELD
Definition: gridcols.hxx:32
static SAL_DLLPRIVATE std::unique_ptr< VclBuilder > GetConversionMenu_Lock()
Definition: fmshimp.cxx:1024
#define DBG_ASSERT(sCon, aError)
SAL_DLLPRIVATE void ForgetActiveControl_Lock()
Definition: fmshimp.cxx:3874
SAL_DLLPRIVATE void ShowSelectionProperties_Lock(bool bShow)
Definition: fmshimp.cxx:2154
bool PutProperties(const css::uno::Sequence< OUString > &rNames, const css::uno::Sequence< css::uno::Any > &rValues)
const sal_uInt16 OBJ_FM_GROUPBOX
Definition: fmglob.hxx:34
bool IsUndoEnabled() const
returns true if undo is currently enabled This returns false if undo was disabled using EnableUndo( f...
Definition: svdmodel.cxx:590
void DisableNotification()
bool m_bFilterMode
Definition: fmshimp.hxx:244
FmFormPage * pPage
Definition: fmshimp.hxx:116
FmFormShell * m_pShell
Definition: fmshimp.hxx:195
SfxBindings & GetBindings()
int i
#define FM_COMPONENT_LISTBOX
Definition: fmservs.hxx:33
#define FM_COMPONENT_IMAGECONTROL
Definition: fmservs.hxx:52
Any aHelper
sal_uInt16 GetItemId(sal_uInt16 nPos) const
virtual bool ShouldHandleElement(const css::uno::Reference< css::uno::XInterface > &_rElement) override
Definition: fmshimp.cxx:523
TRISTATE_FALSE
virtual bool ShouldHandleElement(const css::uno::Reference< css::uno::XInterface > &rElement) override
Definition: fmshimp.cxx:3939
const SdrMarkList & GetMarkedObjectList() const
Definition: svdmrkv.hxx:243
#define FM_PROP_LISTSOURCE
Definition: fmprop.hxx:68
SAL_DLLPRIVATE void impl_defaultCurrentForm_nothrow_Lock()
finds and sets a default for m_xCurrentForm, if it is currently NULL
Definition: fmshimp.cxx:3645
#define FM_COMPONENT_FILECONTROL
Definition: fmservs.hxx:43
#define FM_PROP_REFVALUE
Definition: fmprop.hxx:76
bool m_bInActivate
Definition: fmshimp.hxx:242
void dispose()
clears the instance so that it cannot be used afterwards
const sal_uInt16 OBJ_FM_FILECONTROL
Definition: fmglob.hxx:37
const sal_uInt16 OBJ_FM_COMBOBOX
Definition: fmglob.hxx:32
#define DO_SAFE(statement)
Definition: fmshimp.hxx:70
virtual SAL_DLLPRIVATE void SetUnoControlModel(const css::uno::Reference< css::awt::XControlModel > &_rxModel) override
Definition: fmobj.cxx:608
virtual void Start() override
css::uno::Sequence< css::uno::Any > GetProperties(const css::uno::Sequence< OUString > &rNames)
void setHasBeenActivated()
Definition: fmpgeimp.hxx:85
virtual SAL_DLLPRIVATE void SAL_CALL formDeactivated(const css::lang::EventObject &rEvent) override
Definition: fmshimp.cxx:850
bool IsGroupObject() const
Definition: svdobj.cxx:669
css::uno::Reference< css::frame::XFrame > m_xAttachedFrame
Definition: fmshimp.hxx:225
static const sal_uInt16 DatabaseSlotMap[]
Definition: fmshimp.cxx:112
void getCurrentSelection_Lock(InterfaceBag &_rSelection) const
retrieves the current selection
Definition: fmshimp.cxx:1913
#define FM_PROP_FILTER
Definition: fmprop.hxx:47
bool HasName() const
SAL_DLLPRIVATE void CloseExternalFormViewer_Lock()
Definition: fmshimp.cxx:1682
#define FM_COL_LISTBOX
Definition: gridcols.hxx:33
#define FM_COL_TEXTFIELD
Definition: gridcols.hxx:25
SAL_DLLPRIVATE bool impl_checkDisposed_Lock() const
checks whenever the instance is already disposed, if so, this is reported as assertion error (debug b...
Definition: fmshimp.cxx:683
#define FM_COL_CHECKBOX
Definition: gridcols.hxx:27
#define FM_PROP_ROWCOUNT
Definition: fmprop.hxx:32
static OUString getUIRootDir()
Shell * m_pShell
LoadFormsFlags nFlags
Definition: fmshimp.hxx:118
void SetFormsCreationHdl(const Link< FmFormPageImpl &, void > &_rFormsCreationHdl)
Definition: fmpgeimp.hxx:89
bool m_bSetFocus
Definition: fmshimp.hxx:243
#define FM_COMPONENT_CHECKBOX
Definition: fmservs.hxx:39
const sal_uInt16 OBJ_FM_CHECKBOX
Definition: fmglob.hxx:31
const sal_uInt16 OBJ_FM_SCROLLBAR
Definition: fmglob.hxx:46
const sal_uInt16 OBJ_FM_FIXEDTEXT
Definition: fmglob.hxx:29
Abstract DrawObject.
Definition: svdobj.hxx:312
void SetTimeout(sal_uInt64 nTimeoutMs)
css::uno::Reference< css::form::XForm > m_xActiveForm
Definition: fmshimp.hxx:205
SAL_DLLPRIVATE bool setCurrentSelection_Lock(const InterfaceBag &rSelection)
announces a new "current selection"
Definition: fmshimp.cxx:1936
SAL_DLLPRIVATE void ForceUpdateSelection_Lock()
Definition: fmshimp.cxx:1006
#define FM_COL_DATEFIELD
Definition: gridcols.hxx:29
static SAL_DLLPRIVATE bool isControlConversionSlot(const OString &rIdent)
checks whether the given slot id denotes a control conversion slot
Definition: fmshimp.cxx:1049
SfxViewShell * GetViewShell() const
SAL_DLLPRIVATE bool setCurrentSelectionFromMark_Lock(const SdrMarkList &rMarkList)
sets a new current selection as indicated by a mark list
Definition: fmshimp.cxx:1919
static const sal_Int16 DlgSlotMap[]
Definition: fmshimp.cxx:140
Reference< XIntrospection > xIntrospection
#define FM_SUN_COMPONENT_SPINBUTTON
Definition: fmservs.hxx:77
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
void EnableItem(sal_uInt16 nItemId, bool bEnable=true)
const sal_uInt16 OBJ_FM_SPINBUTTON
Definition: fmglob.hxx:47
bool IsReadOnly() const
virtual SdrInventor GetObjInventor() const
Definition: svdobj.cxx:580
const sal_uInt16 OBJ_FM_GRID
Definition: fmglob.hxx:35
virtual VclPtr< AbstractFmSearchDialog > CreateFmSearchDialog(weld::Window *pParent, const OUString &strInitialText, const ::std::vector< OUString > &_rContexts, sal_Int16 nInitialContext, const Link< FmSearchContext &, sal_uInt32 > &lnkContextSupplier)=0
static SAL_DLLPRIVATE FmFormObj * GetFormObject(SdrObject *_pSdrObject)
returns the FmFormObj behind the given SdrObject
Definition: fmobj.cxx:582
#define FM_COMPONENT_CURRENCYFIELD
Definition: fmservs.hxx:47
#define FM_PROP_HIDDEN
Definition: fmprop.hxx:106
css::uno::Reference< css::sdbc::XRowSet > getCursor() const
void Activate(bool bSync=false)
Definition: fmvwimp.cxx:745
static Reference< XForm > GetForm(const Reference< XInterface > &_rxElement)
Definition: fmshimp.cxx:590
SAL_DLLPRIVATE css::uno::Reference< css::frame::XModel > getContextDocument_Lock() const
Definition: fmshimp.cxx:656
FmFormPage * GetCurPage()
shortcut to "GetSdrPageView() ? PTR_CAST( FmFormPage, GetSdrPageView() ) : NULL"
Definition: fmview.cxx:141
SAL_DLLPRIVATE void stopFiltering_Lock(bool bSave)
Definition: fmshimp.cxx:2988
SAL_DLLPRIVATE void stopListening_Lock()
Definition: fmshimp.cxx:2131
void Update(sal_uInt16 nId)
SAL_DLLPRIVATE bool IsActiveControl_Lock(bool _bCountRichTextOnly) const
Definition: fmshimp.cxx:3867
bool m_bHadPropertyBrowserInDesignMode
Definition: fmshimp.hxx:234
SAL_DLLPRIVATE css::uno::Reference< css::form::XForm > getInternalForm_Lock(const css::uno::Reference< css::form::XForm > &_xForm) const
#define ENSURE_OR_THROW(c, m)
SAL_DLLPRIVATE bool HasControlFocus_Lock() const
Definition: fmshimp.cxx:3908
SdrModel & getSdrModelFromSdrPage() const
Definition: svdpage.hxx:391
SdrObject * Next()
Definition: svditer.hxx:63
virtual SAL_DLLPRIVATE void SAL_CALL disposing() override
Definition: fmshimp.cxx:862
SAL_DLLPRIVATE bool IsPropBrwOpen_Lock() const
Definition: fmshimp.cxx:2693
SAL_DLLPRIVATE void setActiveController_Lock(const css::uno::Reference< css::form::runtime::XFormController > &_xController, bool _bNoSaveOldContent=false)
Definition: fmshimp.cxx:1808
#define FM_COMPONENT_TIMEFIELD
Definition: fmservs.hxx:44
InterfaceBag m_aLastKnownMarkedControls
the last selection/marking of controls only. Necessary to implement the "Control properties" slot ...
Definition: fmshimp.hxx:216
virtual SAL_DLLPRIVATE void SAL_CALL selectionChanged(const css::lang::EventObject &rEvent) override
Definition: fmshimp.cxx:2625
bool HasChildWindow(sal_uInt16)
static const sal_Int16 SelObjectSlotMap[]
Definition: fmshimp.cxx:156
SAL_DLLPRIVATE void handleShowPropertiesRequest_Lock()
handles the request for showing the "Properties"
Definition: fmshimp.cxx:3887
const sal_uInt16 OBJ_FM_RADIOBUTTON
Definition: fmglob.hxx:33
#define FM_PROP_CURSORCOLOR
Definition: fmprop.hxx:111
InterfaceBag m_aCurrentSelection
Definition: fmshimp.hxx:212
#define FMARG_ATTACHTO_MASTERFORM
Definition: fmurl.hxx:47
SVX_DLLPRIVATE FmXFormView * GetImpl() const
Definition: fmview.hxx:131
SAL_DLLPRIVATE::svxform::DocumentType getDocumentType_Lock() const
classifies our host document
Definition: fmshimp.cxx:695
const sal_uInt16 OBJ_FM_FORMATTEDFIELD
Definition: fmglob.hxx:45
void Stop()
#define FM_COMPONENT_DATEFIELD
Definition: fmservs.hxx:45
SAL_DLLPRIVATE bool IsTrackPropertiesEnabled_Lock() const
Definition: fmshimp.hxx:290
std::vector< SdrObject * > m_arrSearchedControls
Definition: fmshimp.hxx:169
FmXFormShell_Base_Disambiguation(::osl::Mutex &_rMutex)
Definition: fmshimp.cxx:603
SAL_DLLPRIVATE FmXFormShell(FmFormShell &_rShell, SfxViewFrame *_pViewFrame)
Definition: fmshimp.cxx:608
#define FMARG_ADDCOL_COLUMNTYPE
Definition: fmurl.hxx:48
#define SAL_WARN_IF(condition, area, stream)
#define FM_COL_CURRENCYFIELD
Definition: gridcols.hxx:31
unsigned char sal_uInt8
void setHasBeenActivated()
Definition: fmvwimp.hxx:215
SAL_DLLPRIVATE void SetControlActivationHandler_Lock(const Link< LinkParamNone *, void > &_rHdl)
Definition: fmshimp.cxx:3881
SAL_DLLPRIVATE void RemoveElement_Lock(const css::uno::Reference< css::uno::XInterface > &Element)
Definition: fmshimp.cxx:2589
SAL_DLLPRIVATE void forgetCurrentForm_Lock()
Definition: fmshimp.cxx:2020
#define FM_PROP_ACTIVE_CONNECTION
Definition: fmprop.hxx:128
OOO_DLLPUBLIC_DBTOOLS bool isEmbeddedInDatabase(const css::uno::Reference< css::uno::XInterface > &_rxComponent, css::uno::Reference< css::sdbc::XConnection > &_rxActualConnection)
SAL_DLLPRIVATE bool IsSelectionUpdatePending_Lock() const
Definition: fmshimp.hxx:532
SAL_DLLPRIVATE void LoopGrids_Lock(LoopGridsSync nSync, LoopGridsFlags nWhat=LoopGridsFlags::NONE)
Definition: fmshimp.cxx:1313
sal_Int16 m_nLockSlotInvalidation
the type of document we're living in
Definition: fmshimp.hxx:233
OUString aName
SAL_DLLPRIVATE void ExecuteTextAttribute_Lock(SfxRequest &_rReq)
Definition: fmshimp.cxx:3853
sal_uInt16 GetItemCount() const
virtual bool IsDesignMode() const override
Definition: fmshell.hxx:158
bool KnowsChildWindow(sal_uInt16)
SAL_DLLPRIVATE void handleMouseButtonDown_Lock(const SdrViewEvent &_rViewEvent)
handles a MouseButtonDown event of the FmFormView
Definition: fmshimp.cxx:3894
#define FM_SUN_COMPONENT_NAVIGATIONBAR
Definition: fmservs.hxx:78
bool IsSearchableControl(const css::uno::Reference< css::uno::XInterface > &_rxControl, OUString *_pCurrentText)
Definition: fmshimp.cxx:472
bool hasEverBeenActivated() const
Definition: fmvwimp.hxx:214
SAL_DLLPRIVATE void GetTextAttributeState_Lock(SfxItemSet &_rSet)
Definition: fmshimp.cxx:3860
IMPL_LINK(FmXFormShell, OnFoundData_Lock, FmFoundRecordInformation &, rfriWhere, void)
Definition: fmshimp.cxx:2173
Reference< XComponentContext > getProcessComponentContext()
void SetInvokeHandler(const Link< Timer *, void > &rLink)
const sal_uInt16 OBJ_FM_LISTBOX
Definition: fmglob.hxx:30
virtual void SetCanceledNotFoundHdl(const Link< FmFoundRecordInformation &, void > &lnk)=0
SAL_DLLPRIVATE void UpdateSlot_Lock(sal_Int16 nId)
Definition: fmshimp.cxx:933
#define FM_COMPONENT_HIDDENCONTROL
Definition: fmservs.hxx:51
SAL_DLLPRIVATE void SetWizardUsing_Lock(bool _bUseThem)
Definition: fmshimp.cxx:3522
mutable::svxform::DocumentType m_eDocumentType
Definition: fmshimp.hxx:232
css::uno::Reference< css::awt::XControl > GetUnoControl(const SdrView &_rView, const OutputDevice &_rOut) const
Definition: svdouno.cxx:477
SAL_DLLPRIVATE void EnableTrackProperties_Lock(bool bEnable)
Definition: fmshimp.hxx:289
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage)
SAL_DLLPRIVATE void SetSelectionDelayed_Lock()
Definition: fmshimp.cxx:2666
css::uno::Reference< css::uno::XInterface > const & Next()
SdrPageView * GetSdrPageView() const
Definition: svdpntv.hxx:310
Reference< XConnection > getConnection(const Reference< XRowSet > &_rxRowSet)
const css::uno::Reference< css::awt::XControlModel > & GetUnoControlModel() const
Definition: svdouno.hxx:91
const sal_uInt16 OBJ_FM_IMAGECONTROL
Definition: fmglob.hxx:44
SAL_DLLPRIVATE void impl_switchActiveControllerListening_Lock(const bool _bListen)
adds or removes ourself as XEventListener at m_xActiveController
Definition: fmshimp.cxx:1796
virtual SAL_DLLPRIVATE void SAL_CALL elementRemoved(const css::container::ContainerEvent &rEvent) override
Definition: fmshimp.cxx:2519
bool hasProperty(const OUString &_rName, const Reference< XPropertySet > &_rxSet)
SAL_DLLPRIVATE void impl_updateCurrentForm_Lock(const css::uno::Reference< css::form::XForm > &_rxNewCurForm)
sets m_xCurrentForm to the provided form, and updates everything which depends on the current form ...
Definition: fmshimp.cxx:2034
SAL_DLLPRIVATE void SetY2KState_Lock(sal_uInt16 n)
Definition: fmshimp.cxx:1612
virtual bool tryToAcquire()
void setCurForm(const css::uno::Reference< css::form::XForm > &xForm)
Definition: fmpgeimp.cxx:354
OUString getLabelName(const Reference< css::beans::XPropertySet > &xControlModel)
Definition: fmtools.cxx:195
void InvalidateShell(const SfxShell &rSh, bool bDeep=false)
#define SAL_WARN(area, stream)
bool m_bPreparedClose
Definition: fmshimp.hxx:246
ImplSVEvent * nEventId
Definition: fmshimp.hxx:117
class FmSearchEngine - Impl class for FmSearchDialog
PFormViewPageWindowAdapter findWindow(const css::uno::Reference< css::awt::XControlContainer > &_rxCC) const
Definition: fmvwimp.cxx:525
#define FM_PROP_CONTROLSOURCE
Definition: fmprop.hxx:43
css::form::NavigationBarMode m_eNavigate
Definition: fmshimp.hxx:182
SAL_DLLPRIVATE bool onlyControlsAreMarked_Lock() const
returns whether the last known marking contained only controls
Definition: fmshimp.hxx:384
bool MarkObj(const Point &rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false)
Definition: svdmrkv.cxx:1673
#define FM_PROP_DEFAULTCONTROL
Definition: fmprop.hxx:53
#define DBG_TESTSOLARMUTEX()
std::unique_ptr< svx::FmTextControlShell > m_pTextShell
Definition: fmshimp.hxx:196
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:366
#define FM_PROP_BOUNDCOLUMN
Definition: fmprop.hxx:90
virtual SAL_DLLPRIVATE void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent &evt) override
Definition: fmshimp.cxx:766
const css::uno::Reference< css::form::XForms > & GetForms(bool _bForceCreate=true) const
Definition: fmpage.cxx:90
::std::queue< FmLoadAction > m_aLoadingPages
Definition: fmshimp.hxx:193
static SAL_DLLPRIVATE void impl_collectFormSearchContexts_nothrow_Lock(const css::uno::Reference< css::uno::XInterface > &_rxStartingPoint, const OUString &_rCurrentLevelPrefix, FmFormArray &_out_rForms,::std::vector< OUString > &_out_rNames)
Definition: fmshimp.cxx:2859
#define FM_SUN_COMPONENT_SCROLLBAR
Definition: fmservs.hxx:76
#define FMURL_GRIDVIEW_ADDCOLUMN
Definition: fmurl.hxx:45
SAL_DLLPRIVATE void LockSlotInvalidation_Lock(bool bLock)
Definition: fmshimp.cxx:970
OUString getString(const Any &_rAny)
static css::uno::Reference< css::awt::XWindow > GetInterface(vcl::Window *pWindow)
SAL_DLLPRIVATE void startListening_Lock()
Definition: fmshimp.cxx:2052
virtual void SetChanged()
Definition: svdobj.cxx:956
SAL_DLLPRIVATE void startFiltering_Lock()
Definition: fmshimp.cxx:2916
svx::ControllerFeatures m_aActiveControllerFeatures
Definition: fmshimp.hxx:198
#define FM_PROP_CONTROLLABEL
Definition: fmprop.hxx:110
sal_Int16 nContext
Definition: fmsearch.hxx:54
const sal_uInt16 OBJ_FM_HIDDEN
Definition: fmglob.hxx:43
SAL_DLLPRIVATE void ExecuteTabOrderDialog_Lock(const css::uno::Reference< css::awt::XTabControllerModel > &_rxForForm)
Definition: fmshimp.cxx:1389
bool hasEverBeenActivated() const
Definition: fmpgeimp.hxx:84
OString GetItemIdent(sal_uInt16 nItemId) const
void TransferFormComponentProperties(const Reference< XPropertySet > &xOldProps, const Reference< XPropertySet > &xNewProps, const Locale &_rLocale)
SdrModel * GetModel() const
Definition: svdpntv.hxx:271
SdrHitKind eHit
Definition: svdview.hxx:107
void UnMarkAll(SdrPageView const *pPV=nullptr)
Definition: svdmrkv.hxx:309
const sal_uInt16 OBJ_FM_BUTTON
Definition: fmglob.hxx:28
#define FM_COMPONENT_FIXEDTEXT
Definition: fmservs.hxx:37
static SAL_DLLPRIVATE OString SlotToIdent(sal_uInt16 nSlot)
Definition: fmshimp.cxx:1036
SAL_DLLPRIVATE void CreateExternalView_Lock()
Definition: fmshimp.cxx:3089
virtual bool ShouldStepInto(const css::uno::Reference< css::uno::XInterface > &_rContainer) const override
Definition: fmshimp.cxx:513
const sal_uInt16 OBJ_FM_TIMEFIELD
Definition: fmglob.hxx:39
SAL_DLLPRIVATE bool isEnhancedForm_Lock() const
Definition: fmshimp.cxx:677
const sal_uInt16 OBJ_FM_CURRENCYFIELD
Definition: fmglob.hxx:41
virtual void SetFoundHandler(const Link< FmFoundRecordInformation &, void > &lnk)=0
FmFormArray m_aSearchForms
Definition: fmshimp.hxx:171
const sal_uInt16 OBJ_FM_DATEFIELD
Definition: fmglob.hxx:38
sal_uInt16 nPos
void Deactivate(bool bDeactivateController=true)
Definition: fmvwimp.cxx:762
bool any2bool(const css::uno::Any &rAny)
void SetDebugName(const sal_Char *pDebugName)
SfxObjectShell * GetObjectShell() const
Definition: fmmodel.hxx:58
LoopGridsFlags
Definition: fmshimp.hxx:77
css::uno::Reference< css::uno::XInterface > m_xStartingPoint
void getState(sal_Int32 _nSlotId, css::form::runtime::FeatureState &_out_rState) const
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)