LCOV - code coverage report
Current view: top level - svtools/source/contnr - imivctl1.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 780 2056 37.9 %
Date: 2015-06-13 12:38:46 Functions: 72 147 49.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11