LCOV - code coverage report
Current view: top level - sw/source/core/attr - calbck.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 254 0.0 %
Date: 2014-04-14 Functions: 0 37 0.0 %
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           0 : TYPEINIT0( SwClient );
      29             : 
      30             : // SwClient
      31             : 
      32           0 : SwClient::SwClient( SwModify* pToRegisterIn )
      33           0 :     : pLeft( 0 ), pRight( 0 ), pRegisteredIn( 0 ), mbIsAllowedToBeRemovedInModifyCall( false )
      34             : {
      35           0 :     if(pToRegisterIn)
      36             :         // connect to SwModify
      37           0 :         pToRegisterIn->Add(this);
      38           0 : }
      39             : 
      40           0 : void SwClient::CheckRegistration( const SfxPoolItem* pOld, const SfxPoolItem* )
      41             : {
      42             :     // this method only handles notification about dying SwModify objects
      43           0 :     if( (!pOld || pOld->Which() != RES_OBJECTDYING) )
      44           0 :         return;
      45             : 
      46           0 :     const SwPtrMsgPoolItem* pDead = static_cast<const SwPtrMsgPoolItem*>(pOld);
      47           0 :     if(pDead && pDead->pObject == pRegisteredIn)
      48             :     {
      49             :         // I've got a notification from the object I know
      50           0 :         SwModify* pAbove = const_cast<SwModify*>(pRegisteredIn->GetRegisteredIn());
      51           0 :         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           0 :             pAbove->Add(this);
      56           0 :             return;
      57             :         }
      58             :         // destroy connection
      59           0 :         pRegisteredIn->Remove(this);
      60             :     }
      61             : }
      62             : 
      63           0 : void SwClient::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
      64             : {
      65           0 :     CheckRegistration( pOldValue, pNewValue );
      66           0 : }
      67             : 
      68           0 : void SwClient::SwClientNotify( const SwModify&, const SfxHint& )
      69             : {
      70           0 : }
      71             : 
      72           0 : SwClient::~SwClient()
      73             : {
      74             :     OSL_ENSURE( !pRegisteredIn || pRegisteredIn->GetDepends(), "SwModify still known, but Client already disconnected!" );
      75           0 :     if( pRegisteredIn && pRegisteredIn->GetDepends() )
      76             :         // still connected
      77           0 :         pRegisteredIn->Remove( this );
      78           0 : }
      79             : 
      80           0 : bool SwClient::GetInfo( SfxPoolItem& ) const
      81             : {
      82           0 :     return true;
      83             : }
      84             : 
      85             : // SwModify
      86             : 
      87           0 : SwModify::SwModify()
      88           0 :     : SwClient(0), pRoot(0)
      89             : {
      90           0 :     bModifyLocked = false;
      91           0 :     bLockClientList = sal_False;
      92           0 :     bInDocDTOR = sal_False;
      93           0 :     bInCache = sal_False;
      94           0 :     bInSwFntCache = sal_False;
      95           0 : }
      96             : 
      97           0 : SwModify::SwModify( SwModify* pToRegisterIn )
      98           0 :     : SwClient( pToRegisterIn ), pRoot( 0 )
      99             : {
     100           0 :     bModifyLocked = false;
     101           0 :     bLockClientList = sal_False;
     102           0 :     bInDocDTOR = sal_False;
     103           0 :     bInCache = sal_False;
     104           0 :     bInSwFntCache = sal_False;
     105           0 : }
     106             : 
     107           0 : SwModify::~SwModify()
     108             : {
     109             :     OSL_ENSURE( !IsModifyLocked(), "Modify destroyed but locked." );
     110             : 
     111           0 :     if ( IsInCache() )
     112           0 :         SwFrm::GetCache().Delete( this );
     113             : 
     114           0 :     if ( IsInSwFntCache() )
     115           0 :         pSwFontCache->Delete( this );
     116             : 
     117           0 :     if( pRoot )
     118             :     {
     119             :         // there are depending objects
     120           0 :         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           0 :             SwClientIter aIter( *this );
     126           0 :             SwClient* p = aIter.GoStart();
     127           0 :             while ( p )
     128             :             {
     129           0 :                 p->pRegisteredIn = 0;
     130           0 :                 p = ++aIter;
     131           0 :             }
     132             :         }
     133             :         else
     134             :         {
     135             :             // notify all clients that they shall remove themselves
     136           0 :             SwPtrMsgPoolItem aDyObject( RES_OBJECTDYING, this );
     137           0 :             NotifyClients( &aDyObject, &aDyObject );
     138             : 
     139             :             // remove all clients that have not done themselves
     140             :             // mba: possibly a hotfix for forgotten base class calls?!
     141           0 :             while( pRoot )
     142           0 :                 pRoot->CheckRegistration( &aDyObject, &aDyObject );
     143             :         }
     144             :     }
     145           0 : }
     146             : 
     147           0 : void SwModify::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     148             : {
     149           0 :     NotifyClients( pOldValue, pNewValue );
     150           0 : }
     151             : 
     152           0 : void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     153             : {
     154           0 :     if ( IsInCache() || IsInSwFntCache() )
     155             :     {
     156             :         const sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
     157           0 :                                         pNewValue ? pNewValue->Which() : 0;
     158           0 :         CheckCaching( nWhich );
     159             :     }
     160             : 
     161           0 :     if ( !pRoot || IsModifyLocked() )
     162           0 :         return;
     163             : 
     164           0 :     LockModify();
     165             : 
     166             :     // mba: WTF?!
     167           0 :     if( !pOldValue )
     168             :     {
     169           0 :         bLockClientList = sal_True;
     170             :     }
     171             :     else
     172             :     {
     173           0 :         switch( pOldValue->Which() )
     174             :         {
     175             :         case RES_OBJECTDYING:
     176             :         case RES_REMOVE_UNO_OBJECT:
     177           0 :             bLockClientList = ((SwPtrMsgPoolItem*)pOldValue)->pObject != this;
     178           0 :             break;
     179             : 
     180             :         case RES_FOOTNOTE_DELETED:
     181             :         case RES_REFMARK_DELETED:
     182             :         case RES_TOXMARK_DELETED:
     183             :         case RES_FIELD_DELETED:
     184           0 :             bLockClientList = sal_False;
     185           0 :             break;
     186             : 
     187             :         default:
     188           0 :             bLockClientList = sal_True;
     189             :         }
     190             :     }
     191             : 
     192           0 :     ModifyBroadcast( pOldValue, pNewValue );
     193           0 :     bLockClientList = sal_False;
     194           0 :     UnlockModify();
     195             : }
     196             : 
     197           0 : bool SwModify::GetInfo( SfxPoolItem& rInfo ) const
     198             : {
     199           0 :     bool bRet = true;       // means: continue with next
     200             : 
     201           0 :     if( pRoot )
     202             :     {
     203           0 :         SwClientIter aIter( *(SwModify*)this );
     204             : 
     205           0 :         SwClient* pLast = aIter.GoStart();
     206           0 :         if( pLast )
     207             :         {
     208           0 :             while( ( bRet = pLast->GetInfo( rInfo ) ) &&
     209             :                    0 != ( pLast = ++aIter ) )
     210             :                 ;
     211           0 :         }
     212             :     }
     213             : 
     214           0 :     return bRet;
     215             : }
     216             : 
     217           0 : void SwModify::Add( SwClient* pDepend )
     218             : {
     219             :     OSL_ENSURE( !bLockClientList, "Client inserted while in Modify" );
     220             : 
     221           0 :     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           0 :         if( pDepend->pRegisteredIn != 0 )
     233           0 :             pDepend->pRegisteredIn->Remove( pDepend );
     234             : 
     235           0 :         if( !pRoot )
     236             :         {
     237             :             // first client added
     238           0 :             pRoot = pDepend;
     239           0 :             pRoot->pLeft = 0;
     240           0 :             pRoot->pRight = 0;
     241             :         }
     242             :         else
     243             :         {
     244             :             // append client
     245           0 :             pDepend->pRight = pRoot->pRight;
     246           0 :             pRoot->pRight = pDepend;
     247           0 :             pDepend->pLeft = pRoot;
     248           0 :             if( pDepend->pRight )
     249           0 :                 pDepend->pRight->pLeft = pDepend;
     250             :         }
     251             : 
     252             :         // connect client to me
     253           0 :         pDepend->pRegisteredIn = this;
     254             :     }
     255           0 : }
     256             : 
     257           0 : SwClient* SwModify::Remove( SwClient* pDepend )
     258             : {
     259           0 :     if ( bInDocDTOR )
     260           0 :         return 0;
     261             : 
     262             :     OSL_ENSURE( !bLockClientList || pDepend->mbIsAllowedToBeRemovedInModifyCall, "SwClient shall be removed in Modify call!" );
     263             : 
     264           0 :     if( pDepend->pRegisteredIn == this )
     265             :     {
     266             :         // SwClient is my listener
     267             :         // remove it from my list
     268           0 :         SwClient* pR = pDepend->pRight;
     269           0 :         SwClient* pL = pDepend->pLeft;
     270           0 :         if( pRoot == pDepend )
     271           0 :             pRoot = pL ? pL : pR;
     272             : 
     273           0 :         if( pL )
     274           0 :             pL->pRight = pR;
     275           0 :         if( pR )
     276           0 :             pR->pLeft = pL;
     277             : 
     278             :         // update ClientIters
     279           0 :         SwClientIter* pTmp = pClientIters;
     280           0 :         while( pTmp )
     281             :         {
     282           0 :             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           0 :                 pTmp->pDelNext = pR;
     287             :             }
     288           0 :             pTmp = pTmp->pNxtIter;
     289             :         }
     290             : 
     291           0 :         pDepend->pLeft = 0;
     292           0 :         pDepend->pRight = 0;
     293             :     }
     294             :     else
     295             :     {
     296             :         OSL_FAIL( "SwModify::Remove(): could not find pDepend" );
     297             :     }
     298             : 
     299             :     // disconnect client from me
     300           0 :     pDepend->pRegisteredIn = 0;
     301           0 :     return pDepend;
     302             : }
     303             : 
     304           0 : void SwModify::CheckCaching( const sal_uInt16 nWhich )
     305             : {
     306           0 :     if( isCHRATR( nWhich ) )
     307             :     {
     308           0 :         SetInSwFntCache( sal_False );
     309             :     }
     310             :     else
     311             :     {
     312           0 :         switch( nWhich )
     313             :         {
     314             :         case RES_OBJECTDYING:
     315             :         case RES_FMT_CHG:
     316             :         case RES_ATTRSET_CHG:
     317           0 :             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           0 :             if( IsInCache() )
     327             :             {
     328           0 :                 SwFrm::GetCache().Delete( this );
     329           0 :                 SetInCache( sal_False );
     330             :             }
     331           0 :             break;
     332             :         }
     333             :     }
     334           0 : }
     335             : 
     336           0 : void SwModify::CallSwClientNotify( const SfxHint& rHint ) const
     337             : {
     338           0 :     SwClientIter aIter(*this);
     339           0 :     SwClient* pClient = aIter.GoStart();
     340           0 :     while( pClient )
     341             :     {
     342           0 :         pClient->SwClientNotify( *this, rHint );
     343           0 :         pClient = ++aIter;
     344           0 :     }
     345           0 : }
     346             : 
     347           0 : void SwModify::ModifyBroadcast( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue, TypeId nType )
     348             : {
     349           0 :     SwClientIter aIter( *this );
     350           0 :     SwClient* pClient = aIter.First( nType );
     351           0 :     while( pClient )
     352             :     {
     353           0 :         pClient->Modify( pOldValue, pNewValue );
     354           0 :         pClient = aIter.Next();
     355           0 :     }
     356           0 : }
     357             : 
     358             : // SwDepend
     359             : 
     360           0 : SwDepend::SwDepend( SwClient* pTellHim, SwModify* pDepend )
     361           0 :     : SwClient( pDepend )
     362             : {
     363           0 :     pToTell  = pTellHim;
     364           0 : }
     365             : 
     366           0 : void SwDepend::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     367             : {
     368           0 :     if( pNewValue && pNewValue->Which() == RES_OBJECTDYING )
     369           0 :         CheckRegistration(pOldValue,pNewValue);
     370           0 :     else if( pToTell )
     371           0 :         pToTell->ModifyNotification(pOldValue, pNewValue);
     372           0 : }
     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           0 : SwClientIter::SwClientIter( const SwModify& rModify )
     388             :     : rRoot(rModify)
     389             :     , pNxtIter(NULL)
     390           0 :     , aSrchId(0)
     391             : {
     392           0 :     if( pClientIters )
     393             :     {
     394             :         // append to list of ClientIters
     395           0 :         SwClientIter* pTmp = pClientIters;
     396           0 :         while( pTmp->pNxtIter )
     397           0 :             pTmp = pTmp->pNxtIter;
     398           0 :         pTmp->pNxtIter = this;
     399             :     }
     400             :     else
     401           0 :         pClientIters = this;
     402             : 
     403           0 :     pAct = const_cast<SwClient*>(rRoot.GetDepends());
     404           0 :     pDelNext = pAct;
     405           0 : }
     406             : 
     407           0 : SwClientIter::~SwClientIter()
     408             : {
     409           0 :     if( pClientIters )
     410             :     {
     411             :         // reorganize list of ClientIters
     412           0 :         if( pClientIters == this )
     413           0 :             pClientIters = pNxtIter;
     414             :         else
     415             :         {
     416           0 :             SwClientIter* pTmp = pClientIters;
     417           0 :             while( pTmp->pNxtIter != this )
     418           0 :                 if( 0 == ( pTmp = pTmp->pNxtIter ) )
     419             :                 {
     420             :                     OSL_ENSURE( this, "Lost my pointer" );
     421           0 :                     return ;
     422             :                 }
     423           0 :             pTmp->pNxtIter = pNxtIter;
     424             :         }
     425             :     }
     426           0 : }
     427             : 
     428           0 : SwClient* SwClientIter::operator++()
     429             : {
     430           0 :     if( pDelNext == pAct )
     431             :     {
     432           0 :         pAct = pAct->pRight;
     433           0 :         pDelNext = pAct;
     434             :     }
     435             :     else
     436           0 :         pAct = pDelNext;
     437           0 :     return pAct;
     438             : }
     439             : 
     440           0 : SwClient* SwClientIter::GoStart()
     441             : {
     442           0 :     pAct = const_cast<SwClient*>(rRoot.GetDepends());
     443           0 :     if( pAct )
     444             :     {
     445           0 :         while( pAct->pLeft )
     446           0 :             pAct = pAct->pLeft;
     447             :     }
     448           0 :     pDelNext = pAct;
     449           0 :     return pAct;
     450             : }
     451             : 
     452           0 : SwClient* SwClientIter::GoEnd()
     453             : {
     454           0 :     pAct = pDelNext;
     455           0 :     if( !pAct )
     456           0 :         pAct = const_cast<SwClient*>(rRoot.GetDepends());
     457           0 :     if( pAct )
     458             :     {
     459           0 :         while( pAct->pRight )
     460           0 :             pAct = pAct->pRight;
     461             :     }
     462           0 :     pDelNext = pAct;
     463           0 :     return pAct;
     464             : }
     465             : 
     466           0 : SwClient* SwClientIter::First( TypeId nType )
     467             : {
     468           0 :     aSrchId = nType;
     469           0 :     GoStart();
     470           0 :     if( pAct )
     471           0 :         do {
     472           0 :             if( pAct->IsA( aSrchId ) )
     473           0 :                 break;
     474             : 
     475           0 :             if( pDelNext == pAct )
     476             :             {
     477           0 :                 pAct = pAct->pRight;
     478           0 :                 pDelNext = pAct;
     479             :             }
     480             :             else
     481           0 :                 pAct = pDelNext;
     482             :         } while( pAct );
     483           0 :     return pAct;
     484             : }
     485             : 
     486           0 : SwClient* SwClientIter::Last( TypeId nType )
     487             : {
     488           0 :     aSrchId = nType;
     489           0 :     GoEnd();
     490           0 :     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           0 :     return pAct;
     502             : }
     503             : 
     504           0 : SwClient* SwClientIter::Next()
     505             : {
     506           0 :     do {
     507           0 :         if( pDelNext == pAct )
     508             :         {
     509           0 :             pAct = pAct->pRight;
     510           0 :             pDelNext = pAct;
     511             :         }
     512             :         else
     513           0 :             pAct = pDelNext;
     514             : 
     515           0 :         if( pAct && pAct->IsA( aSrchId ) )
     516           0 :             break;
     517             :     } while( pAct );
     518           0 :     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