LibreOffice Module sfx2 (master) 1
dispatch.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <config_feature_desktop.h>
21
22#include <algorithm>
23#include <cstddef>
24#include <deque>
25#include <vector>
26
27#include <stdlib.h>
28
29#include <boost/property_tree/json_parser.hpp>
30
31#include <com/sun/star/awt/PopupMenuDirection.hpp>
32#include <com/sun/star/beans/XPropertySet.hpp>
33#include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
34#include <com/sun/star/frame/XLayoutManager.hpp>
35#include <com/sun/star/frame/XPopupMenuController.hpp>
36#include <com/sun/star/uno/XComponentContext.hpp>
37#include <com/sun/star/ui/ContextMenuExecuteEvent.hpp>
38
39#include <LibreOfficeKit/LibreOfficeKitEnums.h>
40#include <comphelper/lok.hxx>
43#include <rtl/strbuf.hxx>
44#include <sal/log.hxx>
45#include <sfx2/app.hxx>
46#include <sfx2/bindings.hxx>
47#include <sfx2/childwin.hxx>
48#include <sfx2/dispatch.hxx>
49#include <sfx2/docfile.hxx>
50#include <hintpost.hxx>
51#include <sfx2/ipclient.hxx>
52#include <sfx2/module.hxx>
53#include <sfx2/msg.hxx>
54#include <sfx2/msgpool.hxx>
55#include <sfx2/objface.hxx>
56#include <sfx2/request.hxx>
57#include <sfx2/sfxsids.hrc>
58#include <sfx2/viewfrm.hxx>
59#include <sfx2/viewsh.hxx>
60#include <svl/eitem.hxx>
61#include <svl/itemiter.hxx>
62#include <svl/itempool.hxx>
65#include <tools/debug.hxx>
66#include <vcl/idle.hxx>
67#include <vcl/menu.hxx>
68
69#include <sfxtypes.hxx>
70#include <slotserv.hxx>
71#include <workwin.hxx>
72
73typedef std::vector<SfxShell*> SfxShellStack_Impl;
74
75namespace {
76
77struct SfxToDo_Impl
78{
79 SfxShell* pCluster;
80 bool bPush;
81 bool bDelete;
82 bool bDeleted;
83 bool bUntil;
84
85 SfxToDo_Impl( bool bOpPush, bool bOpDelete, bool bOpUntil, SfxShell& rCluster )
86 : pCluster(&rCluster)
87 , bPush(bOpPush)
88 , bDelete(bOpDelete)
89 , bDeleted(false)
90 , bUntil(bOpUntil)
91 {}
92};
93
94struct SfxObjectBars_Impl
95{
96 ToolbarId eId; // ConfigId of the Toolbox
97 sal_uInt16 nPos;
98 SfxVisibilityFlags nFlags; // special visibility flags
99
100 SfxObjectBars_Impl() : eId(ToolbarId::None), nPos(0), nFlags(SfxVisibilityFlags::Invisible) {}
101};
102
103}
104
106{
107 //When the dispatched is locked, SfxRequests accumulate in aReqArr for
108 //later dispatch when unlocked via Post
109
110 //The pointers are typically deleted in Post, only if we never get around
111 //to posting them do we delete the unposted requests.
112 std::vector<std::unique_ptr<SfxRequest>>
114 SfxShellStack_Impl aStack; // active functionality
115 Idle aIdle { "sfx::SfxDispatcher_Impl aIdle" }; // for Flush
116 std::deque<SfxToDo_Impl> aToDoStack; // not processed Push/Pop
117 SfxViewFrame* pFrame; // NULL or associated Frame
119 xPoster; // Execute asynchronous
120 bool bFlushing; // sal_True during Flush //?
121 bool bUpdated; // Update_Impl has run
122 bool bLocked; // No Execute
123 bool bInvalidateOnUnlock; // because someone asked
124 bool bActive; // not to be confused with set!
125 bool* pInCallAliveFlag; // view the Destructor Stack
126 SfxObjectBars_Impl aObjBars[SFX_OBJECTBAR_MAX];
127 SfxObjectBars_Impl aFixedObjBars[SFX_OBJECTBAR_MAX];
128 std::vector<sal_uInt32> aChildWins;
129 bool bNoUI; // UI only from Parent Dispatcher
130 bool bReadOnly; // Document is ReadOnly
131 bool bQuiet; // Only use parent dispatcher
132
133 SfxSlotFilterState nFilterEnabling; // 1==filter enabled slots,
134 // 2==ReadOnlyDoc overturned
136 pFilterSIDs; // sorted Array of SIDs
139 std::deque< std::deque<SfxToDo_Impl> > aToDoCopyStack;
140};
141
146{
147 return xImp->bFlushed;
148}
149
156{
157 if (!xImp->bFlushed) FlushImpl();
158}
159
169
170{
172}
173
181
182{
183 return CheckVirtualStack(rShell);
184}
185
197{
198 return xImp->bLocked;
199}
200
207{
208 return !xImp->pFrame;
209}
210
214void SfxDispatcher::Call_Impl(SfxShell& rShell, const SfxSlot &rSlot, SfxRequest &rReq, bool bRecord)
215{
217
218 // The slot may be called (meaning enabled)
219 if ( !rSlot.IsMode(SfxSlotMode::FASTCALL) && !rShell.CanExecuteSlot_Impl(rSlot) && !rShell.IsConditionalFastCall(rReq) )
220 return;
221
222 if ( GetFrame() )
223 {
224 // Recording may start
225 css::uno::Reference< css::beans::XPropertySet > xSet(
226 GetFrame()->GetFrame().GetFrameInterface(),
227 css::uno::UNO_QUERY);
228
229 if ( xSet.is() )
230 {
231 css::uno::Any aProp = xSet->getPropertyValue("DispatchRecorderSupplier");
232 css::uno::Reference< css::frame::XDispatchRecorderSupplier > xSupplier;
233 css::uno::Reference< css::frame::XDispatchRecorder > xRecorder;
234 aProp >>= xSupplier;
235 if(xSupplier.is())
236 xRecorder = xSupplier->getDispatchRecorder();
237
238 if ( bRecord && xRecorder.is() && !rSlot.IsMode(SfxSlotMode::NORECORD) )
239 rReq.Record_Impl( rShell, rSlot, xRecorder, GetFrame() );
240 }
241 }
242 // Get all that is needed, because the slot may not have survived the
243 // Execute if it is a 'pseudo slot' for macros or verbs.
244 bool bAutoUpdate = rSlot.IsMode(SfxSlotMode::AUTOUPDATE);
245
246 // API-call parentheses and document-lock during the calls
247 {
248 // 'this' must respond in the Destructor
249 bool bThisDispatcherAlive = true;
250 bool *pOldInCallAliveFlag = xImp->pInCallAliveFlag;
251 xImp->pInCallAliveFlag = &bThisDispatcherAlive;
252
253 SfxExecFunc pFunc = rSlot.GetExecFnc();
254 (*pFunc)(&rShell, rReq);
255
256 // If 'this' is still alive
257 if ( bThisDispatcherAlive )
258 xImp->pInCallAliveFlag = pOldInCallAliveFlag;
259 else
260 {
261 if ( pOldInCallAliveFlag )
262 {
263 // also protect nested stack frames
264 *pOldInCallAliveFlag = false;
265 }
266
267 // do nothing after this object is dead
268 return;
269 }
270 }
271
272 if ( rReq.IsDone() )
273 {
274 SfxBindings *pBindings = GetBindings();
275
276 // When AutoUpdate update immediately
277 if ( bAutoUpdate && pBindings )
278 {
279 pBindings->Invalidate(rSlot.GetSlotId());
280 pBindings->Update(rSlot.GetSlotId());
281 }
282 }
283}
284
286{
287 xImp.reset(new SfxDispatcher_Impl);
288 xImp->bFlushed = true;
289
290 xImp->bFlushing = false;
291 xImp->bUpdated = false;
292 xImp->bLocked = false;
293 xImp->bActive = false;
294 xImp->bNoUI = false;
295 xImp->bReadOnly = false;
296 xImp->bQuiet = false;
297 xImp->pInCallAliveFlag = nullptr;
298 xImp->nFilterEnabling = SfxSlotFilterState::DISABLED;
299 xImp->nDisableFlags = SfxDisableFlags::NONE;
300
301 xImp->bInvalidateOnUnlock = false;
302
303 for (SfxObjectBars_Impl & rObjBar : xImp->aObjBars)
304 rObjBar.eId = ToolbarId::None;
305
306 xImp->xPoster = new SfxHintPoster(std::bind(&SfxDispatcher::PostMsgHandler, this, std::placeholders::_1));
307
308 xImp->aIdle.SetPriority(TaskPriority::HIGH_IDLE );
309 xImp->aIdle.SetInvokeHandler( LINK(this, SfxDispatcher, EventHdl_Impl ) );
310}
311
313{
315 xImp->pFrame = nullptr;
316}
317
322{
324 xImp->pFrame = pViewFrame;
325}
326
332{
333 SAL_INFO("sfx.control", "Delete Dispatcher " << reinterpret_cast<sal_Int64>(this));
334 DBG_ASSERT( !xImp->bActive, "deleting active Dispatcher" );
335
336 // So that no timer by Reschedule in PlugComm strikes the LeaveRegistrations
337 xImp->aIdle.Stop();
338 xImp->xPoster->SetEventHdl( std::function<void (std::unique_ptr<SfxRequest>)>() );
339
340 // Notify the stack variables in Call_Impl
341 if ( xImp->pInCallAliveFlag )
342 *xImp->pInCallAliveFlag = false;
343
344 // Get bindings and application
345 SfxApplication *pSfxApp = SfxGetpApp();
346 SfxBindings* pBindings = GetBindings();
347
348 // When not flushed, revive the bindings
349 if (pBindings && !pSfxApp->IsDowning() && !xImp->bFlushed)
350 pBindings->DLEAVEREGISTRATIONS();
351
352 // may unregister the bindings
353 while ( pBindings )
354 {
355 if ( pBindings->GetDispatcher_Impl() == this)
356 pBindings->SetDispatcher(nullptr);
357 pBindings = pBindings->GetSubBindings_Impl();
358 }
359}
360
381{
382 DBG_ASSERT( rShell.GetInterface(),
383 "pushing SfxShell without previous RegisterInterface()" );
384
385 bool bDelete = bool(nMode & SfxDispatcherPopFlags::POP_DELETE);
386 bool bUntil = bool(nMode & SfxDispatcherPopFlags::POP_UNTIL);
387 bool bPush = bool(nMode & SfxDispatcherPopFlags::PUSH);
388
389 SfxApplication *pSfxApp = SfxGetpApp();
390
391 SAL_INFO(
392 "sfx.control",
393 "-SfxDispatcher(" << this << (bPush ? ")::Push(" : ")::Pop(")
394 << (rShell.GetInterface()
395 ? rShell.GetInterface()->GetClassName() : SAL_STREAM(&rShell))
396 << (bDelete ? ") with delete" : ")")
397 << (bUntil ? " (up to)" : ""));
398
399 // same shell as on top of the to-do stack?
400 if(!xImp->aToDoStack.empty() && xImp->aToDoStack.front().pCluster == &rShell)
401 {
402 // cancel inverse actions
403 if ( xImp->aToDoStack.front().bPush != bPush )
404 xImp->aToDoStack.pop_front();
405 else
406 {
407 DBG_ASSERT( bPush, "SfxInterface pushed more than once" );
408 DBG_ASSERT( !bPush, "SfxInterface popped more than once" );
409 }
410 }
411 else
412 {
413 // Remember Action
414 xImp->aToDoStack.push_front( SfxToDo_Impl(bPush, bDelete, bUntil, rShell) );
415 if (xImp->bFlushed)
416 {
417 SAL_INFO("sfx.control", "Unflushed dispatcher!");
418 xImp->bFlushed = false;
419 xImp->bUpdated = false;
420
421 // Put bindings to sleep
422 SfxBindings* pBindings = GetBindings();
423 if ( pBindings )
424 pBindings->DENTERREGISTRATIONS();
425 }
426 }
427
428 if(!pSfxApp->IsDowning() && !xImp->aToDoStack.empty())
429 {
430 // No immediate update is requested
431 xImp->aIdle.Start();
432 }
433 else
434 {
435 // but to do nothing
436 xImp->aIdle.Stop();
437
438 // Bindings may wake up again
439 if(xImp->aToDoStack.empty())
440 {
441 SfxBindings* pBindings = GetBindings();
442 if ( pBindings )
443 pBindings->DLEAVEREGISTRATIONS();
444 }
445 }
446}
447
448
455IMPL_LINK_NOARG( SfxDispatcher, EventHdl_Impl, Timer *, void )
456{
457 Flush();
458 Update_Impl();
459 SfxBindings* pBindings = GetBindings();
460 if ( pBindings )
461 pBindings->StartUpdate_Impl();
462}
463
472{
474
475 SfxShellStack_Impl aStack( xImp->aStack );
476 for(std::deque<SfxToDo_Impl>::reverse_iterator i = xImp->aToDoStack.rbegin(); i != xImp->aToDoStack.rend(); ++i)
477 {
478 if(i->bPush)
479 aStack.push_back(i->pCluster);
480 else
481 {
482 SfxShell* pPopped(nullptr);
483 do
484 {
485 DBG_ASSERT( !aStack.empty(), "popping from empty stack" );
486 pPopped = aStack.back();
487 aStack.pop_back();
488 }
489 while(i->bUntil && pPopped != i->pCluster);
490 DBG_ASSERT(pPopped == i->pCluster, "popping unpushed SfxInterface");
491 }
492 }
493
494 bool bReturn = std::find(aStack.begin(), aStack.end(), &rShell) != aStack.end();
495 return bReturn;
496}
497
510sal_uInt16 SfxDispatcher::GetShellLevel(const SfxShell& rShell)
511{
513 Flush();
514
515 for ( size_t n = 0; n < xImp->aStack.size(); ++n )
516 if ( *( xImp->aStack.rbegin() + n ) == &rShell )
517 return n;
518
519 return USHRT_MAX;
520}
521
529SfxShell *SfxDispatcher::GetShell(sal_uInt16 nIdx) const
530{
531 sal_uInt16 nShellCount = xImp->aStack.size();
532 if ( nIdx < nShellCount )
533 return *(xImp->aStack.rbegin() + nIdx);
534 return nullptr;
535}
536
546{
547 if ( xImp->pFrame )
548 return &xImp->pFrame->GetBindings();
549 else
550 return nullptr;
551}
552
558{
559 return xImp->pFrame;
560}
561
574{
575 SFX_STACK(SfxDispatcher::DoActivate);
576 if ( bMDI )
577 {
578 SAL_INFO("sfx.control", "Activate Dispatcher " << reinterpret_cast<sal_Int64>(this));
579 DBG_ASSERT( !xImp->bActive, "Activation error" );
580
581 xImp->bActive = true;
582 xImp->bUpdated = false;
583 SfxBindings* pBindings = GetBindings();
584 if ( pBindings )
585 {
586 pBindings->SetDispatcher(this);
587 pBindings->SetActiveFrame( xImp->pFrame->GetFrame().GetFrameInterface() );
588 }
589 }
590 else
591 {
592 SAL_INFO("sfx.control", "Non-MDI-Activate Dispatcher " << reinterpret_cast<sal_Int64>(this));
593 }
594
595 if ( IsAppDispatcher() )
596 return;
597
598 for ( int i = int(xImp->aStack.size()) - 1; i >= 0; --i )
599 (*(xImp->aStack.rbegin() + i ))->DoActivate_Impl(xImp->pFrame, bMDI);
600
601 if ( bMDI && xImp->pFrame )
602 {
603 xImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( false, 1 );
604 }
605
606 if(!xImp->aToDoStack.empty())
607 {
608 // No immediate update is requested
609 xImp->aIdle.Start();
610 }
611}
612
625{
626 SFX_STACK(SfxDispatcher::DoDeactivate);
627
628 SfxApplication *pSfxApp = SfxGetpApp();
629
630 if ( bMDI )
631 {
632 SAL_INFO("sfx.control", "Deactivate Dispatcher " << this);
633 DBG_ASSERT( xImp->bActive, "Deactivate error" );
634 xImp->bActive = false;
635
636 if ( xImp->pFrame && !(xImp->pFrame->GetObjectShell()->IsInPlaceActive() ) )
637 {
638 SfxWorkWindow *pWorkWin = xImp->pFrame->GetFrame().GetWorkWindow_Impl();
639 if ( pWorkWin )
640 {
641 for (size_t n=0; n<xImp->aChildWins.size();)
642 {
643 SfxChildWindow *pWin = pWorkWin->GetChildWindow_Impl( static_cast<sal_uInt16>( xImp->aChildWins[n] & 0xFFFF ) );
644 if (!pWin || pWin->GetAlignment() == SfxChildAlignment::NOALIGNMENT)
645 xImp->aChildWins.erase(xImp->aChildWins.begin()+n);
646 else
647 n++;
648 }
649 }
650 }
651 }
652 else {
653 SAL_INFO("sfx.control", "Non-MDI-DeActivate Dispatcher " << this);
654 }
655
656 if ( IsAppDispatcher() && !pSfxApp->IsDowning() )
657 return;
658
659 for ( size_t i = 0; i < xImp->aStack.size(); ++i )
660 (*(xImp->aStack.rbegin() + i))->DoDeactivate_Impl(xImp->pFrame, bMDI);
661
662 bool bHidePopups = bMDI && xImp->pFrame;
663 if ( pNew && xImp->pFrame )
664 {
665 css::uno::Reference< css::frame::XFrame > xOldFrame =
666 pNew->GetFrame().GetFrameInterface()->getCreator();
667
668 css::uno::Reference< css::frame::XFrame > xMyFrame =
670
671 if ( xOldFrame == xMyFrame )
672 bHidePopups = false;
673 }
674
675 if ( bHidePopups )
676 {
677 xImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( true, 1 );
678 }
679
680 Flush();
681}
682
696bool SfxDispatcher::GetShellAndSlot_Impl(sal_uInt16 nSlot, SfxShell** ppShell,
697 const SfxSlot** ppSlot, bool bOwnShellsOnly, bool bRealSlot)
698{
700
701 Flush();
702 SfxSlotServer aSvr;
703 if ( FindServer_(nSlot, aSvr) )
704 {
705 if ( bOwnShellsOnly && aSvr.GetShellLevel() >= xImp->aStack.size() )
706 return false;
707
708 *ppShell = GetShell(aSvr.GetShellLevel());
709 *ppSlot = aSvr.GetSlot();
710 if ( nullptr == (*ppSlot)->GetExecFnc() && bRealSlot )
711 *ppSlot = (*ppShell)->GetInterface()->GetRealSlot(*ppSlot);
712 // Check only real slots as enum slots don't have an execute function!
713 return !bRealSlot || ((nullptr != *ppSlot) && (nullptr != (*ppSlot)->GetExecFnc()) );
714 }
715
716 return false;
717}
718
726void SfxDispatcher::Execute_(SfxShell& rShell, const SfxSlot& rSlot,
727 SfxRequest& rReq, SfxCallMode eCallMode)
728{
730 DBG_ASSERT( !xImp->bFlushing, "recursive call to dispatcher" );
731 DBG_ASSERT( xImp->aToDoStack.empty(), "unprepared InPlace _Execute" );
732
733 if ( IsLocked() )
734 return;
735
736 if ( bool(eCallMode & SfxCallMode::ASYNCHRON) ||
737 ( (eCallMode & SfxCallMode::SYNCHRON) == SfxCallMode::SLOT &&
739 {
740 sal_uInt16 nShellCount = xImp->aStack.size();
741 for ( sal_uInt16 n=0; n<nShellCount; n++ )
742 {
743 if ( &rShell == *(xImp->aStack.rbegin() + n) )
744 {
745 if ( bool(eCallMode & SfxCallMode::RECORD) )
746 rReq.AllowRecording( true );
747 xImp->xPoster->Post(std::make_unique<SfxRequest>(rReq));
748 return;
749 }
750 }
751 }
752 else
753 Call_Impl( rShell, rSlot, rReq, SfxCallMode::RECORD==(eCallMode&SfxCallMode::RECORD) );
754}
755
759static void MappedPut_Impl(SfxAllItemSet &rSet, const SfxPoolItem &rItem)
760{
761 // Put with mapped Which-Id if possible
762 const SfxItemPool *pPool = rSet.GetPool();
763 sal_uInt16 nWhich = rItem.Which();
764 if ( SfxItemPool::IsSlot(nWhich) )
765 nWhich = pPool->GetWhich(nWhich);
766 rSet.Put( rItem, nWhich );
767}
768
769const SfxSlot* SfxDispatcher::GetSlot( const OUString& rCommand )
770{
771 // Count the number of Shells on the linked Dispatcher
772 Flush();
773 sal_uInt16 nTotCount = xImp->aStack.size();
774
775 for ( sal_uInt16 i = 0; i < nTotCount; ++i )
776 {
777 if (SfxShell *pObjShell = GetShell(i))
778 {
779 SfxInterface *pIFace = pObjShell->GetInterface();
780 const SfxSlot *pSlot = pIFace->GetSlot( rCommand );
781 if ( pSlot )
782 return pSlot;
783 }
784 }
785
786 return nullptr;
787}
788
789const SfxPoolItem* SfxDispatcher::Execute(sal_uInt16 nSlot, SfxCallMode nCall,
790 SfxItemSet const * pArgs, SfxItemSet const * pInternalArgs, sal_uInt16 nModi)
791{
792 if ( IsLocked() )
793 return nullptr;
794
795 SfxShell *pShell = nullptr;
796 const SfxSlot *pSlot = nullptr;
797 if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, false, true ) )
798 {
799 SfxAllItemSet aSet( pShell->GetPool() );
800 if ( pArgs )
801 {
802 SfxItemIter aIter(*pArgs);
803 for ( const SfxPoolItem *pArg = aIter.GetCurItem();
804 pArg;
805 pArg = aIter.NextItem() )
806 MappedPut_Impl( aSet, *pArg );
807 }
808 SfxRequest aReq(nSlot, nCall, aSet);
809 if (pInternalArgs)
810 aReq.SetInternalArgs_Impl( *pInternalArgs );
811 aReq.SetModifier( nModi );
812
813 Execute_( *pShell, *pSlot, aReq, nCall );
814 return aReq.GetReturnValue();
815 }
816 return nullptr;
817}
818
833const SfxPoolItem* SfxDispatcher::Execute(sal_uInt16 nSlot, SfxCallMode eCall,
834 const SfxPoolItem **pArgs, sal_uInt16 nModi, const SfxPoolItem **pInternalArgs)
835{
836 if ( IsLocked() )
837 return nullptr;
838
839 SfxShell *pShell = nullptr;
840 const SfxSlot *pSlot = nullptr;
841 if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, false, true ) )
842 {
843 std::unique_ptr<SfxRequest> pReq;
844 if ( pArgs && *pArgs )
845 {
846 SfxAllItemSet aSet( pShell->GetPool() );
847 for ( const SfxPoolItem **pArg = pArgs; *pArg; ++pArg )
848 MappedPut_Impl( aSet, **pArg );
849 pReq.reset(new SfxRequest( nSlot, eCall, aSet ));
850 }
851 else
852 pReq.reset(new SfxRequest( nSlot, eCall, pShell->GetPool() ));
853 pReq->SetModifier( nModi );
854 if( pInternalArgs && *pInternalArgs)
855 {
856 SfxAllItemSet aSet( SfxGetpApp()->GetPool() );
857 for ( const SfxPoolItem **pArg = pInternalArgs; *pArg; ++pArg )
858 aSet.Put( **pArg );
859 pReq->SetInternalArgs_Impl( aSet );
860 }
861 Execute_( *pShell, *pSlot, *pReq, eCall );
862 const SfxPoolItem* pRet = pReq->GetReturnValue();
863 return pRet;
864 }
865 return nullptr;
866}
867
881const SfxPoolItem* SfxDispatcher::Execute(sal_uInt16 nSlot, SfxCallMode eCall,
882 const SfxItemSet &rArgs)
883{
884 if ( IsLocked() )
885 return nullptr;
886
887 SfxShell *pShell = nullptr;
888 const SfxSlot *pSlot = nullptr;
889 if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, false, true ) )
890 {
891 SfxAllItemSet aSet( pShell->GetPool() );
892 SfxItemIter aIter(rArgs);
893 for ( const SfxPoolItem *pArg = aIter.GetCurItem();
894 pArg;
895 pArg = aIter.NextItem() )
896 MappedPut_Impl( aSet, *pArg );
897 SfxRequest aReq( nSlot, eCall, aSet );
898 aReq.SetModifier( 0 );
899 Execute_( *pShell, *pSlot, aReq, eCall );
900 return aReq.GetReturnValue();
901 }
902 return nullptr;
903}
904
932 std::initializer_list<SfxPoolItem const*> args,
933 std::initializer_list<SfxPoolItem const*> internalargs)
934{
935 if ( IsLocked() )
936 return nullptr;
937
938 SfxShell *pShell = nullptr;
939 const SfxSlot *pSlot = nullptr;
940 if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, false, true ) )
941 {
942 SfxAllItemSet aSet( pShell->GetPool() );
943
944 for (const SfxPoolItem *pArg : args)
945 {
946 assert(pArg);
947 MappedPut_Impl( aSet, *pArg );
948 }
949
950 SfxRequest aReq(nSlot, eCall, aSet);
951
952 if (internalargs.begin() != internalargs.end())
953 {
954 SfxAllItemSet aInternalSet(SfxGetpApp()->GetPool());
955 for (const SfxPoolItem *pArg : internalargs)
956 {
957 assert(pArg);
958 aInternalSet.Put(*pArg);
959 }
960 aReq.SetInternalArgs_Impl(aInternalSet);
961 }
962
963 Execute_( *pShell, *pSlot, aReq, eCall );
964 return aReq.GetReturnValue();
965 }
966 return nullptr;
967}
968
971void SfxDispatcher::PostMsgHandler(std::unique_ptr<SfxRequest> pReq)
972{
973 DBG_ASSERT( !xImp->bFlushing, "recursive call to dispatcher" );
975
976 // Has also the Pool not yet died?
977 if ( pReq->IsCancelled() )
978 return;
979
980 if ( !IsLocked() )
981 {
982 Flush();
983 SfxSlotServer aSvr;
984 if ( FindServer_(pReq->GetSlot(), aSvr ) ) // HACK(x), whatever that was supposed to mean
985 {
986 const SfxSlot *pSlot = aSvr.GetSlot();
987 SfxShell *pSh = GetShell(aSvr.GetShellLevel());
988
989 // When the pSlot is a "Pseudoslot" for macros or Verbs, it can
990 // be destroyed in the Call_Impl, thus do not use it anymore!
991 pReq->SetSynchronCall( false );
992 Call_Impl( *pSh, *pSlot, *pReq, pReq->AllowsRecording() );
993 }
994 }
995 else
996 {
997 if ( xImp->bLocked )
998 xImp->aReqArr.emplace_back(std::move(pReq));
999 else
1000 xImp->xPoster->Post(std::move(pReq));
1001 }
1002}
1003
1005{
1006#if HAVE_FEATURE_DESKTOP
1007 if ( !xImp->pFrame )
1008 return;
1009
1010 SfxViewFrame* pTop = xImp->pFrame->GetTopViewFrame();
1011 if ( !pTop || pTop->GetBindings().GetDispatcher() != this )
1012 return;
1013
1014 SfxFrame& rFrame = pTop->GetFrame();
1015 if ( !rFrame.IsMenuBarOn_Impl() )
1016 return;
1017
1018 css::uno::Reference < css::beans::XPropertySet > xPropSet( rFrame.GetFrameInterface(), css::uno::UNO_QUERY );
1019 if ( xPropSet.is() )
1020 {
1021 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
1022 css::uno::Any aValue = xPropSet->getPropertyValue("LayoutManager");
1023 aValue >>= xLayoutManager;
1024 if ( xLayoutManager.is() )
1025 {
1026 OUString aMenuBarURL( "private:resource/menubar/menubar" );
1027 if ( !xLayoutManager->isElementVisible( aMenuBarURL ) )
1028 xLayoutManager->createElement( aMenuBarURL );
1029 }
1030 }
1031#endif
1032}
1033
1035{
1037
1038 Flush();
1039
1040 if ( !xImp->pFrame )
1041 return;
1042
1043 bool bUpdate = bForce;
1044 if ( xImp->pFrame )
1045 {
1046 SfxWorkWindow *pWork = xImp->pFrame->GetFrame().GetWorkWindow_Impl();
1047 SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
1048 if (pAct == this)
1049 {
1050 if ( !bUpdate )
1051 bUpdate = !xImp->bUpdated;
1052 xImp->bUpdated = true;
1053 }
1054 }
1055
1056 if ( !bUpdate || xImp->pFrame->GetFrame().IsClosing_Impl() )
1057 return;
1058
1059 SfxViewFrame* pTop = xImp->pFrame ? xImp->pFrame->GetTopViewFrame() : nullptr;
1060 bool bUIActive = pTop && pTop->GetBindings().GetDispatcher() == this;
1061
1062 if ( !bUIActive && pTop && GetBindings() == &pTop->GetBindings() )
1063 // keep own tools internally for collecting
1064 GetBindings()->GetDispatcher()->xImp->bUpdated = false;
1065
1066 css::uno::Reference< css::frame::XFrame > xFrame;
1067 SfxBindings* pBindings = GetBindings();
1068 if (pBindings)
1069 {
1070 pBindings->DENTERREGISTRATIONS();
1071 xFrame = pBindings->GetActiveFrame();
1072 }
1073 css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY );
1074 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
1075 if ( xPropSet.is() )
1076 {
1077 try
1078 {
1079 css::uno::Any aValue = xPropSet->getPropertyValue("LayoutManager");
1080 aValue >>= xLayoutManager;
1081 }
1082 catch (const css::uno::Exception&)
1083 {
1084 }
1085 }
1086
1087 if ( xLayoutManager.is() )
1088 xLayoutManager->lock();
1089
1090 bool bIsIPActive = xImp->pFrame && xImp->pFrame->GetObjectShell()->IsInPlaceActive();
1091 SfxInPlaceClient *pClient = xImp->pFrame ? xImp->pFrame->GetViewShell()->GetUIActiveClient() : nullptr;
1092 if ( bUIActive && /* !bIsIPActive && */ ( !pClient || !pClient->IsObjectUIActive() ) )
1093 SetMenu_Impl();
1094
1095 SfxWorkWindow *pWorkWin = xImp->pFrame->GetFrame().GetWorkWindow_Impl();
1096 pWorkWin->ResetStatusBar_Impl();
1097
1098 {
1099 SfxWorkWindow *pWork = xImp->pFrame->GetFrame().GetWorkWindow_Impl();
1100 SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
1101 if (pAct == this)
1102 {
1103 pWork->ResetObjectBars_Impl();
1104 pWork->ResetChildWindows_Impl();
1105 }
1106 }
1107
1108 bool bIsActive = false;
1109 SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
1110 if ( !bIsActive && this == pActDispat )
1111 bIsActive = true;
1112
1113 Update_Impl_( bUIActive, !bIsIPActive, bIsIPActive, pWorkWin );
1114 if (bUIActive || bIsActive)
1115 pWorkWin->UpdateObjectBars_Impl();
1116
1117 if ( pBindings )
1118 pBindings->DLEAVEREGISTRATIONS();
1119
1120 if ( xLayoutManager.is() )
1121 xLayoutManager->unlock();
1122
1124 {
1125 const SfxPoolItem *pItem;
1126 SfxViewShell::Current()->GetDispatcher()->QueryState(SID_NOTEBOOKBAR, pItem);
1127 }
1128}
1129
1130void SfxDispatcher::Update_Impl_( bool bUIActive, bool bIsMDIApp, bool bIsIPOwner, SfxWorkWindow *pTaskWin )
1131{
1132 SfxWorkWindow *pWorkWin = xImp->pFrame->GetFrame().GetWorkWindow_Impl();
1133 bool bIsActive = false;
1134 SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
1135 if ( pActDispat && !bIsActive )
1136 {
1137 if ( this == pActDispat )
1138 bIsActive = true;
1139 }
1140
1141 for (SfxObjectBars_Impl & rObjBar : xImp->aObjBars)
1142 rObjBar.eId = ToolbarId::None;
1143 xImp->aChildWins.clear();
1144
1145 // bQuiet: own shells aren't considered for UI and SlotServer
1146 // bNoUI: own Shells aren't considered forms UI
1147 if ( xImp->bQuiet || xImp->bNoUI || (xImp->pFrame && xImp->pFrame->GetObjectShell()->IsPreview()) )
1148 return;
1149
1150 StatusBarId eStatBarId = StatusBarId::None;
1151
1153 sal_uInt16 nTotCount = xImp->aStack.size();
1154 for ( sal_uInt16 nShell = nTotCount; nShell > 0; --nShell )
1155 {
1156 SfxShell *pShell = GetShell( nShell-1 );
1157 if (!pShell)
1158 continue;
1159
1160 SfxInterface *pIFace = pShell->GetInterface();
1161
1162 // don't consider shells if "Hidden" or "Quiet"
1163 bool bReadOnlyShell = IsReadOnlyShell_Impl( nShell-1 );
1164 sal_uInt16 nNo;
1165 for ( nNo = 0; pIFace && nNo<pIFace->GetObjectBarCount(); ++nNo )
1166 {
1167 sal_uInt16 nPos = pIFace->GetObjectBarPos(nNo);
1168 SfxVisibilityFlags nFlags = pIFace->GetObjectBarFlags(nNo);
1169 if ( bReadOnlyShell && !( nFlags & SfxVisibilityFlags::ReadonlyDoc ) )
1170 continue;
1171
1172 // check whether toolbar needs activation of a special feature
1173 SfxShellFeature nFeature = pIFace->GetObjectBarFeature(nNo);
1174 if ((nFeature != SfxShellFeature::NONE) && !pShell->HasUIFeature(nFeature))
1175 continue;
1176
1177 // check for toolboxes that are exclusively for a viewer
1178 if ( xImp->pFrame)
1179 {
1180 bool bViewerTbx( nFlags & SfxVisibilityFlags::Viewer );
1181 SfxObjectShell* pSh = xImp->pFrame->GetObjectShell();
1182 const SfxBoolItem* pItem = pSh->GetMedium()->GetItemSet().GetItem(SID_VIEWONLY, false);
1183 bool bIsViewer = pItem && pItem->GetValue();
1184 if ( bIsViewer != bViewerTbx )
1185 continue;
1186 }
1187
1188 // always register toolbars, allows to switch them on
1189 bool bVisible = pIFace->IsObjectBarVisible(nNo);
1190 if ( !bVisible )
1192
1193 SfxObjectBars_Impl& rBar = xImp->aObjBars[nPos];
1194 rBar.nPos = nPos;
1195 rBar.nFlags = nFlags;
1196 rBar.eId = pIFace->GetObjectBarId(nNo);
1197
1198 if ( bUIActive || bIsActive )
1199 {
1200 pWorkWin->SetObjectBar_Impl(nPos, nFlags, rBar.eId);
1201 }
1202
1203 if ( !bVisible )
1204 rBar.eId = ToolbarId::None;
1205 }
1206
1207 for ( nNo=0; pIFace && nNo<pIFace->GetChildWindowCount(); nNo++ )
1208 {
1209 sal_uInt32 nId = pIFace->GetChildWindowId(nNo);
1210 const SfxSlot *pSlot = pSlotPool->GetSlot( static_cast<sal_uInt16>(nId) );
1211 SAL_WARN_IF( !pSlot, "sfx.control", "Childwindow slot missing: " << nId );
1212 if ( bReadOnlyShell )
1213 {
1214 // only show ChildWindows if their slot is allowed for readonly documents
1215 if ( pSlot && !pSlot->IsMode( SfxSlotMode::READONLYDOC ) )
1216 continue;
1217 }
1218
1219 SfxShellFeature nFeature = pIFace->GetChildWindowFeature(nNo);
1220 if ((nFeature != SfxShellFeature::NONE) && !pShell->HasUIFeature(nFeature))
1221 continue;
1222
1223 // slot decides whether a ChildWindow is shown when document is OLE server or OLE client
1225 if( pSlot )
1226 {
1227 if ( pSlot->IsMode(SfxSlotMode::CONTAINER) )
1228 {
1229 if ( pWorkWin->IsVisible_Impl( SfxVisibilityFlags::Client ) )
1231 }
1232 else
1233 {
1234 if ( pWorkWin->IsVisible_Impl( SfxVisibilityFlags::Server ) )
1236 }
1237 }
1238
1239 if ( bUIActive || bIsActive )
1240 pWorkWin->SetChildWindowVisible_Impl( nId, true, nMode );
1241 if ( bUIActive || bIsActive || !pWorkWin->IsFloating( static_cast<sal_uInt16>( nId & 0xFFFF ) ) )
1242 xImp->aChildWins.push_back( nId );
1243 }
1244
1245 if ( bIsMDIApp || bIsIPOwner )
1246 {
1247 StatusBarId eId = pIFace ? pIFace->GetStatusBarId() : StatusBarId::None;
1248 if (eId != StatusBarId::None)
1249 eStatBarId = eId;
1250 }
1251 }
1252
1253 for ( sal_uInt16 nPos=0; nPos<SFX_OBJECTBAR_MAX; nPos++ )
1254 {
1255 SfxObjectBars_Impl& rFixed = xImp->aFixedObjBars[nPos];
1256 if (rFixed.eId != ToolbarId::None)
1257 {
1258 SfxObjectBars_Impl& rBar = xImp->aObjBars[nPos];
1259 rBar = rFixed;
1260 pWorkWin->SetObjectBar_Impl(rFixed.nPos, rFixed.nFlags,
1261 rFixed.eId);
1262 }
1263 }
1264
1265 if ( !pTaskWin || ( !bIsMDIApp && !bIsIPOwner ) )
1266 return;
1267
1268 bool bIsTaskActive = false;
1269
1270 SfxDispatcher *pActDispatcher = pTaskWin->GetBindings().GetDispatcher_Impl();
1271 if ( pActDispatcher && !bIsTaskActive )
1272 {
1273 if ( this == pActDispatcher )
1274 bIsTaskActive = true;
1275 }
1276
1277 if (bIsTaskActive && eStatBarId != StatusBarId::None && xImp->pFrame)
1278 {
1279 // internal frames also may control statusbar
1280 xImp->pFrame->GetFrame().GetWorkWindow_Impl()->SetStatusBar_Impl(eStatBarId);
1281 }
1282}
1283
1287{
1289
1290 SAL_INFO("sfx.control", "Flushing dispatcher!");
1291
1292 xImp->aIdle.Stop();
1293
1294 xImp->bFlushing = !xImp->bFlushing;
1295 if ( !xImp->bFlushing )
1296 {
1297 xImp->bFlushing = true;
1298 return;
1299 }
1300
1301 SfxApplication *pSfxApp = SfxGetpApp();
1302
1303 // Re-build the true stack in the first round
1304 std::deque<SfxToDo_Impl> aToDoCopy;
1305 bool bModify = false;
1306 for(std::deque<SfxToDo_Impl>::reverse_iterator i = xImp->aToDoStack.rbegin(); i != xImp->aToDoStack.rend(); ++i)
1307 {
1308 bModify = true;
1309
1310 if(i->bPush)
1311 {
1312 // Actually push
1313 DBG_ASSERT( std::find(xImp->aStack.begin(), xImp->aStack.end(), i->pCluster) == xImp->aStack.end(),
1314 "pushed SfxShell already on stack" );
1315 xImp->aStack.push_back(i->pCluster);
1316 i->pCluster->SetDisableFlags(xImp->nDisableFlags);
1317
1318 // Mark the moved shell
1319 aToDoCopy.push_front(*i);
1320 }
1321 else
1322 {
1323 // Actually pop
1324 bool bFound = false;
1325 if (!i->bUntil)
1326 {
1327 // pop exactly the requested shell
1328 if (auto it = std::find(xImp->aStack.begin(), xImp->aStack.end(), i->pCluster);
1329 it != xImp->aStack.end())
1330 {
1331 xImp->aStack.erase(it);
1332 i->pCluster->SetDisableFlags(SfxDisableFlags::NONE);
1333 bFound = true;
1334
1335 // Mark the moved Shell
1336 aToDoCopy.push_front(SfxToDo_Impl(false, i->bDelete, false, *i->pCluster));
1337 }
1338 }
1339 while (!bFound)
1340 {
1341 DBG_ASSERT( !xImp->aStack.empty(), "popping from empty stack" );
1342 SfxShell* pPopped = xImp->aStack.back();
1343 xImp->aStack.pop_back();
1345 bFound = (pPopped == i->pCluster);
1346
1347 // Mark the moved Shell
1348 aToDoCopy.push_front(SfxToDo_Impl(false, i->bDelete, false, *pPopped));
1349 if (!i->bUntil)
1350 {
1351 // We get here only when the requested shell was not on the stack.
1352 // I don't know how correct to pop a single random other shell and exit
1353 // in this case, but I just make sure that the previous logic is kept.
1354 break;
1355 }
1356 }
1357 DBG_ASSERT( bFound, "wrong SfxShell popped" );
1358 }
1359 }
1360 xImp->aToDoStack.clear();
1361
1362 // Invalidate bindings, if possible
1363 if ( !pSfxApp->IsDowning() )
1364 {
1365 InvalidateBindings_Impl( bModify );
1366 }
1367
1368 xImp->bFlushing = false;
1369 xImp->bUpdated = false; // not only when bModify, if Doc/Template-Config
1370 xImp->bFlushed = true;
1371 SAL_INFO("sfx.control", "Successfully flushed dispatcher!");
1372
1373 //fdo#70703 FlushImpl may call back into itself so use aToDoCopyStack to talk
1374 //to outer levels of ourself. If DoActivate_Impl/DoDeactivate_Impl deletes
1375 //an entry, then they will walk back up aToDoCopyStack and set outer
1376 //levels's entries to bDeleted
1377 xImp->aToDoCopyStack.push_back(aToDoCopy);
1378 std::deque<SfxToDo_Impl>& rToDoCopy = xImp->aToDoCopyStack.back();
1379 // Activate the Shells and possible delete them in the 2nd round
1380 for(std::deque<SfxToDo_Impl>::reverse_iterator i = rToDoCopy.rbegin(); i != rToDoCopy.rend(); ++i)
1381 {
1382 if (i->bDeleted)
1383 continue;
1384 if (!xImp->bActive)
1385 continue;
1386 if (i->bPush)
1387 i->pCluster->DoActivate_Impl(xImp->pFrame, true);
1388 else
1389 i->pCluster->DoDeactivate_Impl(xImp->pFrame, true);
1390 }
1391
1392 aToDoCopy = xImp->aToDoCopyStack.back();
1393 xImp->aToDoCopyStack.pop_back();
1394
1395 for(std::deque<SfxToDo_Impl>::reverse_iterator i = aToDoCopy.rbegin(); i != aToDoCopy.rend(); ++i)
1396 {
1397 if (i->bDelete && !i->bDeleted)
1398 {
1399 if (!xImp->aToDoCopyStack.empty())
1400 {
1401 //fdo#70703 if there is an outer FlushImpl then inform it that
1402 //we have deleted this cluster
1403 for (auto & elem : xImp->aToDoCopyStack)
1404 {
1405 for (auto & subelem : elem)
1406 {
1407 if (subelem.pCluster == i->pCluster)
1408 subelem.bDeleted = true;
1409 }
1410 }
1411 }
1412 delete i->pCluster;
1413 }
1414 }
1415 bool bAwakeBindings = !aToDoCopy.empty();
1416 if( bAwakeBindings )
1417 aToDoCopy.clear();
1418
1419 // If more changes have occurred on the stack when
1420 // Activate/Deactivate/Delete:
1421 if (!xImp->bFlushed)
1422 // If Push/Pop has been called by someone, then also EnterReg was called!
1423 FlushImpl();
1424
1425 if( bAwakeBindings && GetBindings() )
1426 GetBindings()->DLEAVEREGISTRATIONS();
1427
1428 for (SfxObjectBars_Impl & rFixedObjBar : xImp->aFixedObjBars)
1429 rFixedObjBar.eId = ToolbarId::None;
1430
1431 SAL_INFO("sfx.control", "SfxDispatcher(" << this << ")::Flush() done");
1432}
1433
1467{
1468#ifdef DBG_UTIL
1469 // Check Array
1470 for ( std::size_t n = 1; n < pSIDs.size(); ++n )
1471 DBG_ASSERT( pSIDs[n] > pSIDs[n-1], "SetSlotFilter: SIDs not sorted" );
1472#endif
1473
1474 xImp->nFilterEnabling = nEnable;
1475 xImp->pFilterSIDs = pSIDs;
1476
1477 GetBindings()->InvalidateAll(true);
1478}
1479
1480extern "C" {
1481
1482static int SfxCompareSIDs_Impl(const void* pSmaller, const void* pBigger)
1483{
1484 return static_cast<tools::Long>(*static_cast<sal_uInt16 const *>(pSmaller)) - static_cast<tools::Long>(*static_cast<sal_uInt16 const *>(pBigger));
1485}
1486
1487}
1488
1498{
1499 // no filter?
1500 if ( xImp->pFilterSIDs.empty() )
1501 // => all SIDs allowed
1503
1504 // search
1505 bool bFound = nullptr != bsearch( &nSID, xImp->pFilterSIDs.data(), xImp->pFilterSIDs.size(),
1506 sizeof(sal_uInt16), SfxCompareSIDs_Impl );
1507
1508 // even if ReadOnlyDoc
1509 if ( SfxSlotFilterState::ENABLED_READONLY == xImp->nFilterEnabling )
1511 // Otherwise after Negative/Positive Filter
1512 else if ( SfxSlotFilterState::ENABLED == xImp->nFilterEnabling )
1514 else
1516}
1517
1535bool SfxDispatcher::FindServer_(sal_uInt16 nSlot, SfxSlotServer& rServer)
1536{
1538
1539 // Dispatcher locked? (nevertheless let SID_HELP_PI through)
1540 if ( IsLocked() )
1541 {
1542 xImp->bInvalidateOnUnlock = true;
1543 return false;
1544 }
1545
1546 // Count the number of Shells in the linked dispatchers.
1547 Flush();
1548 sal_uInt16 nTotCount = xImp->aStack.size();
1549
1550 // Verb-Slot?
1551 if (nSlot >= SID_VERB_START && nSlot <= SID_VERB_END)
1552 {
1553 for ( sal_uInt16 nShell = 0;; ++nShell )
1554 {
1555 SfxShell *pSh = GetShell(nShell);
1556 if ( pSh == nullptr )
1557 return false;
1558 if ( dynamic_cast< const SfxViewShell *>( pSh ) != nullptr )
1559 {
1560 const SfxSlot* pSlot = pSh->GetVerbSlot_Impl(nSlot);
1561 if ( pSlot )
1562 {
1563 rServer.SetShellLevel(nShell);
1564 rServer.SetSlot( pSlot );
1565 return true;
1566 }
1567 }
1568 }
1569 }
1570
1571 // SID check against set filter
1573 if ( xImp->pFrame )
1574 {
1575 nSlotEnableMode = IsSlotEnabledByFilter_Impl( nSlot );
1576 if ( SfxSlotFilterState::DISABLED == nSlotEnableMode )
1577 return false;
1578 }
1579
1580 // In Quiet-Mode only Parent-Dispatcher
1581 if ( xImp->bQuiet )
1582 {
1583 return false;
1584 }
1585
1586 bool bReadOnly = ( SfxSlotFilterState::ENABLED_READONLY != nSlotEnableMode && xImp->bReadOnly );
1587
1588 // search through all the shells of the chained dispatchers
1589 // from top to bottom
1590 sal_uInt16 nFirstShell = 0;
1591 for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
1592 {
1593 SfxShell *pObjShell = GetShell(i);
1594 if (!pObjShell)
1595 continue;
1596
1597 SfxInterface *pIFace = pObjShell->GetInterface();
1598 const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
1599
1600 if ( pSlot && pSlot->nDisableFlags != SfxDisableFlags::NONE &&
1601 ( static_cast<int>(pSlot->nDisableFlags) & static_cast<int>(pObjShell->GetDisableFlags()) ) != 0 )
1602 return false;
1603
1604 if ( pSlot && !( pSlot->nFlags & SfxSlotMode::READONLYDOC ) && bReadOnly )
1605 return false;
1606
1607 if ( pSlot )
1608 {
1609 // Slot belongs to Container?
1610 bool bIsContainerSlot = pSlot->IsMode(SfxSlotMode::CONTAINER);
1611 bool bIsInPlace = xImp->pFrame && xImp->pFrame->GetObjectShell()->IsInPlaceActive();
1612
1613 // Shell belongs to Server?
1614 // AppDispatcher or IPFrame-Dispatcher
1615 bool bIsServerShell = !xImp->pFrame || bIsInPlace;
1616
1617 // Of course ShellServer-Slots are also executable even when it is
1618 // executed on a container dispatcher without an IPClient.
1619 if ( !bIsServerShell )
1620 {
1621 SfxViewShell *pViewSh = xImp->pFrame->GetViewShell();
1622 bIsServerShell = !pViewSh || !pViewSh->GetUIActiveClient();
1623 }
1624
1625 // Shell belongs to Container?
1626 // AppDispatcher or no IPFrameDispatcher
1627 bool bIsContainerShell = !xImp->pFrame || !bIsInPlace;
1628 // Shell and Slot match
1629 if ( !( ( bIsContainerSlot && bIsContainerShell ) ||
1630 ( !bIsContainerSlot && bIsServerShell ) ) )
1631 pSlot = nullptr;
1632 }
1633
1634 if ( pSlot )
1635 {
1636 rServer.SetSlot(pSlot);
1637 rServer.SetShellLevel(i);
1638 return true;
1639 }
1640 }
1641
1642 return false;
1643}
1644
1656 const SfxSlot* pRealSlot)
1657{
1659
1660 const SfxSlot *pSlot = rSvr.GetSlot();
1661 if ( pSlot && IsLocked() )
1662 {
1663 xImp->bInvalidateOnUnlock = true;
1664 return false;
1665 }
1666
1667 if ( pSlot )
1668 {
1669 DBG_ASSERT(xImp->bFlushed,
1670 "Dispatcher not flushed after retrieving slot servers!");
1671 if (!xImp->bFlushed)
1672 return false;
1673
1674 // Determine the object and call the Message of this object
1675 SfxShell *pSh = GetShell(rSvr.GetShellLevel());
1676 if (!pSh)
1677 return false;
1678
1679 SfxStateFunc pFunc;
1680
1681 if (pRealSlot)
1682 pFunc = pRealSlot->GetStateFnc();
1683 else
1684 pFunc = pSlot->GetStateFnc();
1685
1686 (*pFunc)(pSh, rState);
1687#ifdef DBG_UTIL
1688 // To examine the conformity of IDL (SlotMap) and current Items
1689 if ( rState.Count() )
1690 {
1691 SfxInterface *pIF = pSh->GetInterface();
1692 SfxItemIter aIter( rState );
1693 for ( const SfxPoolItem *pItem = aIter.GetCurItem();
1694 pItem;
1695 pItem = aIter.NextItem() )
1696 {
1697 if ( !IsInvalidItem(pItem) && !pItem->IsVoidItem() )
1698 {
1699 sal_uInt16 nSlotId = rState.GetPool()->GetSlotId(pItem->Which());
1701 typeid(pItem) != *pIF->GetSlot(nSlotId)->GetType()->Type(),
1702 "sfx.control",
1703 "item-type unequal to IDL (=> no BASIC) with SID: "
1704 << nSlotId << " in " << pIF->GetClassName());
1705 }
1706 }
1707 }
1708#endif
1709
1710 return true;
1711 }
1712
1713 return false;
1714}
1715
1717{
1719 sal_uInt16 nShLevel = 0;
1720 SfxShell *pSh;
1721
1722 if ( rDisp.xImp->bQuiet )
1723 nShLevel = rDisp.xImp->aStack.size();
1724
1725 for ( pSh = rDisp.GetShell(nShLevel); pSh; ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
1726 {
1727 const OUString& rResName = pSh->GetInterface()->GetPopupMenuName();
1728 if ( !rResName.isEmpty() )
1729 {
1730 rDisp.ExecutePopup( rResName, pWin, pPos );
1731 return;
1732 }
1733 }
1734}
1735
1736namespace {
1737
1738boost::property_tree::ptree fillPopupMenu(Menu* pMenu)
1739{
1740 // Activate this menu first
1741 pMenu->HandleMenuActivateEvent(pMenu);
1742 pMenu->HandleMenuDeActivateEvent(pMenu);
1743
1744 boost::property_tree::ptree aTree;
1745 // If last item inserted is some valid text
1746 bool bIsLastItemText = false;
1747 sal_uInt16 nCount = pMenu->GetItemCount();
1748 for (sal_uInt16 nPos = 0; nPos < nCount; nPos++)
1749 {
1750 boost::property_tree::ptree aItemTree;
1751 const MenuItemType aItemType = pMenu->GetItemType(nPos);
1752
1753 if (aItemType == MenuItemType::DONTKNOW)
1754 continue;
1755
1756 if (aItemType == MenuItemType::SEPARATOR)
1757 {
1758 if (bIsLastItemText)
1759 aItemTree.put("type", "separator");
1760 bIsLastItemText = false;
1761 }
1762 else
1763 {
1764 const sal_uInt16 nItemId = pMenu->GetItemId(nPos);
1765 OUString aCommandURL = pMenu->GetItemCommand(nItemId);
1766
1767 if (aCommandURL.isEmpty())
1768 {
1769 const SfxSlot *pSlot = SFX_SLOTPOOL().GetSlot(nItemId);
1770 if (pSlot)
1771 aCommandURL = pSlot->GetCommand();
1772 }
1773
1774 const OUString aItemText = pMenu->GetItemText(nItemId);
1775 Menu* pPopupSubmenu = pMenu->GetPopupMenu(nItemId);
1776
1777 if (!aItemText.isEmpty())
1778 aItemTree.put("text", aItemText.toUtf8().getStr());
1779
1780 if (pPopupSubmenu)
1781 {
1782 boost::property_tree::ptree aSubmenu = ::fillPopupMenu(pPopupSubmenu);
1783 if (aSubmenu.empty())
1784 continue;
1785
1786 aItemTree.put("type", "menu");
1787 if (!aCommandURL.isEmpty())
1788 aItemTree.put("command", aCommandURL.toUtf8().getStr());
1789 aItemTree.push_back(std::make_pair("menu", aSubmenu));
1790 }
1791 else
1792 {
1793 // no point in exposing choices that don't have the .uno:
1794 // command
1795 if (aCommandURL.isEmpty())
1796 continue;
1797
1798 aItemTree.put("type", "command");
1799 aItemTree.put("command", aCommandURL.toUtf8().getStr());
1800 }
1801
1802 aItemTree.put("enabled", pMenu->IsItemEnabled(nItemId));
1803
1804 MenuItemBits aItemBits = pMenu->GetItemBits(nItemId);
1805 bool bHasChecks = true;
1806 if (aItemBits & MenuItemBits::CHECKABLE)
1807 aItemTree.put("checktype", "checkmark");
1808 else if (aItemBits & MenuItemBits::RADIOCHECK)
1809 aItemTree.put("checktype", "radio");
1810 else if (aItemBits & MenuItemBits::AUTOCHECK)
1811 aItemTree.put("checktype", "auto");
1812 else
1813 bHasChecks = false;
1814
1815 if (bHasChecks)
1816 aItemTree.put("checked", pMenu->IsItemChecked(nItemId));
1817 }
1818
1819 if (!aItemTree.empty())
1820 {
1821 aTree.push_back(std::make_pair("", aItemTree));
1822 if (aItemType != MenuItemType::SEPARATOR)
1823 bIsLastItemText = true;
1824 }
1825 }
1826
1827 return aTree;
1828}
1829
1830}
1831
1832boost::property_tree::ptree SfxDispatcher::fillPopupMenu(const rtl::Reference<VCLXPopupMenu>& rPopupMenu)
1833{
1834 PopupMenu* pVCLMenu = static_cast<PopupMenu*>(rPopupMenu->GetMenu());
1835 return ::fillPopupMenu(pVCLMenu);
1836}
1837
1838void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin, const Point* pPos )
1839{
1840 css::uno::Sequence< css::uno::Any > aArgs{
1841 css::uno::Any(comphelper::makePropertyValue( "Value", rResName )),
1842 css::uno::Any(comphelper::makePropertyValue( "Frame", GetFrame()->GetFrame().GetFrameInterface() )),
1843 css::uno::Any(comphelper::makePropertyValue( "IsContextMenu", true ))
1844 };
1845
1846 css::uno::Reference< css::uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
1847 css::uno::Reference< css::frame::XPopupMenuController > xPopupController(
1848 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
1849 "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext ), css::uno::UNO_QUERY );
1850
1852
1853 if ( !xPopupController.is() || !xPopupMenu.is() )
1854 return;
1855
1856 vcl::Window* pWindow = pWin ? pWin : xImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
1857 Point aPos = pPos ? *pPos : pWindow->GetPointerPosPixel();
1858
1859 css::ui::ContextMenuExecuteEvent aEvent;
1860 aEvent.SourceWindow = VCLUnoHelper::GetInterface( pWindow );
1861 aEvent.ExecutePosition.X = aPos.X();
1862 aEvent.ExecutePosition.Y = aPos.Y();
1863
1864 xPopupController->setPopupMenu( xPopupMenu );
1866 {
1867 boost::property_tree::ptree aMenu = fillPopupMenu(xPopupMenu);
1868 boost::property_tree::ptree aRoot;
1869 aRoot.add_child("menu", aMenu);
1870
1871 std::stringstream aStream;
1872 boost::property_tree::write_json(aStream, aRoot, true);
1873 if (SfxViewShell* pViewShell = xImp->pFrame->GetViewShell())
1874 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CONTEXT_MENU, OString(aStream.str()));
1875 }
1876 else
1877 {
1878 OUString aMenuURL = "private:resource/popupmenu/" + rResName;
1879 if (GetFrame()->GetViewShell()->TryContextMenuInterception(xPopupMenu, aMenuURL, aEvent))
1880 {
1881 css::uno::Reference<css::awt::XWindowPeer> xParent(aEvent.SourceWindow, css::uno::UNO_QUERY);
1882 xPopupMenu->execute(xParent, css::awt::Rectangle(aPos.X(), aPos.Y(), 1, 1), css::awt::PopupMenuDirection::EXECUTE_DOWN);
1883 }
1884 }
1885
1886 css::uno::Reference< css::lang::XComponent > xComponent( xPopupController, css::uno::UNO_QUERY );
1887 if ( xComponent.is() )
1888 xComponent->dispose();
1889}
1890
1895void SfxDispatcher::Lock( bool bLock )
1896{
1897 SfxBindings* pBindings = GetBindings();
1898 if ( !bLock && xImp->bLocked && xImp->bInvalidateOnUnlock )
1899 {
1900 if ( pBindings )
1901 pBindings->InvalidateAll(true);
1902 xImp->bInvalidateOnUnlock = false;
1903 }
1904 else if ( pBindings )
1905 pBindings->InvalidateAll(false);
1906 xImp->bLocked = bLock;
1907 if ( !bLock )
1908 {
1909 for(size_t i = 0; i < xImp->aReqArr.size(); ++i)
1910 xImp->xPoster->Post(std::move(xImp->aReqArr[i]));
1911 xImp->aReqArr.clear();
1912 }
1913}
1914
1916{
1917 return xImp->aObjBars[nPos].eId;
1918}
1919
1920void SfxDispatcher::HideUI( bool bHide )
1921{
1922 bool bWasHidden = xImp->bNoUI;
1923 xImp->bNoUI = bHide;
1924 if ( xImp->pFrame )
1925 {
1926 SfxViewFrame* pTop = xImp->pFrame->GetTopViewFrame();
1927 if ( pTop && pTop->GetBindings().GetDispatcher() == this )
1928 {
1929 SfxFrame& rFrame = pTop->GetFrame();
1930 if ( rFrame.IsMenuBarOn_Impl() )
1931 {
1932 css::uno::Reference < css::beans::XPropertySet > xPropSet( rFrame.GetFrameInterface(), css::uno::UNO_QUERY );
1933 if ( xPropSet.is() )
1934 {
1935 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
1936 css::uno::Any aValue = xPropSet->getPropertyValue("LayoutManager");
1937 aValue >>= xLayoutManager;
1938 if ( xLayoutManager.is() )
1939 xLayoutManager->setVisible( !bHide );
1940 }
1941 }
1942 }
1943 }
1944
1945 if ( bHide != bWasHidden )
1946 Update_Impl( true );
1947}
1948
1950{
1951 xImp->bReadOnly = bOn;
1952}
1953
1955{
1956 return xImp->bReadOnly;
1957}
1958
1963{
1964 xImp->bQuiet = bOn;
1965 SfxBindings* pBindings = GetBindings();
1966 if ( pBindings )
1967 pBindings->InvalidateAll(true);
1968}
1969
1970SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSlot, const SfxPoolItem* &rpState )
1971{
1972 SfxShell *pShell = nullptr;
1973 const SfxSlot *pSlot = nullptr;
1974 if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, false, true ) )
1975 {
1976 rpState = pShell->GetSlotState(nSlot);
1977 if ( !rpState )
1978 return SfxItemState::DISABLED;
1979 else
1980 return SfxItemState::DEFAULT;
1981 }
1982
1983 return SfxItemState::DISABLED;
1984}
1985
1986SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSID, css::uno::Any& rAny )
1987{
1988 SfxShell *pShell = nullptr;
1989 const SfxSlot *pSlot = nullptr;
1990 if ( GetShellAndSlot_Impl( nSID, &pShell, &pSlot, false, true ) )
1991 {
1992 const SfxPoolItem* pItem = pShell->GetSlotState( nSID );
1993 if ( !pItem )
1994 return SfxItemState::DISABLED;
1995 else
1996 {
1997 css::uno::Any aState;
1998 if ( !pItem->IsVoidItem() )
1999 {
2000 sal_uInt16 nSubId( 0 );
2001 SfxItemPool& rPool = pShell->GetPool();
2002 sal_uInt16 nWhich = rPool.GetWhich( nSID );
2003 if ( rPool.GetMetric( nWhich ) == MapUnit::MapTwip )
2004 nSubId |= CONVERT_TWIPS;
2005 pItem->QueryValue( aState, static_cast<sal_uInt8>(nSubId) );
2006 }
2007 rAny = aState;
2008
2009 return SfxItemState::DEFAULT;
2010 }
2011 }
2012
2013 return SfxItemState::DISABLED;
2014}
2015
2016bool SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell ) const
2017{
2018 sal_uInt16 nShellCount = xImp->aStack.size();
2019 if ( nShell < nShellCount )
2020 {
2021 SfxShell* pShell = *( xImp->aStack.rbegin() + nShell );
2022 if( dynamic_cast< const SfxModule *>( pShell ) != nullptr || dynamic_cast< const SfxApplication *>( pShell ) != nullptr || dynamic_cast< const SfxViewFrame *>( pShell ) != nullptr )
2023 return false;
2024 else
2025 return xImp->bReadOnly;
2026 }
2027 return true;
2028}
2029
2031{
2032 Flush();
2033
2034 sal_uInt16 nCount = xImp->aStack.size();
2035 for ( sal_uInt16 n=0; n<nCount; ++n )
2036 {
2037 if ( xImp->aStack[n] == &rShell )
2038 {
2039 xImp->aStack.erase( xImp->aStack.begin() + n );
2041 rShell.DoDeactivate_Impl(xImp->pFrame, true);
2042 break;
2043 }
2044 }
2045
2046 if ( !SfxGetpApp()->IsDowning() )
2047 {
2048 xImp->bUpdated = false;
2050 }
2051}
2052
2054{
2055 // App-Dispatcher?
2056 if ( IsAppDispatcher() )
2057 {
2058 for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst();
2059 pFrame;
2060 pFrame = SfxViewFrame::GetNext( *pFrame ) )
2061 pFrame->GetBindings().InvalidateAll(bModify);
2062 }
2063 else
2064 {
2066 if ( pDisp == this )
2067 {
2068 GetBindings()->InvalidateAll( bModify );
2069 }
2070 }
2071}
2072
2074{
2075 return xImp->bUpdated;
2076}
2077
2079{
2080 xImp->nDisableFlags = nFlags;
2081 for ( SfxShellStack_Impl::reverse_iterator it = xImp->aStack.rbegin(); it != xImp->aStack.rend(); ++it )
2082 (*it)->SetDisableFlags( nFlags );
2083}
2084
2086{
2087 return xImp->nDisableFlags;
2088}
2089
2091{
2092 for ( sal_uInt16 nShell = 0;; ++nShell )
2093 {
2094 SfxShell *pSh = GetShell(nShell);
2095 if ( pSh == nullptr )
2096 return nullptr;
2097 if ( auto pModule = dynamic_cast<SfxModule *>( pSh ) )
2098 return pModule;
2099 }
2100}
2101
2102/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxApplication * SfxGetpApp()
Definition: app.hxx:231
AnyEventRef aEvent
SfxCallMode
Definition: bindings.hxx:57
bool IsItemChecked(sal_uInt16 nItemId) const
bool HandleMenuActivateEvent(Menu *pMenu) const
OUString GetItemText(sal_uInt16 nItemId) const
MenuItemBits GetItemBits(sal_uInt16 nItemId) const
MenuItemType GetItemType(sal_uInt16 nPos) const
bool HandleMenuDeActivateEvent(Menu *pMenu) const
OUString GetItemCommand(sal_uInt16 nItemId) const
sal_uInt16 GetItemId(sal_uInt16 nPos) const
PopupMenu * GetPopupMenu(sal_uInt16 nItemId) const
bool IsItemEnabled(sal_uInt16 nItemId) const
sal_uInt16 GetItemCount() const
constexpr tools::Long Y() const
constexpr tools::Long X() const
bool IsDowning() const
Definition: appmisc.cxx:102
SAL_DLLPRIVATE SfxDispatcher * GetDispatcher_Impl()
Definition: app.cxx:228
SAL_DLLPRIVATE SfxDispatcher * GetDispatcher_Impl()
Definition: bindings.hxx:180
SAL_DLLPRIVATE void StartUpdate_Impl(bool bComplete=false)
Definition: bindings.cxx:1493
void Update(sal_uInt16 nId)
Definition: bindings.cxx:302
SfxDispatcher * GetDispatcher() const
Definition: bindings.hxx:172
void Invalidate(sal_uInt16 nId)
Definition: bindings.cxx:639
css::uno::Reference< css::frame::XFrame > GetActiveFrame() const
Definition: bindings.cxx:1712
SAL_DLLPRIVATE SfxBindings * GetSubBindings_Impl() const
Definition: bindings.cxx:1673
void SetActiveFrame(const css::uno::Reference< css::frame::XFrame > &rFrame)
Definition: bindings.cxx:1703
void SetDispatcher(SfxDispatcher *pDisp)
Definition: bindings.cxx:1420
void InvalidateAll(bool bWithMsg)
Definition: bindings.cxx:498
bool GetValue() const
SfxChildAlignment GetAlignment() const
Definition: childwin.hxx:125
void FlushImpl()
Helper method to execute the outstanding push and pop commands.
Definition: dispatch.cxx:1286
bool FindServer_(sal_uInt16 nId, SfxSlotServer &rServer)
This helper method searches for the <Slot-Server> which currently serves the nSlot.
Definition: dispatch.cxx:1535
const SfxSlot * GetSlot(const OUString &rCommand)
Definition: dispatch.cxx:769
std::unique_ptr< SfxDispatcher_Impl > xImp
Definition: dispatch.hxx:71
SAL_DLLPRIVATE void DoActivate_Impl(bool bMDI)
This method controls the activation of a dispatcher.
Definition: dispatch.cxx:573
SAL_DLLPRIVATE void Update_Impl(bool bForce=false)
Definition: dispatch.cxx:1034
void HideUI(bool bHide=true)
Definition: dispatch.cxx:1920
SAL_DLLPRIVATE bool CheckVirtualStack(const SfxShell &rShell)
With this method it can be tested whether the <SfxShell> rShell is on the stack, when it was flushed.
Definition: dispatch.cxx:471
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
Method to execute a <SfxSlot>s over the Slot-Id.
Definition: dispatch.cxx:833
bool IsFlushed() const
This method checks if the stack of the SfxDispatchers is flushed, or if push- or pop- commands are pe...
Definition: dispatch.cxx:145
SAL_DLLPRIVATE void SetQuietMode_Impl(bool bOn)
With 'bOn' the Dispatcher is quasi dead and transfers everything to the Parent-Dispatcher.
Definition: dispatch.cxx:1962
SfxBindings * GetBindings() const
This method returns a pointer to the <SfxBinding> Instance on which the SfxDispatcher is currently bo...
Definition: dispatch.cxx:545
void SetDisableFlags(SfxDisableFlags nFlags)
Definition: dispatch.cxx:2078
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
Method to execute a <SfxSlot>s over the Slot-Id.
Definition: dispatch.cxx:931
ToolbarId GetObjectBarId(sal_uInt16 nPos) const
Definition: dispatch.cxx:1915
SAL_DLLPRIVATE void Construct_Impl()
Definition: dispatch.cxx:285
bool IsLocked() const
With this method it can be determined whether the SfxDispatcher is locked or unlocked.
Definition: dispatch.cxx:196
void SetSlotFilter(SfxSlotFilterState nEnable=SfxSlotFilterState::DISABLED, o3tl::span< sal_uInt16 const > pSIDs=o3tl::span< sal_uInt16 const >())
With this method a filter set, the target slots can be enabled or disabled.
Definition: dispatch.cxx:1465
SAL_DLLPRIVATE SfxSlotFilterState IsSlotEnabledByFilter_Impl(sal_uInt16 nSID) const
Searches for 'nSID' in the Filter set by <SetSlotFilter()> and returns sal_True, if the SIDis allowed...
Definition: dispatch.cxx:1497
bool FillState_(const SfxSlotServer &rServer, SfxItemSet &rState, const SfxSlot *pRealSlot)
Helper method to obtain the status of the <Slot-Server>s rSvr.
Definition: dispatch.cxx:1655
void Pop(SfxShell &rShell, SfxDispatcherPopFlags nMode=SfxDispatcherPopFlags::NONE)
With this method, one or more <SfxShell> are popped from the SfxDispatcher.
Definition: dispatch.cxx:380
SAL_DLLPRIVATE bool IsUpdated_Impl() const
Definition: dispatch.cxx:2073
SfxDisableFlags GetDisableFlags() const
Definition: dispatch.cxx:2085
sal_uInt16 GetShellLevel(const SfxShell &rShell)
Determines the position of a given SfxShell in the stack of the dispatcher.
Definition: dispatch.cxx:510
bool IsAppDispatcher() const
With this method it can be determined if the SfxDispacher is the applications dispatcher.
Definition: dispatch.cxx:206
SAL_DLLPRIVATE void DoDeactivate_Impl(bool bMDI, SfxViewFrame const *pNew)
This method controls the deactivation of a dispatcher.
Definition: dispatch.cxx:624
SAL_DLLPRIVATE void InvalidateBindings_Impl(bool)
Definition: dispatch.cxx:2053
SAL_DLLPRIVATE void SetReadOnly_Impl(bool bOn)
Definition: dispatch.cxx:1949
SfxViewFrame * GetFrame() const
Returns a pointer to the <SfxViewFrame> instance, which belongs to this SfxDispatcher.
Definition: dispatch.cxx:557
SAL_DLLPRIVATE void Call_Impl(SfxShell &rShell, const SfxSlot &rSlot, SfxRequest &rReq, bool bRecord)
Helper function to check whether a slot can be executed and check the execution itself.
Definition: dispatch.cxx:214
void PostMsgHandler(std::unique_ptr< SfxRequest >)
Helper method to receive the asynchronously executed <SfxRequest>s.
Definition: dispatch.cxx:971
~SfxDispatcher()
The destructor of the SfxDispatcher class should not be called when the SfxDispatcher instance is act...
Definition: dispatch.cxx:331
SAL_DLLPRIVATE void SetMenu_Impl()
Definition: dispatch.cxx:1004
SAL_DLLPRIVATE void RemoveShell_Impl(SfxShell &rShell)
Definition: dispatch.cxx:2030
void ExecutePopup(const OUString &rResName, vcl::Window *pWin=nullptr, const Point *pPos=nullptr)
Definition: dispatch.cxx:1838
bool IsActive(const SfxShell &rShell)
This method checks whether a particular <SfxShell> instance is on the SfxDispatcher.
Definition: dispatch.cxx:180
void Lock(bool bLock)
With this method the SfxDispatcher can be locked and released.
Definition: dispatch.cxx:1895
SAL_DLLPRIVATE void Update_Impl_(bool, bool, bool, SfxWorkWindow *)
Definition: dispatch.cxx:1130
static boost::property_tree::ptree fillPopupMenu(const rtl::Reference< VCLXPopupMenu > &rMenu)
Definition: dispatch.cxx:1832
SfxModule * GetModule() const
Definition: dispatch.cxx:2090
void Push(SfxShell &rShell)
With this method, a <SfxShell> pushed on to the SfxDispatcher.
Definition: dispatch.cxx:168
SfxShell * GetShell(sal_uInt16 nIdx) const
Returns a pointer to the <SfxShell> which is at the position nIdx (from the top, last pushed is 0) on...
Definition: dispatch.cxx:529
SAL_DLLPRIVATE bool GetReadOnly_Impl() const
Definition: dispatch.cxx:1954
SAL_DLLPRIVATE bool GetShellAndSlot_Impl(sal_uInt16 nSlot, SfxShell **ppShell, const SfxSlot **ppSlot, bool bOwnShellsOnly, bool bRealSlot)
This method searches in SfxDispatcher after <SfxShell> , from the Slot Id nSlot currently being handl...
Definition: dispatch.cxx:696
void Execute_(SfxShell &rShell, const SfxSlot &rSlot, SfxRequest &rReq, SfxCallMode eCall)
This method performs a request for a cached <Slot-Server>.
Definition: dispatch.cxx:726
SfxItemState QueryState(sal_uInt16 nSID, const SfxPoolItem *&rpState)
Definition: dispatch.cxx:1970
void Flush()
This method performs outstanding push- and pop- commands.
Definition: dispatch.cxx:155
SAL_DLLPRIVATE bool IsReadOnlyShell_Impl(sal_uInt16 nShell) const
Definition: dispatch.cxx:2016
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
Definition: frame.cxx:515
SAL_DLLPRIVATE bool IsMenuBarOn_Impl() const
Definition: frame2.cxx:379
[Description]
Definition: hintpost.hxx:42
bool IsObjectUIActive() const
Definition: ipclient.cxx:844
StatusBarId GetStatusBarId() const
Definition: objface.cxx:396
bool IsObjectBarVisible(sal_uInt16 nNo) const
Definition: objface.cxx:423
const char * GetClassName() const
Definition: objface.hxx:82
const SfxSlot * GetSlot(sal_uInt16 nSlotId) const
Definition: objface.cxx:187
sal_uInt16 GetChildWindowCount() const
Definition: objface.cxx:383
SfxShellFeature GetChildWindowFeature(sal_uInt16 nNo) const
Definition: objface.cxx:364
ToolbarId GetObjectBarId(sal_uInt16 nNo) const
Definition: objface.cxx:261
sal_uInt16 GetObjectBarCount() const
Definition: objface.cxx:318
const OUString & GetPopupMenuName() const
Definition: objface.cxx:391
SfxVisibilityFlags GetObjectBarFlags(sal_uInt16 nNo) const
Definition: objface.cxx:299
sal_uInt16 GetObjectBarPos(sal_uInt16 nNo) const
Definition: objface.cxx:280
SfxShellFeature GetObjectBarFeature(sal_uInt16 nNo) const
Definition: objface.cxx:404
sal_uInt32 GetChildWindowId(sal_uInt16 nNo) const
Definition: objface.cxx:343
const SfxPoolItem * GetCurItem() const
const SfxPoolItem * NextItem()
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
sal_uInt16 GetSlotId(sal_uInt16 nWhich) const
static bool IsSlot(sal_uInt16 nId)
virtual MapUnit GetMetric(sal_uInt16 nWhich) const
SfxItemPool * GetPool() const
sal_uInt16 Count() const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SfxItemSet & GetItemSet() const
Definition: docfile.cxx:3647
SfxMedium * GetMedium() const
Definition: objsh.hxx:261
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const
sal_uInt16 Which() const
virtual bool IsVoidItem() const
const SfxPoolItem * GetReturnValue() const
Definition: request.cxx:429
bool IsDone() const
Definition: request.cxx:648
SAL_DLLPRIVATE void Record_Impl(SfxShell &rSh, const SfxSlot &rSlot, const css::uno::Reference< css::frame::XDispatchRecorder > &xRecorder, SfxViewFrame *)
Definition: request.cxx:372
void SetModifier(sal_uInt16 nModi)
Definition: request.cxx:718
void SetInternalArgs_Impl(const SfxAllItemSet &rArgs)
Definition: request.cxx:309
void AllowRecording(bool)
Definition: request.cxx:730
The class SfxShell is the base class for all classes, which provide the functionality of the form <Sl...
Definition: shell.hxx:128
const SfxPoolItem * GetSlotState(sal_uInt16 nSlotId, const SfxInterface *pIF=nullptr, SfxItemSet *pStateSet=nullptr)
This method returns the status of the slot with the specified slot ID on the specified interface.
Definition: shell.cxx:462
SAL_DLLPRIVATE bool CanExecuteSlot_Impl(const SfxSlot &rSlot)
This method determines by calling the status function whether 'rSlot' can be executed currently.
Definition: shell.cxx:393
SfxItemPool & GetPool() const
Each Subclass of SfxShell must reference a pool.
Definition: shell.hxx:511
virtual bool IsConditionalFastCall(const SfxRequest &rReq)
This method determines whether we need to execute without checking the disabled state of the slot.
Definition: shell.cxx:404
virtual bool HasUIFeature(SfxShellFeature nFeature) const
Definition: shell.cxx:657
void SetDisableFlags(SfxDisableFlags nFlags)
Definition: shell.cxx:684
SAL_DLLPRIVATE void DoDeactivate_Impl(SfxViewFrame const *pFrame, bool bMDI)
This method controls the deactivation of the SfxShell instance.
Definition: shell.cxx:329
SAL_DLLPRIVATE const SfxSlot * GetVerbSlot_Impl(sal_uInt16 nId) const
Definition: shell.cxx:635
virtual SfxInterface * GetInterface() const
With this virtual method, which is automatically overridden by each subclass with its own slots throu...
Definition: shell.cxx:198
SfxDisableFlags GetDisableFlags() const
Definition: shell.cxx:689
SfxDispatcher * GetDispatcher() const
This method returns a pointer to the <SfxDispatcher>, when the SfxShell is currently <UI-active> or a...
Definition: shell.cxx:124
static SfxSlotPool & GetSlotPool(SfxViewFrame *pFrame=nullptr)
Definition: msgpool.cxx:316
const SfxSlot * GetSlot(sal_uInt16 nId) const
Definition: msgpool.cxx:155
void SetSlot(const SfxSlot *pSlot)
Definition: slotserv.hxx:37
void SetShellLevel(sal_uInt16 nLevel)
Definition: slotserv.hxx:36
const SfxSlot * GetSlot() const
Definition: slotserv.hxx:52
sal_uInt16 GetShellLevel() const
Definition: slotserv.hxx:47
Definition: msg.hxx:184
sal_uInt16 GetSlotId() const
Definition: msg.hxx:253
const SfxType * GetType() const
Definition: msg.hxx:236
SFX2_DLLPUBLIC OUString GetCommand() const
Definition: msg.cxx:46
SfxStateFunc GetStateFnc() const
Definition: msg.hxx:245
SfxDisableFlags nDisableFlags
Definition: msg.hxx:202
SfxSlotMode nFlags
Definition: msg.hxx:188
SfxExecFunc GetExecFnc() const
Definition: msg.hxx:244
bool IsMode(SfxSlotMode nMode) const
Definition: msg.hxx:268
SfxBindings & GetBindings()
Definition: viewfrm.hxx:110
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetNext(const SfxViewFrame &rPrev, const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:2006
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetFirst(const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:1983
SfxFrame & GetFrame() const
Definition: viewfrm.cxx:2782
One SfxViewShell more or less represents one edit window for a document, there can be multiple ones f...
Definition: viewsh.hxx:165
SfxInPlaceClient * GetUIActiveClient() const
Definition: viewsh.cxx:1516
static SAL_WARN_UNUSED_RESULT SfxViewShell * Current()
Definition: viewsh.cxx:1848
void UpdateObjectBars_Impl()
Definition: workwin.cxx:1091
void ResetObjectBars_Impl()
Definition: workwin.cxx:1045
bool IsFloating(sal_uInt16 nId)
Definition: workwin.cxx:1901
SfxBindings & GetBindings()
Definition: workwin.hxx:230
bool IsVisible_Impl() const
Definition: workwin.cxx:1493
void ResetChildWindows_Impl()
Definition: workwin.cxx:2089
void SetObjectBar_Impl(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId)
Definition: workwin.cxx:1054
void SetChildWindowVisible_Impl(sal_uInt32, bool, SfxVisibilityFlags)
Definition: workwin.cxx:1752
void ResetStatusBar_Impl()
Definition: workwin.cxx:1444
SfxChildWindow * GetChildWindow_Impl(sal_uInt16)
Definition: workwin.cxx:2075
static css::uno::Reference< css::awt::XWindow > GetInterface(vcl::Window *pWindow)
constexpr size_type size() const noexcept
Point GetPointerPosPixel()
int nCount
#define DBG_ASSERT(sCon, aError)
static int SfxCompareSIDs_Impl(const void *pSmaller, const void *pBigger)
Definition: dispatch.cxx:1482
static void MappedPut_Impl(SfxAllItemSet &rSet, const SfxPoolItem &rItem)
Helper function to put from rItem below the Which-ID in the pool of the Item Sets rSet.
Definition: dispatch.cxx:759
IMPL_LINK_NOARG(SfxDispatcher, EventHdl_Impl, Timer *, void)
This handler is called after <SfxDispatcher::Invalidate()> or after changes on the stack (<SfxDispatc...
Definition: dispatch.cxx:455
std::vector< SfxShell * > SfxShellStack_Impl
Definition: dispatch.cxx:73
SfxDispatcherPopFlags
Definition: dispatch.hxx:49
SfxSlotFilterState
Definition: dispatch.hxx:61
virtual SfxBindings & GetBindings() override
bool bReadOnly
sal_Int64 n
sal_uInt16 nPos
Definition: linksrc.cxx:118
#define SAL_INFO_IF(condition, area, stream)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_STREAM(stream)
#define SAL_INFO(area, stream)
#define SFX_SLOTPOOL()
Definition: msgpool.hxx:70
SfxDispatcher * GetDispatcher()
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
args
long Long
StatusBarId
Definition: objface.hxx:45
#define SFX_OBJECTBAR_MAX
Definition: objface.hxx:42
sal_Int16 nId
#define CONVERT_TWIPS
SfxItemState
bool IsInvalidItem(const SfxPoolItem *pItem)
#define SFX_STACK(s)
Definition: sfxtypes.hxx:44
static SfxItemSet & rSet
Definition: shell.cxx:534
SfxDisableFlags
Definition: shell.hxx:102
SfxShellFeature
Definition: shell.hxx:74
void(* SfxExecFunc)(SfxShell *, SfxRequest &rReq)
Definition: shell.hxx:111
void(* SfxStateFunc)(SfxShell *, SfxItemSet &rSet)
Definition: shell.hxx:112
SfxVisibilityFlags
Definition: shell.hxx:573
SfxSlotFilterState nFilterEnabling
Definition: dispatch.cxx:133
bool * pInCallAliveFlag
Definition: dispatch.cxx:125
tools::SvRef< SfxHintPoster > xPoster
Definition: dispatch.cxx:119
SfxDisableFlags nDisableFlags
Definition: dispatch.cxx:137
SfxObjectBars_Impl aFixedObjBars[SFX_OBJECTBAR_MAX]
Definition: dispatch.cxx:127
SfxObjectBars_Impl aObjBars[SFX_OBJECTBAR_MAX]
Definition: dispatch.cxx:126
std::deque< SfxToDo_Impl > aToDoStack
Definition: dispatch.cxx:116
SfxShellStack_Impl aStack
Definition: dispatch.cxx:114
std::vector< std::unique_ptr< SfxRequest > > aReqArr
Definition: dispatch.cxx:113
SfxViewFrame * pFrame
Definition: dispatch.cxx:117
o3tl::span< sal_uInt16 const > pFilterSIDs
Definition: dispatch.cxx:136
std::deque< std::deque< SfxToDo_Impl > > aToDoCopyStack
Definition: dispatch.cxx:139
std::vector< sal_uInt32 > aChildWins
Definition: dispatch.cxx:128
const std::type_info * Type() const
Definition: msg.hxx:110
Reference< XFrame > xFrame
ToolbarId
Definition: toolbarids.hxx:18
bool bVisible
unsigned char sal_uInt8
MenuItemType
MenuItemBits