Bug Summary

File:home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx
Warning:line 1379, column 32
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 bindings.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 SFX2_DLLIMPLEMENTATION -D ENABLE_CUPS -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sfx2/inc -I /home/maarten/src/libreoffice/core/sfx2/source/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sfx2/sdi -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 -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/sfx2/source/control/bindings.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 <iomanip>
23
24#include <sal/log.hxx>
25#include <svl/itempool.hxx>
26#include <svl/itemiter.hxx>
27#include <svl/eitem.hxx>
28#include <svl/intitem.hxx>
29#include <svl/stritem.hxx>
30#include <vcl/svapp.hxx>
31#include <vcl/timer.hxx>
32#include <com/sun/star/frame/XDispatch.hpp>
33#include <com/sun/star/frame/XDispatchProvider.hpp>
34#include <com/sun/star/frame/DispatchResultState.hpp>
35#include <itemdel.hxx>
36
37//Includes below due to nInReschedule
38#include <sfx2/bindings.hxx>
39#include <sfx2/msg.hxx>
40#include <statcach.hxx>
41#include <sfx2/ctrlitem.hxx>
42#include <sfx2/app.hxx>
43#include <sfx2/dispatch.hxx>
44#include <sfx2/module.hxx>
45#include <sfx2/request.hxx>
46#include <workwin.hxx>
47#include <unoctitm.hxx>
48#include <sfx2/viewfrm.hxx>
49#include <sfx2/objsh.hxx>
50#include <sfx2/msgpool.hxx>
51
52#include <cstddef>
53#include <memory>
54#include <unordered_map>
55#include <utility>
56#include <vector>
57
58using namespace ::com::sun::star;
59using namespace ::com::sun::star::uno;
60using namespace ::com::sun::star::util;
61
62#define TIMEOUT_FIRST300 300
63#define TIMEOUT_UPDATING20 20
64
65struct SfxFoundCache_Impl
66{
67 sal_uInt16 nWhichId; // If available: Which-Id, else: nSlotId
68 const SfxSlot* pSlot; // Pointer to <Master-Slot>
69 SfxStateCache& rCache; // Pointer to StatusCache
70
71 SfxFoundCache_Impl(sal_uInt16 nW, const SfxSlot *pS, SfxStateCache& rC)
72 : nWhichId(nW)
73 , pSlot(pS)
74 , rCache(rC)
75 {}
76};
77
78class SfxFoundCacheArr_Impl
79{
80 typedef std::vector<std::unique_ptr<SfxFoundCache_Impl> > DataType;
81 DataType maData;
82
83public:
84
85 SfxFoundCache_Impl& operator[] ( size_t i )
86 {
87 return *maData[i];
88 }
89
90 size_t size() const
91 {
92 return maData.size();
93 }
94
95 void push_back( SfxFoundCache_Impl* p )
96 {
97 maData.push_back(std::unique_ptr<SfxFoundCache_Impl>(p));
98 }
99};
100
101class SfxBindings_Impl
102{
103public:
104 css::uno::Reference< css::frame::XDispatchRecorder > xRecorder;
105 css::uno::Reference< css::frame::XDispatchProvider > xProv;
106 std::unique_ptr<SfxWorkWindow> mxWorkWin;
107 SfxBindings* pSubBindings;
108 std::vector<std::unique_ptr<SfxStateCache>> pCaches; // One cache for each binding
109 std::size_t nCachedFunc1; // index for the last one called
110 std::size_t nCachedFunc2; // index for the second last called
111 std::size_t nMsgPos; // Message-Position relative the one to be updated
112 bool bContextChanged;
113 bool bMsgDirty; // Has a MessageServer been invalidated?
114 bool bAllMsgDirty; // Has a MessageServer been invalidated?
115 bool bAllDirty; // After InvalidateAll
116 bool bCtrlReleased; // while EnterRegistrations
117 AutoTimer aAutoTimer; // for volatile Slots
118 bool bInUpdate; // for Assertions
119 bool bInNextJob; // for Assertions
120 bool bFirstRound; // First round in Update
121 sal_uInt16 nOwnRegLevel; // Counts the real Locks, except those of the Super Bindings
122 std::unordered_map< sal_uInt16, bool >
123 m_aInvalidateSlots; // store slots which are invalidated while in update
124};
125
126SfxBindings::SfxBindings()
127: pImpl(new SfxBindings_Impl),
128 pDispatcher(nullptr),
129 nRegLevel(1) // first becomes 0, when the Dispatcher is set
130
131{
132 pImpl->nMsgPos = 0;
133 pImpl->bAllMsgDirty = true;
134 pImpl->bContextChanged = false;
135 pImpl->bMsgDirty = true;
136 pImpl->bAllDirty = true;
137 pImpl->nCachedFunc1 = 0;
138 pImpl->nCachedFunc2 = 0;
139 pImpl->bCtrlReleased = false;
140 pImpl->bFirstRound = false;
141 pImpl->bInNextJob = false;
142 pImpl->bInUpdate = false;
143 pImpl->pSubBindings = nullptr;
144 pImpl->nOwnRegLevel = nRegLevel;
145
146 // all caches are valid (no pending invalidate-job)
147 // create the list of caches
148 pImpl->aAutoTimer.SetInvokeHandler( LINK(this, SfxBindings, NextJob)::tools::detail::makeLink( ::tools::detail::castTo<SfxBindings
*>(this), &SfxBindings::LinkStubNextJob)
);
149 pImpl->aAutoTimer.SetDebugName( "sfx::SfxBindings aAutoTimer" );
150}
151
152
153SfxBindings::~SfxBindings()
154
155/* [Description]
156
157 Destructor of the SfxBindings class. The one, for each <SfxApplication>
158 existing Instance is automatically destroyed by the <SfxApplication>
159 after the execution of <SfxApplication::Exit()>.
160
161 The still existing <SfxControllerItem> instances, which are registered
162 by the SfxBindings instance, are automatically destroyed in the Destructor.
163 These are usually the Floating-Toolboxen, Value-Sets
164 etc. Arrays of SfxControllerItems may at this time no longer exist.
165*/
166
167{
168 // The SubBindings should not be locked!
169 pImpl->pSubBindings = nullptr;
170
171 ENTERREGISTRATIONS()EnterRegistrations();
172
173 pImpl->aAutoTimer.Stop();
174 DeleteControllers_Impl();
175
176 // Delete Caches
177 pImpl->pCaches.clear();
178
179 pImpl->mxWorkWin.reset();
180}
181
182
183void SfxBindings::DeleteControllers_Impl()
184{
185 // in the first round delete Controllers
186 std::size_t nCount = pImpl->pCaches.size();
187 std::size_t nCache;
188 for ( nCache = 0; nCache < nCount; ++nCache )
189 {
190 // Remember were you are
191 SfxStateCache *pCache = pImpl->pCaches[nCache].get();
192 sal_uInt16 nSlotId = pCache->GetId();
193
194 // Re-align, because the cache may have been reduced
195 std::size_t nNewCount = pImpl->pCaches.size();
196 if ( nNewCount < nCount )
197 {
198 nCache = GetSlotPos(nSlotId);
199 if ( nCache >= nNewCount ||
200 nSlotId != pImpl->pCaches[nCache]->GetId() )
201 --nCache;
202 nCount = nNewCount;
203 }
204 }
205
206 // Delete all Caches
207 for ( nCache = pImpl->pCaches.size(); nCache > 0; --nCache )
208 {
209 // Get Cache via css::sdbcx::Index
210 SfxStateCache *pCache = pImpl->pCaches[ nCache-1 ].get();
211
212 // unbind all controllers in the cache
213 SfxControllerItem *pNext;
214 for ( SfxControllerItem *pCtrl = pCache->GetItemLink();
215 pCtrl; pCtrl = pNext )
216 {
217 pNext = pCtrl->GetItemLink();
218 pCtrl->UnBind();
219 }
220
221 if ( pCache->GetInternalController() )
222 pCache->GetInternalController()->UnBind();
223
224 // Delete Cache
225 pImpl->pCaches.erase(pImpl->pCaches.begin() + nCache - 1);
226 }
227}
228
229
230void SfxBindings::HidePopups( bool bHide )
231{
232 // Hide SfxChildWindows
233 DBG_ASSERT( pDispatcher, "HidePopups not allowed without dispatcher" )do { if (true && (!(pDispatcher))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "233" ": "), "%s", "HidePopups not allowed without dispatcher"
); } } while (false)
;
234 if ( pImpl->mxWorkWin )
235 pImpl->mxWorkWin->HidePopups_Impl( bHide );
236}
237
238void SfxBindings::Update_Impl(SfxStateCache& rCache /*The up to date SfxStatusCache*/)
239{
240 if (rCache.GetDispatch().is() && rCache.GetItemLink())
241 {
242 rCache.SetCachedState(true);
243 if (!rCache.GetInternalController())
244 return;
245 }
246
247 if ( !pDispatcher )
248 return;
249
250 // gather together all with the same status method which are dirty
251 SfxDispatcher &rDispat = *pDispatcher;
252 const SfxSlot *pRealSlot = nullptr;
253 const SfxSlotServer* pMsgServer = nullptr;
254 SfxFoundCacheArr_Impl aFound;
255 std::unique_ptr<SfxItemSet> pSet = CreateSet_Impl(rCache, pRealSlot, &pMsgServer, aFound);
256 bool bUpdated = false;
257 if ( pSet )
258 {
259 // Query Status
260 if ( rDispat.FillState_( *pMsgServer, *pSet, pRealSlot ) )
261 {
262 // Post Status
263 for ( size_t nPos = 0; nPos < aFound.size(); ++nPos )
264 {
265 const SfxFoundCache_Impl& rFound = aFound[nPos];
266 sal_uInt16 nWhich = rFound.nWhichId;
267 const SfxPoolItem *pItem = nullptr;
268 SfxItemState eState = pSet->GetItemState(nWhich, true, &pItem);
269 if ( eState == SfxItemState::DEFAULT && SfxItemPool::IsWhich(nWhich) )
270 pItem = &pSet->Get(nWhich);
271 UpdateControllers_Impl( rFound, pItem, eState );
272 }
273 bUpdated = true;
274 }
275
276 pSet.reset();
277 }
278
279 if (!bUpdated)
280 {
281 SfxFoundCache_Impl aFoundCache(0, pRealSlot, rCache);
282 UpdateControllers_Impl( aFoundCache, nullptr, SfxItemState::DISABLED);
283 }
284}
285
286void SfxBindings::InvalidateSlotsInMap_Impl()
287{
288 for (auto const& slot : pImpl->m_aInvalidateSlots)
289 Invalidate( slot.first );
290
291 pImpl->m_aInvalidateSlots.clear();
292}
293
294
295void SfxBindings::AddSlotToInvalidateSlotsMap_Impl( sal_uInt16 nId )
296{
297 pImpl->m_aInvalidateSlots[nId] = true;
298}
299
300
301void SfxBindings::Update
302(
303 sal_uInt16 nId // the bound and up-to-date Slot-Id
304)
305{
306 if ( pDispatcher )
307 pDispatcher->Flush();
308
309 if ( pImpl->pSubBindings )
310 pImpl->pSubBindings->Update( nId );
311
312 SfxStateCache* pCache = GetStateCache( nId );
313 if ( !pCache )
314 return;
315
316 pImpl->bInUpdate = true;
317 if ( pImpl->bMsgDirty )
318 {
319 UpdateSlotServer_Impl();
320 pCache = GetStateCache( nId );
321 }
322
323 if (pCache)
324 {
325 bool bInternalUpdate = true;
326 if( pCache->GetDispatch().is() && pCache->GetItemLink() )
327 {
328 pCache->SetCachedState(true);
329 bInternalUpdate = ( pCache->GetInternalController() != nullptr );
330 }
331
332 if ( bInternalUpdate )
333 {
334 // Query Status
335 const SfxSlotServer* pMsgServer = pDispatcher ? pCache->GetSlotServer(*pDispatcher, pImpl->xProv) : nullptr;
336 if ( !pCache->IsControllerDirty() )
337 {
338 pImpl->bInUpdate = false;
339 InvalidateSlotsInMap_Impl();
340 return;
341 }
342 if (!pMsgServer)
343 {
344 pCache->SetState(SfxItemState::DISABLED, nullptr);
345 pImpl->bInUpdate = false;
346 InvalidateSlotsInMap_Impl();
347 return;
348 }
349
350 Update_Impl(*pCache);
351 }
352
353 pImpl->bAllDirty = false;
354 }
355
356 pImpl->bInUpdate = false;
357 InvalidateSlotsInMap_Impl();
358}
359
360
361void SfxBindings::Update()
362{
363 if ( pImpl->pSubBindings )
364 pImpl->pSubBindings->Update();
365
366 if ( !pDispatcher )
367 return;
368
369 if ( nRegLevel )
370 return;
371
372 pImpl->bInUpdate = true;
373 pDispatcher->Flush();
374 pDispatcher->Update_Impl();
375 while ( !NextJob_Impl(nullptr) )
376 ; // loop
377 pImpl->bInUpdate = false;
378 InvalidateSlotsInMap_Impl();
379}
380
381
382void SfxBindings::SetState
383(
384 const SfxItemSet& rSet // status values to be set
385)
386{
387 // when locked then only invalidate
388 if ( nRegLevel )
389 {
390 SfxItemIter aIter(rSet);
391 for ( const SfxPoolItem *pItem = aIter.GetCurItem();
392 pItem;
393 pItem = aIter.NextItem() )
394 Invalidate( pItem->Which() );
395 }
396 else
397 {
398 // Status may be accepted only if all slot-pointers are set
399 if ( pImpl->bMsgDirty )
400 UpdateSlotServer_Impl();
401
402 // Iterate over the itemset, update if the slot bound
403 //! Bug: Use WhichIter and possibly send VoidItems up
404 SfxItemIter aIter(rSet);
405 for ( const SfxPoolItem *pItem = aIter.GetCurItem();
406 pItem;
407 pItem = aIter.NextItem() )
408 {
409 SfxStateCache* pCache =
410 GetStateCache( rSet.GetPool()->GetSlotId(pItem->Which()) );
411 if ( pCache )
412 {
413 // Update status
414 if ( !pCache->IsControllerDirty() )
415 pCache->Invalidate(false);
416 pCache->SetState( SfxItemState::DEFAULT, pItem );
417
418 //! Not implemented: Updates from EnumSlots via master slots
419 }
420 }
421 }
422}
423
424
425void SfxBindings::SetState
426(
427 const SfxPoolItem& rItem // Status value to be set
428)
429{
430 if ( nRegLevel )
431 {
432 Invalidate( rItem.Which() );
433 }
434 else
435 {
436 // Status may be accepted only if all slot-pointers are set
437 if ( pImpl->bMsgDirty )
438 UpdateSlotServer_Impl();
439
440 //update if the slot bound
441 DBG_ASSERT( SfxItemPool::IsSlot( rItem.Which() ),do { if (true && (!(SfxItemPool::IsSlot( rItem.Which(
) )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "442" ": "), "%s", "cannot set items with which-id"); } }
while (false)
442 "cannot set items with which-id" )do { if (true && (!(SfxItemPool::IsSlot( rItem.Which(
) )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "442" ": "), "%s", "cannot set items with which-id"); } }
while (false)
;
443 SfxStateCache* pCache = GetStateCache( rItem.Which() );
444 if ( pCache )
445 {
446 // Update Status
447 if ( !pCache->IsControllerDirty() )
448 pCache->Invalidate(false);
449 pCache->SetState( SfxItemState::DEFAULT, &rItem );
450
451 //! Not implemented: Updates from EnumSlots via master slots
452 }
453 }
454}
455
456
457SfxStateCache* SfxBindings::GetAnyStateCache_Impl( sal_uInt16 nId )
458{
459 SfxStateCache* pCache = GetStateCache( nId );
460 if ( !pCache && pImpl->pSubBindings )
461 return pImpl->pSubBindings->GetAnyStateCache_Impl( nId );
462 return pCache;
463}
464
465SfxStateCache* SfxBindings::GetStateCache
466(
467 sal_uInt16 nId /* Slot-Id, which SfxStatusCache is to be found */
468)
469{
470 return GetStateCache(nId, nullptr);
471}
472
473SfxStateCache* SfxBindings::GetStateCache
474(
475 sal_uInt16 nId, /* Slot-Id, which SfxStatusCache is to be found */
476 std::size_t * pPos /* NULL for instance the position from which the
477 bindings are to be searched binary. Returns the
478 position back for where the nId was found,
479 or where it was inserted. */
480)
481{
482 // is the specified function bound?
483 const std::size_t nStart = ( pPos ? *pPos : 0 );
484 const std::size_t nPos = GetSlotPos( nId, nStart );
485
486 if ( nPos < pImpl->pCaches.size() &&
487 pImpl->pCaches[nPos]->GetId() == nId )
488 {
489 if ( pPos )
490 *pPos = nPos;
491 return pImpl->pCaches[nPos].get();
492 }
493 return nullptr;
494}
495
496
497void SfxBindings::InvalidateAll
498(
499 bool bWithMsg /* true Mark Slot Server as invalid
500 false Slot Server remains valid */
501)
502{
503 DBG_ASSERT( !pImpl->bInUpdate, "SfxBindings::Invalidate while in update" )do { if (true && (!(!pImpl->bInUpdate))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "503" ": "), "%s", "SfxBindings::Invalidate while in update"
); } } while (false)
;
504
505 if ( pImpl->pSubBindings )
506 pImpl->pSubBindings->InvalidateAll( bWithMsg );
507
508 // everything is already set dirty or downing => nothing to do
509 if ( !pDispatcher ||
510 ( pImpl->bAllDirty && ( !bWithMsg || pImpl->bAllMsgDirty ) ) ||
511 SfxGetpApp()->IsDowning() )
512 {
513 return;
514 }
515
516 pImpl->bAllMsgDirty = pImpl->bAllMsgDirty || bWithMsg;
517 pImpl->bMsgDirty = pImpl->bMsgDirty || pImpl->bAllMsgDirty || bWithMsg;
518 pImpl->bAllDirty = true;
519
520 for (std::unique_ptr<SfxStateCache>& pCache : pImpl->pCaches)
521 pCache->Invalidate(bWithMsg);
522
523 pImpl->nMsgPos = 0;
524 if ( !nRegLevel )
525 {
526 pImpl->aAutoTimer.Stop();
527 pImpl->aAutoTimer.SetTimeout(TIMEOUT_FIRST300);
528 pImpl->aAutoTimer.Start();
529 }
530}
531
532
533void SfxBindings::Invalidate
534(
535 const sal_uInt16* pIds /* numerically sorted NULL-terminated array of
536 slot IDs (individual, not as a couple!) */
537)
538{
539 if ( pImpl->bInUpdate )
540 {
541 sal_Int32 i = 0;
542 while ( pIds[i] != 0 )
543 AddSlotToInvalidateSlotsMap_Impl( pIds[i++] );
544
545 if ( pImpl->pSubBindings )
546 pImpl->pSubBindings->Invalidate( pIds );
547 return;
548 }
549
550 if ( pImpl->pSubBindings )
551 pImpl->pSubBindings->Invalidate( pIds );
552
553 // everything is already set dirty or downing => nothing to do
554 if ( !pDispatcher || pImpl->bAllDirty || SfxGetpApp()->IsDowning() )
555 return;
556
557 // Search binary in always smaller areas
558 for ( std::size_t n = GetSlotPos(*pIds);
559 *pIds && n < pImpl->pCaches.size();
560 n = GetSlotPos(*pIds, n) )
561 {
562 // If SID is ever bound, then invalidate the cache
563 SfxStateCache *pCache = pImpl->pCaches[n].get();
564 if ( pCache->GetId() == *pIds )
565 pCache->Invalidate(false);
566
567 // Next SID
568 if ( !*++pIds )
569 break;
570 assert( *pIds > *(pIds-1) )(static_cast <bool> (*pIds > *(pIds-1)) ? void (0) :
__assert_fail ("*pIds > *(pIds-1)", "/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
, 570, __extension__ __PRETTY_FUNCTION__))
;
571 }
572
573 // if not enticed to start update timer
574 pImpl->nMsgPos = 0;
575 if ( !nRegLevel )
576 {
577 pImpl->aAutoTimer.Stop();
578 pImpl->aAutoTimer.SetTimeout(TIMEOUT_FIRST300);
579 pImpl->aAutoTimer.Start();
580 }
581}
582
583
584void SfxBindings::InvalidateShell
585(
586 const SfxShell& rSh, /* <SfxShell> whose Slot-Ids should be
587 invalidated */
588 bool bDeep /* true
589 also the SfxShell's inherited slot IDs are invalidated
590
591 false
592 the inherited and not overridden Slot-Ids are
593 invalidated */
594 // for now always bDeep
595)
596{
597 DBG_ASSERT( !pImpl->bInUpdate, "SfxBindings::Invalidate while in update" )do { if (true && (!(!pImpl->bInUpdate))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "597" ": "), "%s", "SfxBindings::Invalidate while in update"
); } } while (false)
;
598
599 if ( pImpl->pSubBindings )
600 pImpl->pSubBindings->InvalidateShell( rSh, bDeep );
601
602 if ( !pDispatcher || pImpl->bAllDirty || SfxGetpApp()->IsDowning() )
603 return;
604
605 // flush now already, it is done in GetShellLevel (rsh) anyway,
606 // important so that is set correctly: pImpl-> ball(Msg)Dirty
607 pDispatcher->Flush();
608
609 if ((pImpl->bAllDirty && pImpl->bAllMsgDirty) || SfxGetpApp()->IsDowning())
610 {
611 // if the next one is anyway, then all the servers are collected
612 return;
613 }
614
615 // Find Level
616 sal_uInt16 nLevel = pDispatcher->GetShellLevel(rSh);
617 if ( nLevel == USHRT_MAX(32767 *2 +1) )
618 return;
619
620 for (std::unique_ptr<SfxStateCache>& pCache : pImpl->pCaches)
621 {
622 const SfxSlotServer *pMsgServer =
623 pCache->GetSlotServer(*pDispatcher, pImpl->xProv);
624 if ( pMsgServer && pMsgServer->GetShellLevel() == nLevel )
625 pCache->Invalidate(false);
626 }
627 pImpl->nMsgPos = 0;
628 if ( !nRegLevel )
629 {
630 pImpl->aAutoTimer.Stop();
631 pImpl->aAutoTimer.SetTimeout(TIMEOUT_FIRST300);
632 pImpl->aAutoTimer.Start();
633 pImpl->bFirstRound = true;
634 }
635}
636
637
638void SfxBindings::Invalidate
639(
640 sal_uInt16 nId // Status value to be set
641)
642{
643 if ( pImpl->bInUpdate )
644 {
645 AddSlotToInvalidateSlotsMap_Impl( nId );
646 if ( pImpl->pSubBindings )
647 pImpl->pSubBindings->Invalidate( nId );
648 return;
649 }
650
651 if ( pImpl->pSubBindings )
652 pImpl->pSubBindings->Invalidate( nId );
653
654 if ( !pDispatcher || pImpl->bAllDirty || SfxGetpApp()->IsDowning() )
655 return;
656
657 SfxStateCache* pCache = GetStateCache(nId);
658 if ( pCache )
659 {
660 pCache->Invalidate(false);
661 pImpl->nMsgPos = std::min(GetSlotPos(nId), pImpl->nMsgPos);
662 if ( !nRegLevel )
663 {
664 pImpl->aAutoTimer.Stop();
665 pImpl->aAutoTimer.SetTimeout(TIMEOUT_FIRST300);
666 pImpl->aAutoTimer.Start();
667 }
668 }
669}
670
671
672void SfxBindings::Invalidate
673(
674 sal_uInt16 nId, // Status value to be set
675 bool bWithItem, // Clear StateCache?
676 bool bWithMsg // Get new SlotServer?
677)
678{
679 DBG_ASSERT( !pImpl->bInUpdate, "SfxBindings::Invalidate while in update" )do { if (true && (!(!pImpl->bInUpdate))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "679" ": "), "%s", "SfxBindings::Invalidate while in update"
); } } while (false)
;
680
681 if ( pImpl->pSubBindings )
682 pImpl->pSubBindings->Invalidate( nId, bWithItem, bWithMsg );
683
684 if ( SfxGetpApp()->IsDowning() )
685 return;
686
687 SfxStateCache* pCache = GetStateCache(nId);
688 if ( !pCache )
689 return;
690
691 if ( bWithItem )
692 pCache->ClearCache();
693 pCache->Invalidate(bWithMsg);
694
695 if ( !pDispatcher || pImpl->bAllDirty )
696 return;
697
698 pImpl->nMsgPos = std::min(GetSlotPos(nId), pImpl->nMsgPos);
699 if ( !nRegLevel )
700 {
701 pImpl->aAutoTimer.Stop();
702 pImpl->aAutoTimer.SetTimeout(TIMEOUT_FIRST300);
703 pImpl->aAutoTimer.Start();
704 }
705}
706
707
708std::size_t SfxBindings::GetSlotPos( sal_uInt16 nId, std::size_t nStartSearchAt )
709{
710 // answer immediately if a function-seek comes repeated
711 if ( pImpl->nCachedFunc1 < pImpl->pCaches.size() &&
712 pImpl->pCaches[pImpl->nCachedFunc1]->GetId() == nId )
713 {
714 return pImpl->nCachedFunc1;
715 }
716 if ( pImpl->nCachedFunc2 < pImpl->pCaches.size() &&
717 pImpl->pCaches[pImpl->nCachedFunc2]->GetId() == nId )
718 {
719 // swap the caches
720 std::swap(pImpl->nCachedFunc1, pImpl->nCachedFunc2);
721 return pImpl->nCachedFunc1;
722 }
723
724 // binary search, if not found, seek to target-position
725 if ( pImpl->pCaches.size() <= nStartSearchAt )
726 {
727 return 0;
728 }
729 if ( pImpl->pCaches.size() == (nStartSearchAt+1) )
730 {
731 return pImpl->pCaches[nStartSearchAt]->GetId() >= nId ? 0 : 1;
732 }
733 std::size_t nLow = nStartSearchAt;
734 std::size_t nMid = 0;
735 std::size_t nHigh = 0;
736 bool bFound = false;
737 nHigh = pImpl->pCaches.size() - 1;
738 while ( !bFound && nLow <= nHigh )
739 {
740 nMid = (nLow + nHigh) >> 1;
741 DBG_ASSERT( nMid < pImpl->pCaches.size(), "bsearch is buggy" )do { if (true && (!(nMid < pImpl->pCaches.size(
)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "741" ": "), "%s", "bsearch is buggy"); } } while (false
)
;
742 int nDiff = static_cast<int>(nId) - static_cast<int>( (pImpl->pCaches[nMid])->GetId() );
743 if ( nDiff < 0)
744 { if ( nMid == 0 )
745 break;
746 nHigh = nMid - 1;
747 }
748 else if ( nDiff > 0 )
749 { nLow = nMid + 1;
750 if ( nLow == 0 )
751 break;
752 }
753 else
754 bFound = true;
755 }
756 std::size_t nPos = bFound ? nMid : nLow;
757 DBG_ASSERT( nPos <= pImpl->pCaches.size(), "" )do { if (true && (!(nPos <= pImpl->pCaches.size
()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "757" ": "), "%s", ""); } } while (false)
;
758 DBG_ASSERT( nPos == pImpl->pCaches.size() ||do { if (true && (!(nPos == pImpl->pCaches.size() ||
nId <= pImpl->pCaches[nPos]->GetId()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "759" ": "), "%s", ""); } } while (false)
759 nId <= pImpl->pCaches[nPos]->GetId(), "" )do { if (true && (!(nPos == pImpl->pCaches.size() ||
nId <= pImpl->pCaches[nPos]->GetId()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "759" ": "), "%s", ""); } } while (false)
;
760 DBG_ASSERT( nPos == nStartSearchAt ||do { if (true && (!(nPos == nStartSearchAt || nId >
pImpl->pCaches[nPos-1]->GetId()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "761" ": "), "%s", ""); } } while (false)
761 nId > pImpl->pCaches[nPos-1]->GetId(), "" )do { if (true && (!(nPos == nStartSearchAt || nId >
pImpl->pCaches[nPos-1]->GetId()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "761" ": "), "%s", ""); } } while (false)
;
762 DBG_ASSERT( ( (nPos+1) >= pImpl->pCaches.size() ) ||do { if (true && (!(( (nPos+1) >= pImpl->pCaches
.size() ) || nId < pImpl->pCaches[nPos+1]->GetId()))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "763" ": "), "%s", ""); } } while (false)
763 nId < pImpl->pCaches[nPos+1]->GetId(), "" )do { if (true && (!(( (nPos+1) >= pImpl->pCaches
.size() ) || nId < pImpl->pCaches[nPos+1]->GetId()))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "763" ": "), "%s", ""); } } while (false)
;
764 pImpl->nCachedFunc2 = pImpl->nCachedFunc1;
765 pImpl->nCachedFunc1 = nPos;
766 return nPos;
767}
768
769void SfxBindings::RegisterInternal_Impl( SfxControllerItem& rItem )
770{
771 Register_Impl( rItem, true );
772
773}
774
775void SfxBindings::Register( SfxControllerItem& rItem )
776{
777 Register_Impl( rItem, false );
778}
779
780void SfxBindings::Register_Impl( SfxControllerItem& rItem, bool bInternal )
781{
782// DBG_ASSERT( nRegLevel > 0, "registration without EnterRegistrations" );
783 DBG_ASSERT( !pImpl->bInNextJob, "SfxBindings::Register while status-updating" )do { if (true && (!(!pImpl->bInNextJob))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "783" ": "), "%s", "SfxBindings::Register while status-updating"
); } } while (false)
;
784
785 // insert new cache if it does not already exist
786 sal_uInt16 nId = rItem.GetId();
787 std::size_t nPos = GetSlotPos(nId);
788 if ( nPos >= pImpl->pCaches.size() ||
789 pImpl->pCaches[nPos]->GetId() != nId )
790 {
791 pImpl->pCaches.insert( pImpl->pCaches.begin() + nPos, std::make_unique<SfxStateCache>(nId) );
792 DBG_ASSERT( nPos == 0 ||do { if (true && (!(nPos == 0 || pImpl->pCaches[nPos
]->GetId() > pImpl->pCaches[nPos-1]->GetId()))) {
sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "794" ": "), "%s", ""); } } while (false)
793 pImpl->pCaches[nPos]->GetId() >do { if (true && (!(nPos == 0 || pImpl->pCaches[nPos
]->GetId() > pImpl->pCaches[nPos-1]->GetId()))) {
sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "794" ": "), "%s", ""); } } while (false)
794 pImpl->pCaches[nPos-1]->GetId(), "" )do { if (true && (!(nPos == 0 || pImpl->pCaches[nPos
]->GetId() > pImpl->pCaches[nPos-1]->GetId()))) {
sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "794" ": "), "%s", ""); } } while (false)
;
795 DBG_ASSERT( (nPos == pImpl->pCaches.size()-1) ||do { if (true && (!((nPos == pImpl->pCaches.size()
-1) || pImpl->pCaches[nPos]->GetId() < pImpl->pCaches
[nPos+1]->GetId()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "797" ": "), "%s", ""); } } while (false)
796 pImpl->pCaches[nPos]->GetId() <do { if (true && (!((nPos == pImpl->pCaches.size()
-1) || pImpl->pCaches[nPos]->GetId() < pImpl->pCaches
[nPos+1]->GetId()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "797" ": "), "%s", ""); } } while (false)
797 pImpl->pCaches[nPos+1]->GetId(), "" )do { if (true && (!((nPos == pImpl->pCaches.size()
-1) || pImpl->pCaches[nPos]->GetId() < pImpl->pCaches
[nPos+1]->GetId()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "797" ": "), "%s", ""); } } while (false)
;
798 pImpl->bMsgDirty = true;
799 }
800
801 // enqueue the new binding
802 if ( bInternal )
803 {
804 pImpl->pCaches[nPos]->SetInternalController( &rItem );
805 }
806 else
807 {
808 SfxControllerItem *pOldItem = pImpl->pCaches[nPos]->ChangeItemLink(&rItem);
809 rItem.ChangeItemLink(pOldItem);
810 }
811}
812
813
814void SfxBindings::Release( SfxControllerItem& rItem )
815{
816 DBG_ASSERT( !pImpl->bInNextJob, "SfxBindings::Release while status-updating" )do { if (true && (!(!pImpl->bInNextJob))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "816" ": "), "%s", "SfxBindings::Release while status-updating"
); } } while (false)
;
817 ENTERREGISTRATIONS()EnterRegistrations();
818
819 // find the bound function
820 sal_uInt16 nId = rItem.GetId();
821 std::size_t nPos = GetSlotPos(nId);
822 SfxStateCache* pCache = (nPos < pImpl->pCaches.size()) ? pImpl->pCaches[nPos].get() : nullptr;
823 if ( pCache && pCache->GetId() == nId )
824 {
825 if ( pCache->GetInternalController() == &rItem )
826 {
827 pCache->ReleaseInternalController();
828 }
829 else
830 {
831 // is this the first binding in the list?
832 SfxControllerItem* pItem = pCache->GetItemLink();
833 if ( pItem == &rItem )
834 pCache->ChangeItemLink( rItem.GetItemLink() );
835 else
836 {
837 // search the binding in the list
838 while ( pItem && pItem->GetItemLink() != &rItem )
839 pItem = pItem->GetItemLink();
840
841 // unlink it if it was found
842 if ( pItem )
843 pItem->ChangeItemLink( rItem.GetItemLink() );
844 }
845 }
846
847 // was this the last controller?
848 if ( pCache->GetItemLink() == nullptr && !pCache->GetInternalController() )
849 {
850 pImpl->bCtrlReleased = true;
851 }
852 }
853
854 LEAVEREGISTRATIONS()LeaveRegistrations();
855}
856
857
858const SfxPoolItem* SfxBindings::ExecuteSynchron( sal_uInt16 nId, const SfxPoolItem** ppItems )
859{
860 if( !nId || !pDispatcher )
861 return nullptr;
862
863 return Execute_Impl( nId, ppItems, 0, SfxCallMode::SYNCHRON, nullptr );
864}
865
866bool SfxBindings::Execute( sal_uInt16 nId, const SfxPoolItem** ppItems, SfxCallMode nCallMode )
867{
868 if( !nId || !pDispatcher )
869 return false;
870
871 const SfxPoolItem* pRet = Execute_Impl( nId, ppItems, 0, nCallMode, nullptr );
872 return ( pRet != nullptr );
873}
874
875const SfxPoolItem* SfxBindings::Execute_Impl( sal_uInt16 nId, const SfxPoolItem** ppItems, sal_uInt16 nModi, SfxCallMode nCallMode,
876 const SfxPoolItem **ppInternalArgs, bool bGlobalOnly )
877{
878 SfxStateCache *pCache = GetStateCache( nId );
879 if ( !pCache )
880 {
881 SfxBindings *pBind = pImpl->pSubBindings;
882 while ( pBind )
883 {
884 if ( pBind->GetStateCache( nId ) )
885 return pBind->Execute_Impl( nId, ppItems, nModi, nCallMode, ppInternalArgs, bGlobalOnly );
886 pBind = pBind->pImpl->pSubBindings;
887 }
888 }
889
890 SfxDispatcher &rDispatcher = *pDispatcher;
891 rDispatcher.Flush();
892
893 // get SlotServer (Slot+ShellLevel) and Shell from cache
894 std::unique_ptr<SfxStateCache> xCache;
895 if ( !pCache )
896 {
897 // Execution of non cached slots (Accelerators don't use Controllers)
898 // slot is uncached, use SlotCache to handle external dispatch providers
899 xCache.reset(new SfxStateCache(nId));
900 pCache = xCache.get();
901 pCache->GetSlotServer( rDispatcher, pImpl->xProv );
902 }
903
904 if ( pCache->GetDispatch().is() )
905 {
906 DBG_ASSERT( !ppInternalArgs, "Internal args get lost when dispatched!" )do { if (true && (!(!ppInternalArgs))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "906" ": "), "%s", "Internal args get lost when dispatched!"
); } } while (false)
;
907
908 SfxItemPool &rPool = GetDispatcher()->GetFrame()->GetObjectShell()->GetPool();
909 SfxRequest aReq( nId, nCallMode, rPool );
910 aReq.SetModifier( nModi );
911 if( ppItems )
912 while( *ppItems )
913 aReq.AppendItem( **ppItems++ );
914
915 // cache binds to an external dispatch provider
916 sal_Int16 eRet = pCache->Dispatch( aReq.GetArgs(), nCallMode == SfxCallMode::SYNCHRON );
917 std::unique_ptr<SfxPoolItem> pPool;
918 if ( eRet == css::frame::DispatchResultState::DONTKNOW )
919 pPool.reset( new SfxVoidItem( nId ) );
920 else
921 pPool.reset( new SfxBoolItem( nId, eRet == css::frame::DispatchResultState::SUCCESS) );
922
923 auto pTemp = pPool.get();
924 DeleteItemOnIdle( std::move(pPool) );
925 return pTemp;
926 }
927
928 // slot is handled internally by SfxDispatcher
929 if ( pImpl->bMsgDirty )
930 UpdateSlotServer_Impl();
931
932 SfxShell *pShell=nullptr;
933 const SfxSlot *pSlot=nullptr;
934
935 const SfxSlotServer* pServer = pCache->GetSlotServer( rDispatcher, pImpl->xProv );
936 if ( !pServer )
937 {
938 return nullptr;
939 }
940 else
941 {
942 pShell = rDispatcher.GetShell( pServer->GetShellLevel() );
943 pSlot = pServer->GetSlot();
944 }
945
946 if ( bGlobalOnly )
947 if ( dynamic_cast< const SfxModule *>( pShell ) == nullptr && dynamic_cast< const SfxApplication *>( pShell ) == nullptr && dynamic_cast< const SfxViewFrame *>( pShell ) == nullptr )
948 return nullptr;
949
950 SfxItemPool &rPool = pShell->GetPool();
951 SfxRequest aReq( nId, nCallMode, rPool );
952 aReq.SetModifier( nModi );
953 if( ppItems )
954 while( *ppItems )
955 aReq.AppendItem( **ppItems++ );
956 if ( ppInternalArgs )
957 {
958 SfxAllItemSet aSet( rPool );
959 for ( const SfxPoolItem **pArg = ppInternalArgs; *pArg; ++pArg )
960 aSet.Put( **pArg );
961 aReq.SetInternalArgs_Impl( aSet );
962 }
963
964 Execute_Impl( aReq, pSlot, pShell );
965
966 const SfxPoolItem* pRet = aReq.GetReturnValue();
967 if ( !pRet )
968 {
969 std::unique_ptr<SfxPoolItem> pVoid(new SfxVoidItem( nId ));
970 pRet = pVoid.get();
971 DeleteItemOnIdle( std::move(pVoid) );
972 }
973
974 return pRet;
975}
976
977void SfxBindings::Execute_Impl( SfxRequest& aReq, const SfxSlot* pSlot, SfxShell* pShell )
978{
979 SfxItemPool &rPool = pShell->GetPool();
980
981 if ( SfxSlotKind::Attribute == pSlot->GetKind() )
982 {
983 // Which value has to be mapped for Attribute slots
984 const sal_uInt16 nSlotId = pSlot->GetSlotId();
985 aReq.SetSlot( nSlotId );
986 if ( pSlot->IsMode(SfxSlotMode::TOGGLE) )
987 {
988 // The value is attached to a toggleable attribute (Bools)
989 sal_uInt16 nWhich = pSlot->GetWhich(rPool);
990 SfxItemSet aSet(rPool, {{nWhich, nWhich}});
991 SfxStateFunc aFunc = pSlot->GetStateFnc();
992 pShell->CallState( aFunc, aSet );
993 const SfxPoolItem *pOldItem;
994 SfxItemState eState = aSet.GetItemState(nWhich, true, &pOldItem);
995 if ( eState == SfxItemState::DISABLED )
996 return;
997
998 if ( SfxItemState::DEFAULT == eState && SfxItemPool::IsWhich(nWhich) )
999 pOldItem = &aSet.Get(nWhich);
1000
1001 if ( SfxItemState::SET == eState ||
1002 ( SfxItemState::DEFAULT == eState &&
1003 SfxItemPool::IsWhich(nWhich) &&
1004 pOldItem ) )
1005 {
1006 if ( auto pOldBoolItem = dynamic_cast< const SfxBoolItem *>( pOldItem ) )
1007 {
1008 // we can toggle Bools
1009 bool bOldValue = pOldBoolItem->GetValue();
1010 std::unique_ptr<SfxBoolItem> pNewItem(static_cast<SfxBoolItem*>(pOldItem->Clone()));
1011 pNewItem->SetValue( !bOldValue );
1012 aReq.AppendItem( *pNewItem );
1013 }
1014 else if ( dynamic_cast< const SfxEnumItemInterface *>( pOldItem ) != nullptr &&
1015 static_cast<const SfxEnumItemInterface *>(pOldItem)->HasBoolValue())
1016 {
1017 // and Enums with Bool-Interface
1018 std::unique_ptr<SfxEnumItemInterface> pNewItem(
1019 static_cast<SfxEnumItemInterface*>(pOldItem->Clone()));
1020 pNewItem->SetBoolValue(!static_cast<const SfxEnumItemInterface *>(pOldItem)->GetBoolValue());
1021 aReq.AppendItem( *pNewItem );
1022 }
1023 else {
1024 OSL_FAIL( "Toggle only for Enums and Bools allowed" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1024" ": "), "%s", "Toggle only for Enums and Bools allowed"
); } } while (false)
;
1025 }
1026 }
1027 else if ( SfxItemState::DONTCARE == eState )
1028 {
1029 // Create one Status-Item for each Factory
1030 std::unique_ptr<SfxPoolItem> pNewItem = pSlot->GetType()->CreateItem();
1031 DBG_ASSERT( pNewItem, "Toggle to slot without ItemFactory" )do { if (true && (!(pNewItem))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1031" ": "), "%s", "Toggle to slot without ItemFactory"
); } } while (false)
;
1032 pNewItem->SetWhich( nWhich );
1033
1034 if ( auto pNewBoolItem = dynamic_cast<SfxBoolItem *>( pNewItem.get() ) )
1035 {
1036 // we can toggle Bools
1037 pNewBoolItem->SetValue( true );
1038 aReq.AppendItem( *pNewItem );
1039 }
1040 else if ( dynamic_cast< const SfxEnumItemInterface *>( pNewItem.get() ) != nullptr &&
1041 static_cast<SfxEnumItemInterface *>(pNewItem.get())->HasBoolValue())
1042 {
1043 // and Enums with Bool-Interface
1044 static_cast<SfxEnumItemInterface*>(pNewItem.get())->SetBoolValue(true);
1045 aReq.AppendItem( *pNewItem );
1046 }
1047 else {
1048 OSL_FAIL( "Toggle only for Enums and Bools allowed" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1048" ": "), "%s", "Toggle only for Enums and Bools allowed"
); } } while (false)
;
1049 }
1050 }
1051 else {
1052 OSL_FAIL( "suspicious Toggle-Slot" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1052" ": "), "%s", "suspicious Toggle-Slot"); } } while
(false)
;
1053 }
1054 }
1055
1056 pDispatcher->Execute_( *pShell, *pSlot, aReq, aReq.GetCallMode() | SfxCallMode::RECORD );
1057 }
1058 else
1059 pDispatcher->Execute_( *pShell, *pSlot, aReq, aReq.GetCallMode() | SfxCallMode::RECORD );
1060}
1061
1062
1063void SfxBindings::UpdateSlotServer_Impl()
1064{
1065 // synchronize
1066 pDispatcher->Flush();
1067
1068 if ( pImpl->bAllMsgDirty )
1069 {
1070 if ( !nRegLevel )
1071 {
1072 pImpl->bContextChanged = false;
1073 }
1074 else
1075 pImpl->bContextChanged = true;
1076 }
1077
1078 for (std::unique_ptr<SfxStateCache>& pCache : pImpl->pCaches)
1079 {
1080 //GetSlotServer can modify pImpl->pCaches
1081 pCache->GetSlotServer(*pDispatcher, pImpl->xProv);
1082 }
1083 pImpl->bMsgDirty = pImpl->bAllMsgDirty = false;
1084
1085 Broadcast( SfxHint(SfxHintId::DocChanged) );
1086}
1087
1088
1089std::unique_ptr<SfxItemSet> SfxBindings::CreateSet_Impl
1090(
1091 SfxStateCache& rCache, // in: Status-Cache from nId
1092 const SfxSlot*& pRealSlot, // out: RealSlot to nId
1093 const SfxSlotServer** pMsgServer, // out: Slot-Server to nId
1094 SfxFoundCacheArr_Impl& rFound // out: List of Caches for Siblings
1095)
1096{
1097 DBG_ASSERT( !pImpl->bMsgDirty, "CreateSet_Impl with dirty MessageServer" )do { if (true && (!(!pImpl->bMsgDirty))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1097" ": "), "%s", "CreateSet_Impl with dirty MessageServer"
); } } while (false)
;
1098 assert(pDispatcher)(static_cast <bool> (pDispatcher) ? void (0) : __assert_fail
("pDispatcher", "/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
, 1098, __extension__ __PRETTY_FUNCTION__))
;
1099
1100 const SfxSlotServer* pMsgSvr = rCache.GetSlotServer(*pDispatcher, pImpl->xProv);
1101 if (!pMsgSvr)
1102 return nullptr;
1103
1104 pRealSlot = nullptr;
1105 *pMsgServer = pMsgSvr;
1106
1107 sal_uInt16 nShellLevel = pMsgSvr->GetShellLevel();
1108 SfxShell *pShell = pDispatcher->GetShell( nShellLevel );
1109 if ( !pShell ) // rare GPF when browsing through update from Inet-Notify
1110 return nullptr;
1111
1112 SfxItemPool &rPool = pShell->GetPool();
1113
1114 // get the status method, which is served by the rCache
1115 SfxStateFunc pFnc = nullptr;
1116 pRealSlot = pMsgSvr->GetSlot();
1117
1118 pFnc = pRealSlot->GetStateFnc();
1119
1120 // the RealSlot is always on
1121 SfxFoundCache_Impl *pFound = new SfxFoundCache_Impl(
1122 pRealSlot->GetWhich(rPool), pRealSlot, rCache);
1123 rFound.push_back( pFound );
1124
1125 // Search through the bindings for slots served by the same function. This , // will only affect slots which are present in the found interface.
1126
1127 // The position of the Statecaches in StateCache-Array
1128 std::size_t nCachePos = pImpl->nMsgPos;
1129 const SfxSlot *pSibling = pRealSlot->GetNextSlot();
1130
1131 // the Slots ODF and interfaces are linked in a circle
1132 while ( pSibling > pRealSlot )
1133 {
1134 SfxStateFunc pSiblingFnc=nullptr;
1135 SfxStateCache *pSiblingCache =
1136 GetStateCache( pSibling->GetSlotId(), &nCachePos );
1137
1138 // Is the slot cached ?
1139 if ( pSiblingCache )
1140 {
1141 const SfxSlotServer *pServ = pSiblingCache->GetSlotServer(*pDispatcher, pImpl->xProv);
1142 if ( pServ && pServ->GetShellLevel() == nShellLevel )
1143 pSiblingFnc = pServ->GetSlot()->GetStateFnc();
1144 }
1145
1146 // Does the slot have to be updated at all?
1147 bool bInsert = pSiblingCache && pSiblingCache->IsControllerDirty();
1148
1149 // It is not enough to ask for the same shell!!
1150 bool bSameMethod = pSiblingCache && pFnc == pSiblingFnc;
1151
1152 if ( bInsert && bSameMethod )
1153 {
1154 SfxFoundCache_Impl *pFoundCache = new SfxFoundCache_Impl(
1155 pSibling->GetWhich(rPool),
1156 pSibling, *pSiblingCache);
1157
1158 rFound.push_back( pFoundCache );
1159 }
1160
1161 pSibling = pSibling->GetNextSlot();
1162 }
1163
1164 // Create a Set from the ranges
1165 std::unique_ptr<sal_uInt16[]> pRanges(new sal_uInt16[rFound.size() * 2 + 1]);
1166 int j = 0;
1167 size_t i = 0;
1168 while ( i < rFound.size() )
1169 {
1170 pRanges[j++] = rFound[i].nWhichId;
1171 // consecutive numbers
1172 for ( ; i < rFound.size()-1; ++i )
1173 if ( rFound[i].nWhichId+1 != rFound[i+1].nWhichId )
1174 break;
1175 pRanges[j++] = rFound[i++].nWhichId;
1176 }
1177 pRanges[j] = 0; // terminating NULL
1178 std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(rPool, pRanges.get()));
1179 pRanges.reset();
1180 return pSet;
1181}
1182
1183
1184void SfxBindings::UpdateControllers_Impl
1185(
1186 const SfxFoundCache_Impl& rFound, // Cache, Slot, Which etc.
1187 const SfxPoolItem* pItem, // item to send to controller
1188 SfxItemState eState // state of item
1189)
1190{
1191 SfxStateCache& rCache = rFound.rCache;
1192 const SfxSlot* pSlot = rFound.pSlot;
1193 DBG_ASSERT( !pSlot || rCache.GetId() == pSlot->GetSlotId(), "SID mismatch" )do { if (true && (!(!pSlot || rCache.GetId() == pSlot
->GetSlotId()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1193" ": "), "%s", "SID mismatch"); } } while (false)
;
1194
1195 // bound until now, the Controller to update the Slot.
1196 if (!rCache.IsControllerDirty())
1197 return;
1198
1199 if ( SfxItemState::DONTCARE == eState )
1200 {
1201 // ambiguous
1202 rCache.SetState( SfxItemState::DONTCARE, INVALID_POOL_ITEMreinterpret_cast<SfxPoolItem*>(-1) );
1203 }
1204 else if ( SfxItemState::DEFAULT == eState &&
1205 SfxItemPool::IsSlot(rFound.nWhichId) )
1206 {
1207 // no Status or Default but without Pool
1208 SfxVoidItem aVoid(0);
1209 rCache.SetState( SfxItemState::UNKNOWN, &aVoid );
1210 }
1211 else if ( SfxItemState::DISABLED == eState )
1212 rCache.SetState(SfxItemState::DISABLED, nullptr);
1213 else
1214 rCache.SetState(SfxItemState::DEFAULT, pItem);
1215}
1216
1217IMPL_LINK( SfxBindings, NextJob, Timer *, pTimer, void )void SfxBindings::LinkStubNextJob(void * instance, Timer * data
) { return static_cast<SfxBindings *>(instance)->NextJob
(data); } void SfxBindings::NextJob(Timer * pTimer)
1218{
1219 NextJob_Impl(pTimer);
1220}
1221
1222bool SfxBindings::NextJob_Impl(Timer const * pTimer)
1223{
1224 const unsigned MAX_INPUT_DELAY = 200;
1225
1226 if ( Application::GetLastInputInterval() < MAX_INPUT_DELAY && pTimer )
1227 {
1228 pImpl->aAutoTimer.SetTimeout(TIMEOUT_UPDATING20);
1229 return true;
1230 }
1231
1232 SfxApplication *pSfxApp = SfxGetpApp();
1233
1234 if( pDispatcher )
1235 pDispatcher->Update_Impl();
1236
1237 // modifying the SfxObjectInterface-stack without SfxBindings => nothing to do
1238 SfxViewFrame* pFrame = pDispatcher ? pDispatcher->GetFrame() : nullptr;
1239 if ( (pFrame && !pFrame->GetObjectShell()->AcceptStateUpdate()) || pSfxApp->IsDowning() || pImpl->pCaches.empty() )
1240 {
1241 return true;
1242 }
1243 if ( !pDispatcher || !pDispatcher->IsFlushed() )
1244 {
1245 return true;
1246 }
1247
1248 // if possible Update all server / happens in its own time slice
1249 if ( pImpl->bMsgDirty )
1250 {
1251 UpdateSlotServer_Impl();
1252 return false;
1253 }
1254
1255 pImpl->bAllDirty = false;
1256 pImpl->aAutoTimer.SetTimeout(TIMEOUT_UPDATING20);
1257
1258 // at least 10 loops and further if more jobs are available but no input
1259 bool bPreEmptive = pTimer;
1260 sal_uInt16 nLoops = 10;
1261 pImpl->bInNextJob = true;
1262 const std::size_t nCount = pImpl->pCaches.size();
1263 while ( pImpl->nMsgPos < nCount )
1264 {
1265 // iterate through the bound functions
1266 bool bJobDone = false;
1267 while ( !bJobDone )
1268 {
1269 SfxStateCache* pCache = pImpl->pCaches[pImpl->nMsgPos].get();
1270 DBG_ASSERT( pCache, "invalid SfxStateCache-position in job queue" )do { if (true && (!(pCache))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1270" ": "), "%s", "invalid SfxStateCache-position in job queue"
); } } while (false)
;
1271 bool bWasDirty = pCache->IsControllerDirty();
1272 if ( bWasDirty )
1273 {
1274 Update_Impl(*pCache);
1275 DBG_ASSERT(nCount == pImpl->pCaches.size(), "Reschedule in StateChanged => buff")do { if (true && (!(nCount == pImpl->pCaches.size(
)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1275" ": "), "%s", "Reschedule in StateChanged => buff"
); } } while (false)
;
1276 }
1277
1278 // skip to next function binding
1279 ++pImpl->nMsgPos;
1280
1281 // keep job if it is not completed, but any input is available
1282 bJobDone = pImpl->nMsgPos >= nCount;
1283 if ( bJobDone && pImpl->bFirstRound )
1284 {
1285
1286 // Update of the preferred shell has been done, now may
1287 // also the others shells be updated
1288 bJobDone = false;
1289 pImpl->bFirstRound = false;
1290 pImpl->nMsgPos = 0;
1291 }
1292
1293 if ( bWasDirty && !bJobDone && bPreEmptive && (--nLoops == 0) )
1294 {
1295 pImpl->bInNextJob = false;
1296 return false;
1297 }
1298 }
1299 }
1300
1301 pImpl->nMsgPos = 0;
1302
1303 pImpl->aAutoTimer.Stop();
1304
1305 // Update round is finished
1306 pImpl->bInNextJob = false;
1307 Broadcast(SfxHint(SfxHintId::UpdateDone));
1308 return true;
1309}
1310
1311
1312sal_uInt16 SfxBindings::EnterRegistrations(const char *pFile, int nLine)
1313{
1314 SAL_INFO(do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::EnterRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1315 "sfx.control",do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::EnterRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1316 std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' << "this = " << thisdo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::EnterRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1317 << " Level = " << nRegLevel << " SfxBindings::EnterRegistrations "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::EnterRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1318 << (pFiledo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::EnterRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1319 ? SAL_STREAM("File: " << pFile << " Line: " << nLine) : ""))do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::EnterRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::EnterRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::EnterRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1319" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1320
1321 // When bindings are locked, also lock sub bindings.
1322 if ( pImpl->pSubBindings )
1323 {
1324 pImpl->pSubBindings->ENTERREGISTRATIONS()EnterRegistrations();
1325
1326 // These EnterRegistrations are not "real" for the SubBindings
1327 pImpl->pSubBindings->pImpl->nOwnRegLevel--;
1328
1329 // Synchronize Bindings
1330 pImpl->pSubBindings->nRegLevel = nRegLevel + pImpl->pSubBindings->pImpl->nOwnRegLevel + 1;
1331 }
1332
1333 pImpl->nOwnRegLevel++;
1334
1335 // check if this is the outer most level
1336 if ( ++nRegLevel == 1 )
1337 {
1338 // stop background-processing
1339 pImpl->aAutoTimer.Stop();
1340
1341 // flush the cache
1342 pImpl->nCachedFunc1 = 0;
1343 pImpl->nCachedFunc2 = 0;
1344
1345 // Mark if the all of the Caches have disappeared.
1346 pImpl->bCtrlReleased = false;
1347 }
1348
1349 return nRegLevel;
1350}
1351
1352
1353void SfxBindings::LeaveRegistrations( const char *pFile, int nLine )
1354{
1355 DBG_ASSERT( nRegLevel, "Leave without Enter" )do { if (true && (!(nRegLevel))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1355" ": "), "%s", "Leave without Enter"); } } while (false
)
;
13
Assuming field 'nRegLevel' is not equal to 0
14
Taking false branch
15
Loop condition is false. Exiting loop
19
Assuming field 'nRegLevel' is not equal to 0
20
Taking false branch
21
Loop condition is false. Exiting loop
1356
1357 // Only when the SubBindings are still locked by the Superbindings,
1358 // remove this lock (i.e. if there are more locks than "real" ones)
1359 if ( pImpl->pSubBindings
15.1
Field 'pSubBindings' is non-null
&& pImpl->pSubBindings->nRegLevel > pImpl->pSubBindings->pImpl->nOwnRegLevel )
16
Assuming field 'nRegLevel' is > field 'nOwnRegLevel'
17
Taking true branch
22
Assuming field 'pSubBindings' is null
1360 {
1361 // Synchronize Bindings
1362 pImpl->pSubBindings->nRegLevel = nRegLevel + pImpl->pSubBindings->pImpl->nOwnRegLevel;
1363
1364 // This LeaveRegistrations is not "real" for SubBindings
1365 pImpl->pSubBindings->pImpl->nOwnRegLevel++;
1366 pImpl->pSubBindings->LEAVEREGISTRATIONS()LeaveRegistrations();
18
Calling 'SfxBindings::LeaveRegistrations'
1367 }
1368
1369 pImpl->nOwnRegLevel--;
1370
1371 // check if this is the outer most level
1372 if ( --nRegLevel == 0 && SfxGetpApp() && !SfxGetpApp()->IsDowning() )
23
Assuming the condition is true
24
Assuming the condition is true
25
Assuming the condition is true
26
Taking true branch
1373 {
1374 if ( pImpl->bContextChanged )
27
Assuming field 'bContextChanged' is false
28
Taking false branch
1375 {
1376 pImpl->bContextChanged = false;
1377 }
1378
1379 SfxViewFrame* pFrame = pDispatcher->GetFrame();
29
Called C++ object pointer is null
1380
1381 // If possible remove unused Caches, for example prepare PlugInInfo
1382 if ( pImpl->bCtrlReleased )
1383 {
1384 for ( sal_uInt16 nCache = pImpl->pCaches.size(); nCache > 0; --nCache )
1385 {
1386 // Get Cache via css::sdbcx::Index
1387 SfxStateCache *pCache = pImpl->pCaches[nCache-1].get();
1388
1389 // No interested Controller present
1390 if ( pCache->GetItemLink() == nullptr && !pCache->GetInternalController() )
1391 {
1392 // Remove Cache. Safety: first remove and then delete
1393 pImpl->pCaches.erase(pImpl->pCaches.begin() + nCache - 1);
1394 }
1395 }
1396 }
1397
1398 // restart background-processing
1399 pImpl->nMsgPos = 0;
1400 if ( !pFrame || !pFrame->GetObjectShell() )
1401 return;
1402 if ( !pImpl->pCaches.empty() )
1403 {
1404 pImpl->aAutoTimer.Stop();
1405 pImpl->aAutoTimer.SetTimeout(TIMEOUT_FIRST300);
1406 pImpl->aAutoTimer.Start();
1407 }
1408 }
1409
1410 SAL_INFO(do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::LeaveRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1411 "sfx.control",do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::LeaveRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1412 std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' << "this = " << thisdo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::LeaveRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1413 << " Level = " << nRegLevel << " SfxBindings::LeaveRegistrations "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::LeaveRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1414 << (pFiledo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::LeaveRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1415 ? SAL_STREAM("File: " << pFile << " Line: " << nLine) : ""))do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.control")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << std::setw(std::min(nRegLevel
, sal_uInt16(8))) << ' ' << "this = " << this
<< " Level = " << nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << std::setw(std::min(nRegLevel, sal_uInt16(8))) <<
' ' << "this = " << this << " Level = " <<
nRegLevel << " SfxBindings::LeaveRegistrations " <<
(pFile ? (dynamic_cast< ::std::ostringstream & >(::
std::ostringstream() << "File: " << pFile <<
" Line: " << nLine).str()) : "")) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << std::setw(std::min(nRegLevel, sal_uInt16
(8))) << ' ' << "this = " << this << " Level = "
<< nRegLevel << " SfxBindings::LeaveRegistrations "
<< (pFile ? (dynamic_cast< ::std::ostringstream &
>(::std::ostringstream() << "File: " << pFile
<< " Line: " << nLine).str()) : "")), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' <<
"this = " << this << " Level = " << nRegLevel
<< " SfxBindings::LeaveRegistrations " << (pFile
? (dynamic_cast< ::std::ostringstream & >(::std::ostringstream
() << "File: " << pFile << " Line: " <<
nLine).str()) : ""); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.control"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1415" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1416}
1417
1418
1419void SfxBindings::SetDispatcher( SfxDispatcher *pDisp )
1420{
1421 SfxDispatcher *pOldDispat = pDispatcher;
1422 if ( pDisp == pDispatcher )
1
Assuming 'pDisp' is not equal to field 'pDispatcher'
2
Taking false branch
1423 return;
1424
1425 if ( pOldDispat )
3
Assuming 'pOldDispat' is null
4
Taking false branch
1426 {
1427 SfxBindings* pBind = pOldDispat->GetBindings();
1428 while ( pBind )
1429 {
1430 if ( pBind->pImpl->pSubBindings == this && pBind->pDispatcher != pDisp )
1431 pBind->SetSubBindings_Impl( nullptr );
1432 pBind = pBind->pImpl->pSubBindings;
1433 }
1434 }
1435
1436 pDispatcher = pDisp;
1437
1438 css::uno::Reference < css::frame::XDispatchProvider > xProv;
1439 if ( pDisp )
5
Assuming 'pDisp' is null
6
Taking false branch
1440 xProv.set( pDisp->GetFrame()->GetFrame().GetFrameInterface(), UNO_QUERY );
1441
1442 SetDispatchProvider_Impl( xProv );
1443 InvalidateAll( true );
1444
1445 if ( pDispatcher && !pOldDispat
7.1
'pOldDispat' is null
)
7
Assuming field 'pDispatcher' is non-null
8
Taking true branch
1446 {
1447 if ( pImpl->pSubBindings && pImpl->pSubBindings->pDispatcher != pOldDispat )
9
Assuming field 'pSubBindings' is non-null
10
Assuming 'pOldDispat' is equal to field 'pDispatcher'
11
Taking false branch
1448 {
1449 OSL_FAIL( "SubBindings already set before activating!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1449" ": "), "%s", "SubBindings already set before activating!"
); } } while (false)
;
1450 pImpl->pSubBindings->ENTERREGISTRATIONS()EnterRegistrations();
1451 }
1452 LEAVEREGISTRATIONS()LeaveRegistrations();
12
Calling 'SfxBindings::LeaveRegistrations'
1453 }
1454 else if( !pDispatcher )
1455 {
1456 ENTERREGISTRATIONS()EnterRegistrations();
1457 if ( pImpl->pSubBindings && pImpl->pSubBindings->pDispatcher != pOldDispat )
1458 {
1459 OSL_FAIL( "SubBindings still set even when deactivating!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1459" ": "), "%s", "SubBindings still set even when deactivating!"
); } } while (false)
;
1460 pImpl->pSubBindings->LEAVEREGISTRATIONS()LeaveRegistrations();
1461 }
1462 }
1463
1464 Broadcast( SfxHint( SfxHintId::DataChanged ) );
1465
1466 if ( !pDisp )
1467 return;
1468
1469 SfxBindings* pBind = pDisp->GetBindings();
1470 while ( pBind && pBind != this )
1471 {
1472 if ( !pBind->pImpl->pSubBindings )
1473 {
1474 pBind->SetSubBindings_Impl( this );
1475 break;
1476 }
1477
1478 pBind = pBind->pImpl->pSubBindings;
1479 }
1480}
1481
1482
1483void SfxBindings::ClearCache_Impl( sal_uInt16 nSlotId )
1484{
1485 SfxStateCache* pCache = GetStateCache(nSlotId);
1486 if (!pCache)
1487 return;
1488 pCache->ClearCache();
1489}
1490
1491
1492void SfxBindings::StartUpdate_Impl( bool bComplete )
1493{
1494 if ( pImpl->pSubBindings )
1495 pImpl->pSubBindings->StartUpdate_Impl( bComplete );
1496
1497 if ( !bComplete )
1498 // Update may be interrupted
1499 NextJob_Impl(&pImpl->aAutoTimer);
1500 else
1501 // Update all slots in a row
1502 NextJob_Impl(nullptr);
1503}
1504
1505
1506SfxItemState SfxBindings::QueryState( sal_uInt16 nSlot, std::unique_ptr<SfxPoolItem> &rpState )
1507{
1508 css::uno::Reference< css::frame::XDispatch > xDisp;
1509 SfxStateCache *pCache = GetStateCache( nSlot );
1510 if ( pCache )
1511 xDisp = pCache->GetDispatch();
1512 if ( xDisp.is() || !pCache )
1513 {
1514 const SfxSlot* pSlot = SfxSlotPool::GetSlotPool( pDispatcher->GetFrame() ).GetSlot( nSlot );
1515 if ( !pSlot || !pSlot->pUnoName )
1516 return SfxItemState::DISABLED;
1517
1518 css::util::URL aURL;
1519 OUString aCmd( ".uno:" );
1520 aURL.Protocol = aCmd;
1521 aURL.Path = OUString::createFromAscii(pSlot->GetUnoName());
1522 aCmd += aURL.Path;
1523 aURL.Complete = aCmd;
1524 aURL.Main = aCmd;
1525
1526 if ( !xDisp.is() )
1527 xDisp = pImpl->xProv->queryDispatch( aURL, OUString(), 0 );
1528
1529 if ( xDisp.is() )
1530 {
1531 css::uno::Reference< css::lang::XUnoTunnel > xTunnel( xDisp, css::uno::UNO_QUERY );
1532 SfxOfficeDispatch* pDisp = nullptr;
1533 if ( xTunnel.is() )
1534 {
1535 sal_Int64 nImplementation = xTunnel->getSomething(SfxOfficeDispatch::impl_getStaticIdentifier());
1536 pDisp = reinterpret_cast< SfxOfficeDispatch* >( sal::static_int_cast< sal_IntPtr >( nImplementation ));
1537 }
1538
1539 if ( !pDisp )
1540 {
1541 bool bDeleteCache = false;
1542 if ( !pCache )
1543 {
1544 pCache = new SfxStateCache( nSlot );
1545 pCache->GetSlotServer( *GetDispatcher_Impl(), pImpl->xProv );
1546 bDeleteCache = true;
1547 }
1548
1549 SfxItemState eState = SfxItemState::SET;
1550 rtl::Reference<BindDispatch_Impl> xBind(new BindDispatch_Impl( xDisp, aURL, pCache, pSlot ));
1551 xDisp->addStatusListener( xBind.get(), aURL );
1552 if ( !xBind->GetStatus().IsEnabled )
1553 {
1554 eState = SfxItemState::DISABLED;
1555 }
1556 else
1557 {
1558 css::uno::Any aAny = xBind->GetStatus().State;
1559 const css::uno::Type& aType = aAny.getValueType();
1560
1561 if ( aType == cppu::UnoType<bool>::get() )
1562 {
1563 bool bTemp = false;
1564 aAny >>= bTemp ;
1565 rpState.reset(new SfxBoolItem( nSlot, bTemp ));
1566 }
1567 else if ( aType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get() )
1568 {
1569 sal_uInt16 nTemp = 0;
1570 aAny >>= nTemp ;
1571 rpState.reset(new SfxUInt16Item( nSlot, nTemp ));
1572 }
1573 else if ( aType == cppu::UnoType<sal_uInt32>::get() )
1574 {
1575 sal_uInt32 nTemp = 0;
1576 aAny >>= nTemp ;
1577 rpState.reset(new SfxUInt32Item( nSlot, nTemp ));
1578 }
1579 else if ( aType == cppu::UnoType<OUString>::get() )
1580 {
1581 OUString sTemp ;
1582 aAny >>= sTemp ;
1583 rpState.reset(new SfxStringItem( nSlot, sTemp ));
1584 }
1585 else
1586 rpState.reset(new SfxVoidItem( nSlot ));
1587 }
1588
1589 xDisp->removeStatusListener( xBind.get(), aURL );
1590 xBind->Release();
1591 xBind.clear();
1592 if ( bDeleteCache )
1593 {
1594 delete pCache;
1595 pCache = nullptr;
1596 }
1597 return eState;
1598 }
1599 }
1600 }
1601
1602 // Then test at the dispatcher to check if the returned items from
1603 // there are always DELETE_ON_IDLE, a copy of it has to be made in
1604 // order to allow for transition of ownership.
1605 const SfxPoolItem *pItem = nullptr;
1606 SfxItemState eState = pDispatcher->QueryState( nSlot, pItem );
1607 if ( eState == SfxItemState::SET )
1608 {
1609 DBG_ASSERT( pItem, "SfxItemState::SET but no item!" )do { if (true && (!(pItem))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1609" ": "), "%s", "SfxItemState::SET but no item!"); }
} while (false)
;
1610 if ( pItem )
1611 rpState.reset(pItem->Clone());
1612 }
1613 else if ( eState == SfxItemState::DEFAULT && pItem )
1614 {
1615 rpState.reset(pItem->Clone());
1616 }
1617
1618 return eState;
1619}
1620
1621void SfxBindings::QueryControlState( sal_uInt16 nSlot, boost::property_tree::ptree& rState )
1622{
1623 if ( SfxGetpApp()->IsDowning() )
1624 return;
1625
1626 if ( pDispatcher )
1627 pDispatcher->Flush();
1628
1629 if ( pImpl->pSubBindings )
1630 pImpl->pSubBindings->QueryControlState( nSlot, rState );
1631
1632 SfxStateCache* pCache = GetStateCache( nSlot );
1633 if ( !pCache )
1634 return;
1635
1636 if ( pImpl->bMsgDirty )
1637 {
1638 UpdateSlotServer_Impl();
1639 pCache = GetStateCache( nSlot );
1640 }
1641
1642 if (pCache && pCache->GetItemLink() )
1643 {
1644 pCache->GetState(rState);
1645 }
1646}
1647
1648void SfxBindings::SetSubBindings_Impl( SfxBindings *pSub )
1649{
1650 if ( pImpl->pSubBindings )
1651 {
1652 pImpl->pSubBindings->SetDispatchProvider_Impl( css::uno::Reference< css::frame::XDispatchProvider > () );
1653 }
1654
1655 pImpl->pSubBindings = pSub;
1656
1657 if ( pSub )
1658 {
1659 pImpl->pSubBindings->SetDispatchProvider_Impl( pImpl->xProv );
1660 }
1661}
1662
1663SfxBindings* SfxBindings::GetSubBindings_Impl() const
1664{
1665 return pImpl->pSubBindings;
1666}
1667
1668void SfxBindings::SetWorkWindow_Impl( std::unique_ptr<SfxWorkWindow> xWork )
1669{
1670 pImpl->mxWorkWin = std::move(xWork);
1671}
1672
1673SfxWorkWindow* SfxBindings::GetWorkWindow_Impl() const
1674{
1675 return pImpl->mxWorkWin.get();
1676}
1677
1678bool SfxBindings::IsInUpdate() const
1679{
1680 bool bInUpdate = pImpl->bInUpdate;
1681 if ( !bInUpdate && pImpl->pSubBindings )
1682 bInUpdate = pImpl->pSubBindings->IsInUpdate();
1683 return bInUpdate;
1684}
1685
1686void SfxBindings::SetVisibleState( sal_uInt16 nId, bool bShow )
1687{
1688 SfxStateCache *pCache = GetStateCache( nId );
1689 if ( pCache )
1690 pCache->SetVisibleState( bShow );
1691}
1692
1693void SfxBindings::SetActiveFrame( const css::uno::Reference< css::frame::XFrame > & rFrame )
1694{
1695 if ( rFrame.is() || !pDispatcher )
1696 SetDispatchProvider_Impl( css::uno::Reference< css::frame::XDispatchProvider > ( rFrame, css::uno::UNO_QUERY ) );
1697 else
1698 SetDispatchProvider_Impl( css::uno::Reference< css::frame::XDispatchProvider > (
1699 pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), css::uno::UNO_QUERY ) );
1700}
1701
1702css::uno::Reference< css::frame::XFrame > SfxBindings::GetActiveFrame() const
1703{
1704 const css::uno::Reference< css::frame::XFrame > xFrame( pImpl->xProv, css::uno::UNO_QUERY );
1705 if ( xFrame.is() || !pDispatcher )
1706 return xFrame;
1707 else
1708 return pDispatcher->GetFrame()->GetFrame().GetFrameInterface();
1709}
1710
1711void SfxBindings::SetDispatchProvider_Impl( const css::uno::Reference< css::frame::XDispatchProvider > & rProv )
1712{
1713 bool bInvalidate = ( rProv != pImpl->xProv );
1714 if ( bInvalidate )
1715 {
1716 pImpl->xProv = rProv;
1717 InvalidateAll( true );
1718 }
1719
1720 if ( pImpl->pSubBindings )
1721 pImpl->pSubBindings->SetDispatchProvider_Impl( pImpl->xProv );
1722}
1723
1724const css::uno::Reference< css::frame::XDispatchRecorder >& SfxBindings::GetRecorder() const
1725{
1726 return pImpl->xRecorder;
1727}
1728
1729void SfxBindings::SetRecorder_Impl( css::uno::Reference< css::frame::XDispatchRecorder > const & rRecorder )
1730{
1731 pImpl->xRecorder = rRecorder;
1732}
1733
1734void SfxBindings::ContextChanged_Impl()
1735{
1736 if ( !pImpl->bInUpdate && ( !pImpl->bContextChanged || !pImpl->bAllMsgDirty ) )
1737 {
1738 InvalidateAll( true );
1739 }
1740}
1741
1742uno::Reference < frame::XDispatch > SfxBindings::GetDispatch( const SfxSlot* pSlot, const util::URL& aURL, bool bMasterCommand )
1743{
1744 uno::Reference < frame::XDispatch > xRet;
1745 SfxStateCache* pCache = GetStateCache( pSlot->nSlotId );
1746 if ( pCache && !bMasterCommand )
1747 xRet = pCache->GetInternalDispatch();
1748 if ( !xRet.is() )
1749 {
1750 // dispatches for slaves are unbound, they don't have a state
1751 SfxOfficeDispatch* pDispatch = bMasterCommand ?
1752 new SfxOfficeDispatch( pDispatcher, pSlot, aURL ) :
1753 new SfxOfficeDispatch( *this, pDispatcher, pSlot, aURL );
1754
1755 pDispatch->SetMasterUnoCommand( bMasterCommand );
1756 xRet.set( pDispatch );
1757 if ( !pCache )
1758 pCache = GetStateCache( pSlot->nSlotId );
1759
1760 DBG_ASSERT( pCache, "No cache for OfficeDispatch!" )do { if (true && (!(pCache))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/control/bindings.cxx"
":" "1760" ": "), "%s", "No cache for OfficeDispatch!"); } }
while (false)
;
1761 if ( pCache && !bMasterCommand )
1762 pCache->SetInternalDispatch( xRet );
1763 }
1764
1765 return xRet;
1766}
1767
1768/* vim:set shiftwidth=4 softtabstop=4 expandtab: */