Update ooo320-m1
[ooovba.git] / sw / source / core / attr / calbck.cxx
blob344f11cbc29b2e519e8680f57928a4bf7b61851b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: calbck.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx> // fuer RES_..
36 #include <frame.hxx>
37 #include <hints.hxx>
38 #include <swcache.hxx>
39 #include <swfntcch.hxx>
41 #ifndef PRODUCT
42 #include <unotextmarkup.hxx>
43 #endif
45 static SwClientIter* pClientIters = 0;
47 TYPEINIT0(SwClient); //rtti
49 /*************************************************************************
50 |* SwClient::SwClient(SwModify *)
52 |* Beschreibung callback.doc V1.14
53 |* Ersterstellung VB 20.03.91
54 |* Letzte Aenderung MA 20. Mar. 95
55 *************************************************************************/
58 SwClient::SwClient(SwModify *pToRegisterIn)
59 : pLeft( 0 ), pRight( 0 ), pRegisteredIn( 0 )
61 bModifyLocked =
62 bInModify =
63 bInDocDTOR =
64 bInCache = FALSE;
65 bInSwFntCache = FALSE;
67 if(pToRegisterIn)
68 pToRegisterIn->Add(this);
71 /*************************************************************************
72 |* SwClient::Modify()
74 |* Beschreibung callback.doc V1.14
75 |* Ersterstellung VB 20.03.91
76 |* Letzte Aenderung VB 20.03.91
77 *************************************************************************/
80 void SwClient::Modify( SfxPoolItem *pOld, SfxPoolItem * )
82 if( (!pOld || pOld->Which() != RES_OBJECTDYING) )
83 return;
85 SwPtrMsgPoolItem *pDead = (SwPtrMsgPoolItem *)pOld;
86 if(pDead->pObject == pRegisteredIn)
88 SwModify *pAbove = (SwModify*)pRegisteredIn->GetRegisteredIn();
89 if(pAbove)
91 pAbove->Add(this);
92 return;
94 pRegisteredIn->Remove(this);
98 /*************************************************************************
99 |* SwClient::~SwClient()
101 |* Beschreibung callback.doc V1.14
102 |* Ersterstellung VB 20.03.91
103 |* Letzte Aenderung MA 25. Jan. 94
104 *************************************************************************/
107 SwClient::~SwClient()
109 if( pRegisteredIn && pRegisteredIn->GetDepends() )
110 pRegisteredIn->Remove( this );
112 ASSERT( !IsModifyLocked(), "Modify destroyed but locked." );
116 // erfrage vom Client Informationen
117 BOOL SwClient::GetInfo( SfxPoolItem& ) const
119 return TRUE; // und weiter
122 /*************************************************************************
123 |* SwModify::SwModify( SwModify * )
125 |* Beschreibung Dokument 1.7
126 |* Ersterstellung JP 20.11.90
127 |* Letzte Aenderung VB 20.03.91
128 *************************************************************************/
131 SwModify::SwModify( SwModify *pToRegisterIn )
132 : SwClient(pToRegisterIn), pRoot( 0 )
136 // @@@ forbidden and not implemented, but needs to be accessible (protected).
137 SwModify::SwModify( const SwModify & )
138 : SwClient( 0 )
140 OSL_PRECOND(0, "SwModify(const SwModify&): not implemented.");
143 /*************************************************************************
144 |* SwModify::~SwModify()
146 |* Beschreibung Dokument 1.7
147 |* Ersterstellung JP 20.11.90
148 |* Letzte Aenderung JP 15.04.94
149 *************************************************************************/
153 SwModify::~SwModify()
155 if ( IsInCache() )
156 SwFrm::GetCache().Delete( this );
158 if ( IsInSwFntCache() )
159 pSwFontCache->Delete( this );
161 if( pRoot )
163 if( IsInDocDTOR() )
165 // alle Clients "logisch" austragen
166 SwClientIter aIter( *this );
167 SwClient* p;
168 while( 0 != ( p = aIter++ ) )
169 p->pRegisteredIn = 0;
171 p = aIter.GoRoot(); // wieder ab Root (==Start) anfangen
172 do {
173 p->pRegisteredIn = 0;
174 } while( 0 != ( p = aIter-- ) );
176 else
178 // verschicke die Nachricht an die abgeleiteten Objekte.
179 SwPtrMsgPoolItem aDyObject( RES_OBJECTDYING, this );
180 Modify( &aDyObject, &aDyObject );
182 // Zwangsummeldung aller derjenigen, die sich nicht ausgetragen
183 // haben, durch Aufruf von SwClient::Modify()
184 while( pRoot )
185 pRoot->SwClient::Modify(&aDyObject, &aDyObject);
190 /*************************************************************************
191 |* SwModify::Modify( SwHint * pOldValue, SwHint * pNewValue )
193 |* Beschreibung Dokument 1.7
194 |* Ersterstellung JP 20.11.90
195 |* Letzte Aenderung MA 20. Mar. 95
196 *************************************************************************/
200 void SwModify::Modify( SfxPoolItem* pOldValue, SfxPoolItem* pNewValue )
202 if (IsInCache() || IsInSwFntCache())
204 const USHORT nWhich = pOldValue ? pOldValue->Which() :
205 pNewValue ? pNewValue->Which() : 0;
206 CheckCaching( nWhich );
209 if (!pRoot || IsModifyLocked())
210 return;
212 LockModify();
214 #ifdef PRODUCT
215 bInModify = TRUE;
216 #else
217 if( !pOldValue )
218 bInModify = TRUE;
219 else
220 // following Modifies don't calls an ASSRT
221 switch( pOldValue->Which() )
223 case RES_OBJECTDYING:
224 case RES_REMOVE_UNO_OBJECT:
225 bInModify = ((SwPtrMsgPoolItem *)pOldValue)->pObject != this;
226 break;
228 case RES_FOOTNOTE_DELETED:
229 case RES_REFMARK_DELETED:
230 case RES_TOXMARK_DELETED:
231 case RES_FIELD_DELETED:
232 bInModify = FALSE;
233 break;
234 default:
235 bInModify = TRUE;
237 #endif
239 SwClientIter aIter( *this );
240 SwClient * pLast = aIter.GoStart();
241 if( pLast ) // konnte zum Anfang gesprungen werden ??
244 pLast->Modify( pOldValue, pNewValue );
245 if( !pRoot ) // Baum schon Weg ??
246 break;
247 } while( 0 != ( pLast = aIter++ ));
249 bInModify = FALSE;
250 UnlockModify();
253 // erfrage vom Modify Informationen
255 BOOL SwModify::GetInfo( SfxPoolItem& rInfo ) const
257 BOOL bRet = TRUE; // bedeutet weiter zum naechsten
259 if( pRoot )
261 SwClientIter aIter( *(SwModify*)this );
263 SwClient* pLast = aIter.GoStart();
264 if( pLast )
265 while( 0 != ( bRet = pLast->GetInfo( rInfo )) &&
266 0 != ( pLast = aIter++ ) )
270 return bRet; // und weiter
273 /*************************************************************************
274 |* SwModify::Add( SwClient *pDepend )
276 |* Beschreibung Dokument 1.7
277 |* Ersterstellung JP 20.11.90
278 |* Letzte Aenderung JP 14.09.94
279 *************************************************************************/
283 void SwModify::Add(SwClient *pDepend)
285 ASSERT( !bInModify, "Client innerhalb des eigenen Modifies einfuegen?" );
287 // nur wenn das hier noch nicht eingetragen ist einfuegen
288 if(pDepend->pRegisteredIn != this )
290 #ifndef PRODUCT
291 SwClientIter* pTmp = pClientIters;
292 while( pTmp )
294 ASSERT( &pTmp->rRoot != pRoot,
295 "Client beim angemeldeten ClientIter einfuegen?" );
296 pTmp = pTmp->pNxtIter;
298 #endif
299 // wenn schon wanders angemeldet, dann dort abmelden
300 if( pDepend->pRegisteredIn != 0 )
301 pDepend->pRegisteredIn->Remove( pDepend );
303 if( !pRoot )
305 pRoot = pDepend;
306 pRoot->pLeft = 0;
307 pRoot->pRight = 0;
309 else
311 // immer hinter die Root haengen
312 pDepend->pRight = pRoot->pRight;
313 pRoot->pRight = pDepend;
314 pDepend->pLeft = pRoot;
315 if( pDepend->pRight )
316 pDepend->pRight->pLeft = pDepend;
319 pDepend->pRegisteredIn = this;
323 /*************************************************************************
324 |* SwModify::_Remove( SwClient *pDepend )
326 |* Beschreibung Dokument 1.7
327 |* Ersterstellung JP 20.11.90
328 |* Letzte Aenderung JP 14.09.94
329 *************************************************************************/
333 SwClient *SwModify::_Remove(SwClient * pDepend)
335 // FME 2007-07-16 #i79641# SwXTextMarkup is allowed to be removed ...
336 ASSERT( !bInModify || 0 != dynamic_cast<SwXTextMarkup*>(pDepend), "Client innerhalb des eigenen Modifies loeschen?" );
338 // loesche das Object aus der Liste und setze den
339 // Registrierungs-Pointer zurueck
340 if( pDepend->pRegisteredIn == this )
342 SwClient* pR = pDepend->pRight;
343 SwClient* pL = pDepend->pLeft;
344 if( pRoot == pDepend )
345 pRoot = pL ? pL : pR;
347 if( pL )
348 pL->pRight = pR;
349 if( pR )
350 pR->pLeft = pL;
352 // alle Client-Iters updaten
353 SwClientIter* pTmp = pClientIters;
354 while( pTmp )
356 if( pTmp->pAkt == pDepend || pTmp->pDelNext == pDepend )
357 pTmp->pDelNext = pR;
359 // --> FME 2006-02-03 #127369# Notify SwClientIter if mpWatchClient is removed
360 if ( pTmp->mpWatchClient == pDepend )
361 pTmp->mpWatchClient = 0;
362 // <--
364 pTmp = pTmp->pNxtIter;
367 pDepend->pLeft = 0;
368 pDepend->pRight = 0;
370 else {
371 ASSERT( FALSE, "SwModify::Remove(): pDepend nicht gefunden");
373 pDepend->pRegisteredIn = 0;
374 return pDepend;
378 /*************************************************************************
379 |* SwModify::CheckCaching( const USHORT nWhich )
381 |* Ersterstellung JP 25.06.95
382 |* Letzte Aenderung JP 25.06.95
383 *************************************************************************/
387 void SwModify::CheckCaching( const USHORT nWhich )
389 if (isCHRATR(nWhich))
391 SetInSwFntCache( FALSE );
393 else
394 switch ( nWhich )
396 case RES_OBJECTDYING:
397 case RES_FMT_CHG:
398 case RES_ATTRSET_CHG:
399 SetInSwFntCache( FALSE );
401 case RES_UL_SPACE:
402 case RES_LR_SPACE:
403 case RES_BOX:
404 case RES_SHADOW:
405 case RES_FRM_SIZE:
406 case RES_KEEP:
407 case RES_BREAK:
408 if ( IsInCache() )
410 SwFrm::GetCache().Delete( this );
411 SetInCache( FALSE );
413 break;
418 // ----------
419 // SwDepend
420 // ----------
422 /*************************************************************************
423 |* SwDepend::SwDepend(SwClient *pTellHim,SwModify *pDepend)
425 |* Beschreibung callback.doc V1.14
426 |* Ersterstellung VB 20.03.91
427 |* Letzte Aenderung VB 20.03.91
428 *************************************************************************/
431 SwDepend::SwDepend(SwClient *pTellHim, SwModify *pDepend)
432 : SwClient(pDepend)
434 pToTell = pTellHim;
437 /*************************************************************************
439 |* SwDepend::Modify(SwHint *, SwHint *)
441 |* Beschreibung callback.doc V1.14
442 |* Ersterstellung VB 20.03.91
443 |* Letzte Aenderung VB 20.03.91
445 *************************************************************************/
448 void SwDepend::Modify( SfxPoolItem *pOldValue, SfxPoolItem *pNewValue )
450 if(pNewValue && pNewValue->Which() == RES_OBJECTDYING)
451 SwClient::Modify(pOldValue,pNewValue);
452 else if(pToTell)
453 pToTell->Modify(pOldValue, pNewValue);
457 // erfrage vom Modify Informationen
458 BOOL SwDepend::GetInfo( SfxPoolItem& rInfo ) const
460 return pToTell ? pToTell->GetInfo( rInfo ) : TRUE;
463 /********************************************************************/
466 SwClientIter::SwClientIter( SwModify& rModify )
467 : rRoot( rModify )
469 // hinten einketten!
470 pNxtIter = 0;
471 if( pClientIters )
473 SwClientIter* pTmp = pClientIters;
474 while( pTmp->pNxtIter )
475 pTmp = pTmp->pNxtIter;
476 pTmp->pNxtIter = this;
478 else
479 pClientIters = this;
481 pAkt = rRoot.pRoot;
482 pDelNext = pAkt;
483 mpWatchClient = 0;
488 SwClientIter::~SwClientIter()
490 if( pClientIters )
492 if( pClientIters == this )
493 pClientIters = pNxtIter;
494 else
496 SwClientIter* pTmp = pClientIters;
497 while( pTmp->pNxtIter != this )
498 if( 0 == ( pTmp = pTmp->pNxtIter ) )
500 ASSERT( this, "wo ist mein Pointer" );
501 return ;
503 pTmp->pNxtIter = pNxtIter;
509 #ifndef CFRONT
510 // Postfix Operator
511 SwClient* SwClientIter::operator++(int)
513 // solange der CFRONT Prefix und PostFix nicht unterscheiden kann, immer
514 // als Prefix-Operator arbeiten. Wenn der CFRONT es kann, muss auch der
515 // Code entsprechen umgestellt werden !!!
516 if( pDelNext == pAkt )
518 pAkt = pAkt->pRight;
519 pDelNext = pAkt;
521 else
522 pAkt = pDelNext;
523 return pAkt;
525 #endif
528 // Prefix Operator
529 SwClient* SwClientIter::operator++()
531 if( pDelNext == pAkt )
533 pAkt = pAkt->pRight;
534 pDelNext = pAkt;
536 else
537 pAkt = pDelNext;
538 return pAkt;
542 #ifndef CFRONT
543 // Postfix Operator
544 SwClient* SwClientIter::operator--(int)
546 // solange der CFRONT Prefix und PostFix nicht unterscheiden kann, immer
547 // als Prefix-Operator arbeiten. Wenn der CFRONT es kann, muss auch der
548 // Code entsprechen umgestellt werden !!!
549 if( pDelNext == pAkt )
550 pAkt = pAkt->pLeft;
551 else
552 pAkt = pDelNext->pLeft;
553 pDelNext = pAkt;
554 return pAkt;
556 #endif
559 // Prefix Operator
560 SwClient* SwClientIter::operator--()
562 if( pDelNext == pAkt )
563 pAkt = pAkt->pLeft;
564 else
565 pAkt = pDelNext->pLeft;
566 pDelNext = pAkt;
567 return pAkt;
571 SwClient* SwClientIter::GoStart() // zum Anfang des Baums
573 pAkt = rRoot.pRoot;
574 if( pAkt )
575 while( pAkt->pLeft )
576 pAkt = pAkt->pLeft;
577 pDelNext = pAkt;
578 return pAkt;
582 SwClient* SwClientIter::GoEnd() // zum End des Baums
584 pAkt = pDelNext;
585 if( !pAkt )
586 pAkt = rRoot.pRoot;
587 if( pAkt )
588 while( pAkt->pRight )
589 pAkt = pAkt->pRight;
590 pDelNext = pAkt;
591 return pAkt;
596 SwClient* SwClientIter::First( TypeId nType )
598 aSrchId = nType;
599 GoStart();
600 if( pAkt )
601 do {
602 if( pAkt->IsA( aSrchId ) )
603 break;
605 if( pDelNext == pAkt )
607 pAkt = pAkt->pRight;
608 pDelNext = pAkt;
610 else
611 pAkt = pDelNext;
613 } while( pAkt );
614 return pAkt;
618 SwClient* SwClientIter::Next()
620 do {
621 // erstmal zum naechsten
622 if( pDelNext == pAkt )
624 pAkt = pAkt->pRight;
625 pDelNext = pAkt;
627 else
628 pAkt = pDelNext;
630 if( pAkt && pAkt->IsA( aSrchId ) )
631 break;
632 } while( pAkt );
633 return pAkt;