xref: /AOO41X/main/sfx2/source/control/ctrlitem.cxx (revision 3ce09a58b0d6873449cda31e55c66dba2dbc8f7f)
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 <svl/itempool.hxx>
27 #ifndef GCC
28 #endif
29 
30 #include <sfx2/ctrlitem.hxx>
31 #include <sfx2/bindings.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/msgpool.hxx>
34 #include "statcach.hxx"
35 #include <sfx2/viewfrm.hxx>
36 
37 //====================================================================
38 
39 DBG_NAME(SfxControllerItem);
40 
41 //--------------------------------------------------------------------
42 #ifdef DBG_UTIL
43 
CheckConfigure_Impl(sal_uIntPtr nType)44 void SfxControllerItem::CheckConfigure_Impl( sal_uIntPtr nType )
45 {
46     // echter Slot? (also kein Separator etc.)
47     if ( !nId )
48         return;
49 
50     // ist die Id "uberhaupt in 'nType' konfigurierbar?
51     const SfxSlot *pSlot = SFX_SLOTPOOL().GetSlot(nId);
52     DBG_ASSERTWARNING( pSlot, "SfxControllerItem: binding not existing slot" );
53     if ( pSlot && !pSlot->IsMode(nType) )
54     {
55         DBG_WARNING( "SfxControllerItem: slot without ...Config-flag" );
56         DbgOutf( "SfxControllerItem: Config-flag missing at SID %5d",
57                  pSlot->GetSlotId() );
58     }
59 }
60 
61 #endif
62 
63 //--------------------------------------------------------------------
64 
65 // returns the next registered SfxControllerItem with the same id
66 
GetItemLink()67 SfxControllerItem* SfxControllerItem::GetItemLink()
68 {
69     DBG_MEMTEST();
70     DBG_CHKTHIS(SfxControllerItem, 0);
71     return pNext == this ? 0 : pNext;
72 }
73 
74 //--------------------------------------------------------------------
75 
76 // returns sal_True if this binding is really bound to a function
77 
IsBound() const78 sal_Bool SfxControllerItem::IsBound() const
79 {
80     DBG_MEMTEST();
81     DBG_CHKTHIS(SfxControllerItem, 0);
82     return pNext != this;
83 }
84 
85 //--------------------------------------------------------------------
86 
87 // returns the associated function-id or 0 if none
88 
89 // sal_uInt16 SfxControllerItem::GetId() const;
90 
91 //====================================================================
92 
93 // registeres with the id at the bindings
94 
Bind(sal_uInt16 nNewId,SfxBindings * pBindinx)95 void SfxControllerItem::Bind( sal_uInt16 nNewId, SfxBindings *pBindinx )
96 {
97     DBG_MEMTEST();
98     DBG_CHKTHIS(SfxControllerItem, 0);
99     DBG_ASSERT(pBindings || pBindinx, "Keine Bindings");
100 
101     if ( IsBound() ) {
102         DBG_ASSERT(pBindings, "Keine Bindings");
103         pBindings->Release(*this);
104     }
105 
106     nId = nNewId;
107     pNext = 0;
108 
109     if (pBindinx)
110         pBindings = pBindinx;
111     pBindings->Register(*this);
112 }
113 
BindInternal_Impl(sal_uInt16 nNewId,SfxBindings * pBindinx)114 void SfxControllerItem::BindInternal_Impl( sal_uInt16 nNewId, SfxBindings *pBindinx )
115 {
116     DBG_MEMTEST();
117     DBG_CHKTHIS(SfxControllerItem, 0);
118     DBG_ASSERT(pBindings || pBindinx, "Keine Bindings");
119 
120     if ( IsBound() ) {
121         DBG_ASSERT(pBindings, "Keine Bindings");
122         pBindings->Release(*this);
123     }
124 
125     nId = nNewId;
126     pNext = 0;
127 
128     if (pBindinx)
129         pBindings = pBindinx;
130     pBindings->RegisterInternal_Impl(*this);
131 }
132 
133 
134 //====================================================================
135 
UnBind()136 void SfxControllerItem::UnBind()
137 
138 /*  [Beschreibung]
139 
140     "ost die Verbindung dieses SfxControllerItems mit der SfxBindings-Instanz,
141     an der es zur Zeit gebunden ist. Ab diesem Zeitpunkt erh"alt es keine
142     Statusbenachrichtigungen (<SfxControllerItem::StateChented()>) mehr.
143 
144 
145     [Querverweise]
146 
147     <SfxControllerItem::ReBind()>
148     <SfxControllerItem::ClearCache()>
149 */
150 {
151     DBG_MEMTEST();
152     DBG_CHKTHIS(SfxControllerItem, 0);
153     DBG_ASSERT(pBindings, "Keine Bindings");
154     DBG_ASSERT( IsBound(), "unbindings unbound SfxControllerItem" );
155 
156     pBindings->Release(*this);
157     pNext = this;
158 }
159 
160 //====================================================================
161 
ReBind()162 void SfxControllerItem::ReBind()
163 
164 /*  [Beschreibung]
165 
166     Binded dieses SfxControllerItem wieder an die SfxBindings-Instanz,
167     an der es zuletzt gebunden war. Ab diesem Zeitpunkt erh"alt es wieder
168     Statusbenachrichtigungen (<SfxControllerItem::StateChented()>).
169 
170 
171     [Querverweise]
172 
173     <SfxControllerItem::UnBind()>
174     <SfxControllerItem::ClearCache()>
175 */
176 
177 {
178     DBG_MEMTEST();
179 DBG_CHKTHIS(SfxControllerItem, 0);
180     DBG_ASSERT(pBindings, "Keine Bindings");
181     DBG_ASSERT( !IsBound(), "bindings rebound SfxControllerItem" );
182 
183     pBindings->Register(*this);
184 }
185 
186 //====================================================================
187 
UpdateSlot()188 void SfxControllerItem::UpdateSlot()
189 
190 /*  [Beschreibung]
191 
192     Holt den Status 'hart' neu.
193 
194     [Querverweise]
195 
196     <SfxControllerItem::ClearCache()>
197 */
198 
199 {
200     DBG_MEMTEST();
201     DBG_CHKTHIS(SfxControllerItem, 0);
202     DBG_ASSERT(pBindings, "Keine Bindings");
203 
204     pBindings->Update( GetId() );
205 }
206 
207 //--------------------------------------------------------------------
208 
ClearCache()209 void SfxControllerItem::ClearCache()
210 
211 /*  [Beschreibung]
212 
213     "oscht den Status-Cache f"ur dieses SfxControllerItem. D.h. beim
214     n"achsten Status-Update wird das <SfxPoolItem> auf jeden Fall geschickt,
215     auch wenn zuvor dasselbe geschickt wurde. Dies wird ben"otigt, wenn
216     ein Controller umgeschaltet werden kann und sich diesen Status
217     selbst merkt.
218 
219 
220     [Beispiel]
221 
222     Der Kombi-Controller f"ur das Einstellen des Fl"achentyps und der
223     konkreten Auspr"agung (Farbe blau oder Schraffur X) kann im Typ
224     umgestellt werden, wird jedoch dann bei der n"achsten Selektion
225     wieder benachrichtigt, auch wenn es dieselben Daten sind.
226 
227 
228     [Querverweise]
229 
230     <SfxControllerItem::UnBind()>
231     <SfxControllerItem::ReBind()>
232 */
233 
234 
235 {
236     DBG_MEMTEST();
237     DBG_CHKTHIS(SfxControllerItem, 0);
238     DBG_ASSERT(pBindings, "Keine Bindings");
239 
240     pBindings->ClearCache_Impl( GetId() );
241 }
242 
243 //--------------------------------------------------------------------
244 
245 // replaces the successor in the list of bindings of the same id
246 
ChangeItemLink(SfxControllerItem * pNewLink)247 SfxControllerItem* SfxControllerItem::ChangeItemLink( SfxControllerItem* pNewLink )
248 {
249     DBG_MEMTEST();
250     DBG_CHKTHIS(SfxControllerItem, 0);
251     SfxControllerItem* pOldLink = pNext;
252     pNext = pNewLink;
253     return pOldLink == this ? 0 : pOldLink;
254 }
255 
256 //--------------------------------------------------------------------
257 
258 // changes the id of unbound functions (e.g. for sub-menu-ids)
259 
SetId(sal_uInt16 nItemId)260 void SfxControllerItem::SetId( sal_uInt16 nItemId )
261 {
262     DBG_MEMTEST();
263     DBG_CHKTHIS(SfxControllerItem, 0);
264     DBG_ASSERT( !IsBound(), "changing id of bound binding" );
265     nId = nItemId;
266 }
267 
268 //--------------------------------------------------------------------
269 
270 // creates a atomic item for a controller  without registration
271 
SfxControllerItem()272 SfxControllerItem::SfxControllerItem():
273     nId(0),
274     pNext(this),
275     pBindings(0)
276 {
277     DBG_MEMTEST();
278     DBG_CTOR(SfxControllerItem, 0);
279 }
280 
281 //--------------------------------------------------------------------
282 
283 // creates a representation of the function nId and registeres it
284 
SfxControllerItem(sal_uInt16 nID,SfxBindings & rBindings)285 SfxControllerItem::SfxControllerItem( sal_uInt16 nID, SfxBindings &rBindings ):
286     nId(nID),
287     pNext(this),
288     pBindings(&rBindings)
289 {
290     DBG_MEMTEST();
291     DBG_CTOR(SfxControllerItem, 0);
292     Bind(nId, &rBindings);
293 }
294 
295 //--------------------------------------------------------------------
296 
297 // unregisteres the item in the bindings
298 
~SfxControllerItem()299 SfxControllerItem::~SfxControllerItem()
300 {
301     DBG_MEMTEST();
302     if ( IsBound() )
303         pBindings->Release(*this);
304     DBG_DTOR(SfxControllerItem, 0);
305 }
306 
307 //--------------------------------------------------------------------
308 
StateChanged(sal_uInt16,SfxItemState,const SfxPoolItem *)309 void SfxControllerItem::StateChanged
310 (
311     sal_uInt16              ,   // <SID> des ausl"osenden Slot
312     SfxItemState        ,   // <SfxItemState> von 'pState'
313     const SfxPoolItem*      // Slot-Status, ggf. 0 oder IsInvalidItem()
314 )
315 
316 /*  [Beschreibung]
317 
318     Diese virtuelle Methode wird vom SFx gerufen, um <SfxControllerItem>s
319     dar"uber zu benachrichtigen, da\s sich der Status des Slots 'nSID'
320     ge"andert hat. Der neue Wert sowie der von diesem Wert ermittelte
321     Status wird als 'pState' bzw. 'eState' mitgegeben.
322 
323     Der Status eines Slots kann sich "andern, wenn z.B. das MDI-Fenster
324     gewechselt wird oder der Slot explizit mit <SfxBindings::Invalidate()>
325     invalidiert wurde.
326 
327     Achtung! Die Methode wird nicht gerufen, wenn der Slot ung"ultig wurde,
328     danach jedoch wieder denselben Wert angenommen hat.
329 
330     Diese Basisklasse braucht nicht gerufen zu werden, weitere Zwischenstufen
331     jedoch (z.B. <SfxToolboxControl>) sollten gerufen werden.
332 */
333 
334 {
335     DBG_MEMTEST();
336     DBG_CHKTHIS(SfxControllerItem, 0);
337 }
338 
339 //--------------------------------------------------------------------
340 
DeleteFloatingWindow()341 void SfxControllerItem::DeleteFloatingWindow()
342 {
343     DBG_MEMTEST();
344     DBG_CHKTHIS(SfxControllerItem, 0);
345 }
346 
347 //--------------------------------------------------------------------
348 
StateChanged(sal_uInt16 nSID,SfxItemState eState,const SfxPoolItem * pState)349 void SfxStatusForwarder::StateChanged
350 (
351     sal_uInt16              nSID,       // <SID> des ausl"osenden Slot
352     SfxItemState        eState,     // <SfxItemState> von 'pState'
353     const SfxPoolItem*  pState      // Slot-Status, ggf. 0 oder IsInvalidItem()
354 )
355 
356 {
357     pMaster->StateChanged( nSID, eState, pState );
358 }
359 
360 //--------------------------------------------------------------------
361 
SfxStatusForwarder(sal_uInt16 nSlotId,SfxControllerItem & rMaster)362 SfxStatusForwarder::SfxStatusForwarder(
363             sal_uInt16              nSlotId,
364             SfxControllerItem&  rMaster ):
365     SfxControllerItem( nSlotId, rMaster.GetBindings() ),
366     pMaster( &rMaster )
367 {
368 }
369 
370 //--------------------------------------------------------------------
371 
GetItemState(const SfxPoolItem * pState)372 SfxItemState SfxControllerItem::GetItemState
373 (
374     const SfxPoolItem* pState   /*  Pointer auf das <SfxPoolItem>, dessen
375                                     Status erfragt werden soll. */
376 )
377 
378 /*  [Beschreibung]
379 
380     Statische Methode zum Ermitteln des Status des SfxPoolItem-Pointers,
381     in der Methode <SfxControllerItem::StateChanged(const SfxPoolItem*)>
382     zu verwenden.
383 
384     [R"uckgabewert]
385 
386     SfxItemState        SFX_ITEM_UNKNOWN
387                         Enabled, aber keine weitere Statusinformation
388                         verf"ugbar. Typisch f"ur <Slot>s, die allenfalls
389                         zeitweise disabled sind, aber ihre Darstellung sonst
390                         nicht "andern.
391 
392                         SFX_ITEM_DISABLED
393                         Disabled und keine weiter Statusinformation
394                         verf"ugbar. Alle anderen ggf. angezeigten Werte sollten
395                         auf den Default zur"uckgesetzt werden.
396 
397                         SFX_ITEM_DONTCARE
398                         Enabled aber es waren nur uneindeutige Werte
399                         verf"ugbar (also keine, die abgefragt werden k"onnen).
400 
401                         SFX_ITEM_AVAILABLE
402                         Enabled und mit verf"ugbarem Wert, der von 'pState'
403                         erfragbar ist. Der Typ ist dabei im gesamten
404                         Programm eindeutig und durch den Slot festgelegt.
405 */
406 
407 {
408     return !pState
409                 ? SFX_ITEM_DISABLED
410                 : IsInvalidItem(pState)
411                     ? SFX_ITEM_DONTCARE
412                     : pState->ISA(SfxVoidItem) && !pState->Which()
413                         ? SFX_ITEM_UNKNOWN
414                         : SFX_ITEM_AVAILABLE;
415 }
416 
417 //--------------------------------------------------------------------
418 
GetCoreMetric() const419 SfxMapUnit SfxControllerItem::GetCoreMetric() const
420 
421 /*  [Beschreibung]
422 
423     Holt vom zust"andigen Pool die Ma\seinheit ab, in der das Status-Item
424     vorliegt.
425 */
426 
427 {
428     SfxStateCache *pCache = pBindings->GetStateCache( nId );
429     SfxDispatcher *pDispat = pBindings->GetDispatcher_Impl();
430 
431     if ( !pDispat )
432     {
433         SfxViewFrame* pViewFrame = SfxViewFrame::Current();
434         if ( !pViewFrame )
435             SfxViewFrame::GetFirst();
436         if ( pViewFrame )
437             pDispat = pViewFrame->GetDispatcher();
438     }
439 
440     if ( pDispat && pCache )
441     {
442         const SfxSlotServer *pServer = pCache->GetSlotServer( *pDispat );
443         if ( pServer )
444         {
445             SfxShell *pSh = pDispat->GetShell( pServer->GetShellLevel() );
446             SfxItemPool &rPool = pSh->GetPool();
447             sal_uInt16 nWhich = rPool.GetWhich( nId );
448 
449             // invalidate slot and its message|slot server as 'global' information
450             // about the validated message|slot server is not made available
451             pCache->Invalidate( sal_True );
452 
453             return rPool.GetMetric( nWhich );
454         }
455     }
456 
457     DBG_WARNING( "W1: Can not find ItemPool!" );
458     return SFX_MAPUNIT_100TH_MM;
459 }
460 
461 //------------------------------------------------------------------------
462 
463 #ifdef _MSC_VER
464 #pragma optimize("g",off)
465 #endif
466 
467 
468