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