LCOV - code coverage report
Current view: top level - svtools/source/contnr - imivctl2.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 448 0.0 %
Date: 2014-04-14 Functions: 0 27 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "imivctl.hxx"
      21             : 
      22           0 : IcnCursor_Impl::IcnCursor_Impl( SvxIconChoiceCtrl_Impl* pOwner )
      23             : {
      24           0 :     pView       = pOwner;
      25           0 :     pCurEntry   = 0;
      26           0 :     nDeltaWidth = 0;
      27           0 :     nDeltaHeight= 0;
      28           0 :     nCols       = 0;
      29           0 :     nRows       = 0;
      30           0 : }
      31             : 
      32           0 : IcnCursor_Impl::~IcnCursor_Impl()
      33             : {
      34           0 : }
      35             : 
      36           0 : sal_uInt16 IcnCursor_Impl::GetSortListPos( SvxIconChoiceCtrlEntryPtrVec& rList, long nValue,
      37             :     int 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(pColumns==0&&pRows==0,"ImplCreate: Not cleared");
      66             : 
      67           0 :     SetDeltas();
      68             : 
      69           0 :     pColumns.reset(new IconChoiceMap);
      70           0 :     pRows.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 = (*pColumns)[nX];
      88           0 :         sal_uInt16 nIns = GetSortListPos( rColEntry, rRect.Top(), sal_True );
      89           0 :         rColEntry.insert( rColEntry.begin() + nIns, pEntry );
      90             : 
      91           0 :         SvxIconChoiceCtrlEntryPtrVec& rRowEntry = (*pRows)[nY];
      92           0 :         nIns = GetSortListPos( rRowEntry, rRect.Left(), sal_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           0 : void IcnCursor_Impl::Clear()
     104             : {
     105           0 :     if( pColumns )
     106             :     {
     107           0 :         pColumns.reset();
     108           0 :         pRows.reset();
     109           0 :         pCurEntry = 0;
     110           0 :         nDeltaWidth = 0;
     111           0 :         nDeltaHeight = 0;
     112             :     }
     113           0 : }
     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 = pColumns->find( nCol );
     120           0 :     if ( mapIt == pColumns->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 = pRows->find( nRow );
     199           0 :     if ( mapIt == pRows->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, sal_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, sal_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, sal_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(), sal_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(), sal_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           0 : IcnGridMap_Impl::IcnGridMap_Impl(SvxIconChoiceCtrl_Impl* pView)
     535             : {
     536           0 :     _pView = pView;
     537           0 :     _pGridMap = 0;
     538           0 :     _nGridCols = 0;
     539           0 :     _nGridRows = 0;
     540           0 : }
     541             : 
     542           0 : IcnGridMap_Impl::~IcnGridMap_Impl()
     543             : {
     544           0 :     delete[] _pGridMap, _pGridMap=0;
     545           0 : }
     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 :         sal_Bool* pNewGridMap = new sal_Bool[nNewGridRows*nNewGridCols];
     561           0 :         memset( pNewGridMap, 0, nNewGridRows * nNewGridCols * sizeof(sal_Bool) );
     562           0 :         memcpy( pNewGridMap, _pGridMap, _nGridRows * _nGridCols * sizeof(sal_Bool) );
     563           0 :         delete[] _pGridMap;
     564           0 :         _pGridMap = pNewGridMap;
     565           0 :         _nGridRows = nNewGridRows;
     566           0 :         _nGridCols = nNewGridCols;
     567             :     }
     568           0 : }
     569             : 
     570           0 : void IcnGridMap_Impl::Create_Impl()
     571             : {
     572             :     DBG_ASSERT(!_pGridMap,"Unnecessary call to IcnGridMap_Impl::Create_Impl()");
     573           0 :     if( _pGridMap )
     574           0 :         return;
     575           0 :     GetMinMapSize( _nGridCols, _nGridRows );
     576           0 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     577           0 :         _nGridRows += 50;  // avoid resize of gridmap too often
     578             :     else
     579           0 :         _nGridCols += 50;
     580             : 
     581           0 :     _pGridMap = new sal_Bool[ _nGridRows * _nGridCols];
     582           0 :     memset( (void*)_pGridMap, 0, _nGridRows * _nGridCols );
     583             : 
     584           0 :     const size_t nCount = _pView->aEntries.size();
     585           0 :     for( size_t nCur=0; nCur < nCount; nCur++ )
     586           0 :         OccupyGrids( _pView->aEntries[ nCur ] );
     587             : }
     588             : 
     589           0 : void IcnGridMap_Impl::GetMinMapSize( sal_uInt16& rDX, sal_uInt16& rDY ) const
     590             : {
     591             :     long nX, nY;
     592           0 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     593             :     {
     594             :         // The view grows in vertical direction. Its max. width is _pView->nMaxVirtWidth
     595           0 :         nX = _pView->nMaxVirtWidth;
     596           0 :         if( !nX )
     597           0 :             nX = _pView->pView->GetOutputSizePixel().Width();
     598           0 :         if( !(_pView->nFlags & F_ARRANGING) )
     599           0 :             nX -= _pView->nVerSBarWidth;
     600             : 
     601           0 :         nY = _pView->aVirtOutputSize.Height();
     602             :     }
     603             :     else
     604             :     {
     605             :         // The view grows in horizontal direction. Its max. height is _pView->nMaxVirtHeight
     606           0 :         nY = _pView->nMaxVirtHeight;
     607           0 :         if( !nY )
     608           0 :             nY = _pView->pView->GetOutputSizePixel().Height();
     609           0 :         if( !(_pView->nFlags & F_ARRANGING) )
     610           0 :             nY -= _pView->nHorSBarHeight;
     611           0 :         nX = _pView->aVirtOutputSize.Width();
     612             :     }
     613             : 
     614           0 :     if( !nX )
     615           0 :         nX = DEFAULT_MAX_VIRT_WIDTH;
     616           0 :     if( !nY )
     617           0 :         nY = DEFAULT_MAX_VIRT_HEIGHT;
     618             : 
     619           0 :     long nDX = nX / _pView->nGridDX;
     620           0 :     long nDY = nY / _pView->nGridDY;
     621             : 
     622           0 :     if( !nDX )
     623           0 :         nDX++;
     624           0 :     if( !nDY )
     625           0 :         nDY++;
     626             : 
     627           0 :     rDX = (sal_uInt16)nDX;
     628           0 :     rDY = (sal_uInt16)nDY;
     629           0 : }
     630             : 
     631           0 : GridId IcnGridMap_Impl::GetGrid( sal_uInt16 nGridX, sal_uInt16 nGridY )
     632             : {
     633           0 :     Create();
     634           0 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     635           0 :         return nGridX + ( nGridY * _nGridCols );
     636             :     else
     637           0 :         return nGridY + ( nGridX * _nGridRows );
     638             : }
     639             : 
     640           0 : GridId IcnGridMap_Impl::GetGrid( const Point& rDocPos, sal_Bool* pbClipped )
     641             : {
     642           0 :     Create();
     643             : 
     644           0 :     long nX = rDocPos.X();
     645           0 :     long nY = rDocPos.Y();
     646           0 :     nX -= LROFFS_WINBORDER;
     647           0 :     nY -= TBOFFS_WINBORDER;
     648           0 :     nX /= _pView->nGridDX;
     649           0 :     nY /= _pView->nGridDY;
     650           0 :     sal_Bool bClipped = sal_False;
     651           0 :     if( nX >= _nGridCols )
     652             :     {
     653           0 :         nX = _nGridCols - 1;
     654           0 :         bClipped = sal_True;
     655             :     }
     656           0 :     if( nY >= _nGridRows )
     657             :     {
     658           0 :         nY = _nGridRows - 1;
     659           0 :         bClipped = sal_True;
     660             :     }
     661           0 :     GridId nId = GetGrid( (sal_uInt16)nX, (sal_uInt16)nY );
     662           0 :     if( pbClipped )
     663           0 :         *pbClipped = bClipped;
     664             :     DBG_ASSERT(nId <(sal_uLong)(_nGridCols*_nGridRows),"GetGrid failed");
     665           0 :     return nId;
     666             : }
     667             : 
     668           0 : Rectangle IcnGridMap_Impl::GetGridRect( GridId nId )
     669             : {
     670           0 :     Create();
     671             :     sal_uInt16 nGridX, nGridY;
     672           0 :     GetGridCoord( nId, nGridX, nGridY );
     673           0 :     const long nLeft = nGridX * _pView->nGridDX+ LROFFS_WINBORDER;
     674           0 :     const long nTop = nGridY * _pView->nGridDY + TBOFFS_WINBORDER;
     675             :     return Rectangle(
     676             :         nLeft, nTop,
     677             :         nLeft + _pView->nGridDX,
     678           0 :         nTop + _pView->nGridDY );
     679             : }
     680             : 
     681           0 : GridId IcnGridMap_Impl::GetUnoccupiedGrid( sal_Bool bOccupyFound )
     682             : {
     683           0 :     Create();
     684           0 :     sal_uLong nStart = 0;
     685           0 :     sal_Bool bExpanded = sal_False;
     686             : 
     687             :     while( true )
     688             :     {
     689           0 :         const sal_uLong nCount = (sal_uInt16)(_nGridCols * _nGridRows);
     690           0 :         for( sal_uLong nCur = nStart; nCur < nCount; nCur++ )
     691             :         {
     692           0 :             if( !_pGridMap[ nCur ] )
     693             :             {
     694           0 :                 if( bOccupyFound )
     695           0 :                     _pGridMap[ nCur ] = sal_True;
     696           0 :                 return (GridId)nCur;
     697             :             }
     698             :         }
     699             :         DBG_ASSERT(!bExpanded,"ExpandGrid failed");
     700           0 :         if( bExpanded )
     701           0 :             return 0; // prevent never ending loop
     702           0 :         bExpanded = sal_True;
     703           0 :         Expand();
     704           0 :         nStart = nCount;
     705           0 :     }
     706             : }
     707             : 
     708             : // An entry only means that there's a GridRect lying under its center. This
     709             : // variant is much faster than allocating via the bounding rectangle but can
     710             : // lead to small overlaps.
     711           0 : void IcnGridMap_Impl::OccupyGrids( const SvxIconChoiceCtrlEntry* pEntry, sal_Bool bOccupy )
     712             : {
     713           0 :     if( !_pGridMap || !_pView->IsBoundingRectValid( pEntry->aRect ))
     714           0 :         return;
     715           0 :     OccupyGrid( GetGrid( pEntry->aRect.Center()), bOccupy );
     716             : }
     717             : 
     718           0 : void IcnGridMap_Impl::Clear()
     719             : {
     720           0 :     if( _pGridMap )
     721             :     {
     722           0 :         delete[] _pGridMap, _pGridMap=0;
     723           0 :         _nGridRows = 0;
     724           0 :         _nGridCols = 0;
     725           0 :         _aLastOccupiedGrid.SetEmpty();
     726             :     }
     727           0 : }
     728             : 
     729           0 : sal_uLong IcnGridMap_Impl::GetGridCount( const Size& rSizePixel, sal_uInt16 nDX, sal_uInt16 nDY)
     730             : {
     731           0 :     long ndx = (rSizePixel.Width() - LROFFS_WINBORDER) / nDX;
     732           0 :     if( ndx < 0 ) ndx *= -1;
     733           0 :     long ndy = (rSizePixel.Height() - TBOFFS_WINBORDER) / nDY;
     734           0 :     if( ndy < 0 ) ndy *= -1;
     735           0 :     return (sal_uLong)(ndx * ndy);
     736             : }
     737             : 
     738           0 : void IcnGridMap_Impl::OutputSizeChanged()
     739             : {
     740           0 :     if( _pGridMap )
     741             :     {
     742             :         sal_uInt16 nCols, nRows;
     743           0 :         GetMinMapSize( nCols, nRows );
     744           0 :         if( _pView->nWinBits & WB_ALIGN_TOP )
     745             :         {
     746           0 :             if( nCols != _nGridCols )
     747           0 :                 Clear();
     748           0 :             else if( nRows >= _nGridRows )
     749           0 :                 Expand();
     750             :         }
     751             :         else
     752             :         {
     753           0 :             if( nRows != _nGridRows )
     754           0 :                 Clear();
     755           0 :             else if( nCols >= _nGridCols )
     756           0 :                 Expand();
     757             :         }
     758             :     }
     759           0 : }
     760             : 
     761             : // Independently of the view's alignment (TOP or LEFT), the gridmap
     762             : // should contain the data in a continuous region, to make it possible
     763             : // to copy the whole block if the gridmap needs to be expanded.
     764           0 : void IcnGridMap_Impl::GetGridCoord( GridId nId, sal_uInt16& rGridX, sal_uInt16& rGridY )
     765             : {
     766           0 :     Create();
     767           0 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     768             :     {
     769           0 :         rGridX = (sal_uInt16)(nId % _nGridCols);
     770           0 :         rGridY = (sal_uInt16)(nId / _nGridCols);
     771             :     }
     772             :     else
     773             :     {
     774           0 :         rGridX = (sal_uInt16)(nId / _nGridRows);
     775           0 :         rGridY = (sal_uInt16)(nId % _nGridRows);
     776             :     }
     777           0 : }
     778             : 
     779             : 
     780             : 
     781             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10