LCOV - code coverage report
Current view: top level - sw/source/core/attr - calbck.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 224 254 88.2 %
Date: 2014-04-11 Functions: 31 37 83.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <frame.hxx>
      21             : #include <hintids.hxx>
      22             : #include <hints.hxx>
      23             : #include <swcache.hxx>
      24             : #include <swfntcch.hxx>
      25             : 
      26             : static SwClientIter* pClientIters = 0;
      27             : 
      28     4443217 : TYPEINIT0( SwClient );
      29             : 
      30             : // SwClient
      31             : 
      32     5631739 : SwClient::SwClient( SwModify* pToRegisterIn )
      33     5631739 :     : pLeft( 0 ), pRight( 0 ), pRegisteredIn( 0 ), mbIsAllowedToBeRemovedInModifyCall( false )
      34             : {
      35     5631739 :     if(pToRegisterIn)
      36             :         // connect to SwModify
      37      481650 :         pToRegisterIn->Add(this);
      38     5631739 : }
      39             : 
      40       84869 : void SwClient::CheckRegistration( const SfxPoolItem* pOld, const SfxPoolItem* )
      41             : {
      42             :     // this method only handles notification about dying SwModify objects
      43       84869 :     if( (!pOld || pOld->Which() != RES_OBJECTDYING) )
      44       81430 :         return;
      45             : 
      46        3439 :     const SwPtrMsgPoolItem* pDead = static_cast<const SwPtrMsgPoolItem*>(pOld);
      47        3439 :     if(pDead && pDead->pObject == pRegisteredIn)
      48             :     {
      49             :         // I've got a notification from the object I know
      50        3439 :         SwModify* pAbove = const_cast<SwModify*>(pRegisteredIn->GetRegisteredIn());
      51        3439 :         if(pAbove)
      52             :         {
      53             :             // if the dying object itself was listening at an SwModify, I take over
      54             :             // adding myself to pAbove will automatically remove me from my current pRegisteredIn
      55          20 :             pAbove->Add(this);
      56          20 :             return;
      57             :         }
      58             :         // destroy connection
      59        3419 :         pRegisteredIn->Remove(this);
      60             :     }
      61             : }
      62             : 
      63       73670 : void SwClient::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
      64             : {
      65       73670 :     CheckRegistration( pOldValue, pNewValue );
      66       73670 : }
      67             : 
      68         558 : void SwClient::SwClientNotify( const SwModify&, const SfxHint& )
      69             : {
      70         558 : }
      71             : 
      72     7241513 : SwClient::~SwClient()
      73             : {
      74             :     OSL_ENSURE( !pRegisteredIn || pRegisteredIn->GetDepends(), "SwModify still known, but Client already disconnected!" );
      75     7241513 :     if( pRegisteredIn && pRegisteredIn->GetDepends() )
      76             :         // still connected
      77      407758 :         pRegisteredIn->Remove( this );
      78     7241513 : }
      79             : 
      80        2500 : bool SwClient::GetInfo( SfxPoolItem& ) const
      81             : {
      82        2500 :     return true;
      83             : }
      84             : 
      85             : // SwModify
      86             : 
      87       84658 : SwModify::SwModify()
      88       84658 :     : SwClient(0), pRoot(0)
      89             : {
      90       84658 :     bModifyLocked = false;
      91       84658 :     bLockClientList = sal_False;
      92       84658 :     bInDocDTOR = sal_False;
      93       84658 :     bInCache = sal_False;
      94       84658 :     bInSwFntCache = sal_False;
      95       84658 : }
      96             : 
      97      368887 : SwModify::SwModify( SwModify* pToRegisterIn )
      98      368887 :     : SwClient( pToRegisterIn ), pRoot( 0 )
      99             : {
     100      368887 :     bModifyLocked = false;
     101      368887 :     bLockClientList = sal_False;
     102      368887 :     bInDocDTOR = sal_False;
     103      368887 :     bInCache = sal_False;
     104      368887 :     bInSwFntCache = sal_False;
     105      368887 : }
     106             : 
     107      908334 : SwModify::~SwModify()
     108             : {
     109             :     OSL_ENSURE( !IsModifyLocked(), "Modify destroyed but locked." );
     110             : 
     111      453243 :     if ( IsInCache() )
     112       10038 :         SwFrm::GetCache().Delete( this );
     113             : 
     114      453243 :     if ( IsInSwFntCache() )
     115           0 :         pSwFontCache->Delete( this );
     116             : 
     117      453243 :     if( pRoot )
     118             :     {
     119             :         // there are depending objects
     120      207941 :         if( IsInDocDTOR() )
     121             :         {
     122             :             // If the document gets destroyed anyway, just tell clients to
     123             :             // forget me so that they don't try to get removed from my list
     124             :             // later when they also get destroyed
     125         102 :             SwClientIter aIter( *this );
     126         102 :             SwClient* p = aIter.GoStart();
     127         515 :             while ( p )
     128             :             {
     129         311 :                 p->pRegisteredIn = 0;
     130         311 :                 p = ++aIter;
     131         102 :             }
     132             :         }
     133             :         else
     134             :         {
     135             :             // notify all clients that they shall remove themselves
     136      207839 :             SwPtrMsgPoolItem aDyObject( RES_OBJECTDYING, this );
     137      207839 :             NotifyClients( &aDyObject, &aDyObject );
     138             : 
     139             :             // remove all clients that have not done themselves
     140             :             // mba: possibly a hotfix for forgotten base class calls?!
     141      419033 :             while( pRoot )
     142      211194 :                 pRoot->CheckRegistration( &aDyObject, &aDyObject );
     143             :         }
     144             :     }
     145      455091 : }
     146             : 
     147       59200 : void SwModify::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     148             : {
     149       59200 :     NotifyClients( pOldValue, pNewValue );
     150       59200 : }
     151             : 
     152     1108552 : void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     153             : {
     154     1108552 :     if ( IsInCache() || IsInSwFntCache() )
     155             :     {
     156             :         const sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
     157       21530 :                                         pNewValue ? pNewValue->Which() : 0;
     158       21530 :         CheckCaching( nWhich );
     159             :     }
     160             : 
     161     1108552 :     if ( !pRoot || IsModifyLocked() )
     162     1669320 :         return;
     163             : 
     164      547784 :     LockModify();
     165             : 
     166             :     // mba: WTF?!
     167      547784 :     if( !pOldValue )
     168             :     {
     169       61252 :         bLockClientList = sal_True;
     170             :     }
     171             :     else
     172             :     {
     173      486532 :         switch( pOldValue->Which() )
     174             :         {
     175             :         case RES_OBJECTDYING:
     176             :         case RES_REMOVE_UNO_OBJECT:
     177      208706 :             bLockClientList = ((SwPtrMsgPoolItem*)pOldValue)->pObject != this;
     178      208706 :             break;
     179             : 
     180             :         case RES_FOOTNOTE_DELETED:
     181             :         case RES_REFMARK_DELETED:
     182             :         case RES_TOXMARK_DELETED:
     183             :         case RES_FIELD_DELETED:
     184          54 :             bLockClientList = sal_False;
     185          54 :             break;
     186             : 
     187             :         default:
     188      277772 :             bLockClientList = sal_True;
     189             :         }
     190             :     }
     191             : 
     192      547784 :     ModifyBroadcast( pOldValue, pNewValue );
     193      547784 :     bLockClientList = sal_False;
     194      547784 :     UnlockModify();
     195             : }
     196             : 
     197      154448 : bool SwModify::GetInfo( SfxPoolItem& rInfo ) const
     198             : {
     199      154448 :     bool bRet = true;       // means: continue with next
     200             : 
     201      154448 :     if( pRoot )
     202             :     {
     203       71710 :         SwClientIter aIter( *(SwModify*)this );
     204             : 
     205       71710 :         SwClient* pLast = aIter.GoStart();
     206       71710 :         if( pLast )
     207             :         {
     208       71710 :             while( ( bRet = pLast->GetInfo( rInfo ) ) &&
     209             :                    0 != ( pLast = ++aIter ) )
     210             :                 ;
     211       71710 :         }
     212             :     }
     213             : 
     214      154448 :     return bRet;
     215             : }
     216             : 
     217      831700 : void SwModify::Add( SwClient* pDepend )
     218             : {
     219             :     OSL_ENSURE( !bLockClientList, "Client inserted while in Modify" );
     220             : 
     221      831700 :     if(pDepend->pRegisteredIn != this )
     222             :     {
     223             : #if OSL_DEBUG_LEVEL > 0
     224             :         SwClientIter* pTmp = pClientIters;
     225             :         while( pTmp )
     226             :         {
     227             :             OSL_ENSURE( &pTmp->GetModify() != pRoot, "Client added to active ClientIter" );
     228             :             pTmp = pTmp->pNxtIter;
     229             :         }
     230             : #endif
     231             :         // deregister new client in case it is already registered elsewhere
     232      769134 :         if( pDepend->pRegisteredIn != 0 )
     233       45554 :             pDepend->pRegisteredIn->Remove( pDepend );
     234             : 
     235      769134 :         if( !pRoot )
     236             :         {
     237             :             // first client added
     238      432386 :             pRoot = pDepend;
     239      432386 :             pRoot->pLeft = 0;
     240      432386 :             pRoot->pRight = 0;
     241             :         }
     242             :         else
     243             :         {
     244             :             // append client
     245      336748 :             pDepend->pRight = pRoot->pRight;
     246      336748 :             pRoot->pRight = pDepend;
     247      336748 :             pDepend->pLeft = pRoot;
     248      336748 :             if( pDepend->pRight )
     249      237633 :                 pDepend->pRight->pLeft = pDepend;
     250             :         }
     251             : 
     252             :         // connect client to me
     253      769134 :         pDepend->pRegisteredIn = this;
     254             :     }
     255      831700 : }
     256             : 
     257      768638 : SwClient* SwModify::Remove( SwClient* pDepend )
     258             : {
     259      768638 :     if ( bInDocDTOR )
     260           0 :         return 0;
     261             : 
     262             :     OSL_ENSURE( !bLockClientList || pDepend->mbIsAllowedToBeRemovedInModifyCall, "SwClient shall be removed in Modify call!" );
     263             : 
     264      768638 :     if( pDepend->pRegisteredIn == this )
     265             :     {
     266             :         // SwClient is my listener
     267             :         // remove it from my list
     268      768638 :         SwClient* pR = pDepend->pRight;
     269      768638 :         SwClient* pL = pDepend->pLeft;
     270      768638 :         if( pRoot == pDepend )
     271      506328 :             pRoot = pL ? pL : pR;
     272             : 
     273      768638 :         if( pL )
     274      262310 :             pL->pRight = pR;
     275      768638 :         if( pR )
     276      254165 :             pR->pLeft = pL;
     277             : 
     278             :         // update ClientIters
     279      768638 :         SwClientIter* pTmp = pClientIters;
     280     1767260 :         while( pTmp )
     281             :         {
     282      229984 :             if( pTmp->pAct == pDepend || pTmp->pDelNext == pDepend )
     283             :             {
     284             :                 // if object being removed is the current or next object in an
     285             :                 // iterator, advance this iterator
     286      207531 :                 pTmp->pDelNext = pR;
     287             :             }
     288      229984 :             pTmp = pTmp->pNxtIter;
     289             :         }
     290             : 
     291      768638 :         pDepend->pLeft = 0;
     292      768638 :         pDepend->pRight = 0;
     293             :     }
     294             :     else
     295             :     {
     296             :         OSL_FAIL( "SwModify::Remove(): could not find pDepend" );
     297             :     }
     298             : 
     299             :     // disconnect client from me
     300      768638 :     pDepend->pRegisteredIn = 0;
     301      768638 :     return pDepend;
     302             : }
     303             : 
     304       22831 : void SwModify::CheckCaching( const sal_uInt16 nWhich )
     305             : {
     306       22831 :     if( isCHRATR( nWhich ) )
     307             :     {
     308           0 :         SetInSwFntCache( sal_False );
     309             :     }
     310             :     else
     311             :     {
     312       22831 :         switch( nWhich )
     313             :         {
     314             :         case RES_OBJECTDYING:
     315             :         case RES_FMT_CHG:
     316             :         case RES_ATTRSET_CHG:
     317       15772 :             SetInSwFntCache( sal_False );
     318             :             // fall through
     319             :         case RES_UL_SPACE:
     320             :         case RES_LR_SPACE:
     321             :         case RES_BOX:
     322             :         case RES_SHADOW:
     323             :         case RES_FRM_SIZE:
     324             :         case RES_KEEP:
     325             :         case RES_BREAK:
     326       15922 :             if( IsInCache() )
     327             :             {
     328       13064 :                 SwFrm::GetCache().Delete( this );
     329       13064 :                 SetInCache( sal_False );
     330             :             }
     331       15922 :             break;
     332             :         }
     333             :     }
     334       22831 : }
     335             : 
     336        3716 : void SwModify::CallSwClientNotify( const SfxHint& rHint ) const
     337             : {
     338        3716 :     SwClientIter aIter(*this);
     339        3716 :     SwClient* pClient = aIter.GoStart();
     340        8037 :     while( pClient )
     341             :     {
     342         605 :         pClient->SwClientNotify( *this, rHint );
     343         605 :         pClient = ++aIter;
     344        3716 :     }
     345        3716 : }
     346             : 
     347      554098 : void SwModify::ModifyBroadcast( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue, TypeId nType )
     348             : {
     349      554098 :     SwClientIter aIter( *this );
     350      554098 :     SwClient* pClient = aIter.First( nType );
     351     1999922 :     while( pClient )
     352             :     {
     353      891726 :         pClient->Modify( pOldValue, pNewValue );
     354      891726 :         pClient = aIter.Next();
     355      554098 :     }
     356      554098 : }
     357             : 
     358             : // SwDepend
     359             : 
     360      112279 : SwDepend::SwDepend( SwClient* pTellHim, SwModify* pDepend )
     361      112279 :     : SwClient( pDepend )
     362             : {
     363      112279 :     pToTell  = pTellHim;
     364      112279 : }
     365             : 
     366         704 : void SwDepend::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     367             : {
     368         704 :     if( pNewValue && pNewValue->Which() == RES_OBJECTDYING )
     369          54 :         CheckRegistration(pOldValue,pNewValue);
     370         650 :     else if( pToTell )
     371         650 :         pToTell->ModifyNotification(pOldValue, pNewValue);
     372         704 : }
     373             : 
     374           0 : void SwDepend::SwClientNotify( const SwModify& rMod, const SfxHint& rHint )
     375             : {
     376           0 :     if ( pToTell )
     377           0 :         pToTell->SwClientNotifyCall( rMod, rHint );
     378           0 : }
     379             : 
     380           0 : bool SwDepend::GetInfo( SfxPoolItem& rInfo ) const
     381             : {
     382           0 :     return pToTell ? pToTell->GetInfo( rInfo ) : true;
     383             : }
     384             : 
     385             : // SwClientIter
     386             : 
     387     1441189 : SwClientIter::SwClientIter( const SwModify& rModify )
     388             :     : rRoot(rModify)
     389             :     , pNxtIter(NULL)
     390     1441189 :     , aSrchId(0)
     391             : {
     392     1441189 :     if( pClientIters )
     393             :     {
     394             :         // append to list of ClientIters
     395      160015 :         SwClientIter* pTmp = pClientIters;
     396      428170 :         while( pTmp->pNxtIter )
     397      108140 :             pTmp = pTmp->pNxtIter;
     398      160015 :         pTmp->pNxtIter = this;
     399             :     }
     400             :     else
     401     1281174 :         pClientIters = this;
     402             : 
     403     1441189 :     pAct = const_cast<SwClient*>(rRoot.GetDepends());
     404     1441189 :     pDelNext = pAct;
     405     1441189 : }
     406             : 
     407     1441189 : SwClientIter::~SwClientIter()
     408             : {
     409     1441189 :     if( pClientIters )
     410             :     {
     411             :         // reorganize list of ClientIters
     412     1441189 :         if( pClientIters == this )
     413     1281174 :             pClientIters = pNxtIter;
     414             :         else
     415             :         {
     416      160015 :             SwClientIter* pTmp = pClientIters;
     417      428170 :             while( pTmp->pNxtIter != this )
     418      108140 :                 if( 0 == ( pTmp = pTmp->pNxtIter ) )
     419             :                 {
     420             :                     OSL_ENSURE( this, "Lost my pointer" );
     421           0 :                     return ;
     422             :                 }
     423      160015 :             pTmp->pNxtIter = pNxtIter;
     424             :         }
     425             :     }
     426     1441189 : }
     427             : 
     428      261591 : SwClient* SwClientIter::operator++()
     429             : {
     430      261591 :     if( pDelNext == pAct )
     431             :     {
     432      261575 :         pAct = pAct->pRight;
     433      261575 :         pDelNext = pAct;
     434             :     }
     435             :     else
     436          16 :         pAct = pDelNext;
     437      261591 :     return pAct;
     438             : }
     439             : 
     440     1440236 : SwClient* SwClientIter::GoStart()
     441             : {
     442     1440236 :     pAct = const_cast<SwClient*>(rRoot.GetDepends());
     443     1440236 :     if( pAct )
     444             :     {
     445     2686876 :         while( pAct->pLeft )
     446           0 :             pAct = pAct->pLeft;
     447             :     }
     448     1440236 :     pDelNext = pAct;
     449     1440236 :     return pAct;
     450             : }
     451             : 
     452         277 : SwClient* SwClientIter::GoEnd()
     453             : {
     454         277 :     pAct = pDelNext;
     455         277 :     if( !pAct )
     456         277 :         pAct = const_cast<SwClient*>(rRoot.GetDepends());
     457         277 :     if( pAct )
     458             :     {
     459           0 :         while( pAct->pRight )
     460           0 :             pAct = pAct->pRight;
     461             :     }
     462         277 :     pDelNext = pAct;
     463         277 :     return pAct;
     464             : }
     465             : 
     466     1358771 : SwClient* SwClientIter::First( TypeId nType )
     467             : {
     468     1358771 :     aSrchId = nType;
     469     1358771 :     GoStart();
     470     1358771 :     if( pAct )
     471      670181 :         do {
     472     1879128 :             if( pAct->IsA( aSrchId ) )
     473     1208947 :                 break;
     474             : 
     475      670181 :             if( pDelNext == pAct )
     476             :             {
     477      670181 :                 pAct = pAct->pRight;
     478      670181 :                 pDelNext = pAct;
     479             :             }
     480             :             else
     481           0 :                 pAct = pDelNext;
     482             :         } while( pAct );
     483     1358771 :     return pAct;
     484             : }
     485             : 
     486         277 : SwClient* SwClientIter::Last( TypeId nType )
     487             : {
     488         277 :     aSrchId = nType;
     489         277 :     GoEnd();
     490         277 :     if( pAct )
     491           0 :         do {
     492           0 :             if( pAct->IsA( aSrchId ) )
     493           0 :                 break;
     494             : 
     495           0 :             if( pDelNext == pAct )
     496           0 :                 pAct = pAct->pLeft;
     497             :             else
     498           0 :                 pAct = pDelNext->pLeft;
     499           0 :             pDelNext = pAct;
     500             :         } while( pAct );
     501         277 :     return pAct;
     502             : }
     503             : 
     504     1220286 : SwClient* SwClientIter::Next()
     505             : {
     506      813747 :     do {
     507     1220286 :         if( pDelNext == pAct )
     508             :         {
     509     1012793 :             pAct = pAct->pRight;
     510     1012793 :             pDelNext = pAct;
     511             :         }
     512             :         else
     513      207493 :             pAct = pDelNext;
     514             : 
     515     1220286 :         if( pAct && pAct->IsA( aSrchId ) )
     516      406539 :             break;
     517             :     } while( pAct );
     518     1125899 :     return pAct;
     519             : }
     520             : 
     521           0 : SwClient* SwClientIter::Previous()
     522             : {
     523           0 :     do {
     524           0 :         if( pDelNext == pAct )
     525           0 :             pAct = pAct->pLeft;
     526             :         else
     527           0 :             pAct = pDelNext->pLeft;
     528           0 :         pDelNext = pAct;
     529             : 
     530           0 :         if( pAct && pAct->IsA( aSrchId ) )
     531           0 :             break;
     532             :     } while( pAct );
     533           0 :     return pAct;
     534             : }
     535             : 
     536             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10