LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/contnr - imivctl2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 444 0.0 %
Date: 2012-12-27 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             :         DBG_ASSERT( it != rList.end(), "Entry not in Col-List" );
     133           0 :         if( bDown )
     134             :         {
     135           0 :             while( ++it != rList.end() )
     136             :             {
     137           0 :                 SvxIconChoiceCtrlEntry* pEntry = *it;
     138           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     139           0 :                 if( rRect.Top() > rRefRect.Top() )
     140           0 :                     return pEntry;
     141             :             }
     142           0 :             return 0;
     143             :         }
     144             :         else
     145             :         {
     146           0 :             SvxIconChoiceCtrlEntryPtrVec::const_reverse_iterator it2(it);
     147           0 :             while (it2 != rList.rend())
     148             :             {
     149           0 :                 SvxIconChoiceCtrlEntry* pEntry = *it2;
     150           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     151           0 :                 if( rRect.Top() < rRefRect.Top() )
     152           0 :                     return pEntry;
     153           0 :                 ++it2;
     154             :             }
     155           0 :             return 0;
     156             :         }
     157             :     }
     158             : 
     159           0 :     if( nTop > nBottom )
     160             :     {
     161           0 :         sal_uInt16 nTemp = nTop;
     162           0 :         nTop = nBottom;
     163           0 :         nBottom = nTemp;
     164             :     }
     165           0 :     long nMinDistance = LONG_MAX;
     166           0 :     SvxIconChoiceCtrlEntry* pResult = 0;
     167           0 :     for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ )
     168             :     {
     169           0 :         SvxIconChoiceCtrlEntry* pEntry = rList[ nCur ];
     170           0 :         if( pEntry != pCurEntry )
     171             :         {
     172           0 :             sal_uInt16 nY = pEntry->nY;
     173           0 :             if( nY >= nTop && nY <= nBottom )
     174             :             {
     175           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     176           0 :                 long nDistance = rRect.Top() - rRefRect.Top();
     177           0 :                 if( nDistance < 0 )
     178           0 :                     nDistance *= -1;
     179           0 :                 if( nDistance && nDistance < nMinDistance )
     180             :                 {
     181           0 :                     nMinDistance = nDistance;
     182           0 :                     pResult = pEntry;
     183             :                 }
     184             :             }
     185             :         }
     186             :     }
     187           0 :     return pResult;
     188             : }
     189             : 
     190           0 : SvxIconChoiceCtrlEntry* IcnCursor_Impl::SearchRow(sal_uInt16 nRow, sal_uInt16 nLeft, sal_uInt16 nRight,
     191             :     sal_uInt16, bool bRight, bool bSimple )
     192             : {
     193             :     DBG_ASSERT(pCurEntry,"SearchRow: No reference entry");
     194           0 :     IconChoiceMap::iterator mapIt = pRows->find( nRow );
     195           0 :     if ( mapIt == pRows->end() )
     196           0 :         return 0;
     197           0 :     SvxIconChoiceCtrlEntryPtrVec const & rList = mapIt->second;
     198           0 :     const sal_uInt16 nCount = rList.size();
     199           0 :     if( !nCount )
     200           0 :         return 0;
     201             : 
     202           0 :     const Rectangle& rRefRect = pView->GetEntryBoundRect(pCurEntry);
     203             : 
     204           0 :     if( bSimple )
     205             :     {
     206           0 :         SvxIconChoiceCtrlEntryPtrVec::const_iterator it = std::find( rList.begin(), rList.end(), pCurEntry );
     207             :         DBG_ASSERT( it != rList.end(), "Entry not in Row-List" );
     208           0 :         if( bRight )
     209             :         {
     210           0 :             while( ++it != rList.end() )
     211             :             {
     212           0 :                 SvxIconChoiceCtrlEntry* pEntry = *it;
     213           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     214           0 :                 if( rRect.Left() > rRefRect.Left() )
     215           0 :                     return pEntry;
     216             :             }
     217           0 :             return 0;
     218             :         }
     219             :         else
     220             :         {
     221           0 :             SvxIconChoiceCtrlEntryPtrVec::const_reverse_iterator it2(it);
     222           0 :             while (it2 != rList.rend())
     223             :             {
     224           0 :                 SvxIconChoiceCtrlEntry* pEntry = *it2;
     225           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     226           0 :                 if( rRect.Left() < rRefRect.Left() )
     227           0 :                     return pEntry;
     228           0 :                 ++it2;
     229             :             }
     230           0 :             return 0;
     231             :         }
     232             : 
     233             :     }
     234           0 :     if( nRight < nLeft )
     235             :     {
     236           0 :         sal_uInt16 nTemp = nRight;
     237           0 :         nRight = nLeft;
     238           0 :         nLeft = nTemp;
     239             :     }
     240           0 :     long nMinDistance = LONG_MAX;
     241           0 :     SvxIconChoiceCtrlEntry* pResult = 0;
     242           0 :     for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ )
     243             :     {
     244           0 :         SvxIconChoiceCtrlEntry* pEntry = rList[ nCur ];
     245           0 :         if( pEntry != pCurEntry )
     246             :         {
     247           0 :             sal_uInt16 nX = pEntry->nX;
     248           0 :             if( nX >= nLeft && nX <= nRight )
     249             :             {
     250           0 :                 const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     251           0 :                 long nDistance = rRect.Left() - rRefRect.Left();
     252           0 :                 if( nDistance < 0 )
     253           0 :                     nDistance *= -1;
     254           0 :                 if( nDistance && nDistance < nMinDistance )
     255             :                 {
     256           0 :                     nMinDistance = nDistance;
     257           0 :                     pResult = pEntry;
     258             :                 }
     259             :             }
     260             :         }
     261             :     }
     262           0 :     return pResult;
     263             : }
     264             : 
     265             : 
     266             : 
     267             : /*
     268             :     Searches, starting from the passed value, the next entry to the left/to the
     269             :     right. Example for bRight = sal_True:
     270             : 
     271             :                   c
     272             :                 b c
     273             :               a b c
     274             :             S 1 1 1      ====> search direction
     275             :               a b c
     276             :                 b c
     277             :                   c
     278             : 
     279             :     S : starting position
     280             :     1 : first searched rectangle
     281             :     a,b,c : 2nd, 3rd, 4th searched rectangle
     282             : */
     283             : 
     284           0 : SvxIconChoiceCtrlEntry* IcnCursor_Impl::GoLeftRight( SvxIconChoiceCtrlEntry* pCtrlEntry, sal_Bool bRight )
     285             : {
     286             :     SvxIconChoiceCtrlEntry* pResult;
     287           0 :     pCurEntry = pCtrlEntry;
     288           0 :     Create();
     289           0 :     sal_uInt16 nY = pCtrlEntry->nY;
     290           0 :     sal_uInt16 nX = pCtrlEntry->nX;
     291             :     DBG_ASSERT(nY< nRows,"GoLeftRight:Bad column");
     292             :     DBG_ASSERT(nX< nCols,"GoLeftRight:Bad row");
     293             :     // neighbor in same row?
     294           0 :     if( bRight )
     295             :         pResult = SearchRow(
     296           0 :             nY, nX, sal::static_int_cast< sal_uInt16 >(nCols-1), nX, sal_True, sal_True );
     297             :     else
     298           0 :         pResult = SearchRow( nY, nX ,0, nX, sal_False, sal_True );
     299           0 :     if( pResult )
     300           0 :         return pResult;
     301             : 
     302           0 :     long nCurCol = nX;
     303             : 
     304             :     long nColOffs, nLastCol;
     305           0 :     if( bRight )
     306             :     {
     307           0 :         nColOffs = 1;
     308           0 :         nLastCol = nCols;
     309             :     }
     310             :     else
     311             :     {
     312           0 :         nColOffs = -1;
     313           0 :         nLastCol = -1;   // 0-1
     314             :     }
     315             : 
     316           0 :     sal_uInt16 nRowMin = nY;
     317           0 :     sal_uInt16 nRowMax = nY;
     318           0 :     do
     319             :     {
     320           0 :         SvxIconChoiceCtrlEntry* pEntry = SearchCol((sal_uInt16)nCurCol,nRowMin,nRowMax,nY,sal_True, sal_False);
     321           0 :         if( pEntry )
     322           0 :             return pEntry;
     323           0 :         if( nRowMin )
     324           0 :             nRowMin--;
     325           0 :         if( nRowMax < (nRows-1))
     326           0 :             nRowMax++;
     327           0 :         nCurCol += nColOffs;
     328             :     } while( nCurCol != nLastCol );
     329           0 :     return 0;
     330             : }
     331             : 
     332           0 : SvxIconChoiceCtrlEntry* IcnCursor_Impl::GoPageUpDown( SvxIconChoiceCtrlEntry* pStart, sal_Bool bDown)
     333             : {
     334           0 :     if( pView->IsAutoArrange() && !(pView->nWinBits & WB_ALIGN_TOP) )
     335             :     {
     336           0 :         const long nPos = (long)pView->GetEntryListPos( pStart );
     337           0 :         long nEntriesInView = (pView->aOutputSize.Height() / pView->nGridDY);
     338             :         nEntriesInView *=
     339           0 :             ((pView->aOutputSize.Width()+(pView->nGridDX/2)) / pView->nGridDX );
     340           0 :         long nNewPos = nPos;
     341           0 :         if( bDown )
     342             :         {
     343           0 :             nNewPos += nEntriesInView;
     344           0 :             if( nNewPos >= (long)pView->aEntries.size() )
     345           0 :                 nNewPos = pView->aEntries.size() - 1;
     346             :         }
     347             :         else
     348             :         {
     349           0 :             nNewPos -= nEntriesInView;
     350           0 :             if( nNewPos < 0 )
     351           0 :                 nNewPos = 0;
     352             :         }
     353           0 :         if( nPos != nNewPos )
     354           0 :             return pView->aEntries[ (size_t)nNewPos ];
     355           0 :         return 0;
     356             :     }
     357           0 :     long nOpt = pView->GetEntryBoundRect( pStart ).Top();
     358           0 :     if( bDown )
     359             :     {
     360           0 :         nOpt += pView->aOutputSize.Height();
     361           0 :         nOpt -= pView->nGridDY;
     362             :     }
     363             :     else
     364             :     {
     365           0 :         nOpt -= pView->aOutputSize.Height();
     366           0 :         nOpt += pView->nGridDY;
     367             :     }
     368           0 :     if( nOpt < 0 )
     369           0 :         nOpt = 0;
     370             : 
     371           0 :     long nPrevErr = LONG_MAX;
     372             : 
     373           0 :     SvxIconChoiceCtrlEntry* pPrev = pStart;
     374           0 :     SvxIconChoiceCtrlEntry* pNext = GoUpDown( pStart, bDown );
     375           0 :     while( pNext )
     376             :     {
     377           0 :         long nCur = pView->GetEntryBoundRect( pNext ).Top();
     378           0 :         long nErr = nOpt - nCur;
     379           0 :         if( nErr < 0 )
     380           0 :             nErr *= -1;
     381           0 :         if( nErr > nPrevErr )
     382           0 :             return pPrev;
     383           0 :         nPrevErr = nErr;
     384           0 :         pPrev = pNext;
     385           0 :         pNext = GoUpDown( pNext, bDown );
     386             :     }
     387           0 :     if( pPrev != pStart )
     388           0 :         return pPrev;
     389           0 :     return 0;
     390             : }
     391             : 
     392           0 : SvxIconChoiceCtrlEntry* IcnCursor_Impl::GoUpDown( SvxIconChoiceCtrlEntry* pCtrlEntry, sal_Bool bDown)
     393             : {
     394           0 :     if( pView->IsAutoArrange() && !(pView->nWinBits & WB_ALIGN_TOP) )
     395             :     {
     396           0 :         sal_uLong nPos = pView->GetEntryListPos( pCtrlEntry );
     397           0 :         if( bDown && nPos < (pView->aEntries.size() - 1) )
     398           0 :             return pView->aEntries[ nPos + 1 ];
     399           0 :         else if( !bDown && nPos > 0 )
     400           0 :             return pView->aEntries[ nPos - 1 ];
     401           0 :         return 0;
     402             :     }
     403             : 
     404             :     SvxIconChoiceCtrlEntry* pResult;
     405           0 :     pCurEntry = pCtrlEntry;
     406           0 :     Create();
     407           0 :     sal_uInt16 nY = pCtrlEntry->nY;
     408           0 :     sal_uInt16 nX = pCtrlEntry->nX;
     409             :     DBG_ASSERT(nY<nRows,"GoUpDown:Bad column");
     410             :     DBG_ASSERT(nX<nCols,"GoUpDown:Bad row");
     411             : 
     412             :     // neighbor in same column?
     413           0 :     if( bDown )
     414             :         pResult = SearchCol(
     415           0 :             nX, nY, sal::static_int_cast< sal_uInt16 >(nRows-1), nY, sal_True, sal_True );
     416             :     else
     417           0 :         pResult = SearchCol( nX, nY ,0, nY, sal_False, sal_True );
     418           0 :     if( pResult )
     419           0 :         return pResult;
     420             : 
     421           0 :     long nCurRow = nY;
     422             : 
     423             :     long nRowOffs, nLastRow;
     424           0 :     if( bDown )
     425             :     {
     426           0 :         nRowOffs = 1;
     427           0 :         nLastRow = nRows;
     428             :     }
     429             :     else
     430             :     {
     431           0 :         nRowOffs = -1;
     432           0 :         nLastRow = -1;   // 0-1
     433             :     }
     434             : 
     435           0 :     sal_uInt16 nColMin = nX;
     436           0 :     sal_uInt16 nColMax = nX;
     437           0 :     do
     438             :     {
     439           0 :         SvxIconChoiceCtrlEntry* pEntry = SearchRow((sal_uInt16)nCurRow,nColMin,nColMax,nX,sal_True, sal_False);
     440           0 :         if( pEntry )
     441           0 :             return pEntry;
     442           0 :         if( nColMin )
     443           0 :             nColMin--;
     444           0 :         if( nColMax < (nCols-1))
     445           0 :             nColMax++;
     446           0 :         nCurRow += nRowOffs;
     447             :     } while( nCurRow != nLastRow );
     448           0 :     return 0;
     449             : }
     450             : 
     451           0 : void IcnCursor_Impl::SetDeltas()
     452             : {
     453           0 :     const Size& rSize = pView->aVirtOutputSize;
     454           0 :     nCols = rSize.Width() / pView->nGridDX;
     455           0 :     if( !nCols )
     456           0 :         nCols = 1;
     457           0 :     nRows = rSize.Height() / pView->nGridDY;
     458           0 :     if( (nRows * pView->nGridDY) < rSize.Height() )
     459           0 :         nRows++;
     460           0 :     if( !nRows )
     461           0 :         nRows = 1;
     462             : 
     463           0 :     nDeltaWidth = (short)(rSize.Width() / nCols);
     464           0 :     nDeltaHeight = (short)(rSize.Height() / nRows);
     465           0 :     if( !nDeltaHeight )
     466             :     {
     467           0 :         nDeltaHeight = 1;
     468             :         DBG_WARNING("SetDeltas:Bad height");
     469             :     }
     470           0 :     if( !nDeltaWidth )
     471             :     {
     472           0 :         nDeltaWidth = 1;
     473             :         DBG_WARNING("SetDeltas:Bad width");
     474             :     }
     475           0 : }
     476             : 
     477           0 : void IcnCursor_Impl::CreateGridAjustData( IconChoiceMap& rLists, SvxIconChoiceCtrlEntry* pRefEntry)
     478             : {
     479           0 :     if( !pRefEntry )
     480             :     {
     481           0 :         sal_uInt16 nGridRows = (sal_uInt16)(pView->aVirtOutputSize.Height() / pView->nGridDY);
     482           0 :         nGridRows++; // because we round down later!
     483             : 
     484           0 :         if( !nGridRows )
     485           0 :             return;
     486           0 :         const size_t nCount = pView->aEntries.size();
     487           0 :         for( size_t nCur = 0; nCur < nCount; nCur++ )
     488             :         {
     489           0 :             SvxIconChoiceCtrlEntry* pEntry = pView->aEntries[ nCur ];
     490           0 :             const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     491           0 :             short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / pView->nGridDY );
     492           0 :             sal_uInt16 nIns = GetSortListPos( rLists[nY], rRect.Left(), sal_False );
     493           0 :             rLists[ nY ].insert( rLists[ nY ].begin() + nIns, pEntry );
     494             :         }
     495             :     }
     496             :     else
     497             :     {
     498             :         // build a horizontal "tube" in the RefEntry line
     499             :         // STOP AND THINK: maybe use bounding rectangle because of overlaps?
     500           0 :         Rectangle rRefRect( pView->CalcBmpRect( pRefEntry ) );
     501             :         //const Rectangle& rRefRect = pView->GetEntryBoundRect( pRefEntry );
     502           0 :         short nRefRow = (short)( ((rRefRect.Top()+rRefRect.Bottom())/2) / pView->nGridDY );
     503           0 :         SvxIconChoiceCtrlEntryPtrVec& rRow = rLists[0];
     504           0 :         size_t nCount = pView->aEntries.size();
     505           0 :         for( size_t nCur = 0; nCur < nCount; nCur++ )
     506             :         {
     507           0 :             SvxIconChoiceCtrlEntry* pEntry = pView->aEntries[ nCur ];
     508           0 :             Rectangle rRect( pView->CalcBmpRect(pEntry) );
     509             :             //const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
     510           0 :             short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / pView->nGridDY );
     511           0 :             if( nY == nRefRow )
     512             :             {
     513           0 :                 sal_uInt16 nIns = GetSortListPos( rRow, rRect.Left(), sal_False );
     514           0 :                 rRow.insert( rRow.begin() + nIns, pEntry );
     515             :             }
     516             :         }
     517             :     }
     518             : }
     519             : 
     520             : //static
     521           0 : void IcnCursor_Impl::DestroyGridAdjustData( IconChoiceMap& rLists )
     522             : {
     523           0 :     rLists.clear();
     524           0 : }
     525             : 
     526           0 : IcnGridMap_Impl::IcnGridMap_Impl(SvxIconChoiceCtrl_Impl* pView)
     527             : {
     528           0 :     _pView = pView;
     529           0 :     _pGridMap = 0;
     530           0 :     _nGridCols = 0;
     531           0 :     _nGridRows = 0;
     532           0 : }
     533             : 
     534           0 : IcnGridMap_Impl::~IcnGridMap_Impl()
     535             : {
     536           0 :     delete[] _pGridMap, _pGridMap=0;
     537           0 : }
     538             : 
     539           0 : void IcnGridMap_Impl::Expand()
     540             : {
     541           0 :     if( !_pGridMap )
     542           0 :         Create_Impl();
     543             :     else
     544             :     {
     545           0 :         sal_uInt16 nNewGridRows = _nGridRows;
     546           0 :         sal_uInt16 nNewGridCols = _nGridCols;
     547           0 :         if( _pView->nWinBits & WB_ALIGN_TOP )
     548           0 :             nNewGridRows += 50;
     549             :         else
     550           0 :             nNewGridCols += 50;
     551             : 
     552           0 :         sal_Bool* pNewGridMap = new sal_Bool[nNewGridRows*nNewGridCols];
     553           0 :         memset( pNewGridMap, 0, nNewGridRows * nNewGridCols * sizeof(sal_Bool) );
     554           0 :         memcpy( pNewGridMap, _pGridMap, _nGridRows * _nGridCols * sizeof(sal_Bool) );
     555           0 :         delete[] _pGridMap;
     556           0 :         _pGridMap = pNewGridMap;
     557           0 :         _nGridRows = nNewGridRows;
     558           0 :         _nGridCols = nNewGridCols;
     559             :     }
     560           0 : }
     561             : 
     562           0 : void IcnGridMap_Impl::Create_Impl()
     563             : {
     564             :     DBG_ASSERT(!_pGridMap,"Unnecessary call to IcnGridMap_Impl::Create_Impl()");
     565           0 :     if( _pGridMap )
     566           0 :         return;
     567           0 :     GetMinMapSize( _nGridCols, _nGridRows );
     568           0 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     569           0 :         _nGridRows += 50;  // avoid resize of gridmap too often
     570             :     else
     571           0 :         _nGridCols += 50;
     572             : 
     573           0 :     _pGridMap = new sal_Bool[ _nGridRows * _nGridCols];
     574           0 :     memset( (void*)_pGridMap, 0, _nGridRows * _nGridCols );
     575             : 
     576           0 :     const size_t nCount = _pView->aEntries.size();
     577           0 :     for( size_t nCur=0; nCur < nCount; nCur++ )
     578           0 :         OccupyGrids( _pView->aEntries[ nCur ] );
     579             : }
     580             : 
     581           0 : void IcnGridMap_Impl::GetMinMapSize( sal_uInt16& rDX, sal_uInt16& rDY ) const
     582             : {
     583             :     long nX, nY;
     584           0 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     585             :     {
     586             :         // The view grows in vertical direction. Its max. width is _pView->nMaxVirtWidth
     587           0 :         nX = _pView->nMaxVirtWidth;
     588           0 :         if( !nX )
     589           0 :             nX = _pView->pView->GetOutputSizePixel().Width();
     590           0 :         if( !(_pView->nFlags & F_ARRANGING) )
     591           0 :             nX -= _pView->nVerSBarWidth;
     592             : 
     593           0 :         nY = _pView->aVirtOutputSize.Height();
     594             :     }
     595             :     else
     596             :     {
     597             :         // The view grows in horizontal direction. Its max. height is _pView->nMaxVirtHeight
     598           0 :         nY = _pView->nMaxVirtHeight;
     599           0 :         if( !nY )
     600           0 :             nY = _pView->pView->GetOutputSizePixel().Height();
     601           0 :         if( !(_pView->nFlags & F_ARRANGING) )
     602           0 :             nY -= _pView->nHorSBarHeight;
     603           0 :         nX = _pView->aVirtOutputSize.Width();
     604             :     }
     605             : 
     606           0 :     if( !nX )
     607           0 :         nX = DEFAULT_MAX_VIRT_WIDTH;
     608           0 :     if( !nY )
     609           0 :         nY = DEFAULT_MAX_VIRT_HEIGHT;
     610             : 
     611           0 :     long nDX = nX / _pView->nGridDX;
     612           0 :     long nDY = nY / _pView->nGridDY;
     613             : 
     614           0 :     if( !nDX )
     615           0 :         nDX++;
     616           0 :     if( !nDY )
     617           0 :         nDY++;
     618             : 
     619           0 :     rDX = (sal_uInt16)nDX;
     620           0 :     rDY = (sal_uInt16)nDY;
     621           0 : }
     622             : 
     623           0 : GridId IcnGridMap_Impl::GetGrid( sal_uInt16 nGridX, sal_uInt16 nGridY )
     624             : {
     625           0 :     Create();
     626           0 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     627           0 :         return nGridX + ( nGridY * _nGridCols );
     628             :     else
     629           0 :         return nGridY + ( nGridX * _nGridRows );
     630             : }
     631             : 
     632           0 : GridId IcnGridMap_Impl::GetGrid( const Point& rDocPos, sal_Bool* pbClipped )
     633             : {
     634           0 :     Create();
     635             : 
     636           0 :     long nX = rDocPos.X();
     637           0 :     long nY = rDocPos.Y();
     638           0 :     nX -= LROFFS_WINBORDER;
     639           0 :     nY -= TBOFFS_WINBORDER;
     640           0 :     nX /= _pView->nGridDX;
     641           0 :     nY /= _pView->nGridDY;
     642           0 :     sal_Bool bClipped = sal_False;
     643           0 :     if( nX >= _nGridCols )
     644             :     {
     645           0 :         nX = _nGridCols - 1;
     646           0 :         bClipped = sal_True;
     647             :     }
     648           0 :     if( nY >= _nGridRows )
     649             :     {
     650           0 :         nY = _nGridRows - 1;
     651           0 :         bClipped = sal_True;
     652             :     }
     653           0 :     GridId nId = GetGrid( (sal_uInt16)nX, (sal_uInt16)nY );
     654           0 :     if( pbClipped )
     655           0 :         *pbClipped = bClipped;
     656             :     DBG_ASSERT(nId <(sal_uLong)(_nGridCols*_nGridRows),"GetGrid failed");
     657           0 :     return nId;
     658             : }
     659             : 
     660           0 : Rectangle IcnGridMap_Impl::GetGridRect( GridId nId )
     661             : {
     662           0 :     Create();
     663             :     sal_uInt16 nGridX, nGridY;
     664           0 :     GetGridCoord( nId, nGridX, nGridY );
     665           0 :     const long nLeft = nGridX * _pView->nGridDX+ LROFFS_WINBORDER;
     666           0 :     const long nTop = nGridY * _pView->nGridDY + TBOFFS_WINBORDER;
     667             :     return Rectangle(
     668             :         nLeft, nTop,
     669             :         nLeft + _pView->nGridDX,
     670           0 :         nTop + _pView->nGridDY );
     671             : }
     672             : 
     673           0 : GridId IcnGridMap_Impl::GetUnoccupiedGrid( sal_Bool bOccupyFound )
     674             : {
     675           0 :     Create();
     676           0 :     sal_uLong nStart = 0;
     677           0 :     sal_Bool bExpanded = sal_False;
     678             : 
     679           0 :     while( 1 )
     680             :     {
     681           0 :         const sal_uLong nCount = (sal_uInt16)(_nGridCols * _nGridRows);
     682           0 :         for( sal_uLong nCur = nStart; nCur < nCount; nCur++ )
     683             :         {
     684           0 :             if( !_pGridMap[ nCur ] )
     685             :             {
     686           0 :                 if( bOccupyFound )
     687           0 :                     _pGridMap[ nCur ] = sal_True;
     688           0 :                 return (GridId)nCur;
     689             :             }
     690             :         }
     691             :         DBG_ASSERT(!bExpanded,"ExpandGrid failed");
     692           0 :         if( bExpanded )
     693           0 :             return 0; // prevent never ending loop
     694           0 :         bExpanded = sal_True;
     695           0 :         Expand();
     696           0 :         nStart = nCount;
     697             :     }
     698             : }
     699             : 
     700             : // An entry only means that there's a GridRect lying under its center. This
     701             : // variant is much faster than allocating via the bounding rectangle but can
     702             : // lead to small overlaps.
     703           0 : void IcnGridMap_Impl::OccupyGrids( const SvxIconChoiceCtrlEntry* pEntry, sal_Bool bOccupy )
     704             : {
     705           0 :     if( !_pGridMap || !_pView->IsBoundingRectValid( pEntry->aRect ))
     706           0 :         return;
     707           0 :     OccupyGrid( GetGrid( pEntry->aRect.Center()), bOccupy );
     708             : }
     709             : 
     710           0 : void IcnGridMap_Impl::Clear()
     711             : {
     712           0 :     if( _pGridMap )
     713             :     {
     714           0 :         delete[] _pGridMap, _pGridMap=0;
     715           0 :         _nGridRows = 0;
     716           0 :         _nGridCols = 0;
     717           0 :         _aLastOccupiedGrid.SetEmpty();
     718             :     }
     719           0 : }
     720             : 
     721           0 : sal_uLong IcnGridMap_Impl::GetGridCount( const Size& rSizePixel, sal_uInt16 nDX, sal_uInt16 nDY)
     722             : {
     723           0 :     long ndx = (rSizePixel.Width() - LROFFS_WINBORDER) / nDX;
     724           0 :     if( ndx < 0 ) ndx *= -1;
     725           0 :     long ndy = (rSizePixel.Height() - TBOFFS_WINBORDER) / nDY;
     726           0 :     if( ndy < 0 ) ndy *= -1;
     727           0 :     return (sal_uLong)(ndx * ndy);
     728             : }
     729             : 
     730           0 : void IcnGridMap_Impl::OutputSizeChanged()
     731             : {
     732           0 :     if( _pGridMap )
     733             :     {
     734             :         sal_uInt16 nCols, nRows;
     735           0 :         GetMinMapSize( nCols, nRows );
     736           0 :         if( _pView->nWinBits & WB_ALIGN_TOP )
     737             :         {
     738           0 :             if( nCols != _nGridCols )
     739           0 :                 Clear();
     740           0 :             else if( nRows >= _nGridRows )
     741           0 :                 Expand();
     742             :         }
     743             :         else
     744             :         {
     745           0 :             if( nRows != _nGridRows )
     746           0 :                 Clear();
     747           0 :             else if( nCols >= _nGridCols )
     748           0 :                 Expand();
     749             :         }
     750             :     }
     751           0 : }
     752             : 
     753             : // Independently of the view's alignment (TOP or LEFT), the gridmap
     754             : // should contain the data in a continuous region, to make it possible
     755             : // to copy the whole block if the gridmap needs to be expanded.
     756           0 : void IcnGridMap_Impl::GetGridCoord( GridId nId, sal_uInt16& rGridX, sal_uInt16& rGridY )
     757             : {
     758           0 :     Create();
     759           0 :     if( _pView->nWinBits & WB_ALIGN_TOP )
     760             :     {
     761           0 :         rGridX = (sal_uInt16)(nId % _nGridCols);
     762           0 :         rGridY = (sal_uInt16)(nId / _nGridCols);
     763             :     }
     764             :     else
     765             :     {
     766           0 :         rGridX = (sal_uInt16)(nId / _nGridRows);
     767           0 :         rGridY = (sal_uInt16)(nId % _nGridRows);
     768             :     }
     769           0 : }
     770             : 
     771             : 
     772             : 
     773             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10