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

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

Generated by: LCOV version 1.10