Bug Summary

File:home/maarten/src/libreoffice/core/svx/source/form/fmshimp.cxx
Warning:line 564, column 17
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

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