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