LCOV - code coverage report
Current view: top level - svtools/source/contnr - imivctl1.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 818 2136 38.3 %
Date: 2014-11-03 Functions: 72 152 47.4 %
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             : 
      21             : #include <limits.h>
      22             : #include <tools/debug.hxx>
      23             : #include <vcl/wall.hxx>
      24             : #include <vcl/help.hxx>
      25             : #include <vcl/decoview.hxx>
      26             : #include <vcl/svapp.hxx>
      27             : #include <tools/poly.hxx>
      28             : #include <vcl/lineinfo.hxx>
      29             : #include <vcl/i18nhelp.hxx>
      30             : #include <vcl/mnemonic.hxx>
      31             : #include <vcl/controllayout.hxx>
      32             : #include <vcl/settings.hxx>
      33             : 
      34             : #include <svtools/ivctrl.hxx>
      35             : #include "imivctl.hxx"
      36             : #include <svtools/svmedit.hxx>
      37             : 
      38             : #include <algorithm>
      39             : #include <boost/scoped_ptr.hpp>
      40             : 
      41             : #define IMPICNVIEW_ACC_RETURN 1
      42             : #define IMPICNVIEW_ACC_ESCAPE 2
      43             : 
      44             : #define DRAWTEXT_FLAGS_ICON \
      45             :     ( TEXT_DRAW_CENTER | TEXT_DRAW_TOP | TEXT_DRAW_ENDELLIPSIS | \
      46             :       TEXT_DRAW_CLIP | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MNEMONIC )
      47             : 
      48             : #define DRAWTEXT_FLAGS_SMALLICON (TEXT_DRAW_LEFT|TEXT_DRAW_ENDELLIPSIS|TEXT_DRAW_CLIP)
      49             : 
      50             : #define EVENTID_SHOW_CURSOR             (reinterpret_cast<void*>(1))
      51             : #define EVENTID_ADJUST_SCROLLBARS       (reinterpret_cast<void*>(2))
      52             : 
      53             : static bool bEndScrollInvalidate = true;
      54             : 
      55             : class IcnViewEdit_Impl : public MultiLineEdit
      56             : {
      57             :     Link            aCallBackHdl;
      58             :     Accelerator     aAccReturn;
      59             :     Accelerator     aAccEscape;
      60             :     Timer           aTimer;
      61             :     bool            bCanceled;
      62             :     bool            bAlreadyInCallback;
      63             :     bool            bGrabFocus;
      64             : 
      65             :     void            CallCallBackHdl_Impl();
      66             :                     DECL_LINK(Timeout_Impl, void *);
      67             :                     DECL_LINK( ReturnHdl_Impl, Accelerator * );
      68             :                     DECL_LINK( EscapeHdl_Impl, Accelerator * );
      69             : 
      70             : public:
      71             : 
      72             :                     IcnViewEdit_Impl(
      73             :                         SvtIconChoiceCtrl* pParent,
      74             :                         const Point& rPos,
      75             :                         const Size& rSize,
      76             :                         const OUString& rData,
      77             :                         const Link& rNotifyEditEnd );
      78             : 
      79             :                     virtual ~IcnViewEdit_Impl();
      80             :     virtual void    KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
      81             :     virtual bool    PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
      82           0 :     bool            EditingCanceled() const { return bCanceled; }
      83             :     void            StopEditing( bool bCancel = false );
      84           0 :     bool            IsGrabFocus() const { return bGrabFocus; }
      85             : };
      86             : 
      87          16 : SvxIconChoiceCtrl_Impl::SvxIconChoiceCtrl_Impl(
      88             :     SvtIconChoiceCtrl* pCurView,
      89             :     WinBits nWinStyle
      90             : ) :
      91             :     aEntries( this ),
      92             :     aVerSBar( pCurView, WB_DRAG | WB_VSCROLL ),
      93             :     aHorSBar( pCurView, WB_DRAG | WB_HSCROLL ),
      94             :     aScrBarBox( pCurView ),
      95             :     aImageSize( 32, 32 ),
      96          16 :     pColumns( 0 )
      97             : {
      98          16 :     bChooseWithCursor = false;
      99          16 :     pEntryPaintDev = 0;
     100          16 :     pCurEditedEntry = 0;
     101          16 :     pCurHighlightFrame = 0;
     102          16 :     pEdit = 0;
     103          16 :     pAnchor = 0;
     104          16 :     pPrevDropTarget = 0;
     105          16 :     pHdlEntry = 0;
     106          16 :     pHead = NULL;
     107          16 :     pCursor = NULL;
     108          16 :     bUpdateMode = true;
     109          16 :     bEntryEditingEnabled = false;
     110          16 :     bHighlightFramePressed = false;
     111          16 :     eSelectionMode = MULTIPLE_SELECTION;
     112          16 :     pView = pCurView;
     113          16 :     pZOrderList = new SvxIconChoiceCtrlEntryList_impl();
     114          16 :     ePositionMode = IcnViewPositionModeFree;
     115          16 :     SetStyle( nWinStyle );
     116          16 :     nFlags = 0;
     117          16 :     nUserEventAdjustScrBars = 0;
     118          16 :     nUserEventShowCursor = 0;
     119          16 :     nMaxVirtWidth = DEFAULT_MAX_VIRT_WIDTH;
     120          16 :     nMaxVirtHeight = DEFAULT_MAX_VIRT_HEIGHT;
     121          16 :     pDDRefEntry = 0;
     122          16 :     pDDDev = 0;
     123          16 :     pDDBufDev = 0;
     124          16 :     pDDTempDev = 0;
     125          16 :     eTextMode = IcnShowTextShort;
     126          16 :     pImpCursor = new IcnCursor_Impl( this );
     127          16 :     pGridMap = new IcnGridMap_Impl( this );
     128             : 
     129          16 :     aVerSBar.SetScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl, ScrollUpDownHdl ) );
     130          16 :     aHorSBar.SetScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl, ScrollLeftRightHdl ) );
     131          16 :     Link aEndScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl, EndScrollHdl ) );
     132          16 :     aVerSBar.SetEndScrollHdl( aEndScrollHdl );
     133          16 :     aHorSBar.SetEndScrollHdl( aEndScrollHdl );
     134             : 
     135          16 :     nHorSBarHeight = aHorSBar.GetSizePixel().Height();
     136          16 :     nVerSBarWidth = aVerSBar.GetSizePixel().Width();
     137             : 
     138          16 :     aEditTimer.SetTimeout( 800 );
     139          16 :     aEditTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,EditTimeoutHdl));
     140          16 :     aAutoArrangeTimer.SetTimeout( 100 );
     141          16 :     aAutoArrangeTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,AutoArrangeHdl));
     142          16 :     aCallSelectHdlTimer.SetTimeout( 500 );
     143          16 :     aCallSelectHdlTimer.SetTimeoutHdl( LINK(this,SvxIconChoiceCtrl_Impl,CallSelectHdlHdl));
     144             : 
     145          16 :     aDocRectChangedTimer.SetTimeout( 50 );
     146          16 :     aDocRectChangedTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,DocRectChangedHdl));
     147          16 :     aVisRectChangedTimer.SetTimeout( 50 );
     148          16 :     aVisRectChangedTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,VisRectChangedHdl));
     149             : 
     150          16 :     Clear( true );
     151             : 
     152          16 :     SetGrid( Size(100, 70) );
     153          16 : }
     154             : 
     155          24 : SvxIconChoiceCtrl_Impl::~SvxIconChoiceCtrl_Impl()
     156             : {
     157          12 :     pCurEditedEntry = 0;
     158          12 :     DELETEZ(pEdit);
     159          12 :     Clear();
     160          12 :     StopEditTimer();
     161          12 :     CancelUserEvents();
     162          12 :     delete pZOrderList;
     163          12 :     delete pImpCursor;
     164          12 :     delete pGridMap;
     165          12 :     delete pDDDev;
     166          12 :     delete pDDBufDev;
     167          12 :     delete pDDTempDev;
     168          12 :     delete pEntryPaintDev;
     169          12 :     ClearSelectedRectList();
     170          12 :     ClearColumnList();
     171          12 : }
     172             : 
     173          28 : void SvxIconChoiceCtrl_Impl::Clear( bool bInCtor )
     174             : {
     175          28 :     StopEntryEditing( true );
     176          28 :     nSelectionCount = 0;
     177          28 :     pCurHighlightFrame = 0;
     178          28 :     StopEditTimer();
     179          28 :     CancelUserEvents();
     180          28 :     ShowCursor( false );
     181          28 :     bBoundRectsDirty = false;
     182          28 :     nMaxBoundHeight = 0;
     183             : 
     184          28 :     nFlags &= ~(F_PAINTED | F_MOVED_ENTRIES);
     185          28 :     pCursor = 0;
     186          28 :     if( !bInCtor )
     187             :     {
     188          12 :         pImpCursor->Clear();
     189          12 :         pGridMap->Clear();
     190          12 :         aVirtOutputSize.Width() = 0;
     191          12 :         aVirtOutputSize.Height() = 0;
     192          12 :         Size aSize( pView->GetOutputSizePixel() );
     193          12 :         nMaxVirtWidth = aSize.Width() - nVerSBarWidth;
     194          12 :         if( nMaxVirtWidth <= 0 )
     195           0 :             nMaxVirtWidth = DEFAULT_MAX_VIRT_WIDTH;
     196          12 :         nMaxVirtHeight = aSize.Height() - nHorSBarHeight;
     197          12 :         if( nMaxVirtHeight <= 0 )
     198           2 :             nMaxVirtHeight = DEFAULT_MAX_VIRT_HEIGHT;
     199          12 :         pZOrderList->clear();
     200          12 :         SetOrigin( Point() );
     201          12 :         if( bUpdateMode )
     202          12 :             pView->Invalidate(INVALIDATE_NOCHILDREN);
     203             :     }
     204          28 :     AdjustScrollBars();
     205          28 :     size_t nCount = aEntries.size();
     206          76 :     for( size_t nCur = 0; nCur < nCount; nCur++ )
     207             :     {
     208          48 :         SvxIconChoiceCtrlEntry* pCur = aEntries[ nCur ];
     209          48 :         delete pCur;
     210             :     }
     211          28 :     aEntries.clear();
     212          28 :     DocRectChanged();
     213          28 :     VisRectChanged();
     214          28 : }
     215             : 
     216          16 : void SvxIconChoiceCtrl_Impl::SetStyle( WinBits nWinStyle )
     217             : {
     218          16 :     nWinBits = nWinStyle;
     219          16 :     nCurTextDrawFlags = DRAWTEXT_FLAGS_ICON;
     220          16 :     if( nWinBits & (WB_SMALLICON | WB_DETAILS) )
     221           0 :         nCurTextDrawFlags = DRAWTEXT_FLAGS_SMALLICON;
     222          16 :     if( nWinBits & WB_NOSELECTION )
     223           0 :         eSelectionMode = NO_SELECTION;
     224          16 :     if( !(nWinStyle & (WB_ALIGN_TOP | WB_ALIGN_LEFT)))
     225          16 :         nWinBits |= WB_ALIGN_LEFT;
     226          16 :     if( (nWinStyle & WB_DETAILS))
     227             :     {
     228           0 :         if( !pColumns  )
     229           0 :             SetColumn( 0, SvxIconChoiceCtrlColumnInfo( 0, 100, IcnViewAlignLeft ));
     230             :     }
     231          16 : }
     232             : 
     233           0 : IMPL_LINK( SvxIconChoiceCtrl_Impl, ScrollUpDownHdl, ScrollBar*, pScrollBar )
     234             : {
     235           0 :     StopEntryEditing( true );
     236             :     // arrow up: delta=-1; arrow down: delta=+1
     237           0 :     Scroll( 0, pScrollBar->GetDelta(), true );
     238           0 :     bEndScrollInvalidate = true;
     239           0 :     return 0;
     240             : }
     241             : 
     242           0 : IMPL_LINK( SvxIconChoiceCtrl_Impl, ScrollLeftRightHdl, ScrollBar*, pScrollBar )
     243             : {
     244           0 :     StopEntryEditing( true );
     245             :     // arrow left: delta=-1; arrow right: delta=+1
     246           0 :     Scroll( pScrollBar->GetDelta(), 0, true );
     247           0 :     bEndScrollInvalidate = true;
     248           0 :     return 0;
     249             : }
     250             : 
     251           0 : IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl, EndScrollHdl)
     252             : {
     253           0 :     if( pView->HasBackground() && !pView->GetBackground().IsScrollable() &&
     254             :         bEndScrollInvalidate )
     255             :     {
     256           0 :         pView->Invalidate(INVALIDATE_NOCHILDREN);
     257             :     }
     258           0 :     return 0;
     259             : }
     260             : 
     261          16 : void SvxIconChoiceCtrl_Impl::FontModified()
     262             : {
     263          16 :     StopEditTimer();
     264          16 :     DELETEZ(pDDDev);
     265          16 :     DELETEZ(pDDBufDev);
     266          16 :     DELETEZ(pDDTempDev);
     267          16 :     DELETEZ(pEntryPaintDev);
     268          16 :     SetDefaultTextSize();
     269          16 :     ShowCursor( false );
     270          16 :     ShowCursor( true );
     271          16 : }
     272             : 
     273          64 : void SvxIconChoiceCtrl_Impl::InsertEntry( SvxIconChoiceCtrlEntry* pEntry, size_t nPos,
     274             :     const Point* pPos )
     275             : {
     276          64 :     StopEditTimer();
     277          64 :     aEntries.insert( nPos, pEntry );
     278          64 :     if( (nFlags & F_ENTRYLISTPOS_VALID) && nPos >= aEntries.size() - 1 )
     279           0 :         pEntry->nPos = aEntries.size() - 1;
     280             :     else
     281          64 :         nFlags &= ~F_ENTRYLISTPOS_VALID;
     282             : 
     283          64 :     pZOrderList->push_back( pEntry );
     284          64 :     pImpCursor->Clear();
     285          64 :     if( pPos )
     286             :     {
     287           0 :         Size aSize( CalcBoundingSize( pEntry ) );
     288           0 :         SetBoundingRect_Impl( pEntry, *pPos, aSize );
     289           0 :         SetEntryPos( pEntry, *pPos, false, true, true /*keep grid map*/ );
     290           0 :         pEntry->nFlags |= ICNVIEW_FLAG_POS_MOVED;
     291           0 :         SetEntriesMoved( true );
     292             :     }
     293             :     else
     294             :     {
     295             :         // If the UpdateMode is true, don't set all bounding rectangles to
     296             :         // 'to be checked', but only the bounding rectangle of the new entry.
     297             :         // Thus, don't call InvalidateBoundingRect!
     298          64 :         pEntry->aRect.Right() = LONG_MAX;
     299          64 :         if( bUpdateMode )
     300             :         {
     301          64 :             FindBoundingRect( pEntry );
     302          64 :             Rectangle aOutputArea( GetOutputRect() );
     303          64 :             pGridMap->OccupyGrids( pEntry );
     304          64 :             if( !aOutputArea.IsOver( pEntry->aRect ) )
     305         128 :                 return; // is invisible
     306           0 :             pView->Invalidate( pEntry->aRect );
     307             :         }
     308             :         else
     309           0 :             InvalidateBoundingRect( pEntry->aRect );
     310             :     }
     311             : }
     312             : 
     313          16 : void SvxIconChoiceCtrl_Impl::CreateAutoMnemonics( MnemonicGenerator* _pGenerator )
     314             : {
     315          16 :     boost::scoped_ptr< MnemonicGenerator > pAutoDeleteOwnGenerator;
     316          16 :     if ( !_pGenerator )
     317             :     {
     318           0 :         _pGenerator = new MnemonicGenerator;
     319           0 :         pAutoDeleteOwnGenerator.reset( _pGenerator );
     320             :     }
     321             : 
     322          16 :     sal_uLong   nEntryCount = GetEntryCount();
     323             :     sal_uLong   i;
     324             : 
     325             :     // insert texts in generator
     326          80 :     for( i = 0; i < nEntryCount; ++i )
     327             :     {
     328             :         DBG_ASSERT( GetEntry( i ), "-SvxIconChoiceCtrl_Impl::CreateAutoMnemonics(): more expected than provided!" );
     329             : 
     330          64 :         _pGenerator->RegisterMnemonic( GetEntry( i )->GetText() );
     331             :     }
     332             : 
     333             :     // exchange texts with generated mnemonics
     334          80 :     for( i = 0; i < nEntryCount; ++i )
     335             :     {
     336          64 :         SvxIconChoiceCtrlEntry* pEntry = GetEntry( i );
     337          64 :         OUString                aTxt = pEntry->GetText();
     338             : 
     339         128 :         OUString aNewText = _pGenerator->CreateMnemonic( aTxt );
     340          64 :         if( aNewText != aTxt )
     341          64 :             pEntry->SetText( aNewText );
     342          80 :     }
     343          16 : }
     344             : 
     345        1758 : Rectangle SvxIconChoiceCtrl_Impl::GetOutputRect() const
     346             : {
     347        1758 :     Point aOrigin( pView->GetMapMode().GetOrigin() );
     348        1758 :     aOrigin *= -1;
     349        1758 :     return Rectangle( aOrigin, aOutputSize );
     350             : }
     351             : 
     352           0 : void SvxIconChoiceCtrl_Impl::SetListPositions()
     353             : {
     354           0 :     if( nFlags & F_ENTRYLISTPOS_VALID )
     355           0 :         return;
     356             : 
     357           0 :     size_t nCount = aEntries.size();
     358           0 :     for( size_t nCur = 0; nCur < nCount; nCur++ )
     359             :     {
     360           0 :         SvxIconChoiceCtrlEntry* pEntry = aEntries[ nCur ];
     361           0 :         pEntry->nPos = nCur;
     362             :     }
     363           0 :     nFlags |= F_ENTRYLISTPOS_VALID;
     364             : }
     365             : 
     366          12 : void SvxIconChoiceCtrl_Impl::SelectEntry( SvxIconChoiceCtrlEntry* pEntry, bool bSelect,
     367             :     bool bCallHdl, bool bAdd, bool bSyncPaint )
     368             : {
     369          12 :     if( eSelectionMode == NO_SELECTION )
     370          12 :         return;
     371             : 
     372          12 :     if( !bAdd )
     373             :     {
     374          12 :         if ( 0 == ( nFlags & F_CLEARING_SELECTION ) )
     375             :         {
     376          12 :             nFlags |= F_CLEARING_SELECTION;
     377          12 :             DeselectAllBut( pEntry, true );
     378          12 :             nFlags &= ~F_CLEARING_SELECTION;
     379             :         }
     380             :     }
     381          12 :     if( pEntry->IsSelected() != bSelect )
     382             :     {
     383           6 :         pHdlEntry = pEntry;
     384           6 :         sal_uInt16 nEntryFlags = pEntry->GetFlags();
     385           6 :         if( bSelect )
     386             :         {
     387           6 :             nEntryFlags |= ICNVIEW_FLAG_SELECTED;
     388           6 :             pEntry->AssignFlags( nEntryFlags );
     389           6 :             nSelectionCount++;
     390           6 :             if( bCallHdl )
     391           6 :                 CallSelectHandler( pEntry );
     392             :         }
     393             :         else
     394             :         {
     395           0 :             nEntryFlags &= ~( ICNVIEW_FLAG_SELECTED);
     396           0 :             pEntry->AssignFlags( nEntryFlags );
     397           0 :             nSelectionCount--;
     398           0 :             if( bCallHdl )
     399           0 :                 CallSelectHandler( 0 );
     400             :         }
     401           6 :         EntrySelected( pEntry, bSelect, bSyncPaint );
     402             :     }
     403             : }
     404             : 
     405           6 : void SvxIconChoiceCtrl_Impl::EntrySelected( SvxIconChoiceCtrlEntry* pEntry, bool bSelect,
     406             :     bool bSyncPaint )
     407             : {
     408             :     // When using SingleSelection, make sure that the cursor is always placed
     409             :     // over the (only) selected entry. (But only if a cursor exists.)
     410          12 :     if( bSelect && pCursor &&
     411          12 :         eSelectionMode == SINGLE_SELECTION &&
     412           6 :         pEntry != pCursor )
     413             :     {
     414           0 :         SetCursor( pEntry );
     415             :         //DBG_ASSERT(pView->GetSelectionCount()==1,"selection count?")
     416             :     }
     417             : 
     418             :     // Not when dragging though, else the loop in SelectRect doesn't work
     419             :     // correctly!
     420           6 :     if( !(nFlags & F_SELECTING_RECT) )
     421           6 :         ToTop( pEntry );
     422           6 :     if( bUpdateMode )
     423             :     {
     424           6 :         if( pEntry == pCursor )
     425           6 :             ShowCursor( false );
     426           6 :         if( pView->IsTracking() && (bSelect || !pView->HasBackground()) ) // always synchronous when tracking
     427           0 :             PaintEntry( pEntry );
     428           6 :         else if( bSyncPaint ) // synchronous & with a virtual OutDev!
     429           0 :             PaintEntryVirtOutDev( pEntry );
     430             :         else
     431             :         {
     432           6 :             pView->Invalidate( CalcFocusRect( pEntry ) );
     433             :         }
     434           6 :         if( pEntry == pCursor )
     435           6 :             ShowCursor( true );
     436             :     }
     437             : 
     438             :     // #i101012# emit vcl event LISTBOX_SELECT only in case that the given entry is selected.
     439           6 :     if ( bSelect )
     440             :     {
     441           6 :         CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry );
     442             :     }
     443           6 : }
     444             : 
     445         132 : void SvxIconChoiceCtrl_Impl::ResetVirtSize()
     446             : {
     447         132 :     StopEditTimer();
     448         132 :     aVirtOutputSize.Width() = 0;
     449         132 :     aVirtOutputSize.Height() = 0;
     450         132 :     const size_t nCount = aEntries.size();
     451         660 :     for( size_t nCur = 0; nCur < nCount; nCur++ )
     452             :     {
     453         528 :         SvxIconChoiceCtrlEntry* pCur = aEntries[ nCur ];
     454         528 :         pCur->ClearFlags( ICNVIEW_FLAG_POS_MOVED );
     455         528 :         if( pCur->IsPosLocked() )
     456             :         {
     457             :             // adapt (among others) VirtSize
     458           0 :             if( !IsBoundingRectValid( pCur->aRect ) )
     459           0 :                 FindBoundingRect( pCur );
     460             :             else
     461           0 :                 AdjustVirtSize( pCur->aRect );
     462             :         }
     463             :         else
     464         528 :             InvalidateBoundingRect( pCur->aRect );
     465             :     }
     466             : 
     467         132 :     if( !(nWinBits & (WB_NOVSCROLL | WB_NOHSCROLL)) )
     468             :     {
     469           0 :         Size aRealOutputSize( pView->GetOutputSizePixel() );
     470           0 :         if( aVirtOutputSize.Width() < aRealOutputSize.Width() ||
     471           0 :             aVirtOutputSize.Height() < aRealOutputSize.Height() )
     472             :         {
     473             :             sal_uLong nGridCount = IcnGridMap_Impl::GetGridCount(
     474           0 :                 aRealOutputSize, (sal_uInt16)nGridDX, (sal_uInt16)nGridDY );
     475           0 :             if( nGridCount < nCount )
     476             :             {
     477           0 :                 if( nWinBits & WB_ALIGN_TOP )
     478           0 :                     nMaxVirtWidth = aRealOutputSize.Width() - nVerSBarWidth;
     479             :                 else // WB_ALIGN_LEFT
     480           0 :                     nMaxVirtHeight = aRealOutputSize.Height() - nHorSBarHeight;
     481             :             }
     482             :         }
     483             :     }
     484             : 
     485         132 :     pImpCursor->Clear();
     486         132 :     pGridMap->Clear();
     487         132 :     VisRectChanged();
     488         132 : }
     489             : 
     490         592 : void SvxIconChoiceCtrl_Impl::AdjustVirtSize( const Rectangle& rRect )
     491             : {
     492         592 :     long nHeightOffs = 0;
     493         592 :     long nWidthOffs = 0;
     494             : 
     495         592 :     if( aVirtOutputSize.Width() < (rRect.Right()+LROFFS_WINBORDER) )
     496         230 :         nWidthOffs = (rRect.Right()+LROFFS_WINBORDER) - aVirtOutputSize.Width();
     497             : 
     498         592 :     if( aVirtOutputSize.Height() < (rRect.Bottom()+TBOFFS_WINBORDER) )
     499         494 :         nHeightOffs = (rRect.Bottom()+TBOFFS_WINBORDER) - aVirtOutputSize.Height();
     500             : 
     501         592 :     if( nWidthOffs || nHeightOffs )
     502             :     {
     503         576 :         Range aRange;
     504         576 :         aVirtOutputSize.Width() += nWidthOffs;
     505         576 :         aRange.Max() = aVirtOutputSize.Width();
     506         576 :         aHorSBar.SetRange( aRange );
     507             : 
     508         576 :         aVirtOutputSize.Height() += nHeightOffs;
     509         576 :         aRange.Max() = aVirtOutputSize.Height();
     510         576 :         aVerSBar.SetRange( aRange );
     511             : 
     512         576 :         pImpCursor->Clear();
     513         576 :         pGridMap->OutputSizeChanged();
     514         576 :         AdjustScrollBars();
     515         576 :         DocRectChanged();
     516             :     }
     517         592 : }
     518             : 
     519           0 : void SvxIconChoiceCtrl_Impl::InitPredecessors()
     520             : {
     521             :     DBG_ASSERT(!pHead,"SvxIconChoiceCtrl_Impl::InitPredecessors() >> Already initialized");
     522           0 :     size_t nCount = aEntries.size();
     523           0 :     if( nCount )
     524             :     {
     525           0 :         SvxIconChoiceCtrlEntry* pPrev = aEntries[ 0 ];
     526           0 :         for( size_t nCur = 1; nCur <= nCount; nCur++ )
     527             :         {
     528             :             pPrev->ClearFlags( ICNVIEW_FLAG_POS_LOCKED | ICNVIEW_FLAG_POS_MOVED |
     529           0 :                                 ICNVIEW_FLAG_PRED_SET);
     530             : 
     531             :             SvxIconChoiceCtrlEntry* pNext;
     532           0 :             if( nCur == nCount )
     533           0 :                 pNext = aEntries[ 0 ];
     534             :             else
     535           0 :                 pNext = aEntries[ nCur ];
     536           0 :             pPrev->pflink = pNext;
     537           0 :             pNext->pblink = pPrev;
     538           0 :             pPrev = pNext;
     539             :         }
     540           0 :         pHead = aEntries[ 0 ];
     541             :     }
     542             :     else
     543           0 :         pHead = 0;
     544           0 :     nFlags &= ~F_MOVED_ENTRIES;
     545           0 : }
     546             : 
     547         132 : void SvxIconChoiceCtrl_Impl::ClearPredecessors()
     548             : {
     549         132 :     if( pHead )
     550             :     {
     551           0 :         size_t nCount = aEntries.size();
     552           0 :         for( size_t nCur = 0; nCur < nCount; nCur++ )
     553             :         {
     554           0 :             SvxIconChoiceCtrlEntry* pCur = aEntries[ nCur ];
     555           0 :             pCur->pflink = 0;
     556           0 :             pCur->pblink = 0;
     557           0 :             pCur->ClearFlags( ICNVIEW_FLAG_PRED_SET );
     558             :         }
     559           0 :         pHead = 0;
     560             :     }
     561         132 : }
     562             : 
     563         132 : void SvxIconChoiceCtrl_Impl::Arrange( bool bKeepPredecessors, long nSetMaxVirtWidth, long nSetMaxVirtHeight )
     564             : {
     565         132 :     if ( nSetMaxVirtWidth != 0 )
     566           0 :         nMaxVirtWidth = nSetMaxVirtWidth;
     567             :     else
     568         132 :         nMaxVirtWidth = aOutputSize.Width();
     569             : 
     570         132 :     if ( nSetMaxVirtHeight != 0 )
     571         132 :         nMaxVirtHeight = nSetMaxVirtHeight;
     572             :     else
     573           0 :         nMaxVirtHeight = aOutputSize.Height();
     574             : 
     575         132 :     ImpArrange( bKeepPredecessors );
     576         132 : }
     577             : 
     578         132 : void SvxIconChoiceCtrl_Impl::ImpArrange( bool bKeepPredecessors )
     579             : {
     580         132 :     static Point aEmptyPoint;
     581             : 
     582         132 :     bool bOldUpdate = bUpdateMode;
     583         132 :     Rectangle aCurOutputArea( GetOutputRect() );
     584         132 :     if( (nWinBits & WB_SMART_ARRANGE) && aCurOutputArea.TopLeft() != aEmptyPoint )
     585           0 :         bUpdateMode = false;
     586         132 :     aAutoArrangeTimer.Stop();
     587         132 :     nFlags &= ~F_MOVED_ENTRIES;
     588         132 :     nFlags |= F_ARRANGING;
     589         132 :     StopEditTimer();
     590         132 :     ShowCursor( false );
     591         132 :     ResetVirtSize();
     592         132 :     if( !bKeepPredecessors )
     593         132 :         ClearPredecessors();
     594         132 :     bBoundRectsDirty = false;
     595         132 :     SetOrigin( Point() );
     596         132 :     VisRectChanged();
     597         132 :     RecalcAllBoundingRectsSmart();
     598             :     // TODO: the invalidation in the detail view should be more intelligent
     599             :     //if( !(nWinBits & WB_DETAILS ))
     600         132 :         pView->Invalidate( INVALIDATE_NOCHILDREN );
     601         132 :     nFlags &= ~F_ARRANGING;
     602         132 :     if( (nWinBits & WB_SMART_ARRANGE) && aCurOutputArea.TopLeft() != aEmptyPoint )
     603             :     {
     604           0 :         MakeVisible( aCurOutputArea );
     605           0 :         SetUpdateMode( bOldUpdate );
     606             :     }
     607         132 :     ShowCursor( true );
     608         132 : }
     609             : 
     610          12 : void SvxIconChoiceCtrl_Impl::Paint( const Rectangle& rRect )
     611             : {
     612          12 :     bEndScrollInvalidate = false;
     613             : 
     614             : #if defined(OV_DRAWGRID)
     615             :     Color aOldColor ( pView->GetLineColor() );
     616             :     Color aColor( COL_BLACK );
     617             :     pView->SetLineColor( aColor );
     618             :     Point aOffs( pView->GetMapMode().GetOrigin());
     619             :     Size aXSize( pView->GetOutputSizePixel() );
     620             : 
     621             :     {
     622             :     Point aStart( LROFFS_WINBORDER, 0 );
     623             :     Point aEnd( LROFFS_WINBORDER, aXSize.Height());
     624             :     aStart -= aOffs;
     625             :     aEnd -= aOffs;
     626             :     pView->DrawLine( aStart, aEnd );
     627             :     }
     628             :     {
     629             :     Point aStart( 0, TBOFFS_WINBORDER );
     630             :     Point aEnd( aXSize.Width(), TBOFFS_WINBORDER );
     631             :     aStart -= aOffs;
     632             :     aEnd -= aOffs;
     633             :     pView->DrawLine( aStart, aEnd );
     634             :     }
     635             : 
     636             :     for( long nDX = nGridDX; nDX <= aXSize.Width(); nDX += nGridDX )
     637             :     {
     638             :         Point aStart( nDX+LROFFS_WINBORDER, 0 );
     639             :         Point aEnd( nDX+LROFFS_WINBORDER, aXSize.Height());
     640             :         aStart -= aOffs;
     641             :         aEnd -= aOffs;
     642             :         pView->DrawLine( aStart, aEnd );
     643             :     }
     644             :     for( long nDY = nGridDY; nDY <= aXSize.Height(); nDY += nGridDY )
     645             :     {
     646             :         Point aStart( 0, nDY+TBOFFS_WINBORDER );
     647             :         Point aEnd( aXSize.Width(), nDY+TBOFFS_WINBORDER );
     648             :         aStart -= aOffs;
     649             :         aEnd -= aOffs;
     650             :         pView->DrawLine( aStart, aEnd );
     651             :     }
     652             :     pView->SetLineColor( aOldColor );
     653             : #endif
     654          12 :     nFlags |= F_PAINTED;
     655             : 
     656          12 :     if( !aEntries.size() )
     657           0 :         return;
     658          12 :     if( !pCursor )
     659             :     {
     660             :         // set cursor to item with focus-flag
     661           6 :         bool bfound = false;
     662          30 :         for ( sal_uLong i = 0; i < pView->GetEntryCount() && !bfound; i++)
     663             :         {
     664          24 :             SvxIconChoiceCtrlEntry* pEntry = pView->GetEntry ( i );
     665          24 :             if( pEntry->IsFocused() )
     666             :             {
     667           0 :                 pCursor = pEntry;
     668           0 :                 bfound = true;
     669             :             }
     670             :         }
     671             : 
     672           6 :         if( !bfound )
     673           6 :             pCursor = aEntries[ 0 ];
     674             :     }
     675             : 
     676             :     // Show Focus at Init-Time
     677          12 :     if ( pView->HasFocus() )
     678          12 :         GetFocus();
     679             : 
     680          12 :     size_t nCount = pZOrderList->size();
     681          12 :     if( !nCount )
     682           0 :         return;
     683             : 
     684          12 :     bool bResetClipRegion = false;
     685          12 :     if( !pView->IsClipRegion() )
     686             :     {
     687          12 :         vcl::Region const aOutputArea( GetOutputRect() );
     688          12 :         bResetClipRegion = true;
     689          12 :         pView->SetClipRegion( aOutputArea );
     690             :     }
     691             : 
     692          12 :     SvxIconChoiceCtrlEntryList_impl* pNewZOrderList = new SvxIconChoiceCtrlEntryList_impl();
     693          12 :     boost::scoped_ptr<SvxIconChoiceCtrlEntryList_impl> pPaintedEntries(new SvxIconChoiceCtrlEntryList_impl());
     694             : 
     695          12 :     size_t nPos = 0;
     696          72 :     while( nCount )
     697             :     {
     698          48 :         SvxIconChoiceCtrlEntry* pEntry = (*pZOrderList)[ nPos ];
     699          48 :         const Rectangle& rBoundRect = GetEntryBoundRect( pEntry );
     700          48 :         if( rRect.IsOver( rBoundRect ) )
     701             :         {
     702          48 :             PaintEntry( pEntry, rBoundRect.TopLeft(), pView, true );
     703             :             // set entries to Top if they are being repainted
     704          48 :             pPaintedEntries->push_back( pEntry );
     705             :         }
     706             :         else
     707           0 :             pNewZOrderList->push_back( pEntry );
     708             : 
     709          48 :         nCount--;
     710          48 :         nPos++;
     711             :     }
     712          12 :     delete pZOrderList;
     713          12 :     pZOrderList = pNewZOrderList;
     714          12 :     nCount = pPaintedEntries->size();
     715          12 :     if( nCount )
     716             :     {
     717          60 :         for( size_t nCur = 0; nCur < nCount; nCur++ )
     718          48 :             pZOrderList->push_back( (*pPaintedEntries)[ nCur ] );
     719             :     }
     720          12 :     pPaintedEntries.reset();
     721             : 
     722          12 :     if( bResetClipRegion )
     723          12 :         pView->SetClipRegion();
     724             : }
     725             : 
     726          54 : void SvxIconChoiceCtrl_Impl::RepaintEntries( sal_uInt16 nEntryFlagsMask )
     727             : {
     728          54 :     const size_t nCount = pZOrderList->size();
     729          54 :     if( !nCount )
     730          54 :         return;
     731             : 
     732          54 :     bool bResetClipRegion = false;
     733          54 :     Rectangle aOutRect( GetOutputRect() );
     734          54 :     if( !pView->IsClipRegion() )
     735             :     {
     736          54 :         bResetClipRegion = true;
     737          54 :         pView->SetClipRegion(vcl::Region(aOutRect));
     738             :     }
     739         270 :     for( size_t nCur = 0; nCur < nCount; nCur++ )
     740             :     {
     741         216 :         SvxIconChoiceCtrlEntry* pEntry = (*pZOrderList)[ nCur ];
     742         216 :         if( pEntry->GetFlags() & nEntryFlagsMask )
     743             :         {
     744           6 :             const Rectangle& rBoundRect = GetEntryBoundRect( pEntry );
     745           6 :             if( aOutRect.IsOver( rBoundRect ) )
     746           6 :                 PaintEntry( pEntry, rBoundRect.TopLeft() );
     747             :         }
     748             :     }
     749          54 :     if( bResetClipRegion )
     750          54 :         pView->SetClipRegion();
     751             : }
     752             : 
     753             : 
     754          66 : void SvxIconChoiceCtrl_Impl::InitScrollBarBox()
     755             : {
     756          66 :     aScrBarBox.SetSizePixel( Size(nVerSBarWidth-1, nHorSBarHeight-1) );
     757          66 :     Size aSize( pView->GetOutputSizePixel() );
     758          66 :     aScrBarBox.SetPosPixel( Point(aSize.Width()-nVerSBarWidth+1, aSize.Height()-nHorSBarHeight+1));
     759          66 : }
     760             : 
     761           0 : bool SvxIconChoiceCtrl_Impl::MouseButtonDown( const MouseEvent& rMEvt)
     762             : {
     763           0 :     bool bHandled = true;
     764           0 :     bHighlightFramePressed = false;
     765           0 :     StopEditTimer();
     766           0 :     bool bGotFocus = (!pView->HasFocus() && !(nWinBits & WB_NOPOINTERFOCUS));
     767           0 :     if( !(nWinBits & WB_NOPOINTERFOCUS) )
     768           0 :         pView->GrabFocus();
     769             : 
     770           0 :     Point aDocPos( rMEvt.GetPosPixel() );
     771           0 :     if(aDocPos.X()>=aOutputSize.Width() || aDocPos.Y()>=aOutputSize.Height())
     772           0 :         return false;
     773           0 :     ToDocPos( aDocPos );
     774           0 :     SvxIconChoiceCtrlEntry* pEntry = GetEntry( aDocPos, true );
     775           0 :     if( pEntry )
     776           0 :         MakeEntryVisible( pEntry, false );
     777             : 
     778           0 :     if( rMEvt.IsShift() && eSelectionMode != SINGLE_SELECTION )
     779             :     {
     780           0 :         if( pEntry )
     781           0 :             SetCursor_Impl( pCursor, pEntry, rMEvt.IsMod1(), rMEvt.IsShift(), true);
     782           0 :         return true;
     783             :     }
     784             : 
     785           0 :     if( pAnchor && (rMEvt.IsShift() || rMEvt.IsMod1())) // keyboard selection?
     786             :     {
     787             :         DBG_ASSERT(eSelectionMode != SINGLE_SELECTION,"Invalid selection mode");
     788           0 :         if( rMEvt.IsMod1() )
     789           0 :             nFlags |= F_ADD_MODE;
     790             : 
     791           0 :         if( rMEvt.IsShift() )
     792             :         {
     793           0 :             Rectangle aRect( GetEntryBoundRect( pAnchor ));
     794           0 :             if( pEntry )
     795           0 :                 aRect.Union( GetEntryBoundRect( pEntry ) );
     796             :             else
     797             :             {
     798           0 :                 Rectangle aTempRect( aDocPos, Size(1,1));
     799           0 :                 aRect.Union( aTempRect );
     800             :             }
     801           0 :             aCurSelectionRect = aRect;
     802           0 :             SelectRect( aRect, (nFlags & F_ADD_MODE)!=0, &aSelectedRectList );
     803             :         }
     804           0 :         else if( rMEvt.IsMod1() )
     805             :         {
     806           0 :             AddSelectedRect( aCurSelectionRect );
     807           0 :             pAnchor = 0;
     808           0 :             aCurSelectionRect.SetPos( aDocPos );
     809             :         }
     810             : 
     811           0 :         if( !pEntry && !(nWinBits & WB_NODRAGSELECTION))
     812           0 :             pView->StartTracking( STARTTRACK_SCROLLREPEAT );
     813           0 :         return true;
     814             :     }
     815             :     else
     816             :     {
     817           0 :         if( !pEntry )
     818             :         {
     819           0 :             if( eSelectionMode == MULTIPLE_SELECTION )
     820             :             {
     821           0 :                 if( !rMEvt.IsMod1() )  // Ctrl
     822             :                 {
     823           0 :                     if( !bGotFocus )
     824             :                     {
     825           0 :                         SetNoSelection();
     826           0 :                         ClearSelectedRectList();
     827             :                     }
     828             :                 }
     829             :                 else
     830           0 :                     nFlags |= F_ADD_MODE;
     831           0 :                 aCurSelectionRect.SetPos( aDocPos );
     832           0 :                 pView->StartTracking( STARTTRACK_SCROLLREPEAT );
     833             :             }
     834             :             else
     835           0 :                 bHandled = false;
     836           0 :             return bHandled;
     837             :         }
     838             :     }
     839           0 :     bool bSelected = pEntry->IsSelected();
     840           0 :     bool bEditingEnabled = IsEntryEditingEnabled();
     841             : 
     842           0 :     if( rMEvt.GetClicks() == 2 )
     843             :     {
     844           0 :         DeselectAllBut( pEntry );
     845           0 :         SelectEntry( pEntry, true, true, false, true );
     846           0 :         pHdlEntry = pEntry;
     847           0 :         pView->ClickIcon();
     848             :     }
     849             :     else
     850             :     {
     851             :         // Inplace-Editing ?
     852           0 :         if( rMEvt.IsMod2() )  // Alt?
     853             :         {
     854           0 :             if( bEntryEditingEnabled && pEntry &&
     855           0 :                 pEntry->IsSelected())
     856             :             {
     857           0 :                 if( pView->EditingEntry( pEntry ))
     858           0 :                     EditEntry( pEntry );
     859             :             }
     860             :         }
     861           0 :         else if( eSelectionMode == SINGLE_SELECTION )
     862             :         {
     863           0 :             DeselectAllBut( pEntry );
     864           0 :             SetCursor( pEntry );
     865           0 :             if( bEditingEnabled && bSelected && !rMEvt.GetModifier() &&
     866           0 :                 rMEvt.IsLeft() && IsTextHit( pEntry, aDocPos ) )
     867             :             {
     868           0 :                 nFlags |= F_START_EDITTIMER_IN_MOUSEUP;
     869             :             }
     870             :         }
     871           0 :         else if( eSelectionMode == NO_SELECTION )
     872             :         {
     873           0 :             if( rMEvt.IsLeft() && (nWinBits & WB_HIGHLIGHTFRAME) )
     874             :             {
     875           0 :                 pCurHighlightFrame = 0; // force repaint of frame
     876           0 :                 bHighlightFramePressed = true;
     877           0 :                 SetEntryHighlightFrame( pEntry, true );
     878             :             }
     879             :         }
     880             :         else
     881             :         {
     882           0 :             if( !rMEvt.GetModifier() && rMEvt.IsLeft() )
     883             :             {
     884           0 :                 if( !bSelected )
     885             :                 {
     886           0 :                     DeselectAllBut( pEntry, true /* paint synchronously */ );
     887           0 :                     SetCursor( pEntry );
     888           0 :                     SelectEntry( pEntry, true, true, false, true );
     889             :                 }
     890             :                 else
     891             :                 {
     892             :                     // deselect only in the Up, if the Move happened via D&D!
     893           0 :                     nFlags |= F_DOWN_DESELECT;
     894           0 :                     if( bEditingEnabled && IsTextHit( pEntry, aDocPos ) &&
     895           0 :                         rMEvt.IsLeft())
     896             :                     {
     897           0 :                         nFlags |= F_START_EDITTIMER_IN_MOUSEUP;
     898             :                     }
     899             :                 }
     900             :             }
     901           0 :             else if( rMEvt.IsMod1() )
     902           0 :                 nFlags |= F_DOWN_CTRL;
     903             :         }
     904             :     }
     905           0 :     return bHandled;
     906             : }
     907             : 
     908           0 : bool SvxIconChoiceCtrl_Impl::MouseButtonUp( const MouseEvent& rMEvt )
     909             : {
     910           0 :     bool bHandled = false;
     911           0 :     if( rMEvt.IsRight() && (nFlags & (F_DOWN_CTRL | F_DOWN_DESELECT) ))
     912             :     {
     913           0 :         nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT);
     914           0 :         bHandled = true;
     915             :     }
     916             : 
     917           0 :     Point aDocPos( rMEvt.GetPosPixel() );
     918           0 :     ToDocPos( aDocPos );
     919           0 :     SvxIconChoiceCtrlEntry* pDocEntry = GetEntry( aDocPos );
     920           0 :     if( pDocEntry )
     921             :     {
     922           0 :         if( nFlags & F_DOWN_CTRL )
     923             :         {
     924             :             // Ctrl & MultiSelection
     925           0 :             ToggleSelection( pDocEntry );
     926           0 :             SetCursor( pDocEntry );
     927           0 :             bHandled = true;
     928             :         }
     929           0 :         else if( nFlags & F_DOWN_DESELECT )
     930             :         {
     931           0 :             DeselectAllBut( pDocEntry );
     932           0 :             SetCursor( pDocEntry );
     933           0 :             SelectEntry( pDocEntry, true, true, false, true );
     934           0 :             bHandled = true;
     935             :         }
     936             :     }
     937             : 
     938           0 :     nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT);
     939           0 :     if( nFlags & F_START_EDITTIMER_IN_MOUSEUP )
     940             :     {
     941           0 :         bHandled = true;
     942           0 :         StartEditTimer();
     943           0 :         nFlags &= ~F_START_EDITTIMER_IN_MOUSEUP;
     944             :     }
     945             : 
     946           0 :     if((nWinBits & WB_HIGHLIGHTFRAME) && bHighlightFramePressed && pCurHighlightFrame)
     947             :     {
     948           0 :         bHandled = true;
     949           0 :         SvxIconChoiceCtrlEntry* pEntry = pCurHighlightFrame;
     950           0 :         pCurHighlightFrame = 0; // force repaint of frame
     951           0 :         bHighlightFramePressed = false;
     952           0 :         SetEntryHighlightFrame( pEntry, true );
     953             : 
     954           0 :         pHdlEntry = pCurHighlightFrame;
     955           0 :         pView->ClickIcon();
     956             : 
     957             :         // set focus on Icon
     958           0 :         SvxIconChoiceCtrlEntry* pOldCursor = pCursor;
     959           0 :         SetCursor_Impl( pOldCursor, pHdlEntry, false, false, true );
     960             : 
     961           0 :         pHdlEntry = 0;
     962             :     }
     963           0 :     return bHandled;
     964             : }
     965             : 
     966           0 : bool SvxIconChoiceCtrl_Impl::MouseMove( const MouseEvent& rMEvt )
     967             : {
     968           0 :     const Point aDocPos( pView->PixelToLogic(rMEvt.GetPosPixel()) );
     969             : 
     970           0 :     if( pView->IsTracking() )
     971           0 :         return false;
     972           0 :     else if( nWinBits & WB_HIGHLIGHTFRAME )
     973             :     {
     974           0 :         SvxIconChoiceCtrlEntry* pEntry = GetEntry( aDocPos, true );
     975           0 :         SetEntryHighlightFrame( pEntry );
     976             :     }
     977             :     else
     978           0 :         return false;
     979           0 :     return true;
     980             : }
     981             : 
     982           0 : void SvxIconChoiceCtrl_Impl::SetCursor_Impl( SvxIconChoiceCtrlEntry* pOldCursor,
     983             :     SvxIconChoiceCtrlEntry* pNewCursor, bool bMod1, bool bShift, bool bPaintSync )
     984             : {
     985           0 :     if( pNewCursor )
     986             :     {
     987           0 :         SvxIconChoiceCtrlEntry* pFilterEntry = 0;
     988           0 :         bool bDeselectAll = false;
     989           0 :         if( eSelectionMode != SINGLE_SELECTION )
     990             :         {
     991           0 :             if( !bMod1 && !bShift )
     992           0 :                 bDeselectAll = true;
     993           0 :             else if( bShift && !bMod1 && !pAnchor )
     994             :             {
     995           0 :                 bDeselectAll = true;
     996           0 :                 pFilterEntry = pOldCursor;
     997             :             }
     998             :         }
     999           0 :         if( bDeselectAll )
    1000           0 :             DeselectAllBut( pFilterEntry, bPaintSync );
    1001           0 :         ShowCursor( false );
    1002           0 :         MakeEntryVisible( pNewCursor );
    1003           0 :         SetCursor( pNewCursor );
    1004           0 :         if( bMod1 && !bShift )
    1005             :         {
    1006           0 :             if( pAnchor )
    1007             :             {
    1008           0 :                 AddSelectedRect( pAnchor, pOldCursor );
    1009           0 :                 pAnchor = 0;
    1010             :             }
    1011             :         }
    1012           0 :         else if( bShift )
    1013             :         {
    1014           0 :             if( !pAnchor )
    1015           0 :                 pAnchor = pOldCursor;
    1016           0 :             if ( nWinBits & WB_ALIGN_LEFT )
    1017           0 :                 SelectRange( pAnchor, pNewCursor, (nFlags & F_ADD_MODE)!=0 );
    1018             :             else
    1019           0 :                 SelectRect(pAnchor,pNewCursor,(nFlags & F_ADD_MODE)!=0,&aSelectedRectList);
    1020             :         }
    1021             :         else
    1022             :         {
    1023           0 :             SelectEntry( pCursor, true, true,  false, bPaintSync );
    1024           0 :             aCurSelectionRect = GetEntryBoundRect( pCursor );
    1025           0 :             CallEventListeners( VCLEVENT_LISTBOX_SELECT, pCursor );
    1026             :         }
    1027             :     }
    1028           0 : }
    1029             : 
    1030           0 : bool SvxIconChoiceCtrl_Impl::KeyInput( const KeyEvent& rKEvt )
    1031             : {
    1032           0 :     StopEditTimer();
    1033             : 
    1034           0 :     bool bMod2 = rKEvt.GetKeyCode().IsMod2();
    1035           0 :     sal_Unicode cChar = rKEvt.GetCharCode();
    1036           0 :     sal_uLong nPos = (sal_uLong)-1;
    1037           0 :     if ( bMod2 && cChar && IsMnemonicChar( cChar, nPos ) )
    1038             :     {
    1039             :         // shortcut is clicked
    1040           0 :         SvxIconChoiceCtrlEntry* pNewCursor = GetEntry( nPos );
    1041           0 :         SvxIconChoiceCtrlEntry* pOldCursor = pCursor;
    1042           0 :         if ( pNewCursor != pOldCursor )
    1043           0 :             SetCursor_Impl( pOldCursor, pNewCursor, false, false, false );
    1044           0 :         return true;
    1045             :     }
    1046             : 
    1047           0 :     if ( bMod2 )
    1048             :         // no actions with <ALT>
    1049           0 :         return false;
    1050             : 
    1051           0 :     bool bKeyUsed = true;
    1052           0 :     bool bMod1 = rKEvt.GetKeyCode().IsMod1();
    1053           0 :     bool bShift = rKEvt.GetKeyCode().IsShift();
    1054             : 
    1055           0 :     if( eSelectionMode == SINGLE_SELECTION || eSelectionMode == NO_SELECTION)
    1056             :     {
    1057           0 :         bShift = false;
    1058           0 :         bMod1 = false;
    1059             :     }
    1060             : 
    1061           0 :     if( bMod1 )
    1062           0 :         nFlags |= F_ADD_MODE;
    1063             : 
    1064             :     SvxIconChoiceCtrlEntry* pNewCursor;
    1065           0 :     SvxIconChoiceCtrlEntry* pOldCursor = pCursor;
    1066             : 
    1067           0 :     sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
    1068           0 :     switch( nCode )
    1069             :     {
    1070             :         case KEY_UP:
    1071             :         case KEY_PAGEUP:
    1072           0 :             if( pCursor )
    1073             :             {
    1074           0 :                 MakeEntryVisible( pCursor );
    1075           0 :                 if( nCode == KEY_UP )
    1076           0 :                     pNewCursor = pImpCursor->GoUpDown(pCursor,false);
    1077             :                 else
    1078           0 :                     pNewCursor = pImpCursor->GoPageUpDown(pCursor,false);
    1079           0 :                 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, true );
    1080           0 :                 if( !pNewCursor )
    1081             :                 {
    1082           0 :                     Rectangle aRect( GetEntryBoundRect( pCursor ) );
    1083           0 :                     if( aRect.Top())
    1084             :                     {
    1085           0 :                         aRect.Bottom() -= aRect.Top();
    1086           0 :                         aRect.Top() = 0;
    1087           0 :                         MakeVisible( aRect );
    1088             :                     }
    1089             :                 }
    1090             : 
    1091           0 :                 if ( bChooseWithCursor && pNewCursor != NULL )
    1092             :                 {
    1093           0 :                     pHdlEntry = pNewCursor;//GetCurEntry();
    1094           0 :                     pCurHighlightFrame = pHdlEntry;
    1095           0 :                     pView->ClickIcon();
    1096           0 :                     pCurHighlightFrame = NULL;
    1097             :                 }
    1098             :             }
    1099           0 :             break;
    1100             : 
    1101             :         case KEY_DOWN:
    1102             :         case KEY_PAGEDOWN:
    1103           0 :             if( pCursor )
    1104             :             {
    1105           0 :                 if( nCode == KEY_DOWN )
    1106           0 :                     pNewCursor=pImpCursor->GoUpDown( pCursor,true );
    1107             :                 else
    1108           0 :                     pNewCursor=pImpCursor->GoPageUpDown( pCursor,true );
    1109           0 :                 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, true );
    1110             : 
    1111           0 :                 if ( bChooseWithCursor && pNewCursor != NULL)
    1112             :                 {
    1113           0 :                     pHdlEntry = pNewCursor;//GetCurEntry();
    1114           0 :                     pCurHighlightFrame = pHdlEntry;
    1115           0 :                     pView->ClickIcon();
    1116           0 :                     pCurHighlightFrame = NULL;
    1117             :                 }
    1118             :             }
    1119           0 :             break;
    1120             : 
    1121             :         case KEY_RIGHT:
    1122           0 :             if( pCursor )
    1123             :             {
    1124           0 :                 pNewCursor=pImpCursor->GoLeftRight(pCursor,true );
    1125           0 :                 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, true );
    1126             :             }
    1127           0 :             break;
    1128             : 
    1129             :         case KEY_LEFT:
    1130           0 :             if( pCursor )
    1131             :             {
    1132           0 :                 MakeEntryVisible( pCursor );
    1133           0 :                 pNewCursor = pImpCursor->GoLeftRight(pCursor,false );
    1134           0 :                 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, true );
    1135           0 :                 if( !pNewCursor )
    1136             :                 {
    1137           0 :                     Rectangle aRect( GetEntryBoundRect(pCursor));
    1138           0 :                     if( aRect.Left() )
    1139             :                     {
    1140           0 :                         aRect.Right() -= aRect.Left();
    1141           0 :                         aRect.Left() = 0;
    1142           0 :                         MakeVisible( aRect );
    1143             :                     }
    1144             :                 }
    1145             :             }
    1146           0 :             break;
    1147             : 
    1148             :         case KEY_F2:
    1149           0 :             if( !bMod1 && !bShift )
    1150           0 :                 EditTimeoutHdl( 0 );
    1151             :             else
    1152           0 :                 bKeyUsed = false;
    1153           0 :             break;
    1154             : 
    1155             :         case KEY_F8:
    1156           0 :             if( rKEvt.GetKeyCode().IsShift() )
    1157             :             {
    1158           0 :                 if( nFlags & F_ADD_MODE )
    1159           0 :                     nFlags &= (~F_ADD_MODE);
    1160             :                 else
    1161           0 :                     nFlags |= F_ADD_MODE;
    1162             :             }
    1163             :             else
    1164           0 :                 bKeyUsed = false;
    1165           0 :             break;
    1166             : 
    1167             :         case KEY_SPACE:
    1168           0 :             if( pCursor && eSelectionMode != SINGLE_SELECTION )
    1169             :             {
    1170           0 :                 if( !bMod1 )
    1171             :                 {
    1172             :                     //SelectAll( false );
    1173           0 :                     SetNoSelection();
    1174           0 :                     ClearSelectedRectList();
    1175             : 
    1176             :                     // click Icon with spacebar
    1177           0 :                     SetEntryHighlightFrame( GetCurEntry(), true );
    1178           0 :                     pView->ClickIcon();
    1179           0 :                     pHdlEntry = pCurHighlightFrame;
    1180           0 :                     pCurHighlightFrame=0;
    1181             :                 }
    1182             :                 else
    1183           0 :                     ToggleSelection( pCursor );
    1184             :             }
    1185           0 :             break;
    1186             : 
    1187             : #ifdef DBG_UTIL
    1188             :         case KEY_F10:
    1189             :             if( rKEvt.GetKeyCode().IsShift() )
    1190             :             {
    1191             :                 if( pCursor )
    1192             :                     pView->SetEntryTextMode( IcnShowTextFull, pCursor );
    1193             :             }
    1194             :             if( rKEvt.GetKeyCode().IsMod1() )
    1195             :             {
    1196             :                 if( pCursor )
    1197             :                     pView->SetEntryTextMode( IcnShowTextShort, pCursor );
    1198             :             }
    1199             :             break;
    1200             : #endif
    1201             : 
    1202             :         case KEY_ADD:
    1203             :         case KEY_DIVIDE :
    1204             :         case KEY_A:
    1205           0 :             if( bMod1 && (eSelectionMode != SINGLE_SELECTION))
    1206           0 :                 SelectAll( true );
    1207             :             else
    1208           0 :                 bKeyUsed = false;
    1209           0 :             break;
    1210             : 
    1211             :         case KEY_SUBTRACT:
    1212             :         case KEY_COMMA :
    1213           0 :             if( bMod1 )
    1214           0 :                 SetNoSelection();
    1215             :             else
    1216           0 :                 bKeyUsed = false;
    1217           0 :             break;
    1218             : 
    1219             :         case KEY_RETURN:
    1220           0 :             if( bMod1 )
    1221             :             {
    1222           0 :                 if( pCursor && bEntryEditingEnabled )
    1223           0 :                     /*pView->*/EditEntry( pCursor );
    1224             :             }
    1225             :             else
    1226           0 :                 bKeyUsed = false;
    1227           0 :             break;
    1228             : 
    1229             :         case KEY_END:
    1230           0 :             if( pCursor )
    1231             :             {
    1232           0 :                 pNewCursor = aEntries[ aEntries.size() - 1 ];
    1233           0 :                 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, true );
    1234             :             }
    1235           0 :             break;
    1236             : 
    1237             :         case KEY_HOME:
    1238           0 :             if( pCursor )
    1239             :             {
    1240           0 :                 pNewCursor = aEntries[ 0 ];
    1241           0 :                 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, true );
    1242             :             }
    1243           0 :             break;
    1244             : 
    1245             :         default:
    1246           0 :             bKeyUsed = false;
    1247             : 
    1248             :     }
    1249           0 :     return bKeyUsed;
    1250             : }
    1251             : 
    1252             : // recalculate TopLeft of scrollbars (but not their sizes!)
    1253         814 : void SvxIconChoiceCtrl_Impl::PositionScrollBars( long nRealWidth, long nRealHeight )
    1254             : {
    1255             :     // horizontal scrollbar
    1256         814 :     Point aPos( 0, nRealHeight );
    1257         814 :     aPos.Y() -= nHorSBarHeight;
    1258             : 
    1259         814 :     if( aHorSBar.GetPosPixel() != aPos )
    1260          50 :         aHorSBar.SetPosPixel( aPos );
    1261             : 
    1262             :     // vertical scrollbar
    1263         814 :     aPos.X() = nRealWidth; aPos.Y() = 0;
    1264         814 :     aPos.X() -= nVerSBarWidth;
    1265         814 :     aPos.X()++;
    1266         814 :     aPos.Y()--;
    1267             : 
    1268         814 :     if( aVerSBar.GetPosPixel() != aPos )
    1269          32 :         aVerSBar.SetPosPixel( aPos );
    1270         814 : }
    1271             : 
    1272         748 : void SvxIconChoiceCtrl_Impl::AdjustScrollBars( bool )
    1273             : {
    1274         748 :     Rectangle aOldOutRect( GetOutputRect() );
    1275         748 :     long nVirtHeight = aVirtOutputSize.Height();
    1276         748 :     long nVirtWidth = aVirtOutputSize.Width();
    1277             : 
    1278         748 :     Size aOSize( pView->Control::GetOutputSizePixel() );
    1279         748 :     long nRealHeight = aOSize.Height();
    1280         748 :     long nRealWidth = aOSize.Width();
    1281             : 
    1282         748 :     PositionScrollBars( nRealWidth, nRealHeight );
    1283             : 
    1284         748 :     const MapMode& rMapMode = pView->GetMapMode();
    1285         748 :     Point aOrigin( rMapMode.GetOrigin() );
    1286             : 
    1287             :     long nVisibleWidth;
    1288         748 :     if( nRealWidth > nVirtWidth )
    1289         552 :         nVisibleWidth = nVirtWidth + aOrigin.X();
    1290             :     else
    1291         196 :         nVisibleWidth = nRealWidth;
    1292             : 
    1293             :     long nVisibleHeight;
    1294         748 :     if( nRealHeight > nVirtHeight )
    1295         362 :         nVisibleHeight = nVirtHeight + aOrigin.Y();
    1296             :     else
    1297         386 :         nVisibleHeight = nRealHeight;
    1298             : 
    1299         748 :     bool bVerSBar = ( nWinBits & WB_VSCROLL ) != 0;
    1300         748 :     bool bHorSBar = ( nWinBits & WB_HSCROLL ) != 0;
    1301         748 :     bool bNoVerSBar = ( nWinBits & WB_NOVSCROLL ) != 0;
    1302         748 :     bool bNoHorSBar = ( nWinBits & WB_NOHSCROLL ) != 0;
    1303             : 
    1304         748 :     sal_uInt16 nResult = 0;
    1305         748 :     if( nVirtHeight )
    1306             :     {
    1307             :         // activate vertical scrollbar?
    1308         720 :         if( !bNoVerSBar && (bVerSBar || ( nVirtHeight > nVisibleHeight)) )
    1309             :         {
    1310           0 :             nResult = 0x0001;
    1311           0 :             nRealWidth -= nVerSBarWidth;
    1312             : 
    1313           0 :             if( nRealWidth > nVirtWidth )
    1314           0 :                 nVisibleWidth = nVirtWidth + aOrigin.X();
    1315             :             else
    1316           0 :                 nVisibleWidth = nRealWidth;
    1317             : 
    1318           0 :             nFlags |= F_HOR_SBARSIZE_WITH_VBAR;
    1319             :         }
    1320             :         // activate horizontal scrollbar?
    1321         720 :         if( !bNoHorSBar && (bHorSBar || (nVirtWidth > nVisibleWidth)) )
    1322             :         {
    1323           0 :             nResult |= 0x0002;
    1324           0 :             nRealHeight -= nHorSBarHeight;
    1325             : 
    1326           0 :             if( nRealHeight > nVirtHeight )
    1327           0 :                 nVisibleHeight = nVirtHeight + aOrigin.Y();
    1328             :             else
    1329           0 :                 nVisibleHeight = nRealHeight;
    1330             : 
    1331             :             // do we need a vertical scrollbar after all?
    1332           0 :             if( !(nResult & 0x0001) &&  // only if not already there
    1333           0 :                 ( !bNoVerSBar && ((nVirtHeight > nVisibleHeight) || bVerSBar)) )
    1334             :             {
    1335           0 :                 nResult = 3; // both turned on
    1336           0 :                 nRealWidth -= nVerSBarWidth;
    1337             : 
    1338           0 :                 if( nRealWidth > nVirtWidth )
    1339           0 :                     nVisibleWidth = nVirtWidth + aOrigin.X();
    1340             :                 else
    1341           0 :                     nVisibleWidth = nRealWidth;
    1342             : 
    1343           0 :                 nFlags |= F_VER_SBARSIZE_WITH_HBAR;
    1344             :             }
    1345             :         }
    1346             :     }
    1347             : 
    1348             :     // size vertical scrollbar
    1349         748 :     long nThumb = aVerSBar.GetThumbPos();
    1350         748 :     Size aSize( nVerSBarWidth, nRealHeight );
    1351         748 :     aSize.Height() += 2;
    1352         748 :     if( aSize != aVerSBar.GetSizePixel() )
    1353          50 :         aVerSBar.SetSizePixel( aSize );
    1354         748 :     aVerSBar.SetVisibleSize( nVisibleHeight );
    1355         748 :     aVerSBar.SetPageSize( GetScrollBarPageSize( nVisibleHeight ));
    1356             : 
    1357         748 :     if( nResult & 0x0001 )
    1358             :     {
    1359           0 :         aVerSBar.SetThumbPos( nThumb );
    1360           0 :         aVerSBar.Show();
    1361             :     }
    1362             :     else
    1363             :     {
    1364         748 :         aVerSBar.SetThumbPos( 0 );
    1365         748 :         aVerSBar.Hide();
    1366             :     }
    1367             : 
    1368             :     // size horizontal scrollbar
    1369         748 :     nThumb = aHorSBar.GetThumbPos();
    1370         748 :     aSize.Width() = nRealWidth;
    1371         748 :     aSize.Height() = nHorSBarHeight;
    1372         748 :     aSize.Width()++;
    1373         748 :     if( nResult & 0x0001 ) // vertical scrollbar?
    1374             :     {
    1375           0 :         aSize.Width()++;
    1376           0 :         nRealWidth++;
    1377             :     }
    1378         748 :     if( aSize != aHorSBar.GetSizePixel() )
    1379          32 :         aHorSBar.SetSizePixel( aSize );
    1380         748 :     aHorSBar.SetVisibleSize( nVisibleWidth );
    1381         748 :     aHorSBar.SetPageSize( GetScrollBarPageSize(nVisibleWidth ));
    1382         748 :     if( nResult & 0x0002 )
    1383             :     {
    1384           0 :         aHorSBar.SetThumbPos( nThumb );
    1385           0 :         aHorSBar.Show();
    1386             :     }
    1387             :     else
    1388             :     {
    1389         748 :         aHorSBar.SetThumbPos( 0 );
    1390         748 :         aHorSBar.Hide();
    1391             :     }
    1392             : 
    1393         748 :     aOutputSize.Width() = nRealWidth;
    1394         748 :     if( nResult & 0x0002 ) // horizontal scrollbar ?
    1395           0 :         nRealHeight++; // because lower border is clipped
    1396         748 :     aOutputSize.Height() = nRealHeight;
    1397             : 
    1398         748 :     Rectangle aNewOutRect( GetOutputRect() );
    1399         748 :     if( aNewOutRect != aOldOutRect && pView->HasBackground() )
    1400             :     {
    1401           0 :         Wallpaper aPaper( pView->GetBackground() );
    1402           0 :         aPaper.SetRect( aNewOutRect );
    1403           0 :         pView->SetBackground( aPaper );
    1404             :     }
    1405             : 
    1406         748 :     if( (nResult & (0x0001|0x0002)) == (0x0001|0x0002) )
    1407           0 :         aScrBarBox.Show();
    1408             :     else
    1409         748 :         aScrBarBox.Hide();
    1410         748 : }
    1411             : 
    1412          66 : void SvxIconChoiceCtrl_Impl::Resize()
    1413             : {
    1414          66 :     StopEditTimer();
    1415          66 :     InitScrollBarBox();
    1416          66 :     aOutputSize = pView->GetOutputSizePixel();
    1417          66 :     pImpCursor->Clear();
    1418          66 :     pGridMap->OutputSizeChanged();
    1419             : 
    1420          66 :     const Size& rSize = pView->Control::GetOutputSizePixel();
    1421          66 :     PositionScrollBars( rSize.Width(), rSize.Height() );
    1422             :     // The scrollbars are shown/hidden asynchronously, so derived classes can
    1423             :     // do an Arrange during Resize, without the scrollbars suddenly turning
    1424             :     // on and off again.
    1425             :     // If an event is already underway, we don't need to send a new one, at least
    1426             :     // as long as there is only one event type.
    1427          66 :     if ( ! nUserEventAdjustScrBars )
    1428             :         nUserEventAdjustScrBars =
    1429             :             Application::PostUserEvent( LINK( this, SvxIconChoiceCtrl_Impl, UserEventHdl),
    1430          22 :                 EVENTID_ADJUST_SCROLLBARS);
    1431             : 
    1432          66 :     if( pView->HasBackground() && !pView->GetBackground().IsScrollable() )
    1433             :     {
    1434           0 :         Rectangle aRect( GetOutputRect());
    1435           0 :         Wallpaper aPaper( pView->GetBackground() );
    1436           0 :         aPaper.SetRect( aRect );
    1437           0 :         pView->SetBackground( aPaper );
    1438             :     }
    1439          66 :     VisRectChanged();
    1440          66 : }
    1441             : 
    1442           0 : bool SvxIconChoiceCtrl_Impl::CheckHorScrollBar()
    1443             : {
    1444           0 :     if( !pZOrderList || !aHorSBar.IsVisible() )
    1445           0 :         return false;
    1446           0 :     const MapMode& rMapMode = pView->GetMapMode();
    1447           0 :     Point aOrigin( rMapMode.GetOrigin() );
    1448           0 :     if(!( nWinBits & WB_HSCROLL) && !aOrigin.X() )
    1449             :     {
    1450           0 :         long nWidth = aOutputSize.Width();
    1451           0 :         const size_t nCount = pZOrderList->size();
    1452           0 :         long nMostRight = 0;
    1453           0 :         for( size_t nCur = 0; nCur < nCount; nCur++ )
    1454             :         {
    1455           0 :             SvxIconChoiceCtrlEntry* pEntry = (*pZOrderList)[ nCur ];
    1456           0 :             long nRight = GetEntryBoundRect(pEntry).Right();
    1457           0 :             if( nRight > nWidth )
    1458           0 :                 return false;
    1459           0 :             if( nRight > nMostRight )
    1460           0 :                 nMostRight = nRight;
    1461             :         }
    1462           0 :         aHorSBar.Hide();
    1463           0 :         aOutputSize.Height() += nHorSBarHeight;
    1464           0 :         aVirtOutputSize.Width() = nMostRight;
    1465           0 :         aHorSBar.SetThumbPos( 0 );
    1466           0 :         Range aRange;
    1467           0 :         aRange.Max() = nMostRight - 1;
    1468           0 :         aHorSBar.SetRange( aRange  );
    1469           0 :         if( aVerSBar.IsVisible() )
    1470             :         {
    1471           0 :             Size aSize( aVerSBar.GetSizePixel());
    1472           0 :             aSize.Height() += nHorSBarHeight;
    1473           0 :             aVerSBar.SetSizePixel( aSize );
    1474             :         }
    1475           0 :         return true;
    1476             :     }
    1477           0 :     return false;
    1478             : }
    1479             : 
    1480           0 : bool SvxIconChoiceCtrl_Impl::CheckVerScrollBar()
    1481             : {
    1482           0 :     if( !pZOrderList || !aVerSBar.IsVisible() )
    1483           0 :         return false;
    1484           0 :     const MapMode& rMapMode = pView->GetMapMode();
    1485           0 :     Point aOrigin( rMapMode.GetOrigin() );
    1486           0 :     if(!( nWinBits & WB_VSCROLL) && !aOrigin.Y() )
    1487             :     {
    1488           0 :         long nDeepest = 0;
    1489           0 :         long nHeight = aOutputSize.Height();
    1490           0 :         const size_t nCount = pZOrderList->size();
    1491           0 :         for( size_t nCur = 0; nCur < nCount; nCur++ )
    1492             :         {
    1493           0 :             SvxIconChoiceCtrlEntry* pEntry = (*pZOrderList)[ nCur ];
    1494           0 :             long nBottom = GetEntryBoundRect(pEntry).Bottom();
    1495           0 :             if( nBottom > nHeight )
    1496           0 :                 return false;
    1497           0 :             if( nBottom > nDeepest )
    1498           0 :                 nDeepest = nBottom;
    1499             :         }
    1500           0 :         aVerSBar.Hide();
    1501           0 :         aOutputSize.Width() += nVerSBarWidth;
    1502           0 :         aVirtOutputSize.Height() = nDeepest;
    1503           0 :         aVerSBar.SetThumbPos( 0 );
    1504           0 :         Range aRange;
    1505           0 :         aRange.Max() = nDeepest - 1;
    1506           0 :         aVerSBar.SetRange( aRange  );
    1507           0 :         if( aHorSBar.IsVisible() )
    1508             :         {
    1509           0 :             Size aSize( aHorSBar.GetSizePixel());
    1510           0 :             aSize.Width() += nVerSBarWidth;
    1511           0 :             aHorSBar.SetSizePixel( aSize );
    1512             :         }
    1513           0 :         return true;
    1514             :     }
    1515           0 :     return false;
    1516             : }
    1517             : 
    1518             : 
    1519             : // hides scrollbars if they're unnecessary
    1520           0 : void SvxIconChoiceCtrl_Impl::CheckScrollBars()
    1521             : {
    1522           0 :     CheckVerScrollBar();
    1523           0 :     if( CheckHorScrollBar() )
    1524           0 :         CheckVerScrollBar();
    1525           0 :     if( aVerSBar.IsVisible() && aHorSBar.IsVisible() )
    1526           0 :         aScrBarBox.Show();
    1527             :     else
    1528           0 :         aScrBarBox.Hide();
    1529           0 : }
    1530             : 
    1531             : 
    1532          40 : void SvxIconChoiceCtrl_Impl::GetFocus()
    1533             : {
    1534          40 :     RepaintEntries( ICNVIEW_FLAG_SELECTED );
    1535          40 :     if( pCursor )
    1536             :     {
    1537          12 :         pCursor->SetFlags( ICNVIEW_FLAG_FOCUSED );
    1538          12 :         ShowCursor( true );
    1539             :     }
    1540          40 : }
    1541             : 
    1542          14 : void SvxIconChoiceCtrl_Impl::LoseFocus()
    1543             : {
    1544          14 :     StopEditTimer();
    1545          14 :     if( pCursor )
    1546           0 :         pCursor->ClearFlags( ICNVIEW_FLAG_FOCUSED );
    1547          14 :     ShowCursor( false );
    1548             : 
    1549             : //  HideFocus ();
    1550             : //  pView->Invalidate ( aFocus.aRect );
    1551             : 
    1552          14 :     RepaintEntries( ICNVIEW_FLAG_SELECTED );
    1553          14 : }
    1554             : 
    1555           0 : void SvxIconChoiceCtrl_Impl::SetUpdateMode( bool bUpdate )
    1556             : {
    1557           0 :     if( bUpdate != bUpdateMode )
    1558             :     {
    1559           0 :         bUpdateMode = bUpdate;
    1560           0 :         if( bUpdate )
    1561             :         {
    1562           0 :             AdjustScrollBars();
    1563           0 :             pImpCursor->Clear();
    1564           0 :             pGridMap->Clear();
    1565           0 :             pView->Invalidate(INVALIDATE_NOCHILDREN);
    1566             :         }
    1567             :     }
    1568           0 : }
    1569             : 
    1570           0 : void SvxIconChoiceCtrl_Impl::PaintEntry( SvxIconChoiceCtrlEntry* pEntry, bool bIsBackgroundPainted )
    1571             : {
    1572           0 :     Point aPos( GetEntryPos( pEntry ) );
    1573           0 :     PaintEntry( pEntry, aPos, 0, bIsBackgroundPainted );
    1574           0 : }
    1575             : 
    1576             : // priorities of the emphasis:  bDropTarget => bCursored => bSelected
    1577          54 : void SvxIconChoiceCtrl_Impl::PaintEmphasis(
    1578             :     const Rectangle& rTextRect, const Rectangle& rImageRect,
    1579             :     bool bSelected, bool bDropTarget, bool bCursored, OutputDevice* pOut,
    1580             :     bool bIsBackgroundPainted )
    1581             : {
    1582          54 :     static Color aTransparent( COL_TRANSPARENT );
    1583             : 
    1584          54 :     if( !pOut )
    1585           0 :         pOut = pView;
    1586             : 
    1587          54 :     const StyleSettings& rSettings = pOut->GetSettings().GetStyleSettings();
    1588          54 :     Color aOldFillColor( pOut->GetFillColor() );
    1589             : 
    1590          54 :     bool bSolidTextRect = false;
    1591          54 :     bool bSolidImageRect = false;
    1592             : 
    1593          54 :     if( bDropTarget && ( eSelectionMode != NO_SELECTION ) )
    1594             :     {
    1595           0 :         pOut->SetFillColor( rSettings.GetHighlightColor() );
    1596           0 :         bSolidTextRect = true;
    1597           0 :         bSolidImageRect = true;
    1598             :     }
    1599             :     else
    1600             :     {
    1601          54 :         if ( !bSelected || bCursored )
    1602             :         {
    1603          42 :             if( !pView->HasFontFillColor() )
    1604           0 :                 pOut->SetFillColor( pOut->GetBackground().GetColor() );
    1605             :             else
    1606             :             {
    1607          42 :                 const Color& rFillColor = pView->GetFont().GetFillColor();
    1608          42 :                 pOut->SetFillColor( rFillColor );
    1609          42 :                 if( rFillColor != aTransparent )
    1610           0 :                     bSolidTextRect = true;
    1611             :             }
    1612             :         }
    1613             :     }
    1614             : 
    1615             :     // draw text rectangle
    1616          54 :     if( !bSolidTextRect )
    1617             :     {
    1618          54 :         if( !bIsBackgroundPainted )
    1619           6 :             pOut->Erase( rTextRect );
    1620             :     }
    1621             :     else
    1622             :     {
    1623           0 :         Color aOldLineColor;
    1624           0 :         if( bCursored )
    1625             :         {
    1626           0 :             aOldLineColor = pOut->GetLineColor();
    1627           0 :             pOut->SetLineColor( Color( COL_GRAY ) );
    1628             :         }
    1629           0 :         pOut->DrawRect( rTextRect );
    1630           0 :         if( bCursored )
    1631           0 :             pOut->SetLineColor( aOldLineColor );
    1632             :     }
    1633             : 
    1634             :     // draw image rectangle
    1635          54 :     if( !bSolidImageRect )
    1636             :     {
    1637          54 :         if( !bIsBackgroundPainted )
    1638           6 :             pOut->Erase( rImageRect );
    1639             :     }
    1640             : // the emphasis of the images has to be drawn by the derived class (in the
    1641             : // virtual function DrawEntryImage)
    1642             : //  else
    1643             : //      pOut->DrawRect( rImageRect );
    1644             : 
    1645          54 :     pOut->SetFillColor( aOldFillColor );
    1646          54 : }
    1647             : 
    1648             : 
    1649         108 : void SvxIconChoiceCtrl_Impl::PaintItem( const Rectangle& rRect,
    1650             :     IcnViewFieldType eItem, SvxIconChoiceCtrlEntry* pEntry, sal_uInt16 nPaintFlags,
    1651             :     OutputDevice* pOut, const OUString* pStr, ::vcl::ControlLayoutData* _pLayoutData )
    1652             : {
    1653         108 :     if( eItem == IcnViewFieldTypeText )
    1654             :     {
    1655          54 :         OUString aText;
    1656          54 :         if( !pStr )
    1657          54 :             aText = pView->GetEntryText( pEntry, false );
    1658             :         else
    1659           0 :             aText = *pStr;
    1660             : 
    1661          54 :         if ( _pLayoutData )
    1662             :         {
    1663             :             pOut->DrawText( rRect, aText, nCurTextDrawFlags,
    1664           0 :                 &_pLayoutData->m_aUnicodeBoundRects, &_pLayoutData->m_aDisplayText );
    1665             :         }
    1666             :         else
    1667             :         {
    1668          54 :             Color aOldFontColor = pOut->GetTextColor();
    1669          54 :             if ( pView->AutoFontColor() )
    1670             :             {
    1671           0 :                 Color aBkgColor( pOut->GetBackground().GetColor() );
    1672           0 :                 Color aFontColor;
    1673           0 :                 sal_uInt16 nColor = ( aBkgColor.GetRed() + aBkgColor.GetGreen() + aBkgColor.GetBlue() ) / 3;
    1674           0 :                 if ( nColor > 127 )
    1675           0 :                     aFontColor.SetColor ( COL_BLACK );
    1676             :                 else
    1677           0 :                     aFontColor.SetColor( COL_WHITE );
    1678           0 :                 pOut->SetTextColor( aFontColor );
    1679             :             }
    1680             : 
    1681          54 :             pOut->DrawText( rRect, aText, nCurTextDrawFlags );
    1682             : 
    1683          54 :             if ( pView->AutoFontColor() )
    1684           0 :                 pOut->SetTextColor( aOldFontColor );
    1685             : 
    1686          54 :             if( pEntry->IsFocused() )
    1687             :             {
    1688          18 :                 Rectangle aRect ( CalcFocusRect( (SvxIconChoiceCtrlEntry*)pEntry ) );
    1689          18 :                 /*pView->*/ShowFocus( aRect );
    1690          18 :                 DrawFocusRect( pOut );
    1691             :             }
    1692          54 :         }
    1693             :     }
    1694             :     else
    1695             :     {
    1696          54 :         Point aPos( rRect.TopLeft() );
    1697          54 :         if( nPaintFlags & PAINTFLAG_HOR_CENTERED )
    1698          54 :             aPos.X() += (rRect.GetWidth() - aImageSize.Width() ) / 2;
    1699          54 :         if( nPaintFlags & PAINTFLAG_VER_CENTERED )
    1700          54 :             aPos.Y() += (rRect.GetHeight() - aImageSize.Height() ) / 2;
    1701          54 :         pView->DrawEntryImage( pEntry, aPos, *pOut );
    1702             :     }
    1703         108 : }
    1704             : 
    1705           0 : void SvxIconChoiceCtrl_Impl::PaintEntryVirtOutDev( SvxIconChoiceCtrlEntry* pEntry )
    1706             : {
    1707           0 :     if( !pEntryPaintDev )
    1708             :     {
    1709           0 :         pEntryPaintDev = new VirtualDevice( *pView );
    1710           0 :         pEntryPaintDev->SetFont( pView->GetFont() );
    1711           0 :         pEntryPaintDev->SetLineColor();
    1712             :         //pEntryPaintDev->SetBackground( pView->GetBackground() );
    1713             :     }
    1714           0 :     const Rectangle& rRect = GetEntryBoundRect( pEntry );
    1715           0 :     Rectangle aOutRect( GetOutputRect() );
    1716           0 :     if( !rRect.IsOver( aOutRect ) )
    1717           0 :         return;
    1718           0 :     Wallpaper aPaper( pView->GetBackground() );
    1719           0 :     Rectangle aRect( aPaper.GetRect() );
    1720             : 
    1721             :     // move rectangle, so the bounding rectangle of the entry lies in
    1722             :     // VirtOut-Dev at 0,0
    1723           0 :     aRect.Move( -rRect.Left(), -rRect.Top() );
    1724           0 :     aPaper.SetRect( aRect );
    1725           0 :     pEntryPaintDev->SetBackground( aPaper );
    1726           0 :     pEntryPaintDev->SetFont( pView->GetFont() );
    1727             : 
    1728           0 :     Size aSize( rRect.GetSize() );
    1729           0 :     pEntryPaintDev->SetOutputSizePixel( aSize );
    1730             :     pEntryPaintDev->DrawOutDev(
    1731           0 :         Point(), aSize, rRect.TopLeft(), aSize, *pView );
    1732             : 
    1733           0 :     PaintEntry( pEntry, Point(), pEntryPaintDev );
    1734             : 
    1735             :     pView->DrawOutDev(
    1736             :         rRect.TopLeft(),
    1737             :         aSize,
    1738             :         Point(),
    1739             :         aSize,
    1740           0 :         *pEntryPaintDev );
    1741             : }
    1742             : 
    1743             : 
    1744          54 : void SvxIconChoiceCtrl_Impl::PaintEntry( SvxIconChoiceCtrlEntry* pEntry, const Point& rPos,
    1745             :     OutputDevice* pOut, bool bIsBackgroundPainted )
    1746             : {
    1747          54 :     if( !pOut )
    1748           6 :         pOut = pView;
    1749             : 
    1750          54 :     bool bSelected = false;
    1751             : 
    1752          54 :     if( eSelectionMode != NO_SELECTION )
    1753          54 :         bSelected = pEntry->IsSelected();
    1754             : 
    1755          54 :     bool bCursored = pEntry->IsCursored();
    1756          54 :     bool bDropTarget = pEntry->IsDropTarget();
    1757          54 :     bool bNoEmphasis = pEntry->IsBlockingEmphasis();
    1758             : 
    1759          54 :     vcl::Font aTempFont( pOut->GetFont() );
    1760             : 
    1761             :     // AutoFontColor
    1762             :     /*
    1763             :     if ( pView->AutoFontColor() )
    1764             :     {
    1765             :         aTempFont.SetColor ( aFontColor );
    1766             :     }
    1767             :     */
    1768             : 
    1769         108 :     OUString aEntryText( pView->GetEntryText( pEntry, false ) );
    1770          54 :     Rectangle aTextRect( CalcTextRect(pEntry,&rPos,false,&aEntryText));
    1771          54 :     Rectangle aBmpRect( CalcBmpRect(pEntry, &rPos ) );
    1772             : 
    1773             :     bool    bShowSelection =
    1774          12 :         (   (   ( bSelected && !bCursored )
    1775          42 :             ||  bDropTarget
    1776             :             )
    1777          12 :         &&  !bNoEmphasis
    1778          66 :         &&  ( eSelectionMode != NO_SELECTION )
    1779          54 :         );
    1780          54 :     bool bActiveSelection = ( 0 != ( nWinBits & WB_NOHIDESELECTION ) ) || pView->HasFocus();
    1781             : 
    1782          54 :     if ( bShowSelection )
    1783             :     {
    1784          12 :         const StyleSettings& rSettings = pOut->GetSettings().GetStyleSettings();
    1785          12 :         vcl::Font aNewFont( aTempFont );
    1786             : 
    1787             :         // font fill colors that are attributed "hard" need corresponding "hard"
    1788             :         // attributed highlight colors
    1789          12 :         if( pView->HasFontFillColor() )
    1790             :         {
    1791          12 :             if( (nWinBits & WB_NOHIDESELECTION) || pView->HasFocus() )
    1792          12 :                 aNewFont.SetFillColor( rSettings.GetHighlightColor() );
    1793             :             else
    1794           0 :                 aNewFont.SetFillColor( rSettings.GetDeactiveColor() );
    1795             :         }
    1796             : 
    1797          12 :         Color aWinCol = rSettings.GetWindowTextColor();
    1798          12 :         if ( !bActiveSelection && rSettings.GetFaceColor().IsBright() == aWinCol.IsBright() )
    1799           0 :             aNewFont.SetColor( rSettings.GetWindowTextColor() );
    1800             :         else
    1801          12 :             aNewFont.SetColor( rSettings.GetHighlightTextColor() );
    1802             : 
    1803          12 :         pOut->SetFont( aNewFont );
    1804             : 
    1805          12 :         pOut->SetFillColor( pOut->GetBackground().GetColor() );
    1806          12 :         pOut->DrawRect( CalcFocusRect( pEntry ) );
    1807          12 :         pOut->SetFillColor( );
    1808             :     }
    1809             : 
    1810          54 :     bool bResetClipRegion = false;
    1811          54 :     if( !pView->IsClipRegion() && (aVerSBar.IsVisible() || aHorSBar.IsVisible()) )
    1812             :     {
    1813           0 :         Rectangle aOutputArea( GetOutputRect() );
    1814           0 :         if( aOutputArea.IsOver(aTextRect) || aOutputArea.IsOver(aBmpRect) )
    1815             :         {
    1816           0 :             pView->SetClipRegion(vcl::Region(aOutputArea));
    1817           0 :             bResetClipRegion = true;
    1818             :         }
    1819             :     }
    1820             : 
    1821          54 :     bool bLargeIconMode = WB_ICON == ( nWinBits & (VIEWMODE_MASK) );
    1822          54 :     sal_uInt16 nBmpPaintFlags = PAINTFLAG_VER_CENTERED;
    1823          54 :     if ( bLargeIconMode )
    1824          54 :         nBmpPaintFlags |= PAINTFLAG_HOR_CENTERED;
    1825          54 :     sal_uInt16 nTextPaintFlags = bLargeIconMode ? PAINTFLAG_HOR_CENTERED : PAINTFLAG_VER_CENTERED;
    1826             : 
    1827          54 :     if( !bNoEmphasis )
    1828          54 :         PaintEmphasis(aTextRect,aBmpRect,bSelected,bDropTarget,bCursored,pOut,bIsBackgroundPainted);
    1829             : 
    1830          54 :     if ( bShowSelection )
    1831             :         pView->DrawSelectionBackground( CalcFocusRect( pEntry ),
    1832          12 :         bActiveSelection ? 1 : 2 /* highlight */, false /* check */, true /* border */, false /* ext border only */ );
    1833             : 
    1834          54 :     PaintItem( aBmpRect, IcnViewFieldTypeImage, pEntry, nBmpPaintFlags, pOut );
    1835             : 
    1836             :     PaintItem( aTextRect, IcnViewFieldTypeText, pEntry,
    1837          54 :         nTextPaintFlags, pOut );
    1838             : 
    1839             :     // draw highlight frame
    1840          54 :     if( pEntry == pCurHighlightFrame && !bNoEmphasis )
    1841           0 :         DrawHighlightFrame( pOut, CalcFocusRect( pEntry ), false );
    1842             : 
    1843          54 :     pOut->SetFont( aTempFont );
    1844          54 :     if( bResetClipRegion )
    1845          54 :         pView->SetClipRegion();
    1846          54 : }
    1847             : 
    1848           0 : void SvxIconChoiceCtrl_Impl::SetEntryPos( SvxIconChoiceCtrlEntry* pEntry, const Point& rPos,
    1849             :     bool bAdjustAtGrid, bool bCheckScrollBars, bool bKeepGridMap )
    1850             : {
    1851           0 :     ShowCursor( false );
    1852           0 :     Rectangle aBoundRect( GetEntryBoundRect( pEntry ));
    1853           0 :     pView->Invalidate( aBoundRect );
    1854           0 :     ToTop( pEntry );
    1855           0 :     if( !IsAutoArrange() )
    1856             :     {
    1857           0 :         bool bAdjustVirtSize = false;
    1858           0 :         if( rPos != aBoundRect.TopLeft() )
    1859             :         {
    1860             :             Point aGridOffs(
    1861           0 :                 pEntry->aGridRect.TopLeft() - pEntry->aRect.TopLeft() );
    1862           0 :             pImpCursor->Clear();
    1863           0 :             if( !bKeepGridMap )
    1864           0 :                 pGridMap->Clear();
    1865           0 :             aBoundRect.SetPos( rPos );
    1866           0 :             pEntry->aRect = aBoundRect;
    1867           0 :             pEntry->aGridRect.SetPos( rPos + aGridOffs );
    1868           0 :             bAdjustVirtSize = true;
    1869             :         }
    1870           0 :         if( bAdjustAtGrid )
    1871             :         {
    1872           0 :             if( bAdjustVirtSize )
    1873             :             {
    1874             :                 // By aligning the (in some cases newly positioned) entry, it
    1875             :                 // can become completely visible again, so that maybe we don't
    1876             :                 // need a scrollbar after all. To avoid suddenly turning the
    1877             :                 // scrollbar(s) on and then off again, we use the aligned
    1878             :                 // bounding rectangle of the entry to enlarge the virtual
    1879             :                 // output size. The virtual size has to be adapted, because
    1880             :                 // AdjustEntryAtGrid depends on it.
    1881           0 :                 const Rectangle& rBoundRect = GetEntryBoundRect( pEntry );
    1882           0 :                 Rectangle aCenterRect( CalcBmpRect( pEntry, 0 ));
    1883           0 :                 Point aNewPos( AdjustAtGrid( aCenterRect, rBoundRect ) );
    1884           0 :                 Rectangle aNewBoundRect( aNewPos, pEntry->aRect.GetSize());
    1885           0 :                 AdjustVirtSize( aNewBoundRect );
    1886           0 :                 bAdjustVirtSize = false;
    1887             :             }
    1888           0 :             AdjustEntryAtGrid( pEntry );
    1889           0 :             ToTop( pEntry );
    1890             :         }
    1891           0 :         if( bAdjustVirtSize )
    1892           0 :             AdjustVirtSize( pEntry->aRect );
    1893             : 
    1894           0 :         if( bCheckScrollBars && bUpdateMode )
    1895           0 :             CheckScrollBars();
    1896             : 
    1897           0 :         pView->Invalidate( pEntry->aRect );
    1898           0 :         pGridMap->OccupyGrids( pEntry );
    1899             :     }
    1900             :     else
    1901             :     {
    1902           0 :         SvxIconChoiceCtrlEntry* pPrev = FindEntryPredecessor( pEntry, rPos );
    1903           0 :         SetEntryPredecessor( pEntry, pPrev );
    1904           0 :         aAutoArrangeTimer.Start();
    1905             :     }
    1906           0 :     ShowCursor( true );
    1907           0 : }
    1908             : 
    1909           0 : void SvxIconChoiceCtrl_Impl::SetNoSelection()
    1910             : {
    1911             :     // block recursive calls via SelectEntry
    1912           0 :     if( !(nFlags & F_CLEARING_SELECTION ))
    1913             :     {
    1914           0 :         nFlags |= F_CLEARING_SELECTION;
    1915           0 :         DeselectAllBut( 0, true );
    1916           0 :         nFlags &= ~F_CLEARING_SELECTION;
    1917             :     }
    1918           0 : }
    1919             : 
    1920           0 : SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetEntry( const Point& rDocPos, bool bHit )
    1921             : {
    1922           0 :     CheckBoundingRects();
    1923             :     // search through z-order list from the end
    1924           0 :     size_t nCount = pZOrderList->size();
    1925           0 :     while( nCount )
    1926             :     {
    1927           0 :         nCount--;
    1928           0 :         SvxIconChoiceCtrlEntry* pEntry = (*pZOrderList)[ nCount ];
    1929           0 :         if( pEntry->aRect.IsInside( rDocPos ) )
    1930             :         {
    1931           0 :             if( bHit )
    1932             :             {
    1933           0 :                 Rectangle aRect = CalcBmpRect( pEntry );
    1934           0 :                 aRect.Top() -= 3;
    1935           0 :                 aRect.Bottom() += 3;
    1936           0 :                 aRect.Left() -= 3;
    1937           0 :                 aRect.Right() += 3;
    1938           0 :                 if( aRect.IsInside( rDocPos ) )
    1939           0 :                     return pEntry;
    1940           0 :                 aRect = CalcTextRect( pEntry );
    1941           0 :                 if( aRect.IsInside( rDocPos ) )
    1942           0 :                     return pEntry;
    1943             :             }
    1944             :             else
    1945           0 :                 return pEntry;
    1946             :         }
    1947             :     }
    1948           0 :     return 0;
    1949             : }
    1950             : 
    1951           0 : Point SvxIconChoiceCtrl_Impl::GetEntryPos( SvxIconChoiceCtrlEntry* pEntry )
    1952             : {
    1953           0 :     return pEntry->aRect.TopLeft();
    1954             : }
    1955             : 
    1956           0 : void SvxIconChoiceCtrl_Impl::MakeEntryVisible( SvxIconChoiceCtrlEntry* pEntry, bool bBound )
    1957             : {
    1958           0 :     if ( bBound )
    1959             :     {
    1960           0 :         const Rectangle& rRect = GetEntryBoundRect( pEntry );
    1961           0 :         MakeVisible( rRect );
    1962             :     }
    1963             :     else
    1964             :     {
    1965           0 :         Rectangle aRect = CalcBmpRect( pEntry );
    1966           0 :         aRect.Union( CalcTextRect( pEntry ) );
    1967           0 :         aRect.Top() += TBOFFS_BOUND;
    1968           0 :         aRect.Bottom() += TBOFFS_BOUND;
    1969           0 :         aRect.Left() += LROFFS_BOUND;
    1970           0 :         aRect.Right() += LROFFS_BOUND;
    1971           0 :         MakeVisible( aRect );
    1972             :     }
    1973           0 : }
    1974             : 
    1975         848 : const Rectangle& SvxIconChoiceCtrl_Impl::GetEntryBoundRect( SvxIconChoiceCtrlEntry* pEntry )
    1976             : {
    1977         848 :     if( !IsBoundingRectValid( pEntry->aRect ))
    1978           0 :         FindBoundingRect( pEntry );
    1979         848 :     return pEntry->aRect;
    1980             : }
    1981             : 
    1982         192 : Rectangle SvxIconChoiceCtrl_Impl::CalcBmpRect( SvxIconChoiceCtrlEntry* pEntry, const Point* pPos )
    1983             : {
    1984         192 :     Rectangle aBound = GetEntryBoundRect( pEntry );
    1985         192 :     if( pPos )
    1986          54 :         aBound.SetPos( *pPos );
    1987         192 :     Point aPos( aBound.TopLeft() );
    1988             : 
    1989         192 :     switch( nWinBits & (VIEWMODE_MASK) )
    1990             :     {
    1991             :         case WB_ICON:
    1992             :         {
    1993         192 :             aPos.X() += ( aBound.GetWidth() - aImageSize.Width() ) / 2;
    1994         192 :             return Rectangle( aPos, aImageSize );
    1995             :         }
    1996             : 
    1997             :         case WB_SMALLICON:
    1998             :         case WB_DETAILS:
    1999           0 :             aPos.Y() += ( aBound.GetHeight() - aImageSize.Height() ) / 2;
    2000             :             //TODO: determine horizontal distance to bounding rectangle
    2001           0 :             return Rectangle( aPos, aImageSize );
    2002             : 
    2003             :         default:
    2004             :             OSL_FAIL("IconView: Viewmode not set");
    2005           0 :             return aBound;
    2006             :     }
    2007             : }
    2008             : 
    2009         138 : Rectangle SvxIconChoiceCtrl_Impl::CalcTextRect( SvxIconChoiceCtrlEntry* pEntry,
    2010             :     const Point* pEntryPos, bool bEdit, const OUString* pStr )
    2011             : {
    2012         138 :     OUString aEntryText;
    2013         138 :     if( !pStr )
    2014          84 :         aEntryText = pView->GetEntryText( pEntry, bEdit );
    2015             :     else
    2016          54 :         aEntryText = *pStr;
    2017             : 
    2018         138 :     const Rectangle aMaxTextRect( CalcMaxTextRect( pEntry ) );
    2019         138 :     Rectangle aBound( GetEntryBoundRect( pEntry ) );
    2020         138 :     if( pEntryPos )
    2021          54 :         aBound.SetPos( *pEntryPos );
    2022             : 
    2023         138 :     Rectangle aTextRect( aMaxTextRect );
    2024         138 :     if( !bEdit )
    2025         138 :         aTextRect = pView->GetTextRect( aTextRect, aEntryText, nCurTextDrawFlags );
    2026             : 
    2027         138 :     Size aTextSize( aTextRect.GetSize() );
    2028             : 
    2029         138 :     Point aPos( aBound.TopLeft() );
    2030         138 :     long nBoundWidth = aBound.GetWidth();
    2031         138 :     long nBoundHeight = aBound.GetHeight();
    2032             : 
    2033         138 :     switch( nWinBits & (VIEWMODE_MASK) )
    2034             :     {
    2035             :         case WB_ICON:
    2036         138 :             aPos.Y() += aImageSize.Height();
    2037         138 :             aPos.Y() += VER_DIST_BMP_STRING;
    2038             :             // at little more space when editing
    2039         138 :             if( bEdit )
    2040             :             {
    2041             :                 // +20%
    2042           0 :                 long nMinWidth = (( (aImageSize.Width()*10) / 100 ) * 2 ) +
    2043           0 :                                  aImageSize.Width();
    2044           0 :                 if( nMinWidth > nBoundWidth )
    2045           0 :                     nMinWidth = nBoundWidth;
    2046             : 
    2047           0 :                 if( aTextSize.Width() < nMinWidth )
    2048           0 :                     aTextSize.Width() = nMinWidth;
    2049             : 
    2050             :                 // when editing, overlap with the area below is allowed
    2051           0 :                 Size aOptSize = aMaxTextRect.GetSize();
    2052           0 :                 if( aOptSize.Height() > aTextSize.Height() )
    2053           0 :                     aTextSize.Height() = aOptSize.Height();
    2054             :             }
    2055         138 :             aPos.X() += (nBoundWidth - aTextSize.Width()) / 2;
    2056         138 :             break;
    2057             : 
    2058             :         case WB_SMALLICON:
    2059             :         case WB_DETAILS:
    2060           0 :             aPos.X() += aImageSize.Width();
    2061           0 :             aPos.X() += HOR_DIST_BMP_STRING;
    2062           0 :             aPos.Y() += (nBoundHeight - aTextSize.Height()) / 2;
    2063           0 :             break;
    2064             :     }
    2065         138 :     return Rectangle( aPos, aTextSize );
    2066             : }
    2067             : 
    2068             : 
    2069        1184 : long SvxIconChoiceCtrl_Impl::CalcBoundingWidth( SvxIconChoiceCtrlEntry* pEntry ) const
    2070             : {
    2071        1184 :     long nStringWidth = GetItemSize( pEntry, IcnViewFieldTypeText ).Width();
    2072             : //  nStringWidth += 2*LROFFS_TEXT;
    2073        1184 :     long nWidth = 0;
    2074             : 
    2075        1184 :     switch( nWinBits & (VIEWMODE_MASK) )
    2076             :     {
    2077             :         case WB_ICON:
    2078        1184 :             nWidth = std::max( nStringWidth, aImageSize.Width() );
    2079        1184 :             break;
    2080             : 
    2081             :         case WB_SMALLICON:
    2082             :         case WB_DETAILS:
    2083           0 :             nWidth = aImageSize.Width();
    2084           0 :             nWidth += HOR_DIST_BMP_STRING;
    2085           0 :             nWidth += nStringWidth;
    2086           0 :             break;
    2087             :     }
    2088        1184 :     return nWidth;
    2089             : }
    2090             : 
    2091        1184 : long SvxIconChoiceCtrl_Impl::CalcBoundingHeight( SvxIconChoiceCtrlEntry* pEntry ) const
    2092             : {
    2093        1184 :     long nStringHeight = GetItemSize( pEntry, IcnViewFieldTypeText).Height();
    2094        1184 :     long nHeight = 0;
    2095             : 
    2096        1184 :     switch( nWinBits & (VIEWMODE_MASK) )
    2097             :     {
    2098             :         case WB_ICON:
    2099        1184 :             nHeight = aImageSize.Height();
    2100        1184 :             nHeight += VER_DIST_BMP_STRING;
    2101        1184 :             nHeight += nStringHeight;
    2102        1184 :             break;
    2103             : 
    2104             :         case WB_SMALLICON:
    2105             :         case WB_DETAILS:
    2106           0 :             nHeight = std::max( aImageSize.Height(), nStringHeight );
    2107           0 :             break;
    2108             :     }
    2109        1184 :     if( nHeight > nMaxBoundHeight )
    2110             :     {
    2111         148 :         ((SvxIconChoiceCtrl_Impl*)this)->nMaxBoundHeight = nHeight;
    2112         148 :         ((SvxIconChoiceCtrl_Impl*)this)->aHorSBar.SetLineSize( GetScrollBarLineSize() );
    2113         148 :         ((SvxIconChoiceCtrl_Impl*)this)->aVerSBar.SetLineSize( GetScrollBarLineSize() );
    2114             :     }
    2115        1184 :     return nHeight;
    2116             : }
    2117             : 
    2118        1184 : Size SvxIconChoiceCtrl_Impl::CalcBoundingSize( SvxIconChoiceCtrlEntry* pEntry ) const
    2119             : {
    2120             :     return Size( CalcBoundingWidth( pEntry ),
    2121        1184 :                  CalcBoundingHeight( pEntry ) );
    2122             : }
    2123             : 
    2124         132 : void SvxIconChoiceCtrl_Impl::RecalcAllBoundingRectsSmart()
    2125             : {
    2126         132 :     nMaxBoundHeight = 0;
    2127         132 :     pZOrderList->clear();
    2128             :     size_t nCur;
    2129             :     SvxIconChoiceCtrlEntry* pEntry;
    2130         132 :     const size_t nCount = aEntries.size();
    2131             : 
    2132         132 :     if( !IsAutoArrange() || !pHead )
    2133             :     {
    2134         660 :         for( nCur = 0; nCur < nCount; nCur++ )
    2135             :         {
    2136         528 :             pEntry = aEntries[ nCur ];
    2137         528 :             if( IsBoundingRectValid( pEntry->aRect ))
    2138             :             {
    2139           0 :                 Size aBoundSize( pEntry->aRect.GetSize() );
    2140           0 :                 if( aBoundSize.Height() > nMaxBoundHeight )
    2141           0 :                     nMaxBoundHeight = aBoundSize.Height();
    2142             :             }
    2143             :             else
    2144         528 :                 FindBoundingRect( pEntry );
    2145         528 :             pZOrderList->push_back( pEntry );
    2146             :         }
    2147             :     }
    2148             :     else
    2149             :     {
    2150           0 :         nCur = 0;
    2151           0 :         pEntry = pHead;
    2152           0 :         while( nCur != nCount )
    2153             :         {
    2154             :             DBG_ASSERT(pEntry->pflink&&pEntry->pblink,"SvxIconChoiceCtrl_Impl::RecalcAllBoundingRect > Bad link(s)");
    2155           0 :             if( IsBoundingRectValid( pEntry->aRect ))
    2156             :             {
    2157           0 :                 Size aBoundSize( pEntry->aRect.GetSize() );
    2158           0 :                 if( aBoundSize.Height() > nMaxBoundHeight )
    2159           0 :                     nMaxBoundHeight = aBoundSize.Height();
    2160             :             }
    2161             :             else
    2162           0 :                 FindBoundingRect( pEntry );
    2163           0 :             pZOrderList->push_back( pEntry );
    2164           0 :             pEntry = pEntry->pflink;
    2165           0 :             nCur++;
    2166             :         }
    2167             :     }
    2168         132 :     AdjustScrollBars();
    2169         132 : }
    2170             : 
    2171         592 : void SvxIconChoiceCtrl_Impl::FindBoundingRect( SvxIconChoiceCtrlEntry* pEntry )
    2172             : {
    2173             :     DBG_ASSERT(!pEntry->IsPosLocked(),"Locked entry pos in FindBoundingRect");
    2174         592 :     if( pEntry->IsPosLocked() && IsBoundingRectValid( pEntry->aRect) )
    2175             :     {
    2176           0 :         AdjustVirtSize( pEntry->aRect );
    2177         592 :         return;
    2178             :     }
    2179         592 :     Size aSize( CalcBoundingSize( pEntry ) );
    2180         592 :     Point aPos(pGridMap->GetGridRect(pGridMap->GetUnoccupiedGrid(true)).TopLeft());
    2181         592 :     SetBoundingRect_Impl( pEntry, aPos, aSize );
    2182             : }
    2183             : 
    2184         592 : void SvxIconChoiceCtrl_Impl::SetBoundingRect_Impl( SvxIconChoiceCtrlEntry* pEntry, const Point& rPos,
    2185             :     const Size& /*rBoundingSize*/ )
    2186             : {
    2187         592 :     Rectangle aGridRect( rPos, Size(nGridDX, nGridDY) );
    2188         592 :     pEntry->aGridRect = aGridRect;
    2189         592 :     Center( pEntry );
    2190         592 :     AdjustVirtSize( pEntry->aRect );
    2191         592 :     pGridMap->OccupyGrids( pEntry );
    2192         592 : }
    2193             : 
    2194             : 
    2195           6 : void SvxIconChoiceCtrl_Impl::SetCursor( SvxIconChoiceCtrlEntry* pEntry, bool bSyncSingleSelection,
    2196             :     bool bShowFocusAsync )
    2197             : {
    2198           6 :     if( pEntry == pCursor )
    2199             :     {
    2200           0 :         if( pCursor && eSelectionMode == SINGLE_SELECTION && bSyncSingleSelection &&
    2201           0 :                 !pCursor->IsSelected() )
    2202           0 :             SelectEntry( pCursor, true, true );
    2203           6 :         return;
    2204             :     }
    2205           6 :     ShowCursor( false );
    2206           6 :     SvxIconChoiceCtrlEntry* pOldCursor = pCursor;
    2207           6 :     pCursor = pEntry;
    2208           6 :     if( pOldCursor )
    2209             :     {
    2210           6 :         pOldCursor->ClearFlags( ICNVIEW_FLAG_FOCUSED );
    2211           6 :         if( eSelectionMode == SINGLE_SELECTION && bSyncSingleSelection )
    2212           6 :             SelectEntry( pOldCursor, false, true ); // deselect old cursor
    2213             :     }
    2214           6 :     if( pCursor )
    2215             :     {
    2216           6 :         ToTop( pCursor );
    2217           6 :         pCursor->SetFlags( ICNVIEW_FLAG_FOCUSED );
    2218           6 :         if( eSelectionMode == SINGLE_SELECTION && bSyncSingleSelection )
    2219           6 :             SelectEntry( pCursor, true, true );
    2220           6 :         if( !bShowFocusAsync )
    2221           6 :             ShowCursor( true );
    2222             :         else
    2223             :         {
    2224           0 :             if( !nUserEventShowCursor )
    2225             :                 nUserEventShowCursor =
    2226             :                     Application::PostUserEvent( LINK( this, SvxIconChoiceCtrl_Impl, UserEventHdl),
    2227           0 :                         EVENTID_SHOW_CURSOR );
    2228             :         }
    2229             :     }
    2230             : }
    2231             : 
    2232             : 
    2233         374 : void SvxIconChoiceCtrl_Impl::ShowCursor( bool bShow )
    2234             : {
    2235         374 :     if( !pCursor || !bShow || !pView->HasFocus() )
    2236             :     {
    2237         338 :         pView->HideFocus();
    2238         712 :         return;
    2239             :     }
    2240          36 :     Rectangle aRect ( CalcFocusRect( pCursor ) );
    2241          36 :     /*pView->*/ShowFocus( aRect );
    2242             : }
    2243             : 
    2244             : 
    2245           0 : void SvxIconChoiceCtrl_Impl::HideDDIcon()
    2246             : {
    2247           0 :     pView->Update();
    2248           0 :     ImpHideDDIcon();
    2249           0 :     pDDBufDev = pDDDev;
    2250           0 :     pDDDev = 0;
    2251           0 : }
    2252             : 
    2253           0 : void SvxIconChoiceCtrl_Impl::ImpHideDDIcon()
    2254             : {
    2255           0 :     if( pDDDev )
    2256             :     {
    2257           0 :         Size aSize( pDDDev->GetOutputSizePixel() );
    2258             :         // restore pView
    2259           0 :         pView->DrawOutDev( aDDLastRectPos, aSize, Point(), aSize, *pDDDev );
    2260             :     }
    2261           0 : }
    2262             : 
    2263           0 : bool SvxIconChoiceCtrl_Impl::HandleScrollCommand( const CommandEvent& rCmd )
    2264             : {
    2265           0 :     Rectangle aDocRect( GetDocumentRect() );
    2266           0 :     Rectangle aVisRect( GetVisibleRect() );
    2267           0 :     if( aVisRect.IsInside( aDocRect ))
    2268           0 :         return false;
    2269           0 :     Size aDocSize( aDocRect.GetSize() );
    2270           0 :     Size aVisSize( aVisRect.GetSize() );
    2271           0 :     bool bHor = aDocSize.Width() > aVisSize.Width();
    2272           0 :     bool bVer = aDocSize.Height() > aVisSize.Height();
    2273             : 
    2274           0 :     long nScrollDX = 0, nScrollDY = 0;
    2275             : 
    2276           0 :     switch( rCmd.GetCommand() )
    2277             :     {
    2278             :         case COMMAND_STARTAUTOSCROLL:
    2279             :         {
    2280           0 :             pView->EndTracking();
    2281           0 :             sal_uInt16 nScrollFlags = 0;
    2282           0 :             if( bHor )
    2283           0 :                 nScrollFlags |= AUTOSCROLL_HORZ;
    2284           0 :             if( bVer )
    2285           0 :                 nScrollFlags |= AUTOSCROLL_VERT;
    2286           0 :             if( nScrollFlags )
    2287             :             {
    2288           0 :                 pView->StartAutoScroll( nScrollFlags );
    2289           0 :                 return true;
    2290             :             }
    2291             :         }
    2292           0 :         break;
    2293             : 
    2294             :         case COMMAND_WHEEL:
    2295             :         {
    2296           0 :             const CommandWheelData* pData = rCmd.GetWheelData();
    2297           0 :             if( pData && (CommandWheelMode::SCROLL == pData->GetMode()) && !pData->IsHorz() )
    2298             :             {
    2299           0 :                 sal_uLong nScrollLines = pData->GetScrollLines();
    2300           0 :                 if( nScrollLines == COMMAND_WHEEL_PAGESCROLL )
    2301             :                 {
    2302           0 :                     nScrollDY = GetScrollBarPageSize( aVisSize.Width() );
    2303           0 :                     if( pData->GetDelta() < 0 )
    2304           0 :                         nScrollDY *= -1;
    2305             :                 }
    2306             :                 else
    2307             :                 {
    2308           0 :                     nScrollDY = pData->GetNotchDelta() * (long)nScrollLines;
    2309           0 :                     nScrollDY *= GetScrollBarLineSize();
    2310             :                 }
    2311             :             }
    2312             :         }
    2313           0 :         break;
    2314             : 
    2315             :         case COMMAND_AUTOSCROLL:
    2316             :         {
    2317           0 :             const CommandScrollData* pData = rCmd.GetAutoScrollData();
    2318           0 :             if( pData )
    2319             :             {
    2320           0 :                 nScrollDX = pData->GetDeltaX() * GetScrollBarLineSize();
    2321           0 :                 nScrollDY = pData->GetDeltaY() * GetScrollBarLineSize();
    2322             :             }
    2323             :         }
    2324           0 :         break;
    2325             :     }
    2326             : 
    2327           0 :     if( nScrollDX || nScrollDY )
    2328             :     {
    2329           0 :         aVisRect.Top() -= nScrollDY;
    2330           0 :         aVisRect.Bottom() -= nScrollDY;
    2331           0 :         aVisRect.Left() -= nScrollDX;
    2332           0 :         aVisRect.Right() -= nScrollDX;
    2333           0 :         MakeVisible( aVisRect );
    2334           0 :         return true;
    2335             :     }
    2336           0 :     return false;
    2337             : }
    2338             : 
    2339             : 
    2340           0 : void SvxIconChoiceCtrl_Impl::Command( const CommandEvent& rCEvt )
    2341             : {
    2342             :     // scroll mouse event?
    2343           0 :     if( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
    2344           0 :         (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
    2345           0 :         (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
    2346             :     {
    2347           0 :         if( HandleScrollCommand( rCEvt ) )
    2348           0 :             return;
    2349             :     }
    2350             : }
    2351             : 
    2352          12 : void SvxIconChoiceCtrl_Impl::ToTop( SvxIconChoiceCtrlEntry* pEntry )
    2353             : {
    2354          24 :     if( !pZOrderList->empty()
    2355          12 :     &&  pEntry != pZOrderList->back()
    2356             :     ) {
    2357         108 :         for(
    2358          12 :             SvxIconChoiceCtrlEntryList_impl::iterator it = pZOrderList->begin();
    2359          72 :             it != pZOrderList->end();
    2360             :             ++it
    2361             :         ) {
    2362          36 :             if ( *it == pEntry )
    2363             :             {
    2364          12 :                 pZOrderList->erase( it );
    2365          12 :                 pZOrderList->push_back( pEntry );
    2366          12 :                 break;
    2367             :             }
    2368             :         }
    2369             :     }
    2370          12 : }
    2371             : 
    2372           0 : void SvxIconChoiceCtrl_Impl::ClipAtVirtOutRect( Rectangle& rRect ) const
    2373             : {
    2374           0 :     if( rRect.Bottom() >= aVirtOutputSize.Height() )
    2375           0 :         rRect.Bottom() = aVirtOutputSize.Height() - 1;
    2376           0 :     if( rRect.Right() >= aVirtOutputSize.Width() )
    2377           0 :         rRect.Right() = aVirtOutputSize.Width() - 1;
    2378           0 :     if( rRect.Top() < 0 )
    2379           0 :         rRect.Top() = 0;
    2380           0 :     if( rRect.Left() < 0 )
    2381           0 :         rRect.Left() = 0;
    2382           0 : }
    2383             : 
    2384             : // rRect: area of the document (in document coordinates) that we want to make
    2385             : // visible
    2386             : // bScrBar == true: rectangle was calculated because of a scrollbar event
    2387             : 
    2388           0 : void SvxIconChoiceCtrl_Impl::MakeVisible( const Rectangle& rRect, bool bScrBar,
    2389             :     bool bCallRectChangedHdl )
    2390             : {
    2391           0 :     Rectangle aVirtRect( rRect );
    2392           0 :     ClipAtVirtOutRect( aVirtRect );
    2393           0 :     Point aOrigin( pView->GetMapMode().GetOrigin() );
    2394             :     // convert to document coordinate
    2395           0 :     aOrigin *= -1;
    2396           0 :     Rectangle aOutputArea( GetOutputRect() );
    2397           0 :     if( aOutputArea.IsInside( aVirtRect ) )
    2398           0 :         return; // is already visible
    2399             : 
    2400             :     long nDy;
    2401           0 :     if( aVirtRect.Top() < aOutputArea.Top() )
    2402             :     {
    2403             :         // scroll up (nDy < 0)
    2404           0 :         nDy = aVirtRect.Top() - aOutputArea.Top();
    2405             :     }
    2406           0 :     else if( aVirtRect.Bottom() > aOutputArea.Bottom() )
    2407             :     {
    2408             :         // scroll down (nDy > 0)
    2409           0 :         nDy = aVirtRect.Bottom() - aOutputArea.Bottom();
    2410             :     }
    2411             :     else
    2412           0 :         nDy = 0;
    2413             : 
    2414             :     long nDx;
    2415           0 :     if( aVirtRect.Left() < aOutputArea.Left() )
    2416             :     {
    2417             :         // scroll to the left (nDx < 0)
    2418           0 :         nDx = aVirtRect.Left() - aOutputArea.Left();
    2419             :     }
    2420           0 :     else if( aVirtRect.Right() > aOutputArea.Right() )
    2421             :     {
    2422             :         // scroll to the right (nDx > 0)
    2423           0 :         nDx = aVirtRect.Right() - aOutputArea.Right();
    2424             :     }
    2425             :     else
    2426           0 :         nDx = 0;
    2427             : 
    2428           0 :     aOrigin.X() += nDx;
    2429           0 :     aOrigin.Y() += nDy;
    2430           0 :     aOutputArea.SetPos( aOrigin );
    2431           0 :     if( GetUpdateMode() )
    2432             :     {
    2433           0 :         HideDDIcon();
    2434           0 :         pView->Update();
    2435           0 :         ShowCursor( false );
    2436             :     }
    2437             : 
    2438             :     // invert origin for SV (so we can scroll/paint using document coordinates)
    2439           0 :     aOrigin *= -1;
    2440           0 :     SetOrigin( aOrigin );
    2441             : 
    2442           0 :     bool bScrollable = pView->GetBackground().IsScrollable();
    2443           0 :     if( pView->HasBackground() && !bScrollable )
    2444             :     {
    2445           0 :         Rectangle aRect( GetOutputRect());
    2446           0 :         Wallpaper aPaper( pView->GetBackground() );
    2447           0 :         aPaper.SetRect( aRect );
    2448           0 :         pView->SetBackground( aPaper );
    2449             :     }
    2450             : 
    2451           0 :     if( bScrollable && GetUpdateMode() )
    2452             :     {
    2453             :         // scroll in reverse direction!
    2454             :         pView->Control::Scroll( -nDx, -nDy, aOutputArea,
    2455           0 :             SCROLL_NOCHILDREN | SCROLL_USECLIPREGION | SCROLL_CLIP );
    2456             :     }
    2457             :     else
    2458           0 :         pView->Invalidate(INVALIDATE_NOCHILDREN);
    2459             : 
    2460           0 :     if( aHorSBar.IsVisible() || aVerSBar.IsVisible() )
    2461             :     {
    2462           0 :         if( !bScrBar )
    2463             :         {
    2464           0 :             aOrigin *= -1;
    2465             :             // correct thumbs
    2466           0 :             if(aHorSBar.IsVisible() && aHorSBar.GetThumbPos() != aOrigin.X())
    2467           0 :                 aHorSBar.SetThumbPos( aOrigin.X() );
    2468           0 :             if(aVerSBar.IsVisible() && aVerSBar.GetThumbPos() != aOrigin.Y())
    2469           0 :                 aVerSBar.SetThumbPos( aOrigin.Y() );
    2470             :         }
    2471             :     }
    2472             : 
    2473           0 :     if( GetUpdateMode() )
    2474           0 :         ShowCursor( true );
    2475             : 
    2476             :     // check if we still need scrollbars
    2477           0 :     CheckScrollBars();
    2478           0 :     if( bScrollable && GetUpdateMode() )
    2479           0 :         pView->Update();
    2480             : 
    2481             :     // If the requested area can not be made completely visible, the
    2482             :     // Vis-Rect-Changed handler is called in any case. This case may occur e.g.
    2483             :     // if only few pixels of the lower border are invisible, but a scrollbar has
    2484             :     // a larger line size.
    2485           0 :     if( bCallRectChangedHdl || GetOutputRect() != rRect )
    2486           0 :         VisRectChanged();
    2487             : }
    2488             : 
    2489         376 : sal_uLong SvxIconChoiceCtrl_Impl::GetSelectionCount() const
    2490             : {
    2491         376 :     if( (nWinBits & WB_HIGHLIGHTFRAME) && pCurHighlightFrame )
    2492           0 :         return 1;
    2493         376 :     return nSelectionCount;
    2494             : }
    2495             : 
    2496           0 : void SvxIconChoiceCtrl_Impl::ToggleSelection( SvxIconChoiceCtrlEntry* pEntry )
    2497             : {
    2498             :     bool bSel;
    2499           0 :     if( pEntry->IsSelected() )
    2500           0 :         bSel = false;
    2501             :     else
    2502           0 :         bSel = true;
    2503           0 :     SelectEntry( pEntry, bSel, true, true );
    2504           0 : }
    2505             : 
    2506          12 : void SvxIconChoiceCtrl_Impl::DeselectAllBut( SvxIconChoiceCtrlEntry* pThisEntryNot,
    2507             :     bool bPaintSync )
    2508             : {
    2509          12 :     ClearSelectedRectList();
    2510             : 
    2511             :     // TODO: work through z-order list, if necessary!
    2512             : 
    2513          12 :     size_t nCount = aEntries.size();
    2514          60 :     for( size_t nCur = 0; nCur < nCount; nCur++ )
    2515             :     {
    2516          48 :         SvxIconChoiceCtrlEntry* pEntry = aEntries[ nCur ];
    2517          48 :         if( pEntry != pThisEntryNot && pEntry->IsSelected() )
    2518           0 :             SelectEntry( pEntry, false, true, true, bPaintSync );
    2519             :     }
    2520          12 :     pAnchor = 0;
    2521          12 :     nFlags &= (~F_ADD_MODE);
    2522          12 : }
    2523             : 
    2524          32 : Size SvxIconChoiceCtrl_Impl::GetMinGrid() const
    2525             : {
    2526          32 :     Size aMinSize( aImageSize );
    2527          32 :     aMinSize.Width() += 2 * LROFFS_BOUND;
    2528          32 :     aMinSize.Height() += TBOFFS_BOUND;  // single offset is enough (FileDlg)
    2529          32 :     OUString aStrDummy( "XXX" );
    2530          32 :     Size aTextSize( pView->GetTextWidth( aStrDummy ), pView->GetTextHeight() );
    2531          32 :     if( nWinBits & WB_ICON )
    2532             :     {
    2533          32 :         aMinSize.Height() += VER_DIST_BMP_STRING;
    2534          32 :         aMinSize.Height() += aTextSize.Height();
    2535             :     }
    2536             :     else
    2537             :     {
    2538           0 :         aMinSize.Width() += HOR_DIST_BMP_STRING;
    2539           0 :         aMinSize.Width() += aTextSize.Width();
    2540             :     }
    2541          32 :     return aMinSize;
    2542             : }
    2543             : 
    2544          32 : void SvxIconChoiceCtrl_Impl::SetGrid( const Size& rSize )
    2545             : {
    2546          32 :     Size aSize( rSize );
    2547          32 :     Size aMinSize( GetMinGrid() );
    2548          32 :     if( aSize.Width() < aMinSize.Width() )
    2549           0 :         aSize.Width() = aMinSize.Width();
    2550          32 :     if( aSize.Height() < aMinSize.Height() )
    2551           0 :         aSize.Height() = aMinSize.Height();
    2552             : 
    2553          32 :     nGridDX = aSize.Width();
    2554             :     // HACK: Detail mode is not yet fully implemented, this workaround makes it
    2555             :     // fly with a single column
    2556          32 :     if( nWinBits & WB_DETAILS )
    2557             :     {
    2558           0 :         const SvxIconChoiceCtrlColumnInfo* pCol = GetColumn( 0 );
    2559           0 :         if( pCol )
    2560           0 :             ((SvxIconChoiceCtrlColumnInfo*)pCol)->SetWidth( nGridDX );
    2561             :     }
    2562          32 :     nGridDY = aSize.Height();
    2563          32 :     SetDefaultTextSize();
    2564          32 : }
    2565             : 
    2566             : // Calculates the maximum size that the text rectangle may use within its
    2567             : // bounding rectangle. In WB_ICON mode with IcnShowTextFull, Bottom is set to
    2568             : // LONG_MAX.
    2569             : 
    2570         138 : Rectangle SvxIconChoiceCtrl_Impl::CalcMaxTextRect( const SvxIconChoiceCtrlEntry* pEntry ) const
    2571             : {
    2572         138 :     Rectangle aBoundRect;
    2573             :     // avoid infinite recursion: don't calculate the bounding rectangle here
    2574         138 :     if( IsBoundingRectValid( pEntry->aRect ) )
    2575         138 :         aBoundRect = pEntry->aRect;
    2576             :     else
    2577           0 :         aBoundRect = pEntry->aGridRect;
    2578             : 
    2579             :     Rectangle aBmpRect( ((SvxIconChoiceCtrl_Impl*)this)->CalcBmpRect(
    2580         138 :         (SvxIconChoiceCtrlEntry*)pEntry ) );
    2581         138 :     if( nWinBits & WB_ICON )
    2582             :     {
    2583         138 :         aBoundRect.Top() = aBmpRect.Bottom();
    2584         138 :         aBoundRect.Top() += VER_DIST_BMP_STRING;
    2585         138 :         if( aBoundRect.Top() > aBoundRect.Bottom())
    2586           0 :             aBoundRect.Top() = aBoundRect.Bottom();
    2587         138 :         aBoundRect.Left() += LROFFS_BOUND;
    2588         138 :         aBoundRect.Left()++;
    2589         138 :         aBoundRect.Right() -= LROFFS_BOUND;
    2590         138 :         aBoundRect.Right()--;
    2591         138 :         if( aBoundRect.Left() > aBoundRect.Right())
    2592           0 :             aBoundRect.Left() = aBoundRect.Right();
    2593         138 :         if( GetEntryTextModeSmart( pEntry ) == IcnShowTextFull )
    2594           0 :             aBoundRect.Bottom() = LONG_MAX;
    2595             :     }
    2596             :     else
    2597             :     {
    2598           0 :         aBoundRect.Left() = aBmpRect.Right();
    2599           0 :         aBoundRect.Left() += HOR_DIST_BMP_STRING;
    2600           0 :         aBoundRect.Right() -= LROFFS_BOUND;
    2601           0 :         if( aBoundRect.Left() > aBoundRect.Right() )
    2602           0 :             aBoundRect.Left() = aBoundRect.Right();
    2603           0 :         long nHeight = aBoundRect.GetSize().Height();
    2604           0 :         nHeight = nHeight - aDefaultTextSize.Height();
    2605           0 :         nHeight /= 2;
    2606           0 :         aBoundRect.Top() += nHeight;
    2607           0 :         aBoundRect.Bottom() -= nHeight;
    2608             :     }
    2609         138 :     return aBoundRect;
    2610             : }
    2611             : 
    2612          64 : void SvxIconChoiceCtrl_Impl::SetDefaultTextSize()
    2613             : {
    2614          64 :     long nDY = nGridDY;
    2615          64 :     nDY -= aImageSize.Height();
    2616          64 :     nDY -= VER_DIST_BMP_STRING;
    2617          64 :     nDY -= 2*TBOFFS_BOUND;
    2618          64 :     if( nDY <= 0 )
    2619           0 :         nDY = 2;
    2620             : 
    2621          64 :     long nDX = nGridDX;
    2622          64 :     nDX -= 2*LROFFS_BOUND;
    2623          64 :     nDX -= 2;
    2624          64 :     if( nDX <= 0 )
    2625           0 :         nDX = 2;
    2626             : 
    2627          64 :     long nHeight = pView->GetTextHeight();
    2628          64 :     if( nDY < nHeight )
    2629           0 :         nDY = nHeight;
    2630          64 :     aDefaultTextSize = Size( nDX, nDY );
    2631          64 : }
    2632             : 
    2633             : 
    2634         592 : void SvxIconChoiceCtrl_Impl::Center( SvxIconChoiceCtrlEntry* pEntry ) const
    2635             : {
    2636         592 :     pEntry->aRect = pEntry->aGridRect;
    2637         592 :     Size aSize( CalcBoundingSize( pEntry ) );
    2638         592 :     if( nWinBits & WB_ICON )
    2639             :     {
    2640             :         // center horizontally
    2641         592 :         long nBorder = pEntry->aGridRect.GetWidth() - aSize.Width();
    2642         592 :         pEntry->aRect.Left() += nBorder / 2;
    2643         592 :         pEntry->aRect.Right() -= nBorder / 2;
    2644             :     }
    2645             :     // center vertically
    2646         592 :     pEntry->aRect.Bottom() = pEntry->aRect.Top() + aSize.Height();
    2647         592 : }
    2648             : 
    2649             : 
    2650             : // The deltas are the offsets by which the view is moved on the document.
    2651             : // left, up: offsets < 0
    2652             : // right, down: offsets > 0
    2653           0 : void SvxIconChoiceCtrl_Impl::Scroll( long nDeltaX, long nDeltaY, bool bScrollBar )
    2654             : {
    2655           0 :     const MapMode& rMapMode = pView->GetMapMode();
    2656           0 :     Point aOrigin( rMapMode.GetOrigin() );
    2657             :     // convert to document coordinate
    2658           0 :     aOrigin *= -1;
    2659           0 :     aOrigin.Y() += nDeltaY;
    2660           0 :     aOrigin.X() += nDeltaX;
    2661           0 :     Rectangle aRect( aOrigin, aOutputSize );
    2662           0 :     MakeVisible( aRect, bScrollBar );
    2663           0 : }
    2664             : 
    2665             : 
    2666        2368 : const Size& SvxIconChoiceCtrl_Impl::GetItemSize( SvxIconChoiceCtrlEntry*,
    2667             :     IcnViewFieldType eItem ) const
    2668             : {
    2669        2368 :     if( eItem == IcnViewFieldTypeText )
    2670        2368 :         return aDefaultTextSize;
    2671           0 :     return aImageSize;
    2672             : }
    2673             : 
    2674          84 : Rectangle SvxIconChoiceCtrl_Impl::CalcFocusRect( SvxIconChoiceCtrlEntry* pEntry )
    2675             : {
    2676          84 :     Rectangle aTextRect( CalcTextRect( pEntry ) );
    2677          84 :     Rectangle aBoundRect( GetEntryBoundRect( pEntry ) );
    2678             :     return Rectangle(
    2679         252 :         aBoundRect.Left(), aBoundRect.Top() - 1, aBoundRect.Right() - 1,
    2680         336 :         aTextRect.Bottom() + 1);
    2681             : }
    2682             : 
    2683             : // the hot spot is the inner 50% of the rectangle
    2684           0 : static Rectangle GetHotSpot( const Rectangle& rRect )
    2685             : {
    2686           0 :     Rectangle aResult( rRect );
    2687           0 :     aResult.Justify();
    2688           0 :     Size aSize( rRect.GetSize() );
    2689           0 :     long nDelta = aSize.Width() / 4;
    2690           0 :     aResult.Left() += nDelta;
    2691           0 :     aResult.Right() -= nDelta;
    2692           0 :     nDelta = aSize.Height() / 4;
    2693           0 :     aResult.Top() += nDelta;
    2694           0 :     aResult.Bottom() -= nDelta;
    2695           0 :     return aResult;
    2696             : }
    2697             : 
    2698           0 : void SvxIconChoiceCtrl_Impl::SelectRect( SvxIconChoiceCtrlEntry* pEntry1, SvxIconChoiceCtrlEntry* pEntry2,
    2699             :     bool bAdd, std::vector<Rectangle*>* pOtherRects )
    2700             : {
    2701             :     DBG_ASSERT(pEntry1 && pEntry2,"SelectEntry: Invalid Entry-Ptr");
    2702           0 :     Rectangle aRect( GetEntryBoundRect( pEntry1 ) );
    2703           0 :     aRect.Union( GetEntryBoundRect( pEntry2 ) );
    2704           0 :     SelectRect( aRect, bAdd, pOtherRects );
    2705           0 : }
    2706             : 
    2707           0 : void SvxIconChoiceCtrl_Impl::SelectRect( const Rectangle& rRect, bool bAdd,
    2708             :     std::vector<Rectangle*>* pOtherRects )
    2709             : {
    2710           0 :     aCurSelectionRect = rRect;
    2711           0 :     if( !pZOrderList || !pZOrderList->size() )
    2712           0 :         return;
    2713             : 
    2714             :     // set flag, so ToTop won't be called in Select
    2715           0 :     bool bAlreadySelectingRect = nFlags & F_SELECTING_RECT ? true : false;
    2716           0 :     nFlags |= F_SELECTING_RECT;
    2717             : 
    2718           0 :     CheckBoundingRects();
    2719           0 :     pView->Update();
    2720           0 :     const size_t nCount = pZOrderList->size();
    2721             : 
    2722           0 :     Rectangle aRect( rRect );
    2723           0 :     aRect.Justify();
    2724           0 :     bool bCalcOverlap = (bAdd && pOtherRects && !pOtherRects->empty());
    2725             : 
    2726           0 :     bool bResetClipRegion = false;
    2727           0 :     if( !pView->IsClipRegion() )
    2728             :     {
    2729           0 :         bResetClipRegion = true;
    2730           0 :         pView->SetClipRegion(vcl::Region(GetOutputRect()));
    2731             :     }
    2732             : 
    2733           0 :     for( size_t nPos = 0; nPos < nCount; nPos++ )
    2734             :     {
    2735           0 :         SvxIconChoiceCtrlEntry* pEntry = (*pZOrderList)[ nPos ];
    2736             : 
    2737           0 :         if( !IsBoundingRectValid( pEntry->aRect ))
    2738           0 :             FindBoundingRect( pEntry );
    2739           0 :         Rectangle aBoundRect( GetHotSpot( pEntry->aRect ) );
    2740           0 :         bool bSelected = pEntry->IsSelected();
    2741             : 
    2742             :         bool bOverlaps;
    2743           0 :         if( bCalcOverlap )
    2744           0 :             bOverlaps = IsOver( pOtherRects, aBoundRect );
    2745             :         else
    2746           0 :             bOverlaps = false;
    2747           0 :         bool bOver = aRect.IsOver( aBoundRect );
    2748             : 
    2749           0 :         if( bOver && !bOverlaps )
    2750             :         {
    2751             :             // is inside the new selection rectangle and outside of any old one
    2752             :             // => select
    2753           0 :             if( !bSelected )
    2754           0 :                 SelectEntry( pEntry, true, true, true );
    2755             :         }
    2756           0 :         else if( !bAdd )
    2757             :         {
    2758             :             // is outside of the selection rectangle
    2759             :             // => deselect
    2760           0 :             if( bSelected )
    2761           0 :                 SelectEntry( pEntry, false, true, true );
    2762             :         }
    2763           0 :         else if( bAdd && bOverlaps )
    2764             :         {
    2765             :             // The entry is inside an old (=>span multiple rectangles with Ctrl)
    2766             :             // selection rectangle.
    2767             : 
    2768             :             // There is still a bug here! The selection status of an entry in a
    2769             :             // previous rectangle has to be restored, if it was touched by the
    2770             :             // current selection rectangle but is not inside it any more.
    2771             :             // For simplicity's sake, let's assume that all entries in the old
    2772             :             // rectangles were correctly selected. It is wrong to just deselect
    2773             :             // the intersection.
    2774             :             // Possible solution: remember a snapshot of the selection before
    2775             :             // spanning the rectangle.
    2776           0 :             if( aBoundRect.IsOver( rRect))
    2777             :             {
    2778             :                 // deselect intersection between old rectangles and current rectangle
    2779           0 :                 if( bSelected )
    2780           0 :                     SelectEntry( pEntry, false, true, true );
    2781             :             }
    2782             :             else
    2783             :             {
    2784             :                 // select entry of an old rectangle
    2785           0 :                 if( !bSelected )
    2786           0 :                     SelectEntry( pEntry, true, true, true );
    2787             :             }
    2788             :         }
    2789           0 :         else if( !bOver && bSelected )
    2790             :         {
    2791             :             // this entry is completely outside the rectangle => deselect it
    2792           0 :             SelectEntry( pEntry, false, true, true );
    2793             :         }
    2794             :     }
    2795             : 
    2796           0 :     if( !bAlreadySelectingRect )
    2797           0 :         nFlags &= ~F_SELECTING_RECT;
    2798             : 
    2799           0 :     pView->Update();
    2800           0 :     if( bResetClipRegion )
    2801           0 :         pView->SetClipRegion();
    2802             : }
    2803             : 
    2804           0 : void SvxIconChoiceCtrl_Impl::SelectRange(
    2805             :                         SvxIconChoiceCtrlEntry* pStart,
    2806             :                         SvxIconChoiceCtrlEntry* pEnd,
    2807             :                         bool bAdd )
    2808             : {
    2809           0 :     sal_uLong nFront = GetEntryListPos( pStart );
    2810           0 :     sal_uLong nBack  = GetEntryListPos( pEnd );
    2811           0 :     sal_uLong nFirst = std::min( nFront, nBack );
    2812           0 :     sal_uLong nLast  = std::max( nFront, nBack );
    2813             :     sal_uLong i;
    2814             :     SvxIconChoiceCtrlEntry* pEntry;
    2815             : 
    2816           0 :     if ( ! bAdd )
    2817             :     {
    2818             :         // deselect everything before the first entry if not in
    2819             :         // adding mode
    2820           0 :         for ( i=0; i<nFirst; i++ )
    2821             :         {
    2822           0 :             pEntry = GetEntry( i );
    2823           0 :             if( pEntry->IsSelected() )
    2824           0 :                 SelectEntry( pEntry, false, true, true, true );
    2825             :         }
    2826             :     }
    2827             : 
    2828             :     // select everything between nFirst and nLast
    2829           0 :     for ( i=nFirst; i<=nLast; i++ )
    2830             :     {
    2831           0 :         pEntry = GetEntry( i );
    2832           0 :         if( ! pEntry->IsSelected() )
    2833           0 :             SelectEntry( pEntry, true, true,  true, true );
    2834             :     }
    2835             : 
    2836           0 :     if ( ! bAdd )
    2837             :     {
    2838             :         // deselect everything behind the last entry if not in
    2839             :         // adding mode
    2840           0 :         sal_uLong nEnd = GetEntryCount();
    2841           0 :         for ( ; i<nEnd; i++ )
    2842             :         {
    2843           0 :             pEntry = GetEntry( i );
    2844           0 :             if( pEntry->IsSelected() )
    2845           0 :                 SelectEntry( pEntry, false, true, true, true );
    2846             :         }
    2847             :     }
    2848           0 : }
    2849             : 
    2850           0 : bool SvxIconChoiceCtrl_Impl::IsOver( std::vector<Rectangle*>* pRectList, const Rectangle& rBoundRect ) const
    2851             : {
    2852           0 :     const sal_uInt16 nCount = pRectList->size();
    2853           0 :     for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ )
    2854             :     {
    2855           0 :         Rectangle* pRect = (*pRectList)[ nCur ];
    2856           0 :         if( rBoundRect.IsOver( *pRect ))
    2857           0 :             return true;
    2858             :     }
    2859           0 :     return false;
    2860             : }
    2861             : 
    2862           0 : void SvxIconChoiceCtrl_Impl::AddSelectedRect( SvxIconChoiceCtrlEntry* pEntry1,
    2863             :     SvxIconChoiceCtrlEntry* pEntry2 )
    2864             : {
    2865             :     DBG_ASSERT(pEntry1 && pEntry2,"SelectEntry: Invalid Entry-Ptr");
    2866           0 :     Rectangle aRect( GetEntryBoundRect( pEntry1 ) );
    2867           0 :     aRect.Union( GetEntryBoundRect( pEntry2 ) );
    2868           0 :     AddSelectedRect( aRect );
    2869           0 : }
    2870             : 
    2871           0 : void SvxIconChoiceCtrl_Impl::AddSelectedRect( const Rectangle& rRect )
    2872             : {
    2873           0 :     Rectangle* pRect = new Rectangle( rRect );
    2874           0 :     pRect->Justify();
    2875           0 :     aSelectedRectList.push_back( pRect );
    2876           0 : }
    2877             : 
    2878          24 : void SvxIconChoiceCtrl_Impl::ClearSelectedRectList()
    2879             : {
    2880          24 :     const sal_uInt16 nCount = aSelectedRectList.size();
    2881          24 :     for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ )
    2882             :     {
    2883           0 :         Rectangle* pRect = aSelectedRectList[ nCur ];
    2884           0 :         delete pRect;
    2885             :     }
    2886          24 :     aSelectedRectList.clear();
    2887          24 : }
    2888             : 
    2889           0 : IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl, AutoArrangeHdl)
    2890             : {
    2891           0 :     aAutoArrangeTimer.Stop();
    2892           0 :     Arrange( IsAutoArrange() );
    2893           0 :     return 0;
    2894             : }
    2895             : 
    2896          12 : IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl, VisRectChangedHdl)
    2897             : {
    2898           6 :     aVisRectChangedTimer.Stop();
    2899           6 :     pView->VisibleRectChanged();
    2900           6 :     return 0;
    2901             : }
    2902             : 
    2903          12 : IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl, DocRectChangedHdl)
    2904             : {
    2905           6 :     aDocRectChangedTimer.Stop();
    2906           6 :     pView->DocumentRectChanged();
    2907           6 :     return 0;
    2908             : }
    2909             : 
    2910           0 : bool SvxIconChoiceCtrl_Impl::IsTextHit( SvxIconChoiceCtrlEntry* pEntry, const Point& rDocPos )
    2911             : {
    2912           0 :     Rectangle aRect( CalcTextRect( pEntry ));
    2913           0 :     if( aRect.IsInside( rDocPos ) )
    2914           0 :         return true;
    2915           0 :     return false;
    2916             : }
    2917             : 
    2918           0 : IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl, EditTimeoutHdl)
    2919             : {
    2920           0 :     SvxIconChoiceCtrlEntry* pEntry = GetCurEntry();
    2921           0 :     if( bEntryEditingEnabled && pEntry &&
    2922           0 :         pEntry->IsSelected())
    2923             :     {
    2924           0 :         if( pView->EditingEntry( pEntry ))
    2925           0 :             EditEntry( pEntry );
    2926             :     }
    2927           0 :     return 0;
    2928             : }
    2929             : 
    2930             : 
    2931             : 
    2932             : // Function to align entries to the grid
    2933             : 
    2934             : 
    2935             : // pStart == 0: align all entries
    2936             : // else: align all entries of the row from pStart on (including pStart)
    2937           0 : void SvxIconChoiceCtrl_Impl::AdjustEntryAtGrid( SvxIconChoiceCtrlEntry* pStart )
    2938             : {
    2939           0 :     IconChoiceMap aLists;
    2940           0 :     pImpCursor->CreateGridAjustData( aLists, pStart );
    2941           0 :     for (IconChoiceMap::const_iterator iter = aLists.begin();
    2942           0 :             iter != aLists.end(); ++iter)
    2943             :     {
    2944           0 :         AdjustAtGrid(iter->second, pStart);
    2945             :     }
    2946           0 :     IcnCursor_Impl::DestroyGridAdjustData( aLists );
    2947           0 :     CheckScrollBars();
    2948           0 : }
    2949             : 
    2950             : // align a row, might expand width, doesn't break the line
    2951           0 : void SvxIconChoiceCtrl_Impl::AdjustAtGrid( const SvxIconChoiceCtrlEntryPtrVec& rRow, SvxIconChoiceCtrlEntry* pStart )
    2952             : {
    2953           0 :     if( rRow.empty() )
    2954           0 :         return;
    2955             : 
    2956             :     bool bGo;
    2957           0 :     if( !pStart )
    2958           0 :         bGo = true;
    2959             :     else
    2960           0 :         bGo = false;
    2961             : 
    2962           0 :     long nCurRight = 0;
    2963           0 :     for( sal_uInt16 nCur = 0; nCur < rRow.size(); nCur++ )
    2964             :     {
    2965           0 :         SvxIconChoiceCtrlEntry* pCur = rRow[ nCur ];
    2966           0 :         if( !bGo && pCur == pStart )
    2967           0 :             bGo = true;
    2968             : 
    2969             :         // SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pCur);
    2970             :         // Decisive (for our eye) is the bitmap, else, the entry might jump too
    2971             :         // much within long texts.
    2972           0 :         const Rectangle& rBoundRect = GetEntryBoundRect( pCur );
    2973           0 :         Rectangle aCenterRect( CalcBmpRect( pCur, 0 ));
    2974           0 :         if( bGo && !pCur->IsPosLocked() )
    2975             :         {
    2976           0 :             long nWidth = aCenterRect.GetSize().Width();
    2977           0 :             Point aNewPos( AdjustAtGrid( aCenterRect, rBoundRect ) );
    2978           0 :             while( aNewPos.X() < nCurRight )
    2979           0 :                 aNewPos.X() += nGridDX;
    2980           0 :             if( aNewPos != rBoundRect.TopLeft() )
    2981             :             {
    2982           0 :                 SetEntryPos( pCur, aNewPos );
    2983           0 :                 pCur->SetFlags( ICNVIEW_FLAG_POS_MOVED );
    2984           0 :                 nFlags |= F_MOVED_ENTRIES;
    2985             :             }
    2986           0 :             nCurRight = aNewPos.X() + nWidth;
    2987             :         }
    2988             :         else
    2989             :         {
    2990           0 :             nCurRight = rBoundRect.Right();
    2991             :         }
    2992             :     }
    2993             : }
    2994             : 
    2995             : // Aligns a rectangle to the grid, but doesn't guarantee that the new position
    2996             : // is vacant. The position can be used for SetEntryPos. The CenterRect describes
    2997             : // a part of the bounding rectangle that is used for calculating the target
    2998             : // rectangle.
    2999           0 : Point SvxIconChoiceCtrl_Impl::AdjustAtGrid( const Rectangle& rCenterRect,
    3000             :     const Rectangle& rBoundRect ) const
    3001             : {
    3002           0 :     Point aPos( rCenterRect.TopLeft() );
    3003           0 :     Size aSize( rCenterRect.GetSize() );
    3004             : 
    3005           0 :     aPos.X() -= LROFFS_WINBORDER;
    3006           0 :     aPos.Y() -= TBOFFS_WINBORDER;
    3007             : 
    3008             :     // align (the center of the rectangle is the reference)
    3009           0 :     short nGridX = (short)((aPos.X()+(aSize.Width()/2)) / nGridDX);
    3010           0 :     short nGridY = (short)((aPos.Y()+(aSize.Height()/2)) / nGridDY);
    3011           0 :     aPos.X() = nGridX * nGridDX;
    3012           0 :     aPos.Y() = nGridY * nGridDY;
    3013             :     // horizontal center
    3014           0 :     aPos.X() += (nGridDX - rBoundRect.GetSize().Width() ) / 2;
    3015             : 
    3016           0 :     aPos.X() += LROFFS_WINBORDER;
    3017           0 :     aPos.Y() += TBOFFS_WINBORDER;
    3018             : 
    3019           0 :     return aPos;
    3020             : }
    3021             : 
    3022             : #ifdef DBG_UTIL
    3023             : void SvxIconChoiceCtrl_Impl::SetEntryTextMode( SvxIconChoiceCtrlTextMode eMode, SvxIconChoiceCtrlEntry* pEntry )
    3024             : {
    3025             :     if( !pEntry )
    3026             :     {
    3027             :         if( eTextMode != eMode )
    3028             :         {
    3029             :             if( eTextMode == IcnShowTextDontKnow )
    3030             :                 eTextMode = IcnShowTextShort;
    3031             :             eTextMode = eMode;
    3032             :             Arrange( true );
    3033             :         }
    3034             :     }
    3035             :     else
    3036             :     {
    3037             :         if( pEntry->eTextMode != eMode )
    3038             :         {
    3039             :             pEntry->eTextMode = eMode;
    3040             :             InvalidateEntry( pEntry );
    3041             :             pView->Invalidate( GetEntryBoundRect( pEntry ) );
    3042             :             AdjustVirtSize( pEntry->aRect );
    3043             :         }
    3044             :     }
    3045             : }
    3046             : #endif
    3047             : 
    3048         138 : SvxIconChoiceCtrlTextMode SvxIconChoiceCtrl_Impl::GetEntryTextModeSmart( const SvxIconChoiceCtrlEntry* pEntry ) const
    3049             : {
    3050             :     DBG_ASSERT(pEntry,"GetEntryTextModeSmart: Entry not set");
    3051         138 :     SvxIconChoiceCtrlTextMode eMode = pEntry->GetTextMode();
    3052         138 :     if( eMode == IcnShowTextDontKnow )
    3053           0 :         return eTextMode;
    3054         138 :     return eMode;
    3055             : }
    3056             : 
    3057             : 
    3058             : 
    3059             : // Draw my own focusrect, because the focusrect of the outputdevice has got the inverted color
    3060             : // of the background. But what will we see, if the backgroundcolor is gray ? - We will see
    3061             : // a gray focusrect on a gray background !!!
    3062             : 
    3063          54 : void SvxIconChoiceCtrl_Impl::ShowFocus ( Rectangle& rRect )
    3064             : {
    3065          54 :     Color aBkgColor ( pView->GetBackground().GetColor() );
    3066          54 :     Color aPenColor;
    3067          54 :     sal_uInt16 nColor = ( aBkgColor.GetRed() + aBkgColor.GetGreen() + aBkgColor.GetBlue() ) / 3;
    3068          54 :     if ( nColor > 128 )
    3069          54 :         aPenColor.SetColor ( COL_BLACK );
    3070             :     else
    3071           0 :         aPenColor.SetColor( COL_WHITE );
    3072             : 
    3073          54 :     aFocus.bOn = true;
    3074          54 :     aFocus.aPenColor = aPenColor;
    3075          54 :     aFocus.aRect = rRect;
    3076          54 : }
    3077             : 
    3078          18 : void SvxIconChoiceCtrl_Impl::DrawFocusRect ( OutputDevice* pOut )
    3079             : {
    3080          18 :     pOut->SetLineColor( aFocus.aPenColor );
    3081          18 :     pOut->SetFillColor();
    3082          18 :     Polygon aPolygon ( aFocus.aRect );
    3083             : 
    3084          36 :     LineInfo aLineInfo ( LINE_DASH );
    3085             : 
    3086          18 :     aLineInfo.SetDashLen ( 1 );
    3087             : 
    3088          18 :     aLineInfo.SetDotLen ( 1L );
    3089          18 :     aLineInfo.SetDistance ( 1L );
    3090          18 :     aLineInfo.SetDotCount ( 1 );
    3091             : 
    3092          36 :     pOut->DrawPolyLine ( aPolygon, aLineInfo );
    3093          18 : }
    3094             : 
    3095           0 : bool SvxIconChoiceCtrl_Impl::IsMnemonicChar( sal_Unicode cChar, sal_uLong& rPos ) const
    3096             : {
    3097           0 :     bool bRet = false;
    3098           0 :     const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
    3099           0 :     size_t nEntryCount = GetEntryCount();
    3100           0 :     for ( size_t i = 0; i < nEntryCount; ++i )
    3101             :     {
    3102           0 :         if ( rI18nHelper.MatchMnemonic( GetEntry( i )->GetText(), cChar ) )
    3103             :         {
    3104           0 :             bRet = true;
    3105           0 :             rPos = i;
    3106           0 :             break;
    3107             :         }
    3108             :     }
    3109             : 
    3110           0 :     return bRet;
    3111             : }
    3112             : 
    3113             : 
    3114             : 
    3115             : 
    3116          24 : IMPL_LINK(SvxIconChoiceCtrl_Impl, UserEventHdl, void*, nId )
    3117             : {
    3118          12 :     if( nId == EVENTID_ADJUST_SCROLLBARS )
    3119             :     {
    3120          12 :         nUserEventAdjustScrBars = 0;
    3121          12 :         AdjustScrollBars();
    3122             :     }
    3123           0 :     else if( nId == EVENTID_SHOW_CURSOR )
    3124             :     {
    3125           0 :         nUserEventShowCursor = 0;
    3126           0 :         ShowCursor( true );
    3127             :     }
    3128          12 :     return 0;
    3129             : }
    3130             : 
    3131          40 : void SvxIconChoiceCtrl_Impl::CancelUserEvents()
    3132             : {
    3133          40 :     if( nUserEventAdjustScrBars )
    3134             :     {
    3135           6 :         Application::RemoveUserEvent( nUserEventAdjustScrBars );
    3136           6 :         nUserEventAdjustScrBars = 0;
    3137             :     }
    3138          40 :     if( nUserEventShowCursor )
    3139             :     {
    3140           0 :         Application::RemoveUserEvent( nUserEventShowCursor );
    3141           0 :         nUserEventShowCursor = 0;
    3142             :     }
    3143          40 : }
    3144             : 
    3145           0 : void SvxIconChoiceCtrl_Impl::InvalidateEntry( SvxIconChoiceCtrlEntry* pEntry )
    3146             : {
    3147           0 :     if( pEntry == pCursor )
    3148           0 :         ShowCursor( false );
    3149           0 :     pView->Invalidate( pEntry->aRect );
    3150           0 :     Center( pEntry );
    3151           0 :     pView->Invalidate( pEntry->aRect );
    3152           0 :     if( pEntry == pCursor )
    3153           0 :         ShowCursor( true );
    3154           0 : }
    3155             : 
    3156           0 : void SvxIconChoiceCtrl_Impl::EditEntry( SvxIconChoiceCtrlEntry* pEntry )
    3157             : {
    3158             :     DBG_ASSERT(pEntry,"EditEntry: Entry not set");
    3159           0 :     if( !pEntry )
    3160           0 :         return;
    3161             : 
    3162           0 :     StopEntryEditing( true );
    3163           0 :     DELETEZ(pEdit);
    3164           0 :     SetNoSelection();
    3165             : 
    3166           0 :     pCurEditedEntry = pEntry;
    3167           0 :     OUString aEntryText( pView->GetEntryText( pEntry, true ) );
    3168           0 :     Rectangle aRect( CalcTextRect( pEntry, 0, true, &aEntryText ) );
    3169           0 :     MakeVisible( aRect );
    3170           0 :     Point aPos( aRect.TopLeft() );
    3171           0 :     aPos = pView->GetPixelPos( aPos );
    3172           0 :     aRect.SetPos( aPos );
    3173           0 :     pView->HideFocus();
    3174             :     pEdit = new IcnViewEdit_Impl(
    3175             :         pView,
    3176             :         aRect.TopLeft(),
    3177             :         aRect.GetSize(),
    3178             :         aEntryText,
    3179           0 :         LINK( this, SvxIconChoiceCtrl_Impl, TextEditEndedHdl ) );
    3180             : }
    3181             : 
    3182           0 : IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl, TextEditEndedHdl)
    3183             : {
    3184             :     DBG_ASSERT(pEdit,"TextEditEnded: pEdit not set");
    3185           0 :     if( !pEdit )
    3186             :     {
    3187           0 :         pCurEditedEntry = 0;
    3188           0 :         return 0;
    3189             :     }
    3190             :     DBG_ASSERT(pCurEditedEntry,"TextEditEnded: pCurEditedEntry not set");
    3191             : 
    3192           0 :     if( !pCurEditedEntry )
    3193             :     {
    3194           0 :         pEdit->Hide();
    3195           0 :         if( pEdit->IsGrabFocus() )
    3196           0 :             pView->GrabFocus();
    3197           0 :         return 0;
    3198             :     }
    3199             : 
    3200           0 :     OUString aText;
    3201           0 :     if ( !pEdit->EditingCanceled() )
    3202           0 :         aText = pEdit->GetText();
    3203             :     else
    3204           0 :         aText = pEdit->GetSavedValue();
    3205             : 
    3206           0 :     if( pView->EditedEntry( pCurEditedEntry, aText, pEdit->EditingCanceled() ) )
    3207           0 :         InvalidateEntry( pCurEditedEntry );
    3208           0 :     if( !GetSelectionCount() )
    3209           0 :         SelectEntry( pCurEditedEntry, true );
    3210             : 
    3211           0 :     pEdit->Hide();
    3212           0 :     if( pEdit->IsGrabFocus() )
    3213           0 :         pView->GrabFocus();
    3214             :     // The edit can not be deleted here, because it is not within a handler. It
    3215             :     // will be deleted in the dtor or in the next EditEntry.
    3216           0 :     pCurEditedEntry = 0;
    3217           0 :     return 0;
    3218             : }
    3219             : 
    3220          28 : void SvxIconChoiceCtrl_Impl::StopEntryEditing( bool bCancel )
    3221             : {
    3222          28 :     if( pEdit )
    3223           0 :         pEdit->StopEditing( bCancel );
    3224          28 : }
    3225             : 
    3226         376 : SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetFirstSelectedEntry( sal_uLong& rPos ) const
    3227             : {
    3228         376 :     if( !GetSelectionCount() )
    3229          28 :         return 0;
    3230             : 
    3231         348 :     if( (nWinBits & WB_HIGHLIGHTFRAME) && (eSelectionMode == NO_SELECTION) )
    3232             :     {
    3233           0 :         rPos = pView->GetEntryListPos( pCurHighlightFrame );
    3234           0 :         return pCurHighlightFrame;
    3235             :     }
    3236             : 
    3237         348 :     size_t nCount = aEntries.size();
    3238         348 :     if( !pHead )
    3239             :     {
    3240        1044 :         for( size_t nCur = 0; nCur < nCount; nCur++ )
    3241             :         {
    3242        1044 :             SvxIconChoiceCtrlEntry* pEntry = aEntries[ nCur ];
    3243        1044 :             if( pEntry->IsSelected() )
    3244             :             {
    3245         348 :                 rPos = nCur;
    3246         348 :                 return pEntry;
    3247             :             }
    3248             :         }
    3249             :     }
    3250             :     else
    3251             :     {
    3252           0 :         SvxIconChoiceCtrlEntry* pEntry = pHead;
    3253           0 :         while( nCount-- )
    3254             :         {
    3255           0 :             if( pEntry->IsSelected() )
    3256             :             {
    3257           0 :                 rPos = GetEntryListPos( pEntry );
    3258           0 :                 return pEntry;
    3259             :             }
    3260           0 :             pEntry = pEntry->pflink;
    3261           0 :             if( nCount && pEntry == pHead )
    3262             :             {
    3263             :                 OSL_FAIL("SvxIconChoiceCtrl_Impl::GetFirstSelectedEntry > infinite loop!");
    3264           0 :                 return 0;
    3265             :             }
    3266             :         }
    3267             :     }
    3268           0 :     return 0;
    3269             : }
    3270             : 
    3271           0 : void SvxIconChoiceCtrl_Impl::SelectAll( bool bSelect, bool bPaint )
    3272             : {
    3273           0 :     bPaint = true;
    3274             : 
    3275           0 :     size_t nCount = aEntries.size();
    3276           0 :     for( size_t nCur = 0; nCur < nCount && (bSelect || GetSelectionCount() ); nCur++ )
    3277             :     {
    3278           0 :         SvxIconChoiceCtrlEntry* pEntry = aEntries[ nCur ];
    3279           0 :         SelectEntry( pEntry, bSelect, true, true, bPaint );
    3280             :     }
    3281           0 :     nFlags &= (~F_ADD_MODE);
    3282           0 :     pAnchor = 0;
    3283           0 : }
    3284             : 
    3285           0 : IcnViewEdit_Impl::IcnViewEdit_Impl( SvtIconChoiceCtrl* pParent, const Point& rPos,
    3286             :     const Size& rSize, const OUString& rData, const Link& rNotifyEditEnd ) :
    3287           0 :     MultiLineEdit( pParent, (pParent->GetStyle() & WB_ICON) ? WB_CENTER : WB_LEFT),
    3288             :     aCallBackHdl( rNotifyEditEnd ),
    3289             :     bCanceled( false ),
    3290             :     bAlreadyInCallback( false ),
    3291           0 :     bGrabFocus( false )
    3292             : {
    3293           0 :     vcl::Font aFont( pParent->GetPointFont() );
    3294           0 :     aFont.SetTransparent( false );
    3295           0 :     SetControlFont( aFont );
    3296           0 :     if( !pParent->HasFontFillColor() )
    3297             :     {
    3298           0 :         Color aColor( pParent->GetBackground().GetColor() );
    3299           0 :         SetControlBackground( aColor );
    3300             :     }
    3301             :     else
    3302           0 :         SetControlBackground( aFont.GetFillColor() );
    3303           0 :     SetControlForeground( aFont.GetColor() );
    3304           0 :     SetPosPixel( rPos );
    3305           0 :     SetSizePixel( CalcAdjustedSize(rSize) );
    3306           0 :     SetText( rData );
    3307           0 :     SaveValue();
    3308             : 
    3309           0 :     aAccReturn.InsertItem( IMPICNVIEW_ACC_RETURN, vcl::KeyCode(KEY_RETURN) );
    3310           0 :     aAccEscape.InsertItem( IMPICNVIEW_ACC_ESCAPE, vcl::KeyCode(KEY_ESCAPE) );
    3311             : 
    3312           0 :     aAccReturn.SetActivateHdl( LINK( this, IcnViewEdit_Impl, ReturnHdl_Impl) );
    3313           0 :     aAccEscape.SetActivateHdl( LINK( this, IcnViewEdit_Impl, EscapeHdl_Impl) );
    3314           0 :     Application::InsertAccel( &aAccReturn);//, ACCEL_ALWAYS );
    3315           0 :     Application::InsertAccel( &aAccEscape);//, ACCEL_ALWAYS );
    3316           0 :     Show();
    3317           0 :     GrabFocus();
    3318           0 : }
    3319             : 
    3320           0 : IcnViewEdit_Impl::~IcnViewEdit_Impl()
    3321             : {
    3322           0 :     if( !bAlreadyInCallback )
    3323             :     {
    3324           0 :         Application::RemoveAccel( &aAccReturn );
    3325           0 :         Application::RemoveAccel( &aAccEscape );
    3326             :     }
    3327           0 : }
    3328             : 
    3329           0 : void IcnViewEdit_Impl::CallCallBackHdl_Impl()
    3330             : {
    3331           0 :     aTimer.Stop();
    3332           0 :     if ( !bAlreadyInCallback )
    3333             :     {
    3334           0 :         bAlreadyInCallback = true;
    3335           0 :         Application::RemoveAccel( &aAccReturn );
    3336           0 :         Application::RemoveAccel( &aAccEscape );
    3337           0 :         Hide();
    3338           0 :         aCallBackHdl.Call( this );
    3339             :     }
    3340           0 : }
    3341             : 
    3342           0 : IMPL_LINK_NOARG(IcnViewEdit_Impl, Timeout_Impl)
    3343             : {
    3344           0 :     CallCallBackHdl_Impl();
    3345           0 :     return 0;
    3346             : }
    3347             : 
    3348           0 : IMPL_LINK( IcnViewEdit_Impl, ReturnHdl_Impl, Accelerator*, EMPTYARG  )
    3349             : {
    3350           0 :     bCanceled = false;
    3351           0 :     bGrabFocus = true;
    3352           0 :     CallCallBackHdl_Impl();
    3353           0 :     return 1;
    3354             : }
    3355             : 
    3356           0 : IMPL_LINK( IcnViewEdit_Impl, EscapeHdl_Impl, Accelerator*, EMPTYARG  )
    3357             : {
    3358           0 :     bCanceled = true;
    3359           0 :     bGrabFocus = true;
    3360           0 :     CallCallBackHdl_Impl();
    3361           0 :     return 1;
    3362             : }
    3363             : 
    3364           0 : void IcnViewEdit_Impl::KeyInput( const KeyEvent& rKEvt )
    3365             : {
    3366           0 :     vcl::KeyCode aCode = rKEvt.GetKeyCode();
    3367           0 :     sal_uInt16 nCode = aCode.GetCode();
    3368             : 
    3369           0 :     switch ( nCode )
    3370             :     {
    3371             :         case KEY_ESCAPE:
    3372           0 :             bCanceled = true;
    3373           0 :             bGrabFocus = true;
    3374           0 :             CallCallBackHdl_Impl();
    3375           0 :             break;
    3376             : 
    3377             :         case KEY_RETURN:
    3378           0 :             bCanceled = false;
    3379           0 :             bGrabFocus = true;
    3380           0 :             CallCallBackHdl_Impl();
    3381           0 :             break;
    3382             : 
    3383             :         default:
    3384           0 :             MultiLineEdit::KeyInput( rKEvt );
    3385             :     }
    3386           0 : }
    3387             : 
    3388           0 : bool IcnViewEdit_Impl::PreNotify( NotifyEvent& rNEvt )
    3389             : {
    3390           0 :     if( rNEvt.GetType() == EVENT_LOSEFOCUS )
    3391             :     {
    3392           0 :         if ( !bAlreadyInCallback &&
    3393           0 :             ((!Application::GetFocusWindow()) || !IsChild(Application::GetFocusWindow())))
    3394             :         {
    3395           0 :             bCanceled = false;
    3396           0 :             aTimer.SetTimeout(10);
    3397           0 :             aTimer.SetTimeoutHdl(LINK(this,IcnViewEdit_Impl,Timeout_Impl));
    3398           0 :             aTimer.Start();
    3399             :         }
    3400             :     }
    3401           0 :     return false;
    3402             : }
    3403             : 
    3404           0 : void IcnViewEdit_Impl::StopEditing( bool bCancel )
    3405             : {
    3406           0 :     if ( !bAlreadyInCallback )
    3407             :     {
    3408           0 :         bCanceled = bCancel;
    3409           0 :         CallCallBackHdl_Impl();
    3410             :     }
    3411           0 : }
    3412             : 
    3413           0 : sal_uLong SvxIconChoiceCtrl_Impl::GetEntryListPos( SvxIconChoiceCtrlEntry* pEntry ) const
    3414             : {
    3415           0 :     if( !(nFlags & F_ENTRYLISTPOS_VALID ))
    3416           0 :         ((SvxIconChoiceCtrl_Impl*)this)->SetListPositions();
    3417           0 :     return pEntry->nPos;
    3418             : }
    3419             : 
    3420          16 : void SvxIconChoiceCtrl_Impl::InitSettings()
    3421             : {
    3422          16 :     const StyleSettings& rStyleSettings = pView->GetSettings().GetStyleSettings();
    3423             : 
    3424          16 :     if( !pView->HasFont() )
    3425             :     {
    3426             :         // unit (from settings) is Point
    3427          16 :         vcl::Font aFont( rStyleSettings.GetFieldFont() );
    3428             :         //const vcl::Font& rFont = pView->GetFont();
    3429             :         //if( pView->HasFontTextColor() )
    3430          16 :             aFont.SetColor( rStyleSettings.GetWindowTextColor() );
    3431             :         //if( pView->HasFontFillColor() )
    3432             :             //aFont.SetFillColor( rFont.GetFillColor() );
    3433          16 :         pView->SetPointFont( aFont );
    3434          16 :         SetDefaultTextSize();
    3435             :     }
    3436             : 
    3437             :     //if( !pView->HasFontTextColor() )
    3438          16 :         pView->SetTextColor( rStyleSettings.GetFieldTextColor() );
    3439             :     //if( !pView->HasFontFillColor() )
    3440          16 :         pView->SetTextFillColor();
    3441             : 
    3442             :     //if( !pView->HasBackground() )
    3443          16 :         pView->SetBackground( rStyleSettings.GetFieldColor());
    3444             : 
    3445          16 :     long nScrBarSize = rStyleSettings.GetScrollBarSize();
    3446          16 :     if( nScrBarSize != nHorSBarHeight || nScrBarSize != nVerSBarWidth )
    3447             :     {
    3448           0 :         nHorSBarHeight = nScrBarSize;
    3449           0 :         Size aSize( aHorSBar.GetSizePixel() );
    3450           0 :         aSize.Height() = nScrBarSize;
    3451           0 :         aHorSBar.Hide();
    3452           0 :         aHorSBar.SetSizePixel( aSize );
    3453             : 
    3454           0 :         nVerSBarWidth = nScrBarSize;
    3455           0 :         aSize = aVerSBar.GetSizePixel();
    3456           0 :         aSize.Width() = nScrBarSize;
    3457           0 :         aVerSBar.Hide();
    3458           0 :         aVerSBar.SetSizePixel( aSize );
    3459             : 
    3460           0 :         Size aOSize( pView->Control::GetOutputSizePixel() );
    3461           0 :         PositionScrollBars( aOSize.Width(), aOSize.Height() );
    3462           0 :         AdjustScrollBars();
    3463             :     }
    3464          16 : }
    3465             : 
    3466          16 : EntryList_Impl::EntryList_Impl( SvxIconChoiceCtrl_Impl* pOwner ) :
    3467          16 :     _pOwner( pOwner )
    3468             : {
    3469          16 :     _pOwner->pHead = 0;
    3470          16 : }
    3471             : 
    3472          24 : EntryList_Impl::~EntryList_Impl()
    3473             : {
    3474          12 :     _pOwner->pHead = 0;
    3475          12 : }
    3476             : 
    3477          28 : void EntryList_Impl::clear()
    3478             : {
    3479          28 :     _pOwner->pHead = 0;
    3480          28 :     maIconChoiceCtrlEntryList.clear();
    3481          28 : }
    3482             : 
    3483          64 : void EntryList_Impl::insert( size_t nPos, SvxIconChoiceCtrlEntry* pEntry )
    3484             : {
    3485          64 :     if ( nPos < maIconChoiceCtrlEntryList.size() ) {
    3486           0 :         maIconChoiceCtrlEntryList.insert( maIconChoiceCtrlEntryList.begin() + nPos, pEntry );
    3487             :     } else {
    3488          64 :         maIconChoiceCtrlEntryList.push_back( pEntry );
    3489             :     }
    3490          64 :     if( _pOwner->pHead )
    3491           0 :         pEntry->SetBacklink( _pOwner->pHead->pblink );
    3492          64 : }
    3493             : 
    3494          16 : void SvxIconChoiceCtrl_Impl::SetPositionMode( SvxIconChoiceCtrlPositionMode eMode )
    3495             : {
    3496          16 :     if( eMode == ePositionMode )
    3497           0 :         return;
    3498             : 
    3499          16 :     SvxIconChoiceCtrlPositionMode eOldMode = ePositionMode;
    3500          16 :     ePositionMode = eMode;
    3501          16 :     size_t nCount = aEntries.size();
    3502             : 
    3503          16 :     if( eOldMode == IcnViewPositionModeAutoArrange )
    3504             :     {
    3505             :         // when positioning moved entries "hard", there are problems with
    3506             :         // unwanted overlaps, as these entries aren't taken into account in
    3507             :         // Arrange.
    3508           0 :         if( aEntries.size() )
    3509           0 :             aAutoArrangeTimer.Start();
    3510           0 :         return;
    3511             :     }
    3512             : 
    3513          16 :     if( ePositionMode == IcnViewPositionModeAutoArrange )
    3514             :     {
    3515          16 :         for( size_t nCur = 0; nCur < nCount; nCur++ )
    3516             :         {
    3517           0 :             SvxIconChoiceCtrlEntry* pEntry = aEntries[ nCur ];
    3518           0 :             if( pEntry->GetFlags() & (ICNVIEW_FLAG_POS_LOCKED | ICNVIEW_FLAG_POS_MOVED))
    3519           0 :                 SetEntryPos(pEntry, GetEntryBoundRect( pEntry ).TopLeft());
    3520             :         }
    3521             : 
    3522          16 :         if( aEntries.size() )
    3523           0 :             aAutoArrangeTimer.Start();
    3524             :     }
    3525           0 :     else if( ePositionMode == IcnViewPositionModeAutoAdjust )
    3526             :     {
    3527           0 :         AdjustEntryAtGrid( 0 );
    3528             :     }
    3529             : }
    3530             : 
    3531           0 : void SvxIconChoiceCtrl_Impl::SetEntryPredecessor( SvxIconChoiceCtrlEntry* pEntry,
    3532             :     SvxIconChoiceCtrlEntry* pPredecessor )
    3533             : {
    3534           0 :     if( !IsAutoArrange() )
    3535           0 :         return;
    3536             : 
    3537           0 :     if( pEntry == pPredecessor )
    3538           0 :         return;
    3539             : 
    3540           0 :     sal_uLong nPos1 = GetEntryListPos( pEntry );
    3541           0 :     if( !pHead )
    3542             :     {
    3543           0 :         if( pPredecessor )
    3544             :         {
    3545           0 :             sal_uLong nPos2 = GetEntryListPos( pPredecessor );
    3546           0 :             if( nPos1 == (nPos2 + 1) )
    3547           0 :                 return; // is already the predecessor
    3548             :         }
    3549           0 :         else if( !nPos1 )
    3550           0 :             return;
    3551             :     }
    3552             : 
    3553           0 :     if( !pHead )
    3554           0 :         InitPredecessors();
    3555             : 
    3556           0 :     if( !pPredecessor && pHead == pEntry )
    3557           0 :         return; // is already the first one
    3558             : 
    3559           0 :     bool bSetHead = false;
    3560           0 :     if( !pPredecessor )
    3561             :     {
    3562           0 :         bSetHead = true;
    3563           0 :         pPredecessor = pHead->pblink;
    3564             :     }
    3565           0 :     if( pEntry == pHead )
    3566             :     {
    3567           0 :         pHead = pHead->pflink;
    3568           0 :         bSetHead = false;
    3569             :     }
    3570           0 :     if( pEntry != pPredecessor )
    3571             :     {
    3572           0 :         pEntry->Unlink();
    3573           0 :         pEntry->SetBacklink( pPredecessor );
    3574             :     }
    3575           0 :     if( bSetHead )
    3576           0 :         pHead = pEntry;
    3577           0 :     pEntry->SetFlags( ICNVIEW_FLAG_PRED_SET );
    3578           0 :     aAutoArrangeTimer.Start();
    3579             : }
    3580             : 
    3581           0 : SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::FindEntryPredecessor( SvxIconChoiceCtrlEntry* pEntry,
    3582             :     const Point& rPosTopLeft )
    3583             : {
    3584           0 :     Point aPos( rPosTopLeft ); //TopLeft
    3585           0 :     Rectangle aCenterRect( CalcBmpRect( pEntry, &aPos ));
    3586           0 :     Point aNewPos( aCenterRect.Center() );
    3587           0 :     sal_uLong nGrid = GetPredecessorGrid( aNewPos );
    3588           0 :     size_t nCount = aEntries.size();
    3589           0 :     if( nGrid == ULONG_MAX )
    3590           0 :         return 0;
    3591           0 :     if( nGrid >= nCount )
    3592           0 :         nGrid = nCount - 1;
    3593           0 :     if( !pHead )
    3594           0 :         return aEntries[ nGrid ];
    3595             : 
    3596           0 :     SvxIconChoiceCtrlEntry* pCur = pHead; // Grid 0
    3597             :     // TODO: go through list from the end if nGrid > nCount/2
    3598           0 :     for( sal_uLong nCur = 0; nCur < nGrid; nCur++ )
    3599           0 :         pCur = pCur->pflink;
    3600             : 
    3601           0 :     return pCur;
    3602             : }
    3603             : 
    3604           0 : sal_uLong SvxIconChoiceCtrl_Impl::GetPredecessorGrid( const Point& rPos) const
    3605             : {
    3606           0 :     Point aPos( rPos );
    3607           0 :     aPos.X() -= LROFFS_WINBORDER;
    3608           0 :     aPos.Y() -= TBOFFS_WINBORDER;
    3609           0 :     long nMaxCol = aVirtOutputSize.Width() / nGridDX;
    3610           0 :     if( nMaxCol )
    3611           0 :         nMaxCol--;
    3612           0 :     long nGridX = aPos.X() / nGridDX;
    3613           0 :     if( nGridX > nMaxCol )
    3614           0 :         nGridX = nMaxCol;
    3615           0 :     long nGridY = aPos.Y() / nGridDY;
    3616           0 :     long nGridsX = aOutputSize.Width() / nGridDX;
    3617           0 :     sal_uLong nGrid = (nGridY * nGridsX) + nGridX;
    3618           0 :     long nMiddle = (nGridX * nGridDX) + (nGridDX / 2);
    3619           0 :     if( rPos.X() < nMiddle )
    3620             :     {
    3621           0 :         if( !nGrid )
    3622           0 :             nGrid = ULONG_MAX;
    3623             :         else
    3624           0 :             nGrid--;
    3625             :     }
    3626           0 :     return nGrid;
    3627             : }
    3628             : 
    3629           0 : bool SvxIconChoiceCtrl_Impl::RequestHelp( const HelpEvent& rHEvt )
    3630             : {
    3631           0 :     if ( !(rHEvt.GetMode() & HELPMODE_QUICK ) )
    3632           0 :         return false;
    3633             : 
    3634           0 :     Point aPos( pView->ScreenToOutputPixel(rHEvt.GetMousePosPixel() ) );
    3635           0 :     aPos -= pView->GetMapMode().GetOrigin();
    3636           0 :     SvxIconChoiceCtrlEntry* pEntry = GetEntry( aPos, true );
    3637             : 
    3638           0 :     if ( !pEntry )
    3639           0 :         return false;
    3640             : 
    3641           0 :     OUString sQuickHelpText = pEntry->GetQuickHelpText();
    3642           0 :     OUString aEntryText( pView->GetEntryText( pEntry, false ) );
    3643           0 :     Rectangle aTextRect( CalcTextRect( pEntry, 0, false, &aEntryText ) );
    3644           0 :     if ( ( !aTextRect.IsInside( aPos ) || aEntryText.isEmpty() ) && sQuickHelpText.isEmpty() )
    3645           0 :         return false;
    3646             : 
    3647           0 :     Rectangle aOptTextRect( aTextRect );
    3648           0 :     aOptTextRect.Bottom() = LONG_MAX;
    3649           0 :     sal_uInt16 nNewFlags = nCurTextDrawFlags;
    3650           0 :     nNewFlags &= ~( TEXT_DRAW_CLIP | TEXT_DRAW_ENDELLIPSIS );
    3651           0 :     aOptTextRect = pView->GetTextRect( aOptTextRect, aEntryText, nNewFlags );
    3652           0 :     if ( aOptTextRect != aTextRect || !sQuickHelpText.isEmpty() )
    3653             :     {
    3654             :         //aTextRect.Right() = aTextRect.Left() + aRealSize.Width() + 4;
    3655           0 :         Point aPt( aOptTextRect.TopLeft() );
    3656           0 :         aPt += pView->GetMapMode().GetOrigin();
    3657           0 :         aPt = pView->OutputToScreenPixel( aPt );
    3658             :         // subtract border of tooltip help
    3659           0 :         aPt.Y() -= 1;
    3660           0 :         aPt.X() -= 3;
    3661           0 :         aOptTextRect.SetPos( aPt );
    3662           0 :         OUString sHelpText;
    3663           0 :         if ( !sQuickHelpText.isEmpty() )
    3664           0 :             sHelpText = sQuickHelpText;
    3665             :         else
    3666           0 :             sHelpText = aEntryText;
    3667           0 :         Help::ShowQuickHelp( (vcl::Window*)pView, aOptTextRect, sHelpText, QUICKHELP_LEFT | QUICKHELP_VCENTER );
    3668             :     }
    3669             : 
    3670           0 :     return true;
    3671             : }
    3672             : 
    3673          12 : void SvxIconChoiceCtrl_Impl::ClearColumnList()
    3674             : {
    3675          12 :     if( !pColumns )
    3676          24 :         return;
    3677             : 
    3678           0 :     pColumns->clear();
    3679           0 :     DELETEZ(pColumns);
    3680             : }
    3681             : 
    3682           0 : void SvxIconChoiceCtrl_Impl::SetColumn( sal_uInt16 nIndex, const SvxIconChoiceCtrlColumnInfo& rInfo)
    3683             : {
    3684           0 :     if( !pColumns )
    3685           0 :         pColumns = new SvxIconChoiceCtrlColumnInfoMap;
    3686             : 
    3687           0 :     SvxIconChoiceCtrlColumnInfo* pInfo = new SvxIconChoiceCtrlColumnInfo( rInfo );
    3688           0 :     pColumns->insert( nIndex,  pInfo );
    3689             : 
    3690             :     // HACK: Detail mode is not yet fully implemented, this workaround makes it
    3691             :     // fly with a single column
    3692           0 :     if( !nIndex && (nWinBits & WB_DETAILS) )
    3693           0 :         nGridDX = pInfo->GetWidth();
    3694             : 
    3695           0 :     if( GetUpdateMode() )
    3696           0 :         Arrange( IsAutoArrange() );
    3697           0 : }
    3698             : 
    3699           0 : const SvxIconChoiceCtrlColumnInfo* SvxIconChoiceCtrl_Impl::GetColumn( sal_uInt16 nIndex ) const
    3700             : {
    3701           0 :     if (!pColumns)
    3702           0 :         return 0;
    3703           0 :     SvxIconChoiceCtrlColumnInfoMap::const_iterator it = pColumns->find( nIndex );
    3704           0 :     if( it == pColumns->end() )
    3705           0 :         return 0;
    3706           0 :     return it->second;
    3707             : }
    3708             : 
    3709           0 : void SvxIconChoiceCtrl_Impl::DrawHighlightFrame(
    3710             :     OutputDevice* pOut, const Rectangle& rBmpRect, bool bHide )
    3711             : {
    3712           0 :     Rectangle aBmpRect( rBmpRect );
    3713           0 :     long nBorder = 2;
    3714           0 :     if( aImageSize.Width() < 32 )
    3715           0 :         nBorder = 1;
    3716           0 :     aBmpRect.Right() += nBorder;
    3717           0 :     aBmpRect.Left() -= nBorder;
    3718           0 :     aBmpRect.Bottom() += nBorder;
    3719           0 :     aBmpRect.Top() -= nBorder;
    3720             : 
    3721           0 :     if ( bHide )
    3722           0 :         pView->Invalidate( aBmpRect );
    3723             :     else
    3724             :     {
    3725           0 :         DecorationView aDecoView( pOut );
    3726             :         sal_uInt16 nDecoFlags;
    3727           0 :         if ( bHighlightFramePressed )
    3728           0 :             nDecoFlags = FRAME_HIGHLIGHT_TESTBACKGROUND | FRAME_HIGHLIGHT_IN;
    3729             :         else
    3730           0 :             nDecoFlags = FRAME_HIGHLIGHT_TESTBACKGROUND | FRAME_HIGHLIGHT_OUT;
    3731           0 :         aDecoView.DrawHighlightFrame( aBmpRect, nDecoFlags );
    3732             :     }
    3733           0 : }
    3734             : 
    3735           0 : void SvxIconChoiceCtrl_Impl::SetEntryHighlightFrame( SvxIconChoiceCtrlEntry* pEntry,
    3736             :     bool bKeepHighlightFlags )
    3737             : {
    3738           0 :     if( pEntry == pCurHighlightFrame )
    3739           0 :         return;
    3740             : 
    3741           0 :     if( !bKeepHighlightFlags )
    3742           0 :         bHighlightFramePressed = false;
    3743             : 
    3744           0 :     HideEntryHighlightFrame();
    3745           0 :     pCurHighlightFrame = pEntry;
    3746           0 :     if( pEntry )
    3747             :     {
    3748           0 :         Rectangle aBmpRect( CalcFocusRect(pEntry) );
    3749           0 :         DrawHighlightFrame( pView, aBmpRect, false );
    3750             :     }
    3751             : }
    3752             : 
    3753           0 : void SvxIconChoiceCtrl_Impl::HideEntryHighlightFrame()
    3754             : {
    3755           0 :     if( !pCurHighlightFrame )
    3756           0 :         return;
    3757             : 
    3758           0 :     SvxIconChoiceCtrlEntry* pEntry = pCurHighlightFrame;
    3759           0 :     pCurHighlightFrame = 0;
    3760           0 :     Rectangle aBmpRect( CalcFocusRect(pEntry) );
    3761           0 :     DrawHighlightFrame( pView, aBmpRect, true );
    3762             : }
    3763             : 
    3764           6 : void SvxIconChoiceCtrl_Impl::CallSelectHandler( SvxIconChoiceCtrlEntry* )
    3765             : {
    3766             :     // When single-click mode is active, the selection handler should be called
    3767             :     // synchronously, as the selection is automatically taken away once the
    3768             :     // mouse cursor doesn't touch the object any more. Else, we might run into
    3769             :     // missing calls to Select if the object is selected from a mouse movement,
    3770             :     // because when starting the timer, the mouse cursor might have already left
    3771             :     // the object.
    3772             :     // In special cases (=>SfxFileDialog!), synchronous calls can be forced via
    3773             :     // WB_NOASYNCSELECTHDL.
    3774           6 :     if( nWinBits & (WB_NOASYNCSELECTHDL | WB_HIGHLIGHTFRAME) )
    3775             :     {
    3776           6 :         pHdlEntry = 0;
    3777           6 :         pView->ClickIcon();
    3778             :         //pView->Select();
    3779             :     }
    3780             :     else
    3781           0 :         aCallSelectHdlTimer.Start();
    3782           6 : }
    3783             : 
    3784           0 : IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl, CallSelectHdlHdl)
    3785             : {
    3786           0 :     pHdlEntry = 0;
    3787           0 :     pView->ClickIcon();
    3788             :     //pView->Select();
    3789           0 :     return 0;
    3790             : }
    3791             : 
    3792         144 : void SvxIconChoiceCtrl_Impl::SetOrigin( const Point& rPos, bool bDoNotUpdateWallpaper )
    3793             : {
    3794         144 :     MapMode aMapMode( pView->GetMapMode() );
    3795         144 :     aMapMode.SetOrigin( rPos );
    3796         144 :     pView->SetMapMode( aMapMode );
    3797         144 :     if( !bDoNotUpdateWallpaper )
    3798             :     {
    3799         144 :         bool bScrollable = pView->GetBackground().IsScrollable();
    3800         144 :         if( pView->HasBackground() && !bScrollable )
    3801             :         {
    3802           0 :             Rectangle aRect( GetOutputRect());
    3803           0 :             Wallpaper aPaper( pView->GetBackground() );
    3804           0 :             aPaper.SetRect( aRect );
    3805           0 :             pView->SetBackground( aPaper );
    3806             :         }
    3807         144 :     }
    3808         144 : }
    3809             : 
    3810          18 : void SvxIconChoiceCtrl_Impl::CallEventListeners( sal_uLong nEvent, void* pData )
    3811             : {
    3812          18 :     pView->CallImplEventListeners( nEvent, pData );
    3813        1245 : }
    3814             : 
    3815             : 
    3816             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10