LCOV - code coverage report
Current view: top level - svtools/source/contnr - imivctl2.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 109 451 24.2 %
Date: 2015-06-13 12:38:46 Functions: 15 27 55.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "imivctl.hxx"
      21             : 
      22           7 : IcnCursor_Impl::IcnCursor_Impl( SvxIconChoiceCtrl_Impl* pOwner )
      23             : {
      24           7 :     pView       = pOwner;
      25           7 :     pCurEntry   = 0;
      26           7 :     nDeltaWidth = 0;
      27           7 :     nDeltaHeight= 0;
      28           7 :     nCols       = 0;
      29           7 :     nRows       = 0;
      30           7 : }
      31             : 
      32           5 : IcnCursor_Impl::~IcnCursor_Impl()
      33             : {
      34           5 : }
      35             : 
      36           0 : sal_uInt16 IcnCursor_Impl::GetSortListPos( SvxIconChoiceCtrlEntryPtrVec& rList, long nValue,
      37             :     bool bVertical )
      38             : {
      39           0 :     sal_uInt16 nCount = rList.size();
      40           0 :     if( !nCount )
      41           0 :         return 0;
      42             : 
      43           0 :     sal_uInt16 nCurPos = 0;
      44           0 :     long nPrevValue = LONG_MIN;
      45           0 :     while( nCount )
      46             :     {
      47           0 :         const Rectangle& rRect = pView->GetEntryBoundRect( rList[nCurPos] );
      48             :         long nCurValue;
      49           0 :         if( bVertical )
      50           0 :             nCurValue = rRect.Top();
      51             :         else
      52           0 :             nCurValue = rRect.Left();
      53           0 :         if( nValue >= nPrevValue && nValue <= nCurValue )
      54           0 :             return (sal_uInt16)nCurPos;
      55           0 :         nPrevValue = nCurValue;
      56           0 :         nCount--;
      57           0 :         nCurPos++;
      58             :     }
      59           0 :     return rList.size();
      60             : }
      61             : 
      62           0 : void IcnCursor_Impl::ImplCreate()
      63             : {
      64           0 :     pView->CheckBoundingRects();
      65             :     DBG_ASSERT(xColumns==0&&xRows==0,"ImplCreate: Not cleared");
      66             : 
      67           0 :     SetDeltas();
      68             : 
      69           0 :     xColumns.reset(new IconChoiceMap);
      70           0 :     xRows.reset(new IconChoiceMap);
      71             : 
      72           0 :     size_t nCount = pView->aEntries.size();
      73           0 :     for( size_t nCur = 0; nCur < nCount; nCur++ )
      74             :     {
      75           0 :         SvxIconChoiceCtrlEntry* pEntry = pView->aEntries[ nCur ];
      76             :         // const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
      77           0 :         Rectangle rRect( pView->CalcBmpRect( pEntry,0 ) );
      78           0 :         short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / nDeltaHeight );
      79           0 :         short nX = (short)( ((rRect.Left()+rRect.Right())/2) / nDeltaWidth );
      80             : 
      81             :         // capture rounding errors
      82           0 :         if( nY >= nRows )
      83           0 :             nY = sal::static_int_cast< short >(nRows - 1);
      84           0 :         if( nX >= nCols )
      85           0 :             nX = sal::static_int_cast< short >(nCols - 1);
      86             : 
      87           0 :         SvxIconChoiceCtrlEntryPtrVec& rColEntry = (*xColumns)[nX];
      88           0 :         sal_uInt16 nIns = GetSortListPos( rColEntry, rRect.Top(), true );
      89           0 :         rColEntry.insert( rColEntry.begin() + nIns, pEntry );
      90             : 
      91           0 :         SvxIconChoiceCtrlEntryPtrVec& rRowEntry = (*xRows)[nY];
      92           0 :         nIns = GetSortListPos( rRowEntry, rRect.Left(), false );
      93           0 :         rRowEntry.insert( rRowEntry.begin() + nIns, pEntry );
      94             : 
      95           0 :         pEntry->nX = nX;
      96           0 :         pEntry->nY = nY;
      97             :     }
      98           0 : }
      99             : 
     100             : 
     101             : 
     102             : 
     103         373 : void IcnCursor_Impl::Clear()
     104             : {
     105         373 :     if( xColumns )
     106             :     {
     107           0 :         xColumns.reset();
     108           0 :         xRows.reset();
     109           0 :         pCurEntry = 0;
     110           0 :         nDeltaWidth = 0;
     111           0 :         nDeltaHeight = 0;
     112             :     }
     113         373 : }
     114             : 
     115           0 : SvxIconChoiceCtrlEntry* IcnCursor_Impl::SearchCol(sal_uInt16 nCol, sal_uInt16 nTop, sal_uInt16 nBottom,
     116             :     sal_uInt16, bool bDown, bool bSimple )
     117             : {
     118             :     DBG_ASSERT(pCurEntry, "SearchCol: No reference entry");
     119           0 :     IconChoiceMap::iterator mapIt = xColumns->find( nCol );
     120           0 :     if ( mapIt == xColumns->end() )
     121           0 :         return 0;
     122           0 :     SvxIconChoiceCtrlEntryPtrVec const & rList = mapIt->second;
     123           0 :     const sal_uInt16 nCount = rList.size();
     124           0 :     if( !nCount )
     125           0 :         return 0;
     126             : 
     127           0 :     const Rectangle& rRefRect = pView->GetEntryBoundRect(pCurEntry);
     128             : 
     129           0 :     if( bSimple )
     130             :     {
     131           0 :         SvxIconChoiceCtrlEntryPtrVec::const_iterator it = std::find( rList.begin(), rList.end(), pCurEntry );
     132             : 
     133             :         assert(it != rList.end()); //Entry not in Col-List
     134           0 :         if (it == rList.end())
     135           0 :             return 0;
     136             : 
     137           0 :         if( bDown )
     138             :         {
     139           0 :             while( ++it != rList.end() )
     140             :             {
     141           0 :                 SvxIconChoiceCtrlEntry* pEntry = *it;
     142           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     143           0 :                 if( rRect.Top() > rRefRect.Top() )
     144           0 :                     return pEntry;
     145             :             }
     146           0 :             return 0;
     147             :         }
     148             :         else
     149             :         {
     150           0 :             SvxIconChoiceCtrlEntryPtrVec::const_reverse_iterator it2(it);
     151           0 :             while (it2 != rList.rend())
     152             :             {
     153           0 :                 SvxIconChoiceCtrlEntry* pEntry = *it2;
     154           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     155           0 :                 if( rRect.Top() < rRefRect.Top() )
     156           0 :                     return pEntry;
     157           0 :                 ++it2;
     158             :             }
     159           0 :             return 0;
     160             :         }
     161             :     }
     162             : 
     163           0 :     if( nTop > nBottom )
     164             :     {
     165           0 :         sal_uInt16 nTemp = nTop;
     166           0 :         nTop = nBottom;
     167           0 :         nBottom = nTemp;
     168             :     }
     169           0 :     long nMinDistance = LONG_MAX;
     170           0 :     SvxIconChoiceCtrlEntry* pResult = 0;
     171           0 :     for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ )
     172             :     {
     173           0 :         SvxIconChoiceCtrlEntry* pEntry = rList[ nCur ];
     174           0 :         if( pEntry != pCurEntry )
     175             :         {
     176           0 :             sal_uInt16 nY = pEntry->nY;
     177           0 :             if( nY >= nTop && nY <= nBottom )
     178             :             {
     179           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     180           0 :                 long nDistance = rRect.Top() - rRefRect.Top();
     181           0 :                 if( nDistance < 0 )
     182           0 :                     nDistance *= -1;
     183           0 :                 if( nDistance && nDistance < nMinDistance )
     184             :                 {
     185           0 :                     nMinDistance = nDistance;
     186           0 :                     pResult = pEntry;
     187             :                 }
     188             :             }
     189             :         }
     190             :     }
     191           0 :     return pResult;
     192             : }
     193             : 
     194           0 : SvxIconChoiceCtrlEntry* IcnCursor_Impl::SearchRow(sal_uInt16 nRow, sal_uInt16 nLeft, sal_uInt16 nRight,
     195             :     sal_uInt16, bool bRight, bool bSimple )
     196             : {
     197             :     DBG_ASSERT(pCurEntry,"SearchRow: No reference entry");
     198           0 :     IconChoiceMap::iterator mapIt = xRows->find( nRow );
     199           0 :     if ( mapIt == xRows->end() )
     200           0 :         return 0;
     201           0 :     SvxIconChoiceCtrlEntryPtrVec const & rList = mapIt->second;
     202           0 :     const sal_uInt16 nCount = rList.size();
     203           0 :     if( !nCount )
     204           0 :         return 0;
     205             : 
     206           0 :     const Rectangle& rRefRect = pView->GetEntryBoundRect(pCurEntry);
     207             : 
     208           0 :     if( bSimple )
     209             :     {
     210           0 :         SvxIconChoiceCtrlEntryPtrVec::const_iterator it = std::find( rList.begin(), rList.end(), pCurEntry );
     211             : 
     212             :         assert(it != rList.end()); //Entry not in Row-List
     213           0 :         if (it == rList.end())
     214           0 :             return 0;
     215             : 
     216           0 :         if( bRight )
     217             :         {
     218           0 :             while( ++it != rList.end() )
     219             :             {
     220           0 :                 SvxIconChoiceCtrlEntry* pEntry = *it;
     221           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     222           0 :                 if( rRect.Left() > rRefRect.Left() )
     223           0 :                     return pEntry;
     224             :             }
     225           0 :             return 0;
     226             :         }
     227             :         else
     228             :         {
     229           0 :             SvxIconChoiceCtrlEntryPtrVec::const_reverse_iterator it2(it);
     230           0 :             while (it2 != rList.rend())
     231             :             {
     232           0 :                 SvxIconChoiceCtrlEntry* pEntry = *it2;
     233           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     234           0 :                 if( rRect.Left() < rRefRect.Left() )
     235           0 :                     return pEntry;
     236           0 :                 ++it2;
     237             :             }
     238           0 :             return 0;
     239             :         }
     240             : 
     241             :     }
     242           0 :     if( nRight < nLeft )
     243             :     {
     244           0 :         sal_uInt16 nTemp = nRight;
     245           0 :         nRight = nLeft;
     246           0 :         nLeft = nTemp;
     247             :     }
     248           0 :     long nMinDistance = LONG_MAX;
     249           0 :     SvxIconChoiceCtrlEntry* pResult = 0;
     250           0 :     for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ )
     251             :     {
     252           0 :         SvxIconChoiceCtrlEntry* pEntry = rList[ nCur ];
     253           0 :         if( pEntry != pCurEntry )
     254             :         {
     255           0 :             sal_uInt16 nX = pEntry->nX;
     256           0 :             if( nX >= nLeft && nX <= nRight )
     257             :             {
     258           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     259           0 :                 long nDistance = rRect.Left() - rRefRect.Left();
     260           0 :                 if( nDistance < 0 )
     261           0 :                     nDistance *= -1;
     262           0 :                 if( nDistance && nDistance < nMinDistance )
     263             :                 {
     264           0 :                     nMinDistance = nDistance;
     265           0 :                     pResult = pEntry;
     266             :                 }
     267             :             }
     268             :         }
     269             :     }
     270           0 :     return pResult;
     271             : }
     272             : 
     273             : 
     274             : 
     275             : /*
     276             :     Searches, starting from the passed value, the next entry to the left/to the
     277             :     right. Example for bRight = sal_True:
     278             : 
     279             :                   c
     280             :                 b c
     281             :               a b c
     282             :             S 1 1 1      ====> search direction
     283             :               a b c
     284             :                 b c
     285             :                   c
     286             : 
     287             :     S : starting position
     288             :     1 : first searched rectangle
     289             :     a,b,c : 2nd, 3rd, 4th searched rectangle
     290             : */
     291             : 
     292           0 : SvxIconChoiceCtrlEntry* IcnCursor_Impl::GoLeftRight( SvxIconChoiceCtrlEntry* pCtrlEntry, bool bRight )
     293             : {
     294             :     SvxIconChoiceCtrlEntry* pResult;
     295           0 :     pCurEntry = pCtrlEntry;
     296           0 :     Create();
     297           0 :     sal_uInt16 nY = pCtrlEntry->nY;
     298           0 :     sal_uInt16 nX = pCtrlEntry->nX;
     299             :     DBG_ASSERT(nY< nRows,"GoLeftRight:Bad column");
     300             :     DBG_ASSERT(nX< nCols,"GoLeftRight:Bad row");
     301             :     // neighbor in same row?
     302           0 :     if( bRight )
     303             :         pResult = SearchRow(
     304           0 :             nY, nX, sal::static_int_cast< sal_uInt16 >(nCols-1), nX, true, true );
     305             :     else
     306           0 :         pResult = SearchRow( nY, nX ,0, nX, false, true );
     307           0 :     if( pResult )
     308           0 :         return pResult;
     309             : 
     310           0 :     long nCurCol = nX;
     311             : 
     312             :     long nColOffs, nLastCol;
     313           0 :     if( bRight )
     314             :     {
     315           0 :         nColOffs = 1;
     316           0 :         nLastCol = nCols;
     317             :     }
     318             :     else
     319             :     {
     320           0 :         nColOffs = -1;
     321           0 :         nLastCol = -1;   // 0-1
     322             :     }
     323             : 
     324           0 :     sal_uInt16 nRowMin = nY;
     325           0 :     sal_uInt16 nRowMax = nY;
     326           0 :     do
     327             :     {
     328           0 :         SvxIconChoiceCtrlEntry* pEntry = SearchCol((sal_uInt16)nCurCol,nRowMin,nRowMax,nY,true, false);
     329           0 :         if( pEntry )
     330           0 :             return pEntry;
     331           0 :         if( nRowMin )
     332           0 :             nRowMin--;
     333           0 :         if( nRowMax < (nRows-1))
     334           0 :             nRowMax++;
     335           0 :         nCurCol += nColOffs;
     336             :     } while( nCurCol != nLastCol );
     337           0 :     return 0;
     338             : }
     339             : 
     340           0 : SvxIconChoiceCtrlEntry* IcnCursor_Impl::GoPageUpDown( SvxIconChoiceCtrlEntry* pStart, bool bDown)
     341             : {
     342           0 :     if( pView->IsAutoArrange() && !(pView->nWinBits & WB_ALIGN_TOP) )
     343             :     {
     344           0 :         const long nPos = (long)pView->GetEntryListPos( pStart );
     345           0 :         long nEntriesInView = (pView->aOutputSize.Height() / pView->nGridDY);
     346             :         nEntriesInView *=
     347           0 :             ((pView->aOutputSize.Width()+(pView->nGridDX/2)) / pView->nGridDX );
     348           0 :         long nNewPos = nPos;
     349           0 :         if( bDown )
     350             :         {
     351           0 :             nNewPos += nEntriesInView;
     352           0 :             if( nNewPos >= (long)pView->aEntries.size() )
     353           0 :                 nNewPos = pView->aEntries.size() - 1;
     354             :         }
     355             :         else
     356             :         {
     357           0 :             nNewPos -= nEntriesInView;
     358           0 :             if( nNewPos < 0 )
     359           0 :                 nNewPos = 0;
     360             :         }
     361           0 :         if( nPos != nNewPos )
     362           0 :             return pView->aEntries[ (size_t)nNewPos ];
     363           0 :         return 0;
     364             :     }
     365           0 :     long nOpt = pView->GetEntryBoundRect( pStart ).Top();
     366           0 :     if( bDown )
     367             :     {
     368           0 :         nOpt += pView->aOutputSize.Height();
     369           0 :         nOpt -= pView->nGridDY;
     370             :     }
     371             :     else
     372             :     {
     373           0 :         nOpt -= pView->aOutputSize.Height();
     374           0 :         nOpt += pView->nGridDY;
     375             :     }
     376           0 :     if( nOpt < 0 )
     377           0 :         nOpt = 0;
     378             : 
     379           0 :     long nPrevErr = LONG_MAX;
     380             : 
     381           0 :     SvxIconChoiceCtrlEntry* pPrev = pStart;
     382           0 :     SvxIconChoiceCtrlEntry* pNext = GoUpDown( pStart, bDown );
     383           0 :     while( pNext )
     384             :     {
     385           0 :         long nCur = pView->GetEntryBoundRect( pNext ).Top();
     386           0 :         long nErr = nOpt - nCur;
     387           0 :         if( nErr < 0 )
     388           0 :             nErr *= -1;
     389           0 :         if( nErr > nPrevErr )
     390           0 :             return pPrev;
     391           0 :         nPrevErr = nErr;
     392           0 :         pPrev = pNext;
     393           0 :         pNext = GoUpDown( pNext, bDown );
     394             :     }
     395           0 :     if( pPrev != pStart )
     396           0 :         return pPrev;
     397           0 :     return 0;
     398             : }
     399             : 
     400           0 : SvxIconChoiceCtrlEntry* IcnCursor_Impl::GoUpDown( SvxIconChoiceCtrlEntry* pCtrlEntry, bool bDown)
     401             : {
     402           0 :     if( pView->IsAutoArrange() && !(pView->nWinBits & WB_ALIGN_TOP) )
     403             :     {
     404           0 :         sal_uLong nPos = pView->GetEntryListPos( pCtrlEntry );
     405           0 :         if( bDown && nPos < (pView->aEntries.size() - 1) )
     406           0 :             return pView->aEntries[ nPos + 1 ];
     407           0 :         else if( !bDown && nPos > 0 )
     408           0 :             return pView->aEntries[ nPos - 1 ];
     409           0 :         return 0;
     410             :     }
     411             : 
     412             :     SvxIconChoiceCtrlEntry* pResult;
     413           0 :     pCurEntry = pCtrlEntry;
     414           0 :     Create();
     415           0 :     sal_uInt16 nY = pCtrlEntry->nY;
     416           0 :     sal_uInt16 nX = pCtrlEntry->nX;
     417             :     DBG_ASSERT(nY<nRows,"GoUpDown:Bad column");
     418             :     DBG_ASSERT(nX<nCols,"GoUpDown:Bad row");
     419             : 
     420             :     // neighbor in same column?
     421           0 :     if( bDown )
     422             :         pResult = SearchCol(
     423           0 :             nX, nY, sal::static_int_cast< sal_uInt16 >(nRows-1), nY, true, true );
     424             :     else
     425           0 :         pResult = SearchCol( nX, nY ,0, nY, false, true );
     426           0 :     if( pResult )
     427           0 :         return pResult;
     428             : 
     429           0 :     long nCurRow = nY;
     430             : 
     431             :     long nRowOffs, nLastRow;
     432           0 :     if( bDown )
     433             :     {
     434           0 :         nRowOffs = 1;
     435           0 :         nLastRow = nRows;
     436             :     }
     437             :     else
     438             :     {
     439           0 :         nRowOffs = -1;
     440           0 :         nLastRow = -1;   // 0-1
     441             :     }
     442             : 
     443           0 :     sal_uInt16 nColMin = nX;
     444           0 :     sal_uInt16 nColMax = nX;
     445           0 :     do
     446             :     {
     447           0 :         SvxIconChoiceCtrlEntry* pEntry = SearchRow((sal_uInt16)nCurRow,nColMin,nColMax,nX,true, false);
     448           0 :         if( pEntry )
     449           0 :             return pEntry;
     450           0 :         if( nColMin )
     451           0 :             nColMin--;
     452           0 :         if( nColMax < (nCols-1))
     453           0 :             nColMax++;
     454           0 :         nCurRow += nRowOffs;
     455             :     } while( nCurRow != nLastRow );
     456           0 :     return 0;
     457             : }
     458             : 
     459           0 : void IcnCursor_Impl::SetDeltas()
     460             : {
     461           0 :     const Size& rSize = pView->aVirtOutputSize;
     462           0 :     nCols = rSize.Width() / pView->nGridDX;
     463           0 :     if( !nCols )
     464           0 :         nCols = 1;
     465           0 :     nRows = rSize.Height() / pView->nGridDY;
     466           0 :     if( (nRows * pView->nGridDY) < rSize.Height() )
     467           0 :         nRows++;
     468           0 :     if( !nRows )
     469           0 :         nRows = 1;
     470             : 
     471           0 :     nDeltaWidth = (short)(rSize.Width() / nCols);
     472           0 :     nDeltaHeight = (short)(rSize.Height() / nRows);
     473           0 :     if( !nDeltaHeight )
     474             :     {
     475           0 :         nDeltaHeight = 1;
     476             :         DBG_WARNING("SetDeltas:Bad height");
     477             :     }
     478           0 :     if( !nDeltaWidth )
     479             :     {
     480           0 :         nDeltaWidth = 1;
     481             :         DBG_WARNING("SetDeltas:Bad width");
     482             :     }
     483           0 : }
     484             : 
     485           0 : void IcnCursor_Impl::CreateGridAjustData( IconChoiceMap& rLists, SvxIconChoiceCtrlEntry* pRefEntry)
     486             : {
     487           0 :     if( !pRefEntry )
     488             :     {
     489           0 :         sal_uInt16 nGridRows = (sal_uInt16)(pView->aVirtOutputSize.Height() / pView->nGridDY);
     490           0 :         nGridRows++; // because we round down later!
     491             : 
     492           0 :         if( !nGridRows )
     493           0 :             return;
     494           0 :         const size_t nCount = pView->aEntries.size();
     495           0 :         for( size_t nCur = 0; nCur < nCount; nCur++ )
     496             :         {
     497           0 :             SvxIconChoiceCtrlEntry* pEntry = pView->aEntries[ nCur ];
     498           0 :             const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     499           0 :             short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / pView->nGridDY );
     500           0 :             sal_uInt16 nIns = GetSortListPos( rLists[nY], rRect.Left(), false );
     501           0 :             rLists[ nY ].insert( rLists[ nY ].begin() + nIns, pEntry );
     502             :         }
     503             :     }
     504             :     else
     505             :     {
     506             :         // build a horizontal "tube" in the RefEntry line
     507             :         // STOP AND THINK: maybe use bounding rectangle because of overlaps?
     508           0 :         Rectangle rRefRect( pView->CalcBmpRect( pRefEntry ) );
     509             :         //const Rectangle& rRefRect = pView->GetEntryBoundRect( pRefEntry );
     510           0 :         short nRefRow = (short)( ((rRefRect.Top()+rRefRect.Bottom())/2) / pView->nGridDY );
     511           0 :         SvxIconChoiceCtrlEntryPtrVec& rRow = rLists[0];
     512           0 :         size_t nCount = pView->aEntries.size();
     513           0 :         for( size_t nCur = 0; nCur < nCount; nCur++ )
     514             :         {
     515           0 :             SvxIconChoiceCtrlEntry* pEntry = pView->aEntries[ nCur ];
     516           0 :             Rectangle rRect( pView->CalcBmpRect(pEntry) );
     517             :             //const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     518           0 :             short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / pView->nGridDY );
     519           0 :             if( nY == nRefRow )
     520             :             {
     521           0 :                 sal_uInt16 nIns = GetSortListPos( rRow, rRect.Left(), false );
     522           0 :                 rRow.insert( rRow.begin() + nIns, pEntry );
     523             :             }
     524             :         }
     525             :     }
     526             : }
     527             : 
     528             : //static
     529           0 : void IcnCursor_Impl::DestroyGridAdjustData( IconChoiceMap& rLists )
     530             : {
     531           0 :     rLists.clear();
     532           0 : }
     533             : 
     534           7 : IcnGridMap_Impl::IcnGridMap_Impl(SvxIconChoiceCtrl_Impl* pView)
     535             : {
     536           7 :     _pView = pView;
     537           7 :     _pGridMap = 0;
     538           7 :     _nGridCols = 0;
     539           7 :     _nGridRows = 0;
     540           7 : }
     541             : 
     542           5 : IcnGridMap_Impl::~IcnGridMap_Impl()
     543             : {
     544           5 :     delete[] _pGridMap, _pGridMap=0;
     545           5 : }
     546             : 
     547           0 : void IcnGridMap_Impl::Expand()
     548             : {
     549           0 :     if( !_pGridMap )
     550           0 :         Create_Impl();
     551             :     else
     552             :     {
     553           0 :         sal_uInt16 nNewGridRows = _nGridRows;
     554           0 :         sal_uInt16 nNewGridCols = _nGridCols;
     555           0 :         if( _pView->nWinBits & WB_ALIGN_TOP )
     556           0 :             nNewGridRows += 50;
     557             :         else
     558           0 :             nNewGridCols += 50;
     559             : 
     560           0 :         size_t nNewCellCount = static_cast<size_t>(nNewGridRows) * nNewGridCols;
     561           0 :         bool* pNewGridMap = new bool[nNewCellCount];
     562           0 :         memset(pNewGridMap, 0, nNewCellCount * sizeof(bool));
     563           0 :         size_t nOldCellCount = static_cast<size_t>(_nGridRows) * _nGridCols;
     564           0 :         memcpy(pNewGridMap, _pGridMap, nOldCellCount * sizeof(bool));
     565           0 :         delete[] _pGridMap;
     566           0 :         _pGridMap = pNewGridMap;
     567           0 :         _nGridRows = nNewGridRows;
     568           0 :         _nGridCols = nNewGridCols;
     569             :     }
     570           0 : }
     571             : 
     572          65 : void IcnGridMap_Impl::Create_Impl()
     573             : {
     574             :     DBG_ASSERT(!_pGridMap,"Unnecessary call to IcnGridMap_Impl::Create_Impl()");
     575          65 :     if( _pGridMap )
     576          65 :         return;
     577          65 :     GetMinMapSize( _nGridCols, _nGridRows );
     578          65 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     579           0 :         _nGridRows += 50;  // avoid resize of gridmap too often
     580             :     else
     581          65 :         _nGridCols += 50;
     582             : 
     583          65 :     size_t nCellCount = static_cast<size_t>(_nGridRows) * _nGridCols;
     584          65 :     _pGridMap = new bool[nCellCount];
     585          65 :     memset(_pGridMap, 0, nCellCount * sizeof(bool));
     586             : 
     587          65 :     const size_t nCount = _pView->aEntries.size();
     588         304 :     for( size_t nCur=0; nCur < nCount; nCur++ )
     589         239 :         OccupyGrids( _pView->aEntries[ nCur ] );
     590             : }
     591             : 
     592         347 : void IcnGridMap_Impl::GetMinMapSize( sal_uInt16& rDX, sal_uInt16& rDY ) const
     593             : {
     594             :     long nX, nY;
     595         347 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     596             :     {
     597             :         // The view grows in vertical direction. Its max. width is _pView->nMaxVirtWidth
     598           0 :         nX = _pView->nMaxVirtWidth;
     599           0 :         if( !nX )
     600           0 :             nX = _pView->pView->GetOutputSizePixel().Width();
     601           0 :         if( !(_pView->nFlags & F_ARRANGING) )
     602           0 :             nX -= _pView->nVerSBarWidth;
     603             : 
     604           0 :         nY = _pView->aVirtOutputSize.Height();
     605             :     }
     606             :     else
     607             :     {
     608             :         // The view grows in horizontal direction. Its max. height is _pView->nMaxVirtHeight
     609         347 :         nY = _pView->nMaxVirtHeight;
     610         347 :         if( !nY )
     611           0 :             nY = _pView->pView->GetOutputSizePixel().Height();
     612         347 :         if( !(_pView->nFlags & F_ARRANGING) )
     613          57 :             nY -= _pView->nHorSBarHeight;
     614         347 :         nX = _pView->aVirtOutputSize.Width();
     615             :     }
     616             : 
     617         347 :     if( !nX )
     618          65 :         nX = DEFAULT_MAX_VIRT_WIDTH;
     619         347 :     if( !nY )
     620           0 :         nY = DEFAULT_MAX_VIRT_HEIGHT;
     621             : 
     622         347 :     long nDX = nX / _pView->nGridDX;
     623         347 :     long nDY = nY / _pView->nGridDY;
     624             : 
     625         347 :     if( !nDX )
     626           0 :         nDX++;
     627         347 :     if( !nDY )
     628           0 :         nDY++;
     629             : 
     630         347 :     rDX = (sal_uInt16)nDX;
     631         347 :     rDY = (sal_uInt16)nDY;
     632         347 : }
     633             : 
     634         288 : GridId IcnGridMap_Impl::GetGrid( sal_uInt16 nGridX, sal_uInt16 nGridY )
     635             : {
     636         288 :     Create();
     637         288 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     638           0 :         return nGridX + ( static_cast<GridId>(nGridY) * _nGridCols );
     639             :     else
     640         288 :         return nGridY + ( static_cast<GridId>(nGridX) * _nGridRows );
     641             : }
     642             : 
     643         288 : GridId IcnGridMap_Impl::GetGrid( const Point& rDocPos, bool* pbClipped )
     644             : {
     645         288 :     Create();
     646             : 
     647         288 :     long nX = rDocPos.X();
     648         288 :     long nY = rDocPos.Y();
     649         288 :     nX -= LROFFS_WINBORDER;
     650         288 :     nY -= TBOFFS_WINBORDER;
     651         288 :     nX /= _pView->nGridDX;
     652         288 :     nY /= _pView->nGridDY;
     653         288 :     bool bClipped = false;
     654         288 :     if( nX >= _nGridCols )
     655             :     {
     656           0 :         nX = _nGridCols - 1;
     657           0 :         bClipped = true;
     658             :     }
     659         288 :     if( nY >= _nGridRows )
     660             :     {
     661           0 :         nY = _nGridRows - 1;
     662           0 :         bClipped = true;
     663             :     }
     664         288 :     GridId nId = GetGrid( (sal_uInt16)nX, (sal_uInt16)nY );
     665         288 :     if( pbClipped )
     666           0 :         *pbClipped = bClipped;
     667             :     DBG_ASSERT(nId <(sal_uLong)(_nGridCols*_nGridRows),"GetGrid failed");
     668         288 :     return nId;
     669             : }
     670             : 
     671         260 : Rectangle IcnGridMap_Impl::GetGridRect( GridId nId )
     672             : {
     673         260 :     Create();
     674             :     sal_uInt16 nGridX, nGridY;
     675         260 :     GetGridCoord( nId, nGridX, nGridY );
     676         260 :     const long nLeft = nGridX * _pView->nGridDX+ LROFFS_WINBORDER;
     677         260 :     const long nTop = nGridY * _pView->nGridDY + TBOFFS_WINBORDER;
     678             :     return Rectangle(
     679             :         nLeft, nTop,
     680             :         nLeft + _pView->nGridDX,
     681         260 :         nTop + _pView->nGridDY );
     682             : }
     683             : 
     684         260 : GridId IcnGridMap_Impl::GetUnoccupiedGrid( bool bOccupyFound )
     685             : {
     686         260 :     Create();
     687         260 :     sal_uLong nStart = 0;
     688         260 :     bool bExpanded = false;
     689             : 
     690             :     while( true )
     691             :     {
     692         260 :         const sal_uLong nCount = (sal_uInt16)(_nGridCols * _nGridRows);
     693         650 :         for( sal_uLong nCur = nStart; nCur < nCount; nCur++ )
     694             :         {
     695         650 :             if( !_pGridMap[ nCur ] )
     696             :             {
     697         260 :                 if( bOccupyFound )
     698         260 :                     _pGridMap[ nCur ] = true;
     699         260 :                 return (GridId)nCur;
     700             :             }
     701             :         }
     702             :         DBG_ASSERT(!bExpanded,"ExpandGrid failed");
     703           0 :         if( bExpanded )
     704           0 :             return 0; // prevent never ending loop
     705           0 :         bExpanded = true;
     706           0 :         Expand();
     707           0 :         nStart = nCount;
     708           0 :     }
     709             : }
     710             : 
     711             : // An entry only means that there's a GridRect lying under its center. This
     712             : // variant is much faster than allocating via the bounding rectangle but can
     713             : // lead to small overlaps.
     714         527 : void IcnGridMap_Impl::OccupyGrids( const SvxIconChoiceCtrlEntry* pEntry, bool bOccupy )
     715             : {
     716         527 :     if( !_pGridMap || !SvxIconChoiceCtrl_Impl::IsBoundingRectValid( pEntry->aRect ))
     717         766 :         return;
     718         288 :     OccupyGrid( GetGrid( pEntry->aRect.Center()), bOccupy );
     719             : }
     720             : 
     721          63 : void IcnGridMap_Impl::Clear()
     722             : {
     723          63 :     if( _pGridMap )
     724             :     {
     725          63 :         delete[] _pGridMap, _pGridMap=0;
     726          63 :         _nGridRows = 0;
     727          63 :         _nGridCols = 0;
     728          63 :         _aLastOccupiedGrid.SetEmpty();
     729             :     }
     730          63 : }
     731             : 
     732           0 : sal_uLong IcnGridMap_Impl::GetGridCount( const Size& rSizePixel, sal_uInt16 nDX, sal_uInt16 nDY)
     733             : {
     734           0 :     long ndx = (rSizePixel.Width() - LROFFS_WINBORDER) / nDX;
     735           0 :     if( ndx < 0 ) ndx *= -1;
     736           0 :     long ndy = (rSizePixel.Height() - TBOFFS_WINBORDER) / nDY;
     737           0 :     if( ndy < 0 ) ndy *= -1;
     738           0 :     return (sal_uLong)(ndx * ndy);
     739             : }
     740             : 
     741         282 : void IcnGridMap_Impl::OutputSizeChanged()
     742             : {
     743         282 :     if( _pGridMap )
     744             :     {
     745             :         sal_uInt16 nCols, nRows;
     746         282 :         GetMinMapSize( nCols, nRows );
     747         282 :         if( _pView->nWinBits & WB_ALIGN_TOP )
     748             :         {
     749           0 :             if( nCols != _nGridCols )
     750           0 :                 Clear();
     751           0 :             else if( nRows >= _nGridRows )
     752           0 :                 Expand();
     753             :         }
     754             :         else
     755             :         {
     756         282 :             if( nRows != _nGridRows )
     757           0 :                 Clear();
     758         282 :             else if( nCols >= _nGridCols )
     759           0 :                 Expand();
     760             :         }
     761             :     }
     762         282 : }
     763             : 
     764             : // Independently of the view's alignment (TOP or LEFT), the gridmap
     765             : // should contain the data in a continuous region, to make it possible
     766             : // to copy the whole block if the gridmap needs to be expanded.
     767         260 : void IcnGridMap_Impl::GetGridCoord( GridId nId, sal_uInt16& rGridX, sal_uInt16& rGridY )
     768             : {
     769         260 :     Create();
     770         260 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     771             :     {
     772           0 :         rGridX = (sal_uInt16)(nId % _nGridCols);
     773           0 :         rGridY = (sal_uInt16)(nId / _nGridCols);
     774             :     }
     775             :     else
     776             :     {
     777         260 :         rGridX = (sal_uInt16)(nId / _nGridRows);
     778         260 :         rGridY = (sal_uInt16)(nId % _nGridRows);
     779             :     }
     780         260 : }
     781             : 
     782             : 
     783             : 
     784             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11