1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: calbck.cxx,v $
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_..
38 #include <swcache.hxx>
39 #include <swfntcch.hxx>
42 #include <unotextmarkup.hxx>
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 )
65 bInSwFntCache
= FALSE
;
68 pToRegisterIn
->Add(this);
71 /*************************************************************************
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
) )
85 SwPtrMsgPoolItem
*pDead
= (SwPtrMsgPoolItem
*)pOld
;
86 if(pDead
->pObject
== pRegisteredIn
)
88 SwModify
*pAbove
= (SwModify
*)pRegisteredIn
->GetRegisteredIn();
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
& )
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()
156 SwFrm::GetCache().Delete( this );
158 if ( IsInSwFntCache() )
159 pSwFontCache
->Delete( this );
165 // alle Clients "logisch" austragen
166 SwClientIter
aIter( *this );
168 while( 0 != ( p
= aIter
++ ) )
169 p
->pRegisteredIn
= 0;
171 p
= aIter
.GoRoot(); // wieder ab Root (==Start) anfangen
173 p
->pRegisteredIn
= 0;
174 } while( 0 != ( p
= aIter
-- ) );
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()
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())
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;
228 case RES_FOOTNOTE_DELETED
:
229 case RES_REFMARK_DELETED
:
230 case RES_TOXMARK_DELETED
:
231 case RES_FIELD_DELETED
:
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 ??
247 } while( 0 != ( pLast
= aIter
++ ));
253 // erfrage vom Modify Informationen
255 BOOL
SwModify::GetInfo( SfxPoolItem
& rInfo
) const
257 BOOL bRet
= TRUE
; // bedeutet weiter zum naechsten
261 SwClientIter
aIter( *(SwModify
*)this );
263 SwClient
* pLast
= aIter
.GoStart();
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 )
291 SwClientIter
* pTmp
= pClientIters
;
294 ASSERT( &pTmp
->rRoot
!= pRoot
,
295 "Client beim angemeldeten ClientIter einfuegen?" );
296 pTmp
= pTmp
->pNxtIter
;
299 // wenn schon wanders angemeldet, dann dort abmelden
300 if( pDepend
->pRegisteredIn
!= 0 )
301 pDepend
->pRegisteredIn
->Remove( pDepend
);
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
;
352 // alle Client-Iters updaten
353 SwClientIter
* pTmp
= pClientIters
;
356 if( pTmp
->pAkt
== pDepend
|| pTmp
->pDelNext
== pDepend
)
359 // --> FME 2006-02-03 #127369# Notify SwClientIter if mpWatchClient is removed
360 if ( pTmp
->mpWatchClient
== pDepend
)
361 pTmp
->mpWatchClient
= 0;
364 pTmp
= pTmp
->pNxtIter
;
371 ASSERT( FALSE
, "SwModify::Remove(): pDepend nicht gefunden");
373 pDepend
->pRegisteredIn
= 0;
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
);
396 case RES_OBJECTDYING
:
398 case RES_ATTRSET_CHG
:
399 SetInSwFntCache( FALSE
);
410 SwFrm::GetCache().Delete( this );
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
)
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
);
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
)
473 SwClientIter
* pTmp
= pClientIters
;
474 while( pTmp
->pNxtIter
)
475 pTmp
= pTmp
->pNxtIter
;
476 pTmp
->pNxtIter
= this;
488 SwClientIter::~SwClientIter()
492 if( pClientIters
== this )
493 pClientIters
= pNxtIter
;
496 SwClientIter
* pTmp
= pClientIters
;
497 while( pTmp
->pNxtIter
!= this )
498 if( 0 == ( pTmp
= pTmp
->pNxtIter
) )
500 ASSERT( this, "wo ist mein Pointer" );
503 pTmp
->pNxtIter
= pNxtIter
;
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
)
529 SwClient
* SwClientIter::operator++()
531 if( pDelNext
== pAkt
)
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
)
552 pAkt
= pDelNext
->pLeft
;
560 SwClient
* SwClientIter::operator--()
562 if( pDelNext
== pAkt
)
565 pAkt
= pDelNext
->pLeft
;
571 SwClient
* SwClientIter::GoStart() // zum Anfang des Baums
582 SwClient
* SwClientIter::GoEnd() // zum End des Baums
588 while( pAkt
->pRight
)
596 SwClient
* SwClientIter::First( TypeId nType
)
602 if( pAkt
->IsA( aSrchId
) )
605 if( pDelNext
== pAkt
)
618 SwClient
* SwClientIter::Next()
621 // erstmal zum naechsten
622 if( pDelNext
== pAkt
)
630 if( pAkt
&& pAkt
->IsA( aSrchId
) )