Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

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 fmshell.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/fmshell.cxx

/home/maarten/src/libreoffice/core/svx/source/form/fmshell.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 <fmvwimp.hxx>
21#include <svx/fmshell.hxx>
22#include <svx/fmtools.hxx>
23#include <fmprop.hxx>
24#include <fmundo.hxx>
25#include <com/sun/star/beans/XPropertySet.hpp>
26#include <com/sun/star/awt/XTabControllerModel.hpp>
27#include <sfx2/viewfrm.hxx>
28#include <vcl/svapp.hxx>
29#include <vcl/weld.hxx>
30#include <svl/whiter.hxx>
31#include <sfx2/app.hxx>
32#include <svl/intitem.hxx>
33#include <svl/stritem.hxx>
34#include <svl/visitem.hxx>
35#include <unotools/moduleoptions.hxx>
36#include <sfx2/objface.hxx>
37#include <sfx2/request.hxx>
38#include <sfx2/dispatch.hxx>
39#include <svx/svdobj.hxx>
40#include <svx/fmpage.hxx>
41#include <svx/svditer.hxx>
42
43#include <svx/svxids.hrc>
44
45#include <svx/fmglob.hxx>
46#include <svl/eitem.hxx>
47#include <tools/diagnose_ex.h>
48#include <svx/svdpage.hxx>
49#include <svx/fmmodel.hxx>
50#include <fmshimp.hxx>
51#include <svx/svdpagv.hxx>
52#include <sfx2/objitem.hxx>
53#include <sfx2/viewsh.hxx>
54#include <fmexpl.hxx>
55#include <formcontrolling.hxx>
56#include <comphelper/types.hxx>
57#include <fmdocumentclassification.hxx>
58#include <formtoolbars.hxx>
59
60#include <svx/svxdlg.hxx>
61
62#include <svx/sdrobjectfilter.hxx>
63
64#define ShellClass_FmFormShell
65#include <svxslots.hxx>
66
67#include <memory>
68
69// is used for Invalidate -> maintain it as well
70// sort ascending !!!!!!
71sal_uInt16 const ControllerSlotMap[] = // slots of the controller
72{
73 SID_FM_CONFIG( 10000 + 593 ),
74 SID_FM_PUSHBUTTON( 10000 + 594 ),
75 SID_FM_RADIOBUTTON( 10000 + 595 ),
76 SID_FM_CHECKBOX( 10000 + 596 ),
77 SID_FM_FIXEDTEXT( 10000 + 597 ),
78 SID_FM_GROUPBOX( 10000 + 598 ),
79 SID_FM_EDIT( 10000 + 599 ),
80 SID_FM_LISTBOX( 10000 + 600 ),
81 SID_FM_COMBOBOX( 10000 + 601 ),
82 SID_FM_DBGRID( 10000 + 603 ),
83 SID_FM_IMAGEBUTTON( 10000 + 604 ),
84 SID_FM_FILECONTROL( 10000 + 605 ),
85 SID_FM_NAVIGATIONBAR( 10000 + 607 ),
86 SID_FM_CTL_PROPERTIES( 10000 + 613 ),
87 SID_FM_PROPERTIES( 10000 + 614 ),
88 SID_FM_TAB_DIALOG( 10000 + 615 ),
89 SID_FM_ADD_FIELD( 10000 + 623 ),
90 SID_FM_DESIGN_MODE( 10000 + 629 ),
91 SID_FM_SHOW_FMEXPLORER( 10000 + 633 ),
92 SID_FM_SHOW_PROPERTIES( 10000 + 635 ),
93 SID_FM_FMEXPLORER_CONTROL( 10000 + 637 ),
94 SID_FM_DATEFIELD( 10000 + 704 ),
95 SID_FM_TIMEFIELD( 10000 + 705 ),
96 SID_FM_NUMERICFIELD( 10000 + 706 ),
97 SID_FM_CURRENCYFIELD( 10000 + 707 ),
98 SID_FM_PATTERNFIELD( 10000 + 708 ),
99 SID_FM_OPEN_READONLY( 10000 + 709 ),
100 SID_FM_IMAGECONTROL( 10000 + 710 ),
101 SID_FM_USE_WIZARDS( 10000 + 727 ),
102 SID_FM_FORMATTEDFIELD( 10000 + 728 ),
103 SID_FM_FILTER_NAVIGATOR( 10000 + 732 ),
104 SID_FM_AUTOCONTROLFOCUS( 10000 + 763 ),
105 SID_FM_SCROLLBAR( 10000 + 768 ),
106 SID_FM_SPINBUTTON( 10000 + 769 ),
107 SID_FM_SHOW_DATANAVIGATOR( 10000 + 773 ),
108 SID_FM_DATANAVIGATOR_CONTROL( 10000 + 774 ),
109
110 0
111};
112
113using namespace ::com::sun::star::uno;
114using namespace ::com::sun::star::awt;
115using namespace ::com::sun::star::sdbc;
116using namespace ::com::sun::star::sdbcx;
117using namespace ::com::sun::star::beans;
118using namespace ::com::sun::star::form;
119using namespace ::com::sun::star::form::runtime;
120using namespace ::svxform;
121
122FmDesignModeChangedHint::FmDesignModeChangedHint( bool bDesMode )
123 :m_bDesignMode( bDesMode )
124{
125}
126
127
128FmDesignModeChangedHint::~FmDesignModeChangedHint()
129{
130}
131
132SFX_IMPL_INTERFACE(FmFormShell, SfxShell)SfxInterface* FmFormShell::pInterface = nullptr; SfxInterface
* FmFormShell::GetStaticInterface() { if ( !pInterface ) { pInterface
= new SfxInterface( "FmFormShell", false, GetInterfaceId(), SfxShell
::GetStaticInterface(), aFmFormShellSlots_Impl[0], sal_uInt16
(sizeof(aFmFormShellSlots_Impl) / sizeof(SfxSlot) ) ); InitInterface_Impl
(); } return pInterface; } SfxInterface* FmFormShell::GetInterface
() const { return GetStaticInterface(); } void FmFormShell::RegisterInterface
(const SfxModule* pMod) { GetStaticInterface()->Register(pMod
); }
133
134void FmFormShell::InitInterface_Impl()
135{
136 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_NAVIGATION12, SfxVisibilityFlags::Standard|SfxVisibilityFlags::ReadonlyDoc,
137 ToolbarId::SvxTbx_Form_Navigation,
138 SfxShellFeature::FormShowDatabaseBar);
139
140 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_NAVIGATION12, SfxVisibilityFlags::Standard|SfxVisibilityFlags::ReadonlyDoc,
141 ToolbarId::SvxTbx_Form_Filter,
142 SfxShellFeature::FormShowFilterBar);
143
144 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT1, SfxVisibilityFlags::Standard | SfxVisibilityFlags::ReadonlyDoc,
145 ToolbarId::SvxTbx_Text_Control_Attributes,
146 SfxShellFeature::FormShowTextControlBar);
147
148 GetStaticInterface()->RegisterChildWindow(SID_FM_ADD_FIELD( 10000 + 623 ), false, SfxShellFeature::FormShowField);
149 GetStaticInterface()->RegisterChildWindow(SID_FM_SHOW_PROPERTIES( 10000 + 635 ), false, SfxShellFeature::FormShowProperties);
150 GetStaticInterface()->RegisterChildWindow(SID_FM_SHOW_FMEXPLORER( 10000 + 633 ), false, SfxShellFeature::FormShowExplorer);
151 GetStaticInterface()->RegisterChildWindow(SID_FM_FILTER_NAVIGATOR( 10000 + 732 ), false, SfxShellFeature::FormShowFilterNavigator);
152 GetStaticInterface()->RegisterChildWindow(SID_FM_SHOW_DATANAVIGATOR( 10000 + 773 ), false, SfxShellFeature::FormShowDataNavigator);
153
154 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT1, SfxVisibilityFlags::Standard,
155 ToolbarId::SvxTbx_Controls,
156 SfxShellFeature::FormTBControls);
157
158 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT1, SfxVisibilityFlags::Standard,
159 ToolbarId::SvxTbx_FormDesign,
160 SfxShellFeature::FormTBDesign);
161}
162
163
164FmFormShell::FmFormShell( SfxViewShell* _pParent, FmFormView* pView )
165 :SfxShell(_pParent)
166 ,m_pImpl(new FmXFormShell(*this, _pParent->GetViewFrame()))
167 ,m_pFormView( pView )
168 ,m_pFormModel( nullptr )
169 ,m_nLastSlot( 0 )
170 ,m_bDesignMode( true )
171 ,m_bHasForms(false)
172{
173 SetPool( &SfxGetpApp()->GetPool() );
174 SetName( "Form" );
175
176 SetView(m_pFormView);
177}
178
179
180FmFormShell::~FmFormShell()
181{
182 if ( m_pFormView )
183 SetView( nullptr );
184
185 m_pImpl->dispose();
186}
187
188
189void FmFormShell::NotifyMarkListChanged(FmFormView* pWhichView)
190{
191 FmNavViewMarksChanged aChangeNotification(pWhichView);
192 Broadcast(aChangeNotification);
193}
194
195
196bool FmFormShell::PrepareClose(bool bUI)
197{
198 if (GetImpl()->didPrepareClose_Lock())
199 // we already made a PrepareClose for the current modifications of the current form
200 return true;
201
202 bool bResult = true;
203 // Save the data records, not in DesignMode and FilterMode
204 if (!m_bDesignMode && !GetImpl()->isInFilterMode_Lock() &&
205 m_pFormView && m_pFormView->GetActualOutDev() &&
206 m_pFormView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
207 {
208 SdrPageView* pCurPageView = m_pFormView->GetSdrPageView();
209
210 // sal_uInt16 nPos = pCurPageView ? pCurPageView->GetWinList().Find((OutputDevice*)m_pFormView->GetActualOutDev()) : SDRPAGEVIEWWIN_NOTFOUND;
211 SdrPageWindow* pWindow = pCurPageView ? pCurPageView->FindPageWindow(*const_cast<OutputDevice*>(m_pFormView->GetActualOutDev())) : nullptr;
212
213 if(pWindow)
214 {
215 // First, the current contents of the controls are stored.
216 // If everything has gone smoothly, the modified records are stored.
217 if (GetImpl()->getActiveController_Lock().is())
218 {
219 const svx::ControllerFeatures& rController = GetImpl()->getActiveControllerFeatures_Lock();
220 if ( rController->commitCurrentControl() )
221 {
222 const bool bModified = rController->isModifiedRow();
223
224 if ( bModified && bUI )
225 {
226 SfxViewShell* pShell = GetViewShell();
227 vcl::Window* pShellWnd = pShell ? pShell->GetWindow() : nullptr;
228 weld::Widget* pFrameWeld = pShellWnd ? pShellWnd->GetFrameWeld() : nullptr;
229 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pFrameWeld, "svx/ui/savemodifieddialog.ui"));
230 std::unique_ptr<weld::MessageDialog> xQry(xBuilder->weld_message_dialog("SaveModifiedDialog"));
231 switch (xQry->run())
232 {
233 case RET_YES:
234 bResult = rController->commitCurrentRecord( );
235 [[fallthrough]];
236 case RET_NO:
237 GetImpl()->didPrepareClose_Lock(true);
238 break;
239
240 case RET_CANCEL:
241 return false;
242 }
243 }
244 }
245 }
246 }
247 }
248 return bResult;
249}
250
251
252void FmFormShell::impl_setDesignMode(bool bDesign)
253{
254 if (m_pFormView)
255 {
256 if (!bDesign)
257 m_nLastSlot = SID_FM_DESIGN_MODE( 10000 + 629 );
258
259 GetImpl()->SetDesignMode_Lock(bDesign);
260 // my m_bDesignMode is also set by the Impl ...
261 }
262 else
263 {
264 m_bHasForms = false;
265 m_bDesignMode = bDesign;
266 UIFeatureChanged();
267 }
268
269 GetViewShell()->GetViewFrame()->GetBindings().Invalidate(ControllerSlotMap);
270}
271
272
273bool FmFormShell::HasUIFeature(SfxShellFeature nFeature) const
274{
275 assert((nFeature & ~SfxShellFeature::FormMask) == SfxShellFeature::NONE)(static_cast <bool> ((nFeature & ~SfxShellFeature::
FormMask) == SfxShellFeature::NONE) ? void (0) : __assert_fail
("(nFeature & ~SfxShellFeature::FormMask) == SfxShellFeature::NONE"
, "/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
, 275, __extension__ __PRETTY_FUNCTION__))
;
276 bool bResult = false;
277 if (nFeature & SfxShellFeature::FormShowDatabaseBar)
278 {
279 // only if forms are also available
280 bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && !GetImpl()->isInFilterMode_Lock();
281 }
282 else if (nFeature & SfxShellFeature::FormShowFilterBar)
283 {
284 // only if forms are also available
285 bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && GetImpl()->isInFilterMode_Lock();
286 }
287 else if (nFeature & SfxShellFeature::FormShowFilterNavigator)
288 {
289 bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && GetImpl()->isInFilterMode_Lock();
290 }
291 else if (nFeature & SfxShellFeature::FormShowField)
292 {
293 bResult = m_bDesignMode && m_pFormView && m_bHasForms;
294 }
295 else if (nFeature & SfxShellFeature::FormShowProperties)
296 {
297 bResult = m_bDesignMode && m_pFormView && m_bHasForms;
298 }
299 else if (nFeature & SfxShellFeature::FormShowExplorer)
300 {
301 bResult = m_bDesignMode; // OJ #101593# && m_pFormView && m_bHasForms;
302 }
303 else if (nFeature & SfxShellFeature::FormShowTextControlBar)
304 {
305 bResult = !GetImpl()->IsReadonlyDoc_Lock() && m_pImpl->IsActiveControl_Lock(true);
306 }
307 else if (nFeature & SfxShellFeature::FormShowDataNavigator)
308 {
309 bResult = GetImpl()->isEnhancedForm_Lock();
310 }
311 else if ( (nFeature & SfxShellFeature::FormTBControls)
312 || (nFeature & SfxShellFeature::FormTBDesign)
313 )
314 {
315 bResult = true;
316 }
317
318 return bResult;
319}
320
321
322void FmFormShell::Execute(SfxRequest &rReq)
323{
324 sal_uInt16 nSlot = rReq.GetSlot();
325
326
327 // set MasterSlot
328 switch( nSlot )
1
'Default' branch taken. Execution continues on line 357
329 {
330 case SID_FM_PUSHBUTTON( 10000 + 594 ):
331 case SID_FM_RADIOBUTTON( 10000 + 595 ):
332 case SID_FM_CHECKBOX( 10000 + 596 ):
333 case SID_FM_FIXEDTEXT( 10000 + 597 ):
334 case SID_FM_GROUPBOX( 10000 + 598 ):
335 case SID_FM_LISTBOX( 10000 + 600 ):
336 case SID_FM_COMBOBOX( 10000 + 601 ):
337 case SID_FM_NAVIGATIONBAR( 10000 + 607 ):
338 case SID_FM_EDIT( 10000 + 599 ):
339 case SID_FM_DBGRID( 10000 + 603 ):
340 case SID_FM_IMAGEBUTTON( 10000 + 604 ):
341 case SID_FM_IMAGECONTROL( 10000 + 710 ):
342 case SID_FM_FILECONTROL( 10000 + 605 ):
343 case SID_FM_DATEFIELD( 10000 + 704 ):
344 case SID_FM_TIMEFIELD( 10000 + 705 ):
345 case SID_FM_NUMERICFIELD( 10000 + 706 ):
346 case SID_FM_CURRENCYFIELD( 10000 + 707 ):
347 case SID_FM_PATTERNFIELD( 10000 + 708 ):
348 case SID_FM_FORMATTEDFIELD( 10000 + 728 ):
349 case SID_FM_SCROLLBAR( 10000 + 768 ):
350 case SID_FM_SPINBUTTON( 10000 + 769 ):
351 m_nLastSlot = nSlot;
352 break;
353 }
354
355
356 // set the Identifier and Inventor of the Uno control
357 sal_uInt16 nIdentifier = 0;
358 switch( nSlot )
2
'Default' branch taken. Execution continues on line 425
359 {
360 case SID_FM_CHECKBOX( 10000 + 596 ):
361 nIdentifier = OBJ_FM_CHECKBOX;
362 break;
363 case SID_FM_PUSHBUTTON( 10000 + 594 ):
364 nIdentifier = OBJ_FM_BUTTON;
365 break;
366 case SID_FM_FIXEDTEXT( 10000 + 597 ):
367 nIdentifier = OBJ_FM_FIXEDTEXT;
368 break;
369 case SID_FM_LISTBOX( 10000 + 600 ):
370 nIdentifier = OBJ_FM_LISTBOX;
371 break;
372 case SID_FM_EDIT( 10000 + 599 ):
373 nIdentifier = OBJ_FM_EDIT;
374 break;
375 case SID_FM_RADIOBUTTON( 10000 + 595 ):
376 nIdentifier = OBJ_FM_RADIOBUTTON;
377 break;
378 case SID_FM_GROUPBOX( 10000 + 598 ):
379 nIdentifier = OBJ_FM_GROUPBOX;
380 break;
381 case SID_FM_COMBOBOX( 10000 + 601 ):
382 nIdentifier = OBJ_FM_COMBOBOX;
383 break;
384 case SID_FM_NAVIGATIONBAR( 10000 + 607 ):
385 nIdentifier = OBJ_FM_NAVIGATIONBAR;
386 break;
387 case SID_FM_DBGRID( 10000 + 603 ):
388 nIdentifier = OBJ_FM_GRID;
389 break;
390 case SID_FM_IMAGEBUTTON( 10000 + 604 ):
391 nIdentifier = OBJ_FM_IMAGEBUTTON;
392 break;
393 case SID_FM_IMAGECONTROL( 10000 + 710 ):
394 nIdentifier = OBJ_FM_IMAGECONTROL;
395 break;
396 case SID_FM_FILECONTROL( 10000 + 605 ):
397 nIdentifier = OBJ_FM_FILECONTROL;
398 break;
399 case SID_FM_DATEFIELD( 10000 + 704 ):
400 nIdentifier = OBJ_FM_DATEFIELD;
401 break;
402 case SID_FM_TIMEFIELD( 10000 + 705 ):
403 nIdentifier = OBJ_FM_TIMEFIELD;
404 break;
405 case SID_FM_NUMERICFIELD( 10000 + 706 ):
406 nIdentifier = OBJ_FM_NUMERICFIELD;
407 break;
408 case SID_FM_CURRENCYFIELD( 10000 + 707 ):
409 nIdentifier = OBJ_FM_CURRENCYFIELD;
410 break;
411 case SID_FM_PATTERNFIELD( 10000 + 708 ):
412 nIdentifier = OBJ_FM_PATTERNFIELD;
413 break;
414 case SID_FM_FORMATTEDFIELD( 10000 + 728 ):
415 nIdentifier = OBJ_FM_FORMATTEDFIELD;
416 break;
417 case SID_FM_SCROLLBAR( 10000 + 768 ):
418 nIdentifier = OBJ_FM_SCROLLBAR;
419 break;
420 case SID_FM_SPINBUTTON( 10000 + 769 ):
421 nIdentifier = OBJ_FM_SPINBUTTON;
422 break;
423 }
424
425 switch ( nSlot )
3
'Default' branch taken. Execution continues on line 490
426 {
427 case SID_FM_CHECKBOX( 10000 + 596 ):
428 case SID_FM_PUSHBUTTON( 10000 + 594 ):
429 case SID_FM_FIXEDTEXT( 10000 + 597 ):
430 case SID_FM_LISTBOX( 10000 + 600 ):
431 case SID_FM_EDIT( 10000 + 599 ):
432 case SID_FM_RADIOBUTTON( 10000 + 595 ):
433 case SID_FM_COMBOBOX( 10000 + 601 ):
434 case SID_FM_NAVIGATIONBAR( 10000 + 607 ):
435 case SID_FM_GROUPBOX( 10000 + 598 ):
436 case SID_FM_DBGRID( 10000 + 603 ):
437 case SID_FM_IMAGEBUTTON( 10000 + 604 ):
438 case SID_FM_IMAGECONTROL( 10000 + 710 ):
439 case SID_FM_FILECONTROL( 10000 + 605 ):
440 case SID_FM_DATEFIELD( 10000 + 704 ):
441 case SID_FM_TIMEFIELD( 10000 + 705 ):
442 case SID_FM_NUMERICFIELD( 10000 + 706 ):
443 case SID_FM_CURRENCYFIELD( 10000 + 707 ):
444 case SID_FM_PATTERNFIELD( 10000 + 708 ):
445 case SID_FM_FORMATTEDFIELD( 10000 + 728 ):
446 case SID_FM_SCROLLBAR( 10000 + 768 ):
447 case SID_FM_SPINBUTTON( 10000 + 769 ):
448 {
449 const SfxBoolItem* pGrabFocusItem = rReq.GetArg<SfxBoolItem>(SID_FM_TOGGLECONTROLFOCUS( 10000 + 767 ));
450 if ( pGrabFocusItem && pGrabFocusItem->GetValue() )
451 { // see below
452 SfxViewShell* pShell = GetViewShell();
453 vcl::Window* pShellWnd = pShell ? pShell->GetWindow() : nullptr;
454 if ( pShellWnd )
455 pShellWnd->GrabFocus();
456 break;
457 }
458
459 SfxUInt16Item aIdentifierItem( SID_FM_CONTROL_IDENTIFIER( 10000 + 631 ), nIdentifier );
460 SfxUInt32Item aInventorItem( SID_FM_CONTROL_INVENTOR( 10000 + 632 ), sal_uInt32(SdrInventor::FmForm) );
461 const SfxPoolItem* pArgs[] =
462 {
463 &aIdentifierItem, &aInventorItem, nullptr
464 };
465 const SfxPoolItem* pInternalArgs[] =
466 {
467 nullptr
468 };
469
470 GetViewShell()->GetViewFrame()->GetDispatcher()->Execute( SID_FM_CREATE_CONTROL( 10000 + 628 ), SfxCallMode::ASYNCHRON,
471 pArgs, rReq.GetModifier(), pInternalArgs );
472
473 if ( rReq.GetModifier() & KEY_MOD1 )
474 {
475 // #99013# if selected with control key, return focus to current view
476 // do this asynchron, so that the creation can be finished first
477 // reusing the SID_FM_TOGGLECONTROLFOCUS is somewhat hacky... which it wouldn't if it would have another
478 // name, so I do not really have a big problem with this...
479 SfxBoolItem aGrabFocusIndicatorItem( SID_FM_TOGGLECONTROLFOCUS( 10000 + 767 ), true );
480 GetViewShell()->GetViewFrame()->GetDispatcher()->ExecuteList(
481 nSlot, SfxCallMode::ASYNCHRON,
482 { &aGrabFocusIndicatorItem });
483 }
484
485 rReq.Done();
486 } break;
487 }
488
489 // individual actions
490 switch( nSlot )
4
Control jumps to 'case 10622:' at line 690
491 {
492 case SID_FM_FORM_DESIGN_TOOLS( 10000 + 1046 ):
493 {
494 FormToolboxes aToolboxAccess(GetImpl()->getHostFrame_Lock());
495 aToolboxAccess.toggleToolbox( nSlot );
496 rReq.Done();
497 }
498 break;
499
500 case SID_FM_TOGGLECONTROLFOCUS( 10000 + 767 ):
501 {
502 FmFormView* pFormView = GetFormView();
503 if ( !pFormView )
504 break;
505
506 // if we execute this ourself, then either the application does not implement an own handling for this,
507 // of we're on the top of the dispatcher stack, which means a control has the focus.
508 // In the latter case, we put the focus to the document window, otherwise, we focus the first control
509 const bool bHasControlFocus = GetImpl()->HasControlFocus_Lock();
510 if ( bHasControlFocus )
511 {
512 if (m_pFormView)
513 {
514 const OutputDevice* pDevice = m_pFormView->GetActualOutDev();
515 vcl::Window* pWindow = dynamic_cast< vcl::Window* >( const_cast< OutputDevice* >( pDevice ) );
516 if ( pWindow )
517 pWindow->GrabFocus();
518 }
519 }
520 else
521 {
522 pFormView->GrabFirstControlFocus( );
523 }
524 }
525 break;
526
527 case SID_FM_VIEW_AS_GRID( 10000 + 761 ):
528 GetImpl()->CreateExternalView_Lock();
529 break;
530 case SID_FM_CONVERTTO_EDIT( 10000 + 734 ) :
531 case SID_FM_CONVERTTO_BUTTON( 10000 + 735 ) :
532 case SID_FM_CONVERTTO_FIXEDTEXT( 10000 + 736 ) :
533 case SID_FM_CONVERTTO_LISTBOX( 10000 + 737 ) :
534 case SID_FM_CONVERTTO_CHECKBOX( 10000 + 738 ) :
535 case SID_FM_CONVERTTO_RADIOBUTTON( 10000 + 739 ) :
536 case SID_FM_CONVERTTO_GROUPBOX( 10000 + 740 ) :
537 case SID_FM_CONVERTTO_COMBOBOX( 10000 + 741 ) :
538 case SID_FM_CONVERTTO_IMAGEBUTTON( 10000 + 743 ) :
539 case SID_FM_CONVERTTO_FILECONTROL( 10000 + 744 ) :
540 case SID_FM_CONVERTTO_DATE( 10000 + 745 ) :
541 case SID_FM_CONVERTTO_TIME( 10000 + 746 ) :
542 case SID_FM_CONVERTTO_NUMERIC( 10000 + 747 ) :
543 case SID_FM_CONVERTTO_CURRENCY( 10000 + 748 ) :
544 case SID_FM_CONVERTTO_PATTERN( 10000 + 749 ) :
545 case SID_FM_CONVERTTO_IMAGECONTROL( 10000 + 750 ) :
546 case SID_FM_CONVERTTO_FORMATTED( 10000 + 751 ) :
547 case SID_FM_CONVERTTO_SCROLLBAR( 10000 + 770 ) :
548 case SID_FM_CONVERTTO_SPINBUTTON( 10000 + 771 ) :
549 case SID_FM_CONVERTTO_NAVIGATIONBAR( 10000 + 772 ) :
550 GetImpl()->executeControlConversionSlot_Lock(FmXFormShell::SlotToIdent(nSlot));
551 // after the conversion, re-determine the selection, since the
552 // selected object has changed
553 GetImpl()->SetSelection_Lock(GetFormView()->GetMarkedObjectList());
554 break;
555 case SID_FM_LEAVE_CREATE( 10000 + 726 ):
556 m_nLastSlot = 0;
557 rReq.Done();
558 break;
559 case SID_FM_SHOW_PROPERTY_BROWSER( 10000 + 703 ):
560 {
561 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(SID_FM_SHOW_PROPERTIES( 10000 + 635 ));
562 bool bShow = true;
563 if ( pShowItem )
564 bShow = pShowItem->GetValue();
565 GetImpl()->ShowSelectionProperties_Lock(bShow);
566
567 rReq.Done();
568 } break;
569
570 case SID_FM_PROPERTIES( 10000 + 614 ):
571 {
572 // display the PropertyBrowser
573 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(nSlot);
574 bool bShow = pShowItem == nullptr || pShowItem->GetValue();
575
576 InterfaceBag aOnlyTheForm;
577 aOnlyTheForm.insert(Reference<XInterface>(GetImpl()->getCurrentForm_Lock(), UNO_QUERY));
578 GetImpl()->setCurrentSelection_Lock(aOnlyTheForm);
579
580 GetImpl()->ShowSelectionProperties_Lock(bShow);
581
582 rReq.Done();
583 } break;
584
585 case SID_FM_CTL_PROPERTIES( 10000 + 613 ):
586 {
587 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(nSlot);
588 bool bShow = pShowItem == nullptr || pShowItem->GetValue();
589
590 OSL_ENSURE( GetImpl()->onlyControlsAreMarked_Lock(), "FmFormShell::Execute: ControlProperties should be disabled!" )do { if (true && (!(GetImpl()->onlyControlsAreMarked_Lock
()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "590" ": "), "%s", "FmFormShell::Execute: ControlProperties should be disabled!"
); } } while (false)
;
591 if ( bShow )
592 GetImpl()->selectLastMarkedControls_Lock();
593 GetImpl()->ShowSelectionProperties_Lock(bShow);
594
595 rReq.Done();
596 } break;
597 case SID_FM_SHOW_PROPERTIES( 10000 + 635 ):
598 case SID_FM_ADD_FIELD( 10000 + 623 ):
599 case SID_FM_FILTER_NAVIGATOR( 10000 + 732 ):
600 case SID_FM_SHOW_DATANAVIGATOR( 10000 + 773 ) :
601 {
602 GetViewShell()->GetViewFrame()->ToggleChildWindow(nSlot);
603 rReq.Done();
604 } break;
605 case SID_FM_SHOW_FMEXPLORER( 10000 + 633 ):
606 {
607 if (!m_pFormView) // force setting the view
608 GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_CREATE_SW_DRAWVIEW( 10000 + 860 ));
609
610 GetViewShell()->GetViewFrame()->ChildWindowExecute(rReq);
611 rReq.Done();
612 }
613 break;
614
615 case SID_FM_TAB_DIALOG( 10000 + 615 ):
616 {
617 GetImpl()->ExecuteTabOrderDialog_Lock(
618 Reference<XTabControllerModel>(GetImpl()->getCurrentForm_Lock(), UNO_QUERY));
619 rReq.Done();
620 }
621 break;
622
623 case SID_FM_DESIGN_MODE( 10000 + 629 ):
624 {
625 const SfxBoolItem* pDesignItem = rReq.GetArg<SfxBoolItem>(nSlot);
626 bool bDesignMode = pDesignItem ? pDesignItem->GetValue() : !m_bDesignMode;
627 SetDesignMode( bDesignMode );
628 if ( m_bDesignMode == bDesignMode )
629 rReq.Done();
630
631 m_nLastSlot = SID_FM_DESIGN_MODE( 10000 + 629 );
632 }
633 break;
634
635 case SID_FM_AUTOCONTROLFOCUS( 10000 + 763 ):
636 {
637 FmFormModel* pModel = GetFormModel();
638 DBG_ASSERT(pModel, "FmFormShell::Execute : invalid call !")do { if (true && (!(pModel))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "638" ": "), "%s", "FmFormShell::Execute : invalid call !"
); } } while (false)
;
639 // should have been disabled in GetState if we don't have a FormModel
640 pModel->SetAutoControlFocus( !pModel->GetAutoControlFocus() );
641 GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_AUTOCONTROLFOCUS( 10000 + 763 ));
642 }
643 break;
644 case SID_FM_OPEN_READONLY( 10000 + 709 ):
645 {
646 FmFormModel* pModel = GetFormModel();
647 DBG_ASSERT(pModel, "FmFormShell::Execute : invalid call !")do { if (true && (!(pModel))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "647" ": "), "%s", "FmFormShell::Execute : invalid call !"
); } } while (false)
;
648 // should have been disabled in GetState if we don't have a FormModel
649 pModel->SetOpenInDesignMode( !pModel->GetOpenInDesignMode() );
650 GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_OPEN_READONLY( 10000 + 709 ));
651 }
652 break;
653 case SID_FM_USE_WIZARDS( 10000 + 727 ):
654 {
655 GetImpl()->SetWizardUsing_Lock(!GetImpl()->GetWizardUsing_Lock());
656 GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_USE_WIZARDS( 10000 + 727 ));
657 }
658 break;
659 case SID_FM_SEARCH( 10000 + 725 ):
660 {
661 const svx::ControllerFeatures& rController = GetImpl()->getActiveControllerFeatures_Lock();
662 if ( rController->commitCurrentControl() && rController->commitCurrentRecord() )
663 GetImpl()->ExecuteSearch_Lock();
664 rReq.Done();
665 }
666 break;
667
668 case SID_FM_RECORD_FIRST( 10000 + 616 ):
669 case SID_FM_RECORD_PREV( 10000 + 618 ):
670 case SID_FM_RECORD_NEXT( 10000 + 617 ):
671 case SID_FM_RECORD_LAST( 10000 + 619 ):
672 case SID_FM_RECORD_NEW( 10000 + 620 ):
673 case SID_FM_REFRESH( 10000 + 724 ):
674 case SID_FM_REFRESH_FORM_CONTROL( 10000 + 775 ):
675 case SID_FM_RECORD_DELETE( 10000 + 621 ):
676 case SID_FM_RECORD_UNDO( 10000 + 630 ):
677 case SID_FM_RECORD_SAVE( 10000 + 627 ):
678 case SID_FM_REMOVE_FILTER_SORT( 10000 + 711 ):
679 case SID_FM_SORTDOWN( 10000 + 713 ):
680 case SID_FM_SORTUP( 10000 + 712 ):
681 case SID_FM_AUTOFILTER( 10000 + 716 ):
682 case SID_FM_ORDERCRIT( 10000 + 714 ):
683 case SID_FM_FORM_FILTERED( 10000 + 723 ):
684 {
685 GetImpl()->ExecuteFormSlot_Lock(nSlot);
686 rReq.Done();
687 }
688 break;
689
690 case SID_FM_RECORD_ABSOLUTE( 10000 + 622 ):
691 {
692 const svx::ControllerFeatures& rController = GetImpl()->getNavControllerFeatures_Lock();
693 sal_Int32 nRecord = -1;
694
695 const SfxItemSet* pArgs = rReq.GetArgs();
696 if ( pArgs )
5
Assuming 'pArgs' is null
6
Taking false branch
697 {
698 const SfxPoolItem* pItem;
699 if ( ( pArgs->GetItemState( FN_PARAM_1((20000 + 1100)+60), true, &pItem ) ) == SfxItemState::SET )
700 {
701 const SfxInt32Item* pTypedItem = dynamic_cast<const SfxInt32Item* >( pItem );
702 if ( pTypedItem )
703 nRecord = std::max( pTypedItem->GetValue(), sal_Int32(0) );
704 }
705 }
706 else
707 {
708 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
709 ScopedVclPtr<AbstractFmInputRecordNoDialog> dlg(pFact->CreateFmInputRecordNoDialog(rReq.GetFrameWeld()));
7
Calling constructor for 'ScopedVclPtr<AbstractFmInputRecordNoDialog>'
14
Returning from constructor for 'ScopedVclPtr<AbstractFmInputRecordNoDialog>'
15
Calling implicit destructor for 'VclPtr<AbstractFmInputRecordNoDialog>'
16
Calling '~Reference'
23
Returning from '~Reference'
24
Returning from destructor for 'VclPtr<AbstractFmInputRecordNoDialog>'
710 dlg->SetValue( rController->getCursor()->getRow() );
25
Calling 'VclPtr::operator->'
711 if ( dlg->Execute() == RET_OK )
712 nRecord = dlg->GetValue();
713
714 rReq.AppendItem( SfxInt32Item( FN_PARAM_1((20000 + 1100)+60), nRecord ) );
715 }
716
717 if ( nRecord != -1 )
718 rController->execute( nSlot, "Position", makeAny( nRecord ) );
719
720 rReq.Done();
721 } break;
722 case SID_FM_FILTER_EXECUTE( 10000 + 731 ):
723 case SID_FM_FILTER_EXIT( 10000 + 730 ):
724 {
725 bool bCancelled = ( SID_FM_FILTER_EXIT( 10000 + 730 ) == nSlot );
726 bool bReopenNavigator = false;
727
728 if ( !bCancelled )
729 {
730 // if the filter navigator is still open, we need to close it, so it can possibly
731 // commit it's most recent changes
732 if ( GetViewShell() && GetViewShell()->GetViewFrame() )
733 if ( GetViewShell()->GetViewFrame()->HasChildWindow( SID_FM_FILTER_NAVIGATOR( 10000 + 732 ) ) )
734 {
735 GetViewShell()->GetViewFrame()->ToggleChildWindow( SID_FM_FILTER_NAVIGATOR( 10000 + 732 ) );
736 bReopenNavigator = true;
737 }
738
739 Reference<runtime::XFormController> const xController(GetImpl()->getActiveController_Lock());
740
741 if ( GetViewShell()->GetViewFrame()->HasChildWindow( SID_FM_FILTER_NAVIGATOR( 10000 + 732 ) )
742 // closing the window was denied, for instance because of an invalid criterion
743
744 || ( xController.is()
745 && !GetImpl()->getActiveControllerFeatures_Lock()->commitCurrentControl()
746 )
747 // committing the controller was denied
748 )
749 {
750 rReq.Done();
751 break;
752 }
753 }
754
755 GetImpl()->stopFiltering_Lock(!bCancelled);
756 rReq.Done();
757
758 if ( bReopenNavigator )
759 // we closed the navigator only to implicitly commit it (as we do not have another
760 // direct wire to it), but to the user, it should look as it was always open
761 GetViewShell()->GetViewFrame()->ToggleChildWindow( SID_FM_FILTER_NAVIGATOR( 10000 + 732 ) );
762 }
763 break;
764
765 case SID_FM_FILTER_START( 10000 + 729 ):
766 {
767 GetImpl()->startFiltering_Lock();
768 rReq.Done();
769
770 // initially open the filter navigator, the whole form based filter is pretty useless without it
771 SfxBoolItem aIdentifierItem( SID_FM_FILTER_NAVIGATOR( 10000 + 732 ), true );
772 GetViewShell()->GetViewFrame()->GetDispatcher()->ExecuteList(
773 SID_FM_FILTER_NAVIGATOR( 10000 + 732 ), SfxCallMode::ASYNCHRON,
774 { &aIdentifierItem });
775 } break;
776 }
777}
778
779
780void FmFormShell::GetState(SfxItemSet &rSet)
781{
782 SfxWhichIter aIter( rSet );
783 sal_uInt16 nWhich = aIter.FirstWhich();
784 while ( nWhich )
785 {
786 switch( nWhich )
787 {
788 case SID_FM_FORM_DESIGN_TOOLS( 10000 + 1046 ):
789 {
790 FormToolboxes aToolboxAccess(GetImpl()->getHostFrame_Lock());
791 rSet.Put( SfxBoolItem( nWhich, aToolboxAccess.isToolboxVisible( nWhich ) ) );
792 }
793 break;
794
795 case SID_FM_FILTER_EXECUTE( 10000 + 731 ):
796 case SID_FM_FILTER_EXIT( 10000 + 730 ):
797 if (!GetImpl()->isInFilterMode_Lock())
798 rSet.DisableItem( nWhich );
799 break;
800
801 case SID_FM_USE_WIZARDS( 10000 + 727 ):
802 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
803 rSet.Put( SfxVisibilityItem( nWhich, false ) );
804 else if (!GetFormModel())
805 rSet.DisableItem( nWhich );
806 else
807 rSet.Put(SfxBoolItem(nWhich, GetImpl()->GetWizardUsing_Lock()));
808 break;
809 case SID_FM_AUTOCONTROLFOCUS( 10000 + 763 ):
810 if (!GetFormModel())
811 rSet.DisableItem( nWhich );
812 else
813 rSet.Put( SfxBoolItem(nWhich, GetFormModel()->GetAutoControlFocus() ) );
814 break;
815 case SID_FM_OPEN_READONLY( 10000 + 709 ):
816 if (!GetFormModel())
817 rSet.DisableItem( nWhich );
818 else
819 rSet.Put( SfxBoolItem(nWhich, GetFormModel()->GetOpenInDesignMode() ) );
820 break;
821
822 case SID_FM_NAVIGATIONBAR( 10000 + 607 ):
823 case SID_FM_DBGRID( 10000 + 603 ):
824 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
825 {
826 rSet.Put( SfxVisibilityItem( nWhich, false ) );
827 break;
828 }
829 [[fallthrough]];
830
831 case SID_FM_SCROLLBAR( 10000 + 768 ):
832 case SID_FM_IMAGECONTROL( 10000 + 710 ):
833 case SID_FM_FILECONTROL( 10000 + 605 ):
834 case SID_FM_CURRENCYFIELD( 10000 + 707 ):
835 case SID_FM_PATTERNFIELD( 10000 + 708 ):
836 case SID_FM_IMAGEBUTTON( 10000 + 604 ):
837 case SID_FM_RADIOBUTTON( 10000 + 595 ):
838 case SID_FM_COMBOBOX( 10000 + 601 ):
839 case SID_FM_GROUPBOX( 10000 + 598 ):
840 case SID_FM_CHECKBOX( 10000 + 596 ):
841 case SID_FM_PUSHBUTTON( 10000 + 594 ):
842 case SID_FM_FIXEDTEXT( 10000 + 597 ):
843 case SID_FM_LISTBOX( 10000 + 600 ):
844 case SID_FM_EDIT( 10000 + 599 ):
845 case SID_FM_DATEFIELD( 10000 + 704 ):
846 case SID_FM_TIMEFIELD( 10000 + 705 ):
847 case SID_FM_NUMERICFIELD( 10000 + 706 ):
848 case SID_FM_FORMATTEDFIELD( 10000 + 728 ):
849 case SID_FM_SPINBUTTON( 10000 + 769 ):
850 if (!m_bDesignMode)
851 rSet.DisableItem( nWhich );
852 else
853 {
854 bool bLayerLocked = false;
855 if (m_pFormView)
856 {
857 // If the css::drawing::Layer is locked, the slots must be disabled. #36897
858 SdrPageView* pPV = m_pFormView->GetSdrPageView();
859 if (pPV != nullptr)
860 bLayerLocked = pPV->IsLayerLocked(m_pFormView->GetActiveLayer());
861 }
862 if (bLayerLocked)
863 rSet.DisableItem( nWhich );
864 else
865 rSet.Put( SfxBoolItem(nWhich, (nWhich==m_nLastSlot)) );
866 }
867 break;
868 case SID_FM_FILTER_NAVIGATOR_CONTROL( 10000 + 752 ):
869 {
870 if (GetImpl()->isInFilterMode_Lock())
871 rSet.Put(SfxObjectItem(nWhich, this));
872 else
873 rSet.Put(SfxObjectItem(nWhich));
874 } break;
875 case SID_FM_FIELDS_CONTROL( 10000 + 634 ):
876 case SID_FM_PROPERTY_CONTROL( 10000 + 636 ):
877 {
878 if (!m_bDesignMode || !m_pFormView || !m_bHasForms)
879 rSet.Put(SfxObjectItem(nWhich));
880 else
881 rSet.Put(SfxObjectItem(nWhich, this));
882
883 } break;
884 case SID_FM_FMEXPLORER_CONTROL( 10000 + 637 ):
885 case SID_FM_DATANAVIGATOR_CONTROL( 10000 + 774 ) :
886 {
887 if (!m_bDesignMode || !m_pFormView)
888 rSet.Put(SfxObjectItem(nWhich));
889 else
890 rSet.Put(SfxObjectItem(nWhich, this));
891
892 } break;
893 case SID_FM_ADD_FIELD( 10000 + 623 ):
894 case SID_FM_SHOW_FMEXPLORER( 10000 + 633 ):
895 case SID_FM_SHOW_PROPERTIES( 10000 + 635 ):
896 case SID_FM_FILTER_NAVIGATOR( 10000 + 732 ):
897 case SID_FM_SHOW_DATANAVIGATOR( 10000 + 773 ):
898 {
899 if ( GetViewShell()->GetViewFrame()->KnowsChildWindow(nWhich) )
900 rSet.Put( SfxBoolItem( nWhich, GetViewShell()->GetViewFrame()->HasChildWindow(nWhich)) );
901 else
902 rSet.DisableItem(nWhich);
903 } break;
904
905 case SID_FM_SHOW_PROPERTY_BROWSER( 10000 + 703 ):
906 {
907 rSet.Put(SfxBoolItem(nWhich, GetImpl()->IsPropBrwOpen_Lock()));
908 }
909 break;
910
911 case SID_FM_CTL_PROPERTIES( 10000 + 613 ):
912 {
913 // potentially, give the Impl the opportunity to update its
914 // current objects which are aligned with the current MarkList
915 if (GetImpl()->IsSelectionUpdatePending_Lock())
916 GetImpl()->ForceUpdateSelection_Lock();
917
918 if (!m_pFormView || !m_bDesignMode || !GetImpl()->onlyControlsAreMarked_Lock())
919 rSet.DisableItem( nWhich );
920 else
921 {
922 bool const bChecked = GetImpl()->IsPropBrwOpen_Lock() && !GetImpl()->isSolelySelected_Lock(GetImpl()->getCurrentForm_Lock());
923 // if the property browser is open, and only controls are marked, and the current selection
924 // does not consist of only the current form, then the current selection is the (composition of)
925 // the currently marked controls
926 rSet.Put( SfxBoolItem( nWhich, bChecked ) );
927 }
928 } break;
929
930 case SID_FM_PROPERTIES( 10000 + 614 ):
931 {
932 // potentially, give the Impl the opportunity to update its
933 // current objects which are aligned with the current MarkList
934 if (GetImpl()->IsSelectionUpdatePending_Lock())
935 GetImpl()->ForceUpdateSelection_Lock();
936
937 if (!m_pFormView || !m_bDesignMode || !GetImpl()->getCurrentForm_Lock().is())
938 rSet.DisableItem( nWhich );
939 else
940 {
941 bool const bChecked = GetImpl()->IsPropBrwOpen_Lock() && GetImpl()->isSolelySelected_Lock(GetImpl()->getCurrentForm_Lock());
942 rSet.Put(SfxBoolItem(nWhich, bChecked));
943 }
944 } break;
945 case SID_FM_TAB_DIALOG( 10000 + 615 ):
946 // potentially, give the Impl the opportunity to update its
947 // current objects which are aligned with the current MarkList
948 if (GetImpl()->IsSelectionUpdatePending_Lock())
949 GetImpl()->ForceUpdateSelection_Lock();
950
951 if (!m_pFormView || !m_bDesignMode || !GetImpl()->getCurrentForm_Lock().is() )
952 rSet.DisableItem( nWhich );
953 break;
954 case SID_FM_DESIGN_MODE( 10000 + 629 ):
955 if (!m_pFormView || GetImpl()->IsReadonlyDoc_Lock())
956 rSet.DisableItem( nWhich );
957 else
958 rSet.Put( SfxBoolItem(nWhich, m_bDesignMode) );
959 break;
960 case SID_FM_SEARCH( 10000 + 725 ):
961 case SID_FM_RECORD_FIRST( 10000 + 616 ):
962 case SID_FM_RECORD_NEXT( 10000 + 617 ):
963 case SID_FM_RECORD_PREV( 10000 + 618 ):
964 case SID_FM_RECORD_LAST( 10000 + 619 ):
965 case SID_FM_RECORD_NEW( 10000 + 620 ):
966 case SID_FM_RECORD_DELETE( 10000 + 621 ):
967 case SID_FM_RECORD_ABSOLUTE( 10000 + 622 ):
968 case SID_FM_RECORD_TOTAL( 10000 + 626 ):
969 case SID_FM_RECORD_SAVE( 10000 + 627 ):
970 case SID_FM_RECORD_UNDO( 10000 + 630 ):
971 case SID_FM_FORM_FILTERED( 10000 + 723 ):
972 case SID_FM_REMOVE_FILTER_SORT( 10000 + 711 ):
973 case SID_FM_SORTUP( 10000 + 712 ):
974 case SID_FM_SORTDOWN( 10000 + 713 ):
975 case SID_FM_ORDERCRIT( 10000 + 714 ):
976 case SID_FM_FILTER_START( 10000 + 729 ):
977 case SID_FM_AUTOFILTER( 10000 + 716 ):
978 case SID_FM_REFRESH( 10000 + 724 ):
979 case SID_FM_REFRESH_FORM_CONTROL( 10000 + 775 ):
980 case SID_FM_VIEW_AS_GRID( 10000 + 761 ):
981 GetFormState(rSet,nWhich);
982 break;
983
984 case SID_FM_CHANGECONTROLTYPE( 10000 + 733 ):
985 {
986 if ( !m_pFormView || !m_bDesignMode )
987 rSet.DisableItem( nWhich );
988 else
989 {
990 if (!GetImpl()->canConvertCurrentSelectionToControl_Lock("ConvertToFixed"))
991 // if it cannot be converted to a fixed text, it is no single control
992 rSet.DisableItem( nWhich );
993 }
994 } break;
995
996 case SID_FM_CONVERTTO_FILECONTROL( 10000 + 744 ) :
997 case SID_FM_CONVERTTO_CURRENCY( 10000 + 748 ) :
998 case SID_FM_CONVERTTO_PATTERN( 10000 + 749 ) :
999 case SID_FM_CONVERTTO_IMAGECONTROL( 10000 + 750 ) :
1000 case SID_FM_CONVERTTO_SCROLLBAR( 10000 + 770 ) :
1001 case SID_FM_CONVERTTO_NAVIGATIONBAR( 10000 + 772 ) :
1002 case SID_FM_CONVERTTO_IMAGEBUTTON( 10000 + 743 ) :
1003 case SID_FM_CONVERTTO_EDIT( 10000 + 734 ) :
1004 case SID_FM_CONVERTTO_BUTTON( 10000 + 735 ) :
1005 case SID_FM_CONVERTTO_FIXEDTEXT( 10000 + 736 ) :
1006 case SID_FM_CONVERTTO_LISTBOX( 10000 + 737 ) :
1007 case SID_FM_CONVERTTO_CHECKBOX( 10000 + 738 ) :
1008 case SID_FM_CONVERTTO_RADIOBUTTON( 10000 + 739 ) :
1009 case SID_FM_CONVERTTO_GROUPBOX( 10000 + 740 ) :
1010 case SID_FM_CONVERTTO_COMBOBOX( 10000 + 741 ) :
1011 case SID_FM_CONVERTTO_DATE( 10000 + 745 ) :
1012 case SID_FM_CONVERTTO_TIME( 10000 + 746 ) :
1013 case SID_FM_CONVERTTO_NUMERIC( 10000 + 747 ) :
1014 case SID_FM_CONVERTTO_FORMATTED( 10000 + 751 ) :
1015 case SID_FM_CONVERTTO_SPINBUTTON( 10000 + 771 ) :
1016 {
1017 if (!m_pFormView || !m_bDesignMode || !GetImpl()->canConvertCurrentSelectionToControl_Lock(FmXFormShell::SlotToIdent(nWhich)))
1018 rSet.DisableItem( nWhich );
1019 else
1020 {
1021 rSet.Put( SfxBoolItem( nWhich, false ) );
1022 // just to have a defined state (available and not checked)
1023 }
1024 }
1025 break;
1026 }
1027 nWhich = aIter.NextWhich();
1028 }
1029}
1030
1031
1032void FmFormShell::GetFormState(SfxItemSet &rSet, sal_uInt16 nWhich)
1033{
1034 if ( !GetImpl()->getNavController_Lock().is()
1035 || !isRowSetAlive(GetImpl()->getNavController_Lock()->getModel())
1036 || !m_pFormView
1037 || m_bDesignMode
1038 || !GetImpl()->getActiveForm_Lock().is()
1039 || GetImpl()->isInFilterMode_Lock()
1040 )
1041 rSet.DisableItem(nWhich);
1042 else
1043 {
1044 bool bEnable = false;
1045 try
1046 {
1047 switch (nWhich)
1048 {
1049 case SID_FM_VIEW_AS_GRID( 10000 + 761 ):
1050 if (GetImpl()->getHostFrame_Lock().is() && GetImpl()->getNavController_Lock().is())
1051 {
1052 bEnable = true;
1053 bool bDisplayingCurrent =
1054 GetImpl()->getInternalForm_Lock(
1055 Reference<XForm>(GetImpl()->getNavController_Lock()->getModel(), UNO_QUERY)
1056 ) == GetImpl()->getExternallyDisplayedForm_Lock();
1057 rSet.Put(SfxBoolItem(nWhich, bDisplayingCurrent));
1058 }
1059 break;
1060
1061 case SID_FM_SEARCH( 10000 + 725 ):
1062 {
1063 Reference<css::beans::XPropertySet> const xNavSet(GetImpl()->getActiveForm_Lock(), UNO_QUERY);
1064 sal_Int32 nCount = ::comphelper::getINT32(xNavSet->getPropertyValue(FM_PROP_ROWCOUNT"RowCount"));
1065 bEnable = nCount != 0;
1066 } break;
1067 case SID_FM_RECORD_ABSOLUTE( 10000 + 622 ):
1068 case SID_FM_RECORD_TOTAL( 10000 + 626 ):
1069 {
1070 FeatureState aState;
1071 GetImpl()->getNavControllerFeatures_Lock()->getState( nWhich, aState );
1072 if ( SID_FM_RECORD_ABSOLUTE( 10000 + 622 ) == nWhich )
1073 {
1074 sal_Int32 nPosition = 0;
1075 aState.State >>= nPosition;
1076 rSet.Put( SfxInt32Item( nWhich, nPosition ) );
1077 }
1078 else if ( SID_FM_RECORD_TOTAL( 10000 + 626 ) == nWhich )
1079 {
1080 OUString sTotalCount;
1081 aState.State >>= sTotalCount;
1082 rSet.Put( SfxStringItem( nWhich, sTotalCount ) );
1083 }
1084 bEnable = aState.Enabled;
1085 }
1086 break;
1087
1088 // first, prev, next, last, and absolute affect the nav controller, not the
1089 // active controller
1090 case SID_FM_RECORD_FIRST( 10000 + 616 ):
1091 case SID_FM_RECORD_PREV( 10000 + 618 ):
1092 case SID_FM_RECORD_NEXT( 10000 + 617 ):
1093 case SID_FM_RECORD_LAST( 10000 + 619 ):
1094 case SID_FM_RECORD_NEW( 10000 + 620 ):
1095 case SID_FM_RECORD_SAVE( 10000 + 627 ):
1096 case SID_FM_RECORD_UNDO( 10000 + 630 ):
1097 case SID_FM_RECORD_DELETE( 10000 + 621 ):
1098 case SID_FM_REFRESH( 10000 + 724 ):
1099 case SID_FM_REFRESH_FORM_CONTROL( 10000 + 775 ):
1100 case SID_FM_REMOVE_FILTER_SORT( 10000 + 711 ):
1101 case SID_FM_SORTUP( 10000 + 712 ):
1102 case SID_FM_SORTDOWN( 10000 + 713 ):
1103 case SID_FM_AUTOFILTER( 10000 + 716 ):
1104 case SID_FM_ORDERCRIT( 10000 + 714 ):
1105 bEnable = GetImpl()->IsFormSlotEnabled( nWhich, nullptr );
1106 break;
1107
1108 case SID_FM_FORM_FILTERED( 10000 + 723 ):
1109 {
1110 FeatureState aState;
1111 bEnable = GetImpl()->IsFormSlotEnabled( nWhich, &aState );
1112
1113 rSet.Put( SfxBoolItem( nWhich, ::comphelper::getBOOL( aState.State ) ) );
1114 }
1115 break;
1116
1117 case SID_FM_FILTER_START( 10000 + 729 ):
1118 bEnable = GetImpl()->getActiveControllerFeatures_Lock()->canDoFormFilter();
1119 break;
1120 }
1121 }
1122 catch( const Exception& )
1123 {
1124 TOOLS_WARN_EXCEPTION("svx.form", "caught an exception while determining the state!")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() << "caught an exception while determining the state!"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"svx.form"), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "1124" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "caught an exception while determining the state!"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "caught an exception while determining the state!" <<
" " << exceptionToString(tools_warn_exception); ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.form"), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "1124" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "caught an exception while determining the state!"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"svx.form"), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "1124" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "caught an exception while determining the state!"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "caught an exception while determining the state!" <<
" " << exceptionToString(tools_warn_exception); ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.form"), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "1124" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1125 }
1126 if (!bEnable)
1127 rSet.DisableItem(nWhich);
1128 }
1129}
1130
1131
1132FmFormPage* FmFormShell::GetCurPage() const
1133{
1134 FmFormPage* pP = nullptr;
1135 if (m_pFormView && m_pFormView->GetSdrPageView())
1136 pP = dynamic_cast<FmFormPage*>( m_pFormView->GetSdrPageView()->GetPage() );
1137 return pP;
1138}
1139
1140
1141void FmFormShell::SetView( FmFormView* _pView )
1142{
1143 if ( m_pFormView )
1144 {
1145 if ( IsActive() )
1146 GetImpl()->viewDeactivated_Lock(*m_pFormView);
1147
1148 m_pFormView->SetFormShell( nullptr, FmFormView::FormShellAccess() );
1149 m_pFormView = nullptr;
1150 m_pFormModel = nullptr;
1151 }
1152
1153 if ( !_pView )
1154 return;
1155
1156 m_pFormView = _pView;
1157 m_pFormView->SetFormShell( this, FmFormView::FormShellAccess() );
1158 m_pFormModel = static_cast<FmFormModel*>(m_pFormView->GetModel());
1159
1160 impl_setDesignMode( m_pFormView->IsDesignMode() );
1161
1162 // We activate our view if we are activated ourself, but sometimes the Activate precedes the SetView.
1163 // But here we know both the view and our activation state so we at least are able to pass the latter
1164 // to the former.
1165 // FS - 30.06.99 - 67308
1166 if ( IsActive() )
1167 GetImpl()->viewActivated_Lock(*m_pFormView);
1168}
1169
1170
1171void FmFormShell::DetermineForms(bool bInvalidate)
1172{
1173 // are there forms on the current page
1174 bool bForms = GetImpl()->hasForms_Lock();
1175 if (bForms != m_bHasForms)
1176 {
1177 m_bHasForms = bForms;
1178 if (bInvalidate)
1179 UIFeatureChanged();
1180 }
1181}
1182
1183
1184bool FmFormShell::GetY2KState(sal_uInt16& nReturn)
1185{
1186 return GetImpl()->GetY2KState_Lock(nReturn);
1187}
1188
1189
1190void FmFormShell::SetY2KState(sal_uInt16 n)
1191{
1192 GetImpl()->SetY2KState_Lock(n);
1193}
1194
1195
1196void FmFormShell::Activate(bool bMDI)
1197{
1198 SfxShell::Activate(bMDI);
1199
1200 if ( m_pFormView )
1201 GetImpl()->viewActivated_Lock(*m_pFormView, true);
1202}
1203
1204
1205void FmFormShell::Deactivate(bool bMDI)
1206{
1207 SfxShell::Deactivate(bMDI);
1208
1209 if ( m_pFormView )
1210 GetImpl()->viewDeactivated_Lock(*m_pFormView, false);
1211}
1212
1213
1214void FmFormShell::ExecuteTextAttribute( SfxRequest& _rReq )
1215{
1216 m_pImpl->ExecuteTextAttribute_Lock(_rReq);
1217}
1218
1219
1220void FmFormShell::GetTextAttributeState( SfxItemSet& _rSet )
1221{
1222 m_pImpl->GetTextAttributeState_Lock(_rSet);
1223}
1224
1225
1226bool FmFormShell::IsActiveControl() const
1227{
1228 return m_pImpl->IsActiveControl_Lock(false);
1229}
1230
1231
1232void FmFormShell::ForgetActiveControl()
1233{
1234 m_pImpl->ForgetActiveControl_Lock();
1235}
1236
1237
1238void FmFormShell::SetControlActivationHandler( const Link<LinkParamNone*,void>& _rHdl )
1239{
1240 m_pImpl->SetControlActivationHandler_Lock(_rHdl);
1241}
1242
1243
1244namespace
1245{
1246 SdrUnoObj* lcl_findUnoObject( const SdrObjList& _rObjList, const Reference< XControlModel >& _rxModel )
1247 {
1248 SdrObjListIter aIter( &_rObjList );
1249 while ( aIter.IsMore() )
1250 {
1251 SdrObject* pObject = aIter.Next();
1252 SdrUnoObj* pUnoObject = dynamic_cast<SdrUnoObj*>( pObject );
1253 if ( !pUnoObject )
1254 continue;
1255
1256 Reference< XControlModel > xControlModel = pUnoObject->GetUnoControlModel();
1257 if ( !xControlModel.is() )
1258 continue;
1259
1260 if ( _rxModel == xControlModel )
1261 return pUnoObject;
1262 }
1263 return nullptr;
1264 }
1265}
1266
1267
1268void FmFormShell::ToggleControlFocus( const SdrUnoObj& i_rUnoObject, const SdrView& i_rView, OutputDevice& i_rDevice ) const
1269{
1270 try
1271 {
1272 // check if the focus currently is in a control
1273 // Well, okay, do it the other way 'round: Check whether the current control of the active controller
1274 // actually has the focus. This should be equivalent.
1275 const bool bHasControlFocus = GetImpl()->HasControlFocus_Lock();
1276
1277 if ( bHasControlFocus )
1278 {
1279 vcl::Window* pWindow( dynamic_cast< vcl::Window* >( &i_rDevice ) );
1280 OSL_ENSURE( pWindow, "FmFormShell::ToggleControlFocus: I need a Window, really!" )do { if (true && (!(pWindow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "1280" ": "), "%s", "FmFormShell::ToggleControlFocus: I need a Window, really!"
); } } while (false)
;
1281 if ( pWindow )
1282 pWindow->GrabFocus();
1283 }
1284 else
1285 {
1286 Reference< XControl > xControl;
1287 GetFormControl( i_rUnoObject.GetUnoControlModel(), i_rView, i_rDevice, xControl );
1288 Reference< XWindow > xControlWindow( xControl, UNO_QUERY );
1289 if ( xControlWindow.is() )
1290 xControlWindow->setFocus();
1291 }
1292 }
1293 catch( const Exception& )
1294 {
1295 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "1295" ": ", "svx" );
;
1296 }
1297}
1298
1299
1300namespace
1301{
1302 class FocusableControlsFilter : public svx::ISdrObjectFilter
1303 {
1304 public:
1305 FocusableControlsFilter( const SdrView& i_rView, const OutputDevice& i_rDevice )
1306 :m_rView( i_rView )
1307 ,m_rDevice( i_rDevice )
1308 {
1309 }
1310
1311 public:
1312 virtual bool includeObject( const SdrObject& i_rObject ) const override
1313 {
1314 const SdrUnoObj* pUnoObj = dynamic_cast< const SdrUnoObj* >( &i_rObject );
1315 if ( !pUnoObj )
1316 return false;
1317
1318 Reference< XControl > xControl = pUnoObj->GetUnoControl( m_rView, m_rDevice );
1319 return FmXFormView::isFocusable( xControl );
1320 }
1321
1322 private:
1323 const SdrView& m_rView;
1324 const OutputDevice& m_rDevice;
1325 };
1326}
1327
1328
1329::std::unique_ptr< svx::ISdrObjectFilter > FmFormShell::CreateFocusableControlFilter( const SdrView& i_rView, const OutputDevice& i_rDevice )
1330{
1331 ::std::unique_ptr< svx::ISdrObjectFilter > pFilter;
1332
1333 if ( !i_rView.IsDesignMode() )
1334 pFilter.reset( new FocusableControlsFilter( i_rView, i_rDevice ) );
1335
1336 return pFilter;
1337}
1338
1339
1340SdrUnoObj* FmFormShell::GetFormControl( const Reference< XControlModel >& _rxModel, const SdrView& _rView, const OutputDevice& _rDevice, Reference< XControl >& _out_rxControl ) const
1341{
1342 if ( !_rxModel.is() )
1343 return nullptr;
1344
1345 // we can only retrieve controls for SdrObjects which belong to page which is actually displayed in the given view
1346 SdrPageView* pPageView = _rView.GetSdrPageView();
1347 SdrPage* pPage = pPageView ? pPageView->GetPage() : nullptr;
1348 OSL_ENSURE( pPage, "FmFormShell::GetFormControl: no page displayed in the given view!" )do { if (true && (!(pPage))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "1348" ": "), "%s", "FmFormShell::GetFormControl: no page displayed in the given view!"
); } } while (false)
;
1349 if ( !pPage )
1350 return nullptr;
1351
1352 SdrUnoObj* pUnoObject = lcl_findUnoObject( *pPage, _rxModel );
1353 if ( pUnoObject )
1354 {
1355 _out_rxControl = pUnoObject->GetUnoControl( _rView, _rDevice );
1356 return pUnoObject;
1357 }
1358
1359#if OSL_DEBUG_LEVEL1 > 0
1360 // perhaps we are fed with a control model which lives on a page other than the one displayed
1361 // in the given view. This is worth being reported as error, in non-product builds.
1362 FmFormModel* pModel = GetFormModel();
1363 if ( pModel )
1364 {
1365 sal_uInt16 pageCount = pModel->GetPageCount();
1366 for ( sal_uInt16 page = 0; page < pageCount; ++page )
1367 {
1368 pPage = pModel->GetPage( page );
1369 OSL_ENSURE( pPage, "FmFormShell::GetFormControl: NULL page encountered!" )do { if (true && (!(pPage))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "1369" ": "), "%s", "FmFormShell::GetFormControl: NULL page encountered!"
); } } while (false)
;
1370 if ( !pPage )
1371 continue;
1372
1373 pUnoObject = lcl_findUnoObject( *pPage, _rxModel );
1374 OSL_ENSURE( !pUnoObject, "FmFormShell::GetFormControl: the given control model belongs to a wrong page (displayed elsewhere)!" )do { if (true && (!(!pUnoObject))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/form/fmshell.cxx"
":" "1374" ": "), "%s", "FmFormShell::GetFormControl: the given control model belongs to a wrong page (displayed elsewhere)!"
); } } while (false)
;
1375 }
1376 }
1377#else
1378 (void) this; // avoid loplugin:staticmethods
1379#endif
1380
1381 return nullptr;
1382}
1383
1384
1385Reference< runtime::XFormController > FmFormShell::GetFormController( const Reference< XForm >& _rxForm, const SdrView& _rView, const OutputDevice& _rDevice )
1386{
1387 const FmFormView* pFormView = dynamic_cast< const FmFormView* >( &_rView );
1388 if ( !pFormView )
1389 return nullptr;
1390
1391 return pFormView->GetFormController( _rxForm, _rDevice );
1392}
1393
1394
1395void FmFormShell::SetDesignMode( bool _bDesignMode )
1396{
1397 if ( _bDesignMode == m_bDesignMode )
1398 return;
1399
1400 FmFormModel* pModel = GetFormModel();
1401 if (pModel)
1402 // Switch off the undo environment for the time of the transition. This ensures that
1403 // one can also change non-transient properties there. (It should be done with
1404 // caution, however, and it should always be reversed when one switches the mode back.
1405 // An example is the setting of the maximum text length by the OEditModel on its control.)
1406 pModel->GetUndoEnv().Lock();
1407
1408 // then the actual switch
1409 if ( m_bDesignMode || PrepareClose() )
1410 impl_setDesignMode(!m_bDesignMode );
1411
1412 // and my undo environment back on
1413 if ( pModel )
1414 pModel->GetUndoEnv().UnLock();
1415}
1416
1417/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
26
Calling 'Reference::get'
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
8
Calling implicit copy constructor for 'VclPtr<AbstractFmInputRecordNoDialog>'
9
Calling copy constructor for 'Reference<AbstractFmInputRecordNoDialog>'
12
Returning from copy constructor for 'Reference<AbstractFmInputRecordNoDialog>'
13
Returning from copy constructor for 'VclPtr<AbstractFmInputRecordNoDialog>'
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
10
Assuming field 'm_pBody' is non-null
11
Taking true branch
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
16.1
Field 'm_pBody' is non-null
16.1
Field 'm_pBody' is non-null
16.1
Field 'm_pBody' is non-null
16.1
Field 'm_pBody' is non-null
)
17
Taking true branch
113 m_pBody->release();
18
Calling 'VclReferenceBase::release'
22
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
27
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
19
Assuming the condition is true
20
Taking true branch
40 delete this;
21
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif