Line data Source code
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 <com/sun/star/beans/XPropertySet.hpp>
21 : #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
22 : #include <com/sun/star/frame/XLayoutManager.hpp>
23 : #include <svl/itempool.hxx>
24 : #include <svl/itemiter.hxx>
25 : #include <svl/whiter.hxx>
26 : #include <svl/intitem.hxx>
27 : #include <svl/eitem.hxx>
28 : #include <svl/undo.hxx>
29 : #include <vcl/wrkwin.hxx>
30 : #include <stdio.h>
31 : #include <stdarg.h>
32 : #include <stdlib.h> // due to bsearch
33 :
34 : #include <svtools/helpopt.hxx>
35 :
36 : // due to nAutoPageID
37 : #include "appdata.hxx"
38 : #include "sfx2/sfxhelp.hxx"
39 : #include <sfx2/dispatch.hxx>
40 : #include <sfx2/minstack.hxx>
41 : #include <sfx2/msg.hxx>
42 : #include <sfx2/objface.hxx>
43 : #include <sfx2/bindings.hxx>
44 : #include <sfx2/request.hxx>
45 : #include <sfx2/app.hxx>
46 : #include <sfx2/hintpost.hxx>
47 : #include "slotserv.hxx"
48 : #include <sfx2/ipclient.hxx>
49 : #include "sfxtypes.hxx"
50 : #include <sfx2/viewfrm.hxx>
51 : #include <sfx2/viewsh.hxx>
52 : #include <sfx2/childwin.hxx>
53 : #include <sfx2/docfac.hxx>
54 : #include <sfx2/msgpool.hxx>
55 : #include <sfx2/module.hxx>
56 : #include <sfx2/sfxuno.hxx>
57 : #include <sfx2/docfile.hxx>
58 : #include <sfx2/mnumgr.hxx>
59 : #include "workwin.hxx"
60 : #include <rtl/strbuf.hxx>
61 :
62 : #include <deque>
63 : #include <boost/ptr_container/ptr_vector.hpp>
64 :
65 : DBG_NAME(SfxDispatcherFlush)
66 : DBG_NAME(SfxDispatcherFillState)
67 :
68 : typedef boost::ptr_vector<SfxRequest> SfxRequestPtrArray;
69 :
70 86367 : DECL_PTRSTACK(SfxShellStack_Impl, SfxShell*, 8, 4 );
71 :
72 : struct SfxToDo_Impl
73 : {
74 : SfxShell* pCluster;
75 : bool bPush;
76 : bool bDelete;
77 : bool bUntil;
78 :
79 : SfxToDo_Impl()
80 : : pCluster(0)
81 : , bPush(false)
82 : , bDelete(false)
83 : , bUntil(false)
84 : {}
85 2531 : SfxToDo_Impl( bool bOpPush, bool bOpDelete, bool bOpUntil, SfxShell& rCluster )
86 : : pCluster(&rCluster)
87 : , bPush(bOpPush)
88 : , bDelete(bOpDelete)
89 2531 : , bUntil(bOpUntil)
90 2531 : {}
91 7015 : ~SfxToDo_Impl(){}
92 :
93 : bool operator==( const SfxToDo_Impl& rWith ) const
94 : { return pCluster==rWith.pCluster && bPush==rWith.bPush; }
95 : };
96 :
97 1742 : struct SfxObjectBars_Impl
98 : {
99 : sal_uInt32 nResId; // Resource - and ConfigId of the Toolbox
100 : sal_uInt16 nMode; // special visibility flags
101 : String aName;
102 : SfxInterface* pIFace;
103 :
104 6838 : SfxObjectBars_Impl() :
105 6838 : nResId( 0 )
106 6838 : {}
107 : };
108 :
109 : //------------------------------------------------------------------
110 :
111 330 : struct SfxDispatcher_Impl
112 : {
113 : SfxRequestPtrArray aReqArr;
114 : const SfxSlotServer* pCachedServ1; // last called message
115 : const SfxSlotServer* pCachedServ2; // penultimate called Message
116 : SfxShellStack_Impl aStack; // active functionality
117 : Timer aTimer; // for Flush
118 : std::deque<SfxToDo_Impl> aToDoStack; // not processed Push/Pop
119 : SfxViewFrame* pFrame; // NULL or associated Frame
120 : SfxDispatcher* pParent; // AppDispatcher, NULL if possible
121 : SfxHintPosterRef xPoster; // Execute asynchronous
122 : sal_Bool bFlushing; // sal_True during Flush //?
123 : sal_Bool bUpdated; // Update_Impl has run
124 : sal_Bool bLocked; // No Execute
125 : sal_Bool bInvalidateOnUnlock; // because someone asked
126 : sal_Bool bActive; // not to be confused with set!
127 : sal_Bool* pInCallAliveFlag; // view the Destructor Stack
128 : SfxObjectBars_Impl aObjBars[SFX_OBJECTBAR_MAX];
129 : SfxObjectBars_Impl aFixedObjBars[SFX_OBJECTBAR_MAX];
130 : std::vector<sal_uInt32> aChildWins;
131 : sal_uInt32 nEventId; // EventId UserEvent
132 : sal_Bool bNoUI; // UI only from Parent Dispatcher
133 : sal_Bool bReadOnly; // Document is ReadOnly
134 : sal_Bool bQuiet; // Only use parent dispatcher
135 : sal_Bool bModal; // Only slots from parent dispatcher
136 :
137 : sal_Bool bFilterEnabling; // sal_True=filter enabled slots,
138 : // 2==ReadOnlyDoc overturned
139 : sal_uInt16 nFilterCount; // Number of SIDs in pFilterSIDs
140 : const sal_uInt16* pFilterSIDs; // sorted Array of SIDs
141 : sal_uInt16 nStandardMode; // ExecuteMode from PlugInDispatcher
142 : std::vector<sal_uInt16>* pDisableList;
143 : sal_uInt32 nDisableFlags;
144 : };
145 :
146 : //------------------------------------------------------------------
147 :
148 : #define SFX_FLUSH_TIMEOUT 50
149 :
150 : //====================================================================
151 2430 : sal_Bool SfxDispatcher::IsLocked( sal_uInt16 ) const
152 :
153 : /* [Description]
154 :
155 : With this method it can be determined whether the SfxDispatcher is
156 : locked or unlocked. A locked SfxDispatcher does not perform <SfxRequest>s
157 : and no longer provides any status information. It behaves as if all the
158 : slots are disabled.
159 :
160 : The dispatcher is also marked as blocked, if all Dispatcher are locked
161 : (<SfxApplication::LockDispatcher()>) or the associated top frame is in the
162 : modal-mode and if the specified slot are handled as frame-specific
163 : (ie, not served by the application).
164 : */
165 :
166 : {
167 2430 : return pImp->bLocked;
168 : }
169 :
170 : //--------------------------------------------------------------------
171 1417 : sal_Bool SfxDispatcher::IsAppDispatcher() const
172 :
173 : /* [Description]
174 :
175 : With this method it can be determined if the SfxDispacher is the
176 : applications dispatcher.
177 :
178 : [Return value]
179 :
180 : sal_Bool sal_True it is the application dispatcher.
181 : sal_Fals it is a SfxViewFrame dispatcher.
182 : */
183 :
184 : {
185 1417 : return !pImp->pFrame;
186 : }
187 :
188 : //--------------------------------------------------------------------
189 1 : int SfxDispatcher::Call_Impl( SfxShell& rShell, const SfxSlot &rSlot, SfxRequest &rReq, sal_Bool bRecord )
190 :
191 : /* [Description]
192 :
193 : Helper function to check whether a slot can be executed and
194 : check the execution itself
195 : */
196 :
197 : {
198 : SFX_STACK(SfxDispatcher::Call_Impl);
199 :
200 : // The slot may be called (meaning enabled)
201 1 : if ( rSlot.IsMode(SFX_SLOT_FASTCALL) || rShell.CanExecuteSlot_Impl(rSlot) )
202 : {
203 1 : if ( GetFrame() )
204 : {
205 : // Recording may start
206 : com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame(
207 1 : GetFrame()->GetFrame().GetFrameInterface(),
208 1 : com::sun::star::uno::UNO_QUERY);
209 :
210 : com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xSet(
211 : xFrame,
212 1 : com::sun::star::uno::UNO_QUERY);
213 :
214 1 : if ( xSet.is() )
215 : {
216 1 : com::sun::star::uno::Any aProp = xSet->getPropertyValue(::rtl::OUString("DispatchRecorderSupplier"));
217 1 : com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier > xSupplier;
218 1 : com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder;
219 1 : aProp >>= xSupplier;
220 1 : if(xSupplier.is())
221 0 : xRecorder = xSupplier->getDispatchRecorder();
222 :
223 1 : if ( bRecord && xRecorder.is() && !rSlot.IsMode(SFX_SLOT_NORECORD) )
224 0 : rReq.Record_Impl( rShell, rSlot, xRecorder, GetFrame() );
225 1 : }
226 : }
227 : // Get all that is needed, because the slot may not have survived the
228 : // Execute if it is a 'pseudo slot' for macros or verbs.
229 1 : sal_Bool bAutoUpdate = rSlot.IsMode(SFX_SLOT_AUTOUPDATE);
230 :
231 : // API-call parentheses and document-lock during the calls
232 : {
233 : // 'this' must respond in the Destructor
234 1 : sal_Bool bThisDispatcherAlive = sal_True;
235 1 : sal_Bool *pOldInCallAliveFlag = pImp->pInCallAliveFlag;
236 1 : pImp->pInCallAliveFlag = &bThisDispatcherAlive;
237 :
238 1 : SfxViewFrame* pView = GetFrame();
239 1 : if ( !pView )
240 0 : pView = SfxViewFrame::Current();
241 1 : if ( pView )
242 : {
243 1 : rtl::OString aCmd(".uno:");
244 1 : aCmd += rSlot.GetUnoName();
245 1 : SfxHelp::OpenHelpAgent( &pView->GetFrame(), aCmd );
246 : }
247 :
248 1 : SfxExecFunc pFunc = rSlot.GetExecFnc();
249 1 : rShell.CallExec( pFunc, rReq );
250 :
251 : // If 'this' is still alive
252 1 : if ( bThisDispatcherAlive )
253 1 : pImp->pInCallAliveFlag = pOldInCallAliveFlag;
254 : else
255 : {
256 0 : if ( pOldInCallAliveFlag )
257 : {
258 : // also protect nested stack frames
259 0 : *pOldInCallAliveFlag = sal_False;
260 : }
261 :
262 : // do nothing after this object is dead
263 0 : return rReq.IsDone();
264 : }
265 : }
266 :
267 1 : if ( rReq.IsDone() )
268 : {
269 1 : SfxBindings *pBindings = GetBindings();
270 :
271 : // When AutoUpdate update immediately; "Pseudoslots" must not be
272 : // Autoupdate!
273 1 : if ( bAutoUpdate && pBindings )
274 : {
275 0 : const SfxSlot* pSlave = rSlot.GetLinkedSlot();
276 0 : if (pSlave)
277 : {
278 : // When enum slots take any bound slave slot
279 0 : while (!pBindings->IsBound(pSlave->GetSlotId()) && pSlave != &rSlot )
280 0 : pSlave = pSlave->GetLinkedSlot();
281 0 : pBindings->Invalidate(pSlave->GetSlotId());
282 0 : pBindings->Update(pSlave->GetSlotId());
283 : }
284 : else
285 : {
286 0 : pBindings->Invalidate(rSlot.GetSlotId());
287 0 : pBindings->Update(rSlot.GetSlotId());
288 : }
289 : }
290 :
291 1 : return sal_True;
292 : }
293 : }
294 :
295 0 : return sal_False;
296 : }
297 :
298 : //====================================================================
299 263 : void SfxDispatcher::Construct_Impl( SfxDispatcher* pParent )
300 : {
301 263 : pImp = new SfxDispatcher_Impl;
302 263 : bFlushed = sal_True;
303 263 : SfxApplication *pSfxApp = SFX_APP();
304 :
305 263 : pImp->pCachedServ1 = 0;
306 263 : pImp->pCachedServ2 = 0;
307 263 : pImp->bFlushing = sal_False;
308 263 : pImp->bUpdated = sal_False;
309 263 : pImp->bLocked = sal_False;
310 263 : pImp->bActive = sal_False;
311 263 : pImp->pParent = NULL;
312 263 : pImp->bNoUI = sal_False;
313 263 : pImp->bReadOnly = sal_False;
314 263 : pImp->bQuiet = sal_False;
315 263 : pImp->bModal = sal_False;
316 263 : pImp->pInCallAliveFlag = 0;
317 263 : pImp->bFilterEnabling = sal_False;
318 263 : pImp->nFilterCount = 0;
319 263 : pImp->pFilterSIDs = 0;
320 263 : pImp->nStandardMode = 0;
321 263 : pImp->pDisableList = pSfxApp->GetDisabledSlotList_Impl();
322 263 : pImp->nDisableFlags = 0;
323 :
324 263 : pImp->pParent = pParent;
325 :
326 263 : pImp->bInvalidateOnUnlock = sal_False;
327 :
328 3682 : for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
329 3419 : pImp->aObjBars[n].nResId = 0;
330 :
331 263 : GenLink aGenLink( LINK(this, SfxDispatcher, PostMsgHandler) );
332 :
333 263 : pImp->xPoster = new SfxHintPoster(aGenLink);
334 :
335 263 : pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
336 263 : pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
337 263 : }
338 :
339 19 : SfxDispatcher::SfxDispatcher( SfxDispatcher* pParent )
340 : {
341 19 : Construct_Impl( pParent );
342 19 : pImp->pFrame = 0;
343 19 : }
344 :
345 244 : SfxDispatcher::SfxDispatcher( SfxViewFrame *pViewFrame )
346 :
347 : /* [Description]
348 :
349 : The constructor of the SfxDispatcher class places a stack of empty
350 : <SfxShell> pointers. It is not initially locked and is considered flushed.
351 : */
352 :
353 : {
354 244 : if ( pViewFrame )
355 : {
356 244 : SfxViewFrame *pFrame = pViewFrame->GetParentViewFrame();
357 244 : if ( pFrame )
358 0 : Construct_Impl( pFrame->GetDispatcher() );
359 : else
360 244 : Construct_Impl( 0 );
361 : }
362 : else
363 0 : Construct_Impl( 0 );
364 244 : pImp->pFrame = pViewFrame;
365 244 : }
366 :
367 : //====================================================================
368 134 : SfxDispatcher::~SfxDispatcher()
369 :
370 : /* [Description]
371 :
372 : The destructor of the SfxDispatcher class should not be called when the
373 : SfxDispatcher instance is active. It may, however, still be a <SfxShell>
374 : pointer on the stack.
375 : */
376 :
377 : {
378 : #ifdef DBG_UTIL
379 : rtl::OStringBuffer sTemp(RTL_CONSTASCII_STRINGPARAM("Delete Dispatcher "));
380 : sTemp.append(reinterpret_cast<sal_Int64>(this));
381 : OSL_TRACE("%s", sTemp.getStr());
382 : DBG_ASSERT( !pImp->bActive, "deleting active Dispatcher" );
383 : #endif
384 :
385 : // So that no timer by Reschedule in PlugComm strikes the LeaveRegistrations
386 67 : pImp->aTimer.Stop();
387 67 : pImp->xPoster->SetEventHdl( Link() );
388 :
389 : // Notify the stack varialbles in Call_Impl
390 67 : if ( pImp->pInCallAliveFlag )
391 0 : *pImp->pInCallAliveFlag = sal_False;
392 :
393 : // Get bindings and application
394 67 : SfxApplication *pSfxApp = SFX_APP();
395 67 : SfxBindings* pBindings = GetBindings();
396 :
397 : // When not flushed, revive the bindings
398 67 : if ( pBindings && !pSfxApp->IsDowning() && !bFlushed )
399 63 : pBindings->DLEAVEREGISTRATIONS();
400 :
401 : // may unregister the bindings
402 205 : while ( pBindings )
403 : {
404 71 : if ( pBindings->GetDispatcher_Impl() == this)
405 67 : pBindings->SetDispatcher(0);
406 71 : pBindings = pBindings->GetSubBindings_Impl();
407 : }
408 :
409 67 : delete pImp;
410 134 : }
411 :
412 : //====================================================================
413 2213 : void SfxDispatcher::Pop
414 : (
415 : SfxShell& rShell, /* the stack to take the SfxShell instance. */
416 :
417 : sal_uInt16 nMode /* SFX_SHELL_POP_UNTIL
418 : Also all 'rShell' of SfxShells are taken from the
419 : stack.
420 :
421 : SFX_SHELL_POP_DELETE
422 : All SfxShells actually taken from the stack
423 : will be deleted.
424 :
425 : SFX_SHELL_PUSH (InPlace use only)
426 : The Shell is pushed. */
427 : )
428 : /* [Description]
429 :
430 : With this method, one or more <SfxShell> are poped from the SfxDispatcher.
431 : The SfxShell is marked for popping and a timer is set up. Only when the
432 : timer has reached the end, the pop is actually performed
433 : ( <SfxDispatcher::Flush()> ) and the <SfxBindings> is invalidated.
434 : While the timer is running the opposing push and pop commands on one
435 : SfxShell cancel each other out.
436 : */
437 :
438 : {
439 : DBG_ASSERT( rShell.GetInterface(),
440 : "pushing SfxShell without previous RegisterInterface()" );
441 :
442 2213 : bool bDelete = (nMode & SFX_SHELL_POP_DELETE) == SFX_SHELL_POP_DELETE;
443 2213 : bool bUntil = (nMode & SFX_SHELL_POP_UNTIL) == SFX_SHELL_POP_UNTIL;
444 2213 : bool bPush = (nMode & SFX_SHELL_PUSH) == SFX_SHELL_PUSH;
445 :
446 2213 : SfxApplication *pSfxApp = SFX_APP();
447 :
448 : SAL_INFO(
449 : "sfx2",
450 : "-SfxDispatcher(" << this << (bPush ? ")::Push(" : ")::Pop(")
451 : << (rShell.GetInterface()
452 : ? rShell.GetInterface()->GetClassName() : SAL_STREAM(&rShell))
453 : << (bDelete ? ") with delete" : ")")
454 : << (bUntil ? " (up to)" : ""));
455 :
456 : // same shell as on top of the to-do stack?
457 2213 : if(pImp->aToDoStack.size() && pImp->aToDoStack.front().pCluster == &rShell)
458 : {
459 : // cancel inverse actions
460 2 : if ( pImp->aToDoStack.front().bPush != bPush )
461 2 : pImp->aToDoStack.pop_front();
462 : else
463 : {
464 : DBG_ASSERT( bPush, "SfxInterface pushed more than once" );
465 : DBG_ASSERT( !bPush, "SfxInterface popped more than once" );
466 : }
467 : }
468 : else
469 : {
470 : // Remember ::com::sun::star::chaos::Action
471 2211 : pImp->aToDoStack.push_front( SfxToDo_Impl(bPush, bDelete, bUntil, rShell) );
472 2211 : if ( bFlushed )
473 : {
474 : OSL_TRACE("Unflushed dispatcher!");
475 926 : bFlushed = sal_False;
476 926 : pImp->bUpdated = sal_False;
477 :
478 : // Put bindings to sleep
479 926 : SfxBindings* pBindings = GetBindings();
480 926 : if ( pBindings )
481 907 : pBindings->DENTERREGISTRATIONS();
482 : }
483 : }
484 :
485 2213 : if(!pSfxApp->IsDowning() && !pImp->aToDoStack.empty())
486 : {
487 : // No immediate update is requested
488 2213 : pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
489 2213 : pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
490 2213 : pImp->aTimer.Start();
491 : }
492 : else
493 : {
494 : // but to do nothing
495 0 : pImp->aTimer.Stop();
496 :
497 : // Bindings may wake up again
498 0 : if(pImp->aToDoStack.empty())
499 : {
500 0 : SfxBindings* pBindings = GetBindings();
501 0 : if ( pBindings )
502 0 : pBindings->DLEAVEREGISTRATIONS();
503 : }
504 : }
505 2213 : }
506 :
507 : //--------------------------------------------------------------------
508 :
509 0 : IMPL_LINK_INLINE_START( SfxDispatcher, EventHdl_Impl, void *, pvoid )
510 :
511 : /* [Description]
512 :
513 : This handler is called after <SfxDispatcher::Invalidate()> or after
514 : changes on the stack (<SfxDispatcher::Push()> and <SfxDispatcher::Pop())
515 :
516 : It flushes the Stack, if it is dirty, thus it actually excecutes the
517 : pending Push and Pop commands.
518 : */
519 :
520 : {
521 : (void)pvoid; // unused
522 :
523 0 : Flush();
524 0 : Update_Impl();
525 0 : SfxBindings* pBindings = GetBindings();
526 0 : if ( pBindings )
527 0 : pBindings->StartUpdate_Impl(sal_False);
528 0 : return 0;
529 : }
530 0 : IMPL_LINK_INLINE_END( SfxDispatcher, EventHdl_Impl, void *, pvoid )
531 :
532 : //--------------------------------------------------------------------
533 0 : sal_Bool SfxDispatcher::CheckVirtualStack( const SfxShell& rShell, sal_Bool bDeep )
534 :
535 : /* [Description]
536 :
537 : With this method it can be tested whether the <SfxShell> rShell is on the
538 : stack, when it was flushed. This way the SfxDispatcher is not actually
539 : flushed.
540 :
541 : This method is intended among other things to make assertions possible
542 : without the side effect of having to flush the SfxDispathcer.
543 : */
544 :
545 : {
546 : SFX_STACK(SfxDispatcher::CheckVirtualStack);
547 :
548 0 : SfxShellStack_Impl aStack( pImp->aStack );
549 0 : for(std::deque<SfxToDo_Impl>::reverse_iterator i = pImp->aToDoStack.rbegin(); i != pImp->aToDoStack.rend(); ++i)
550 : {
551 0 : if(i->bPush)
552 0 : aStack.Push(i->pCluster);
553 : else
554 : {
555 0 : SfxShell* pPopped(NULL);
556 0 : do
557 : {
558 : DBG_ASSERT( aStack.Count(), "popping from empty stack" );
559 0 : pPopped = aStack.Pop();
560 : }
561 0 : while(i->bUntil && pPopped != i->pCluster);
562 : DBG_ASSERT(pPopped == i->pCluster, "popping unpushed SfxInterface");
563 : }
564 : }
565 :
566 : sal_Bool bReturn;
567 0 : if ( bDeep )
568 0 : bReturn = aStack.Contains(&rShell);
569 : else
570 0 : bReturn = aStack.Top() == &rShell;
571 0 : return bReturn;
572 : }
573 :
574 : //--------------------------------------------------------------------
575 63 : sal_uInt16 SfxDispatcher::GetShellLevel( const SfxShell& rShell )
576 :
577 : /* [Description]
578 :
579 : Determines the position of a given SfxShell in the stack of the dispatcher.
580 : If possible this is flushed before.
581 :
582 : [Return value]
583 :
584 : sal_uInt16 == USRT_MAX
585 : The SfxShell is not on this SfxDispatcher.
586 :
587 : < USHRT_MAX
588 : Position of the SfxShell on the Dispatcher
589 : from the top count stating with 0.
590 : */
591 :
592 : {
593 : SFX_STACK(SfxDispatcher::GetShellLevel);
594 63 : Flush();
595 :
596 253 : for ( sal_uInt16 n = 0; n < pImp->aStack.Count(); ++n )
597 253 : if ( pImp->aStack.Top( n ) == &rShell )
598 63 : return n;
599 0 : if ( pImp->pParent )
600 : {
601 0 : sal_uInt16 nRet = pImp->pParent->GetShellLevel(rShell);
602 0 : if ( nRet == USHRT_MAX )
603 0 : return nRet;
604 0 : return nRet + pImp->aStack.Count();
605 : }
606 :
607 0 : return USHRT_MAX;
608 : }
609 :
610 : //--------------------------------------------------------------------
611 11299 : SfxShell *SfxDispatcher::GetShell(sal_uInt16 nIdx) const
612 :
613 : /* [Description]
614 :
615 : Returns a pointer to the <SfxShell> which is at the position nIdx
616 : (from the top, last pushed is 0) on the stack.
617 :
618 : Thus the SfxDispatcher is not flushed.
619 :
620 : Is the stack not deep enough a NULL-Pointer is returned.
621 : */
622 :
623 : {
624 11299 : sal_uInt16 nShellCount = pImp->aStack.Count();
625 11299 : if ( nIdx < nShellCount )
626 11299 : return pImp->aStack.Top(nIdx);
627 0 : else if ( pImp->pParent )
628 0 : return pImp->pParent->GetShell( nIdx - nShellCount );
629 0 : return 0;
630 : }
631 :
632 : //--------------------------------------------------------------------
633 7272 : SfxBindings* SfxDispatcher::GetBindings() const
634 :
635 : /* [Description]
636 :
637 : This method returns a pointer to the <SfxBinding> Instance on which the
638 : SfxDispatcher is curretly bound. A SfxDispatcher is only bound to
639 : the SfxBindings when it is <UI-aktiv>. If it is not UI-active,
640 : a NULL-pointer is returned.
641 :
642 : The returned pointer is only valid in the immediate context of the method
643 : call.
644 : */
645 :
646 : {
647 7272 : if ( pImp->pFrame )
648 7215 : return &pImp->pFrame->GetBindings();
649 : else
650 57 : return NULL;
651 : }
652 :
653 : //--------------------------------------------------------------------
654 12986 : SfxViewFrame* SfxDispatcher::GetFrame() const
655 :
656 : /* [Description]
657 :
658 : Returns a pointer to the <SfxViewFrame> instance, which belongs to
659 : this SfxDispatcher. If it is about the application dispatcher,
660 : a NULL-pointer is returned.
661 : */
662 :
663 : {
664 12986 : return pImp->pFrame;
665 : }
666 :
667 : //--------------------------------------------------------------------
668 255 : void SfxDispatcher::DoActivate_Impl( sal_Bool bMDI, SfxViewFrame* /* pOld */ )
669 :
670 : /* [Description]
671 :
672 : This method controls the activation of a dispatcher.
673 :
674 : Since the application dispatcher is always active, either as a sub
675 : dispatcher of the <SfxViewFrame> dispatcher or as itself, it is never
676 : activated as a whole, instead only its individual <SfxShell>s at
677 : <SfxDispatcher::Push(SfxShell&)>.
678 :
679 : When activating a SfxDispatcher all of the SfxShells located on its stack
680 : are called with the handler <SfxShell::Activate(sal_Bool)>, starting with
681 : the lowest.
682 : */
683 :
684 : {
685 : SFX_STACK(SfxDispatcher::DoActivate);
686 255 : if ( bMDI )
687 : {
688 : #ifdef DBG_UTIL
689 : rtl::OStringBuffer sTemp(
690 : RTL_CONSTASCII_STRINGPARAM("Activate Dispatcher "));
691 : sTemp.append(reinterpret_cast<sal_Int64>(this));
692 : OSL_TRACE("%s", sTemp.getStr());
693 : DBG_ASSERT( !pImp->bActive, "Activation error" );
694 : #endif
695 255 : pImp->bActive = sal_True;
696 255 : pImp->bUpdated = sal_False;
697 255 : SfxBindings* pBindings = GetBindings();
698 255 : if ( pBindings )
699 : {
700 236 : pBindings->SetDispatcher(this);
701 236 : pBindings->SetActiveFrame( pImp->pFrame->GetFrame().GetFrameInterface() );
702 : }
703 : }
704 : else
705 : {
706 : #ifdef DBG_UTIL
707 : rtl::OStringBuffer sTemp(
708 : RTL_CONSTASCII_STRINGPARAM("Non-MDI-Activate Dispatcher"));
709 : sTemp.append(reinterpret_cast<sal_Int64>(this));
710 : OSL_TRACE("%s", sTemp.getStr());
711 : #endif
712 : }
713 :
714 255 : if ( IsAppDispatcher() )
715 274 : return;
716 :
717 1423 : for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
718 1187 : pImp->aStack.Top( (sal_uInt16) i )->DoActivate_Impl(pImp->pFrame, bMDI);
719 :
720 236 : if ( bMDI && pImp->pFrame )
721 : {
722 236 : SfxBindings *pBind = GetBindings();
723 708 : while ( pBind )
724 : {
725 236 : pBind->HidePopupCtrls_Impl( sal_False );
726 236 : pBind = pBind->GetSubBindings_Impl();
727 : }
728 :
729 236 : pImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( sal_False, sal_False, 1 );
730 : }
731 :
732 236 : if(!pImp->aToDoStack.empty())
733 : {
734 : // No immediate update is requested
735 0 : pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
736 0 : pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
737 0 : pImp->aTimer.Start();
738 : }
739 : }
740 :
741 0 : void SfxDispatcher::DoParentActivate_Impl()
742 : {
743 0 : for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
744 0 : pImp->aStack.Top( (sal_uInt16) i )->ParentActivate();
745 0 : }
746 :
747 : //--------------------------------------------------------------------
748 236 : void SfxDispatcher::DoDeactivate_Impl( sal_Bool bMDI, SfxViewFrame* pNew )
749 :
750 : /* [Description]
751 :
752 : This method controls the deactivation of a dispatcher.
753 :
754 : Since the application dispatcher is always active, either as a sub
755 : dispatcher of the <SfxViewFrame> dispatcher or as itself, it is never
756 : deactivated as a whole, instead only its individual <SfxShell>s at
757 : <SfxDispatcher::Pop(SfxShell&)>.
758 :
759 : When deactivating a SfxDispatcher all of the SfxShells located on its stack
760 : are called with the handler <SfxShell::Deactivate(sal_Bool)>, starting with
761 : the lowest.
762 : */
763 :
764 : {
765 : SFX_STACK(SfxDispatcher::DoDeactivate);
766 :
767 236 : SfxApplication *pSfxApp = SFX_APP();
768 :
769 236 : if ( bMDI )
770 : {
771 : OSL_TRACE(rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Deactivate Dispatcher")).append(reinterpret_cast<sal_Int64>(this)).getStr());
772 : DBG_ASSERT( pImp->bActive, "Deactivate error" );
773 236 : pImp->bActive = sal_False;
774 :
775 236 : if ( pImp->pFrame && !(pImp->pFrame->GetObjectShell()->IsInPlaceActive() ) )
776 : {
777 236 : SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
778 236 : if ( pWorkWin )
779 : {
780 8999 : for (size_t n=0; n<pImp->aChildWins.size();)
781 : {
782 8527 : SfxChildWindow *pWin = pWorkWin->GetChildWindow_Impl( (sal_uInt16) ( pImp->aChildWins[n] & 0xFFFF ) );
783 8527 : if (!pWin || (pWin && pWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT))
784 8354 : pImp->aChildWins.erase(pImp->aChildWins.begin()+n);
785 : else
786 173 : n++;
787 : }
788 : }
789 : }
790 : }
791 : else {
792 : OSL_TRACE(rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Non-MDI-DeActivate Dispatcher")).append(reinterpret_cast<sal_Int64>(this)).getStr());
793 : }
794 :
795 236 : if ( IsAppDispatcher() && !pSfxApp->IsDowning() )
796 236 : return;
797 :
798 2146 : for ( sal_uInt16 i = 0; i < pImp->aStack.Count(); ++i )
799 1910 : pImp->aStack.Top(i)->DoDeactivate_Impl(pImp->pFrame, bMDI);
800 :
801 236 : sal_Bool bHidePopups = bMDI && pImp->pFrame;
802 236 : if ( pNew && pImp->pFrame )
803 : {
804 : com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xOldFrame(
805 173 : pNew->GetFrame().GetFrameInterface()->getCreator(), com::sun::star::uno::UNO_QUERY );
806 :
807 : com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xMyFrame(
808 173 : GetFrame()->GetFrame().GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
809 :
810 173 : if ( xOldFrame == xMyFrame )
811 0 : bHidePopups = sal_False;
812 : }
813 :
814 236 : if ( bHidePopups )
815 : {
816 236 : SfxBindings *pBind = GetBindings();
817 708 : while ( pBind )
818 : {
819 236 : pBind->HidePopupCtrls_Impl( sal_True );
820 236 : pBind = pBind->GetSubBindings_Impl();
821 : }
822 :
823 236 : pImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( sal_True, sal_False, 1 );
824 : }
825 :
826 236 : Flush();
827 : }
828 :
829 0 : void SfxDispatcher::DoParentDeactivate_Impl()
830 : {
831 0 : for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
832 0 : pImp->aStack.Top( (sal_uInt16) i )->ParentDeactivate();
833 0 : }
834 :
835 : //--------------------------------------------------------------------
836 1 : int SfxDispatcher::GetShellAndSlot_Impl
837 : (
838 : sal_uInt16 nSlot, // the searchable Slot-Id
839 : SfxShell** ppShell, // the SfxShell, which are currently handled
840 : // the nSlot
841 : const SfxSlot** ppSlot, // the SfxSlot, which are currently handled
842 : // the nSlot
843 : sal_Bool bOwnShellsOnly,
844 : sal_Bool bModal, // ModalMode
845 : sal_Bool bRealSlot
846 : )
847 :
848 : /* [Description]
849 :
850 : This method searches in SfxDispatcher after <SfxShell> , from the Slot Id
851 : nSlot currently being handled. For this, the dispatcher is first flushed.
852 :
853 : [Return value]
854 :
855 : int sal_True
856 : The SfxShell was found, ppShell and ppSlot are valid.
857 :
858 : sal_False
859 : The SfxShell was not found, ppShell and ppSlot are invalid.
860 : */
861 :
862 : {
863 : SFX_STACK(SfxDispatcher::GetShellAndSlot_Impl);
864 :
865 1 : Flush();
866 1 : SfxSlotServer aSvr;
867 1 : if ( _FindServer(nSlot, aSvr, bModal) )
868 : {
869 1 : if ( bOwnShellsOnly && aSvr.GetShellLevel() >= pImp->aStack.Count() )
870 0 : return sal_False;
871 :
872 1 : *ppShell = GetShell(aSvr.GetShellLevel());
873 1 : *ppSlot = aSvr.GetSlot();
874 1 : if ( 0 == (*ppSlot)->GetExecFnc() && bRealSlot )
875 0 : *ppSlot = (*ppShell)->GetInterface()->GetRealSlot(*ppSlot);
876 : // Check only real slots as enum slots don't have an execute function!
877 1 : if ( bRealSlot && ((0 == *ppSlot) || (0 == (*ppSlot)->GetExecFnc()) ))
878 0 : return sal_False;
879 :
880 1 : return sal_True;
881 : }
882 :
883 0 : return sal_False;
884 : }
885 :
886 : //--------------------------------------------------------------------
887 1 : void SfxDispatcher::_Execute
888 : (
889 : SfxShell& rShell, // to the calling <SfxShell>
890 : const SfxSlot& rSlot, // to the calling <SfxSlot>
891 : SfxRequest& rReq, // function to be performed
892 : // (Id and optional parameters)
893 : SfxCallMode eCallMode // Synchronously, asynchronously or as shown in
894 : // the slot
895 : )
896 :
897 : /* [Description]
898 :
899 : This method performs a request for a cached <Slot-Server>.
900 : */
901 :
902 : {
903 : DBG_ASSERT( !pImp->bFlushing, "recursive call to dispatcher" );
904 : DBG_ASSERT( pImp->aToDoStack.empty(), "unprepared InPlace _Execute" );
905 :
906 1 : if ( IsLocked( rSlot.GetSlotId() ) )
907 0 : return;
908 :
909 3 : if ( (eCallMode & SFX_CALLMODE_ASYNCHRON) ||
910 1 : ( !(eCallMode & SFX_CALLMODE_SYNCHRON) &&
911 1 : rSlot.IsMode(SFX_SLOT_ASYNCHRON) ) )
912 : {
913 0 : SfxDispatcher *pDispat = this;
914 0 : while ( pDispat )
915 : {
916 0 : sal_uInt16 nShellCount = pDispat->pImp->aStack.Count();
917 0 : for ( sal_uInt16 n=0; n<nShellCount; n++ )
918 : {
919 0 : if ( &rShell == pDispat->pImp->aStack.Top(n) )
920 : {
921 0 : if ( eCallMode & SFX_CALLMODE_RECORD )
922 0 : rReq.AllowRecording( sal_True );
923 0 : pDispat->pImp->xPoster->Post(new SfxRequest(rReq));
924 0 : return;
925 : }
926 : }
927 :
928 0 : pDispat = pDispat->pImp->pParent;
929 : }
930 : }
931 : else
932 1 : Call_Impl( rShell, rSlot, rReq, SFX_CALLMODE_RECORD==(eCallMode&SFX_CALLMODE_RECORD) );
933 : }
934 :
935 : //--------------------------------------------------------------------
936 1 : void MappedPut_Impl( SfxAllItemSet &rSet, const SfxPoolItem &rItem )
937 :
938 : /* [Description]
939 :
940 : Helper function to put from rItem below the Which-ID in the pool of the
941 : Item Sets rSet.
942 : */
943 :
944 : {
945 : // Put with mapped Which-Id if possible
946 1 : const SfxItemPool *pPool = rSet.GetPool();
947 1 : sal_uInt16 nWhich = rItem.Which();
948 1 : if ( pPool->IsSlot(nWhich) )
949 1 : nWhich = pPool->GetWhich(nWhich);
950 1 : rSet.Put( rItem, nWhich );
951 1 : }
952 :
953 : //--------------------------------------------------------------------
954 :
955 : #ifndef SFX_USE_BINDINGS
956 : #define SFX_USE_BINDINGS 0x8000
957 : #endif
958 :
959 0 : const SfxSlot* SfxDispatcher::GetSlot( const String& rCommand )
960 : {
961 : // Count the number of Shells on the linked Dispatcher
962 0 : Flush();
963 0 : sal_uInt16 nTotCount = pImp->aStack.Count();
964 0 : if ( pImp->pParent )
965 : {
966 0 : SfxDispatcher *pParent = pImp->pParent;
967 0 : while ( pParent )
968 : {
969 0 : nTotCount = nTotCount + pParent->pImp->aStack.Count();
970 0 : pParent = pParent->pImp->pParent;
971 : }
972 : }
973 :
974 0 : const SfxSlot *pSlot=NULL;
975 0 : sal_uInt16 nFirstShell = 0;
976 0 : for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
977 : {
978 0 : SfxShell *pObjShell = GetShell(i);
979 0 : SfxInterface *pIFace = pObjShell->GetInterface();
980 0 : pSlot = pIFace->GetSlot( rCommand );
981 0 : if ( pSlot )
982 0 : return pSlot;
983 : }
984 :
985 0 : return 0;
986 : }
987 :
988 : //--------------------------------------------------------------------
989 0 : const SfxPoolItem* SfxDispatcher::Execute(
990 : sal_uInt16 nSlot,
991 : SfxCallMode nCall,
992 : SfxItemSet* pArgs,
993 : SfxItemSet* pInternalArgs,
994 : sal_uInt16 nModi)
995 : {
996 0 : if ( IsLocked(nSlot) )
997 0 : return 0;
998 :
999 0 : SfxShell *pShell = 0;
1000 0 : const SfxSlot *pSlot = 0;
1001 0 : if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
1002 0 : SFX_CALLMODE_MODAL==(nCall&SFX_CALLMODE_MODAL) ) )
1003 : {
1004 0 : SfxAllItemSet aSet( pShell->GetPool() );
1005 0 : if ( pArgs )
1006 : {
1007 0 : SfxItemIter aIter(*pArgs);
1008 0 : for ( const SfxPoolItem *pArg = aIter.FirstItem();
1009 : pArg;
1010 : pArg = aIter.NextItem() )
1011 0 : MappedPut_Impl( aSet, *pArg );
1012 : }
1013 0 : SfxRequest aReq( nSlot, nCall, aSet );
1014 0 : if (pInternalArgs)
1015 0 : aReq.SetInternalArgs_Impl( *pInternalArgs );
1016 0 : aReq.SetModifier( nModi );
1017 :
1018 0 : _Execute( *pShell, *pSlot, aReq, nCall );
1019 0 : return aReq.GetReturnValue();
1020 : }
1021 0 : return 0;
1022 : }
1023 :
1024 : //--------------------------------------------------------------------
1025 0 : const SfxPoolItem* SfxDispatcher::Execute
1026 : (
1027 : sal_uInt16 nSlot, // the Id of the executing function
1028 : SfxCallMode eCall, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON
1029 : // or ..._SLOT
1030 : const SfxPoolItem **pArgs, // Zero teminated C-Array of Parameters
1031 : sal_uInt16 nModi,
1032 : const SfxPoolItem **pInternalArgs // Zero terminated C-Array of Parameters
1033 : )
1034 :
1035 : /* [Description]
1036 :
1037 : Method to excecute a <SfxSlot>s over the Slot-Id.
1038 :
1039 : [Return value]
1040 :
1041 : const SfxPoolItem* Pointer to the SfxPoolItem valid to the next run
1042 : though the Message-Loop, which contains the return
1043 : value.
1044 :
1045 : Or a NULL-Pointer, when the function was not
1046 : executed (for example canceled by the user).
1047 : */
1048 :
1049 : {
1050 0 : if ( IsLocked(nSlot) )
1051 0 : return 0;
1052 :
1053 0 : SfxShell *pShell = 0;
1054 0 : const SfxSlot *pSlot = 0;
1055 0 : if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
1056 0 : SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
1057 : {
1058 : SfxRequest* pReq;
1059 0 : if ( pArgs && *pArgs )
1060 : {
1061 0 : SfxAllItemSet aSet( pShell->GetPool() );
1062 0 : for ( const SfxPoolItem **pArg = pArgs; *pArg; ++pArg )
1063 0 : MappedPut_Impl( aSet, **pArg );
1064 0 : pReq = new SfxRequest( nSlot, eCall, aSet );
1065 : }
1066 : else
1067 0 : pReq = new SfxRequest( nSlot, eCall, pShell->GetPool() );
1068 0 : pReq->SetModifier( nModi );
1069 0 : if( pInternalArgs && *pInternalArgs)
1070 : {
1071 0 : SfxAllItemSet aSet( SFX_APP()->GetPool() );
1072 0 : for ( const SfxPoolItem **pArg = pInternalArgs; *pArg; ++pArg )
1073 0 : aSet.Put( **pArg );
1074 0 : pReq->SetInternalArgs_Impl( aSet );
1075 : }
1076 0 : _Execute( *pShell, *pSlot, *pReq, eCall );
1077 0 : const SfxPoolItem* pRet = pReq->GetReturnValue();
1078 0 : delete pReq; return pRet;
1079 : }
1080 0 : return 0;
1081 : }
1082 :
1083 : //--------------------------------------------------------------------
1084 0 : const SfxPoolItem* SfxDispatcher::Execute
1085 : (
1086 : sal_uInt16 nSlot, // the Id of the executing function
1087 : SfxCallMode eCall, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON or ..._SLOT
1088 : const SfxItemSet &rArgs // <SfxItemSet> with the parameters
1089 : )
1090 :
1091 : /* [Description]
1092 :
1093 : Method to excecute a <SfxSlot>s over the Slot-Id.
1094 :
1095 : [Return value]
1096 :
1097 : const SfxPoolItem* Pointer to the SfxPoolItem valid to the next run
1098 : though the Message-Loop, which contains the return
1099 : value.
1100 :
1101 : Or a NULL-Pointer, when the function was not
1102 : executed (for example canceled by the user).
1103 : */
1104 :
1105 : {
1106 0 : return Execute( nSlot, eCall, 0, rArgs );
1107 : }
1108 :
1109 : //--------------------------------------------------------------------
1110 0 : const SfxPoolItem* SfxDispatcher::Execute
1111 : (
1112 : sal_uInt16 nSlot,
1113 : SfxCallMode eCall,
1114 : sal_uInt16 nModi,
1115 : const SfxItemSet &rArgs
1116 : )
1117 : {
1118 0 : if ( IsLocked(nSlot) )
1119 0 : return 0;
1120 :
1121 0 : SfxShell *pShell = 0;
1122 0 : const SfxSlot *pSlot = 0;
1123 0 : if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
1124 0 : SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
1125 : {
1126 0 : SfxAllItemSet aSet( pShell->GetPool() );
1127 0 : SfxItemIter aIter(rArgs);
1128 0 : for ( const SfxPoolItem *pArg = aIter.FirstItem();
1129 : pArg;
1130 : pArg = aIter.NextItem() )
1131 0 : MappedPut_Impl( aSet, *pArg );
1132 0 : SfxRequest aReq( nSlot, eCall, aSet );
1133 0 : aReq.SetModifier( nModi );
1134 0 : _Execute( *pShell, *pSlot, aReq, eCall );
1135 0 : return aReq.GetReturnValue();
1136 : }
1137 0 : return 0;
1138 : }
1139 :
1140 : //--------------------------------------------------------------------
1141 1 : const SfxPoolItem* SfxDispatcher::Execute
1142 : (
1143 : sal_uInt16 nSlot, // the Id of the executing function
1144 : SfxCallMode eCall, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON or
1145 : // ..._SLOT
1146 : const SfxPoolItem* pArg1, // First parameter
1147 : ... // Zero terminated list of parameters
1148 : )
1149 :
1150 : /* [Description]
1151 :
1152 : Method to excecute a <SfxSlot>s over the Slot-Id.
1153 :
1154 : [Note]
1155 :
1156 : The parameters are copied, can therefore be passed on as the address
1157 : of stack objects.
1158 :
1159 : [Return value]
1160 :
1161 : const SfxPoolItem* Pointer to the SfxPoolItem valid to the next run
1162 : though the Message-Loop, which contains the return
1163 : value.
1164 :
1165 : Or a NULL-Pointer, when the function was not
1166 : executed (for example canceled by the user).
1167 :
1168 : [Example]
1169 :
1170 : pDispatcher->Execute( SID_OPENDOCUMENT, SFX_CALLMODE_SYNCHRON,
1171 : &SfxStringItem( SID_FILE_NAME, "\\tmp\\temp.sdd" ),
1172 : &SfxStringItem( SID_FILTER_NAME, "StarDraw Presentation" ),
1173 : &SfxBoolItem( SID_DOC_READONLY, sal_False ),
1174 : 0L );
1175 : */
1176 :
1177 : {
1178 1 : if ( IsLocked(nSlot) )
1179 0 : return 0;
1180 :
1181 1 : SfxShell *pShell = 0;
1182 1 : const SfxSlot *pSlot = 0;
1183 1 : if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
1184 1 : SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
1185 : {
1186 1 : SfxAllItemSet aSet( pShell->GetPool() );
1187 :
1188 : va_list pVarArgs;
1189 1 : va_start( pVarArgs, pArg1 );
1190 2 : for ( const SfxPoolItem *pArg = pArg1;
1191 : pArg;
1192 1 : pArg = va_arg( pVarArgs, const SfxPoolItem* ) )
1193 1 : MappedPut_Impl( aSet, *pArg );
1194 1 : va_end(pVarArgs);
1195 :
1196 1 : SfxRequest aReq( nSlot, eCall, aSet );
1197 1 : _Execute( *pShell, *pSlot, aReq, eCall );
1198 1 : return aReq.GetReturnValue();
1199 : }
1200 0 : return 0;
1201 : }
1202 :
1203 : //--------------------------------------------------------------------
1204 :
1205 0 : IMPL_LINK( SfxDispatcher, PostMsgHandler, SfxRequest*, pReq )
1206 :
1207 : /* [Description]
1208 :
1209 : Helper method to receive the asynchronously executed <SfxRequest>s.
1210 : */
1211 :
1212 : {
1213 : DBG_ASSERT( !pImp->bFlushing, "recursive call to dispatcher" );
1214 : SFX_STACK(SfxDispatcher::PostMsgHandler);
1215 :
1216 : // Has also the Pool not yet died?
1217 0 : if ( !pReq->IsCancelled() )
1218 : {
1219 0 : if ( !IsLocked(pReq->GetSlot()) )
1220 : {
1221 0 : Flush();
1222 0 : SfxSlotServer aSvr;
1223 0 : if ( _FindServer(pReq->GetSlot(), aSvr, sal_True ) ) // HACK(x), whatever that was supposed to mean
1224 : {
1225 0 : const SfxSlot *pSlot = aSvr.GetSlot();
1226 0 : SfxShell *pSh = GetShell(aSvr.GetShellLevel());
1227 :
1228 : DBG( SfxApplication *pSfxApp = SFX_APP() );
1229 : DBG( pSfxApp->EnterAsynchronCall_Impl() );
1230 :
1231 : // When the pSlot is a "Pseudoslot" for macros or Verbs, it can
1232 : // be destroyed in the Call_Impl, thus do not use it anymore!
1233 0 : pReq->SetSynchronCall( sal_False );
1234 0 : Call_Impl( *pSh, *pSlot, *pReq, pReq->AllowsRecording() ); //! why bRecord?
1235 : DBG( pSfxApp->LeaveAsynchronCall_Impl() );
1236 : }
1237 : }
1238 : else
1239 : {
1240 0 : if ( pImp->bLocked )
1241 0 : pImp->aReqArr.push_back(new SfxRequest(*pReq));
1242 : else
1243 0 : pImp->xPoster->Post(new SfxRequest(*pReq));
1244 : }
1245 : }
1246 :
1247 0 : delete pReq;
1248 0 : return 0;
1249 : }
1250 : //--------------------------------------------------------------------
1251 594 : void SfxDispatcher::SetMenu_Impl()
1252 : {
1253 594 : if ( pImp->pFrame )
1254 : {
1255 594 : SfxViewFrame* pTop = pImp->pFrame->GetTopViewFrame();
1256 594 : if ( pTop && pTop->GetBindings().GetDispatcher() == this )
1257 : {
1258 594 : SfxFrame& rFrame = pTop->GetFrame();
1259 594 : if ( rFrame.IsMenuBarOn_Impl() )
1260 : {
1261 594 : com::sun::star::uno::Reference < com::sun::star::beans::XPropertySet > xPropSet( rFrame.GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
1262 594 : if ( xPropSet.is() )
1263 : {
1264 594 : com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
1265 594 : com::sun::star::uno::Any aValue = xPropSet->getPropertyValue( rtl::OUString( "LayoutManager" ));
1266 594 : aValue >>= xLayoutManager;
1267 594 : if ( xLayoutManager.is() )
1268 : {
1269 594 : rtl::OUString aMenuBarURL( "private:resource/menubar/menubar" );
1270 594 : if ( !xLayoutManager->isElementVisible( aMenuBarURL ) )
1271 236 : xLayoutManager->createElement( aMenuBarURL );
1272 594 : }
1273 594 : }
1274 : }
1275 : }
1276 : }
1277 594 : }
1278 :
1279 : //--------------------------------------------------------------------
1280 805 : void SfxDispatcher::Update_Impl( sal_Bool bForce )
1281 : {
1282 : SFX_STACK(SfxDispatcher::Update_Impl);
1283 :
1284 805 : Flush();
1285 :
1286 805 : if ( !pImp->pFrame )
1287 : return;
1288 :
1289 805 : SFX_APP(); // -Wall is this required???
1290 805 : SfxDispatcher *pDisp = this;
1291 805 : sal_Bool bUpdate = bForce;
1292 2415 : while ( pDisp && pDisp->pImp->pFrame )
1293 : {
1294 805 : SfxWorkWindow *pWork = pDisp->pImp->pFrame->GetFrame().GetWorkWindow_Impl();
1295 805 : SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
1296 805 : if ( pAct == pDisp || pAct == this )
1297 : {
1298 805 : if ( !bUpdate )
1299 447 : bUpdate = !pDisp->pImp->bUpdated;
1300 805 : pDisp->pImp->bUpdated = sal_True;
1301 : }
1302 : else
1303 0 : break;
1304 :
1305 805 : pDisp = pDisp->pImp->pParent;
1306 : }
1307 :
1308 805 : if ( !bUpdate || pImp->pFrame->GetFrame().IsClosing_Impl() )
1309 : return;
1310 :
1311 594 : SfxViewFrame* pTop = pImp->pFrame ? pImp->pFrame->GetTopViewFrame() : NULL;
1312 594 : sal_Bool bUIActive = pTop && pTop->GetBindings().GetDispatcher() == this;
1313 :
1314 594 : if ( !bUIActive && pTop && GetBindings() == &pTop->GetBindings() )
1315 : // keep own tools internally for collecting
1316 0 : GetBindings()->GetDispatcher()->pImp->bUpdated = sal_False;
1317 :
1318 594 : SfxBindings* pBindings = GetBindings();
1319 594 : if ( pBindings )
1320 594 : pBindings->DENTERREGISTRATIONS();
1321 :
1322 594 : com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame = pBindings->GetActiveFrame();
1323 594 : com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xPropSet( xFrame, com::sun::star::uno::UNO_QUERY );
1324 594 : com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
1325 594 : if ( xPropSet.is() )
1326 : {
1327 : try
1328 : {
1329 594 : com::sun::star::uno::Any aValue = xPropSet->getPropertyValue( rtl::OUString( "LayoutManager" ) );
1330 594 : aValue >>= xLayoutManager;
1331 : }
1332 0 : catch (const com::sun::star::uno::Exception&)
1333 : {
1334 : }
1335 : }
1336 :
1337 594 : if ( xLayoutManager.is() )
1338 594 : xLayoutManager->lock();
1339 :
1340 594 : sal_Bool bIsIPActive = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();
1341 594 : SfxInPlaceClient *pClient = pImp->pFrame ? pImp->pFrame->GetViewShell()->GetUIActiveClient() : NULL;
1342 594 : if ( bUIActive && /* !bIsIPActive && */ ( !pClient || !pClient->IsObjectUIActive() ) )
1343 594 : SetMenu_Impl();
1344 :
1345 594 : SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
1346 594 : SfxWorkWindow *pTaskWin = pImp->pFrame->GetTopFrame().GetWorkWindow_Impl();
1347 594 : pTaskWin->ResetStatusBar_Impl();
1348 :
1349 594 : SfxDispatcher *pDispat = this;
1350 1782 : while ( pDispat )
1351 : {
1352 594 : SfxWorkWindow *pWork = pDispat->pImp->pFrame->GetFrame().GetWorkWindow_Impl();
1353 594 : SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
1354 594 : if ( pAct == pDispat || pAct == this )
1355 : {
1356 594 : pWork->ResetObjectBars_Impl();
1357 594 : pWork->ResetChildWindows_Impl();
1358 : }
1359 :
1360 594 : pDispat = pDispat->pImp->pParent;
1361 : }
1362 :
1363 594 : sal_Bool bIsActive = sal_False;
1364 594 : SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
1365 594 : pDispat = this;
1366 1782 : while ( pActDispat && !bIsActive )
1367 : {
1368 594 : if ( pDispat == pActDispat )
1369 594 : bIsActive = sal_True;
1370 594 : pActDispat = pActDispat->pImp->pParent;
1371 : }
1372 :
1373 594 : _Update_Impl( bUIActive, !bIsIPActive, bIsIPActive, pTaskWin );
1374 594 : if ( bUIActive || bIsActive )
1375 594 : pWorkWin->UpdateObjectBars_Impl();
1376 :
1377 594 : if ( pBindings )
1378 594 : pBindings->DLEAVEREGISTRATIONS();
1379 :
1380 594 : if ( xLayoutManager.is() )
1381 594 : xLayoutManager->unlock();
1382 :
1383 594 : return;
1384 : }
1385 :
1386 594 : void SfxDispatcher::_Update_Impl( sal_Bool bUIActive, sal_Bool bIsMDIApp, sal_Bool bIsIPOwner, SfxWorkWindow *pTaskWin )
1387 : {
1388 594 : SFX_APP();
1389 594 : SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
1390 594 : sal_Bool bIsActive = sal_False;
1391 594 : sal_Bool bIsTaskActive = sal_False;
1392 594 : SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
1393 594 : SfxDispatcher *pDispat = this;
1394 1782 : while ( pActDispat && !bIsActive )
1395 : {
1396 594 : if ( pDispat == pActDispat )
1397 594 : bIsActive = sal_True;
1398 594 : pActDispat = pActDispat->pImp->pParent;
1399 : }
1400 :
1401 594 : if ( pImp->pParent && !pImp->bQuiet /* && bUIActive */ )
1402 0 : pImp->pParent->_Update_Impl( bUIActive, bIsMDIApp, bIsIPOwner, pTaskWin );
1403 :
1404 8316 : for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
1405 7722 : pImp->aObjBars[n].nResId = 0;
1406 594 : pImp->aChildWins.clear();
1407 :
1408 : // bQuiet : own shells aren't considered for UI and SlotServer
1409 : // bNoUI: own Shells aren't considered fors UI
1410 594 : if ( pImp->bQuiet || pImp->bNoUI || (pImp->pFrame && pImp->pFrame->GetObjectShell()->IsPreview()) )
1411 594 : return;
1412 :
1413 594 : sal_uInt32 nStatBarId=0;
1414 594 : SfxShell *pStatusBarShell = NULL;
1415 :
1416 594 : SfxSlotPool* pSlotPool = &SfxSlotPool::GetSlotPool( GetFrame() );
1417 594 : sal_uInt16 nTotCount = pImp->aStack.Count();
1418 4675 : for ( sal_uInt16 nShell = nTotCount; nShell > 0; --nShell )
1419 : {
1420 4081 : SfxShell *pShell = GetShell( nShell-1 );
1421 4081 : SfxInterface *pIFace = pShell->GetInterface();
1422 :
1423 : // don't consider shells if "Hidden" oder "Quiet"
1424 4081 : sal_Bool bReadOnlyShell = IsReadOnlyShell_Impl( nShell-1 );
1425 : sal_uInt16 nNo;
1426 9008 : for ( nNo = 0; pIFace && nNo<pIFace->GetObjectBarCount(); ++nNo )
1427 : {
1428 4927 : sal_uInt16 nPos = pIFace->GetObjectBarPos(nNo);
1429 4927 : if ( bReadOnlyShell && !( nPos & SFX_VISIBILITY_READONLYDOC ) )
1430 0 : continue;
1431 :
1432 : // check whether toolbar needs activation of a special feature
1433 4927 : sal_uInt32 nFeature = pIFace->GetObjectBarFeature(nNo);
1434 4927 : if ( nFeature && !pShell->HasUIFeature( nFeature ) )
1435 1080 : continue;
1436 :
1437 : // check for toolboxes that are exclusively for a viewer
1438 3847 : if ( pImp->pFrame)
1439 : {
1440 3847 : sal_Bool bViewerTbx = SFX_VISIBILITY_VIEWER == ( nPos & SFX_VISIBILITY_VIEWER );
1441 3847 : SfxObjectShell* pSh = pImp->pFrame->GetObjectShell();
1442 3847 : SFX_ITEMSET_ARG( pSh->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_VIEWONLY, sal_False );
1443 3847 : sal_Bool bIsViewer = pItem && pItem->GetValue();
1444 3847 : if ( bIsViewer != bViewerTbx )
1445 594 : continue;
1446 : }
1447 :
1448 : // always register toolbars, allows to switch them on
1449 3253 : sal_Bool bVisible = pIFace->IsObjectBarVisible(nNo);
1450 3253 : if ( !bVisible )
1451 0 : nPos &= SFX_POSITION_MASK;
1452 :
1453 3253 : SfxObjectBars_Impl& rBar = pImp->aObjBars[nPos & SFX_POSITION_MASK];
1454 3253 : rBar.nMode = nPos;
1455 3253 : rBar.nResId = pIFace->GetObjectBarResId(nNo).GetId();
1456 3253 : const String *pName = pIFace->GetObjectBarName(nNo);
1457 3253 : if ( pName )
1458 3253 : rBar.aName = *pName;
1459 : else
1460 0 : rBar.aName.Erase();
1461 3253 : rBar.pIFace = pIFace;
1462 :
1463 3253 : if ( bUIActive || bIsActive )
1464 : {
1465 : pWorkWin->SetObjectBar_Impl(
1466 3253 : nPos, rBar.nResId, rBar.pIFace, &rBar.aName );
1467 : }
1468 :
1469 3253 : if ( !bVisible )
1470 0 : rBar.nResId = 0;
1471 : }
1472 :
1473 25581 : for ( nNo=0; pIFace && nNo<pIFace->GetChildWindowCount(); nNo++ )
1474 : {
1475 21500 : sal_uInt32 nId = pIFace->GetChildWindowId(nNo);
1476 21500 : const SfxSlot *pSlot = pSlotPool->GetSlot( (sal_uInt16) nId );
1477 : DBG_ASSERT( pSlot, "Childwindow slot missing!");
1478 21500 : if ( bReadOnlyShell )
1479 : {
1480 : // only show ChildWindows if their slot is allowed for readonly documents
1481 0 : if ( pSlot && !pSlot->IsMode( SFX_SLOT_READONLYDOC ) )
1482 0 : continue;
1483 : }
1484 :
1485 21500 : sal_uInt32 nFeature = pIFace->GetChildWindowFeature(nNo);
1486 21500 : if ( nFeature && !pShell->HasUIFeature( nFeature ) )
1487 2644 : continue;
1488 :
1489 : // slot decides whether a ChildWindow is shown when document is OLE server or OLE client
1490 18856 : sal_uInt16 nMode = SFX_VISIBILITY_STANDARD;
1491 18856 : if( pSlot )
1492 : {
1493 18262 : if ( pSlot->IsMode(SFX_SLOT_CONTAINER) )
1494 : {
1495 2970 : if ( pWorkWin->IsVisible_Impl( SFX_VISIBILITY_CLIENT ) )
1496 2970 : nMode |= SFX_VISIBILITY_CLIENT;
1497 : }
1498 : else
1499 : {
1500 15292 : if ( pWorkWin->IsVisible_Impl( SFX_VISIBILITY_SERVER ) )
1501 15292 : nMode |= SFX_VISIBILITY_SERVER;
1502 : }
1503 : }
1504 :
1505 18856 : if ( bUIActive || bIsActive )
1506 18856 : pWorkWin->SetChildWindowVisible_Impl( nId, sal_True, nMode );
1507 18856 : if ( bUIActive || bIsActive || !pWorkWin->IsFloating( (sal_uInt16) ( nId & 0xFFFF ) ) )
1508 18856 : pImp->aChildWins.push_back( nId );
1509 : }
1510 :
1511 4081 : if ( bIsMDIApp || bIsIPOwner )
1512 : {
1513 4081 : sal_uInt32 nId = pIFace->GetStatusBarResId().GetId();
1514 4081 : if ( nId )
1515 : {
1516 1188 : nStatBarId = nId;
1517 1188 : pStatusBarShell = pShell;
1518 : }
1519 : }
1520 : }
1521 :
1522 8316 : for ( sal_uInt16 nPos=0; nPos<SFX_OBJECTBAR_MAX; nPos++ )
1523 : {
1524 7722 : SfxObjectBars_Impl& rFixed = pImp->aFixedObjBars[nPos];
1525 7722 : if ( rFixed.nResId )
1526 : {
1527 0 : SfxObjectBars_Impl& rBar = pImp->aObjBars[nPos];
1528 0 : rBar = rFixed;
1529 : pWorkWin->SetObjectBar_Impl( rFixed.nMode,
1530 0 : rFixed.nResId, rFixed.pIFace, &rFixed.aName );
1531 : }
1532 : }
1533 :
1534 594 : if ( pTaskWin && ( bIsMDIApp || bIsIPOwner ) )
1535 : {
1536 594 : SfxDispatcher *pActDispatcher = pTaskWin->GetBindings().GetDispatcher_Impl();
1537 594 : SfxDispatcher *pDispatcher = this;
1538 1782 : while ( pActDispatcher && !bIsTaskActive )
1539 : {
1540 594 : if ( pDispatcher == pActDispatcher )
1541 594 : bIsTaskActive = sal_True;
1542 594 : pActDispatcher = pActDispatcher->pImp->pParent;
1543 : }
1544 :
1545 594 : if ( bIsTaskActive && nStatBarId && pImp->pFrame )
1546 : {
1547 : // internal frames also may control statusbar
1548 594 : SfxBindings& rBindings = pImp->pFrame->GetBindings();
1549 594 : pImp->pFrame->GetFrame().GetWorkWindow_Impl()->SetStatusBar_Impl( nStatBarId, pStatusBarShell, rBindings );
1550 : }
1551 : }
1552 : }
1553 :
1554 : //--------------------------------------------------------------------
1555 863 : void SfxDispatcher::FlushImpl()
1556 :
1557 : /* [Description]
1558 :
1559 : Helper method to execute the outstanding push and pop commands.
1560 : */
1561 :
1562 : {
1563 : DBG_PROFSTART(SfxDispatcherFlush);
1564 : SFX_STACK(SfxDispatcher::FlushImpl);
1565 :
1566 : OSL_TRACE("Flushing dispatcher!");
1567 :
1568 863 : pImp->aTimer.Stop();
1569 :
1570 863 : if ( pImp->pParent )
1571 0 : pImp->pParent->Flush();
1572 :
1573 863 : pImp->bFlushing = !pImp->bFlushing;
1574 863 : if ( !pImp->bFlushing )
1575 : {
1576 0 : pImp->bFlushing = sal_True;
1577 : DBG_PROFSTOP(SfxDispatcherFlush);
1578 863 : return;
1579 : }
1580 :
1581 863 : SfxApplication *pSfxApp = SFX_APP();
1582 :
1583 : // Re-build the true stack in the first round
1584 863 : std::deque<SfxToDo_Impl> aToDoCopy;
1585 863 : sal_Bool bModify = sal_False;
1586 3009 : for(std::deque<SfxToDo_Impl>::reverse_iterator i = pImp->aToDoStack.rbegin(); i != pImp->aToDoStack.rend(); ++i)
1587 : {
1588 2146 : bModify = sal_True;
1589 :
1590 2146 : if(i->bPush)
1591 : {
1592 : // Actually push
1593 : DBG_ASSERT(!pImp->aStack.Contains(i->pCluster),
1594 : "pushed SfxShell already on stack" );
1595 1953 : pImp->aStack.Push(i->pCluster);
1596 1953 : i->pCluster->SetDisableFlags(pImp->nDisableFlags);
1597 :
1598 : // Mark the moved shell
1599 1953 : aToDoCopy.push_front(*i);
1600 : }
1601 : else
1602 : {
1603 : // Actually pop
1604 193 : SfxShell* pPopped = 0;
1605 193 : bool bFound = false;
1606 510 : do
1607 : {
1608 : DBG_ASSERT( pImp->aStack.Count(), "popping from empty stack" );
1609 320 : pPopped = pImp->aStack.Pop();
1610 320 : pPopped->SetDisableFlags( 0 );
1611 320 : bFound = (pPopped == i->pCluster);
1612 :
1613 : // Mark the moved Shell
1614 320 : aToDoCopy.push_front(SfxToDo_Impl(sal_False, i->bDelete, sal_False, *pPopped));
1615 : }
1616 510 : while(i->bUntil && !bFound);
1617 : DBG_ASSERT( bFound, "wrong SfxShell popped" );
1618 : }
1619 : }
1620 863 : pImp->aToDoStack.clear();
1621 :
1622 : // Invalidate bindings, if possible
1623 863 : if ( !pSfxApp->IsDowning() )
1624 : {
1625 863 : if ( bModify )
1626 : {
1627 863 : pImp->pCachedServ1 = 0;
1628 863 : pImp->pCachedServ2 = 0;
1629 : }
1630 :
1631 863 : InvalidateBindings_Impl( bModify );
1632 : }
1633 :
1634 863 : pImp->bFlushing = sal_False;
1635 863 : pImp->bUpdated = sal_False; // not only when bModify, if Doc/Template-Config
1636 863 : bFlushed = sal_True;
1637 : OSL_TRACE("Successfully flushed dispatcher!");
1638 :
1639 : // Activate the Shells and possible delete them in the 2nd round
1640 3136 : for(std::deque<SfxToDo_Impl>::reverse_iterator i = aToDoCopy.rbegin(); i != aToDoCopy.rend(); ++i)
1641 : {
1642 2273 : if(i->bPush)
1643 : {
1644 1953 : if ( pImp->bActive )
1645 727 : i->pCluster->DoActivate_Impl(pImp->pFrame, sal_True);
1646 : }
1647 320 : else if ( pImp->bActive )
1648 4 : i->pCluster->DoDeactivate_Impl(pImp->pFrame, sal_True);
1649 : }
1650 :
1651 3136 : for(std::deque<SfxToDo_Impl>::reverse_iterator i = aToDoCopy.rbegin(); i != aToDoCopy.rend(); ++i)
1652 : {
1653 2273 : if(i->bDelete)
1654 194 : delete i->pCluster;
1655 : }
1656 863 : sal_Bool bAwakeBindings = !aToDoCopy.empty();
1657 863 : if( bAwakeBindings )
1658 863 : aToDoCopy.clear();
1659 :
1660 : // If more changes have occured on the stach when
1661 : // Activate/Deactivate/Delete:
1662 863 : if (!bFlushed)
1663 : // If Push/Pop hs been called by someone, theb also EnterReg was called!
1664 0 : FlushImpl();
1665 :
1666 863 : if( bAwakeBindings && GetBindings() )
1667 844 : GetBindings()->DLEAVEREGISTRATIONS();
1668 : DBG_PROFSTOP(SfxDispatcherFlush);
1669 :
1670 12082 : for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
1671 11219 : pImp->aFixedObjBars[n].nResId = 0;
1672 :
1673 863 : SAL_INFO("sfx2", "SfxDispatcher(" << this << ")::Flush() done");
1674 : }
1675 :
1676 : //--------------------------------------------------------------------
1677 0 : void SfxDispatcher::SetSlotFilter
1678 : (
1679 : // HACK(hier muss mal ein enum rein) ???
1680 : sal_Bool bEnable, /* sal_True:
1681 : only enable specified slots,
1682 : disable all other
1683 :
1684 : sal_False:
1685 : disable specified slots,
1686 : first enable all other
1687 : */
1688 : sal_uInt16 nCount, // Number of SIDs in the following Array
1689 : const sal_uInt16* pSIDs // sorted Array of 'nCount' SIDs
1690 : )
1691 :
1692 : /* [Description]
1693 :
1694 : With this method a filter set, the target slots can be enabled or disabled.
1695 : The passed array must be retained until the destructor or the next
1696 : <SetSlotFilter()>, it is not deleted from the dispatcher, so it can thus be
1697 : static.
1698 :
1699 : In read-only documents the quasi ReadOnlyDoc Flag of slots can be
1700 : overturned by the use of 'bEnable == 2', so this will be displayed again.
1701 : On the other slots it has no effect.
1702 :
1703 : [Example]
1704 :
1705 : Targeted disabling of Slots 1, 2 and 3:
1706 :
1707 : static sal_uInt16 const pSIDs[] = { 1, 2, 3 };
1708 : pDisp->SetSlotFilter( sal_False, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
1709 :
1710 : only permit Slots 5, 6 and 7:
1711 :
1712 : static sal_uInt16 const pSIDs[] = { 5, 6, 7 };
1713 : pDisp->SetSlotFilter( sal_True, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
1714 :
1715 : Turn-off Filter:
1716 :
1717 : pDisp->SetSlotFilter();
1718 : */
1719 :
1720 : {
1721 : #ifdef DBG_UTIL
1722 : // Check Array
1723 : for ( sal_uInt16 n = 1; n < nCount; ++n )
1724 : DBG_ASSERT( pSIDs[n] > pSIDs[n-1], "SetSlotFilter: SIDs not sorted" );
1725 : #endif
1726 :
1727 0 : if ( pImp->pFilterSIDs )
1728 0 : pImp->pFilterSIDs = 0;
1729 :
1730 0 : pImp->bFilterEnabling = bEnable;
1731 0 : pImp->nFilterCount = nCount;
1732 0 : pImp->pFilterSIDs = pSIDs;
1733 :
1734 0 : GetBindings()->InvalidateAll(sal_True);
1735 0 : }
1736 :
1737 : //--------------------------------------------------------------------
1738 : EXTERN_C
1739 : #ifdef WNT
1740 : int _cdecl
1741 : #else
1742 : int
1743 : #endif
1744 :
1745 0 : SfxCompareSIDs_Impl( const void* pSmaller, const void* pBigger )
1746 : {
1747 0 : return ( (long) *((sal_uInt16*)pSmaller) ) - ( (long) *((sal_uInt16*)pBigger) );
1748 : }
1749 :
1750 : //--------------------------------------------------------------------
1751 1636 : sal_Bool SfxDispatcher::IsSlotEnabledByFilter_Impl( sal_uInt16 nSID ) const
1752 :
1753 : /* [Description]
1754 :
1755 : Searches for 'nSID' in the Filter set by <SetSlotFilter()> and
1756 : returns sal_True, if the SIDis allowed, or sal_False, if it is
1757 : disabled by the Filter.
1758 :
1759 : [Return value]
1760 : sal_Bool 0 => disabled
1761 : 1 => enabled
1762 : 2 => enabled even if ReadOnlyDoc
1763 : */
1764 :
1765 : {
1766 : // no filter?
1767 1636 : if ( 0 == pImp->nFilterCount )
1768 : // => all SIDs allowed
1769 1636 : return sal_True;
1770 :
1771 : // search
1772 : sal_Bool bFound = 0 != bsearch( &nSID, pImp->pFilterSIDs, pImp->nFilterCount,
1773 0 : sizeof(sal_uInt16), SfxCompareSIDs_Impl );
1774 :
1775 : // even if ReadOnlyDoc
1776 0 : if ( 2 == pImp->bFilterEnabling )
1777 0 : return bFound ? 2 : 1;
1778 : // Otherwise after Negative/Positive Filter
1779 0 : return pImp->bFilterEnabling ? bFound : !bFound;
1780 : }
1781 :
1782 : //--------------------------------------------------------------------
1783 0 : sal_Bool SfxDispatcher::_TryIntercept_Impl
1784 : (
1785 : sal_uInt16 nSlot, // Slot-Id to search for
1786 : SfxSlotServer& rServer, // <SfxSlotServer>-Instance to fill
1787 : sal_Bool bSelf
1788 : )
1789 : {
1790 : // Maybe the parent is also belongs to a component
1791 0 : SfxDispatcher *pParent = pImp->pParent;
1792 0 : sal_uInt16 nLevels = pImp->aStack.Count();
1793 0 : while ( pParent && pParent->pImp->pFrame )
1794 : {
1795 0 : if ( pParent->pImp->pFrame->GetFrame().HasComponent() )
1796 : {
1797 : // Components may be intercepted
1798 0 : if ( pParent->_TryIntercept_Impl( nSlot, rServer, sal_True ) )
1799 : {
1800 : // The own shells are added to the Shell Level
1801 0 : rServer.SetShellLevel( rServer.GetShellLevel() + nLevels );
1802 0 : return sal_True;
1803 : }
1804 : else
1805 : // No further Interception
1806 0 : break;
1807 : }
1808 : else
1809 0 : nLevels = nLevels + pParent->pImp->aStack.Count();
1810 :
1811 0 : pParent = pParent->pImp->pParent;
1812 : }
1813 :
1814 0 : if ( bSelf )
1815 : {
1816 : // Query the ComponentViewShell
1817 0 : Flush();
1818 0 : SfxShell *pObjShell = GetShell(0);
1819 0 : SfxInterface *pIFace = pObjShell->GetInterface();
1820 0 : const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
1821 :
1822 0 : if ( pSlot )
1823 : {
1824 0 : rServer.SetSlot(pSlot);
1825 0 : rServer.SetShellLevel(0);
1826 0 : return sal_True;
1827 : }
1828 : }
1829 :
1830 0 : return sal_False;
1831 : }
1832 :
1833 1636 : sal_Bool SfxDispatcher::_FindServer
1834 : (
1835 : sal_uInt16 nSlot, // Slot-Id to search for
1836 : SfxSlotServer& rServer, // <SfxSlotServer>-Instance to fill
1837 : sal_Bool bModal // Dispite ModalMode
1838 : )
1839 :
1840 : /* [Description]
1841 :
1842 : This helper method searches for the <Slot-Server> which currently serves
1843 : the nSlot. As the result, rServe is filled accordingly.
1844 :
1845 : If known the SfxInterface which is currently served by nSlot can be
1846 : passed along.
1847 :
1848 : The SfxDispatcher is flushed while searching for nSlot.
1849 :
1850 : [Return value]
1851 :
1852 :
1853 : sal_Bool sal_True
1854 : The Slot was found, rServer is valid.
1855 :
1856 : sal_False
1857 : The Slot is currently not served, rServer is invalid.
1858 : */
1859 :
1860 : {
1861 : SFX_STACK(SfxDispatcher::_FindServer);
1862 :
1863 : // Dispatcher locked? (nevertheless let SID_HELP_PI through)
1864 1636 : if ( IsLocked(nSlot) )
1865 : {
1866 0 : pImp->bInvalidateOnUnlock = sal_True;
1867 0 : return sal_False;
1868 : }
1869 :
1870 : // Count the number of Shells in the linked dispatchers.
1871 1636 : Flush();
1872 1636 : sal_uInt16 nTotCount = pImp->aStack.Count();
1873 1636 : if ( pImp->pParent )
1874 : {
1875 0 : SfxDispatcher *pParent = pImp->pParent;
1876 0 : while ( pParent )
1877 : {
1878 0 : nTotCount = nTotCount + pParent->pImp->aStack.Count();
1879 0 : pParent = pParent->pImp->pParent;
1880 : }
1881 : }
1882 :
1883 : // Verb-Slot?
1884 1636 : if (nSlot >= SID_VERB_START && nSlot <= SID_VERB_END)
1885 : {
1886 0 : for ( sal_uInt16 nShell = 0;; ++nShell )
1887 : {
1888 0 : SfxShell *pSh = GetShell(nShell);
1889 0 : if ( pSh == NULL )
1890 0 : return false;
1891 0 : if ( pSh->ISA(SfxViewShell) )
1892 : {
1893 0 : const SfxSlot* pSlot = pSh->GetVerbSlot_Impl(nSlot);
1894 0 : if ( pSlot )
1895 : {
1896 0 : rServer.SetShellLevel(nShell);
1897 0 : rServer.SetSlot( pSlot );
1898 0 : return true;
1899 : }
1900 : }
1901 : }
1902 : }
1903 :
1904 : // SID check against set filter
1905 1636 : sal_uInt16 nSlotEnableMode=0;
1906 1636 : if ( pImp->pFrame )
1907 : {
1908 1636 : nSlotEnableMode = IsSlotEnabledByFilter_Impl( nSlot );
1909 1636 : if ( 0 == nSlotEnableMode )
1910 0 : return sal_False;
1911 : }
1912 :
1913 : // In Quiet-Mode only Parent-Dispatcher
1914 1636 : if ( pImp->bQuiet )
1915 : {
1916 0 : if ( pImp->pParent )
1917 : {
1918 0 : sal_Bool bRet = pImp->pParent->_FindServer( nSlot, rServer, bModal );
1919 : rServer.SetShellLevel
1920 0 : ( rServer.GetShellLevel() + pImp->aStack.Count() );
1921 0 : return bRet;
1922 : }
1923 : else
1924 0 : return sal_False;
1925 : }
1926 :
1927 1636 : sal_Bool bReadOnly = ( 2 != nSlotEnableMode && pImp->bReadOnly );
1928 :
1929 : // search through all the shells of the chained dispatchers
1930 : // from top to bottom
1931 1636 : sal_uInt16 nFirstShell = pImp->bModal && !bModal ? pImp->aStack.Count() : 0;
1932 6692 : for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
1933 : {
1934 6692 : SfxShell *pObjShell = GetShell(i);
1935 6692 : SfxInterface *pIFace = pObjShell->GetInterface();
1936 6692 : const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
1937 :
1938 6692 : if ( pSlot && pSlot->nDisableFlags && ( pSlot->nDisableFlags & pObjShell->GetDisableFlags() ) != 0 )
1939 0 : return sal_False;
1940 :
1941 6692 : if ( pSlot && !( pSlot->nFlags & SFX_SLOT_READONLYDOC ) && bReadOnly )
1942 0 : return sal_False;
1943 :
1944 6692 : if ( pSlot )
1945 : {
1946 : // Slot belongs to Container?
1947 1636 : bool bIsContainerSlot = pSlot->IsMode(SFX_SLOT_CONTAINER);
1948 1636 : bool bIsInPlace = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();
1949 :
1950 : // Shell belongs to Server?
1951 : // AppDispatcher or IPFrame-Dispatcher
1952 1636 : bool bIsServerShell = !pImp->pFrame || bIsInPlace;
1953 :
1954 : // Of course ShellServer-Slots are also executable even when it is
1955 : // excecuted on a container dispatcher without a IPClient.
1956 1636 : if ( !bIsServerShell )
1957 : {
1958 1636 : SfxViewShell *pViewSh = pImp->pFrame->GetViewShell();
1959 1636 : bIsServerShell = !pViewSh || !pViewSh->GetUIActiveClient();
1960 : }
1961 :
1962 : // Shell belongs to Container?
1963 : // AppDispatcher or no IPFrameDispatcher
1964 1636 : bool bIsContainerShell = !pImp->pFrame || !bIsInPlace;
1965 : // Shell and Slot match
1966 1636 : if ( !( ( bIsContainerSlot && bIsContainerShell ) ||
1967 1636 : ( !bIsContainerSlot && bIsServerShell ) ) )
1968 0 : pSlot = 0;
1969 : }
1970 :
1971 6692 : if ( pSlot && !IsAllowed( nSlot ) )
1972 : {
1973 0 : pSlot = NULL;
1974 : }
1975 :
1976 6692 : if ( pSlot )
1977 : {
1978 1636 : rServer.SetSlot(pSlot);
1979 1636 : rServer.SetShellLevel(i);
1980 1636 : return sal_True;
1981 : }
1982 : }
1983 :
1984 0 : return sal_False;
1985 : }
1986 :
1987 : //--------------------------------------------------------------------
1988 104 : sal_Bool SfxDispatcher::_FillState
1989 : (
1990 : const SfxSlotServer& rSvr, // <Slot-Server> to query
1991 : SfxItemSet& rState, // <SfxItemSet> to be filled
1992 : const SfxSlot* pRealSlot // The actual Slot if possible
1993 : )
1994 :
1995 : /* [Description]
1996 :
1997 : Helper method to obtain the status of the <Slot-Server>s rSvr.
1998 : The required slots IDs (partly converted to Which-IDs of the pool)
1999 : must be present in rstate.
2000 :
2001 : The SfxDispatcher is flushed before the query.
2002 : */
2003 :
2004 : {
2005 : SFX_STACK(SfxDispatcher::_FillState);
2006 :
2007 : DBG_PROFSTART(SfxDispatcherFillState);
2008 :
2009 104 : const SfxSlot *pSlot = rSvr.GetSlot();
2010 104 : if ( pSlot && IsLocked( pSlot->GetSlotId() ) )
2011 : {
2012 0 : pImp->bInvalidateOnUnlock = sal_True;
2013 : DBG_PROFSTOP(SfxDispatcherFillState);
2014 0 : return sal_False;
2015 : }
2016 :
2017 104 : if ( pSlot )
2018 : {
2019 : DBG_ASSERT(bFlushed, "Dispatcher not flushed after retrieving slot servers!");
2020 104 : if ( !bFlushed )
2021 0 : return sal_False;
2022 :
2023 : // Determine the object and call the Message of this object
2024 104 : SfxShell *pSh = GetShell(rSvr.GetShellLevel());
2025 : DBG_ASSERT(pSh, "ObjektShell not found");
2026 :
2027 : SfxStateFunc pFunc;
2028 :
2029 104 : if (pRealSlot)
2030 104 : pFunc = pRealSlot->GetStateFnc();
2031 : else
2032 0 : pFunc = pSlot->GetStateFnc();
2033 :
2034 104 : pSh->CallState( pFunc, rState );
2035 : #ifdef DBG_UTIL
2036 : // To examine the conformity of IDL (SlotMap) and current Items
2037 : if ( DbgIsAssertWarning() && rState.Count() )
2038 : {
2039 : SfxInterface *pIF = pSh->GetInterface();
2040 : SfxItemIter aIter( rState );
2041 : for ( const SfxPoolItem *pItem = aIter.FirstItem();
2042 : pItem;
2043 : pItem = aIter.NextItem() )
2044 : {
2045 : if ( !IsInvalidItem(pItem) && !pItem->ISA(SfxVoidItem) )
2046 : {
2047 : sal_uInt16 nSlotId = rState.GetPool()->GetSlotId(pItem->Which());
2048 : if ( !pItem->IsA(pIF->GetSlot(nSlotId)->GetType()->Type()) )
2049 : {
2050 : rtl::OStringBuffer aMsg(RTL_CONSTASCII_STRINGPARAM(
2051 : "item-type unequal to IDL (=> no BASIC)"));
2052 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("\nwith SID: "));
2053 : aMsg.append(static_cast<sal_Int32>(nSlotId));
2054 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("\nin "));
2055 : aMsg.append(pIF->GetClassName());
2056 : DbgOut(aMsg.getStr(), DBG_OUT_ERROR, __FILE__, __LINE__);
2057 : }
2058 : }
2059 : }
2060 : }
2061 : #endif
2062 :
2063 : DBG_PROFSTOP(SfxDispatcherFillState);
2064 104 : return sal_True;
2065 : }
2066 :
2067 : DBG_PROFSTOP(SfxDispatcherFillState);
2068 0 : return sal_False;
2069 : }
2070 :
2071 0 : SfxPopupMenuManager* SfxDispatcher::Popup( sal_uInt16 nConfigId,Window *pWin, const Point *pPos )
2072 : {
2073 0 : SfxDispatcher &rDisp = *SFX_APP()->GetDispatcher_Impl();
2074 0 : sal_uInt16 nShLevel = 0;
2075 : SfxShell *pSh;
2076 :
2077 0 : if ( rDisp.pImp->bQuiet )
2078 : {
2079 0 : nConfigId = 0;
2080 0 : nShLevel = rDisp.pImp->aStack.Count();
2081 : }
2082 :
2083 0 : Window *pWindow = pWin ? pWin : rDisp.pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
2084 0 : for ( pSh = rDisp.GetShell(nShLevel); pSh; ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
2085 : {
2086 0 : const ResId& rResId = pSh->GetInterface()->GetPopupMenuResId();
2087 0 : if ( ( nConfigId == 0 && rResId.GetId() ) || ( nConfigId != 0 && rResId.GetId() == nConfigId ) )
2088 : {
2089 0 : return SfxPopupMenuManager::Popup( rResId, rDisp.GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
2090 : }
2091 : }
2092 0 : return 0;
2093 : }
2094 :
2095 :
2096 : //----------------------------------------------------------------------
2097 0 : void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId, Window *pWin, const Point *pPos )
2098 : {
2099 0 : SfxDispatcher &rDisp = *SFX_APP()->GetDispatcher_Impl();
2100 0 : sal_uInt16 nShLevel = 0;
2101 : SfxShell *pSh;
2102 :
2103 0 : if ( rDisp.pImp->bQuiet )
2104 : {
2105 0 : nConfigId = 0;
2106 0 : nShLevel = rDisp.pImp->aStack.Count();
2107 : }
2108 :
2109 0 : Window *pWindow = pWin ? pWin : rDisp.pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
2110 0 : for ( pSh = rDisp.GetShell(nShLevel); pSh; ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
2111 : {
2112 0 : const ResId& rResId = pSh->GetInterface()->GetPopupMenuResId();
2113 0 : if ( ( nConfigId == 0 && rResId.GetId() ) || ( nConfigId != 0 && rResId.GetId() == nConfigId ) )
2114 : {
2115 0 : SfxPopupMenuManager::ExecutePopup( rResId, rDisp.GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
2116 0 : return;
2117 : }
2118 : }
2119 : }
2120 :
2121 : //----------------------------------------------------------------------
2122 0 : void SfxDispatcher::ExecutePopup( const ResId &rId, Window *pWin, const Point *pPos )
2123 : {
2124 0 : Window *pWindow = pWin ? pWin : pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
2125 0 : SfxPopupMenuManager::ExecutePopup( rId, GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
2126 0 : }
2127 :
2128 : //--------------------------------------------------------------------
2129 1003 : void SfxDispatcher::Lock( sal_Bool bLock )
2130 :
2131 : /* [Description]
2132 :
2133 : With this method the SfxDispatcher can be locked and released. A locked
2134 : SfxDispatcher does not perform <SfxRequest>s and does no longer provide
2135 : status information. It behaves as if all the slots were disabled.
2136 : */
2137 :
2138 : {
2139 1003 : SfxBindings* pBindings = GetBindings();
2140 1003 : if ( !bLock && pImp->bLocked && pImp->bInvalidateOnUnlock )
2141 : {
2142 0 : if ( pBindings )
2143 0 : pBindings->InvalidateAll(sal_True);
2144 0 : pImp->bInvalidateOnUnlock = sal_False;
2145 : }
2146 1003 : else if ( pBindings )
2147 1003 : pBindings->InvalidateAll(sal_False);
2148 1003 : pImp->bLocked = bLock;
2149 1003 : if ( !bLock )
2150 : {
2151 590 : for(size_t i = 0; i < pImp->aReqArr.size(); ++i)
2152 0 : pImp->xPoster->Post(&pImp->aReqArr[i]);
2153 590 : pImp->aReqArr.clear();
2154 : }
2155 1003 : }
2156 :
2157 2 : sal_uInt32 SfxDispatcher::GetObjectBarId( sal_uInt16 nPos ) const
2158 : {
2159 2 : return pImp->aObjBars[nPos].nResId;
2160 : }
2161 :
2162 : //-------------------------------------------------------------------------
2163 236 : void SfxDispatcher::HideUI( sal_Bool bHide )
2164 : {
2165 236 : sal_Bool bWasHidden = pImp->bNoUI;
2166 236 : pImp->bNoUI = bHide;
2167 236 : if ( pImp->pFrame )
2168 : {
2169 236 : SfxViewFrame* pTop = pImp->pFrame->GetTopViewFrame();
2170 236 : if ( pTop && pTop->GetBindings().GetDispatcher() == this )
2171 : {
2172 236 : SfxFrame& rFrame = pTop->GetFrame();
2173 236 : if ( rFrame.IsMenuBarOn_Impl() )
2174 : {
2175 236 : com::sun::star::uno::Reference < com::sun::star::beans::XPropertySet > xPropSet( rFrame.GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
2176 236 : if ( xPropSet.is() )
2177 : {
2178 236 : com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
2179 236 : com::sun::star::uno::Any aValue = xPropSet->getPropertyValue( rtl::OUString( "LayoutManager" ));
2180 236 : aValue >>= xLayoutManager;
2181 236 : if ( xLayoutManager.is() )
2182 236 : xLayoutManager->setVisible( !bHide );
2183 236 : }
2184 : }
2185 : }
2186 : }
2187 :
2188 236 : if ( bHide != bWasHidden )
2189 0 : Update_Impl( sal_True );
2190 236 : }
2191 :
2192 240 : void SfxDispatcher::SetReadOnly_Impl( sal_Bool bOn )
2193 : {
2194 240 : pImp->bReadOnly = bOn;
2195 240 : }
2196 :
2197 0 : sal_Bool SfxDispatcher::GetReadOnly_Impl() const
2198 : {
2199 0 : return pImp->bReadOnly;
2200 : }
2201 :
2202 : //-------------------------------------------------------------------------
2203 0 : void SfxDispatcher::SetQuietMode_Impl( sal_Bool bOn )
2204 :
2205 : /* [Description]
2206 :
2207 : With 'bOn' the Dispatcher is quasi dead and transfers everything to the
2208 : Parent-Dispatcher.
2209 : */
2210 :
2211 : {
2212 0 : pImp->bQuiet = bOn;
2213 0 : SfxBindings* pBindings = GetBindings();
2214 0 : if ( pBindings )
2215 0 : pBindings->InvalidateAll(sal_True);
2216 0 : }
2217 :
2218 0 : void SfxDispatcher::SetExecuteMode( sal_uInt16 nMode )
2219 : {
2220 0 : pImp->nStandardMode = nMode;
2221 0 : }
2222 :
2223 0 : SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSlot, const SfxPoolItem* &rpState )
2224 : {
2225 0 : SfxShell *pShell = 0;
2226 0 : const SfxSlot *pSlot = 0;
2227 0 : if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False, sal_False ) )
2228 : {
2229 0 : rpState = pShell->GetSlotState(nSlot);
2230 0 : if ( !rpState )
2231 0 : return SFX_ITEM_DISABLED;
2232 : else
2233 0 : return SFX_ITEM_AVAILABLE;
2234 : }
2235 :
2236 0 : return SFX_ITEM_DISABLED;
2237 : }
2238 :
2239 0 : SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSID, ::com::sun::star::uno::Any& rAny )
2240 : {
2241 0 : SfxShell *pShell = 0;
2242 0 : const SfxSlot *pSlot = 0;
2243 0 : if ( GetShellAndSlot_Impl( nSID, &pShell, &pSlot, sal_False, sal_False ) )
2244 : {
2245 0 : const SfxPoolItem* pItem( 0 );
2246 :
2247 0 : pItem = pShell->GetSlotState( nSID );
2248 0 : if ( !pItem )
2249 0 : return SFX_ITEM_DISABLED;
2250 : else
2251 : {
2252 0 : ::com::sun::star::uno::Any aState;
2253 0 : if ( !pItem->ISA(SfxVoidItem) )
2254 : {
2255 0 : sal_uInt16 nSubId( 0 );
2256 0 : SfxItemPool& rPool = pShell->GetPool();
2257 0 : sal_uInt16 nWhich = rPool.GetWhich( nSID );
2258 0 : if ( rPool.GetMetric( nWhich ) == SFX_MAPUNIT_TWIP )
2259 0 : nSubId |= CONVERT_TWIPS;
2260 0 : pItem->QueryValue( aState, (sal_uInt8)nSubId );
2261 : }
2262 0 : rAny = aState;
2263 :
2264 0 : return SFX_ITEM_AVAILABLE;
2265 : }
2266 : }
2267 :
2268 0 : return SFX_ITEM_DISABLED;
2269 : }
2270 :
2271 4081 : sal_Bool SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell ) const
2272 : {
2273 4081 : sal_uInt16 nShellCount = pImp->aStack.Count();
2274 4081 : if ( nShell < nShellCount )
2275 : {
2276 4081 : SfxShell* pShell = pImp->aStack.Top( nShell );
2277 4081 : if( pShell->ISA( SfxModule ) || pShell->ISA( SfxApplication ) || pShell->ISA( SfxViewFrame ) )
2278 1782 : return sal_False;
2279 : else
2280 2299 : return pImp->bReadOnly;
2281 : }
2282 0 : else if ( pImp->pParent )
2283 0 : return pImp->pParent->IsReadOnlyShell_Impl( nShell - nShellCount );
2284 0 : return sal_True;
2285 : }
2286 :
2287 : // A dirty trick, to get hold of the methods of the private base class
2288 : // SfxShellStack_Impl
2289 : class StackAccess_Impl : public SfxShellStack_Implarr_
2290 : {};
2291 :
2292 63 : void SfxDispatcher::RemoveShell_Impl( SfxShell& rShell )
2293 : {
2294 63 : Flush();
2295 :
2296 : // The cast is because SfxShellStack_Impl member has non of its own
2297 63 : StackAccess_Impl& rStack = *((StackAccess_Impl*) (&pImp->aStack));
2298 63 : sal_uInt16 nCount = rStack.Count();
2299 126 : for ( sal_uInt16 n=0; n<nCount; ++n )
2300 : {
2301 126 : if ( rStack[n] == &rShell )
2302 : {
2303 63 : rStack.Remove( n );
2304 63 : rShell.SetDisableFlags( 0 );
2305 63 : rShell.DoDeactivate_Impl(pImp->pFrame, sal_True);
2306 63 : break;
2307 : }
2308 : }
2309 :
2310 63 : if ( !SFX_APP()->IsDowning() )
2311 : {
2312 63 : pImp->bUpdated = sal_False;
2313 63 : pImp->pCachedServ1 = 0;
2314 63 : pImp->pCachedServ2 = 0;
2315 63 : InvalidateBindings_Impl(sal_True);
2316 : }
2317 63 : }
2318 :
2319 1636 : sal_Bool SfxDispatcher::IsAllowed
2320 : (
2321 : sal_uInt16 nSlot
2322 : ) const
2323 : /*
2324 : [Description]
2325 :
2326 : The method checks whether the access is allowed on this interface.
2327 : */
2328 : {
2329 1636 : if ( !pImp->pDisableList )
2330 : {
2331 1636 : return sal_True;
2332 : }
2333 :
2334 : // BinSearch in the disable list
2335 0 : std::vector<sal_uInt16>& rList = *pImp->pDisableList;
2336 0 : sal_uInt16 nCount = rList.size();
2337 0 : sal_uInt16 nLow = 0, nMid = 0, nHigh;
2338 0 : sal_Bool bFound = sal_False;
2339 0 : nHigh = nCount - 1;
2340 :
2341 0 : while ( !bFound && nLow <= nHigh )
2342 : {
2343 0 : nMid = (nLow + nHigh) >> 1;
2344 : DBG_ASSERT( nMid < nCount, "bsearch is buggy" );
2345 :
2346 0 : int nDiff = (int) nSlot - (int) rList[nMid];
2347 0 : if ( nDiff < 0)
2348 : {
2349 0 : if ( nMid == 0 )
2350 0 : break;
2351 0 : nHigh = nMid - 1;
2352 : }
2353 0 : else if ( nDiff > 0 )
2354 : {
2355 0 : nLow = nMid + 1;
2356 0 : if ( nLow == 0 )
2357 0 : break;
2358 : }
2359 : else
2360 0 : bFound = sal_True;
2361 : }
2362 :
2363 : #ifdef _DEBUG
2364 : // Slot found in the List?
2365 : sal_uInt16 nPos = bFound ? nMid : nLow;
2366 :
2367 : DBG_ASSERT( nPos <= nCount, "" );
2368 : DBG_ASSERT( nPos == nCount || nSlot <= rList[nPos], "" );
2369 : DBG_ASSERT( nPos == 0 || nSlot > rList[nPos-1], "" );
2370 : DBG_ASSERT( ( (nPos+1) >= nCount ) || nSlot < rList[nPos+1], "" );
2371 : #endif
2372 :
2373 0 : return !bFound;
2374 : }
2375 :
2376 926 : void SfxDispatcher::InvalidateBindings_Impl( sal_Bool bModify )
2377 : {
2378 : // App-Dispatcher?
2379 926 : if ( IsAppDispatcher() )
2380 : {
2381 19 : for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst();
2382 : pFrame;
2383 : pFrame = SfxViewFrame::GetNext( *pFrame ) )
2384 0 : pFrame->GetBindings().InvalidateAll(bModify);
2385 : }
2386 : else
2387 : {
2388 907 : SfxDispatcher *pDisp = GetBindings()->GetDispatcher_Impl();
2389 1814 : while ( pDisp )
2390 : {
2391 907 : if ( pDisp == this )
2392 : {
2393 907 : GetBindings()->InvalidateAll( bModify );
2394 907 : break;
2395 : }
2396 :
2397 0 : pDisp = pDisp->pImp->pParent;
2398 : }
2399 : }
2400 926 : }
2401 :
2402 0 : sal_Bool SfxDispatcher::IsUpdated_Impl() const
2403 : {
2404 0 : return pImp->bUpdated;
2405 : }
2406 :
2407 304 : void SfxDispatcher::SetDisableFlags( sal_uInt32 nFlags )
2408 : {
2409 304 : pImp->nDisableFlags = nFlags;
2410 1395 : for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
2411 1091 : pImp->aStack.Top( (sal_uInt16) i )->SetDisableFlags( nFlags );
2412 304 : }
2413 :
2414 640 : sal_uInt32 SfxDispatcher::GetDisableFlags() const
2415 : {
2416 640 : return pImp->nDisableFlags;
2417 : }
2418 :
2419 0 : SfxModule* SfxDispatcher::GetModule() const
2420 : {
2421 0 : for ( sal_uInt16 nShell = 0;; ++nShell )
2422 : {
2423 0 : SfxShell *pSh = GetShell(nShell);
2424 0 : if ( pSh == NULL )
2425 0 : return 0;
2426 0 : if ( pSh->ISA(SfxModule) )
2427 0 : return (SfxModule*) pSh;
2428 : }
2429 : }
2430 :
2431 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|