LCOV - code coverage report
Current view: top level - sw/source/core/doc - docsort.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 332 446 74.4 %
Date: 2012-08-25 Functions: 30 33 90.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 322 776 41.5 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <boost/ptr_container/ptr_set.hpp>
      30                 :            : 
      31                 :            : #include <hintids.hxx>
      32                 :            : #include <rtl/math.hxx>
      33                 :            : #include <unotools/collatorwrapper.hxx>
      34                 :            : #include <unotools/localedatawrapper.hxx>
      35                 :            : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      36                 :            : #include <com/sun/star/i18n/CollatorOptions.hpp>
      37                 :            : #include <comphelper/processfactory.hxx>
      38                 :            : #include <editeng/unolingu.hxx>
      39                 :            : #include <docary.hxx>
      40                 :            : #include <fmtanchr.hxx>
      41                 :            : #include <frmfmt.hxx>
      42                 :            : #include <doc.hxx>
      43                 :            : #include <IDocumentUndoRedo.hxx>
      44                 :            : #include <node.hxx>
      45                 :            : #include <pam.hxx>
      46                 :            : #include <ndtxt.hxx>
      47                 :            : #include <swtable.hxx>
      48                 :            : #include <swundo.hxx>
      49                 :            : #include <sortopt.hxx>
      50                 :            : #include <docsort.hxx>
      51                 :            : #include <UndoSort.hxx>
      52                 :            : #include <UndoRedline.hxx>
      53                 :            : #include <hints.hxx>
      54                 :            : #include <tblsel.hxx>
      55                 :            : #include <cellatr.hxx>
      56                 :            : #include <redline.hxx>
      57                 :            : #include <node2lay.hxx>
      58                 :            : #include <unochart.hxx>
      59                 :            : 
      60                 :            : using namespace ::com::sun::star::lang;
      61                 :            : using namespace ::com::sun::star;
      62                 :            : 
      63                 :            : SwSortOptions*      SwSortElement::pOptions = 0;
      64                 :            : SwDoc*              SwSortElement::pDoc = 0;
      65                 :            : const FlatFndBox*   SwSortElement::pBox = 0;
      66                 :            : CollatorWrapper*    SwSortElement::pSortCollator = 0;
      67                 :            : lang::Locale*             SwSortElement::pLocale = 0;
      68                 :            : String*             SwSortElement::pLastAlgorithm = 0;
      69                 :            : LocaleDataWrapper*  SwSortElement::pLclData = 0;
      70                 :            : 
      71                 :            : // List of all sorted elements
      72                 :            : typedef SwSortElement*      SwSortElementPtr;
      73                 :            : 
      74                 :            : typedef ::boost::ptr_multiset<SwSortTxtElement> SwSortTxtElements;
      75                 :            : typedef ::boost::ptr_multiset<SwSortBoxElement> SwSortBoxElements;
      76                 :            : 
      77                 :            : /*--------------------------------------------------------------------
      78                 :            :     Description: Construct a SortElement for the Sort
      79                 :            :  --------------------------------------------------------------------*/
      80                 :         16 : void SwSortElement::Init( SwDoc* pD, const SwSortOptions& rOpt,
      81                 :            :                             FlatFndBox* pFltBx )
      82                 :            : {
      83                 :            :     OSL_ENSURE( !pDoc && !pOptions && !pBox, "Who forgot to call Finit?" );
      84                 :         16 :     pDoc = pD;
      85         [ +  - ]:         16 :     pOptions = new SwSortOptions( rOpt );
      86                 :         16 :     pBox = pFltBx;
      87                 :            : 
      88                 :         16 :     LanguageType nLang = rOpt.nLanguage;
      89         [ -  + ]:         16 :     switch ( nLang )
      90                 :            :     {
      91                 :            :     case LANGUAGE_NONE:
      92                 :            :     case LANGUAGE_DONTKNOW:
      93                 :          0 :         nLang = (LanguageType)GetAppLanguage();
      94                 :          0 :         break;
      95                 :            :     }
      96         [ +  - ]:         16 :     pLocale = new lang::Locale( SvxCreateLocale( nLang ) );
      97                 :            : 
      98                 :            :     pSortCollator = new CollatorWrapper(
      99 [ +  - ][ +  - ]:         16 :                                 ::comphelper::getProcessServiceFactory() );
     100                 :         16 : }
     101                 :            : 
     102                 :         16 : void SwSortElement::Finit()
     103                 :            : {
     104         [ +  - ]:         16 :     delete pOptions, pOptions = 0;
     105         [ +  - ]:         16 :     delete pLocale, pLocale = 0;
     106         [ +  + ]:         16 :     delete pLastAlgorithm, pLastAlgorithm = 0;
     107         [ +  - ]:         16 :     delete pSortCollator, pSortCollator = 0;
     108         [ +  + ]:         16 :     delete pLclData, pLclData = 0;
     109                 :         16 :     pDoc = 0;
     110                 :         16 :     pBox = 0;
     111                 :         16 : }
     112                 :            : 
     113                 :        104 : SwSortElement::~SwSortElement()
     114                 :            : {
     115         [ -  + ]:        104 : }
     116                 :            : 
     117                 :        428 : double SwSortElement::StrToDouble( const String& rStr ) const
     118                 :            : {
     119         [ +  + ]:        428 :     if( !pLclData )
     120                 :            :         pLclData = new LocaleDataWrapper(
     121 [ +  - ][ +  - ]:          8 :                     ::comphelper::getProcessServiceFactory(), *pLocale );
                 [ +  - ]
     122                 :            : 
     123                 :            :     rtl_math_ConversionStatus eStatus;
     124                 :            :     sal_Int32 nEnd;
     125                 :            :     double nRet = ::rtl::math::stringToDouble( rStr,
     126         [ +  - ]:        428 :                                     pLclData->getNumDecimalSep()[0],
     127         [ +  - ]:        428 :                                     pLclData->getNumThousandSep()[0],
     128         [ +  - ]:        428 :                                     &eStatus, &nEnd );
     129                 :            : 
     130 [ +  + ][ +  - ]:        428 :     if( rtl_math_ConversionStatus_Ok != eStatus || nEnd == 0 )
     131                 :        362 :         nRet = 0.0;
     132                 :        428 :     return nRet;
     133                 :            : }
     134                 :            : 
     135                 :        384 : int SwSortElement::keycompare(const SwSortElement& rCmp, sal_uInt16 nKey) const
     136                 :            : {
     137                 :        384 :     int nCmp = 0;
     138                 :            :     // The actual comparison
     139                 :            :     const SwSortElement *pOrig, *pCmp;
     140                 :            : 
     141                 :        384 :     const SwSortKey* pSrtKey = pOptions->aKeys[ nKey ];
     142         [ +  + ]:        384 :     if( pSrtKey->eSortOrder == SRT_ASCENDING )
     143                 :        188 :         pOrig = this, pCmp = &rCmp;
     144                 :            :     else
     145                 :        196 :         pOrig = &rCmp, pCmp = this;
     146                 :            : 
     147         [ +  + ]:        384 :     if( pSrtKey->bIsNumeric )
     148                 :            :     {
     149                 :        246 :         double n1 = pOrig->GetValue( nKey );
     150                 :        246 :         double n2 = pCmp->GetValue( nKey );
     151                 :            : 
     152         [ +  + ]:        246 :         nCmp = n1 < n2 ? -1 : n1 == n2 ? 0 : 1;
     153                 :            :     }
     154                 :            :     else
     155                 :            :     {
     156 [ +  + ][ -  + ]:        138 :         if( !pLastAlgorithm || *pLastAlgorithm != pSrtKey->sSortType )
                 [ +  + ]
     157                 :            :         {
     158         [ -  + ]:          8 :             if( pLastAlgorithm )
     159                 :          0 :                 *pLastAlgorithm = pSrtKey->sSortType;
     160                 :            :             else
     161         [ +  - ]:          8 :                 pLastAlgorithm = new String( pSrtKey->sSortType );
     162                 :            :             pSortCollator->loadCollatorAlgorithm( *pLastAlgorithm,
     163                 :            :                     *pLocale,
     164 [ +  - ][ +  - ]:          8 :                     pOptions->bIgnoreCase ? SW_COLLATOR_IGNORES : 0 );
     165                 :            :         }
     166                 :            : 
     167                 :            :         nCmp = pSortCollator->compareString(
     168 [ +  - ][ +  - ]:        138 :                     pOrig->GetKey( nKey ), pCmp->GetKey( nKey ));
         [ +  - ][ +  - ]
                 [ +  - ]
     169                 :            :     }
     170                 :        384 :     return nCmp;
     171                 :            : }
     172                 :            : 
     173                 :            : /*--------------------------------------------------------------------
     174                 :            :     Description: Comparison operators
     175                 :            :  --------------------------------------------------------------------*/
     176                 :          0 : sal_Bool SwSortElement::operator==(const SwSortElement& ) const
     177                 :            : {
     178                 :          0 :     return sal_False;
     179                 :            : }
     180                 :            : 
     181                 :            : /*--------------------------------------------------------------------
     182                 :            :     Description: Less-than operator for sorting
     183                 :            :  --------------------------------------------------------------------*/
     184                 :        280 : sal_Bool SwSortElement::operator<(const SwSortElement& rCmp) const
     185                 :            : {
     186                 :            :     // The actual comparison
     187         [ +  + ]:        436 :     for(sal_uInt16 nKey = 0; nKey < pOptions->aKeys.size(); ++nKey)
     188                 :            :     {
     189                 :        384 :         int nCmp = keycompare(rCmp, nKey);
     190                 :            : 
     191         [ +  + ]:        384 :         if (nCmp == 0)
     192                 :        156 :             continue;
     193                 :            : 
     194                 :        228 :         return nCmp < 0;
     195                 :            :     }
     196                 :            : 
     197                 :        280 :     return sal_False;
     198                 :            : }
     199                 :            : 
     200                 :        428 : double SwSortElement::GetValue( sal_uInt16 nKey ) const
     201                 :            : {
     202         [ +  - ]:        428 :     return StrToDouble( GetKey( nKey ));
     203                 :            : }
     204                 :            : 
     205                 :            : /*--------------------------------------------------------------------
     206                 :            :     Description: SortingElement for Text
     207                 :            :  --------------------------------------------------------------------*/
     208                 :         56 : SwSortTxtElement::SwSortTxtElement(const SwNodeIndex& rPos)
     209         [ +  - ]:         56 :     : nOrg(rPos.GetIndex()), aPos(rPos)
     210                 :            : {
     211                 :         56 : }
     212                 :            : 
     213         [ +  - ]:         56 : SwSortTxtElement::~SwSortTxtElement()
     214                 :            : {
     215         [ -  + ]:        112 : }
     216                 :            : 
     217                 :            : /*--------------------------------------------------------------------
     218                 :            :     Description: Get Key
     219                 :            :  --------------------------------------------------------------------*/
     220                 :        440 : String SwSortTxtElement::GetKey(sal_uInt16 nId) const
     221                 :            : {
     222                 :        440 :     SwTxtNode* pTxtNd = aPos.GetNode().GetTxtNode();
     223         [ -  + ]:        440 :     if( !pTxtNd )
     224                 :          0 :         return aEmptyStr;
     225                 :            : 
     226                 :            :     // for TextNodes
     227                 :        440 :     const String& rStr = pTxtNd->GetTxt();
     228                 :            : 
     229                 :        440 :     sal_Unicode nDeli = pOptions->cDeli;
     230                 :        440 :     sal_uInt16 nDCount = pOptions->aKeys[nId]->nColumnId, i = 1;
     231                 :        440 :     xub_StrLen nStart = 0;
     232                 :            : 
     233                 :            :     // Find the delimiter
     234 [ +  - ][ -  + ]:        440 :     while( nStart != STRING_NOTFOUND && i < nDCount)
                 [ -  + ]
     235         [ #  # ]:          0 :         if( STRING_NOTFOUND != ( nStart = rStr.Search( nDeli, nStart ) ) )
     236                 :            :         {
     237                 :          0 :             nStart++;
     238                 :          0 :             i++;
     239                 :            :         }
     240                 :            : 
     241                 :            :     // Found next delimiter or end of String
     242                 :            :     // and copy
     243                 :        440 :     xub_StrLen nEnd = rStr.Search( nDeli, nStart+1 );
     244                 :        440 :     return rStr.Copy( nStart, nEnd-nStart );
     245                 :            : }
     246                 :            : 
     247                 :            : /*--------------------------------------------------------------------
     248                 :            :     Description: SortingElement for Tables
     249                 :            :  --------------------------------------------------------------------*/
     250                 :         48 : SwSortBoxElement::SwSortBoxElement( sal_uInt16 nRC )
     251                 :         48 :     : nRow( nRC )
     252                 :            : {
     253                 :         48 : }
     254                 :            : 
     255                 :         48 : SwSortBoxElement::~SwSortBoxElement()
     256                 :            : {
     257         [ -  + ]:         96 : }
     258                 :            : 
     259                 :            : /*--------------------------------------------------------------------
     260                 :            :     Description: Get Key for a cell
     261                 :            :  --------------------------------------------------------------------*/
     262                 :        264 : String SwSortBoxElement::GetKey(sal_uInt16 nKey) const
     263                 :            : {
     264                 :            :     const _FndBox* pFndBox;
     265                 :        264 :     sal_uInt16 nCol = pOptions->aKeys[nKey]->nColumnId-1;
     266                 :            : 
     267         [ +  - ]:        264 :     if( SRT_ROWS == pOptions->eDirection )
     268                 :        264 :         pFndBox = pBox->GetBox(nCol, nRow);         // Sort rows
     269                 :            :     else
     270                 :          0 :         pFndBox = pBox->GetBox(nRow, nCol);         // Sort columns
     271                 :            : 
     272                 :            :     // Extract the Text
     273                 :        264 :     String aRetStr;
     274         [ +  - ]:        264 :     if( pFndBox )
     275                 :            :     {   // Get StartNode and skip it
     276                 :        264 :         const SwTableBox* pMyBox = pFndBox->GetBox();
     277                 :            :         OSL_ENSURE(pMyBox, "No atomic Box");
     278                 :            : 
     279         [ +  - ]:        264 :         if( pMyBox->GetSttNd() )
     280                 :            :         {
     281                 :            :             // Iterate over all the Box's TextNodes
     282                 :        264 :             const SwNode *pNd = 0, *pEndNd = pMyBox->GetSttNd()->EndOfSectionNode();
     283 [ +  + ][ +  - ]:        792 :             for( sal_uLong nIdx = pMyBox->GetSttIdx() + 1; pNd != pEndNd; ++nIdx )
     284 [ +  - ][ +  - ]:        528 :                 if( ( pNd = pDoc->GetNodes()[ nIdx ])->IsTxtNode() )
                 [ +  + ]
     285 [ +  - ][ +  - ]:        264 :                     aRetStr += ((SwTxtNode*)pNd)->GetTxt();
     286                 :            :         }
     287                 :            :     }
     288                 :        264 :     return aRetStr;
     289                 :            : }
     290                 :            : 
     291                 :        208 : double SwSortBoxElement::GetValue( sal_uInt16 nKey ) const
     292                 :            : {
     293                 :            :     const _FndBox* pFndBox;
     294                 :        208 :     sal_uInt16 nCol = pOptions->aKeys[nKey]->nColumnId-1;
     295                 :            : 
     296         [ +  - ]:        208 :     if( SRT_ROWS == pOptions->eDirection )
     297                 :        208 :         pFndBox = pBox->GetBox(nCol, nRow);         // Sort rows
     298                 :            :     else
     299                 :          0 :         pFndBox = pBox->GetBox(nRow, nCol);         // Sort columns
     300                 :            : 
     301                 :            : 
     302                 :            :     double nVal;
     303         [ +  - ]:        208 :     if( pFndBox )
     304                 :            :     {
     305                 :        208 :         const SwFmt *pFmt = pFndBox->GetBox()->GetFrmFmt();
     306         [ +  + ]:        208 :         if (pFmt->GetTblBoxNumFmt().GetValue() & NUMBERFORMAT_TEXT)
     307                 :        144 :             nVal = SwSortElement::GetValue( nKey );
     308                 :            :         else
     309                 :         64 :             nVal = pFmt->GetTblBoxValue().GetValue();
     310                 :            :     }
     311                 :            :     else
     312                 :          0 :         nVal = 0;
     313                 :            : 
     314                 :        208 :     return nVal;
     315                 :            : }
     316                 :            : 
     317                 :            : /*--------------------------------------------------------------------
     318                 :            :     Description: Sort Text in the Document
     319                 :            :  --------------------------------------------------------------------*/
     320                 :          8 : sal_Bool SwDoc::SortText(const SwPaM& rPaM, const SwSortOptions& rOpt)
     321                 :            : {
     322                 :            :     // Check if Frame is in the Text
     323 [ +  - ][ +  - ]:          8 :     const SwPosition *pStart = rPaM.Start(), *pEnd = rPaM.End();
     324                 :            : 
     325                 :            :     // Set index to the Selection's start
     326         [ -  + ]:          8 :     for ( sal_uInt16 n = 0; n < GetSpzFrmFmts()->size(); ++n )
     327                 :            :     {
     328                 :          0 :         SwFrmFmt *const pFmt = static_cast<SwFrmFmt*>((*GetSpzFrmFmts())[n]);
     329         [ #  # ]:          0 :         SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
     330         [ #  # ]:          0 :         SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
     331                 :            : 
     332 [ #  # ][ #  #  :          0 :         if (pAPos && (FLY_AT_PARA == pAnchor->GetAnchorId()) &&
             #  #  #  # ]
                 [ #  # ]
     333                 :          0 :             pStart->nNode <= pAPos->nNode && pAPos->nNode <= pEnd->nNode )
     334                 :          0 :             return sal_False;
     335                 :            :     }
     336                 :            : 
     337                 :            :     // Check if only TextNodes are within the Selection
     338                 :            :     {
     339                 :          8 :         sal_uLong nStart = pStart->nNode.GetIndex(),
     340                 :          8 :                         nEnd = pEnd->nNode.GetIndex();
     341         [ +  + ]:         64 :         while( nStart <= nEnd )
     342                 :            :             // Iterate over a selected Area
     343 [ +  - ][ +  - ]:         56 :             if( !GetNodes()[ nStart++ ]->IsTxtNode() )
                 [ -  + ]
     344                 :          0 :                 return sal_False;
     345                 :            :     }
     346                 :            : 
     347 [ +  - ][ +  - ]:          8 :     bool const bUndo = GetIDocumentUndoRedo().DoesUndo();
     348         [ +  - ]:          8 :     if( bUndo )
     349                 :            :     {
     350 [ +  - ][ +  - ]:          8 :         GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
     351                 :            :     }
     352                 :            : 
     353                 :          8 :     SwPaM* pRedlPam = 0;
     354                 :          8 :     SwUndoRedlineSort* pRedlUndo = 0;
     355                 :          8 :     SwUndoSort* pUndoSort = 0;
     356                 :            : 
     357 [ +  - ][ +  - ]:          8 :     if( IsRedlineOn() || (!IsIgnoreRedline() && !pRedlineTbl->empty() ))
         [ +  - ][ +  - ]
         [ -  + ][ -  + ]
     358                 :            :     {
     359 [ #  # ][ #  # ]:          0 :         pRedlPam = new SwPaM( pStart->nNode, pEnd->nNode, -1, 1 );
     360                 :          0 :         SwCntntNode* pCNd = pRedlPam->GetCntntNode( sal_False );
     361         [ #  # ]:          0 :         if( pCNd )
     362 [ #  # ][ #  # ]:          0 :             pRedlPam->GetMark()->nContent = pCNd->Len();
     363                 :            : 
     364 [ #  # ][ #  # ]:          0 :         if( IsRedlineOn() && !IsShowOriginal( GetRedlineMode() ) )
         [ #  # ][ #  # ]
                 [ #  # ]
     365                 :            :         {
     366         [ #  # ]:          0 :             if( bUndo )
     367                 :            :             {
     368 [ #  # ][ #  # ]:          0 :                 pRedlUndo = new SwUndoRedlineSort( *pRedlPam,rOpt );
     369 [ #  # ][ #  # ]:          0 :                 GetIDocumentUndoRedo().DoUndo(false);
     370                 :            :             }
     371                 :            :             // First copy the area
     372         [ #  # ]:          0 :             SwNodeIndex aEndIdx( pEnd->nNode, 1 );
     373         [ #  # ]:          0 :             SwNodeRange aRg( pStart->nNode, aEndIdx );
     374 [ #  # ][ #  # ]:          0 :             GetNodes()._Copy( aRg, aEndIdx );
     375                 :            : 
     376                 :            :             // Area is new from pEnd->nNode+1 to aEndIdx
     377         [ #  # ]:          0 :             DeleteRedline( *pRedlPam, true, USHRT_MAX );
     378                 :            : 
     379         [ #  # ]:          0 :             pRedlPam->GetMark()->nNode.Assign( pEnd->nNode.GetNode(), 1 );
     380                 :          0 :             pCNd = pRedlPam->GetCntntNode( sal_False );
     381 [ #  # ][ #  # ]:          0 :             pRedlPam->GetMark()->nContent.Assign( pCNd, 0 );
     382                 :            : 
     383         [ #  # ]:          0 :             pRedlPam->GetPoint()->nNode.Assign( aEndIdx.GetNode() );
     384                 :          0 :             pCNd = pRedlPam->GetCntntNode( sal_True );
     385                 :          0 :             xub_StrLen nCLen = 0;
     386 [ #  # ][ #  # ]:          0 :             if( !pCNd &&
                 [ #  # ]
     387 [ #  # ][ #  # ]:          0 :                 0 != (pCNd = GetNodes()[ aEndIdx.GetIndex()-1 ]->GetCntntNode()))
     388                 :            :             {
     389         [ #  # ]:          0 :                 nCLen = pCNd->Len();
     390         [ #  # ]:          0 :                 pRedlPam->GetPoint()->nNode.Assign( *pCNd );
     391                 :            :             }
     392 [ #  # ][ #  # ]:          0 :             pRedlPam->GetPoint()->nContent.Assign( pCNd, nCLen );
     393                 :            : 
     394         [ #  # ]:          0 :             if( pRedlUndo )
     395 [ #  # ][ #  # ]:          0 :                 pRedlUndo->SetValues( rPaM );
                 [ #  # ]
     396                 :            :         }
     397                 :            :         else
     398                 :            :         {
     399         [ #  # ]:          0 :             DeleteRedline( *pRedlPam, true, USHRT_MAX );
     400 [ #  # ][ #  # ]:          0 :             delete pRedlPam, pRedlPam = 0;
     401                 :            :         }
     402                 :            :     }
     403                 :            : 
     404         [ +  - ]:          8 :     SwNodeIndex aStart(pStart->nNode);
     405         [ +  - ]:          8 :     SwSortElement::Init( this, rOpt );
     406         [ +  - ]:          8 :     SwSortTxtElements aSortSet;
     407         [ +  + ]:         64 :     while( aStart <= pEnd->nNode )
     408                 :            :     {
     409                 :            :         // Iterate over a selected Area
     410 [ +  - ][ +  - ]:         56 :         SwSortTxtElement* pSE = new SwSortTxtElement( aStart );
     411         [ +  - ]:         56 :         aSortSet.insert(pSE);
     412         [ +  - ]:         56 :         aStart++;
     413                 :            :     }
     414                 :            : 
     415                 :            :     // Now comes the tricky part: Move Nodes (and always keep Undo in mind)
     416                 :          8 :     sal_uLong nBeg = pStart->nNode.GetIndex();
     417         [ +  - ]:          8 :     SwNodeRange aRg( aStart, aStart );
     418                 :            : 
     419 [ +  - ][ +  - ]:          8 :     if( bUndo && !pRedlUndo )
     420                 :            :     {
     421 [ +  - ][ +  - ]:          8 :         pUndoSort = new SwUndoSort(rPaM, rOpt);
     422 [ +  - ][ +  - ]:          8 :         GetIDocumentUndoRedo().AppendUndo(pUndoSort);
     423                 :            :     }
     424                 :            : 
     425 [ +  - ][ +  - ]:          8 :     GetIDocumentUndoRedo().DoUndo(false);
     426                 :            : 
     427                 :          8 :     size_t n = 0;
     428 [ +  - ][ +  - ]:        128 :     for (SwSortTxtElements::const_iterator it = aSortSet.begin();
         [ +  - ][ +  - ]
                 [ +  + ]
     429         [ +  - ]:         64 :             it != aSortSet.end(); ++it, ++n)
     430                 :            :     {
     431         [ +  - ]:         56 :         aStart      = nBeg + n;
     432 [ +  - ][ +  - ]:         56 :         aRg.aStart  = it->aPos.GetIndex();
     433         [ +  - ]:         56 :         aRg.aEnd    = aRg.aStart.GetIndex() + 1;
     434                 :            : 
     435                 :            :         // Move Nodes
     436                 :            :         MoveNodeRange( aRg, aStart,
     437         [ +  - ]:         56 :             IDocumentContentOperations::DOC_MOVEDEFAULT );
     438                 :            : 
     439                 :            :         // Insert Move in Undo
     440         [ +  - ]:         56 :         if(pUndoSort)
     441                 :            :         {
     442 [ +  - ][ +  - ]:         56 :             pUndoSort->Insert(it->nOrg, nBeg + n);
     443                 :            :         }
     444                 :            :     }
     445                 :            :     // Delete all elements from the SortArray
     446         [ +  - ]:          8 :     aSortSet.clear();
     447         [ +  - ]:          8 :     SwSortElement::Finit();
     448                 :            : 
     449         [ -  + ]:          8 :     if( pRedlPam )
     450                 :            :     {
     451         [ #  # ]:          0 :         if( pRedlUndo )
     452                 :            :         {
     453         [ #  # ]:          0 :             pRedlUndo->SetSaveRange( *pRedlPam );
     454                 :            :             // UGLY: temp. enable Undo
     455 [ #  # ][ #  # ]:          0 :             GetIDocumentUndoRedo().DoUndo(true);
     456 [ #  # ][ #  # ]:          0 :             GetIDocumentUndoRedo().AppendUndo( pRedlUndo );
     457 [ #  # ][ #  # ]:          0 :             GetIDocumentUndoRedo().DoUndo(false);
     458                 :            :         }
     459                 :            : 
     460                 :            :         // nBeg is start of sorted range
     461 [ #  # ][ #  # ]:          0 :         SwNodeIndex aSttIdx( GetNodes(), nBeg );
     462                 :            : 
     463                 :            :         // the copied range is deleted
     464                 :            :         SwRedline *const pDeleteRedline(
     465 [ #  # ][ #  # ]:          0 :             new SwRedline( nsRedlineType_t::REDLINE_DELETE, *pRedlPam ));
     466                 :            : 
     467                 :            :         // pRedlPam points to nodes that may be deleted (hidden) by
     468                 :            :         // AppendRedline, so adjust it beforehand to prevent ASSERT
     469         [ #  # ]:          0 :         pRedlPam->GetPoint()->nNode = aSttIdx;
     470                 :          0 :         SwCntntNode* pCNd = aSttIdx.GetNode().GetCntntNode();
     471 [ #  # ][ #  # ]:          0 :         pRedlPam->GetPoint()->nContent.Assign( pCNd, 0 );
     472                 :            : 
     473         [ #  # ]:          0 :         AppendRedline(pDeleteRedline, true);
     474                 :            : 
     475                 :            :         // the sorted range is inserted
     476 [ #  # ][ #  # ]:          0 :         AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, *pRedlPam ), true);
                 [ #  # ]
     477                 :            : 
     478         [ #  # ]:          0 :         if( pRedlUndo )
     479                 :            :         {
     480         [ #  # ]:          0 :             SwNodeIndex aInsEndIdx( pRedlPam->GetMark()->nNode, -1 );
     481         [ #  # ]:          0 :             pRedlPam->GetMark()->nNode = aInsEndIdx;
     482                 :            :             SwCntntNode *const pPrevNode =
     483                 :          0 :                 pRedlPam->GetMark()->nNode.GetNode().GetCntntNode();
     484 [ #  # ][ #  # ]:          0 :             pRedlPam->GetMark()->nContent.Assign( pPrevNode, pPrevNode->Len() );
                 [ #  # ]
     485                 :            : 
     486 [ #  # ][ #  # ]:          0 :             pRedlUndo->SetValues( *pRedlPam );
     487                 :            :         }
     488                 :            : 
     489         [ #  # ]:          0 :         if( pRedlUndo )
     490         [ #  # ]:          0 :             pRedlUndo->SetOffset( aSttIdx );
     491                 :            : 
     492 [ #  # ][ #  # ]:          0 :         delete pRedlPam, pRedlPam = 0;
                 [ #  # ]
     493                 :            :     }
     494 [ +  - ][ +  - ]:          8 :     GetIDocumentUndoRedo().DoUndo( bUndo );
     495         [ +  - ]:          8 :     if( bUndo )
     496                 :            :     {
     497 [ +  - ][ +  - ]:          8 :         GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
     498                 :            :     }
     499                 :            : 
     500 [ +  - ][ +  - ]:          8 :     return sal_True;
                 [ +  - ]
     501                 :            : }
     502                 :            : 
     503                 :            : /*--------------------------------------------------------------------
     504                 :            :     Description: Sort Table in the Document
     505                 :            :  --------------------------------------------------------------------*/
     506                 :          8 : sal_Bool SwDoc::SortTbl(const SwSelBoxes& rBoxes, const SwSortOptions& rOpt)
     507                 :            : {
     508                 :            :     // Via SwDoc for Undo!
     509                 :            :     OSL_ENSURE( !rBoxes.empty(), "no valid Box list" );
     510 [ +  - ][ +  - ]:          8 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
     511         [ -  + ]:          8 :     if( !pTblNd )
     512                 :          0 :         return sal_False;
     513                 :            : 
     514                 :            :     // We begin sorting
     515                 :            :     // Find all Boxes/Lines
     516         [ +  - ]:          8 :     _FndBox aFndBox( 0, 0 );
     517                 :            :     {
     518                 :          8 :         _FndPara aPara( rBoxes, &aFndBox );
     519         [ +  - ]:          8 :         ForEach_FndLineCopyCol( pTblNd->GetTable().GetTabLines(), &aPara );
     520                 :            :     }
     521                 :            : 
     522         [ -  + ]:          8 :     if(aFndBox.GetLines().empty())
     523                 :          0 :         return sal_False;
     524                 :            : 
     525 [ +  - ][ +  - ]:          8 :     if( !IsIgnoreRedline() && !GetRedlineTbl().empty() )
         [ +  - ][ -  + ]
                 [ -  + ]
     526         [ #  # ]:          0 :         DeleteRedline( *pTblNd, true, USHRT_MAX );
     527                 :            : 
     528                 :          8 :     sal_uInt16 nStart = 0;
     529 [ +  - ][ -  + ]:          8 :     if( pTblNd->GetTable().GetRowsToRepeat() > 0 && rOpt.eDirection == SRT_ROWS )
         [ #  # ][ -  + ]
     530                 :            :     {
     531                 :            :         // Uppermost selected Cell
     532                 :          0 :         _FndLines& rLines = aFndBox.GetLines();
     533                 :            : 
     534         [ #  # ]:          0 :         while( nStart < rLines.size() )
     535                 :            :         {
     536                 :            :             // Respect Split Merge nesting,
     537                 :            :             // extract the upper most
     538         [ #  # ]:          0 :             SwTableLine* pLine = rLines[nStart].GetLine();
     539         [ #  # ]:          0 :             while ( pLine->GetUpper() )
     540                 :          0 :                 pLine = pLine->GetUpper()->GetUpper();
     541                 :            : 
     542 [ #  # ][ #  # ]:          0 :             if( pTblNd->GetTable().IsHeadline( *pLine ) )
     543                 :          0 :                 nStart++;
     544                 :            :             else
     545                 :          0 :                 break;
     546                 :            :         }
     547                 :            :         // Are all selected in the HeaderLine?  -> no Offset
     548         [ #  # ]:          0 :         if( nStart == rLines.size() )
     549                 :          0 :             nStart = 0;
     550                 :            :     }
     551                 :            : 
     552                 :            :     // Switch to relative Formulas
     553         [ +  - ]:          8 :     SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
     554                 :          8 :     aMsgHnt.eFlags = TBL_RELBOXNAME;
     555         [ +  - ]:          8 :     UpdateTblFlds( &aMsgHnt );
     556                 :            : 
     557                 :            :     // Table as a flat array structure
     558         [ +  - ]:          8 :     FlatFndBox aFlatBox(this, aFndBox);
     559                 :            : 
     560         [ -  + ]:          8 :     if(!aFlatBox.IsSymmetric())
     561                 :          0 :         return sal_False;
     562                 :            : 
     563                 :            :     // Delete HTML layout
     564         [ +  - ]:          8 :     pTblNd->GetTable().SetHTMLTableLayout( 0 );
     565                 :            : 
     566                 :            :     // #i37739# A simple 'MakeFrms' after the node sorting
     567                 :            :     // does not work if the table is inside a frame and has no prev/next.
     568         [ +  - ]:          8 :     SwNode2Layout aNode2Layout( *pTblNd );
     569                 :            : 
     570                 :            :     // Delete the Table's Frames
     571         [ +  - ]:          8 :     pTblNd->DelFrms();
     572                 :            :     // ? TL_CHART2: ?
     573                 :            : 
     574                 :          8 :     SwUndoSort* pUndoSort = 0;
     575 [ +  - ][ +  - ]:          8 :     if (GetIDocumentUndoRedo().DoesUndo())
                 [ +  - ]
     576                 :            :     {
     577         [ +  - ]:          8 :         pUndoSort = new SwUndoSort( rBoxes[0]->GetSttIdx(),
     578         [ +  - ]:          8 :                                     rBoxes.back()->GetSttIdx(),
     579 [ +  - ][ +  - ]:         16 :                                    *pTblNd, rOpt, aFlatBox.HasItemSets() );
         [ +  - ][ +  - ]
     580 [ +  - ][ +  - ]:          8 :         GetIDocumentUndoRedo().AppendUndo(pUndoSort);
     581                 :            :     }
     582 [ +  - ][ +  - ]:          8 :     ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
     583                 :            : 
     584                 :            :     // Insert KeyElements
     585                 :            :     sal_uInt16 nCount = (rOpt.eDirection == SRT_ROWS) ?
     586         [ +  - ]:          8 :                     aFlatBox.GetRows() : aFlatBox.GetCols();
     587                 :            : 
     588                 :            :     // Sort SortList by Key
     589         [ +  - ]:          8 :     SwSortElement::Init( this, rOpt, &aFlatBox );
     590         [ +  - ]:          8 :     SwSortBoxElements aSortList;
     591                 :            : 
     592                 :            :     // When sorting, do not include the first row if the HeaderLine is repeated
     593                 :            :     sal_uInt16 i;
     594                 :            : 
     595         [ +  + ]:         56 :     for( i = nStart; i < nCount; ++i)
     596                 :            :     {
     597         [ +  - ]:         48 :         SwSortBoxElement* pEle = new SwSortBoxElement( i );
     598         [ +  - ]:         48 :         aSortList.insert(pEle);
     599                 :            :     }
     600                 :            : 
     601                 :            :     // Move after Sorting
     602         [ +  - ]:          8 :     SwMovedBoxes aMovedList;
     603                 :          8 :     i = 0;
     604 [ +  - ][ +  - ]:        112 :     for (SwSortBoxElements::const_iterator it = aSortList.begin();
         [ +  - ][ +  - ]
                 [ +  + ]
     605         [ +  - ]:         56 :             it != aSortList.end(); ++i, ++it)
     606                 :            :     {
     607         [ +  - ]:         48 :         if(rOpt.eDirection == SRT_ROWS)
     608                 :            :         {
     609 [ +  - ][ +  - ]:         48 :             MoveRow(this, aFlatBox, it->nRow, i+nStart, aMovedList, pUndoSort);
     610                 :            :         }
     611                 :            :         else
     612                 :            :         {
     613 [ #  # ][ #  # ]:          0 :             MoveCol(this, aFlatBox, it->nRow, i+nStart, aMovedList, pUndoSort);
     614                 :            :         }
     615                 :            :     }
     616                 :            : 
     617                 :            :     // Restore table frames:
     618                 :            :     // #i37739# A simple 'MakeFrms' after the node sorting
     619                 :            :     // does not work if the table is inside a frame and has no prev/next.
     620                 :          8 :     const sal_uLong nIdx = pTblNd->GetIndex();
     621 [ +  - ][ +  - ]:          8 :     aNode2Layout.RestoreUpperFrms( GetNodes(), nIdx, nIdx + 1 );
     622                 :            : 
     623                 :            :     // TL_CHART2: need to inform chart of probably changed cell names
     624         [ +  - ]:          8 :     UpdateCharts( pTblNd->GetTable().GetFrmFmt()->GetName() );
     625                 :            : 
     626                 :            :     // Delete all Elements in the SortArray
     627         [ +  - ]:          8 :     aSortList.clear();
     628         [ +  - ]:          8 :     SwSortElement::Finit();
     629                 :            : 
     630         [ +  - ]:          8 :     SetModified();
     631 [ +  - ][ +  - ]:          8 :     return sal_True;
         [ +  - ][ +  - ]
                 [ +  - ]
     632                 :            : }
     633                 :            : 
     634                 :            : /*--------------------------------------------------------------------
     635                 :            :     Description: Move a row
     636                 :            :  --------------------------------------------------------------------*/
     637                 :         48 : void MoveRow(SwDoc* pDoc, const FlatFndBox& rBox, sal_uInt16 nS, sal_uInt16 nT,
     638                 :            :              SwMovedBoxes& rMovedList, SwUndoSort* pUD)
     639                 :            : {
     640         [ +  + ]:        144 :     for( sal_uInt16 i=0; i < rBox.GetCols(); ++i )
     641                 :            :     {   // Get old cell position and remember it
     642                 :         96 :         const _FndBox* pSource = rBox.GetBox(i, nS);
     643                 :            : 
     644                 :            :         // new cell position
     645                 :         96 :         const _FndBox* pTarget = rBox.GetBox(i, nT);
     646                 :            : 
     647                 :         96 :         const SwTableBox* pT = pTarget->GetBox();
     648                 :         96 :         const SwTableBox* pS = pSource->GetBox();
     649                 :            : 
     650         [ +  - ]:         96 :         sal_Bool bMoved = rMovedList.GetPos(pT) != USHRT_MAX;
     651                 :            : 
     652                 :            :         // and move it
     653         [ +  - ]:         96 :         MoveCell(pDoc, pS, pT, bMoved, pUD);
     654                 :            : 
     655         [ +  - ]:         96 :         rMovedList.push_back(pS);
     656                 :            : 
     657         [ +  + ]:         96 :         if( pS != pT )
     658                 :            :         {
     659                 :         76 :             SwFrmFmt* pTFmt = (SwFrmFmt*)pT->GetFrmFmt();
     660                 :         76 :             const SfxItemSet* pSSet = rBox.GetItemSet( i, nS );
     661                 :            : 
     662 [ +  - ][ +  - ]:        190 :             if( pSSet ||
         [ -  + ][ +  + ]
                 [ +  + ]
     663         [ +  - ]:         38 :                 SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_FORMAT ) ||
     664         [ +  - ]:         38 :                 SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_FORMULA ) ||
     665         [ +  - ]:         38 :                 SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_VALUE ) )
     666                 :            :             {
     667         [ +  - ]:         38 :                 pTFmt = ((SwTableBox*)pT)->ClaimFrmFmt();
     668                 :         38 :                 pTFmt->LockModify();
     669 [ +  - ][ +  - ]:         38 :                 if( pTFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE ) )
     670         [ +  - ]:         38 :                     pTFmt->ResetFmtAttr( RES_VERT_ORIENT );
     671                 :            : 
     672         [ +  - ]:         38 :                 if( pSSet )
     673         [ +  - ]:         38 :                     pTFmt->SetFmtAttr( *pSSet );
     674                 :         38 :                 pTFmt->UnlockModify();
     675                 :            :             }
     676                 :            :         }
     677                 :            :     }
     678                 :         48 : }
     679                 :            : 
     680                 :            : /*--------------------------------------------------------------------
     681                 :            :     Description: Move a column
     682                 :            :  --------------------------------------------------------------------*/
     683                 :          0 : void MoveCol(SwDoc* pDoc, const FlatFndBox& rBox, sal_uInt16 nS, sal_uInt16 nT,
     684                 :            :              SwMovedBoxes& rMovedList, SwUndoSort* pUD)
     685                 :            : {
     686         [ #  # ]:          0 :     for(sal_uInt16 i=0; i < rBox.GetRows(); ++i)
     687                 :            :     {   // Get old cell position and remember it
     688                 :          0 :         const _FndBox* pSource = rBox.GetBox(nS, i);
     689                 :            : 
     690                 :            :         // new cell position
     691                 :          0 :         const _FndBox* pTarget = rBox.GetBox(nT, i);
     692                 :            : 
     693                 :            :         // and move it
     694                 :          0 :         const SwTableBox* pT = pTarget->GetBox();
     695                 :          0 :         const SwTableBox* pS = pSource->GetBox();
     696                 :            : 
     697                 :            :         // and move it
     698         [ #  # ]:          0 :         sal_Bool bMoved = rMovedList.GetPos(pT) != USHRT_MAX;
     699         [ #  # ]:          0 :         MoveCell(pDoc, pS, pT, bMoved, pUD);
     700                 :            : 
     701         [ #  # ]:          0 :         rMovedList.push_back(pS);
     702                 :            : 
     703         [ #  # ]:          0 :         if( pS != pT )
     704                 :            :         {
     705                 :          0 :             SwFrmFmt* pTFmt = (SwFrmFmt*)pT->GetFrmFmt();
     706                 :          0 :             const SfxItemSet* pSSet = rBox.GetItemSet( nS, i );
     707                 :            : 
     708 [ #  # ][ #  # ]:          0 :             if( pSSet ||
         [ #  # ][ #  # ]
                 [ #  # ]
     709         [ #  # ]:          0 :                 SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_FORMAT ) ||
     710         [ #  # ]:          0 :                 SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_FORMULA ) ||
     711         [ #  # ]:          0 :                 SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_VALUE ) )
     712                 :            :             {
     713         [ #  # ]:          0 :                 pTFmt = ((SwTableBox*)pT)->ClaimFrmFmt();
     714                 :          0 :                 pTFmt->LockModify();
     715 [ #  # ][ #  # ]:          0 :                 if( pTFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE ) )
     716         [ #  # ]:          0 :                     pTFmt->ResetFmtAttr( RES_VERT_ORIENT );
     717                 :            : 
     718         [ #  # ]:          0 :                 if( pSSet )
     719         [ #  # ]:          0 :                     pTFmt->SetFmtAttr( *pSSet );
     720                 :          0 :                 pTFmt->UnlockModify();
     721                 :            :             }
     722                 :            :         }
     723                 :            :     }
     724                 :          0 : }
     725                 :            : 
     726                 :            : /*--------------------------------------------------------------------
     727                 :            :     Description: Move a single Cell
     728                 :            :  --------------------------------------------------------------------*/
     729                 :         96 : void MoveCell(SwDoc* pDoc, const SwTableBox* pSource, const SwTableBox* pTar,
     730                 :            :               sal_Bool bMovedBefore, SwUndoSort* pUD)
     731                 :            : {
     732                 :            :     OSL_ENSURE(pSource && pTar,"Source or target missing");
     733                 :            : 
     734         [ +  + ]:         96 :     if(pSource == pTar)
     735                 :         96 :         return;
     736                 :            : 
     737         [ +  - ]:         76 :     if(pUD)
     738 [ +  - ][ +  - ]:         76 :         pUD->Insert( pSource->GetName(), pTar->GetName() );
         [ +  - ][ +  - ]
                 [ +  - ]
     739                 :            : 
     740                 :            :     // Set Pam source to the first ContentNode
     741         [ +  - ]:         76 :     SwNodeRange aRg( *pSource->GetSttNd(), 0, *pSource->GetSttNd() );
     742 [ +  - ][ +  - ]:         76 :     SwNode* pNd = pDoc->GetNodes().GoNext( &aRg.aStart );
                 [ +  - ]
     743                 :            : 
     744                 :            :     // If the Cell (Source) wasn't moved
     745                 :            :     // -> insert an empty Node and move the rest or the Mark
     746                 :            :     // points to the first ContentNode
     747         [ +  + ]:         76 :     if( pNd->StartOfSectionNode() == pSource->GetSttNd() )
     748         [ +  - ]:         40 :         pNd = pDoc->GetNodes().MakeTxtNode( aRg.aStart,
     749 [ +  - ][ +  - ]:         80 :                 (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl() );
     750         [ +  - ]:         76 :     aRg.aEnd = *pNd->EndOfSectionNode();
     751                 :            : 
     752                 :            :     // If the Target is empty (there is one empty Node)
     753                 :            :     // -> delete it and move the Target
     754         [ +  - ]:         76 :     SwNodeIndex aTar( *pTar->GetSttNd() );
     755 [ +  - ][ +  - ]:         76 :     pNd = pDoc->GetNodes().GoNext( &aTar );     // next ContentNode
                 [ +  - ]
     756                 :         76 :     sal_uLong nCount = pNd->EndOfSectionIndex() - pNd->StartOfSectionIndex();
     757                 :            : 
     758                 :         76 :     sal_Bool bDelFirst = sal_False;
     759         [ +  - ]:         76 :     if( nCount == 2 )
     760                 :            :     {
     761                 :            :         OSL_ENSURE( pNd->GetCntntNode(), "No ContentNode");
     762 [ +  - ][ +  + ]:         76 :         bDelFirst = !pNd->GetCntntNode()->Len() && bMovedBefore;
                 [ +  + ]
     763                 :            :     }
     764                 :            : 
     765         [ +  + ]:         76 :     if(!bDelFirst)
     766                 :            :     {   // We already have Content -> old Content Section Down
     767         [ +  - ]:         36 :         SwNodeRange aRgTar( aTar.GetNode(), 0, *pNd->EndOfSectionNode() );
     768 [ +  - ][ +  - ]:         36 :         pDoc->GetNodes().SectionDown( &aRgTar );
                 [ +  - ]
     769                 :            :     }
     770                 :            : 
     771                 :            :     // Insert the Source
     772         [ +  - ]:         76 :     SwNodeIndex aIns( *pTar->GetSttNd()->EndOfSectionNode() );
     773                 :            :     pDoc->MoveNodeRange( aRg, aIns,
     774         [ +  - ]:         76 :         IDocumentContentOperations::DOC_MOVEDEFAULT );
     775                 :            : 
     776                 :            :     // If first Node is empty -> delete it
     777         [ +  + ]:         76 :     if(bDelFirst)
     778 [ +  - ][ +  - ]:         96 :         pDoc->GetNodes().Delete( aTar, 1 );
         [ +  - ][ +  - ]
                 [ +  - ]
     779                 :            : }
     780                 :            : 
     781                 :            : /*--------------------------------------------------------------------
     782                 :            :     Description: Generate two-dimensional array of FndBoxes
     783                 :            :  --------------------------------------------------------------------*/
     784                 :          8 : FlatFndBox::FlatFndBox(SwDoc* pDocPtr, const _FndBox& rBox) :
     785                 :            :     pDoc(pDocPtr),
     786                 :            :     rBoxRef(rBox),
     787                 :            :     pArr(0),
     788                 :            :     ppItemSets(0),
     789                 :            :     nRow(0),
     790                 :          8 :     nCol(0)
     791                 :            : { // If the array is symmetric
     792         [ +  - ]:          8 :     if((bSym = CheckLineSymmetry(rBoxRef)) != 0)
     793                 :            :     {
     794                 :            :         // Determine column/row count
     795                 :          8 :         nCols = GetColCount(rBoxRef);
     796                 :          8 :         nRows = GetRowCount(rBoxRef);
     797                 :            : 
     798                 :            :         // Create linear array
     799                 :          8 :         pArr = new const _FndBox*[ nRows * nCols ];
     800                 :          8 :         _FndBox** ppTmp = (_FndBox**)pArr;
     801                 :          8 :         memset( ppTmp, 0, sizeof(const _FndBox*) * nRows * nCols );
     802                 :            : 
     803                 :            : 
     804                 :          8 :         FillFlat( rBoxRef );
     805                 :            :     }
     806                 :          8 : }
     807                 :            : 
     808                 :          8 : FlatFndBox::~FlatFndBox()
     809                 :            : {
     810                 :          8 :     _FndBox** ppTmp = (_FndBox**)pArr;
     811         [ +  - ]:          8 :     delete [] ppTmp;
     812                 :            : 
     813         [ +  - ]:          8 :     if( ppItemSets )
     814         [ +  - ]:          8 :         delete [] ppItemSets;
     815                 :          8 : }
     816                 :            : 
     817                 :            : /*--------------------------------------------------------------------
     818                 :            :     Description: All Lines of a Box need to have as many Boxes
     819                 :            :  --------------------------------------------------------------------*/
     820                 :          8 : sal_Bool FlatFndBox::CheckLineSymmetry(const _FndBox& rBox)
     821                 :            : {
     822                 :          8 :     const _FndLines &rLines = rBox.GetLines();
     823                 :          8 :     sal_uInt16 nBoxes(0);
     824                 :            : 
     825                 :            :     // Iterate over Lines
     826         [ +  + ]:         56 :     for(sal_uInt16 i=0; i < rLines.size(); ++i)
     827                 :            :     {   // A List's Box
     828                 :         48 :         const _FndLine* pLn = &rLines[i];
     829                 :         48 :         const _FndBoxes& rBoxes = pLn->GetBoxes();
     830                 :            : 
     831                 :            :         // Amount of Boxes of all Lines is uneven -> no symmetry
     832 [ -  + ][ -  + ]:         48 :         if( i  && nBoxes != rBoxes.size())
                 [ +  + ]
     833                 :          0 :             return sal_False;
     834                 :            : 
     835                 :         48 :         nBoxes = rBoxes.size();
     836         [ -  + ]:         48 :         if( !CheckBoxSymmetry( *pLn ) )
     837                 :          0 :             return sal_False;
     838                 :            :     }
     839                 :          8 :     return sal_True;
     840                 :            : }
     841                 :            : 
     842                 :            : /*--------------------------------------------------------------------
     843                 :            :     Description: Check Box for symmetry
     844                 :            :                  All Boxes of a Line need to have as many Lines
     845                 :            :  --------------------------------------------------------------------*/
     846                 :         48 : sal_Bool FlatFndBox::CheckBoxSymmetry(const _FndLine& rLn)
     847                 :            : {
     848                 :         48 :     const _FndBoxes &rBoxes = rLn.GetBoxes();
     849                 :         48 :     sal_uInt16 nLines(0);
     850                 :            : 
     851                 :            :     // Iterate over Boxes
     852         [ +  + ]:        144 :     for(sal_uInt16 i=0; i < rBoxes.size(); ++i)
     853                 :            :     {   // The Boxes of a Line
     854                 :         96 :         _FndBox const*const pBox = &rBoxes[i];
     855                 :         96 :         const _FndLines& rLines = pBox->GetLines();
     856                 :            : 
     857                 :            :         // Amount of Boxes of all Lines is uneven -> no symmetry
     858 [ -  + ][ -  + ]:         96 :         if( i && nLines != rLines.size() )
                 [ +  + ]
     859                 :          0 :             return sal_False;
     860                 :            : 
     861                 :         96 :         nLines = rLines.size();
     862 [ #  # ][ -  + ]:         96 :         if( nLines && !CheckLineSymmetry( *pBox ) )
                 [ -  + ]
     863                 :          0 :             return sal_False;
     864                 :            :     }
     865                 :         48 :     return sal_True;
     866                 :            : }
     867                 :            : 
     868                 :            : /*--------------------------------------------------------------------
     869                 :            :     Description: Maximum count of Columns (Boxes)
     870                 :            :  --------------------------------------------------------------------*/
     871                 :          8 : sal_uInt16 FlatFndBox::GetColCount(const _FndBox& rBox)
     872                 :            : {
     873                 :          8 :     const _FndLines& rLines = rBox.GetLines();
     874                 :            :     // Iterate over Lines
     875         [ -  + ]:          8 :     if( rLines.empty() )
     876                 :          0 :         return 1;
     877                 :            : 
     878                 :          8 :     sal_uInt16 nSum = 0;
     879         [ +  + ]:         56 :     for( sal_uInt16 i=0; i < rLines.size(); ++i )
     880                 :            :     {
     881                 :            :         // The Boxes of a Line
     882                 :         48 :         sal_uInt16 nCount = 0;
     883                 :         48 :         const _FndBoxes& rBoxes = rLines[i].GetBoxes();
     884         [ +  + ]:        144 :         for( sal_uInt16 j=0; j < rBoxes.size(); ++j )
     885                 :            :             // Iterate recursively over the Lines
     886                 :         96 :             nCount += (rBoxes[j].GetLines().size())
     887         [ -  + ]:         96 :                         ? GetColCount(rBoxes[j]) : 1;
     888                 :            : 
     889         [ +  + ]:         48 :         if( nSum < nCount )
     890                 :          8 :             nSum = nCount;
     891                 :            :     }
     892                 :          8 :     return nSum;
     893                 :            : }
     894                 :            : 
     895                 :            : /*--------------------------------------------------------------------
     896                 :            :     Description: Maximum count of Rows (Lines)
     897                 :            :  --------------------------------------------------------------------*/
     898                 :          8 : sal_uInt16 FlatFndBox::GetRowCount(const _FndBox& rBox)
     899                 :            : {
     900                 :          8 :     const _FndLines& rLines = rBox.GetLines();
     901         [ -  + ]:          8 :     if( rLines.empty() )
     902                 :          0 :         return 1;
     903                 :            : 
     904                 :          8 :     sal_uInt16 nLines = 0;
     905         [ +  + ]:         56 :     for(sal_uInt16 i=0; i < rLines.size(); ++i)
     906                 :            :     {   // The Boxes of a Line
     907                 :         48 :         const _FndBoxes& rBoxes = rLines[i].GetBoxes();
     908                 :         48 :         sal_uInt16 nLn = 1;
     909         [ +  + ]:        144 :         for(sal_uInt16 j=0; j < rBoxes.size(); ++j)
     910         [ -  + ]:         96 :             if (rBoxes[j].GetLines().size())
     911                 :            :                 // Iterate recursively over the Lines
     912                 :          0 :                 nLn = Max(GetRowCount(rBoxes[j]), nLn);
     913                 :            : 
     914                 :         48 :         nLines = nLines + nLn;
     915                 :            :     }
     916                 :          8 :     return nLines;
     917                 :            : }
     918                 :            : 
     919                 :            : /*--------------------------------------------------------------------
     920                 :            :     Description: Create a linear array of atmoic FndBoxes
     921                 :            :  --------------------------------------------------------------------*/
     922                 :          8 : void FlatFndBox::FillFlat(const _FndBox& rBox, sal_Bool bLastBox)
     923                 :            : {
     924                 :          8 :     sal_Bool bModRow = sal_False;
     925                 :          8 :     const _FndLines& rLines = rBox.GetLines();
     926                 :            : 
     927                 :            :     // Iterate over Lines
     928                 :          8 :     sal_uInt16 nOldRow = nRow;
     929         [ +  + ]:         56 :     for( sal_uInt16 i=0; i < rLines.size(); ++i )
     930                 :            :     {
     931                 :            :         // The Boxes of a Line
     932                 :         48 :         const _FndBoxes& rBoxes = rLines[i].GetBoxes();
     933                 :         48 :         sal_uInt16 nOldCol = nCol;
     934         [ +  + ]:        144 :         for( sal_uInt16 j = 0; j < rBoxes.size(); ++j )
     935                 :            :         {
     936                 :            :             // Check the Box if it's an atomic one
     937                 :         96 :             const _FndBox *const pBox = &rBoxes[j];
     938                 :            : 
     939         [ +  - ]:         96 :             if( !pBox->GetLines().size() )
     940                 :            :             {
     941                 :            :                 // save it
     942                 :         96 :                 sal_uInt16 nOff = nRow * nCols + nCol;
     943                 :         96 :                 *(pArr + nOff) = pBox;
     944                 :            : 
     945                 :            :                 // Save the Formula/Format/Value values
     946                 :         96 :                 const SwFrmFmt* pFmt = pBox->GetBox()->GetFrmFmt();
     947 [ +  + ][ +  +  :        192 :                 if( SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMAT ) ||
             +  -  -  + ]
     948                 :         48 :                     SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMULA ) ||
     949                 :         48 :                     SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_VALUE ) )
     950                 :            :                 {
     951                 :         48 :                     SfxItemSet* pSet = new SfxItemSet( pDoc->GetAttrPool(),
     952                 :            :                                     RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
     953         [ +  - ]:         48 :                                     RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
     954                 :         48 :                     pSet->Put( pFmt->GetAttrSet() );
     955         [ +  + ]:         48 :                     if( !ppItemSets )
     956                 :            :                     {
     957                 :          8 :                         ppItemSets = new SfxItemSet*[ nRows * nCols ];
     958                 :          8 :                         memset( ppItemSets, 0, sizeof(SfxItemSet*) * nRows * nCols );
     959                 :            :                     }
     960                 :         48 :                     *(ppItemSets + nOff ) = pSet;
     961                 :            :                 }
     962                 :            : 
     963                 :         96 :                 bModRow = sal_True;
     964                 :            :             }
     965                 :            :             else
     966                 :            :             {
     967                 :            :                 // Iterate recursively over the Lines of a Box
     968                 :          0 :                 FillFlat( *pBox, ( j == rBoxes.size()-1 ) );
     969                 :            :             }
     970                 :         96 :             nCol++;
     971                 :            :         }
     972         [ +  - ]:         48 :         if(bModRow)
     973                 :         48 :             nRow++;
     974                 :         48 :         nCol = nOldCol;
     975                 :            :     }
     976         [ +  - ]:          8 :     if(!bLastBox)
     977                 :          8 :         nRow = nOldRow;
     978                 :          8 : }
     979                 :            : 
     980                 :            : /*--------------------------------------------------------------------
     981                 :            :     Description: Access a specific Cell
     982                 :            :  --------------------------------------------------------------------*/
     983                 :        664 : const _FndBox* FlatFndBox::GetBox(sal_uInt16 n_Col, sal_uInt16 n_Row) const
     984                 :            : {
     985                 :        664 :     sal_uInt16 nOff = n_Row * nCols + n_Col;
     986                 :        664 :     const _FndBox* pTmp = *(pArr + nOff);
     987                 :            : 
     988                 :            :     OSL_ENSURE(n_Col < nCols && n_Row < nRows && pTmp, "invalid array access");
     989                 :        664 :     return pTmp;
     990                 :            : }
     991                 :            : 
     992                 :         76 : const SfxItemSet* FlatFndBox::GetItemSet(sal_uInt16 n_Col, sal_uInt16 n_Row) const
     993                 :            : {
     994                 :            :     OSL_ENSURE( !ppItemSets || ( n_Col < nCols && n_Row < nRows), "invalid array access");
     995                 :            : 
     996         [ +  - ]:         76 :     return ppItemSets ? *(ppItemSets + (n_Row * nCols + n_Col )) : 0;
     997                 :            : }
     998                 :            : 
     999                 :         96 : sal_uInt16 SwMovedBoxes::GetPos(const SwTableBox* pTableBox) const
    1000                 :            : {
    1001         [ +  - ]:         96 :     const_iterator it = std::find(begin(), end(), pTableBox);
    1002 [ +  - ][ +  + ]:         96 :     return it == end() ? USHRT_MAX : it - begin();
         [ +  - ][ +  + ]
                 [ #  # ]
    1003                 :            : }
    1004                 :            : 
    1005                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10