xref: /trunk/main/sfx2/source/control/ctrlitem.cxx (revision 6837c635)
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