xref: /aoo41x/main/sfx2/source/control/shell.cxx (revision d119d52d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sfx2.hxx"
26 #include <com/sun/star/embed/VerbDescriptor.hpp>
27 #include <com/sun/star/embed/VerbAttributes.hpp>
28 #include <basic/sbstar.hxx>
29 #include <svl/itempool.hxx>
30 #include <svl/undo.hxx>
31 #include <svtools/itemdel.hxx>
32 #include <svtools/asynclink.hxx>
33 #include <basic/sbx.hxx>
34 
35 #include <unotools/undoopt.hxx>
36 
37 #ifndef GCC
38 #endif
39 
40 #include <sfx2/app.hxx>
41 #include <sfx2/shell.hxx>
42 #include <sfx2/bindings.hxx>
43 #include <sfx2/dispatch.hxx>
44 #include <sfx2/viewfrm.hxx>
45 #include <sfx2/objface.hxx>
46 #include <sfx2/objsh.hxx>
47 #include <sfx2/viewsh.hxx>
48 #include <sfx2/dispatch.hxx>
49 #include "sfxtypes.hxx"
50 #include <sfx2/request.hxx>
51 #include <sfx2/mnumgr.hxx>
52 #include "statcach.hxx"
53 #include <sfx2/msgpool.hxx>
54 
55 //====================================================================
56 
57 DBG_NAME(SfxShell)
58 
59 //====================================================================
60 
61 TYPEINIT0(SfxShell);
62 
63 //====================================================================
64 typedef SfxSlot* SfxSlotPtr;
65 SV_DECL_PTRARR_DEL( SfxVerbSlotArr_Impl, SfxSlotPtr, 4, 4)
66 SV_IMPL_PTRARR( SfxVerbSlotArr_Impl, SfxSlotPtr);
67 
68 using namespace com::sun::star;
69 
70 //=========================================================================
71 // SfxShell_Impl
72 //=========================================================================
73 struct SfxShell_Impl: public SfxBroadcaster
74 {
75 	String                      aObjectName;// Name des Sbx-Objects
76 	SfxItemArray_Impl           aItems;     // Datenaustausch auf Item-Basis
77     SfxViewShell*               pViewSh;    // SfxViewShell falls Shell ViewFrame/ViewShell/SubShell ist
78 	SfxViewFrame*               pFrame;     // Frame, falls <UI-aktiv>
79 	SfxRepeatTarget*            pRepeatTarget;
80 //    SbxObjectRef                xParent;
81 	sal_Bool						bInAppBASIC;
82 	sal_Bool                        bActive;
83 	sal_uIntPtr						nDisableFlags;
84 	sal_uIntPtr                       nHelpId;
85     svtools::AsynchronLink*     pExecuter;
86     svtools::AsynchronLink*     pUpdater;
87     SfxVerbSlotArr_Impl         aSlotArr;
88     com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > aVerbList;
89 	SfxShell_Impl()  : pExecuter( 0 ), pUpdater( 0 ) {}
90 	~SfxShell_Impl() { delete pExecuter; delete pUpdater;}
91 };
92 
93 //====================================================================
94 #ifdef DBG_UTIL
95 
96 String SfxShellIdent_Impl( const SfxShell *pSh )
97 
98 /*  [Beschreibung]
99 
100 	Interne Hilfesfunktion. Liefert einen die SfxShell 'pSh' beschreibenden
101 	String zur"uck. Z.B.: SfxApplication[StarWriter]
102 */
103 
104 {
105 	String aIdent( pSh->ISA(SfxApplication) ? DEFINE_CONST_UNICODE("SfxApplication") :
106 				   pSh->ISA(SfxViewFrame) ? DEFINE_CONST_UNICODE("SfxViewFrame") :
107 				   pSh->ISA(SfxViewShell) ? DEFINE_CONST_UNICODE("SfxViewShell") :
108 				   pSh->ISA(SfxObjectShell) ? DEFINE_CONST_UNICODE("SfxObjectShell") : DEFINE_CONST_UNICODE("SfxShell") );
109 	aIdent += '[';
110 	aIdent += pSh->GetName();
111 	aIdent += ']';
112 	return aIdent;
113 }
114 
115 #endif
116 //====================================================================
117 
118 //=========================================================================
119 // SfxShell
120 //=========================================================================
121 
122 void __EXPORT SfxShell::EmptyExecStub(SfxShell *, SfxRequest &)
123 {
124 }
125 
126 void __EXPORT SfxShell::EmptyStateStub(SfxShell *, SfxItemSet &)
127 {
128 }
129 
130 SfxShell::SfxShell()
131 
132 /*  [Beschreibung]
133 
134 	Der Konstruktor der Klasse SfxShell initialisierung nur einfache
135 	Typen, das dazugeh"orige SbxObject wird erst on-demand erzeugt.
136 	Daher ist das Anlegen einer SfxShell Instanz sehr billig.
137 */
138 
139 :	pImp(0),
140     pPool(0),
141 	pUndoMgr(0)
142 {
143 	DBG_CTOR(SfxShell, 0);
144 	pImp = new SfxShell_Impl;
145 	pImp->pViewSh = 0;
146 	pImp->pFrame = 0;
147 	pImp->pRepeatTarget = 0;
148 	pImp->bInAppBASIC = sal_False;
149 	pImp->nHelpId = 0L;
150 	pImp->bActive = sal_False;
151 	pImp->nDisableFlags = 0;
152 }
153 
154 //-------------------------------------------------------------------------
155 
156 SfxShell::SfxShell( SfxViewShell *pViewSh )
157 
158 /*  [Beschreibung]
159 
160 	Der Konstruktor der Klasse SfxShell initialisierung nur einfache
161 	Typen, das dazugeh"orige SbxObject wird erst on-demand erzeugt.
162 	Daher ist das Anlegen einer SfxShell Instanz sehr billig.
163 */
164 
165 :	pImp(0),
166     pPool(0),
167 	pUndoMgr(0)
168 {
169 	DBG_CTOR(SfxShell, 0);
170 	pImp = new SfxShell_Impl;
171 	pImp->pViewSh = pViewSh;
172 	pImp->pFrame = 0;
173 	pImp->pRepeatTarget = 0;
174 	pImp->bInAppBASIC = sal_False;
175 	pImp->nHelpId = 0L;
176 	pImp->bActive = sal_False;
177 }
178 
179 //--------------------------------------------------------------------
180 
181 SfxShell::~SfxShell()
182 
183 /*  [Beschreibung]
184 
185 	Die Verbindungs zu einem ggf. zugeh"origen SbxObject wird gel"ost.
186 	Das SbxObject existiert ggf. weiter, kann aber keine Funktionen
187 	mehr ausf"uhren und keine Properties mehr bereitstellen.
188 */
189 
190 {
191 	DBG_DTOR(SfxShell, 0);
192 	delete pImp;
193 }
194 
195 //--------------------------------------------------------------------
196 
197 void SfxShell::SetName( const String &rName )
198 
199 /*  [Beschreibung]
200 
201 	Setzt den Namen des Shell-Objekts. Mit diesem Namen kann die
202 	SfxShell-Instanz vom BASIC aus angesprochen werden.
203 */
204 
205 {
206 	pImp->aObjectName = rName;
207 }
208 
209 //--------------------------------------------------------------------
210 
211 const String& SfxShell::GetName() const
212 
213 /*  [Beschreibung]
214 
215 	Liefert den Namen des Shell-Objekts. Mit diesem Namen kann die
216 	SfxShell-Instanz vom BASIC aus angesprochen werden.
217 */
218 
219 {
220 	return pImp->aObjectName;
221 }
222 
223 //--------------------------------------------------------------------
224 
225 SvGlobalName SfxShell::GetGlobalName() const
226 
227 /*  [Beschreibung]
228 
229 	Liefert den Global Unique Identifier des Shell-Objekts. Mit diesem
230 	Namen kann die SfxShell-Instanz z.B. via OLE Automation angesprochen
231 	werden, bzw. in der Registration-Database gefunden werden.
232 */
233 
234 {
235 	return SvGlobalName();
236 }
237 
238 //--------------------------------------------------------------------
239 
240 SfxDispatcher* SfxShell::GetDispatcher() const
241 
242 /*  [Beschreibung]
243 
244 	Diese Methode liefert einen Pointer auf den <SfxDispatcher>, in
245 	dem die SfxShell gerade <UI-aktiv> ist bzw. einen 0-Pointer, wenn
246 	sie gerade nicht UI-aktiv ist.
247 
248 	Der zur"uckgegebene Pointer ist nur im unmittelbaren Kontext des
249 	Methodenaufrufs g"ultig.
250 */
251 
252 {
253 	return pImp->pFrame ? pImp->pFrame->GetDispatcher() : 0;
254 }
255 
256 //--------------------------------------------------------------------
257 
258 SfxViewShell* SfxShell::GetViewShell() const
259 
260 /*  [Beschreibung]
261 
262 	Liefert bei SubShells die SfxViewShell, in der sie liegen. Sonst und
263 	falls nicht vom App-Entwickler angegeben liefert diese Methode 0.
264 */
265 
266 {
267 	return pImp->pViewSh;
268 }
269 
270 //--------------------------------------------------------------------
271 
272 SfxViewFrame* SfxShell::GetFrame() const
273 
274 /*  [Beschreibung]
275 
276 	Diese Methode liefert einen Pointer auf den <SfxViewFrame>, dem diese
277 	SfxShell-Instanz zugeordnet ist oder in dem sie zur Zeit <UI-aktiv> ist.
278 	Ein 0-Pointer wird geliefert, wenn diese SfxShell-OInstanz gerade nicht
279 	UI-aktiv ist und auch keinem SfxViewFrame fest zugeordnet ist.
280 
281 	Der zur"uckgegebene Pointer ist nur im unmittelbaren Kontext des
282 	Methodenaufrufs g"ultig.
283 
284 
285 	[Anmerkung]
286 
287 	Nur Instanzen von Subklasse von SfxApplication und SfxObjectShell sollten
288 	hier einen 0-Pointer liefern. Ansonsten liegt ein Fehler im Anwendungs-
289 	programm vor (falscher Ctor von SfxShell gerufen).
290 
291 
292 	[Querverweise]
293 
294 	<SfxViewShell::GetViewFrame()const>
295 */
296 
297 {
298 	if ( pImp->pFrame )
299 		return pImp->pFrame;
300 	if ( pImp->pViewSh )
301 		return pImp->pViewSh->GetViewFrame();
302 	return 0;
303 }
304 
305 //--------------------------------------------------------------------
306 
307 const SfxPoolItem* SfxShell::GetItem
308 (
309 	sal_uInt16  nSlotId         // Slot-Id des zu erfragenden <SfxPoolItem>s
310 )   const
311 
312 /*  [Beschreibung]
313 
314 	Mit dieser Methode kann auf beliebige Objekte von Subklassen von
315 	<SfxPoolItem> zugegriffen werden. Diese Austauschtechnik wird ben"otigt,
316 	wenn z.B. spezielle <SfxToolBoxControl> Subklassen Zugriff auf
317 	bestimmte Daten z.B. der <SfxObjectShell> ben"otigen.
318 
319 	Die zur"uckgelieferte Instanz geh"ort der jeweilige SfxShell und
320 	darf nur im unmittelbaren Kontext des Methodenaufrufs verwendet werden.
321 
322 
323 	[Querverweise]
324 
325 	<SfxShell::PutItem(const SfxPoolItem&)>
326 	<SfxShell::RemoveItem(sal_uInt16)>
327 */
328 
329 {
330 	for ( sal_uInt16 nPos = 0; nPos < pImp->aItems.Count(); ++nPos )
331 		if ( pImp->aItems.GetObject(nPos)->Which() == nSlotId )
332 			return pImp->aItems.GetObject(nPos);
333 	return 0;
334 }
335 
336 //--------------------------------------------------------------------
337 
338 void SfxShell::RemoveItem
339 (
340 	sal_uInt16  nSlotId         // Slot-Id des zu l"oschenden <SfxPoolItem>s
341 )
342 
343 /*  [Beschreibung]
344 
345 	Mit dieser Methode k"onnen die allgemein zur Verf"ugung gestellten
346 	Instanzen von Subklassen von <SfxPoolItem> aus der SfxShell entfernt
347 	werden.
348 
349 	Die gespeicherte Instanz wird gel"oscht.
350 
351 
352 	[Querverweise]
353 
354 	<SfxShell::PutItem(const SfxPoolItem&)>
355 	<SfxShell::GetItem(sal_uInt16)>
356 */
357 
358 {
359 	for ( sal_uInt16 nPos = 0; nPos < pImp->aItems.Count(); ++nPos )
360 		if ( pImp->aItems.GetObject(nPos)->Which() == nSlotId )
361 		{
362 			// Item entfernen und l"oschen
363 			SfxPoolItem *pItem = pImp->aItems.GetObject(nPos);
364 			delete pItem;
365 			pImp->aItems.Remove(nPos);
366 
367 			// falls aktiv Bindings benachrichtigen
368 			SfxDispatcher *pDispat = GetDispatcher();
369 			if ( pDispat )
370 			{
371 				SfxVoidItem aVoid( nSlotId );
372 				pDispat->GetBindings()->Broadcast( SfxPoolItemHint( &aVoid ) );
373 			}
374 		}
375 }
376 
377 //--------------------------------------------------------------------
378 
379 void SfxShell::PutItem
380 (
381 	const SfxPoolItem&  rItem   /*  Instanz, von der eine Kopie erstellt wird,
382 									die in der SfxShell in einer Liste
383 									gespeichert wird. */
384 )
385 
386 /*  [Beschreibung]
387 
388 	Mit dieser Methode k"onnen beliebige Objekte von Subklassen von
389 	<SfxPoolItem> zur Verf"ugung gestellt werden. Diese Austauschtechnik
390 	wird ben"otigt, wenn z.B. spezielle <SfxToolBoxControl> Subklassen
391 	Zugriff auf bestimmte Daten z.B. der <SfxObjectShell> ben"otigen.
392 
393 	Falls ein SfxPoolItem mit derselben Slot-Id exisitert, wird dieses
394 	automatisch gel"oscht.
395 
396 
397 	[Querverweise]
398 
399 	<SfxShell::RemoveItem(sal_uInt16)>
400 	<SfxShell::GetItem(sal_uInt16)>
401 */
402 
403 {
404 	DBG_ASSERT( !rItem.ISA(SfxSetItem), "SetItems aren't allowed here" );
405 	DBG_ASSERT( SfxItemPool::IsSlot( rItem.Which() ),
406 				"items with Which-Ids aren't allowed here" );
407 
408 	// MSC auf WNT/W95 machte hier Mist, Vorsicht bei Umstellungen
409 	const SfxPoolItem *pItem = rItem.Clone();
410 	SfxPoolItemHint aItemHint( (SfxPoolItem*) pItem );
411 	const sal_uInt16 nWhich = rItem.Which();
412 	SfxPoolItem **ppLoopItem = (SfxPoolItem**) pImp->aItems.GetData();
413 	sal_uInt16 nPos;
414 	for ( nPos = 0; nPos < pImp->aItems.Count(); ++nPos, ++ppLoopItem )
415 	{
416 		if ( (*ppLoopItem)->Which() == nWhich )
417 		{
418 			// Item austauschen
419 			delete *ppLoopItem;
420 			pImp->aItems.Remove(nPos);
421 			pImp->aItems.Insert( (SfxPoolItemPtr) pItem, nPos );
422 
423 			// falls aktiv Bindings benachrichtigen
424 			SfxDispatcher *pDispat = GetDispatcher();
425 			if ( pDispat )
426             {
427                 SfxBindings* pBindings = pDispat->GetBindings();
428                 pBindings->Broadcast( aItemHint );
429                 sal_uInt16 nSlotId = nWhich; //pItem->GetSlotId();
430                 SfxStateCache* pCache = pBindings->GetStateCache( nSlotId );
431                 if ( pCache )
432                 {
433                     pCache->SetState( SFX_ITEM_AVAILABLE, pItem->Clone(), sal_True );
434                     pCache->SetCachedState( sal_True );
435                 }
436             }
437             return;
438 		}
439 	}
440 
441 	Broadcast( aItemHint );
442 	pImp->aItems.Insert((SfxPoolItemPtr)pItem, nPos );
443 }
444 
445 //--------------------------------------------------------------------
446 
447 SfxInterface* SfxShell::GetInterface() const
448 
449 /*  [Beschreibung]
450 
451 	Mit dieser virtuellen Methode, die durch das Makro <SFX_DECL_INTERFACE>
452 	von jeder Subclass mit eigenen Slots automatisch "uberladen wird, kann
453 	auf die zu der Subklasse geh"orende <SfxInterface>-Instanz zugegriffen
454 	werden.
455 
456 	Die Klasse SfxShell selbst hat noch kein eigenes SfxInterface
457 	(keine Slots), daher wird ein 0-Pointer zur"uckgeliefert.
458 */
459 
460 {
461     return GetStaticInterface();
462 }
463 
464 //--------------------------------------------------------------------
465 
466 SfxBroadcaster* SfxShell::GetBroadcaster()
467 
468 /*	[Beschreibung]
469 
470 	Liefert einen SfxBroadcaster f"ur diese SfxShell-Instanz bis die
471 	Klasse SfxShell von SfxBroadcaster abgeleitet ist.
472 */
473 
474 {
475 	return pImp;
476 }
477 
478 //--------------------------------------------------------------------
479 
480 ::svl::IUndoManager* SfxShell::GetUndoManager()
481 
482 /*  [Beschreibung]
483 
484 	Jede Subclass von SfxShell kann "uber einen <SfxUndoManager> verf"ugen.
485 	Dieser kann in den abgeleiteten Klasse mit <SfxShell:SetUndoManager()>
486 	gesetzt werden.
487 
488 	Die Klasse SfxShell selbst hat noch keinen SfxUndoManager, es wird
489 	daher ein 0-Pointer zur"uckgeliefert.
490 */
491 
492 {
493 	return pUndoMgr;
494 }
495 
496 //--------------------------------------------------------------------
497 
498 void SfxShell::SetUndoManager( ::svl::IUndoManager *pNewUndoMgr )
499 
500 /*  [Beschreibung]
501 
502 	Setzt einen <SfxUndoManager> f"ur diese <SfxShell> Instanz. F"ur das
503 	Undo wird immer nur der Undo-Manager an der jeweils oben auf dem
504 	Stack des <SfxDispatcher> liegenden SfxShell verwendet.
505 
506 	Am "ubergebenen <SfxUndoManager> wird automatisch die aktuelle
507 	Max-Undo-Action-Count Einstellung aus den Optionen gesetzt.
508 
509 	'pNewUndoMgr' mu\s bis zum Dtor dieser SfxShell-Instanz oder bis
510 	zum n"achsten 'SetUndoManager()' existieren.
511 */
512 
513 {
514     OSL_ENSURE( ( pUndoMgr == NULL ) || ( pNewUndoMgr == NULL ) || ( pUndoMgr == pNewUndoMgr ),
515         "SfxShell::SetUndoManager: exchanging one non-NULL manager with another non-NULL manager? Suspicious!" );
516     // there's at least one client of our UndoManager - the DocumentUndoManager at the SfxBaseModel - which
517     // caches the UndoManager, and registers itself as listener. If exchanging non-NULL UndoManagers is really
518     // a supported scenario (/me thinks it is not), then we would need to notify all such clients instances.
519 
520 	pUndoMgr = pNewUndoMgr;
521 	if ( pUndoMgr )
522         pUndoMgr->SetMaxUndoActionCount( (sal_uInt16) SvtUndoOptions().GetUndoCount() );
523 }
524 
525 //--------------------------------------------------------------------
526 
527 SfxRepeatTarget* SfxShell::GetRepeatTarget() const
528 
529 /*  [Beschreibung]
530 
531 	Liefert einen Pointer auf die <SfxRepeatTarget>-Instanz, die
532 	als RepeatTarget bei SID_REPEAT verwendet wird, wenn der
533 	von dieser SfxShell gelieferte <SfxUndoManager> angesprochen wird.
534 	Der R"uckgabewert kann 0 sein.
535 
536 
537 	[Anmerkung]
538 
539 	Eine Ableitung von <SfxShell> oder einer ihrer Subklassen von
540 	<SfxRepeatTarget> ist nicht zu empfehlen, da Compiler-Fehler
541 	provoziert werden (wegen Call-to-Pointer-to-Member-Function to
542 	subclass).
543 */
544 
545 {
546 	return pImp->pRepeatTarget;
547 }
548 
549 //--------------------------------------------------------------------
550 
551 void SfxShell::SetRepeatTarget( SfxRepeatTarget *pTarget )
552 
553 /*  [Beschreibung]
554 
555 	Setzt den die <SfxRepeatTarget>-Instanz, die bei SID_REPEAT als
556 	RepeatTarget verwendet wird, wenn der von dieser SfxShell gelieferte
557 	<SfxUndoManager> angesprochen wird. Durch 'pTarget==0' wird SID_REPEAT
558 	f"ur diese SfxShell disabled. Die Instanz '*pTarget' mu\s so lange
559 	leben, wie sie angemeldet ist.
560 
561 
562 	[Anmerkung]
563 
564 	Eine Ableitung von <SfxShell> oder einer ihrer Subklassen von
565 	<SfxRepeatTarget> ist nicht zu empfehlen, da Compiler-Fehler
566 	provoziert werden (wegen Call-to-Pointer-to-Member-Function to
567 	subclass).
568 */
569 
570 {
571 	pImp->pRepeatTarget = pTarget;
572 }
573 
574 //--------------------------------------------------------------------
575 
576 void SfxShell::Invalidate
577 (
578 	sal_uInt16          nId     /* Zu invalidierende Slot-Id oder Which-Id.
579 							   Falls diese 0 ist (default), werden
580 							   alle z.Zt. von dieser Shell bedienten
581 							   Slot-Ids invalidiert. */
582 )
583 
584 /*  [Beschreibung]
585 
586 	Mit dieser Methode k"onnen Slots der Subclasses "uber die Slot-Id
587 	oder alternativ "uber die Which-Id invalidiert werden. Slot-Ids,
588 	die von der Subclass ererbt sind, werden ebenfalls invalidert.
589 
590 	[Querverweise]
591 	<SfxBindings::Invalidate(sal_uInt16)>
592 	<SfxBindings::InvalidateAll(sal_Bool)>
593 */
594 
595 {
596     if ( !GetViewShell() )
597     {
598         DBG_ERROR( "wrong Invalidate method called!" );
599         return;
600     }
601 
602     Invalidate_Impl( GetViewShell()->GetViewFrame()->GetBindings(), nId );
603 }
604 
605 void SfxShell::Invalidate_Impl( SfxBindings& rBindings, sal_uInt16 nId )
606 {
607 	if ( nId == 0 )
608     {
609         rBindings.InvalidateShell( *this, sal_False );
610     }
611 	else
612 	{
613 		const SfxInterface *pIF = GetInterface();
614 		do
615 		{
616 			const SfxSlot *pSlot = pIF->GetSlot(nId);
617 			if ( pSlot )
618 			{
619 				// bei Enum-Slots ist der Master-Slot zu invalidieren
620 				if ( SFX_KIND_ENUM == pSlot->GetKind() )
621 					pSlot = pSlot->GetLinkedSlot();
622 
623 				// den Slot selbst und ggf. auch alle Slave-Slots invalidieren
624 				rBindings.Invalidate( pSlot->GetSlotId() );
625 				for ( const SfxSlot *pSlave = pSlot->GetLinkedSlot();
626 					  pSlave && pIF->ContainsSlot_Impl( pSlave ) &&
627 						pSlave->GetLinkedSlot() == pSlot;
628 					  ++pSlave )
629 					rBindings.Invalidate( pSlave->GetSlotId() );
630 
631 				return;
632 			}
633 
634 			pIF = pIF->GetGenoType();
635 		}
636 
637 		while ( pIF );
638 
639 		DBG_WARNING( "W3: invalidating slot-id unknown in shell" );
640 	}
641 }
642 
643 //--------------------------------------------------------------------
644 
645 void SfxShell::DoActivate_Impl( SfxViewFrame *pFrame, sal_Bool bMDI )
646 
647 /*  [Beschreibung]
648 
649 	Diese Methode steuert die Aktivierung der SfxShell-Instanz. Zun"achst
650 	wird durch Aufruf der virtuellen Methode <SfxShell::Activate(sal_Bool)>
651 	der Subclass die M"oglichkeit gegeben, auf das Event zu reagieren.
652 
653 	Bei bMDI == TRUE wird das zugeh"orige SbxObject 'scharfgeschaltet',
654 	so da\s Methoden des Objekts unqualifiziert (ohne den Namen des Objekts)
655 	vom BASIC gefunden werden.
656 */
657 
658 {
659 #ifdef DBG_UTIL
660 	const SfxInterface *p_IF = GetInterface();
661 	if ( !p_IF )
662 		return;
663 #endif
664 #ifdef DBG_UTIL_VB
665 		String aMsg("SfxShell::DoActivate() ");
666 		aMsg += (long)this;
667 		aMsg += "  ";
668 		aMsg += GetInterface()->GetName();
669 		aMsg += " bMDI ";
670 		if ( bMDI ) aMsg += "MDI";
671 		DbgTrace( aMsg.GetBuffer() );
672 #endif
673 
674 	if ( bMDI )
675 	{
676 		// Frame merken, in dem aktiviert wird
677 		pImp->pFrame = pFrame;
678 		pImp->bActive = sal_True;
679 	}
680 
681 	// Subklasse benachrichtigen
682 	Activate(bMDI);
683 }
684 
685 //--------------------------------------------------------------------
686 
687 void SfxShell::DoDeactivate_Impl( SfxViewFrame *pFrame, sal_Bool bMDI )
688 
689 /*  [Beschreibung]
690 
691 	Diese Methode steuert die Deaktivierung der SfxShell-Instanz. Bei
692 	bMDI == TRUE wird zun"achst das SbxObject in einen Status versetzt,
693 	so da\s Methoden vom BASIC aus nur noch qualifiziert gerufen werden
694 	k"onnen.
695 
696 	Dann erh"alt in jedem Fall die Subclass durch Aufruf der virtuellen
697 	Methode <SfxShell::Deactivate(sal_Bool)> die M"oglichkeit auf das Event
698 	zu reagieren.
699 */
700 
701 {
702 #ifdef DBG_UTIL
703 	const SfxInterface *p_IF = GetInterface();
704 	if ( !p_IF )
705 		return;
706 #endif
707 #ifdef DBG_UTIL_VB
708 		String aMsg("SfxShell::DoDeactivate()");
709 		aMsg += (long)this;
710 		aMsg += "  ";
711 		aMsg += GetInterface()->GetName();
712 		aMsg += " bMDI ";
713 		if ( bMDI ) aMsg += "MDI";
714 		DbgTrace( aMsg.GetBuffer() );
715 #endif
716 
717 	// nur wenn er vom Frame kommt (nicht z.B. pop der BASIC-IDE vom AppDisp)
718 	if ( bMDI && pImp->pFrame == pFrame )
719 	{
720 		// austragen
721 		pImp->pFrame = 0;
722 		pImp->bActive = sal_False;
723 	}
724 
725 	// Subklasse benachrichtigen
726 	Deactivate(bMDI);
727 }
728 
729 //--------------------------------------------------------------------
730 
731 sal_Bool SfxShell::IsActive() const
732 {
733 	return pImp->bActive;
734 }
735 
736 //--------------------------------------------------------------------
737 
738 void SfxShell::Activate
739 (
740 	sal_Bool    /*bMDI*/        /*  TRUE
741 							der <SfxDispatcher>, auf dem die SfxShell sich
742 							befindet, ist aktiv geworden oder die SfxShell
743 							Instanz wurde auf einen aktiven SfxDispatcher
744 							gepusht. (vergl. SystemWindow::IsMDIActivate())
745 
746 							FALSE
747 							das zum <SfxViewFrame>, auf dessen SfxDispatcher
748 							sich die SfxShell Instanz befindet, wurde
749 							aktiviert.
750 							(z.B. durch einen geschlossenen Dialog) */
751 )
752 
753 /*  [Beschreibung]
754 
755 	Virtuelle Methode, die beim Aktivieren der SfxShell Instanz gerufen
756 	wird, um den Subclasses die Gelegenheit zu geben, auf das Aktivieren
757 	zu reagieren.
758 
759 	Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
760 
761 
762 	[Querverweise]
763 	StarView SystemWindow::Activate(sal_Bool)
764 */
765 
766 {
767 }
768 
769 //--------------------------------------------------------------------
770 
771 void SfxShell::Deactivate
772 (
773 	sal_Bool    /*bMDI*/        /*  TRUE
774 							der <SfxDispatcher>, auf dem die SfxShell sich
775 							befindet, ist inaktiv geworden oder die SfxShell
776 							Instanz wurde auf einen aktiven SfxDispatcher
777 							gepoppt. (vergl. SystemWindow::IsMDIActivate())
778 
779 							FALSE
780 							das zum <SfxViewFrame>, auf dessen SfxDispatcher
781 							sich die SfxShell Instanz befindet, wurde
782 							deaktiviert. (z.B. durch einen Dialog) */
783 
784 )
785 
786 /*  [Beschreibung]
787 
788 	Virtuelle Methode, die beim Deaktivieren der SfxShell Instanz gerufen
789 	wird, um den Subclasses die Gelegenheit zu geben, auf das Deaktivieren
790 	zu reagieren.
791 
792 	Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
793 
794 
795 	[Querverweise]
796 	StarView SystemWindow::Dectivate(sal_Bool)
797 */
798 
799 {
800 }
801 
802 void SfxShell::ParentActivate
803 (
804 )
805 
806 /*  [Beschreibung]
807 
808 	Ein Parent des <SfxDispatcher>, auf dem die SfxShell sich befindet,
809 	ist aktiv geworden, oder die SfxShell Instanz wurde auf einen
810 	<SfxDispatcher> gepusht, dessen parent aktiv ist.
811 
812 	Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
813 
814 	[Querverweise]
815 	SfxShell::Activate()
816 */
817 {
818 }
819 
820 //--------------------------------------------------------------------
821 
822 void SfxShell::ParentDeactivate
823 (
824 )
825 
826 /*  [Beschreibung]
827 
828 	Der aktive Parent des <SfxDispatcher>, auf dem die SfxShell sich befindet,
829 	ist deaktiviert worden.
830 
831 	Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
832 
833 	[Querverweise]
834 	SfxShell::Deactivate()
835 */
836 {
837 }
838 
839 //--------------------------------------------------------------------
840 
841 ResMgr* SfxShell::GetResMgr() const
842 
843 /*  [Beschreibung]
844 
845 	Diese Methode liefert den ResMgr der <Resource-DLL>, die von der
846 	SfxShell-Instanz verwendet wird. Ist dies ein 0-Pointer, so
847 	ist der aktuelle Resource-Manager zu verwenden.
848 */
849 
850 {
851 	return GetInterface()->GetResMgr();
852 }
853 
854 //--------------------------------------------------------------------
855 
856 bool SfxShell::CanExecuteSlot_Impl( const SfxSlot &rSlot )
857 
858 /*  [Beschreibung]
859 
860 	Diese Methode stellt durch Aufruf der Statusfunktion fest,
861 	ob 'rSlot' aktuell ausgef"uhrt werden kann.
862 */
863 {
864 	// Slot-Status holen
865 	SfxItemPool &rPool = GetPool();
866 	const sal_uInt16 nId = rSlot.GetWhich( rPool );
867 	SfxItemSet aSet(rPool, nId, nId);
868 	SfxStateFunc pFunc = rSlot.GetStateFnc();
869 	CallState( pFunc, aSet );
870 	return aSet.GetItemState(nId) != SFX_ITEM_DISABLED;
871 }
872 
873 //--------------------------------------------------------------------
874 
875 long ShellCall_Impl( void* pObj, void* pArg )
876 {
877 	((SfxShell* )pObj)->ExecuteSlot( *(SfxRequest*)pArg, (SfxInterface*)0L );
878 	return 0;
879 }
880 
881 /*  [Beschreibung]
882 	Asynchrones ExecuteSlot fuer das RELOAD
883  */
884 
885 //--------------------------------------------------------------------
886 const SfxPoolItem* SfxShell::ExecuteSlot( SfxRequest& rReq, sal_Bool bAsync )
887 {
888 	if( !bAsync )
889 		return ExecuteSlot( rReq, (SfxInterface*)0L );
890 	else
891 	{
892 		if( !pImp->pExecuter )
893             pImp->pExecuter = new svtools::AsynchronLink(
894 				Link( this, ShellCall_Impl ) );
895 		pImp->pExecuter->Call( new SfxRequest( rReq ) );
896 		return 0;
897 	}
898 }
899 
900 const SfxPoolItem* SfxShell::ExecuteSlot
901 (
902 	SfxRequest &rReq,			// der weiterzuleitende <SfxRequest>
903 	const SfxInterface* pIF     // default = 0 bedeutet virtuell besorgen
904 )
905 
906 /*  [Beschreibung]
907 
908 	Diese Methode erm"oglicht das Weiterleiten eines <SfxRequest> an
909 	die angegebene Basis-<SfxShell>.
910 
911 
912 	[Beispiel]
913 
914 	In einer von SfxViewShell abgeleiteten Klasse soll SID_PRINTDOCDIRECT
915 	abgefangen werden. Unter bestimmten Umst"anden soll vor dem Drucken
916 	eine Abfrage erscheinen, und der Request soll ggf. abgebrochen werden.
917 
918 	Dazu ist in der IDL dieser Subklasse der o.g. Slot einzutragen. Die
919 	Execute-Methode enth"alt dann skizziert:
920 
921 	void SubViewShell::Exec( SfxRequest &rReq )
922 	{
923 		if ( rReq.GetSlot() == SID_PRINTDOCDIRECT )
924 		{
925 			'dialog'
926 			if ( 'condition' )
927 				ExecuteSlot( rReq, SfxViewShell::GetInterface() );
928 		}
929 	}
930 
931 	Es braucht i.d.R. kein rReq.Done() gerufen zu werden, da das bereits
932 	die Implementierung der SfxViewShell erledigt bzw. abgebrochen wurde.
933 
934 
935 	[Querverweise]
936 
937 	<SfxShell::GetSlotState(sal_uInt16,const SfxInterface*,SfxItemSet*)>
938 */
939 
940 {
941 	if ( !pIF )
942 		pIF = GetInterface();
943 
944     sal_uInt16 nSlot = rReq.GetSlot();
945     const SfxSlot* pSlot = NULL;
946     if ( nSlot >= SID_VERB_START && nSlot <= SID_VERB_END )
947         pSlot = GetVerbSlot_Impl(nSlot);
948     if ( !pSlot )
949         pSlot = pIF->GetSlot(nSlot);
950 	DBG_ASSERT( pSlot, "slot not supported" );
951 
952 	SfxExecFunc pFunc = pSlot->GetExecFnc();
953     if ( pFunc )
954         CallExec( pFunc, rReq );
955 
956 	return rReq.GetReturnValue();
957 }
958 
959 //--------------------------------------------------------------------
960 
961 const SfxPoolItem* SfxShell::GetSlotState
962 (
963 	sal_uInt16              nSlotId,    // Slot-Id des zu befragenden Slots
964 	const SfxInterface* pIF,        // default = 0 bedeutet virtuell besorgen
965 	SfxItemSet*         pStateSet   // SfxItemSet der Slot-State-Methode
966 )
967 
968 /*  [Beschreibung]
969 
970 	Diese Methode liefert den Status des Slots mit der angegebenen Slot-Id
971 	"uber das angegebene Interface.
972 
973 	Ist der Slot disabled oder in dieser SfxShell (und deren Parent-Shells)
974 	nicht bekannt, wird ein 0-Pointer zur"uckgeliefert.
975 
976 	Hat der Slot keinen Status, wird ein SfxVoidItem zur"uckgeliefert.
977 
978 	Der Status wird bei pStateSet != 0 gleich in diesem Set gesetzt, so
979 	da\s <SfxShell>-Subklassen Slots-"uberladen und auch bei der
980 	Status-Methode die Basis-Implementierung rufen k"onnen.
981 
982 
983 	[Beispiel]
984 
985 	In einer von SfxViewShell abgeleiteten Klasse soll SID_PRINTDOCDIRECT
986 	abgefangen werden. Unter bestimmten Umst"anden soll vor dem Drucken
987 	eine Abfrage erscheinen, und der Request soll ggf. abgebrochen werden.
988 
989 	Dazu ist in der IDL dieser Subklasse der o.g. Slot einzutragen. Die
990 	Status-Methode enth"alt dann skizziert:
991 
992 	void SubViewShell::PrintState( SfxItemSet &rState )
993 	{
994 		if ( rState.GetItemState( SID_PRINTDOCDIRECT ) != SFX_ITEM_UNKNOWN )
995 			GetSlotState( SID_PRINTDOCDIRECT, SfxViewShell::GetInterface(),
996 					&rState );
997 		...
998 	}
999 
1000 
1001 	[Querverweise]
1002 
1003 	<SfxShell::ExecuteSlot(SfxRequest&)>
1004 */
1005 
1006 {
1007 	// Slot am angegebenen Interface besorgen
1008 	if ( !pIF )
1009 		pIF = GetInterface();
1010 	SfxItemState eState;
1011 	SfxItemPool &rPool = GetPool();
1012 
1013     const SfxSlot* pSlot = NULL;
1014     if ( nSlotId >= SID_VERB_START && nSlotId <= SID_VERB_END )
1015         pSlot = GetVerbSlot_Impl(nSlotId);
1016     if ( !pSlot )
1017         pSlot = pIF->GetSlot(nSlotId);
1018 	if ( pSlot )
1019 		// ggf. auf Which-Id mappen
1020 		nSlotId = pSlot->GetWhich( rPool );
1021 
1022 	// Item und Item-Status besorgen
1023 	const SfxPoolItem *pItem = NULL;
1024 	SfxItemSet aSet( rPool, nSlotId, nSlotId ); // pItem stirbt sonst zu fr"uh
1025 	if ( pSlot )
1026 	{
1027 		// Status-Methode rufen
1028 		SfxStateFunc pFunc = pSlot->GetStateFnc();
1029         if ( pFunc )
1030             CallState( pFunc, aSet );
1031 		eState = aSet.GetItemState( nSlotId, sal_True, &pItem );
1032 
1033 		// ggf. Default-Item besorgen
1034 		if ( eState == SFX_ITEM_DEFAULT )
1035 		{
1036 			if ( SfxItemPool::IsWhich(nSlotId) )
1037 				pItem = &rPool.GetDefaultItem(nSlotId);
1038 			else
1039 				eState = SFX_ITEM_DONTCARE;
1040 		}
1041 	}
1042 	else
1043 		eState = SFX_ITEM_UNKNOWN;
1044 
1045 	// Item und Item-Status auswerten und ggf. in pStateSet mitpflegen
1046 	SfxPoolItem *pRetItem = 0;
1047 	if ( eState <= SFX_ITEM_DISABLED )
1048 	{
1049 		if ( pStateSet )
1050 			pStateSet->DisableItem(nSlotId);
1051 		return 0;
1052 	}
1053 	else if ( eState == SFX_ITEM_DONTCARE )
1054 	{
1055 		if ( pStateSet )
1056 			pStateSet->ClearItem(nSlotId);
1057 		pRetItem = new SfxVoidItem(0);
1058 	}
1059 	else
1060 	{
1061 		if ( pStateSet && pStateSet->Put( *pItem ) )
1062 			return &pStateSet->Get( pItem->Which() );
1063 		pRetItem = pItem->Clone();
1064 	}
1065 	DeleteItemOnIdle(pRetItem);
1066 
1067 	return pRetItem;
1068 }
1069 
1070 //--------------------------------------------------------------------
1071 
1072 SFX_EXEC_STUB(SfxShell, VerbExec)
1073 SFX_STATE_STUB(SfxShell, VerbState)
1074 
1075 void SfxShell::SetVerbs(const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& aVerbs)
1076 {
1077 	SfxViewShell *pViewSh = PTR_CAST ( SfxViewShell, this);
1078 
1079 	DBG_ASSERT(pViewSh, "SetVerbs nur an der ViewShell aufrufen!");
1080     if ( !pViewSh )
1081         return;
1082 
1083     // Zun"achst alle Statecaches dirty machen, damit keiner mehr versucht,
1084     // die Slots zu benutzen
1085     {
1086         SfxBindings *pBindings =
1087             pViewSh->GetViewFrame()->GetDispatcher()->GetBindings();
1088         sal_uInt16 nCount = pImp->aSlotArr.Count();
1089         for (sal_uInt16 n1=0; n1<nCount ; n1++)
1090         {
1091             sal_uInt16 nId = SID_VERB_START + n1;
1092             pBindings->Invalidate(nId, sal_False, sal_True);
1093         }
1094     }
1095 
1096     sal_uInt16 nr=0;
1097     for (sal_Int32 n=0; n<aVerbs.getLength(); n++)
1098     {
1099         sal_uInt16 nSlotId = SID_VERB_START + nr++;
1100         DBG_ASSERT(nSlotId <= SID_VERB_END, "Zuviele Verben!");
1101         if (nSlotId > SID_VERB_END)
1102             break;
1103 
1104         SfxSlot *pNewSlot = new SfxSlot;
1105         pNewSlot->nSlotId = nSlotId;
1106         pNewSlot->nGroupId = 0;
1107 
1108         // Verb-Slots m"ussen asynchron ausgef"uhrt werden, da sie w"ahrend
1109         // des Ausf"uhrens zerst"ort werden k"onnten
1110         pNewSlot->nFlags = SFX_SLOT_ASYNCHRON | SFX_SLOT_CONTAINER;
1111         pNewSlot->nMasterSlotId = 0;
1112         pNewSlot->nValue = 0;
1113         pNewSlot->fnExec = SFX_STUB_PTR(SfxShell,VerbExec);
1114         pNewSlot->fnState = SFX_STUB_PTR(SfxShell,VerbState);
1115         pNewSlot->pType = 0; HACK(SFX_TYPE(SfxVoidItem))
1116         pNewSlot->pName = U2S(aVerbs[n].VerbName);
1117         pNewSlot->pLinkedSlot = 0;
1118         pNewSlot->nArgDefCount = 0;
1119         pNewSlot->pFirstArgDef = 0;
1120         pNewSlot->pUnoName = 0;
1121 
1122         if (pImp->aSlotArr.Count())
1123         {
1124             SfxSlot *pSlot = (pImp->aSlotArr)[0];
1125             pNewSlot->pNextSlot = pSlot->pNextSlot;
1126             pSlot->pNextSlot = pNewSlot;
1127         }
1128         else
1129             pNewSlot->pNextSlot = pNewSlot;
1130 
1131         pImp->aSlotArr.Insert(pNewSlot, (sal_uInt16) n);
1132 	}
1133 
1134     pImp->aVerbList = aVerbs;
1135 
1136     if (pViewSh)
1137 	{
1138 		// Der Status von SID_OBJECT wird im Controller direkt an der Shell
1139 		// abgeholt, es reicht also, ein neues StatusUpdate anzuregen
1140 		SfxBindings *pBindings = pViewSh->GetViewFrame()->GetDispatcher()->
1141 				GetBindings();
1142 		pBindings->Invalidate( SID_OBJECT, sal_True, sal_True );
1143 	}
1144 }
1145 
1146 //--------------------------------------------------------------------
1147 
1148 const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& SfxShell::GetVerbs() const
1149 {
1150     return pImp->aVerbList;
1151 }
1152 
1153 //--------------------------------------------------------------------
1154 
1155 void SfxShell::VerbExec(SfxRequest& rReq)
1156 {
1157 	sal_uInt16 nId = rReq.GetSlot();
1158 	SfxViewShell *pViewShell = GetViewShell();
1159 	if ( pViewShell )
1160 	{
1161         sal_Bool bReadOnly = pViewShell->GetObjectShell()->IsReadOnly();
1162         com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > aList = pViewShell->GetVerbs();
1163         for (sal_Int32 n=0, nVerb=0; n<aList.getLength(); n++)
1164 		{
1165             // check for ReadOnly verbs
1166             if ( bReadOnly && !(aList[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES) )
1167                 continue;
1168 
1169             // check for verbs that shouldn't appear in the menu
1170             if ( !(aList[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU) )
1171                 continue;
1172 
1173             if (nId == SID_VERB_START + nVerb++)
1174 			{
1175                 pViewShell->DoVerb(aList[n].VerbID);
1176 				rReq.Done();
1177 				return;
1178 			}
1179 		}
1180 	}
1181 }
1182 
1183 //--------------------------------------------------------------------
1184 
1185 void SfxShell::VerbState(SfxItemSet& )
1186 {
1187 }
1188 
1189 //--------------------------------------------------------------------
1190 
1191 const SfxSlot* SfxShell::GetVerbSlot_Impl(sal_uInt16 nId) const
1192 {
1193     com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > rList = pImp->aVerbList;
1194 
1195 	DBG_ASSERT(nId >= SID_VERB_START && nId <= SID_VERB_END,"Falsche VerbId!");
1196 	sal_uInt16 nIndex = nId - SID_VERB_START;
1197     DBG_ASSERT(nIndex < rList.getLength(),"Falsche VerbId!");
1198 
1199     if (nIndex < rList.getLength())
1200         return pImp->aSlotArr[nIndex];
1201 	else
1202 		return 0;
1203 }
1204 
1205 //--------------------------------------------------------------------
1206 
1207 void SfxShell::SetHelpId(sal_uIntPtr nId)
1208 {
1209 	pImp->nHelpId = nId;
1210 }
1211 
1212 //--------------------------------------------------------------------
1213 
1214 sal_uIntPtr SfxShell::GetHelpId() const
1215 {
1216 	return pImp->nHelpId;
1217 }
1218 
1219 //--------------------------------------------------------------------
1220 
1221 SfxObjectShell* SfxShell::GetObjectShell()
1222 {
1223 	if ( GetViewShell() )
1224 		return GetViewShell()->GetViewFrame()->GetObjectShell();
1225 	else
1226 		return NULL;
1227 }
1228 
1229 //--------------------------------------------------------------------
1230 
1231 sal_Bool SfxShell::HasUIFeature( sal_uInt32 )
1232 {
1233 	return sal_False;
1234 }
1235 
1236 long DispatcherUpdate_Impl( void*, void* pArg )
1237 {
1238 	((SfxDispatcher*) pArg)->Update_Impl( sal_True );
1239     ((SfxDispatcher*) pArg)->GetBindings()->InvalidateAll(sal_False);
1240 	return 0;
1241 }
1242 
1243 void SfxShell::UIFeatureChanged()
1244 {
1245 	SfxViewFrame *pFrame = GetFrame();
1246     if ( pFrame && pFrame->IsVisible() )
1247 	{
1248 		// Auch dann Update erzwingen, wenn Dispatcher schon geupdated ist,
1249 		// sonst bleibt evtl. irgendwas in den gebunkerten Tools stecken.
1250 		// Asynchron aufrufen, um Rekursionen zu vermeiden
1251 		if ( !pImp->pUpdater )
1252             pImp->pUpdater = new svtools::AsynchronLink( Link( this, DispatcherUpdate_Impl ) );
1253 
1254 		// Mehrfachaufrufe gestattet
1255 		pImp->pUpdater->Call( pFrame->GetDispatcher(), sal_True );
1256 	}
1257 }
1258 
1259 void SfxShell::SetDisableFlags( sal_uIntPtr nFlags )
1260 {
1261 	pImp->nDisableFlags = nFlags;
1262 }
1263 
1264 sal_uIntPtr SfxShell::GetDisableFlags() const
1265 {
1266 	return pImp->nDisableFlags;
1267 }
1268 
1269 SfxItemSet*	SfxShell::CreateItemSet( sal_uInt16 )
1270 {
1271 	return NULL;
1272 }
1273 
1274 void SfxShell::ApplyItemSet( sal_uInt16, const SfxItemSet& )
1275 {
1276 }
1277 
1278 void SfxShell::SetViewShell_Impl( SfxViewShell* pView )
1279 {
1280     pImp->pViewSh = pView;
1281 }
1282 
1283 
1284 
1285