LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/attr - calbck.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 226 256 88.3 %
Date: 2013-07-09 Functions: 33 39 84.6 %
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>          // contains RES_.. IDs
      22             : #include <hints.hxx>
      23             : #include <swcache.hxx>          // mba: get rid of that dependency
      24             : #include <swfntcch.hxx>         // mba: get rid of that dependency
      25             : 
      26             : static SwClientIter* pClientIters = 0;
      27             : 
      28     1017151 : TYPEINIT0( SwClient );
      29             : 
      30             : // ----------
      31             : // SwClient
      32             : // ----------
      33             : 
      34      335084 : SwClient::SwClient( SwModify* pToRegisterIn )
      35      335084 :     : pLeft( 0 ), pRight( 0 ), pRegisteredIn( 0 ), mbIsAllowedToBeRemovedInModifyCall( false )
      36             : {
      37      335084 :     if(pToRegisterIn)
      38             :         // connect to SwModify
      39       89044 :         pToRegisterIn->Add(this);
      40      335084 : }
      41             : 
      42       15486 : void SwClient::CheckRegistration( const SfxPoolItem* pOld, const SfxPoolItem* )
      43             : {
      44             :     // this method only handles notification about dying SwModify objects
      45       15486 :     if( (!pOld || pOld->Which() != RES_OBJECTDYING) )
      46       14523 :         return;
      47             : 
      48         963 :     const SwPtrMsgPoolItem* pDead = static_cast<const SwPtrMsgPoolItem*>(pOld);
      49         963 :     if(pDead && pDead->pObject == pRegisteredIn)
      50             :     {
      51             :         // I've got a notification from the object I know
      52         963 :         SwModify* pAbove = const_cast<SwModify*>(pRegisteredIn->GetRegisteredIn());
      53         963 :         if(pAbove)
      54             :         {
      55             :             // if the dying object itself was listening at an SwModify, I take over
      56             :             // adding myself to pAbove will automatically remove me from my current pRegisteredIn
      57          20 :             pAbove->Add(this);
      58          20 :             return;
      59             :         }
      60             :         // destroy connection
      61         943 :         pRegisteredIn->Remove(this);
      62             :     }
      63             : }
      64             : 
      65       11720 : void SwClient::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
      66             : {
      67       11720 :     CheckRegistration( pOldValue, pNewValue );
      68       11720 : }
      69             : 
      70         321 : void SwClient::SwClientNotify( const SwModify&, const SfxHint& )
      71             : {
      72         321 : }
      73             : 
      74      757106 : SwClient::~SwClient()
      75             : {
      76             :     OSL_ENSURE( !pRegisteredIn || pRegisteredIn->GetDepends(), "SwModify still known, but Client already disconnected!" );
      77      378553 :     if( pRegisteredIn && pRegisteredIn->GetDepends() )
      78             :         // still connected
      79       87206 :         pRegisteredIn->Remove( this );
      80      378553 : }
      81             : 
      82        2526 : bool SwClient::GetInfo( SfxPoolItem& ) const
      83             : {
      84        2526 :     return true;
      85             : }
      86             : 
      87             : // ----------
      88             : // SwModify
      89             : // ----------
      90             : 
      91       14079 : SwModify::SwModify()
      92       14079 :     : SwClient(0), pRoot(0)
      93             : {
      94       14079 :     bModifyLocked = false;
      95       14079 :     bLockClientList = sal_False;
      96       14079 :     bInDocDTOR = sal_False;
      97       14079 :     bInCache = sal_False;
      98       14079 :     bInSwFntCache = sal_False;
      99       14079 : }
     100             : 
     101      109674 : SwModify::SwModify( SwModify* pToRegisterIn )
     102      109674 :     : SwClient( pToRegisterIn ), pRoot( 0 )
     103             : {
     104      109674 :     bModifyLocked = false;
     105      109674 :     bLockClientList = sal_False;
     106      109674 :     bInDocDTOR = sal_False;
     107      109674 :     bInCache = sal_False;
     108      109674 :     bInSwFntCache = sal_False;
     109      109674 : }
     110             : 
     111      247977 : SwModify::~SwModify()
     112             : {
     113             :     OSL_ENSURE( !IsModifyLocked(), "Modify destroyed but locked." );
     114             : 
     115      123541 :     if ( IsInCache() )
     116        3404 :         SwFrm::GetCache().Delete( this );
     117             : 
     118      123541 :     if ( IsInSwFntCache() )
     119           0 :         pSwFontCache->Delete( this );
     120             : 
     121      123541 :     if( pRoot )
     122             :     {
     123             :         // there are depending objects
     124       31694 :         if( IsInDocDTOR() )
     125             :         {
     126             :             // If the document gets destroyed anyway, just tell clients to
     127             :             // forget me so that they don't try to get removed from my list
     128             :             // later when they also get destroyed
     129          31 :             SwClientIter aIter( *this );
     130          31 :             SwClient* p = aIter.GoStart();
     131         173 :             while ( p )
     132             :             {
     133         111 :                 p->pRegisteredIn = 0;
     134         111 :                 p = ++aIter;
     135          31 :             }
     136             :         }
     137             :         else
     138             :         {
     139             :             // notify all clients that they shall remove themselves
     140       31663 :             SwPtrMsgPoolItem aDyObject( RES_OBJECTDYING, this );
     141       31663 :             NotifyClients( &aDyObject, &aDyObject );
     142             : 
     143             :             // remove all clients that have not done themselves
     144             :             // mba: possibly a hotfix for forgotten base class calls?!
     145       64211 :             while( pRoot )
     146       32548 :                 pRoot->CheckRegistration( &aDyObject, &aDyObject );
     147             :         }
     148             :     }
     149      124436 : }
     150             : 
     151       25529 : void SwModify::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     152             : {
     153       25529 :     NotifyClients( pOldValue, pNewValue );
     154       25529 : }
     155             : 
     156      279225 : void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     157             : {
     158      279225 :     if ( IsInCache() || IsInSwFntCache() )
     159             :     {
     160             :         const sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
     161        9662 :                                         pNewValue ? pNewValue->Which() : 0;
     162        9662 :         CheckCaching( nWhich );
     163             :     }
     164             : 
     165      279225 :     if ( !pRoot || IsModifyLocked() )
     166      435530 :         return;
     167             : 
     168      122920 :     LockModify();
     169             : 
     170             :     // mba: WTF?!
     171      122920 :     if( !pOldValue )
     172             :     {
     173       16395 :         bLockClientList = sal_True;
     174             :     }
     175             :     else
     176             :     {
     177      106525 :         switch( pOldValue->Which() )
     178             :         {
     179             :         case RES_OBJECTDYING:
     180             :         case RES_REMOVE_UNO_OBJECT:
     181       32007 :             bLockClientList = ((SwPtrMsgPoolItem*)pOldValue)->pObject != this;
     182       32007 :             break;
     183             : 
     184             :         case RES_FOOTNOTE_DELETED:
     185             :         case RES_REFMARK_DELETED:
     186             :         case RES_TOXMARK_DELETED:
     187             :         case RES_FIELD_DELETED:
     188          44 :             bLockClientList = sal_False;
     189          44 :             break;
     190             : 
     191             :         default:
     192       74474 :             bLockClientList = sal_True;
     193             :         }
     194             :     }
     195             : 
     196      122920 :     ModifyBroadcast( pOldValue, pNewValue );
     197      122920 :     bLockClientList = sal_False;
     198      122920 :     UnlockModify();
     199             : }
     200             : 
     201      131367 : bool SwModify::GetInfo( SfxPoolItem& rInfo ) const
     202             : {
     203      131367 :     bool bRet = true;       // means: continue with next
     204             : 
     205      131367 :     if( pRoot )
     206             :     {
     207       51444 :         SwClientIter aIter( *(SwModify*)this );
     208             : 
     209       51444 :         SwClient* pLast = aIter.GoStart();
     210       51444 :         if( pLast )
     211             :         {
     212       51444 :             while( ( bRet = pLast->GetInfo( rInfo ) ) &&
     213             :                    0 != ( pLast = ++aIter ) )
     214             :                 ;
     215       51444 :         }
     216             :     }
     217             : 
     218      131367 :     return bRet;
     219             : }
     220             : 
     221      191973 : void SwModify::Add( SwClient* pDepend )
     222             : {
     223             :     OSL_ENSURE( !bLockClientList, "Client inserted while in Modify" );
     224             : 
     225      191973 :     if(pDepend->pRegisteredIn != this )
     226             :     {
     227             : #if OSL_DEBUG_LEVEL > 0
     228             :         SwClientIter* pTmp = pClientIters;
     229             :         while( pTmp )
     230             :         {
     231             :             OSL_ENSURE( &pTmp->GetModify() != pRoot, "Client added to active ClientIter" );
     232             :             pTmp = pTmp->pNxtIter;
     233             :         }
     234             : #endif
     235             :         // deregister new client in case it is already registered elsewhere
     236      163635 :         if( pDepend->pRegisteredIn != 0 )
     237       10973 :             pDepend->pRegisteredIn->Remove( pDepend );
     238             : 
     239      163635 :         if( !pRoot )
     240             :         {
     241             :             // first client added
     242       85679 :             pRoot = pDepend;
     243       85679 :             pRoot->pLeft = 0;
     244       85679 :             pRoot->pRight = 0;
     245             :         }
     246             :         else
     247             :         {
     248             :             // append client
     249       77956 :             pDepend->pRight = pRoot->pRight;
     250       77956 :             pRoot->pRight = pDepend;
     251       77956 :             pDepend->pLeft = pRoot;
     252       77956 :             if( pDepend->pRight )
     253       51543 :                 pDepend->pRight->pLeft = pDepend;
     254             :         }
     255             : 
     256             :         // connect client to me
     257      163635 :         pDepend->pRegisteredIn = this;
     258             :     }
     259      191973 : }
     260             : 
     261      163387 : SwClient* SwModify::Remove( SwClient* pDepend )
     262             : {
     263      163387 :     if ( bInDocDTOR )
     264           0 :         return 0;
     265             : 
     266             :     OSL_ENSURE( !bLockClientList || pDepend->mbIsAllowedToBeRemovedInModifyCall, "SwClient shall be removed in Modify call!" );
     267             : 
     268      163387 :     if( pDepend->pRegisteredIn == this )
     269             :     {
     270             :         // SwClient is my listener
     271             :         // remove it from my list
     272      163387 :         SwClient* pR = pDepend->pRight;
     273      163387 :         SwClient* pL = pDepend->pLeft;
     274      163387 :         if( pRoot == pDepend )
     275      109379 :             pRoot = pL ? pL : pR;
     276             : 
     277      163387 :         if( pL )
     278       54008 :             pL->pRight = pR;
     279      163387 :         if( pR )
     280       58751 :             pR->pLeft = pL;
     281             : 
     282             :         // update ClientIters
     283      163387 :         SwClientIter* pTmp = pClientIters;
     284      363518 :         while( pTmp )
     285             :         {
     286       36744 :             if( pTmp->pAct == pDepend || pTmp->pDelNext == pDepend )
     287             :             {
     288             :                 // if object being removed is the current or next object in an
     289             :                 // iterator, advance this iterator
     290       31970 :                 pTmp->pDelNext = pR;
     291             :             }
     292       36744 :             pTmp = pTmp->pNxtIter;
     293             :         }
     294             : 
     295      163387 :         pDepend->pLeft = 0;
     296      163387 :         pDepend->pRight = 0;
     297             :     }
     298             :     else
     299             :     {
     300             :         OSL_FAIL( "SwModify::Remove(): could not find pDepend" );
     301             :     }
     302             : 
     303             :     // disconnect client from me
     304      163387 :     pDepend->pRegisteredIn = 0;
     305      163387 :     return pDepend;
     306             : }
     307             : 
     308       10177 : void SwModify::CheckCaching( const sal_uInt16 nWhich )
     309             : {
     310       10177 :     if( isCHRATR( nWhich ) )
     311             :     {
     312           0 :         SetInSwFntCache( sal_False );
     313             :     }
     314             :     else
     315             :     {
     316       10177 :         switch( nWhich )
     317             :         {
     318             :         case RES_OBJECTDYING:
     319             :         case RES_FMT_CHG:
     320             :         case RES_ATTRSET_CHG:
     321        4391 :             SetInSwFntCache( sal_False );
     322             : 
     323             :         case RES_UL_SPACE:
     324             :         case RES_LR_SPACE:
     325             :         case RES_BOX:
     326             :         case RES_SHADOW:
     327             :         case RES_FRM_SIZE:
     328             :         case RES_KEEP:
     329             :         case RES_BREAK:
     330        4423 :             if( IsInCache() )
     331             :             {
     332        3394 :                 SwFrm::GetCache().Delete( this );
     333        3394 :                 SetInCache( sal_False );
     334             :             }
     335        4423 :             break;
     336             :         }
     337             :     }
     338       10177 : }
     339             : 
     340         960 : void SwModify::CallSwClientNotify( const SfxHint& rHint ) const
     341             : {
     342         960 :     SwClientIter aIter(*this);
     343         960 :     SwClient* pClient = aIter.GoStart();
     344        2264 :     while( pClient )
     345             :     {
     346         344 :         pClient->SwClientNotify( *this, rHint );
     347         344 :         pClient = ++aIter;
     348         960 :     }
     349         960 : }
     350             : 
     351      123278 : void SwModify::ModifyBroadcast( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue, TypeId nType )
     352             : {
     353      123278 :     SwClientIter aIter( *this );
     354      123278 :     SwClient* pClient = aIter.First( nType );
     355      468310 :     while( pClient )
     356             :     {
     357      221754 :         pClient->Modify( pOldValue, pNewValue );
     358      221754 :         pClient = aIter.Next();
     359      123278 :     }
     360      123278 : }
     361             : 
     362             : // ----------
     363             : // SwDepend
     364             : // ----------
     365             : 
     366       29286 : SwDepend::SwDepend( SwClient* pTellHim, SwModify* pDepend )
     367       29286 :     : SwClient( pDepend )
     368             : {
     369       29286 :     pToTell  = pTellHim;
     370       29286 : }
     371             : 
     372         343 : void SwDepend::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     373             : {
     374         343 :     if( pNewValue && pNewValue->Which() == RES_OBJECTDYING )
     375          46 :         CheckRegistration(pOldValue,pNewValue);
     376         297 :     else if( pToTell )
     377         297 :         pToTell->ModifyNotification(pOldValue, pNewValue);
     378         343 : }
     379             : 
     380           0 : void SwDepend::SwClientNotify( const SwModify& rMod, const SfxHint& rHint )
     381             : {
     382           0 :     if ( pToTell )
     383           0 :         pToTell->SwClientNotifyCall( rMod, rHint );
     384           0 : }
     385             : 
     386           0 : bool SwDepend::GetInfo( SfxPoolItem& rInfo ) const
     387             : {
     388           0 :     return pToTell ? pToTell->GetInfo( rInfo ) : true;
     389             : }
     390             : 
     391             : // ------------
     392             : // SwClientIter
     393             : // ------------
     394             : 
     395      468917 : SwClientIter::SwClientIter( const SwModify& rModify )
     396      468917 :     : rRoot( rModify )
     397             : {
     398      468917 :     pNxtIter = 0;
     399      468917 :     if( pClientIters )
     400             :     {
     401             :         // append to list of ClientIters
     402       62486 :         SwClientIter* pTmp = pClientIters;
     403      159918 :         while( pTmp->pNxtIter )
     404       34946 :             pTmp = pTmp->pNxtIter;
     405       62486 :         pTmp->pNxtIter = this;
     406             :     }
     407             :     else
     408      406431 :         pClientIters = this;
     409             : 
     410      468917 :     pAct = const_cast<SwClient*>(rRoot.GetDepends());
     411      468917 :     pDelNext = pAct;
     412      468917 : }
     413             : 
     414             : 
     415             : 
     416      468917 : SwClientIter::~SwClientIter()
     417             : {
     418      468917 :     if( pClientIters )
     419             :     {
     420             :         // reorganize list of ClientIters
     421      468917 :         if( pClientIters == this )
     422      406431 :             pClientIters = pNxtIter;
     423             :         else
     424             :         {
     425       62486 :             SwClientIter* pTmp = pClientIters;
     426      159918 :             while( pTmp->pNxtIter != this )
     427       34946 :                 if( 0 == ( pTmp = pTmp->pNxtIter ) )
     428             :                 {
     429             :                     OSL_ENSURE( this, "Lost my pointer" );
     430           0 :                     return ;
     431             :                 }
     432       62486 :             pTmp->pNxtIter = pNxtIter;
     433             :         }
     434             :     }
     435      468917 : }
     436             : 
     437       32617 : SwClient* SwClientIter::operator++()
     438             : {
     439       32617 :     if( pDelNext == pAct )
     440             :     {
     441       32595 :         pAct = pAct->pRight;
     442       32595 :         pDelNext = pAct;
     443             :     }
     444             :     else
     445          22 :         pAct = pDelNext;
     446       32617 :     return pAct;
     447             : }
     448             : 
     449      468727 : SwClient* SwClientIter::GoStart()
     450             : {
     451      468727 :     pAct = const_cast<SwClient*>(rRoot.GetDepends());
     452      468727 :     if( pAct )
     453             :     {
     454      894560 :         while( pAct->pLeft )
     455           0 :             pAct = pAct->pLeft;
     456             :     }
     457      468727 :     pDelNext = pAct;
     458      468727 :     return pAct;
     459             : }
     460             : 
     461         148 : SwClient* SwClientIter::GoEnd()
     462             : {
     463         148 :     pAct = pDelNext;
     464         148 :     if( !pAct )
     465         148 :         pAct = const_cast<SwClient*>(rRoot.GetDepends());
     466         148 :     if( pAct )
     467             :     {
     468           0 :         while( pAct->pRight )
     469           0 :             pAct = pAct->pRight;
     470             :     }
     471         148 :     pDelNext = pAct;
     472         148 :     return pAct;
     473             : }
     474             : 
     475      415517 : SwClient* SwClientIter::First( TypeId nType )
     476             : {
     477      415517 :     aSrchId = nType;
     478      415517 :     GoStart();
     479      415517 :     if( pAct )
     480       78477 :         do {
     481      466642 :             if( pAct->IsA( aSrchId ) )
     482      388165 :                 break;
     483             : 
     484       78477 :             if( pDelNext == pAct )
     485             :             {
     486       78477 :                 pAct = pAct->pRight;
     487       78477 :                 pDelNext = pAct;
     488             :             }
     489             :             else
     490           0 :                 pAct = pDelNext;
     491             :         } while( pAct );
     492      415517 :     return pAct;
     493             : }
     494             : 
     495         148 : SwClient* SwClientIter::Last( TypeId nType )
     496             : {
     497         148 :     aSrchId = nType;
     498         148 :     GoEnd();
     499         148 :     if( pAct )
     500           0 :         do {
     501           0 :             if( pAct->IsA( aSrchId ) )
     502           0 :                 break;
     503             : 
     504           0 :             if( pDelNext == pAct )
     505           0 :                 pAct = pAct->pLeft;
     506             :             else
     507           0 :                 pAct = pDelNext->pLeft;
     508           0 :             pDelNext = pAct;
     509             :         } while( pAct );
     510         148 :     return pAct;
     511             : }
     512             : 
     513      384092 : SwClient* SwClientIter::Next()
     514             : {
     515      251823 :     do {
     516      384092 :         if( pDelNext == pAct )
     517             :         {
     518      352153 :             pAct = pAct->pRight;
     519      352153 :             pDelNext = pAct;
     520             :         }
     521             :         else
     522       31939 :             pAct = pDelNext;
     523             : 
     524      384092 :         if( pAct && pAct->IsA( aSrchId ) )
     525      132269 :             break;
     526             :     } while( pAct );
     527      309214 :     return pAct;
     528             : }
     529             : 
     530           0 : SwClient* SwClientIter::Previous()
     531             : {
     532           0 :     do {
     533           0 :         if( pDelNext == pAct )
     534           0 :             pAct = pAct->pLeft;
     535             :         else
     536           0 :             pAct = pDelNext->pLeft;
     537           0 :         pDelNext = pAct;
     538             : 
     539           0 :         if( pAct && pAct->IsA( aSrchId ) )
     540           0 :             break;
     541             :     } while( pAct );
     542           0 :     return pAct;
     543          99 : }
     544             : 
     545             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10