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/embed/VerbDescriptor.hpp>
21 : #include <com/sun/star/embed/VerbAttributes.hpp>
22 : #include <basic/sbstar.hxx>
23 : #include <officecfg/Office/Common.hxx>
24 : #include <rtl/ustring.hxx>
25 : #include <sal/log.hxx>
26 : #include <svl/itempool.hxx>
27 : #include <svl/undo.hxx>
28 : #include <svtools/itemdel.hxx>
29 : #include <svtools/asynclink.hxx>
30 : #include <basic/sbx.hxx>
31 :
32 : #include <sfx2/app.hxx>
33 : #include <sfx2/shell.hxx>
34 : #include <sfx2/bindings.hxx>
35 : #include <sfx2/dispatch.hxx>
36 : #include <sfx2/viewfrm.hxx>
37 : #include <sfx2/objface.hxx>
38 : #include <sfx2/objsh.hxx>
39 : #include <sfx2/viewsh.hxx>
40 : #include "sfxtypes.hxx"
41 : #include <sfx2/request.hxx>
42 : #include <sfx2/mnumgr.hxx>
43 : #include "statcach.hxx"
44 : #include <sfx2/msgpool.hxx>
45 :
46 : //====================================================================
47 :
48 : DBG_NAME(SfxShell)
49 :
50 : //====================================================================
51 :
52 29002 : TYPEINIT0(SfxShell);
53 :
54 : //====================================================================
55 1904 : class SfxVerbSlotArr_Impl : public std::vector<SfxSlot*>
56 : {
57 : public:
58 642 : ~SfxVerbSlotArr_Impl()
59 642 : {
60 642 : for(const_iterator it = begin(); it != end(); ++it)
61 0 : delete *it;
62 642 : }
63 : };
64 :
65 : using namespace com::sun::star;
66 :
67 : //=========================================================================
68 : // SfxShell_Impl
69 : //=========================================================================
70 : struct SfxShell_Impl: public SfxBroadcaster
71 : {
72 : String aObjectName; // Name of Sbx-Objects
73 : SfxItemPtrMap aItems; // Data exchange on Item level
74 : SfxViewShell* pViewSh; // SfxViewShell if Shell is
75 : // ViewFrame/ViewShell/SubShell list
76 : SfxViewFrame* pFrame; // Frame, if <UI-active>
77 : SfxRepeatTarget* pRepeatTarget; // SbxObjectRef xParent;
78 : sal_Bool bInAppBASIC;
79 : sal_Bool bActive;
80 : sal_uIntPtr nDisableFlags;
81 : sal_uIntPtr nHelpId;
82 : svtools::AsynchronLink* pExecuter;
83 : svtools::AsynchronLink* pUpdater;
84 : SfxVerbSlotArr_Impl aSlotArr;
85 :
86 : com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > aVerbList;
87 1904 : SfxShell_Impl() : pExecuter( 0 ), pUpdater( 0 ) {}
88 1284 : ~SfxShell_Impl() { delete pExecuter; delete pUpdater;}
89 : };
90 :
91 : //=========================================================================
92 : // SfxShell
93 : //=========================================================================
94 :
95 0 : void SfxShell::EmptyExecStub(SfxShell *, SfxRequest &)
96 : {
97 0 : }
98 :
99 0 : void SfxShell::EmptyStateStub(SfxShell *, SfxItemSet &)
100 : {
101 0 : }
102 :
103 930 : SfxShell::SfxShell()
104 :
105 : /* [Description]
106 :
107 : The constructor of the SfxShell class initializes only simple types,
108 : the corresponding SbxObject is only created on-demand. Therefore,
109 : the application of a SfxShell instance is very cheap.
110 : */
111 :
112 : : pImp(0),
113 : pPool(0),
114 930 : pUndoMgr(0)
115 : {
116 : DBG_CTOR(SfxShell, 0);
117 930 : pImp = new SfxShell_Impl;
118 930 : pImp->pViewSh = 0;
119 930 : pImp->pFrame = 0;
120 930 : pImp->pRepeatTarget = 0;
121 930 : pImp->bInAppBASIC = sal_False;
122 930 : pImp->nHelpId = 0L;
123 930 : pImp->bActive = sal_False;
124 930 : pImp->nDisableFlags = 0;
125 930 : }
126 :
127 : //-------------------------------------------------------------------------
128 :
129 974 : SfxShell::SfxShell( SfxViewShell *pViewSh )
130 :
131 : /* [Description]
132 :
133 : The constructor of the SfxShell class initializes only simple types,
134 : the corresponding SbxObject is only created on-demand. Therefore,
135 : the application of a SfxShell instance is very cheap.
136 : */
137 :
138 : : pImp(0),
139 : pPool(0),
140 974 : pUndoMgr(0)
141 : {
142 : DBG_CTOR(SfxShell, 0);
143 974 : pImp = new SfxShell_Impl;
144 974 : pImp->pViewSh = pViewSh;
145 974 : pImp->pFrame = 0;
146 974 : pImp->pRepeatTarget = 0;
147 974 : pImp->bInAppBASIC = sal_False;
148 974 : pImp->nHelpId = 0L;
149 974 : pImp->bActive = sal_False;
150 974 : }
151 :
152 : //--------------------------------------------------------------------
153 :
154 1284 : SfxShell::~SfxShell()
155 :
156 : /* [Description]
157 :
158 : The connection to a possible corresponding SbxObject is dissolved.
159 : The SbxObject may continoue to exist, but can not any longer perform
160 : any functions and can not provide any properties.
161 : */
162 :
163 : {
164 : DBG_DTOR(SfxShell, 0);
165 642 : delete pImp;
166 642 : }
167 :
168 : //--------------------------------------------------------------------
169 :
170 2851 : void SfxShell::SetName( const String &rName )
171 :
172 : /* [Description]
173 :
174 : Sets the name of the Shell object. With this name, the SfxShell instance
175 : of BASIC can be expressed.
176 : */
177 :
178 : {
179 2851 : pImp->aObjectName = rName;
180 2851 : }
181 :
182 : //--------------------------------------------------------------------
183 :
184 3633 : const String& SfxShell::GetName() const
185 :
186 : /* [Description]
187 :
188 : Returns the name of the Shell object. With this name, the SfxShell instance
189 : of BASIC can be expressed.
190 : */
191 :
192 : {
193 3633 : return pImp->aObjectName;
194 : }
195 :
196 : //--------------------------------------------------------------------
197 :
198 0 : SvGlobalName SfxShell::GetGlobalName() const
199 :
200 : /* [Description]
201 :
202 : Provides the Global Unique Identifier of the Shell object. With this name
203 : can the SfxShell instance for example be expressed via OLE Automation, or
204 : be found in the Registration Database.
205 : */
206 :
207 : {
208 0 : return SvGlobalName();
209 : }
210 :
211 : //--------------------------------------------------------------------
212 :
213 552 : SfxDispatcher* SfxShell::GetDispatcher() const
214 :
215 : /* [Description]
216 :
217 : This method returns a pointer to the <SfxDispatcher>, when the SfxShell
218 : is currently <UI-active> or a NULL-pointer if it is not UI-active.
219 :
220 : The returned pointer is only valid in the immediate context of the method
221 : call.
222 : */
223 :
224 : {
225 552 : return pImp->pFrame ? pImp->pFrame->GetDispatcher() : 0;
226 : }
227 :
228 : //--------------------------------------------------------------------
229 :
230 14068 : SfxViewShell* SfxShell::GetViewShell() const
231 :
232 : /* [Description]
233 :
234 : Returns the SfxViewShell in which they are located in the subshells.
235 : Otherwise, and if not specified by the App developer, this method
236 : returns NULL.
237 : */
238 :
239 : {
240 14068 : return pImp->pViewSh;
241 : }
242 :
243 : //--------------------------------------------------------------------
244 :
245 1792 : SfxViewFrame* SfxShell::GetFrame() const
246 :
247 : /* [Description]
248 :
249 : This method returns a pointer to the <SfxViewFrame> to which this SfxShell
250 : instance is associated or in which they currently is <UI-active>.
251 : A NULL pointer is returned if this SfxShell instance is not UI-active at
252 : the moment and also no SfxViewFrame is permanently assigned.
253 :
254 : The returned pointer is only valid in the immediate context of the method
255 : call.
256 :
257 : [Note]
258 :
259 : Only instances of a subclass of SfxApplication and SfxObjectShell
260 : should here provide a NULL-pointer. Otherwise, there is an error in the
261 : application program (wrong constructor was called from SfxShell).
262 :
263 : [Cross-reference]
264 :
265 : <SfxViewShell::GetViewFrame()const>
266 : */
267 :
268 : {
269 1792 : if ( pImp->pFrame )
270 234 : return pImp->pFrame;
271 1558 : if ( pImp->pViewSh )
272 954 : return pImp->pViewSh->GetViewFrame();
273 604 : return 0;
274 : }
275 :
276 : //--------------------------------------------------------------------
277 :
278 408 : const SfxPoolItem* SfxShell::GetItem
279 : (
280 : sal_uInt16 nSlotId // Slot-Id of the querying <SfxPoolItem>s
281 : ) const
282 :
283 : /* [Description]
284 :
285 : With this method any objects of <SfxPoolItemu> subclasses can be accessed.
286 : This exchange method is needed if, for example special <SfxToolBoxControl>
287 : subclasses need access to certain data such as the <SfxObjectShell>.
288 :
289 : The returned instance belongs to the particular SfxShell and may be
290 : used only in the immediate context of the method call.
291 :
292 : [Cross-reference]
293 :
294 : <SfxShell::PutItem(const SfxPoolItem&)>
295 : <SfxShell::RemoveItem(sal_uInt16)>
296 : */
297 :
298 : {
299 408 : SfxItemPtrMap::iterator it = pImp->aItems.find( nSlotId );
300 408 : if( it != pImp->aItems.end() )
301 386 : return it->second;
302 22 : return 0;
303 : }
304 :
305 : //--------------------------------------------------------------------
306 :
307 3121 : void SfxShell::PutItem
308 : (
309 : const SfxPoolItem& rItem /* Instance, of which a copy is created,
310 : which is stored in the SfxShell in a list. */
311 : )
312 :
313 : /* [Description]
314 :
315 : With this method, any objects of subclasses of <SfxPoolItem> can be made
316 : available. This exchange technology is needed if, for example, special
317 : <SfxToolBoxControl> Subclasses need access to certain data such as the
318 : <SfxObjectShell>
319 :
320 : If a SfxPoolItem exists with the same slot ID, it is deleted automatically.
321 :
322 : [Cross-reference]
323 :
324 : <SfxShell::RemoveItem(sal_uInt16)>
325 : <SfxShell::GetItem(sal_uInt16)>
326 : */
327 :
328 : {
329 : DBG_ASSERT( !rItem.ISA(SfxSetItem), "SetItems aren't allowed here" );
330 : DBG_ASSERT( SfxItemPool::IsSlot( rItem.Which() ),
331 : "items with Which-Ids aren't allowed here" );
332 :
333 : // MSC made a mess here of WNT/W95, beware of changes
334 3121 : SfxPoolItem *pItem = rItem.Clone();
335 3121 : SfxPoolItemHint aItemHint( pItem );
336 3121 : const sal_uInt16 nWhich = rItem.Which();
337 :
338 3121 : SfxItemPtrMap::iterator it = pImp->aItems.find( nWhich );
339 3121 : if( it != pImp->aItems.end() )
340 : {
341 552 : SfxPoolItem *pLoopItem = it->second;
342 : // Replace Item
343 552 : delete pLoopItem;
344 552 : it->second = pItem;
345 :
346 : // if active, notify Bindings
347 552 : SfxDispatcher *pDispat = GetDispatcher();
348 552 : if ( pDispat )
349 : {
350 0 : SfxBindings* pBindings = pDispat->GetBindings();
351 0 : pBindings->Broadcast( aItemHint );
352 0 : sal_uInt16 nSlotId = nWhich; //pItem->GetSlotId();
353 0 : SfxStateCache* pCache = pBindings->GetStateCache( nSlotId );
354 0 : if ( pCache )
355 : {
356 0 : pCache->SetState( SFX_ITEM_AVAILABLE, pItem->Clone(), sal_True );
357 0 : pCache->SetCachedState( sal_True );
358 : }
359 : }
360 3121 : return;
361 : }
362 : else
363 : {
364 2569 : Broadcast( aItemHint );
365 2569 : pImp->aItems[ pItem->Which() ] = pItem;
366 3121 : }
367 : }
368 :
369 : //--------------------------------------------------------------------
370 :
371 0 : SfxInterface* SfxShell::GetInterface() const
372 :
373 : /* [Description]
374 :
375 : With this virtual method, which is automatically overloaded by each subclass
376 : with its own slots through the macro <SFX_DECL_INTERFACE>, one can access
377 : each of the <SfxInterface> instance beloning to the subclass.
378 :
379 : The class SfxShell itself has no own SfxInterface (no slots), therefore a
380 : NULL-pointer is returned.
381 : */
382 :
383 : {
384 0 : return GetStaticInterface();
385 : }
386 :
387 : //--------------------------------------------------------------------
388 :
389 1 : ::svl::IUndoManager* SfxShell::GetUndoManager()
390 :
391 : /* [Description]
392 :
393 : Each Subclass of SfxShell can hava a <SfxUndoManager>. This can be set in
394 : the derived class with <SfxShell:SetUndoManager()>.
395 :
396 : The class SfxShell itself does not have a SfxUndoManager, a NULL-pointer
397 : is therefore returned.
398 : */
399 :
400 : {
401 1 : return pUndoMgr;
402 : }
403 :
404 : //--------------------------------------------------------------------
405 :
406 485 : void SfxShell::SetUndoManager( ::svl::IUndoManager *pNewUndoMgr )
407 :
408 : /* [Description]
409 :
410 : Sets a <SfxUndoManager> for this <SfxShell> Instance. For the undo
411 : is only the undo-manager used for SfxShell at the top of the stack of each
412 : <SfxDispatcher>.
413 :
414 : On the given <SfxUndoManager> is automatically the current
415 : Max-Undo-Action-Count setting set form the options.
416 :
417 : 'pNewUndoMgr' must exist until the Destuctor of SfxShell instance is called
418 : or until the next 'SetUndoManager()'.
419 : */
420 :
421 : {
422 : OSL_ENSURE( ( pUndoMgr == NULL ) || ( pNewUndoMgr == NULL ) || ( pUndoMgr == pNewUndoMgr ),
423 : "SfxShell::SetUndoManager: exchanging one non-NULL manager with another non-NULL manager? Suspicious!" );
424 : // there's at least one client of our UndoManager - the DocumentUndoManager at the SfxBaseModel - which
425 : // caches the UndoManager, and registers itself as listener. If exchanging non-NULL UndoManagers is really
426 : // a supported scenario (/me thinks it is not), then we would need to notify all such clients instances.
427 :
428 485 : pUndoMgr = pNewUndoMgr;
429 485 : if ( pUndoMgr )
430 : pUndoMgr->SetMaxUndoActionCount(
431 662 : officecfg::Office::Common::Undo::Steps::get());
432 485 : }
433 :
434 : //--------------------------------------------------------------------
435 :
436 0 : SfxRepeatTarget* SfxShell::GetRepeatTarget() const
437 :
438 : /* [Description]
439 :
440 : Returns a pointer to the <SfxRepeatTarget> instance that is used in
441 : SID_REPEAT as repeat target when it is addressed from the <SfxUndoManager>
442 : supplied by this SfxShell. The return value can be NULL.
443 :
444 : [Note]
445 :
446 : A derivation of <SfxShell> or one of its subclasses of <SfxRepeatTarget>
447 : is not recommended, as compiler errors are provoked.
448 : (due to Call-to-Pointer-to-Member-Function to the subclass).
449 : */
450 :
451 : {
452 0 : return pImp->pRepeatTarget;
453 : }
454 :
455 : //--------------------------------------------------------------------
456 :
457 0 : void SfxShell::SetRepeatTarget( SfxRepeatTarget *pTarget )
458 :
459 : /* [Description]
460 :
461 : Sets the <SfxRepeatTarget> instance that is used in SID_REPEAT as
462 : RepeatTarget, when the current supplied by this <SfxUndoManager> is
463 : addressed. By 'pTarget==0' the SID_REPEAT is disabled for this SfxShell.
464 : The instance '*pTarget' must live as long as it is registered.
465 :
466 : [Note]
467 :
468 : A derivation of <SfxShell> or one of its subclasses of <SfxRepeatTarget>
469 : is not recommended, as compiler errors are provoked.
470 : (due to Call-to-Pointer-to-Member-Function to the subclass).
471 : */
472 :
473 : {
474 0 : pImp->pRepeatTarget = pTarget;
475 0 : }
476 :
477 : //--------------------------------------------------------------------
478 :
479 0 : void SfxShell::Invalidate
480 : (
481 : sal_uInt16 nId /* Invalidated Slot-Id or Which-Id.
482 : If these are 0 (default), then all
483 : by this Shell currently handled Slot-Ids are
484 : invalidated. */
485 : )
486 :
487 : /* [Description]
488 :
489 : With this method can the slots of the subclasses be invalidated through the
490 : slot Id or alternatively through the Which ID. Slot IDs, which are
491 : inherited by the subclass are also invalidert.
492 :
493 : [Cross-reference]
494 :
495 : <SfxBindings::Invalidate(sal_uInt16)>
496 : <SfxBindings::InvalidateAll(sal_Bool)>
497 : */
498 :
499 : {
500 0 : if ( !GetViewShell() )
501 : {
502 : OSL_FAIL( "wrong Invalidate method called!" );
503 0 : return;
504 : }
505 :
506 0 : Invalidate_Impl( GetViewShell()->GetViewFrame()->GetBindings(), nId );
507 : }
508 :
509 4 : void SfxShell::Invalidate_Impl( SfxBindings& rBindings, sal_uInt16 nId )
510 : {
511 4 : if ( nId == 0 )
512 : {
513 0 : rBindings.InvalidateShell( *this, sal_False );
514 : }
515 : else
516 : {
517 4 : const SfxInterface *pIF = GetInterface();
518 0 : do
519 : {
520 4 : const SfxSlot *pSlot = pIF->GetSlot(nId);
521 4 : if ( pSlot )
522 : {
523 : // At Enum-Slots invalidate the Master-Slot
524 4 : if ( SFX_KIND_ENUM == pSlot->GetKind() )
525 0 : pSlot = pSlot->GetLinkedSlot();
526 :
527 : // Invalidate the Slot itself and possible also all Slave-Slots
528 4 : rBindings.Invalidate( pSlot->GetSlotId() );
529 4 : for ( const SfxSlot *pSlave = pSlot->GetLinkedSlot();
530 0 : pSlave && pIF->ContainsSlot_Impl( pSlave ) &&
531 0 : pSlave->GetLinkedSlot() == pSlot;
532 : ++pSlave )
533 0 : rBindings.Invalidate( pSlave->GetSlotId() );
534 :
535 8 : return;
536 : }
537 :
538 0 : pIF = pIF->GetGenoType();
539 : }
540 :
541 : while ( pIF );
542 :
543 : DBG_WARNING( "W3: invalidating slot-id unknown in shell" );
544 : }
545 : }
546 :
547 : //--------------------------------------------------------------------
548 :
549 1914 : void SfxShell::DoActivate_Impl( SfxViewFrame *pFrame, sal_Bool bMDI )
550 :
551 : /* [Description]
552 :
553 : This method controls the activation of SfxShell instance. First, by calling
554 : the virtual method <SfxShell::Activate(sal_Bool)> which gives the subclass the
555 : opportunity to respond to the event.
556 :
557 : When bMDI == TRUE, the associated SbxObject is being 'armed', so that
558 : unqualified methods of the object (without the name of the object)
559 : from BASIC are found.
560 : */
561 :
562 : {
563 : #ifdef DBG_UTIL
564 : const SfxInterface *p_IF = GetInterface();
565 : if ( !p_IF )
566 : return;
567 : #endif
568 : SAL_INFO(
569 : "sfx2.vb",
570 : "SfxShell::DoActivate() " << this << " " << GetInterface()->GetName()
571 : << " bMDI " << (bMDI ? "MDI" : ""));
572 :
573 1914 : if ( bMDI )
574 : {
575 : // Remember Frame, in which it was activated
576 1914 : pImp->pFrame = pFrame;
577 1914 : pImp->bActive = sal_True;
578 : }
579 :
580 : // Notify Subclass
581 1914 : Activate(bMDI);
582 1914 : }
583 :
584 : //--------------------------------------------------------------------
585 :
586 1977 : void SfxShell::DoDeactivate_Impl( SfxViewFrame *pFrame, sal_Bool bMDI )
587 :
588 : /* [Description]
589 :
590 : This method controls the deactivation of the SfxShell instance. When
591 : bMDI == TRUE the SbxObject is first set to a status that only qualified
592 : BASIC methods can be called.
593 :
594 : Then the subclass gets the opportunity in every case to respond to the
595 : event by calling the virtual method <SfxShell::Deactivate(sal_Bool)>.
596 : */
597 :
598 : {
599 : #ifdef DBG_UTIL
600 : const SfxInterface *p_IF = GetInterface();
601 : if ( !p_IF )
602 : return;
603 : #endif
604 : SAL_INFO(
605 : "sfx2.vb",
606 : "SfxShell::DoDeactivate()" << this << " " << GetInterface()->GetName()
607 : << " bMDI " << (bMDI ? "MDI" : ""));
608 :
609 : // Only when it comes from a Frame
610 : // (not when for instance by poping BASIC-IDE from AppDisp)
611 1977 : if ( bMDI && pImp->pFrame == pFrame )
612 : {
613 : // deliver
614 1914 : pImp->pFrame = 0;
615 1914 : pImp->bActive = sal_False;
616 : }
617 :
618 : // Notify Subclass
619 1977 : Deactivate(bMDI);
620 1977 : }
621 :
622 : //--------------------------------------------------------------------
623 :
624 771 : sal_Bool SfxShell::IsActive() const
625 : {
626 771 : return pImp->bActive;
627 : }
628 :
629 : //--------------------------------------------------------------------
630 :
631 1442 : void SfxShell::Activate
632 : (
633 : sal_Bool /*bMDI*/ /* TRUE
634 : the <SfxDispatcher>, on which the SfxShell is
635 : located, is activated or the SfxShell instance
636 : was pushed on an active SfxDispatcher.
637 : (compare with SystemWindow::IsMDIActivate())
638 :
639 : FALSE
640 : the <SfxViewFrame>, on which SfxDispatcher
641 : the SfxShell instance is located, was
642 : activated. (for example by a closing dialoge) */
643 : )
644 :
645 : /* [Description]
646 :
647 : Virtual method that is called when enabling the SfxShell instance,
648 : in order to give the Subclasses the opportunity to respond to the
649 : to the enabling.
650 :
651 : The base implementation is empty and does not need to be called.
652 :
653 : [Cross-reference]
654 :
655 : StarView SystemWindow::Activate(sal_Bool)
656 : */
657 :
658 : {
659 1442 : }
660 :
661 : //--------------------------------------------------------------------
662 :
663 1505 : void SfxShell::Deactivate
664 : (
665 : sal_Bool /*bMDI*/ /* TRUE
666 : the <SfxDispatcher>, on which the SfxShell is
667 : located, is inactivated or the SfxShell instance
668 : was popped on an active SfxDispatcher.
669 : (compare with SystemWindow::IsMDIActivate())
670 :
671 : FALSE
672 : the <SfxViewFrame>, on which SfxDispatcher
673 : the SfxShell instance is located, was
674 : deactivated. (for example by a dialoge) */
675 :
676 : )
677 :
678 : /* [Description]
679 :
680 : Virtual method that is called when disabling the SfxShell instance,
681 : to give the Subclasses the opportunity to respond to the disabling.
682 :
683 : The base implementation is empty and does not need to be called.
684 :
685 : [Cross-reference]
686 :
687 : StarView SystemWindow::Dectivate(sal_Bool)
688 : */
689 :
690 : {
691 1505 : }
692 :
693 0 : void SfxShell::ParentActivate
694 : (
695 : )
696 :
697 : /* [Description]
698 :
699 : A parent of the <SfxDispatcher> on which the SfxShell is located, has
700 : become active, or the SfxShell instance was pushed on a <SfxDispatcher>,
701 : which parent is active.
702 :
703 : The base implementation is empty and does not need to be called.
704 :
705 : [Cross-reference]
706 :
707 : SfxShell::Activate()
708 : */
709 : {
710 0 : }
711 :
712 : //--------------------------------------------------------------------
713 :
714 0 : void SfxShell::ParentDeactivate
715 : (
716 : )
717 :
718 : /* [Description]
719 :
720 : The active parent of the <SfxDispatcher> on which the SfxShell is located,
721 : has been disabled.
722 :
723 : The base implementation is empty and does not need to be called.
724 :
725 : [Cross-reference]
726 :
727 : SfxShell::Deactivate()
728 : */
729 : {
730 0 : }
731 :
732 : //--------------------------------------------------------------------
733 :
734 0 : ResMgr* SfxShell::GetResMgr() const
735 :
736 : /* [Description]
737 :
738 : This method provides the ResMgr of the <Resource-DLL> that are used by
739 : the SfxShell instance. If this is a NULL-pointer, then the current
740 : resource manager is to be used.
741 : */
742 :
743 : {
744 0 : return GetInterface()->GetResMgr();
745 : }
746 :
747 : //--------------------------------------------------------------------
748 :
749 1 : bool SfxShell::CanExecuteSlot_Impl( const SfxSlot &rSlot )
750 :
751 : /* [Description]
752 :
753 : This method determines by calling the status function whether 'rSlot'
754 : can be executed currently.
755 : */
756 : {
757 : // Get Slot status
758 1 : SfxItemPool &rPool = GetPool();
759 1 : const sal_uInt16 nId = rSlot.GetWhich( rPool );
760 1 : SfxItemSet aSet(rPool, nId, nId);
761 1 : SfxStateFunc pFunc = rSlot.GetStateFnc();
762 1 : CallState( pFunc, aSet );
763 1 : return aSet.GetItemState(nId) != SFX_ITEM_DISABLED;
764 : }
765 :
766 : //--------------------------------------------------------------------
767 :
768 0 : long ShellCall_Impl( void* pObj, void* pArg )
769 : {
770 0 : ((SfxShell* )pObj)->ExecuteSlot( *(SfxRequest*)pArg, (SfxInterface*)0L );
771 0 : return 0;
772 : }
773 :
774 : /* [Description]
775 :
776 : Asynchronous ExecuteSlot for the RELOAD
777 : */
778 :
779 : //--------------------------------------------------------------------
780 0 : const SfxPoolItem* SfxShell::ExecuteSlot( SfxRequest& rReq, sal_Bool bAsync )
781 : {
782 0 : if( !bAsync )
783 0 : return ExecuteSlot( rReq, (SfxInterface*)0L );
784 : else
785 : {
786 0 : if( !pImp->pExecuter )
787 : pImp->pExecuter = new svtools::AsynchronLink(
788 0 : Link( this, ShellCall_Impl ) );
789 0 : pImp->pExecuter->Call( new SfxRequest( rReq ) );
790 0 : return 0;
791 : }
792 : }
793 :
794 0 : const SfxPoolItem* SfxShell::ExecuteSlot
795 : (
796 : SfxRequest &rReq, // the relayed <SfxRequest>
797 : const SfxInterface* pIF // default = 0 means get virtually
798 : )
799 :
800 : /* [Description]
801 :
802 : This method allows you to forward a <SfxRequest> to the specified
803 : base <SfxShell>.
804 :
805 : [Example]
806 :
807 : In a derived class of SfxViewShell the SID_PRINTDOCDIRECT will be
808 : intercepted. Under certain circumstances a query should appear before
809 : you print, and the request will be aborted if necessary.
810 :
811 : Also in the IDL of this subclass of the above slot is entered. The status
812 : method will contain in outline:
813 :
814 : void SubViewShell::Exec( SfxRequest &rReq )
815 : {
816 : if ( rReq.GetSlot() == SID_PRINTDOCDIRECT )
817 : {
818 : 'dialog'
819 : if ( 'condition' )
820 : ExecuteSlot( rReq, SfxViewShell::GetInterface() );
821 : }
822 : }
823 :
824 : It usually takes no rReq.Done() to be called as that is already completed
825 : in implementation of the SfxViewShell, for instance it has been canceled.
826 :
827 : [Cross-reference]
828 :
829 : <SfxShell::GetSlotState(sal_uInt16,const SfxInterface*,SfxItemSet*)>
830 : */
831 :
832 : {
833 0 : if ( !pIF )
834 0 : pIF = GetInterface();
835 :
836 0 : sal_uInt16 nSlot = rReq.GetSlot();
837 0 : const SfxSlot* pSlot = NULL;
838 0 : if ( nSlot >= SID_VERB_START && nSlot <= SID_VERB_END )
839 0 : pSlot = GetVerbSlot_Impl(nSlot);
840 0 : if ( !pSlot )
841 0 : pSlot = pIF->GetSlot(nSlot);
842 : DBG_ASSERT( pSlot, "slot not supported" );
843 :
844 0 : SfxExecFunc pFunc = pSlot->GetExecFnc();
845 0 : if ( pFunc )
846 0 : CallExec( pFunc, rReq );
847 :
848 0 : return rReq.GetReturnValue();
849 : }
850 :
851 : //--------------------------------------------------------------------
852 :
853 0 : const SfxPoolItem* SfxShell::GetSlotState
854 : (
855 : sal_uInt16 nSlotId, // Slot-Id to the Slots in question
856 : const SfxInterface* pIF, // default = 0 means get virtually
857 : SfxItemSet* pStateSet // SfxItemSet of the Slot-State method
858 : )
859 :
860 : /* [Description]
861 :
862 : This method returns the status of the slot with the specified slot ID
863 : on the specified interface.
864 :
865 : If the slot is disabled or in this SfxShell (and their parent shells) are
866 : not known, a Null-pointer is returned.
867 :
868 : If the slot does not have a Status, a SfxVoidItem is returned.
869 :
870 : The status is set directly in this Set when pStateSet != 0 , so that
871 : overloaded Slots of the <SfxShell> Subclasses and also in the Status
872 : method of the base implementation can be called.
873 :
874 : [Example]
875 :
876 : In a derived class of SfxViewShell the SID_PRINTDOCDIRECT will be
877 : intercepted. Under certain circumstances a query should appear before
878 : you print, and the request will be aborted if necessary.
879 :
880 : Also in the IDL of this subclass of the above slot is entered. The status
881 : method will contain in outline:
882 :
883 : void SubViewShell::PrintState( SfxItemSet &rState )
884 : {
885 : if ( rState.GetItemState( SID_PRINTDOCDIRECT ) != SFX_ITEM_UNKNOWN )
886 : GetSlotState( SID_PRINTDOCDIRECT, SfxViewShell::GetInterface(),
887 : &rState );
888 : ...
889 : }
890 :
891 : [Cross-reference]
892 :
893 : <SfxShell::ExecuteSlot(SfxRequest&)>
894 : */
895 :
896 : {
897 : // Get Slot on the given Interface
898 0 : if ( !pIF )
899 0 : pIF = GetInterface();
900 : SfxItemState eState;
901 0 : SfxItemPool &rPool = GetPool();
902 :
903 0 : const SfxSlot* pSlot = NULL;
904 0 : if ( nSlotId >= SID_VERB_START && nSlotId <= SID_VERB_END )
905 0 : pSlot = GetVerbSlot_Impl(nSlotId);
906 0 : if ( !pSlot )
907 0 : pSlot = pIF->GetSlot(nSlotId);
908 0 : if ( pSlot )
909 : // Map on Which-Id if possible
910 0 : nSlotId = pSlot->GetWhich( rPool );
911 :
912 : // Get Item and Item status
913 0 : const SfxPoolItem *pItem = NULL;
914 0 : SfxItemSet aSet( rPool, nSlotId, nSlotId ); // else pItem dies too soon
915 0 : if ( pSlot )
916 : {
917 : // Call Status method
918 0 : SfxStateFunc pFunc = pSlot->GetStateFnc();
919 0 : if ( pFunc )
920 0 : CallState( pFunc, aSet );
921 0 : eState = aSet.GetItemState( nSlotId, sal_True, &pItem );
922 :
923 : // get default Item if possible
924 0 : if ( eState == SFX_ITEM_DEFAULT )
925 : {
926 0 : if ( SfxItemPool::IsWhich(nSlotId) )
927 0 : pItem = &rPool.GetDefaultItem(nSlotId);
928 : else
929 0 : eState = SFX_ITEM_DONTCARE;
930 : }
931 : }
932 : else
933 0 : eState = SFX_ITEM_UNKNOWN;
934 :
935 : // Evaluate Item and item status and possibly maintain them in pStateSet
936 0 : SfxPoolItem *pRetItem = 0;
937 0 : if ( eState <= SFX_ITEM_DISABLED )
938 : {
939 0 : if ( pStateSet )
940 0 : pStateSet->DisableItem(nSlotId);
941 0 : return 0;
942 : }
943 0 : else if ( eState == SFX_ITEM_DONTCARE )
944 : {
945 0 : if ( pStateSet )
946 0 : pStateSet->ClearItem(nSlotId);
947 0 : pRetItem = new SfxVoidItem(0);
948 : }
949 : else
950 : {
951 0 : if ( pStateSet && pStateSet->Put( *pItem ) )
952 0 : return &pStateSet->Get( pItem->Which() );
953 0 : pRetItem = pItem->Clone();
954 : }
955 0 : DeleteItemOnIdle(pRetItem);
956 :
957 0 : return pRetItem;
958 : }
959 :
960 : //--------------------------------------------------------------------
961 :
962 0 : SFX_EXEC_STUB(SfxShell, VerbExec)
963 0 : SFX_STATE_STUB(SfxShell, VerbState)
964 :
965 0 : void SfxShell::SetVerbs(const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& aVerbs)
966 : {
967 0 : SfxViewShell *pViewSh = PTR_CAST ( SfxViewShell, this);
968 :
969 : DBG_ASSERT(pViewSh, "Only call SetVerbs at the ViewShell!");
970 0 : if ( !pViewSh )
971 0 : return;
972 :
973 : // First make all Statecaches dirty, so that no-one no longer tries to use
974 : // the Slots
975 : {
976 : SfxBindings *pBindings =
977 0 : pViewSh->GetViewFrame()->GetDispatcher()->GetBindings();
978 0 : sal_uInt16 nCount = pImp->aSlotArr.size();
979 0 : for (sal_uInt16 n1=0; n1<nCount ; n1++)
980 : {
981 0 : sal_uInt16 nId = SID_VERB_START + n1;
982 0 : pBindings->Invalidate(nId, sal_False, sal_True);
983 : }
984 : }
985 :
986 0 : sal_uInt16 nr=0;
987 0 : for (sal_Int32 n=0; n<aVerbs.getLength(); n++)
988 : {
989 0 : sal_uInt16 nSlotId = SID_VERB_START + nr++;
990 : DBG_ASSERT(nSlotId <= SID_VERB_END, "To many Verbs!");
991 0 : if (nSlotId > SID_VERB_END)
992 : break;
993 :
994 0 : SfxSlot *pNewSlot = new SfxSlot;
995 0 : pNewSlot->nSlotId = nSlotId;
996 0 : pNewSlot->nGroupId = 0;
997 :
998 : // Verb slots must be executed asynchronously, so that they can be
999 : // destroyed while executing.
1000 0 : pNewSlot->nFlags = SFX_SLOT_ASYNCHRON | SFX_SLOT_CONTAINER;
1001 0 : pNewSlot->nMasterSlotId = 0;
1002 0 : pNewSlot->nValue = 0;
1003 0 : pNewSlot->fnExec = SFX_STUB_PTR(SfxShell,VerbExec);
1004 0 : pNewSlot->fnState = SFX_STUB_PTR(SfxShell,VerbState);
1005 0 : pNewSlot->pType = 0; // HACK(SFX_TYPE(SfxVoidItem)) ???
1006 0 : pNewSlot->pName = U2S(aVerbs[n].VerbName).getStr();
1007 0 : pNewSlot->pLinkedSlot = 0;
1008 0 : pNewSlot->nArgDefCount = 0;
1009 0 : pNewSlot->pFirstArgDef = 0;
1010 0 : pNewSlot->pUnoName = 0;
1011 :
1012 0 : if (!pImp->aSlotArr.empty())
1013 : {
1014 0 : SfxSlot *pSlot = pImp->aSlotArr[0];
1015 0 : pNewSlot->pNextSlot = pSlot->pNextSlot;
1016 0 : pSlot->pNextSlot = pNewSlot;
1017 : }
1018 : else
1019 0 : pNewSlot->pNextSlot = pNewSlot;
1020 :
1021 0 : pImp->aSlotArr.insert(pImp->aSlotArr.begin() + (sal_uInt16) n, pNewSlot);
1022 : }
1023 :
1024 0 : pImp->aVerbList = aVerbs;
1025 :
1026 0 : if (pViewSh)
1027 : {
1028 : // The status of SID_OBJECT is collected in the controller directly on
1029 : // the Shell, it is thus enough to encourage a new status update
1030 : SfxBindings *pBindings = pViewSh->GetViewFrame()->GetDispatcher()->
1031 0 : GetBindings();
1032 0 : pBindings->Invalidate( SID_OBJECT, sal_True, sal_True );
1033 : }
1034 : }
1035 :
1036 : //--------------------------------------------------------------------
1037 :
1038 0 : const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& SfxShell::GetVerbs() const
1039 : {
1040 0 : return pImp->aVerbList;
1041 : }
1042 :
1043 : //--------------------------------------------------------------------
1044 :
1045 0 : void SfxShell::VerbExec(SfxRequest& rReq)
1046 : {
1047 0 : sal_uInt16 nId = rReq.GetSlot();
1048 0 : SfxViewShell *pViewShell = GetViewShell();
1049 0 : if ( pViewShell )
1050 : {
1051 0 : sal_Bool bReadOnly = pViewShell->GetObjectShell()->IsReadOnly();
1052 0 : com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > aList = pViewShell->GetVerbs();
1053 0 : for (sal_Int32 n=0, nVerb=0; n<aList.getLength(); n++)
1054 : {
1055 : // check for ReadOnly verbs
1056 0 : if ( bReadOnly && !(aList[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES) )
1057 0 : continue;
1058 :
1059 : // check for verbs that shouldn't appear in the menu
1060 0 : if ( !(aList[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU) )
1061 0 : continue;
1062 :
1063 0 : if (nId == SID_VERB_START + nVerb++)
1064 : {
1065 0 : pViewShell->DoVerb(aList[n].VerbID);
1066 0 : rReq.Done();
1067 0 : return;
1068 : }
1069 0 : }
1070 : }
1071 : }
1072 :
1073 : //--------------------------------------------------------------------
1074 :
1075 0 : void SfxShell::VerbState(SfxItemSet& )
1076 : {
1077 0 : }
1078 :
1079 : //--------------------------------------------------------------------
1080 :
1081 0 : const SfxSlot* SfxShell::GetVerbSlot_Impl(sal_uInt16 nId) const
1082 : {
1083 0 : com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > rList = pImp->aVerbList;
1084 :
1085 : DBG_ASSERT(nId >= SID_VERB_START && nId <= SID_VERB_END,"Wrong VerbId!");
1086 0 : sal_uInt16 nIndex = nId - SID_VERB_START;
1087 : DBG_ASSERT(nIndex < rList.getLength(),"Wrong VerbId!");
1088 :
1089 0 : if (nIndex < rList.getLength())
1090 0 : return pImp->aSlotArr[nIndex];
1091 : else
1092 0 : return 0;
1093 : }
1094 :
1095 : //--------------------------------------------------------------------
1096 :
1097 698 : void SfxShell::SetHelpId(sal_uIntPtr nId)
1098 : {
1099 698 : pImp->nHelpId = nId;
1100 698 : }
1101 :
1102 : //--------------------------------------------------------------------
1103 :
1104 7 : sal_uIntPtr SfxShell::GetHelpId() const
1105 : {
1106 7 : return pImp->nHelpId;
1107 : }
1108 :
1109 : //--------------------------------------------------------------------
1110 :
1111 124 : SfxObjectShell* SfxShell::GetObjectShell()
1112 : {
1113 124 : if ( GetViewShell() )
1114 124 : return GetViewShell()->GetViewFrame()->GetObjectShell();
1115 : else
1116 0 : return NULL;
1117 : }
1118 :
1119 : //--------------------------------------------------------------------
1120 :
1121 0 : sal_Bool SfxShell::HasUIFeature( sal_uInt32 )
1122 : {
1123 0 : return sal_False;
1124 : }
1125 :
1126 122 : long DispatcherUpdate_Impl( void*, void* pArg )
1127 : {
1128 122 : ((SfxDispatcher*) pArg)->Update_Impl( sal_True );
1129 122 : ((SfxDispatcher*) pArg)->GetBindings()->InvalidateAll(sal_False);
1130 122 : return 0;
1131 : }
1132 :
1133 236 : void SfxShell::UIFeatureChanged()
1134 : {
1135 236 : SfxViewFrame *pFrame = GetFrame();
1136 236 : if ( pFrame && pFrame->IsVisible() )
1137 : {
1138 : // Also force an update, if dispatcher is already updated otherwise
1139 : // something my get stuck in the bunkered tools. Asynchronous call to
1140 : // prevent recursion.
1141 234 : if ( !pImp->pUpdater )
1142 234 : pImp->pUpdater = new svtools::AsynchronLink( Link( this, DispatcherUpdate_Impl ) );
1143 :
1144 : // Multiple views allowed
1145 234 : pImp->pUpdater->Call( pFrame->GetDispatcher(), sal_True );
1146 : }
1147 236 : }
1148 :
1149 3427 : void SfxShell::SetDisableFlags( sal_uIntPtr nFlags )
1150 : {
1151 3427 : pImp->nDisableFlags = nFlags;
1152 3427 : }
1153 :
1154 1635 : sal_uIntPtr SfxShell::GetDisableFlags() const
1155 : {
1156 1635 : return pImp->nDisableFlags;
1157 : }
1158 :
1159 0 : SfxItemSet* SfxShell::CreateItemSet( sal_uInt16 )
1160 : {
1161 0 : return NULL;
1162 : }
1163 :
1164 0 : void SfxShell::ApplyItemSet( sal_uInt16, const SfxItemSet& )
1165 : {
1166 0 : }
1167 :
1168 303 : void SfxShell::SetViewShell_Impl( SfxViewShell* pView )
1169 : {
1170 303 : pImp->pViewSh = pView;
1171 303 : }
1172 :
1173 :
1174 :
1175 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|