1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
34 #include <svtools/ivctrl.hxx>
35 #include "imivctl.hxx"
36 #include <svtools/svmedit.hxx>
39 #include <boost/scoped_ptr.hpp>
40 #include <vcl/idle.hxx>
42 #define IMPICNVIEW_ACC_RETURN 1
43 #define IMPICNVIEW_ACC_ESCAPE 2
45 #define DRAWTEXT_FLAGS_ICON \
46 ( DrawTextFlags::Center | DrawTextFlags::Top | DrawTextFlags::EndEllipsis | \
47 DrawTextFlags::Clip | DrawTextFlags::MultiLine | DrawTextFlags::WordBreak | DrawTextFlags::Mnemonic )
49 #define DRAWTEXT_FLAGS_SMALLICON (DrawTextFlags::Left|DrawTextFlags::EndEllipsis|DrawTextFlags::Clip)
51 #define EVENTID_SHOW_CURSOR (reinterpret_cast<void*>(1))
52 #define EVENTID_ADJUST_SCROLLBARS (reinterpret_cast<void*>(2))
54 static bool bEndScrollInvalidate
= true;
56 class IcnViewEdit_Impl
: public MultiLineEdit
59 Accelerator aAccReturn
;
60 Accelerator aAccEscape
;
63 bool bAlreadyInCallback
;
66 void CallCallBackHdl_Impl();
67 DECL_LINK_TYPED(Timeout_Impl
, Idle
*, void);
68 DECL_LINK( ReturnHdl_Impl
, Accelerator
* );
69 DECL_LINK( EscapeHdl_Impl
, Accelerator
* );
74 SvtIconChoiceCtrl
* pParent
,
77 const OUString
& rData
,
78 const Link
<>& rNotifyEditEnd
);
80 virtual ~IcnViewEdit_Impl();
81 virtual void dispose() SAL_OVERRIDE
;
82 virtual void KeyInput( const KeyEvent
& rKEvt
) SAL_OVERRIDE
;
83 virtual bool PreNotify( NotifyEvent
& rNEvt
) SAL_OVERRIDE
;
84 bool EditingCanceled() const { return bCanceled
; }
85 void StopEditing( bool bCancel
= false );
86 bool IsGrabFocus() const { return bGrabFocus
; }
89 SvxIconChoiceCtrl_Impl::SvxIconChoiceCtrl_Impl(
90 SvtIconChoiceCtrl
* pCurView
,
94 aVerSBar( VclPtr
<ScrollBar
>::Create(pCurView
, WB_DRAG
| WB_VSCROLL
) ),
95 aHorSBar( VclPtr
<ScrollBar
>::Create(pCurView
, WB_DRAG
| WB_HSCROLL
) ),
96 aScrBarBox( VclPtr
<ScrollBarBox
>::Create(pCurView
) ),
100 bChooseWithCursor
= false;
103 pCurHighlightFrame
= 0;
111 bEntryEditingEnabled
= false;
112 bHighlightFramePressed
= false;
113 eSelectionMode
= MULTIPLE_SELECTION
;
115 pZOrderList
= new SvxIconChoiceCtrlEntryList_impl();
116 ePositionMode
= IcnViewPositionModeFree
;
117 SetStyle( nWinStyle
);
119 nUserEventAdjustScrBars
= 0;
120 nUserEventShowCursor
= 0;
121 nMaxVirtWidth
= DEFAULT_MAX_VIRT_WIDTH
;
122 nMaxVirtHeight
= DEFAULT_MAX_VIRT_HEIGHT
;
127 eTextMode
= IcnShowTextShort
;
128 pImpCursor
= new IcnCursor_Impl( this );
129 pGridMap
= new IcnGridMap_Impl( this );
131 aVerSBar
->SetScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl
, ScrollUpDownHdl
) );
132 aHorSBar
->SetScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl
, ScrollLeftRightHdl
) );
133 Link
<> aEndScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl
, EndScrollHdl
) );
134 aVerSBar
->SetEndScrollHdl( aEndScrollHdl
);
135 aHorSBar
->SetEndScrollHdl( aEndScrollHdl
);
137 nHorSBarHeight
= aHorSBar
->GetSizePixel().Height();
138 nVerSBarWidth
= aVerSBar
->GetSizePixel().Width();
140 aEditIdle
.SetPriority( SchedulerPriority::LOWEST
);
141 aEditIdle
.SetIdleHdl(LINK(this,SvxIconChoiceCtrl_Impl
,EditTimeoutHdl
));
142 aAutoArrangeIdle
.SetPriority( SchedulerPriority::LOW
);
143 aAutoArrangeIdle
.SetIdleHdl(LINK(this,SvxIconChoiceCtrl_Impl
,AutoArrangeHdl
));
144 aCallSelectHdlIdle
.SetPriority( SchedulerPriority::LOWEST
);
145 aCallSelectHdlIdle
.SetIdleHdl( LINK(this,SvxIconChoiceCtrl_Impl
,CallSelectHdlHdl
));
147 aDocRectChangedIdle
.SetPriority( SchedulerPriority::MEDIUM
);
148 aDocRectChangedIdle
.SetIdleHdl(LINK(this,SvxIconChoiceCtrl_Impl
,DocRectChangedHdl
));
149 aVisRectChangedIdle
.SetPriority( SchedulerPriority::MEDIUM
);
150 aVisRectChangedIdle
.SetIdleHdl(LINK(this,SvxIconChoiceCtrl_Impl
,VisRectChangedHdl
));
154 SetGrid( Size(100, 70) );
157 SvxIconChoiceCtrl_Impl::~SvxIconChoiceCtrl_Impl()
160 pEdit
.disposeAndClear();
167 pDDDev
.disposeAndClear();
168 pDDBufDev
.disposeAndClear();
169 pDDTempDev
.disposeAndClear();
170 pEntryPaintDev
.disposeAndClear();
171 ClearSelectedRectList();
173 aVerSBar
.disposeAndClear();
174 aHorSBar
.disposeAndClear();
175 aScrBarBox
.disposeAndClear();
178 void SvxIconChoiceCtrl_Impl::Clear( bool bInCtor
)
180 StopEntryEditing( true );
182 pCurHighlightFrame
= 0;
186 bBoundRectsDirty
= false;
189 nFlags
&= ~(F_PAINTED
| F_MOVED_ENTRIES
);
195 aVirtOutputSize
.Width() = 0;
196 aVirtOutputSize
.Height() = 0;
197 Size
aSize( pView
->GetOutputSizePixel() );
198 nMaxVirtWidth
= aSize
.Width() - nVerSBarWidth
;
199 if( nMaxVirtWidth
<= 0 )
200 nMaxVirtWidth
= DEFAULT_MAX_VIRT_WIDTH
;
201 nMaxVirtHeight
= aSize
.Height() - nHorSBarHeight
;
202 if( nMaxVirtHeight
<= 0 )
203 nMaxVirtHeight
= DEFAULT_MAX_VIRT_HEIGHT
;
204 pZOrderList
->clear();
205 SetOrigin( Point() );
207 pView
->Invalidate(INVALIDATE_NOCHILDREN
);
210 size_t nCount
= aEntries
.size();
211 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
213 SvxIconChoiceCtrlEntry
* pCur
= aEntries
[ nCur
];
221 void SvxIconChoiceCtrl_Impl::SetStyle( WinBits nWinStyle
)
223 nWinBits
= nWinStyle
;
224 nCurTextDrawFlags
= DRAWTEXT_FLAGS_ICON
;
225 if( nWinBits
& (WB_SMALLICON
| WB_DETAILS
) )
226 nCurTextDrawFlags
= DRAWTEXT_FLAGS_SMALLICON
;
227 if( nWinBits
& WB_NOSELECTION
)
228 eSelectionMode
= NO_SELECTION
;
229 if( !(nWinStyle
& (WB_ALIGN_TOP
| WB_ALIGN_LEFT
)))
230 nWinBits
|= WB_ALIGN_LEFT
;
231 if( (nWinStyle
& WB_DETAILS
))
234 SetColumn( 0, SvxIconChoiceCtrlColumnInfo( 0, 100, IcnViewAlignLeft
));
238 IMPL_LINK( SvxIconChoiceCtrl_Impl
, ScrollUpDownHdl
, ScrollBar
*, pScrollBar
)
240 StopEntryEditing( true );
241 // arrow up: delta=-1; arrow down: delta=+1
242 Scroll( 0, pScrollBar
->GetDelta(), true );
243 bEndScrollInvalidate
= true;
247 IMPL_LINK( SvxIconChoiceCtrl_Impl
, ScrollLeftRightHdl
, ScrollBar
*, pScrollBar
)
249 StopEntryEditing( true );
250 // arrow left: delta=-1; arrow right: delta=+1
251 Scroll( pScrollBar
->GetDelta(), 0, true );
252 bEndScrollInvalidate
= true;
256 IMPL_STATIC_LINK_NOARG(SvxIconChoiceCtrl_Impl
, EndScrollHdl
)
261 void SvxIconChoiceCtrl_Impl::FontModified()
264 pDDDev
.disposeAndClear();
265 pDDBufDev
.disposeAndClear();
266 pDDTempDev
.disposeAndClear();
267 pEntryPaintDev
.disposeAndClear();
268 SetDefaultTextSize();
273 void SvxIconChoiceCtrl_Impl::InsertEntry( SvxIconChoiceCtrlEntry
* pEntry
, size_t nPos
,
277 aEntries
.insert( nPos
, pEntry
);
278 if( (nFlags
& F_ENTRYLISTPOS_VALID
) && nPos
>= aEntries
.size() - 1 )
279 pEntry
->nPos
= aEntries
.size() - 1;
281 nFlags
&= ~F_ENTRYLISTPOS_VALID
;
283 pZOrderList
->push_back( pEntry
);
287 Size
aSize( CalcBoundingSize( pEntry
) );
288 SetBoundingRect_Impl( pEntry
, *pPos
, aSize
);
289 SetEntryPos( pEntry
, *pPos
, false, true, true /*keep grid map*/ );
290 pEntry
->nFlags
|= SvxIconViewFlags::POS_MOVED
;
291 SetEntriesMoved( true );
295 // If the UpdateMode is true, don't set all bounding rectangles to
296 // 'to be checked', but only the bounding rectangle of the new entry.
297 // Thus, don't call InvalidateBoundingRect!
298 pEntry
->aRect
.Right() = LONG_MAX
;
301 FindBoundingRect( pEntry
);
302 Rectangle
aOutputArea( GetOutputRect() );
303 pGridMap
->OccupyGrids( pEntry
);
304 if( !aOutputArea
.IsOver( pEntry
->aRect
) )
305 return; // is invisible
306 pView
->Invalidate( pEntry
->aRect
);
309 InvalidateBoundingRect( pEntry
->aRect
);
313 void SvxIconChoiceCtrl_Impl::CreateAutoMnemonics( MnemonicGenerator
* _pGenerator
)
315 boost::scoped_ptr
< MnemonicGenerator
> pAutoDeleteOwnGenerator
;
318 _pGenerator
= new MnemonicGenerator
;
319 pAutoDeleteOwnGenerator
.reset( _pGenerator
);
322 sal_uLong nEntryCount
= GetEntryCount();
325 // insert texts in generator
326 for( i
= 0; i
< nEntryCount
; ++i
)
328 DBG_ASSERT( GetEntry( i
), "-SvxIconChoiceCtrl_Impl::CreateAutoMnemonics(): more expected than provided!" );
330 _pGenerator
->RegisterMnemonic( GetEntry( i
)->GetText() );
333 // exchange texts with generated mnemonics
334 for( i
= 0; i
< nEntryCount
; ++i
)
336 SvxIconChoiceCtrlEntry
* pEntry
= GetEntry( i
);
337 OUString aTxt
= pEntry
->GetText();
339 OUString aNewText
= _pGenerator
->CreateMnemonic( aTxt
);
340 if( aNewText
!= aTxt
)
341 pEntry
->SetText( aNewText
);
345 Rectangle
SvxIconChoiceCtrl_Impl::GetOutputRect() const
347 Point
aOrigin( pView
->GetMapMode().GetOrigin() );
349 return Rectangle( aOrigin
, aOutputSize
);
352 void SvxIconChoiceCtrl_Impl::SetListPositions()
354 if( nFlags
& F_ENTRYLISTPOS_VALID
)
357 size_t nCount
= aEntries
.size();
358 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
360 SvxIconChoiceCtrlEntry
* pEntry
= aEntries
[ nCur
];
363 nFlags
|= F_ENTRYLISTPOS_VALID
;
366 void SvxIconChoiceCtrl_Impl::SelectEntry( SvxIconChoiceCtrlEntry
* pEntry
, bool bSelect
,
367 bool bCallHdl
, bool bAdd
, bool bSyncPaint
)
369 if( eSelectionMode
== NO_SELECTION
)
374 if ( 0 == ( nFlags
& F_CLEARING_SELECTION
) )
376 nFlags
|= F_CLEARING_SELECTION
;
377 DeselectAllBut( pEntry
, true );
378 nFlags
&= ~F_CLEARING_SELECTION
;
381 if( pEntry
->IsSelected() != bSelect
)
384 SvxIconViewFlags nEntryFlags
= pEntry
->GetFlags();
387 nEntryFlags
|= SvxIconViewFlags::SELECTED
;
388 pEntry
->AssignFlags( nEntryFlags
);
391 CallSelectHandler( pEntry
);
395 nEntryFlags
&= ~( SvxIconViewFlags::SELECTED
);
396 pEntry
->AssignFlags( nEntryFlags
);
399 CallSelectHandler( 0 );
401 EntrySelected( pEntry
, bSelect
, bSyncPaint
);
405 void SvxIconChoiceCtrl_Impl::EntrySelected(SvxIconChoiceCtrlEntry
* pEntry
, bool bSelect
, bool /*bSyncPaint*/)
407 // When using SingleSelection, make sure that the cursor is always placed
408 // over the (only) selected entry. (But only if a cursor exists.)
409 if (bSelect
&& pCursor
&&
410 eSelectionMode
== SINGLE_SELECTION
&&
416 // Not when dragging though, else the loop in SelectRect doesn't work
418 if (!(nFlags
& F_SELECTING_RECT
))
422 if (pEntry
== pCursor
)
424 pView
->Invalidate(CalcFocusRect(pEntry
));
425 if (pEntry
== pCursor
)
429 // #i101012# emit vcl event LISTBOX_SELECT only in case that the given entry is selected.
432 CallEventListeners(VCLEVENT_LISTBOX_SELECT
, pEntry
);
436 void SvxIconChoiceCtrl_Impl::ResetVirtSize()
439 aVirtOutputSize
.Width() = 0;
440 aVirtOutputSize
.Height() = 0;
441 const size_t nCount
= aEntries
.size();
442 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
444 SvxIconChoiceCtrlEntry
* pCur
= aEntries
[ nCur
];
445 pCur
->ClearFlags( SvxIconViewFlags::POS_MOVED
);
446 if( pCur
->IsPosLocked() )
448 // adapt (among others) VirtSize
449 if( !IsBoundingRectValid( pCur
->aRect
) )
450 FindBoundingRect( pCur
);
452 AdjustVirtSize( pCur
->aRect
);
455 InvalidateBoundingRect( pCur
->aRect
);
458 if( !(nWinBits
& (WB_NOVSCROLL
| WB_NOHSCROLL
)) )
460 Size
aRealOutputSize( pView
->GetOutputSizePixel() );
461 if( aVirtOutputSize
.Width() < aRealOutputSize
.Width() ||
462 aVirtOutputSize
.Height() < aRealOutputSize
.Height() )
464 sal_uLong nGridCount
= IcnGridMap_Impl::GetGridCount(
465 aRealOutputSize
, (sal_uInt16
)nGridDX
, (sal_uInt16
)nGridDY
);
466 if( nGridCount
< nCount
)
468 if( nWinBits
& WB_ALIGN_TOP
)
469 nMaxVirtWidth
= aRealOutputSize
.Width() - nVerSBarWidth
;
470 else // WB_ALIGN_LEFT
471 nMaxVirtHeight
= aRealOutputSize
.Height() - nHorSBarHeight
;
481 void SvxIconChoiceCtrl_Impl::AdjustVirtSize( const Rectangle
& rRect
)
483 long nHeightOffs
= 0;
486 if( aVirtOutputSize
.Width() < (rRect
.Right()+LROFFS_WINBORDER
) )
487 nWidthOffs
= (rRect
.Right()+LROFFS_WINBORDER
) - aVirtOutputSize
.Width();
489 if( aVirtOutputSize
.Height() < (rRect
.Bottom()+TBOFFS_WINBORDER
) )
490 nHeightOffs
= (rRect
.Bottom()+TBOFFS_WINBORDER
) - aVirtOutputSize
.Height();
492 if( nWidthOffs
|| nHeightOffs
)
495 aVirtOutputSize
.Width() += nWidthOffs
;
496 aRange
.Max() = aVirtOutputSize
.Width();
497 aHorSBar
->SetRange( aRange
);
499 aVirtOutputSize
.Height() += nHeightOffs
;
500 aRange
.Max() = aVirtOutputSize
.Height();
501 aVerSBar
->SetRange( aRange
);
504 pGridMap
->OutputSizeChanged();
510 void SvxIconChoiceCtrl_Impl::InitPredecessors()
512 DBG_ASSERT(!pHead
,"SvxIconChoiceCtrl_Impl::InitPredecessors() >> Already initialized");
513 size_t nCount
= aEntries
.size();
516 SvxIconChoiceCtrlEntry
* pPrev
= aEntries
[ 0 ];
517 for( size_t nCur
= 1; nCur
<= nCount
; nCur
++ )
519 pPrev
->ClearFlags( SvxIconViewFlags::POS_LOCKED
| SvxIconViewFlags::POS_MOVED
|
520 SvxIconViewFlags::PRED_SET
);
522 SvxIconChoiceCtrlEntry
* pNext
;
524 pNext
= aEntries
[ 0 ];
526 pNext
= aEntries
[ nCur
];
527 pPrev
->pflink
= pNext
;
528 pNext
->pblink
= pPrev
;
531 pHead
= aEntries
[ 0 ];
535 nFlags
&= ~F_MOVED_ENTRIES
;
538 void SvxIconChoiceCtrl_Impl::ClearPredecessors()
542 size_t nCount
= aEntries
.size();
543 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
545 SvxIconChoiceCtrlEntry
* pCur
= aEntries
[ nCur
];
548 pCur
->ClearFlags( SvxIconViewFlags::PRED_SET
);
554 void SvxIconChoiceCtrl_Impl::Arrange( bool bKeepPredecessors
, long nSetMaxVirtWidth
, long nSetMaxVirtHeight
)
556 if ( nSetMaxVirtWidth
!= 0 )
557 nMaxVirtWidth
= nSetMaxVirtWidth
;
559 nMaxVirtWidth
= aOutputSize
.Width();
561 if ( nSetMaxVirtHeight
!= 0 )
562 nMaxVirtHeight
= nSetMaxVirtHeight
;
564 nMaxVirtHeight
= aOutputSize
.Height();
566 ImpArrange( bKeepPredecessors
);
569 void SvxIconChoiceCtrl_Impl::ImpArrange( bool bKeepPredecessors
)
571 static Point aEmptyPoint
;
573 bool bOldUpdate
= bUpdateMode
;
574 Rectangle
aCurOutputArea( GetOutputRect() );
575 if( (nWinBits
& WB_SMART_ARRANGE
) && aCurOutputArea
.TopLeft() != aEmptyPoint
)
577 aAutoArrangeIdle
.Stop();
578 nFlags
&= ~F_MOVED_ENTRIES
;
579 nFlags
|= F_ARRANGING
;
583 if( !bKeepPredecessors
)
585 bBoundRectsDirty
= false;
586 SetOrigin( Point() );
588 RecalcAllBoundingRectsSmart();
589 // TODO: the invalidation in the detail view should be more intelligent
590 //if( !(nWinBits & WB_DETAILS ))
591 pView
->Invalidate( INVALIDATE_NOCHILDREN
);
592 nFlags
&= ~F_ARRANGING
;
593 if( (nWinBits
& WB_SMART_ARRANGE
) && aCurOutputArea
.TopLeft() != aEmptyPoint
)
595 MakeVisible( aCurOutputArea
);
596 SetUpdateMode( bOldUpdate
);
601 void SvxIconChoiceCtrl_Impl::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
)
603 bEndScrollInvalidate
= false;
605 #if defined(OV_DRAWGRID)
606 Color
aOldColor (rRenderContext
.GetLineColor());
607 Color
aColor(COL_BLACK
);
608 rRenderContext
.SetLineColor( aColor
);
609 Point
aOffs(rRenderContext
.GetMapMode().GetOrigin());
610 Size
aXSize(GetOutputSizePixel());
612 Point
aStart(LROFFS_WINBORDER
, 0);
613 Point
aEnd(LROFFS_WINBORDER
, aXSize
.Height());
616 rRenderContext
.DrawLine(aStart
, aEnd
);
619 Point
aStart(0, TBOFFS_WINBORDER
);
620 Point
aEnd(aXSize
.Width(), TBOFFS_WINBORDER
);
623 rRenderContext
.DrawLine(aStart
, aEnd
);
626 for (long nDX
= nGridDX
; nDX
<= aXSize
.Width(); nDX
+= nGridDX
)
628 Point
aStart( nDX
+LROFFS_WINBORDER
, 0 );
629 Point
aEnd( nDX
+LROFFS_WINBORDER
, aXSize
.Height());
632 rRenderContext
.DrawLine(aStart
, aEnd
);
634 for (long nDY
= nGridDY
; nDY
<= aXSize
.Height(); nDY
+= nGridDY
)
636 Point
aStart(0, nDY
+ TBOFFS_WINBORDER
);
637 Point
aEnd(aXSize
.Width(), nDY
+ TBOFFS_WINBORDER
);
640 rRenderContext
.DrawLine(aStart
, aEnd
);
642 rRenderContext
.SetLineColor(aOldColor
);
646 if (!aEntries
.size())
650 // set cursor to item with focus-flag
652 for (sal_uLong i
= 0; i
< pView
->GetEntryCount() && !bfound
; i
++)
654 SvxIconChoiceCtrlEntry
* pEntry
= pView
->GetEntry (i
);
655 if (pEntry
->IsFocused())
663 pCursor
= aEntries
[ 0 ];
666 size_t nCount
= pZOrderList
->size();
670 rRenderContext
.Push(PushFlags::CLIPREGION
);
671 rRenderContext
.SetClipRegion(vcl::Region(rRect
));
673 SvxIconChoiceCtrlEntryList_impl
* pNewZOrderList
= new SvxIconChoiceCtrlEntryList_impl();
674 boost::scoped_ptr
<SvxIconChoiceCtrlEntryList_impl
> pPaintedEntries(new SvxIconChoiceCtrlEntryList_impl());
679 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[nPos
];
680 const Rectangle
& rBoundRect
= GetEntryBoundRect(pEntry
);
681 if (rRect
.IsOver(rBoundRect
))
683 PaintEntry(pEntry
, rBoundRect
.TopLeft(), rRenderContext
, true);
684 // set entries to Top if they are being repainted
685 pPaintedEntries
->push_back(pEntry
);
688 pNewZOrderList
->push_back(pEntry
);
694 pZOrderList
= pNewZOrderList
;
695 nCount
= pPaintedEntries
->size();
698 for (size_t nCur
= 0; nCur
< nCount
; nCur
++)
699 pZOrderList
->push_back((*pPaintedEntries
)[nCur
]);
701 pPaintedEntries
.reset();
703 rRenderContext
.Pop();
706 void SvxIconChoiceCtrl_Impl::RepaintEntries(SvxIconViewFlags nEntryFlagsMask
)
708 const size_t nCount
= pZOrderList
->size();
712 Rectangle
aOutRect(GetOutputRect());
713 for (size_t nCur
= 0; nCur
< nCount
; nCur
++)
715 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[nCur
];
716 if (pEntry
->GetFlags() & nEntryFlagsMask
)
718 const Rectangle
& rBoundRect
= GetEntryBoundRect(pEntry
);
719 if (aOutRect
.IsOver(rBoundRect
))
720 pView
->Invalidate(rBoundRect
);
725 void SvxIconChoiceCtrl_Impl::InitScrollBarBox()
727 aScrBarBox
->SetSizePixel( Size(nVerSBarWidth
-1, nHorSBarHeight
-1) );
728 Size
aSize( pView
->GetOutputSizePixel() );
729 aScrBarBox
->SetPosPixel( Point(aSize
.Width()-nVerSBarWidth
+1, aSize
.Height()-nHorSBarHeight
+1));
732 bool SvxIconChoiceCtrl_Impl::MouseButtonDown( const MouseEvent
& rMEvt
)
734 bool bHandled
= true;
735 bHighlightFramePressed
= false;
737 bool bGotFocus
= (!pView
->HasFocus() && !(nWinBits
& WB_NOPOINTERFOCUS
));
738 if( !(nWinBits
& WB_NOPOINTERFOCUS
) )
741 Point
aDocPos( rMEvt
.GetPosPixel() );
742 if(aDocPos
.X()>=aOutputSize
.Width() || aDocPos
.Y()>=aOutputSize
.Height())
745 SvxIconChoiceCtrlEntry
* pEntry
= GetEntry( aDocPos
, true );
747 MakeEntryVisible( pEntry
, false );
749 if( rMEvt
.IsShift() && eSelectionMode
!= SINGLE_SELECTION
)
752 SetCursor_Impl( pCursor
, pEntry
, rMEvt
.IsMod1(), rMEvt
.IsShift(), true);
756 if( pAnchor
&& (rMEvt
.IsShift() || rMEvt
.IsMod1())) // keyboard selection?
758 DBG_ASSERT(eSelectionMode
!= SINGLE_SELECTION
,"Invalid selection mode");
760 nFlags
|= F_ADD_MODE
;
762 if( rMEvt
.IsShift() )
764 Rectangle
aRect( GetEntryBoundRect( pAnchor
));
766 aRect
.Union( GetEntryBoundRect( pEntry
) );
769 Rectangle
aTempRect( aDocPos
, Size(1,1));
770 aRect
.Union( aTempRect
);
772 aCurSelectionRect
= aRect
;
773 SelectRect( aRect
, (nFlags
& F_ADD_MODE
)!=0, &aSelectedRectList
);
775 else if( rMEvt
.IsMod1() )
777 AddSelectedRect( aCurSelectionRect
);
779 aCurSelectionRect
.SetPos( aDocPos
);
782 if( !pEntry
&& !(nWinBits
& WB_NODRAGSELECTION
))
783 pView
->StartTracking( STARTTRACK_SCROLLREPEAT
);
790 if( eSelectionMode
== MULTIPLE_SELECTION
)
792 if( !rMEvt
.IsMod1() ) // Ctrl
797 ClearSelectedRectList();
801 nFlags
|= F_ADD_MODE
;
802 aCurSelectionRect
.SetPos( aDocPos
);
803 pView
->StartTracking( STARTTRACK_SCROLLREPEAT
);
810 bool bSelected
= pEntry
->IsSelected();
811 bool bEditingEnabled
= IsEntryEditingEnabled();
813 if( rMEvt
.GetClicks() == 2 )
815 DeselectAllBut( pEntry
);
816 SelectEntry( pEntry
, true, true, false, true );
823 if( rMEvt
.IsMod2() ) // Alt?
825 if( bEntryEditingEnabled
&& pEntry
&&
826 pEntry
->IsSelected())
831 else if( eSelectionMode
== SINGLE_SELECTION
)
833 DeselectAllBut( pEntry
);
835 if( bEditingEnabled
&& bSelected
&& !rMEvt
.GetModifier() &&
836 rMEvt
.IsLeft() && IsTextHit( pEntry
, aDocPos
) )
838 nFlags
|= F_START_EDITTIMER_IN_MOUSEUP
;
841 else if( eSelectionMode
== NO_SELECTION
)
843 if( rMEvt
.IsLeft() && (nWinBits
& WB_HIGHLIGHTFRAME
) )
845 pCurHighlightFrame
= 0; // force repaint of frame
846 bHighlightFramePressed
= true;
847 SetEntryHighlightFrame( pEntry
, true );
852 if( !rMEvt
.GetModifier() && rMEvt
.IsLeft() )
856 DeselectAllBut( pEntry
, true /* paint synchronously */ );
858 SelectEntry( pEntry
, true, true, false, true );
862 // deselect only in the Up, if the Move happened via D&D!
863 nFlags
|= F_DOWN_DESELECT
;
864 if( bEditingEnabled
&& IsTextHit( pEntry
, aDocPos
) &&
867 nFlags
|= F_START_EDITTIMER_IN_MOUSEUP
;
871 else if( rMEvt
.IsMod1() )
872 nFlags
|= F_DOWN_CTRL
;
878 bool SvxIconChoiceCtrl_Impl::MouseButtonUp( const MouseEvent
& rMEvt
)
880 bool bHandled
= false;
881 if( rMEvt
.IsRight() && (nFlags
& (F_DOWN_CTRL
| F_DOWN_DESELECT
) ))
883 nFlags
&= ~(F_DOWN_CTRL
| F_DOWN_DESELECT
);
887 Point
aDocPos( rMEvt
.GetPosPixel() );
889 SvxIconChoiceCtrlEntry
* pDocEntry
= GetEntry( aDocPos
);
892 if( nFlags
& F_DOWN_CTRL
)
894 // Ctrl & MultiSelection
895 ToggleSelection( pDocEntry
);
896 SetCursor( pDocEntry
);
899 else if( nFlags
& F_DOWN_DESELECT
)
901 DeselectAllBut( pDocEntry
);
902 SetCursor( pDocEntry
);
903 SelectEntry( pDocEntry
, true, true, false, true );
908 nFlags
&= ~(F_DOWN_CTRL
| F_DOWN_DESELECT
);
909 if( nFlags
& F_START_EDITTIMER_IN_MOUSEUP
)
913 nFlags
&= ~F_START_EDITTIMER_IN_MOUSEUP
;
916 if((nWinBits
& WB_HIGHLIGHTFRAME
) && bHighlightFramePressed
&& pCurHighlightFrame
)
919 SvxIconChoiceCtrlEntry
* pEntry
= pCurHighlightFrame
;
920 pCurHighlightFrame
= 0; // force repaint of frame
921 bHighlightFramePressed
= false;
922 SetEntryHighlightFrame( pEntry
, true );
924 pHdlEntry
= pCurHighlightFrame
;
928 SvxIconChoiceCtrlEntry
* pOldCursor
= pCursor
;
929 SetCursor_Impl( pOldCursor
, pHdlEntry
, false, false, true );
936 bool SvxIconChoiceCtrl_Impl::MouseMove( const MouseEvent
& rMEvt
)
938 const Point
aDocPos( pView
->PixelToLogic(rMEvt
.GetPosPixel()) );
940 if( pView
->IsTracking() )
942 else if( nWinBits
& WB_HIGHLIGHTFRAME
)
944 SvxIconChoiceCtrlEntry
* pEntry
= GetEntry( aDocPos
, true );
945 SetEntryHighlightFrame( pEntry
);
952 void SvxIconChoiceCtrl_Impl::SetCursor_Impl( SvxIconChoiceCtrlEntry
* pOldCursor
,
953 SvxIconChoiceCtrlEntry
* pNewCursor
, bool bMod1
, bool bShift
, bool bPaintSync
)
957 SvxIconChoiceCtrlEntry
* pFilterEntry
= 0;
958 bool bDeselectAll
= false;
959 if( eSelectionMode
!= SINGLE_SELECTION
)
961 if( !bMod1
&& !bShift
)
963 else if( bShift
&& !bMod1
&& !pAnchor
)
966 pFilterEntry
= pOldCursor
;
970 DeselectAllBut( pFilterEntry
, bPaintSync
);
972 MakeEntryVisible( pNewCursor
);
973 SetCursor( pNewCursor
);
974 if( bMod1
&& !bShift
)
978 AddSelectedRect( pAnchor
, pOldCursor
);
985 pAnchor
= pOldCursor
;
986 if ( nWinBits
& WB_ALIGN_LEFT
)
987 SelectRange( pAnchor
, pNewCursor
, (nFlags
& F_ADD_MODE
)!=0 );
989 SelectRect(pAnchor
,pNewCursor
,(nFlags
& F_ADD_MODE
)!=0,&aSelectedRectList
);
993 SelectEntry( pCursor
, true, true, false, bPaintSync
);
994 aCurSelectionRect
= GetEntryBoundRect( pCursor
);
995 CallEventListeners( VCLEVENT_LISTBOX_SELECT
, pCursor
);
1000 bool SvxIconChoiceCtrl_Impl::KeyInput( const KeyEvent
& rKEvt
)
1004 bool bMod2
= rKEvt
.GetKeyCode().IsMod2();
1005 sal_Unicode cChar
= rKEvt
.GetCharCode();
1006 sal_uLong nPos
= (sal_uLong
)-1;
1007 if ( bMod2
&& cChar
&& IsMnemonicChar( cChar
, nPos
) )
1009 // shortcut is clicked
1010 SvxIconChoiceCtrlEntry
* pNewCursor
= GetEntry( nPos
);
1011 SvxIconChoiceCtrlEntry
* pOldCursor
= pCursor
;
1012 if ( pNewCursor
!= pOldCursor
)
1013 SetCursor_Impl( pOldCursor
, pNewCursor
, false, false, false );
1018 // no actions with <ALT>
1021 bool bKeyUsed
= true;
1022 bool bMod1
= rKEvt
.GetKeyCode().IsMod1();
1023 bool bShift
= rKEvt
.GetKeyCode().IsShift();
1025 if( eSelectionMode
== SINGLE_SELECTION
|| eSelectionMode
== NO_SELECTION
)
1032 nFlags
|= F_ADD_MODE
;
1034 SvxIconChoiceCtrlEntry
* pNewCursor
;
1035 SvxIconChoiceCtrlEntry
* pOldCursor
= pCursor
;
1037 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
1044 MakeEntryVisible( pCursor
);
1045 if( nCode
== KEY_UP
)
1046 pNewCursor
= pImpCursor
->GoUpDown(pCursor
,false);
1048 pNewCursor
= pImpCursor
->GoPageUpDown(pCursor
,false);
1049 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, true );
1052 Rectangle
aRect( GetEntryBoundRect( pCursor
) );
1055 aRect
.Bottom() -= aRect
.Top();
1057 MakeVisible( aRect
);
1061 if ( bChooseWithCursor
&& pNewCursor
!= NULL
)
1063 pHdlEntry
= pNewCursor
;//GetCurEntry();
1064 pCurHighlightFrame
= pHdlEntry
;
1066 pCurHighlightFrame
= NULL
;
1075 if( nCode
== KEY_DOWN
)
1076 pNewCursor
=pImpCursor
->GoUpDown( pCursor
,true );
1078 pNewCursor
=pImpCursor
->GoPageUpDown( pCursor
,true );
1079 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, true );
1081 if ( bChooseWithCursor
&& pNewCursor
!= NULL
)
1083 pHdlEntry
= pNewCursor
;//GetCurEntry();
1084 pCurHighlightFrame
= pHdlEntry
;
1086 pCurHighlightFrame
= NULL
;
1094 pNewCursor
=pImpCursor
->GoLeftRight(pCursor
,true );
1095 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, true );
1102 MakeEntryVisible( pCursor
);
1103 pNewCursor
= pImpCursor
->GoLeftRight(pCursor
,false );
1104 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, true );
1107 Rectangle
aRect( GetEntryBoundRect(pCursor
));
1110 aRect
.Right() -= aRect
.Left();
1112 MakeVisible( aRect
);
1119 if( !bMod1
&& !bShift
)
1120 EditTimeoutHdl( 0 );
1126 if( rKEvt
.GetKeyCode().IsShift() )
1128 if( nFlags
& F_ADD_MODE
)
1129 nFlags
&= (~F_ADD_MODE
);
1131 nFlags
|= F_ADD_MODE
;
1138 if( pCursor
&& eSelectionMode
!= SINGLE_SELECTION
)
1142 //SelectAll( false );
1144 ClearSelectedRectList();
1146 // click Icon with spacebar
1147 SetEntryHighlightFrame( GetCurEntry(), true );
1149 pHdlEntry
= pCurHighlightFrame
;
1150 pCurHighlightFrame
=0;
1153 ToggleSelection( pCursor
);
1159 if( rKEvt
.GetKeyCode().IsShift() )
1162 pView
->SetEntryTextMode( IcnShowTextFull
, pCursor
);
1164 if( rKEvt
.GetKeyCode().IsMod1() )
1167 pView
->SetEntryTextMode( IcnShowTextShort
, pCursor
);
1175 if( bMod1
&& (eSelectionMode
!= SINGLE_SELECTION
))
1192 if( pCursor
&& bEntryEditingEnabled
)
1193 /*pView->*/EditEntry( pCursor
);
1202 pNewCursor
= aEntries
[ aEntries
.size() - 1 ];
1203 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, true );
1210 pNewCursor
= aEntries
[ 0 ];
1211 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, true );
1222 // recalculate TopLeft of scrollbars (but not their sizes!)
1223 void SvxIconChoiceCtrl_Impl::PositionScrollBars( long nRealWidth
, long nRealHeight
)
1225 // horizontal scrollbar
1226 Point
aPos( 0, nRealHeight
);
1227 aPos
.Y() -= nHorSBarHeight
;
1229 if( aHorSBar
->GetPosPixel() != aPos
)
1230 aHorSBar
->SetPosPixel( aPos
);
1232 // vertical scrollbar
1233 aPos
.X() = nRealWidth
; aPos
.Y() = 0;
1234 aPos
.X() -= nVerSBarWidth
;
1238 if( aVerSBar
->GetPosPixel() != aPos
)
1239 aVerSBar
->SetPosPixel( aPos
);
1242 void SvxIconChoiceCtrl_Impl::AdjustScrollBars( bool )
1244 long nVirtHeight
= aVirtOutputSize
.Height();
1245 long nVirtWidth
= aVirtOutputSize
.Width();
1247 Size
aOSize( pView
->Control::GetOutputSizePixel() );
1248 long nRealHeight
= aOSize
.Height();
1249 long nRealWidth
= aOSize
.Width();
1251 PositionScrollBars( nRealWidth
, nRealHeight
);
1253 const MapMode
& rMapMode
= pView
->GetMapMode();
1254 Point
aOrigin( rMapMode
.GetOrigin() );
1257 if( nRealWidth
> nVirtWidth
)
1258 nVisibleWidth
= nVirtWidth
+ aOrigin
.X();
1260 nVisibleWidth
= nRealWidth
;
1262 long nVisibleHeight
;
1263 if( nRealHeight
> nVirtHeight
)
1264 nVisibleHeight
= nVirtHeight
+ aOrigin
.Y();
1266 nVisibleHeight
= nRealHeight
;
1268 bool bVerSBar
= ( nWinBits
& WB_VSCROLL
) != 0;
1269 bool bHorSBar
= ( nWinBits
& WB_HSCROLL
) != 0;
1270 bool bNoVerSBar
= ( nWinBits
& WB_NOVSCROLL
) != 0;
1271 bool bNoHorSBar
= ( nWinBits
& WB_NOHSCROLL
) != 0;
1273 sal_uInt16 nResult
= 0;
1276 // activate vertical scrollbar?
1277 if( !bNoVerSBar
&& (bVerSBar
|| ( nVirtHeight
> nVisibleHeight
)) )
1280 nRealWidth
-= nVerSBarWidth
;
1282 if( nRealWidth
> nVirtWidth
)
1283 nVisibleWidth
= nVirtWidth
+ aOrigin
.X();
1285 nVisibleWidth
= nRealWidth
;
1287 nFlags
|= F_HOR_SBARSIZE_WITH_VBAR
;
1289 // activate horizontal scrollbar?
1290 if( !bNoHorSBar
&& (bHorSBar
|| (nVirtWidth
> nVisibleWidth
)) )
1293 nRealHeight
-= nHorSBarHeight
;
1295 if( nRealHeight
> nVirtHeight
)
1296 nVisibleHeight
= nVirtHeight
+ aOrigin
.Y();
1298 nVisibleHeight
= nRealHeight
;
1300 // do we need a vertical scrollbar after all?
1301 if( !(nResult
& 0x0001) && // only if not already there
1302 ( !bNoVerSBar
&& ((nVirtHeight
> nVisibleHeight
) || bVerSBar
)) )
1304 nResult
= 3; // both turned on
1305 nRealWidth
-= nVerSBarWidth
;
1307 if( nRealWidth
> nVirtWidth
)
1308 nVisibleWidth
= nVirtWidth
+ aOrigin
.X();
1310 nVisibleWidth
= nRealWidth
;
1312 nFlags
|= F_VER_SBARSIZE_WITH_HBAR
;
1317 // size vertical scrollbar
1318 long nThumb
= aVerSBar
->GetThumbPos();
1319 Size
aSize( nVerSBarWidth
, nRealHeight
);
1320 aSize
.Height() += 2;
1321 if( aSize
!= aVerSBar
->GetSizePixel() )
1322 aVerSBar
->SetSizePixel( aSize
);
1323 aVerSBar
->SetVisibleSize( nVisibleHeight
);
1324 aVerSBar
->SetPageSize( GetScrollBarPageSize( nVisibleHeight
));
1326 if( nResult
& 0x0001 )
1328 aVerSBar
->SetThumbPos( nThumb
);
1333 aVerSBar
->SetThumbPos( 0 );
1337 // size horizontal scrollbar
1338 nThumb
= aHorSBar
->GetThumbPos();
1339 aSize
.Width() = nRealWidth
;
1340 aSize
.Height() = nHorSBarHeight
;
1342 if( nResult
& 0x0001 ) // vertical scrollbar?
1347 if( aSize
!= aHorSBar
->GetSizePixel() )
1348 aHorSBar
->SetSizePixel( aSize
);
1349 aHorSBar
->SetVisibleSize( nVisibleWidth
);
1350 aHorSBar
->SetPageSize( GetScrollBarPageSize(nVisibleWidth
));
1351 if( nResult
& 0x0002 )
1353 aHorSBar
->SetThumbPos( nThumb
);
1358 aHorSBar
->SetThumbPos( 0 );
1362 aOutputSize
.Width() = nRealWidth
;
1363 if( nResult
& 0x0002 ) // horizontal scrollbar ?
1364 nRealHeight
++; // because lower border is clipped
1365 aOutputSize
.Height() = nRealHeight
;
1367 if( (nResult
& (0x0001|0x0002)) == (0x0001|0x0002) )
1373 void SvxIconChoiceCtrl_Impl::Resize()
1377 aOutputSize
= pView
->GetOutputSizePixel();
1378 pImpCursor
->Clear();
1379 pGridMap
->OutputSizeChanged();
1381 const Size
& rSize
= pView
->Control::GetOutputSizePixel();
1382 PositionScrollBars( rSize
.Width(), rSize
.Height() );
1383 // The scrollbars are shown/hidden asynchronously, so derived classes can
1384 // do an Arrange during Resize, without the scrollbars suddenly turning
1385 // on and off again.
1386 // If an event is already underway, we don't need to send a new one, at least
1387 // as long as there is only one event type.
1388 if ( ! nUserEventAdjustScrBars
)
1389 nUserEventAdjustScrBars
=
1390 Application::PostUserEvent( LINK( this, SvxIconChoiceCtrl_Impl
, UserEventHdl
),
1391 EVENTID_ADJUST_SCROLLBARS
);
1396 bool SvxIconChoiceCtrl_Impl::CheckHorScrollBar()
1398 if( !pZOrderList
|| !aHorSBar
->IsVisible() )
1400 const MapMode
& rMapMode
= pView
->GetMapMode();
1401 Point
aOrigin( rMapMode
.GetOrigin() );
1402 if(!( nWinBits
& WB_HSCROLL
) && !aOrigin
.X() )
1404 long nWidth
= aOutputSize
.Width();
1405 const size_t nCount
= pZOrderList
->size();
1406 long nMostRight
= 0;
1407 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
1409 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[ nCur
];
1410 long nRight
= GetEntryBoundRect(pEntry
).Right();
1411 if( nRight
> nWidth
)
1413 if( nRight
> nMostRight
)
1414 nMostRight
= nRight
;
1417 aOutputSize
.Height() += nHorSBarHeight
;
1418 aVirtOutputSize
.Width() = nMostRight
;
1419 aHorSBar
->SetThumbPos( 0 );
1421 aRange
.Max() = nMostRight
- 1;
1422 aHorSBar
->SetRange( aRange
);
1423 if( aVerSBar
->IsVisible() )
1425 Size
aSize( aVerSBar
->GetSizePixel());
1426 aSize
.Height() += nHorSBarHeight
;
1427 aVerSBar
->SetSizePixel( aSize
);
1434 bool SvxIconChoiceCtrl_Impl::CheckVerScrollBar()
1436 if( !pZOrderList
|| !aVerSBar
->IsVisible() )
1438 const MapMode
& rMapMode
= pView
->GetMapMode();
1439 Point
aOrigin( rMapMode
.GetOrigin() );
1440 if(!( nWinBits
& WB_VSCROLL
) && !aOrigin
.Y() )
1443 long nHeight
= aOutputSize
.Height();
1444 const size_t nCount
= pZOrderList
->size();
1445 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
1447 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[ nCur
];
1448 long nBottom
= GetEntryBoundRect(pEntry
).Bottom();
1449 if( nBottom
> nHeight
)
1451 if( nBottom
> nDeepest
)
1455 aOutputSize
.Width() += nVerSBarWidth
;
1456 aVirtOutputSize
.Height() = nDeepest
;
1457 aVerSBar
->SetThumbPos( 0 );
1459 aRange
.Max() = nDeepest
- 1;
1460 aVerSBar
->SetRange( aRange
);
1461 if( aHorSBar
->IsVisible() )
1463 Size
aSize( aHorSBar
->GetSizePixel());
1464 aSize
.Width() += nVerSBarWidth
;
1465 aHorSBar
->SetSizePixel( aSize
);
1473 // hides scrollbars if they're unnecessary
1474 void SvxIconChoiceCtrl_Impl::CheckScrollBars()
1476 CheckVerScrollBar();
1477 if( CheckHorScrollBar() )
1478 CheckVerScrollBar();
1479 if( aVerSBar
->IsVisible() && aHorSBar
->IsVisible() )
1486 void SvxIconChoiceCtrl_Impl::GetFocus()
1488 RepaintEntries( SvxIconViewFlags::SELECTED
);
1491 pCursor
->SetFlags( SvxIconViewFlags::FOCUSED
);
1496 void SvxIconChoiceCtrl_Impl::LoseFocus()
1500 pCursor
->ClearFlags( SvxIconViewFlags::FOCUSED
);
1501 ShowCursor( false );
1504 // pView->Invalidate ( aFocus.aRect );
1506 RepaintEntries( SvxIconViewFlags::SELECTED
);
1509 void SvxIconChoiceCtrl_Impl::SetUpdateMode( bool bUpdate
)
1511 if( bUpdate
!= bUpdateMode
)
1513 bUpdateMode
= bUpdate
;
1517 pImpCursor
->Clear();
1519 pView
->Invalidate(INVALIDATE_NOCHILDREN
);
1524 // priorities of the emphasis: bDropTarget => bCursored => bSelected
1525 void SvxIconChoiceCtrl_Impl::PaintEmphasis(const Rectangle
& rTextRect
, const Rectangle
& rImageRect
, bool bSelected
,
1526 bool bDropTarget
, bool bCursored
, vcl::RenderContext
& rRenderContext
, bool bIsBackgroundPainted
)
1528 static Color
aTransparent(COL_TRANSPARENT
);
1530 const StyleSettings
& rSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1531 Color
aOldFillColor(rRenderContext
.GetFillColor());
1533 bool bSolidTextRect
= false;
1534 bool bSolidImageRect
= false;
1536 if(bDropTarget
&& (eSelectionMode
!= NO_SELECTION
))
1538 rRenderContext
.SetFillColor(rSettings
.GetHighlightColor());
1539 bSolidTextRect
= true;
1540 bSolidImageRect
= true;
1544 if (!bSelected
|| bCursored
)
1546 const Color
& rFillColor
= rRenderContext
.GetFont().GetFillColor();
1547 rRenderContext
.SetFillColor(rFillColor
);
1548 if (rFillColor
!= aTransparent
)
1549 bSolidTextRect
= true;
1553 // draw text rectangle
1554 if (!bSolidTextRect
)
1556 if (!bIsBackgroundPainted
)
1557 rRenderContext
.Erase(rTextRect
);
1561 Color aOldLineColor
;
1564 aOldLineColor
= rRenderContext
.GetLineColor();
1565 rRenderContext
.SetLineColor(Color(COL_GRAY
));
1567 rRenderContext
.DrawRect(rTextRect
);
1569 rRenderContext
.SetLineColor(aOldLineColor
);
1572 // draw image rectangle
1573 if (!bSolidImageRect
)
1575 if (!bIsBackgroundPainted
)
1576 rRenderContext
.Erase(rImageRect
);
1579 rRenderContext
.SetFillColor(aOldFillColor
);
1583 void SvxIconChoiceCtrl_Impl::PaintItem(const Rectangle
& rRect
,
1584 IcnViewFieldType eItem
, SvxIconChoiceCtrlEntry
* pEntry
, sal_uInt16 nPaintFlags
,
1585 vcl::RenderContext
& rRenderContext
, const OUString
* pStr
, vcl::ControlLayoutData
* _pLayoutData
)
1587 if (eItem
== IcnViewFieldTypeText
)
1591 aText
= SvtIconChoiceCtrl::GetEntryText(pEntry
, false);
1597 rRenderContext
.DrawText(rRect
, aText
, nCurTextDrawFlags
, &_pLayoutData
->m_aUnicodeBoundRects
, &_pLayoutData
->m_aDisplayText
);
1601 Color aOldFontColor
= rRenderContext
.GetTextColor();
1602 if (pView
->AutoFontColor())
1604 Color
aBkgColor(rRenderContext
.GetBackground().GetColor());
1606 sal_uInt16 nColor
= (aBkgColor
.GetRed() + aBkgColor
.GetGreen() + aBkgColor
.GetBlue()) / 3;
1608 aFontColor
.SetColor(COL_BLACK
);
1610 aFontColor
.SetColor(COL_WHITE
);
1611 rRenderContext
.SetTextColor(aFontColor
);
1614 rRenderContext
.DrawText(rRect
, aText
, nCurTextDrawFlags
);
1616 if (pView
->AutoFontColor())
1617 rRenderContext
.SetTextColor(aOldFontColor
);
1619 if (pEntry
->IsFocused())
1621 Rectangle
aRect (CalcFocusRect(pEntry
));
1623 DrawFocusRect(rRenderContext
);
1629 Point
aPos(rRect
.TopLeft());
1630 if (nPaintFlags
& PAINTFLAG_HOR_CENTERED
)
1631 aPos
.X() += (rRect
.GetWidth() - aImageSize
.Width()) / 2;
1632 if (nPaintFlags
& PAINTFLAG_VER_CENTERED
)
1633 aPos
.Y() += (rRect
.GetHeight() - aImageSize
.Height()) / 2;
1634 SvtIconChoiceCtrl::DrawEntryImage(pEntry
, aPos
, rRenderContext
);
1638 void SvxIconChoiceCtrl_Impl::PaintEntry(SvxIconChoiceCtrlEntry
* pEntry
, const Point
& rPos
, vcl::RenderContext
& rRenderContext
, bool bIsBackgroundPainted
)
1640 bool bSelected
= false;
1642 if (eSelectionMode
!= NO_SELECTION
)
1643 bSelected
= pEntry
->IsSelected();
1645 bool bCursored
= pEntry
->IsCursored();
1646 bool bDropTarget
= pEntry
->IsDropTarget();
1647 bool bNoEmphasis
= pEntry
->IsBlockingEmphasis();
1649 rRenderContext
.Push(PushFlags::FONT
| PushFlags::TEXTCOLOR
);
1651 OUString
aEntryText(SvtIconChoiceCtrl::GetEntryText(pEntry
, false));
1652 Rectangle
aTextRect(CalcTextRect(pEntry
, &rPos
, false, &aEntryText
));
1653 Rectangle
aBmpRect(CalcBmpRect(pEntry
, &rPos
));
1655 bool bShowSelection
= ((bSelected
&& !bCursored
) && !bNoEmphasis
&& (eSelectionMode
!= NO_SELECTION
));
1657 bool bActiveSelection
= (0 != (nWinBits
& WB_NOHIDESELECTION
)) || pView
->HasFocus();
1661 const StyleSettings
& rSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1662 vcl::Font
aNewFont(rRenderContext
.GetFont());
1664 // font fill colors that are attributed "hard" need corresponding "hard"
1665 // attributed highlight colors
1666 if ((nWinBits
& WB_NOHIDESELECTION
) || pView
->HasFocus())
1667 aNewFont
.SetFillColor(rSettings
.GetHighlightColor());
1669 aNewFont
.SetFillColor(rSettings
.GetDeactiveColor());
1671 Color aWinCol
= rSettings
.GetWindowTextColor();
1672 if (!bActiveSelection
&& rSettings
.GetFaceColor().IsBright() == aWinCol
.IsBright())
1673 aNewFont
.SetColor(rSettings
.GetWindowTextColor());
1675 aNewFont
.SetColor(rSettings
.GetHighlightTextColor());
1677 rRenderContext
.SetFont(aNewFont
);
1679 rRenderContext
.SetFillColor(rRenderContext
.GetBackground().GetColor());
1680 rRenderContext
.DrawRect(CalcFocusRect(pEntry
));
1681 rRenderContext
.SetFillColor();
1684 bool bResetClipRegion
= false;
1685 if (!rRenderContext
.IsClipRegion() && (aVerSBar
->IsVisible() || aHorSBar
->IsVisible()))
1687 Rectangle
aOutputArea(GetOutputRect());
1688 if (aOutputArea
.IsOver(aTextRect
) || aOutputArea
.IsOver(aBmpRect
))
1690 rRenderContext
.SetClipRegion(vcl::Region(aOutputArea
));
1691 bResetClipRegion
= true;
1695 bool bLargeIconMode
= WB_ICON
== ( nWinBits
& (VIEWMODE_MASK
) );
1696 sal_uInt16 nBmpPaintFlags
= PAINTFLAG_VER_CENTERED
;
1698 nBmpPaintFlags
|= PAINTFLAG_HOR_CENTERED
;
1699 sal_uInt16 nTextPaintFlags
= bLargeIconMode
? PAINTFLAG_HOR_CENTERED
: PAINTFLAG_VER_CENTERED
;
1702 PaintEmphasis(aTextRect
, aBmpRect
, bSelected
, bDropTarget
, bCursored
, rRenderContext
, bIsBackgroundPainted
);
1704 if ( bShowSelection
)
1705 vcl::RenderTools::DrawSelectionBackground(rRenderContext
, *pView
.get(), CalcFocusRect(pEntry
),
1706 bActiveSelection
? 1 : 2, false, true, false);
1709 PaintItem(aBmpRect
, IcnViewFieldTypeImage
, pEntry
, nBmpPaintFlags
, rRenderContext
);
1711 PaintItem(aTextRect
, IcnViewFieldTypeText
, pEntry
, nTextPaintFlags
, rRenderContext
);
1713 // draw highlight frame
1714 if (pEntry
== pCurHighlightFrame
&& !bNoEmphasis
)
1715 DrawHighlightFrame(rRenderContext
, CalcFocusRect(pEntry
), false);
1717 rRenderContext
.Pop();
1718 if (bResetClipRegion
)
1719 rRenderContext
.SetClipRegion();
1722 void SvxIconChoiceCtrl_Impl::SetEntryPos( SvxIconChoiceCtrlEntry
* pEntry
, const Point
& rPos
,
1723 bool bAdjustAtGrid
, bool bCheckScrollBars
, bool bKeepGridMap
)
1725 ShowCursor( false );
1726 Rectangle
aBoundRect( GetEntryBoundRect( pEntry
));
1727 pView
->Invalidate( aBoundRect
);
1729 if( !IsAutoArrange() )
1731 bool bAdjustVirtSize
= false;
1732 if( rPos
!= aBoundRect
.TopLeft() )
1735 pEntry
->aGridRect
.TopLeft() - pEntry
->aRect
.TopLeft() );
1736 pImpCursor
->Clear();
1739 aBoundRect
.SetPos( rPos
);
1740 pEntry
->aRect
= aBoundRect
;
1741 pEntry
->aGridRect
.SetPos( rPos
+ aGridOffs
);
1742 bAdjustVirtSize
= true;
1746 if( bAdjustVirtSize
)
1748 // By aligning the (in some cases newly positioned) entry, it
1749 // can become completely visible again, so that maybe we don't
1750 // need a scrollbar after all. To avoid suddenly turning the
1751 // scrollbar(s) on and then off again, we use the aligned
1752 // bounding rectangle of the entry to enlarge the virtual
1753 // output size. The virtual size has to be adapted, because
1754 // AdjustEntryAtGrid depends on it.
1755 const Rectangle
& rBoundRect
= GetEntryBoundRect( pEntry
);
1756 Rectangle
aCenterRect( CalcBmpRect( pEntry
, 0 ));
1757 Point
aNewPos( AdjustAtGrid( aCenterRect
, rBoundRect
) );
1758 Rectangle
aNewBoundRect( aNewPos
, pEntry
->aRect
.GetSize());
1759 AdjustVirtSize( aNewBoundRect
);
1760 bAdjustVirtSize
= false;
1762 AdjustEntryAtGrid( pEntry
);
1765 if( bAdjustVirtSize
)
1766 AdjustVirtSize( pEntry
->aRect
);
1768 if( bCheckScrollBars
&& bUpdateMode
)
1771 pView
->Invalidate( pEntry
->aRect
);
1772 pGridMap
->OccupyGrids( pEntry
);
1776 SvxIconChoiceCtrlEntry
* pPrev
= FindEntryPredecessor( pEntry
, rPos
);
1777 SetEntryPredecessor( pEntry
, pPrev
);
1778 aAutoArrangeIdle
.Start();
1783 void SvxIconChoiceCtrl_Impl::SetNoSelection()
1785 // block recursive calls via SelectEntry
1786 if( !(nFlags
& F_CLEARING_SELECTION
))
1788 nFlags
|= F_CLEARING_SELECTION
;
1789 DeselectAllBut( 0, true );
1790 nFlags
&= ~F_CLEARING_SELECTION
;
1794 SvxIconChoiceCtrlEntry
* SvxIconChoiceCtrl_Impl::GetEntry( const Point
& rDocPos
, bool bHit
)
1796 CheckBoundingRects();
1797 // search through z-order list from the end
1798 size_t nCount
= pZOrderList
->size();
1802 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[ nCount
];
1803 if( pEntry
->aRect
.IsInside( rDocPos
) )
1807 Rectangle aRect
= CalcBmpRect( pEntry
);
1809 aRect
.Bottom() += 3;
1812 if( aRect
.IsInside( rDocPos
) )
1814 aRect
= CalcTextRect( pEntry
);
1815 if( aRect
.IsInside( rDocPos
) )
1825 void SvxIconChoiceCtrl_Impl::MakeEntryVisible( SvxIconChoiceCtrlEntry
* pEntry
, bool bBound
)
1829 const Rectangle
& rRect
= GetEntryBoundRect( pEntry
);
1830 MakeVisible( rRect
);
1834 Rectangle aRect
= CalcBmpRect( pEntry
);
1835 aRect
.Union( CalcTextRect( pEntry
) );
1836 aRect
.Top() += TBOFFS_BOUND
;
1837 aRect
.Bottom() += TBOFFS_BOUND
;
1838 aRect
.Left() += LROFFS_BOUND
;
1839 aRect
.Right() += LROFFS_BOUND
;
1840 MakeVisible( aRect
);
1844 const Rectangle
& SvxIconChoiceCtrl_Impl::GetEntryBoundRect( SvxIconChoiceCtrlEntry
* pEntry
)
1846 if( !IsBoundingRectValid( pEntry
->aRect
))
1847 FindBoundingRect( pEntry
);
1848 return pEntry
->aRect
;
1851 Rectangle
SvxIconChoiceCtrl_Impl::CalcBmpRect( SvxIconChoiceCtrlEntry
* pEntry
, const Point
* pPos
)
1853 Rectangle aBound
= GetEntryBoundRect( pEntry
);
1855 aBound
.SetPos( *pPos
);
1856 Point
aPos( aBound
.TopLeft() );
1858 switch( nWinBits
& (VIEWMODE_MASK
) )
1862 aPos
.X() += ( aBound
.GetWidth() - aImageSize
.Width() ) / 2;
1863 return Rectangle( aPos
, aImageSize
);
1868 aPos
.Y() += ( aBound
.GetHeight() - aImageSize
.Height() ) / 2;
1869 //TODO: determine horizontal distance to bounding rectangle
1870 return Rectangle( aPos
, aImageSize
);
1873 OSL_FAIL("IconView: Viewmode not set");
1878 Rectangle
SvxIconChoiceCtrl_Impl::CalcTextRect( SvxIconChoiceCtrlEntry
* pEntry
,
1879 const Point
* pEntryPos
, bool bEdit
, const OUString
* pStr
)
1881 OUString aEntryText
;
1883 aEntryText
= SvtIconChoiceCtrl::GetEntryText( pEntry
, bEdit
);
1887 const Rectangle
aMaxTextRect( CalcMaxTextRect( pEntry
) );
1888 Rectangle
aBound( GetEntryBoundRect( pEntry
) );
1890 aBound
.SetPos( *pEntryPos
);
1892 Rectangle
aTextRect( aMaxTextRect
);
1894 aTextRect
= pView
->GetTextRect( aTextRect
, aEntryText
, nCurTextDrawFlags
);
1896 Size
aTextSize( aTextRect
.GetSize() );
1898 Point
aPos( aBound
.TopLeft() );
1899 long nBoundWidth
= aBound
.GetWidth();
1900 long nBoundHeight
= aBound
.GetHeight();
1902 switch( nWinBits
& (VIEWMODE_MASK
) )
1905 aPos
.Y() += aImageSize
.Height();
1906 aPos
.Y() += VER_DIST_BMP_STRING
;
1907 // at little more space when editing
1911 long nMinWidth
= (( (aImageSize
.Width()*10) / 100 ) * 2 ) +
1913 if( nMinWidth
> nBoundWidth
)
1914 nMinWidth
= nBoundWidth
;
1916 if( aTextSize
.Width() < nMinWidth
)
1917 aTextSize
.Width() = nMinWidth
;
1919 // when editing, overlap with the area below is allowed
1920 Size aOptSize
= aMaxTextRect
.GetSize();
1921 if( aOptSize
.Height() > aTextSize
.Height() )
1922 aTextSize
.Height() = aOptSize
.Height();
1924 aPos
.X() += (nBoundWidth
- aTextSize
.Width()) / 2;
1929 aPos
.X() += aImageSize
.Width();
1930 aPos
.X() += HOR_DIST_BMP_STRING
;
1931 aPos
.Y() += (nBoundHeight
- aTextSize
.Height()) / 2;
1934 return Rectangle( aPos
, aTextSize
);
1938 long SvxIconChoiceCtrl_Impl::CalcBoundingWidth( SvxIconChoiceCtrlEntry
* pEntry
) const
1940 long nStringWidth
= GetItemSize( pEntry
, IcnViewFieldTypeText
).Width();
1941 // nStringWidth += 2*LROFFS_TEXT;
1944 switch( nWinBits
& (VIEWMODE_MASK
) )
1947 nWidth
= std::max( nStringWidth
, aImageSize
.Width() );
1952 nWidth
= aImageSize
.Width();
1953 nWidth
+= HOR_DIST_BMP_STRING
;
1954 nWidth
+= nStringWidth
;
1960 long SvxIconChoiceCtrl_Impl::CalcBoundingHeight( SvxIconChoiceCtrlEntry
* pEntry
) const
1962 long nStringHeight
= GetItemSize( pEntry
, IcnViewFieldTypeText
).Height();
1965 switch( nWinBits
& (VIEWMODE_MASK
) )
1968 nHeight
= aImageSize
.Height();
1969 nHeight
+= VER_DIST_BMP_STRING
;
1970 nHeight
+= nStringHeight
;
1975 nHeight
= std::max( aImageSize
.Height(), nStringHeight
);
1978 if( nHeight
> nMaxBoundHeight
)
1980 const_cast<SvxIconChoiceCtrl_Impl
*>(this)->nMaxBoundHeight
= nHeight
;
1981 const_cast<SvxIconChoiceCtrl_Impl
*>(this)->aHorSBar
->SetLineSize( GetScrollBarLineSize() );
1982 const_cast<SvxIconChoiceCtrl_Impl
*>(this)->aVerSBar
->SetLineSize( GetScrollBarLineSize() );
1987 Size
SvxIconChoiceCtrl_Impl::CalcBoundingSize( SvxIconChoiceCtrlEntry
* pEntry
) const
1989 return Size( CalcBoundingWidth( pEntry
),
1990 CalcBoundingHeight( pEntry
) );
1993 void SvxIconChoiceCtrl_Impl::RecalcAllBoundingRectsSmart()
1995 nMaxBoundHeight
= 0;
1996 pZOrderList
->clear();
1998 SvxIconChoiceCtrlEntry
* pEntry
;
1999 const size_t nCount
= aEntries
.size();
2001 if( !IsAutoArrange() || !pHead
)
2003 for( nCur
= 0; nCur
< nCount
; nCur
++ )
2005 pEntry
= aEntries
[ nCur
];
2006 if( IsBoundingRectValid( pEntry
->aRect
))
2008 Size
aBoundSize( pEntry
->aRect
.GetSize() );
2009 if( aBoundSize
.Height() > nMaxBoundHeight
)
2010 nMaxBoundHeight
= aBoundSize
.Height();
2013 FindBoundingRect( pEntry
);
2014 pZOrderList
->push_back( pEntry
);
2021 while( nCur
!= nCount
)
2023 DBG_ASSERT(pEntry
->pflink
&&pEntry
->pblink
,"SvxIconChoiceCtrl_Impl::RecalcAllBoundingRect > Bad link(s)");
2024 if( IsBoundingRectValid( pEntry
->aRect
))
2026 Size
aBoundSize( pEntry
->aRect
.GetSize() );
2027 if( aBoundSize
.Height() > nMaxBoundHeight
)
2028 nMaxBoundHeight
= aBoundSize
.Height();
2031 FindBoundingRect( pEntry
);
2032 pZOrderList
->push_back( pEntry
);
2033 pEntry
= pEntry
->pflink
;
2040 void SvxIconChoiceCtrl_Impl::FindBoundingRect( SvxIconChoiceCtrlEntry
* pEntry
)
2042 DBG_ASSERT(!pEntry
->IsPosLocked(),"Locked entry pos in FindBoundingRect");
2043 if( pEntry
->IsPosLocked() && IsBoundingRectValid( pEntry
->aRect
) )
2045 AdjustVirtSize( pEntry
->aRect
);
2048 Size
aSize( CalcBoundingSize( pEntry
) );
2049 Point
aPos(pGridMap
->GetGridRect(pGridMap
->GetUnoccupiedGrid(true)).TopLeft());
2050 SetBoundingRect_Impl( pEntry
, aPos
, aSize
);
2053 void SvxIconChoiceCtrl_Impl::SetBoundingRect_Impl( SvxIconChoiceCtrlEntry
* pEntry
, const Point
& rPos
,
2054 const Size
& /*rBoundingSize*/ )
2056 Rectangle
aGridRect( rPos
, Size(nGridDX
, nGridDY
) );
2057 pEntry
->aGridRect
= aGridRect
;
2059 AdjustVirtSize( pEntry
->aRect
);
2060 pGridMap
->OccupyGrids( pEntry
);
2064 void SvxIconChoiceCtrl_Impl::SetCursor( SvxIconChoiceCtrlEntry
* pEntry
, bool bSyncSingleSelection
,
2065 bool bShowFocusAsync
)
2067 if( pEntry
== pCursor
)
2069 if( pCursor
&& eSelectionMode
== SINGLE_SELECTION
&& bSyncSingleSelection
&&
2070 !pCursor
->IsSelected() )
2071 SelectEntry( pCursor
, true, true );
2074 ShowCursor( false );
2075 SvxIconChoiceCtrlEntry
* pOldCursor
= pCursor
;
2079 pOldCursor
->ClearFlags( SvxIconViewFlags::FOCUSED
);
2080 if( eSelectionMode
== SINGLE_SELECTION
&& bSyncSingleSelection
)
2081 SelectEntry( pOldCursor
, false, true ); // deselect old cursor
2086 pCursor
->SetFlags( SvxIconViewFlags::FOCUSED
);
2087 if( eSelectionMode
== SINGLE_SELECTION
&& bSyncSingleSelection
)
2088 SelectEntry( pCursor
, true, true );
2089 if( !bShowFocusAsync
)
2093 if( !nUserEventShowCursor
)
2094 nUserEventShowCursor
=
2095 Application::PostUserEvent( LINK( this, SvxIconChoiceCtrl_Impl
, UserEventHdl
),
2096 EVENTID_SHOW_CURSOR
);
2102 void SvxIconChoiceCtrl_Impl::ShowCursor( bool bShow
)
2104 if( !pCursor
|| !bShow
|| !pView
->HasFocus() )
2109 Rectangle
aRect ( CalcFocusRect( pCursor
) );
2110 /*pView->*/ShowFocus( aRect
);
2114 void SvxIconChoiceCtrl_Impl::HideDDIcon()
2122 void SvxIconChoiceCtrl_Impl::ImpHideDDIcon()
2126 Size
aSize( pDDDev
->GetOutputSizePixel() );
2128 pView
->DrawOutDev( aDDLastRectPos
, aSize
, Point(), aSize
, *pDDDev
);
2132 bool SvxIconChoiceCtrl_Impl::HandleScrollCommand( const CommandEvent
& rCmd
)
2134 Rectangle
aDocRect( GetDocumentRect() );
2135 Rectangle
aVisRect( GetVisibleRect() );
2136 if( aVisRect
.IsInside( aDocRect
))
2138 Size
aDocSize( aDocRect
.GetSize() );
2139 Size
aVisSize( aVisRect
.GetSize() );
2140 bool bHor
= aDocSize
.Width() > aVisSize
.Width();
2141 bool bVer
= aDocSize
.Height() > aVisSize
.Height();
2143 long nScrollDX
= 0, nScrollDY
= 0;
2145 switch( rCmd
.GetCommand() )
2147 case CommandEventId::StartAutoScroll
:
2149 pView
->EndTracking();
2150 sal_uInt16 nScrollFlags
= 0;
2152 nScrollFlags
|= AUTOSCROLL_HORZ
;
2154 nScrollFlags
|= AUTOSCROLL_VERT
;
2157 pView
->StartAutoScroll( nScrollFlags
);
2163 case CommandEventId::Wheel
:
2165 const CommandWheelData
* pData
= rCmd
.GetWheelData();
2166 if( pData
&& (CommandWheelMode::SCROLL
== pData
->GetMode()) && !pData
->IsHorz() )
2168 sal_uLong nScrollLines
= pData
->GetScrollLines();
2169 if( nScrollLines
== COMMAND_WHEEL_PAGESCROLL
)
2171 nScrollDY
= GetScrollBarPageSize( aVisSize
.Width() );
2172 if( pData
->GetDelta() < 0 )
2177 nScrollDY
= pData
->GetNotchDelta() * (long)nScrollLines
;
2178 nScrollDY
*= GetScrollBarLineSize();
2184 case CommandEventId::AutoScroll
:
2186 const CommandScrollData
* pData
= rCmd
.GetAutoScrollData();
2189 nScrollDX
= pData
->GetDeltaX() * GetScrollBarLineSize();
2190 nScrollDY
= pData
->GetDeltaY() * GetScrollBarLineSize();
2198 if( nScrollDX
|| nScrollDY
)
2200 aVisRect
.Top() -= nScrollDY
;
2201 aVisRect
.Bottom() -= nScrollDY
;
2202 aVisRect
.Left() -= nScrollDX
;
2203 aVisRect
.Right() -= nScrollDX
;
2204 MakeVisible( aVisRect
);
2211 void SvxIconChoiceCtrl_Impl::Command( const CommandEvent
& rCEvt
)
2213 // scroll mouse event?
2214 if( (rCEvt
.GetCommand() == CommandEventId::Wheel
) ||
2215 (rCEvt
.GetCommand() == CommandEventId::StartAutoScroll
) ||
2216 (rCEvt
.GetCommand() == CommandEventId::AutoScroll
) )
2218 if( HandleScrollCommand( rCEvt
) )
2223 void SvxIconChoiceCtrl_Impl::ToTop( SvxIconChoiceCtrlEntry
* pEntry
)
2225 if( !pZOrderList
->empty()
2226 && pEntry
!= pZOrderList
->back()
2229 SvxIconChoiceCtrlEntryList_impl::iterator it
= pZOrderList
->begin();
2230 it
!= pZOrderList
->end();
2233 if ( *it
== pEntry
)
2235 pZOrderList
->erase( it
);
2236 pZOrderList
->push_back( pEntry
);
2243 void SvxIconChoiceCtrl_Impl::ClipAtVirtOutRect( Rectangle
& rRect
) const
2245 if( rRect
.Bottom() >= aVirtOutputSize
.Height() )
2246 rRect
.Bottom() = aVirtOutputSize
.Height() - 1;
2247 if( rRect
.Right() >= aVirtOutputSize
.Width() )
2248 rRect
.Right() = aVirtOutputSize
.Width() - 1;
2249 if( rRect
.Top() < 0 )
2251 if( rRect
.Left() < 0 )
2255 // rRect: area of the document (in document coordinates) that we want to make
2257 // bScrBar == true: rectangle was calculated because of a scrollbar event
2259 void SvxIconChoiceCtrl_Impl::MakeVisible( const Rectangle
& rRect
, bool bScrBar
,
2260 bool bCallRectChangedHdl
)
2262 Rectangle
aVirtRect( rRect
);
2263 ClipAtVirtOutRect( aVirtRect
);
2264 Point
aOrigin( pView
->GetMapMode().GetOrigin() );
2265 // convert to document coordinate
2267 Rectangle
aOutputArea( GetOutputRect() );
2268 if( aOutputArea
.IsInside( aVirtRect
) )
2269 return; // is already visible
2272 if( aVirtRect
.Top() < aOutputArea
.Top() )
2274 // scroll up (nDy < 0)
2275 nDy
= aVirtRect
.Top() - aOutputArea
.Top();
2277 else if( aVirtRect
.Bottom() > aOutputArea
.Bottom() )
2279 // scroll down (nDy > 0)
2280 nDy
= aVirtRect
.Bottom() - aOutputArea
.Bottom();
2286 if( aVirtRect
.Left() < aOutputArea
.Left() )
2288 // scroll to the left (nDx < 0)
2289 nDx
= aVirtRect
.Left() - aOutputArea
.Left();
2291 else if( aVirtRect
.Right() > aOutputArea
.Right() )
2293 // scroll to the right (nDx > 0)
2294 nDx
= aVirtRect
.Right() - aOutputArea
.Right();
2301 aOutputArea
.SetPos( aOrigin
);
2302 if( GetUpdateMode() )
2306 ShowCursor( false );
2309 // invert origin for SV (so we can scroll/paint using document coordinates)
2311 SetOrigin( aOrigin
);
2313 bool bScrollable
= pView
->GetBackground().IsScrollable();
2315 if( bScrollable
&& GetUpdateMode() )
2317 // scroll in reverse direction!
2318 pView
->Control::Scroll( -nDx
, -nDy
, aOutputArea
,
2319 SCROLL_NOCHILDREN
| SCROLL_USECLIPREGION
| SCROLL_CLIP
);
2322 pView
->Invalidate(INVALIDATE_NOCHILDREN
);
2324 if( aHorSBar
->IsVisible() || aVerSBar
->IsVisible() )
2330 if(aHorSBar
->IsVisible() && aHorSBar
->GetThumbPos() != aOrigin
.X())
2331 aHorSBar
->SetThumbPos( aOrigin
.X() );
2332 if(aVerSBar
->IsVisible() && aVerSBar
->GetThumbPos() != aOrigin
.Y())
2333 aVerSBar
->SetThumbPos( aOrigin
.Y() );
2337 if( GetUpdateMode() )
2340 // check if we still need scrollbars
2342 if( bScrollable
&& GetUpdateMode() )
2345 // If the requested area can not be made completely visible, the
2346 // Vis-Rect-Changed handler is called in any case. This case may occur e.g.
2347 // if only few pixels of the lower border are invisible, but a scrollbar has
2348 // a larger line size.
2349 if( bCallRectChangedHdl
|| GetOutputRect() != rRect
)
2353 sal_uLong
SvxIconChoiceCtrl_Impl::GetSelectionCount() const
2355 if( (nWinBits
& WB_HIGHLIGHTFRAME
) && pCurHighlightFrame
)
2357 return nSelectionCount
;
2360 void SvxIconChoiceCtrl_Impl::ToggleSelection( SvxIconChoiceCtrlEntry
* pEntry
)
2363 if( pEntry
->IsSelected() )
2367 SelectEntry( pEntry
, bSel
, true, true );
2370 void SvxIconChoiceCtrl_Impl::DeselectAllBut( SvxIconChoiceCtrlEntry
* pThisEntryNot
,
2373 ClearSelectedRectList();
2375 // TODO: work through z-order list, if necessary!
2377 size_t nCount
= aEntries
.size();
2378 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
2380 SvxIconChoiceCtrlEntry
* pEntry
= aEntries
[ nCur
];
2381 if( pEntry
!= pThisEntryNot
&& pEntry
->IsSelected() )
2382 SelectEntry( pEntry
, false, true, true, bPaintSync
);
2385 nFlags
&= (~F_ADD_MODE
);
2388 Size
SvxIconChoiceCtrl_Impl::GetMinGrid() const
2390 Size
aMinSize( aImageSize
);
2391 aMinSize
.Width() += 2 * LROFFS_BOUND
;
2392 aMinSize
.Height() += TBOFFS_BOUND
; // single offset is enough (FileDlg)
2393 OUString
aStrDummy( "XXX" );
2394 Size
aTextSize( pView
->GetTextWidth( aStrDummy
), pView
->GetTextHeight() );
2395 if( nWinBits
& WB_ICON
)
2397 aMinSize
.Height() += VER_DIST_BMP_STRING
;
2398 aMinSize
.Height() += aTextSize
.Height();
2402 aMinSize
.Width() += HOR_DIST_BMP_STRING
;
2403 aMinSize
.Width() += aTextSize
.Width();
2408 void SvxIconChoiceCtrl_Impl::SetGrid( const Size
& rSize
)
2410 Size
aSize( rSize
);
2411 Size
aMinSize( GetMinGrid() );
2412 if( aSize
.Width() < aMinSize
.Width() )
2413 aSize
.Width() = aMinSize
.Width();
2414 if( aSize
.Height() < aMinSize
.Height() )
2415 aSize
.Height() = aMinSize
.Height();
2417 nGridDX
= aSize
.Width();
2418 // HACK: Detail mode is not yet fully implemented, this workaround makes it
2419 // fly with a single column
2420 if( nWinBits
& WB_DETAILS
)
2422 const SvxIconChoiceCtrlColumnInfo
* pCol
= GetColumn( 0 );
2424 const_cast<SvxIconChoiceCtrlColumnInfo
*>(pCol
)->SetWidth( nGridDX
);
2426 nGridDY
= aSize
.Height();
2427 SetDefaultTextSize();
2430 // Calculates the maximum size that the text rectangle may use within its
2431 // bounding rectangle. In WB_ICON mode with IcnShowTextFull, Bottom is set to
2434 Rectangle
SvxIconChoiceCtrl_Impl::CalcMaxTextRect( const SvxIconChoiceCtrlEntry
* pEntry
) const
2436 Rectangle aBoundRect
;
2437 // avoid infinite recursion: don't calculate the bounding rectangle here
2438 if( IsBoundingRectValid( pEntry
->aRect
) )
2439 aBoundRect
= pEntry
->aRect
;
2441 aBoundRect
= pEntry
->aGridRect
;
2443 Rectangle
aBmpRect( const_cast<SvxIconChoiceCtrl_Impl
*>(this)->CalcBmpRect(
2444 const_cast<SvxIconChoiceCtrlEntry
*>(pEntry
) ) );
2445 if( nWinBits
& WB_ICON
)
2447 aBoundRect
.Top() = aBmpRect
.Bottom();
2448 aBoundRect
.Top() += VER_DIST_BMP_STRING
;
2449 if( aBoundRect
.Top() > aBoundRect
.Bottom())
2450 aBoundRect
.Top() = aBoundRect
.Bottom();
2451 aBoundRect
.Left() += LROFFS_BOUND
;
2452 aBoundRect
.Left()++;
2453 aBoundRect
.Right() -= LROFFS_BOUND
;
2454 aBoundRect
.Right()--;
2455 if( aBoundRect
.Left() > aBoundRect
.Right())
2456 aBoundRect
.Left() = aBoundRect
.Right();
2457 if( GetEntryTextModeSmart( pEntry
) == IcnShowTextFull
)
2458 aBoundRect
.Bottom() = LONG_MAX
;
2462 aBoundRect
.Left() = aBmpRect
.Right();
2463 aBoundRect
.Left() += HOR_DIST_BMP_STRING
;
2464 aBoundRect
.Right() -= LROFFS_BOUND
;
2465 if( aBoundRect
.Left() > aBoundRect
.Right() )
2466 aBoundRect
.Left() = aBoundRect
.Right();
2467 long nHeight
= aBoundRect
.GetSize().Height();
2468 nHeight
= nHeight
- aDefaultTextSize
.Height();
2470 aBoundRect
.Top() += nHeight
;
2471 aBoundRect
.Bottom() -= nHeight
;
2476 void SvxIconChoiceCtrl_Impl::SetDefaultTextSize()
2479 nDY
-= aImageSize
.Height();
2480 nDY
-= VER_DIST_BMP_STRING
;
2481 nDY
-= 2 * TBOFFS_BOUND
;
2486 nDX
-= 2 * LROFFS_BOUND
;
2491 long nHeight
= pView
->GetTextHeight();
2494 aDefaultTextSize
= Size(nDX
, nDY
);
2498 void SvxIconChoiceCtrl_Impl::Center( SvxIconChoiceCtrlEntry
* pEntry
) const
2500 pEntry
->aRect
= pEntry
->aGridRect
;
2501 Size
aSize( CalcBoundingSize( pEntry
) );
2502 if( nWinBits
& WB_ICON
)
2504 // center horizontally
2505 long nBorder
= pEntry
->aGridRect
.GetWidth() - aSize
.Width();
2506 pEntry
->aRect
.Left() += nBorder
/ 2;
2507 pEntry
->aRect
.Right() -= nBorder
/ 2;
2509 // center vertically
2510 pEntry
->aRect
.Bottom() = pEntry
->aRect
.Top() + aSize
.Height();
2514 // The deltas are the offsets by which the view is moved on the document.
2515 // left, up: offsets < 0
2516 // right, down: offsets > 0
2517 void SvxIconChoiceCtrl_Impl::Scroll( long nDeltaX
, long nDeltaY
, bool bScrollBar
)
2519 const MapMode
& rMapMode
= pView
->GetMapMode();
2520 Point
aOrigin( rMapMode
.GetOrigin() );
2521 // convert to document coordinate
2523 aOrigin
.Y() += nDeltaY
;
2524 aOrigin
.X() += nDeltaX
;
2525 Rectangle
aRect( aOrigin
, aOutputSize
);
2526 MakeVisible( aRect
, bScrollBar
);
2530 const Size
& SvxIconChoiceCtrl_Impl::GetItemSize( SvxIconChoiceCtrlEntry
*,
2531 IcnViewFieldType eItem
) const
2533 if (eItem
== IcnViewFieldTypeText
)
2534 return aDefaultTextSize
;
2538 Rectangle
SvxIconChoiceCtrl_Impl::CalcFocusRect( SvxIconChoiceCtrlEntry
* pEntry
)
2540 Rectangle
aTextRect( CalcTextRect( pEntry
) );
2541 Rectangle
aBoundRect( GetEntryBoundRect( pEntry
) );
2543 aBoundRect
.Left(), aBoundRect
.Top() - 1, aBoundRect
.Right() - 1,
2544 aTextRect
.Bottom() + 1);
2547 // the hot spot is the inner 50% of the rectangle
2548 static Rectangle
GetHotSpot( const Rectangle
& rRect
)
2550 Rectangle
aResult( rRect
);
2552 Size
aSize( rRect
.GetSize() );
2553 long nDelta
= aSize
.Width() / 4;
2554 aResult
.Left() += nDelta
;
2555 aResult
.Right() -= nDelta
;
2556 nDelta
= aSize
.Height() / 4;
2557 aResult
.Top() += nDelta
;
2558 aResult
.Bottom() -= nDelta
;
2562 void SvxIconChoiceCtrl_Impl::SelectRect( SvxIconChoiceCtrlEntry
* pEntry1
, SvxIconChoiceCtrlEntry
* pEntry2
,
2563 bool bAdd
, std::vector
<Rectangle
*>* pOtherRects
)
2565 DBG_ASSERT(pEntry1
&& pEntry2
,"SelectEntry: Invalid Entry-Ptr");
2566 Rectangle
aRect( GetEntryBoundRect( pEntry1
) );
2567 aRect
.Union( GetEntryBoundRect( pEntry2
) );
2568 SelectRect( aRect
, bAdd
, pOtherRects
);
2571 void SvxIconChoiceCtrl_Impl::SelectRect( const Rectangle
& rRect
, bool bAdd
,
2572 std::vector
<Rectangle
*>* pOtherRects
)
2574 aCurSelectionRect
= rRect
;
2575 if( !pZOrderList
|| !pZOrderList
->size() )
2578 // set flag, so ToTop won't be called in Select
2579 bool bAlreadySelectingRect
= (nFlags
& F_SELECTING_RECT
) != 0;
2580 nFlags
|= F_SELECTING_RECT
;
2582 CheckBoundingRects();
2584 const size_t nCount
= pZOrderList
->size();
2586 Rectangle
aRect( rRect
);
2588 bool bCalcOverlap
= (bAdd
&& pOtherRects
&& !pOtherRects
->empty());
2590 bool bResetClipRegion
= false;
2591 if( !pView
->IsClipRegion() )
2593 bResetClipRegion
= true;
2594 pView
->SetClipRegion(vcl::Region(GetOutputRect()));
2597 for( size_t nPos
= 0; nPos
< nCount
; nPos
++ )
2599 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[ nPos
];
2601 if( !IsBoundingRectValid( pEntry
->aRect
))
2602 FindBoundingRect( pEntry
);
2603 Rectangle
aBoundRect( GetHotSpot( pEntry
->aRect
) );
2604 bool bSelected
= pEntry
->IsSelected();
2608 bOverlaps
= IsOver( pOtherRects
, aBoundRect
);
2611 bool bOver
= aRect
.IsOver( aBoundRect
);
2613 if( bOver
&& !bOverlaps
)
2615 // is inside the new selection rectangle and outside of any old one
2618 SelectEntry( pEntry
, true, true, true );
2622 // is outside of the selection rectangle
2625 SelectEntry( pEntry
, false, true, true );
2627 else if( bAdd
&& bOverlaps
)
2629 // The entry is inside an old (=>span multiple rectangles with Ctrl)
2630 // selection rectangle.
2632 // There is still a bug here! The selection status of an entry in a
2633 // previous rectangle has to be restored, if it was touched by the
2634 // current selection rectangle but is not inside it any more.
2635 // For simplicity's sake, let's assume that all entries in the old
2636 // rectangles were correctly selected. It is wrong to just deselect
2637 // the intersection.
2638 // Possible solution: remember a snapshot of the selection before
2639 // spanning the rectangle.
2640 if( aBoundRect
.IsOver( rRect
))
2642 // deselect intersection between old rectangles and current rectangle
2644 SelectEntry( pEntry
, false, true, true );
2648 // select entry of an old rectangle
2650 SelectEntry( pEntry
, true, true, true );
2653 else if( !bOver
&& bSelected
)
2655 // this entry is completely outside the rectangle => deselect it
2656 SelectEntry( pEntry
, false, true, true );
2660 if( !bAlreadySelectingRect
)
2661 nFlags
&= ~F_SELECTING_RECT
;
2664 if( bResetClipRegion
)
2665 pView
->SetClipRegion();
2668 void SvxIconChoiceCtrl_Impl::SelectRange(
2669 SvxIconChoiceCtrlEntry
* pStart
,
2670 SvxIconChoiceCtrlEntry
* pEnd
,
2673 sal_uLong nFront
= GetEntryListPos( pStart
);
2674 sal_uLong nBack
= GetEntryListPos( pEnd
);
2675 sal_uLong nFirst
= std::min( nFront
, nBack
);
2676 sal_uLong nLast
= std::max( nFront
, nBack
);
2678 SvxIconChoiceCtrlEntry
* pEntry
;
2682 // deselect everything before the first entry if not in
2684 for ( i
=0; i
<nFirst
; i
++ )
2686 pEntry
= GetEntry( i
);
2687 if( pEntry
->IsSelected() )
2688 SelectEntry( pEntry
, false, true, true, true );
2692 // select everything between nFirst and nLast
2693 for ( i
=nFirst
; i
<=nLast
; i
++ )
2695 pEntry
= GetEntry( i
);
2696 if( ! pEntry
->IsSelected() )
2697 SelectEntry( pEntry
, true, true, true, true );
2702 // deselect everything behind the last entry if not in
2704 sal_uLong nEnd
= GetEntryCount();
2705 for ( ; i
<nEnd
; i
++ )
2707 pEntry
= GetEntry( i
);
2708 if( pEntry
->IsSelected() )
2709 SelectEntry( pEntry
, false, true, true, true );
2714 bool SvxIconChoiceCtrl_Impl::IsOver( std::vector
<Rectangle
*>* pRectList
, const Rectangle
& rBoundRect
)
2716 const sal_uInt16 nCount
= pRectList
->size();
2717 for( sal_uInt16 nCur
= 0; nCur
< nCount
; nCur
++ )
2719 Rectangle
* pRect
= (*pRectList
)[ nCur
];
2720 if( rBoundRect
.IsOver( *pRect
))
2726 void SvxIconChoiceCtrl_Impl::AddSelectedRect( SvxIconChoiceCtrlEntry
* pEntry1
,
2727 SvxIconChoiceCtrlEntry
* pEntry2
)
2729 DBG_ASSERT(pEntry1
&& pEntry2
,"SelectEntry: Invalid Entry-Ptr");
2730 Rectangle
aRect( GetEntryBoundRect( pEntry1
) );
2731 aRect
.Union( GetEntryBoundRect( pEntry2
) );
2732 AddSelectedRect( aRect
);
2735 void SvxIconChoiceCtrl_Impl::AddSelectedRect( const Rectangle
& rRect
)
2737 Rectangle
* pRect
= new Rectangle( rRect
);
2739 aSelectedRectList
.push_back( pRect
);
2742 void SvxIconChoiceCtrl_Impl::ClearSelectedRectList()
2744 const sal_uInt16 nCount
= aSelectedRectList
.size();
2745 for( sal_uInt16 nCur
= 0; nCur
< nCount
; nCur
++ )
2747 Rectangle
* pRect
= aSelectedRectList
[ nCur
];
2750 aSelectedRectList
.clear();
2753 IMPL_LINK_NOARG_TYPED(SvxIconChoiceCtrl_Impl
, AutoArrangeHdl
, Idle
*, void)
2755 aAutoArrangeIdle
.Stop();
2756 Arrange( IsAutoArrange() );
2759 IMPL_LINK_NOARG_TYPED(SvxIconChoiceCtrl_Impl
, VisRectChangedHdl
, Idle
*, void)
2761 aVisRectChangedIdle
.Stop();
2762 pView
->VisibleRectChanged();
2765 IMPL_LINK_NOARG_TYPED(SvxIconChoiceCtrl_Impl
, DocRectChangedHdl
, Idle
*, void)
2767 aDocRectChangedIdle
.Stop();
2768 pView
->DocumentRectChanged();
2771 bool SvxIconChoiceCtrl_Impl::IsTextHit( SvxIconChoiceCtrlEntry
* pEntry
, const Point
& rDocPos
)
2773 Rectangle
aRect( CalcTextRect( pEntry
));
2774 if( aRect
.IsInside( rDocPos
) )
2779 IMPL_LINK_NOARG_TYPED(SvxIconChoiceCtrl_Impl
, EditTimeoutHdl
, Idle
*, void)
2781 SvxIconChoiceCtrlEntry
* pEntry
= GetCurEntry();
2782 if( bEntryEditingEnabled
&& pEntry
&&
2783 pEntry
->IsSelected())
2785 EditEntry( pEntry
);
2791 // Function to align entries to the grid
2794 // pStart == 0: align all entries
2795 // else: align all entries of the row from pStart on (including pStart)
2796 void SvxIconChoiceCtrl_Impl::AdjustEntryAtGrid( SvxIconChoiceCtrlEntry
* pStart
)
2798 IconChoiceMap aLists
;
2799 pImpCursor
->CreateGridAjustData( aLists
, pStart
);
2800 for (IconChoiceMap::const_iterator iter
= aLists
.begin();
2801 iter
!= aLists
.end(); ++iter
)
2803 AdjustAtGrid(iter
->second
, pStart
);
2805 IcnCursor_Impl::DestroyGridAdjustData( aLists
);
2809 // align a row, might expand width, doesn't break the line
2810 void SvxIconChoiceCtrl_Impl::AdjustAtGrid( const SvxIconChoiceCtrlEntryPtrVec
& rRow
, SvxIconChoiceCtrlEntry
* pStart
)
2822 for( sal_uInt16 nCur
= 0; nCur
< rRow
.size(); nCur
++ )
2824 SvxIconChoiceCtrlEntry
* pCur
= rRow
[ nCur
];
2825 if( !bGo
&& pCur
== pStart
)
2828 // SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pCur);
2829 // Decisive (for our eye) is the bitmap, else, the entry might jump too
2830 // much within long texts.
2831 const Rectangle
& rBoundRect
= GetEntryBoundRect( pCur
);
2832 Rectangle
aCenterRect( CalcBmpRect( pCur
, 0 ));
2833 if( bGo
&& !pCur
->IsPosLocked() )
2835 long nWidth
= aCenterRect
.GetSize().Width();
2836 Point
aNewPos( AdjustAtGrid( aCenterRect
, rBoundRect
) );
2837 while( aNewPos
.X() < nCurRight
)
2838 aNewPos
.X() += nGridDX
;
2839 if( aNewPos
!= rBoundRect
.TopLeft() )
2841 SetEntryPos( pCur
, aNewPos
);
2842 pCur
->SetFlags( SvxIconViewFlags::POS_MOVED
);
2843 nFlags
|= F_MOVED_ENTRIES
;
2845 nCurRight
= aNewPos
.X() + nWidth
;
2849 nCurRight
= rBoundRect
.Right();
2854 // Aligns a rectangle to the grid, but doesn't guarantee that the new position
2855 // is vacant. The position can be used for SetEntryPos. The CenterRect describes
2856 // a part of the bounding rectangle that is used for calculating the target
2858 Point
SvxIconChoiceCtrl_Impl::AdjustAtGrid( const Rectangle
& rCenterRect
,
2859 const Rectangle
& rBoundRect
) const
2861 Point
aPos( rCenterRect
.TopLeft() );
2862 Size
aSize( rCenterRect
.GetSize() );
2864 aPos
.X() -= LROFFS_WINBORDER
;
2865 aPos
.Y() -= TBOFFS_WINBORDER
;
2867 // align (the center of the rectangle is the reference)
2868 short nGridX
= (short)((aPos
.X()+(aSize
.Width()/2)) / nGridDX
);
2869 short nGridY
= (short)((aPos
.Y()+(aSize
.Height()/2)) / nGridDY
);
2870 aPos
.X() = nGridX
* nGridDX
;
2871 aPos
.Y() = nGridY
* nGridDY
;
2872 // horizontal center
2873 aPos
.X() += (nGridDX
- rBoundRect
.GetSize().Width() ) / 2;
2875 aPos
.X() += LROFFS_WINBORDER
;
2876 aPos
.Y() += TBOFFS_WINBORDER
;
2882 void SvxIconChoiceCtrl_Impl::SetEntryTextMode( SvxIconChoiceCtrlTextMode eMode
, SvxIconChoiceCtrlEntry
* pEntry
)
2886 if( eTextMode
!= eMode
)
2888 if( eTextMode
== IcnShowTextDontKnow
)
2889 eTextMode
= IcnShowTextShort
;
2896 if( pEntry
->eTextMode
!= eMode
)
2898 pEntry
->eTextMode
= eMode
;
2899 InvalidateEntry( pEntry
);
2900 pView
->Invalidate( GetEntryBoundRect( pEntry
) );
2901 AdjustVirtSize( pEntry
->aRect
);
2907 SvxIconChoiceCtrlTextMode
SvxIconChoiceCtrl_Impl::GetEntryTextModeSmart( const SvxIconChoiceCtrlEntry
* pEntry
) const
2909 DBG_ASSERT(pEntry
,"GetEntryTextModeSmart: Entry not set");
2910 SvxIconChoiceCtrlTextMode eMode
= pEntry
->GetTextMode();
2911 if( eMode
== IcnShowTextDontKnow
)
2918 // Draw my own focusrect, because the focusrect of the outputdevice has got the inverted color
2919 // of the background. But what will we see, if the backgroundcolor is gray ? - We will see
2920 // a gray focusrect on a gray background !!!
2922 void SvxIconChoiceCtrl_Impl::ShowFocus ( Rectangle
& rRect
)
2924 Color
aBkgColor(pView
->GetBackground().GetColor());
2926 sal_uInt16 nColor
= ( aBkgColor
.GetRed() + aBkgColor
.GetGreen() + aBkgColor
.GetBlue() ) / 3;
2928 aPenColor
.SetColor(COL_BLACK
);
2930 aPenColor
.SetColor(COL_WHITE
);
2933 aFocus
.aPenColor
= aPenColor
;
2934 aFocus
.aRect
= rRect
;
2937 void SvxIconChoiceCtrl_Impl::DrawFocusRect(vcl::RenderContext
& rRenderContext
)
2939 rRenderContext
.SetLineColor(aFocus
.aPenColor
);
2940 rRenderContext
.SetFillColor();
2941 Polygon
aPolygon (aFocus
.aRect
);
2943 LineInfo
aLineInfo(LINE_DASH
);
2945 aLineInfo
.SetDashLen(1);
2946 aLineInfo
.SetDotLen(1L);
2947 aLineInfo
.SetDistance(1L);
2948 aLineInfo
.SetDotCount(1);
2950 rRenderContext
.DrawPolyLine(aPolygon
, aLineInfo
);
2953 bool SvxIconChoiceCtrl_Impl::IsMnemonicChar( sal_Unicode cChar
, sal_uLong
& rPos
) const
2956 const vcl::I18nHelper
& rI18nHelper
= Application::GetSettings().GetUILocaleI18nHelper();
2957 size_t nEntryCount
= GetEntryCount();
2958 for ( size_t i
= 0; i
< nEntryCount
; ++i
)
2960 if ( rI18nHelper
.MatchMnemonic( GetEntry( i
)->GetText(), cChar
) )
2974 IMPL_LINK(SvxIconChoiceCtrl_Impl
, UserEventHdl
, void*, nId
)
2976 if( nId
== EVENTID_ADJUST_SCROLLBARS
)
2978 nUserEventAdjustScrBars
= 0;
2981 else if( nId
== EVENTID_SHOW_CURSOR
)
2983 nUserEventShowCursor
= 0;
2989 void SvxIconChoiceCtrl_Impl::CancelUserEvents()
2991 if( nUserEventAdjustScrBars
)
2993 Application::RemoveUserEvent( nUserEventAdjustScrBars
);
2994 nUserEventAdjustScrBars
= 0;
2996 if( nUserEventShowCursor
)
2998 Application::RemoveUserEvent( nUserEventShowCursor
);
2999 nUserEventShowCursor
= 0;
3003 void SvxIconChoiceCtrl_Impl::InvalidateEntry( SvxIconChoiceCtrlEntry
* pEntry
)
3005 if( pEntry
== pCursor
)
3006 ShowCursor( false );
3007 pView
->Invalidate( pEntry
->aRect
);
3009 pView
->Invalidate( pEntry
->aRect
);
3010 if( pEntry
== pCursor
)
3014 void SvxIconChoiceCtrl_Impl::EditEntry( SvxIconChoiceCtrlEntry
* pEntry
)
3016 DBG_ASSERT(pEntry
,"EditEntry: Entry not set");
3020 StopEntryEditing( true );
3021 pEdit
.disposeAndClear();
3024 pCurEditedEntry
= pEntry
;
3025 OUString
aEntryText( SvtIconChoiceCtrl::GetEntryText( pEntry
, true ) );
3026 Rectangle
aRect( CalcTextRect( pEntry
, 0, true, &aEntryText
) );
3027 MakeVisible( aRect
);
3028 Point
aPos( aRect
.TopLeft() );
3029 aPos
= pView
->GetPixelPos( aPos
);
3030 aRect
.SetPos( aPos
);
3032 pEdit
= VclPtr
<IcnViewEdit_Impl
>::Create(
3038 LINK( this, SvxIconChoiceCtrl_Impl
, TextEditEndedHdl
) );
3041 IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl
, TextEditEndedHdl
)
3043 DBG_ASSERT(pEdit
,"TextEditEnded: pEdit not set");
3046 pCurEditedEntry
= 0;
3049 DBG_ASSERT(pCurEditedEntry
,"TextEditEnded: pCurEditedEntry not set");
3051 if( !pCurEditedEntry
)
3054 if( pEdit
->IsGrabFocus() )
3060 if ( !pEdit
->EditingCanceled() )
3061 aText
= pEdit
->GetText();
3063 aText
= pEdit
->GetSavedValue();
3065 InvalidateEntry( pCurEditedEntry
);
3066 if( !GetSelectionCount() )
3067 SelectEntry( pCurEditedEntry
, true );
3070 if( pEdit
->IsGrabFocus() )
3072 // The edit can not be deleted here, because it is not within a handler. It
3073 // will be deleted in the dtor or in the next EditEntry.
3074 pCurEditedEntry
= 0;
3078 void SvxIconChoiceCtrl_Impl::StopEntryEditing( bool bCancel
)
3081 pEdit
->StopEditing( bCancel
);
3084 SvxIconChoiceCtrlEntry
* SvxIconChoiceCtrl_Impl::GetFirstSelectedEntry( sal_uLong
& rPos
) const
3086 if( !GetSelectionCount() )
3089 if( (nWinBits
& WB_HIGHLIGHTFRAME
) && (eSelectionMode
== NO_SELECTION
) )
3091 rPos
= pView
->GetEntryListPos( pCurHighlightFrame
);
3092 return pCurHighlightFrame
;
3095 size_t nCount
= aEntries
.size();
3098 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
3100 SvxIconChoiceCtrlEntry
* pEntry
= aEntries
[ nCur
];
3101 if( pEntry
->IsSelected() )
3110 SvxIconChoiceCtrlEntry
* pEntry
= pHead
;
3113 if( pEntry
->IsSelected() )
3115 rPos
= GetEntryListPos( pEntry
);
3118 pEntry
= pEntry
->pflink
;
3119 if( nCount
&& pEntry
== pHead
)
3121 OSL_FAIL("SvxIconChoiceCtrl_Impl::GetFirstSelectedEntry > infinite loop!");
3129 void SvxIconChoiceCtrl_Impl::SelectAll( bool bSelect
, bool bPaint
)
3133 size_t nCount
= aEntries
.size();
3134 for( size_t nCur
= 0; nCur
< nCount
&& (bSelect
|| GetSelectionCount() ); nCur
++ )
3136 SvxIconChoiceCtrlEntry
* pEntry
= aEntries
[ nCur
];
3137 SelectEntry( pEntry
, bSelect
, true, true, bPaint
);
3139 nFlags
&= (~F_ADD_MODE
);
3143 IcnViewEdit_Impl::IcnViewEdit_Impl( SvtIconChoiceCtrl
* pParent
, const Point
& rPos
,
3144 const Size
& rSize
, const OUString
& rData
, const Link
<>& rNotifyEditEnd
) :
3145 MultiLineEdit( pParent
, (pParent
->GetStyle() & WB_ICON
) ? WB_CENTER
: WB_LEFT
),
3146 aCallBackHdl( rNotifyEditEnd
),
3148 bAlreadyInCallback( false ),
3151 // FIXME: Outside of Paint Hierarchy
3152 vcl::Font
aFont(pParent
->GetPointFont(*this));
3153 aFont
.SetTransparent( false );
3154 SetControlFont(aFont
);
3155 SetControlBackground(aFont
.GetFillColor());
3156 SetControlForeground(aFont
.GetColor());
3158 SetSizePixel(CalcAdjustedSize(rSize
));
3162 aAccReturn
.InsertItem( IMPICNVIEW_ACC_RETURN
, vcl::KeyCode(KEY_RETURN
) );
3163 aAccEscape
.InsertItem( IMPICNVIEW_ACC_ESCAPE
, vcl::KeyCode(KEY_ESCAPE
) );
3165 aAccReturn
.SetActivateHdl( LINK( this, IcnViewEdit_Impl
, ReturnHdl_Impl
) );
3166 aAccEscape
.SetActivateHdl( LINK( this, IcnViewEdit_Impl
, EscapeHdl_Impl
) );
3167 Application::InsertAccel( &aAccReturn
);//, ACCEL_ALWAYS );
3168 Application::InsertAccel( &aAccEscape
);//, ACCEL_ALWAYS );
3173 IcnViewEdit_Impl::~IcnViewEdit_Impl()
3178 void IcnViewEdit_Impl::dispose()
3180 if( !bAlreadyInCallback
)
3182 Application::RemoveAccel( &aAccReturn
);
3183 Application::RemoveAccel( &aAccEscape
);
3185 MultiLineEdit::dispose();
3188 void IcnViewEdit_Impl::CallCallBackHdl_Impl()
3191 if ( !bAlreadyInCallback
)
3193 bAlreadyInCallback
= true;
3194 Application::RemoveAccel( &aAccReturn
);
3195 Application::RemoveAccel( &aAccEscape
);
3197 aCallBackHdl
.Call( this );
3201 IMPL_LINK_NOARG_TYPED(IcnViewEdit_Impl
, Timeout_Impl
, Idle
*, void)
3203 CallCallBackHdl_Impl();
3206 IMPL_LINK( IcnViewEdit_Impl
, ReturnHdl_Impl
, Accelerator
*, )
3210 CallCallBackHdl_Impl();
3214 IMPL_LINK( IcnViewEdit_Impl
, EscapeHdl_Impl
, Accelerator
*, )
3218 CallCallBackHdl_Impl();
3222 void IcnViewEdit_Impl::KeyInput( const KeyEvent
& rKEvt
)
3224 vcl::KeyCode aCode
= rKEvt
.GetKeyCode();
3225 sal_uInt16 nCode
= aCode
.GetCode();
3232 CallCallBackHdl_Impl();
3238 CallCallBackHdl_Impl();
3242 MultiLineEdit::KeyInput( rKEvt
);
3246 bool IcnViewEdit_Impl::PreNotify( NotifyEvent
& rNEvt
)
3248 if( rNEvt
.GetType() == MouseNotifyEvent::LOSEFOCUS
)
3250 if ( !bAlreadyInCallback
&&
3251 ((!Application::GetFocusWindow()) || !IsChild(Application::GetFocusWindow())))
3254 aIdle
.SetPriority(SchedulerPriority::REPAINT
);
3255 aIdle
.SetIdleHdl(LINK(this,IcnViewEdit_Impl
,Timeout_Impl
));
3262 void IcnViewEdit_Impl::StopEditing( bool bCancel
)
3264 if ( !bAlreadyInCallback
)
3266 bCanceled
= bCancel
;
3267 CallCallBackHdl_Impl();
3271 sal_uLong
SvxIconChoiceCtrl_Impl::GetEntryListPos( SvxIconChoiceCtrlEntry
* pEntry
) const
3273 if( !(nFlags
& F_ENTRYLISTPOS_VALID
))
3274 const_cast<SvxIconChoiceCtrl_Impl
*>(this)->SetListPositions();
3275 return pEntry
->nPos
;
3278 void SvxIconChoiceCtrl_Impl::InitSettings()
3280 const StyleSettings
& rStyleSettings
= pView
->GetSettings().GetStyleSettings();
3282 // unit (from settings) is Point
3283 vcl::Font
aFont( rStyleSettings
.GetFieldFont() );
3284 aFont
.SetColor( rStyleSettings
.GetWindowTextColor() );
3285 pView
->SetPointFont( aFont
);
3286 SetDefaultTextSize();
3288 pView
->SetTextColor( rStyleSettings
.GetFieldTextColor() );
3289 pView
->SetTextFillColor();
3291 pView
->SetBackground( rStyleSettings
.GetFieldColor());
3293 long nScrBarSize
= rStyleSettings
.GetScrollBarSize();
3294 if( nScrBarSize
!= nHorSBarHeight
|| nScrBarSize
!= nVerSBarWidth
)
3296 nHorSBarHeight
= nScrBarSize
;
3297 Size
aSize( aHorSBar
->GetSizePixel() );
3298 aSize
.Height() = nScrBarSize
;
3300 aHorSBar
->SetSizePixel( aSize
);
3302 nVerSBarWidth
= nScrBarSize
;
3303 aSize
= aVerSBar
->GetSizePixel();
3304 aSize
.Width() = nScrBarSize
;
3306 aVerSBar
->SetSizePixel( aSize
);
3308 Size
aOSize( pView
->Control::GetOutputSizePixel() );
3309 PositionScrollBars( aOSize
.Width(), aOSize
.Height() );
3314 EntryList_Impl::EntryList_Impl( SvxIconChoiceCtrl_Impl
* pOwner
) :
3320 EntryList_Impl::~EntryList_Impl()
3325 void EntryList_Impl::clear()
3328 maIconChoiceCtrlEntryList
.clear();
3331 void EntryList_Impl::insert( size_t nPos
, SvxIconChoiceCtrlEntry
* pEntry
)
3333 if ( nPos
< maIconChoiceCtrlEntryList
.size() ) {
3334 maIconChoiceCtrlEntryList
.insert( maIconChoiceCtrlEntryList
.begin() + nPos
, pEntry
);
3336 maIconChoiceCtrlEntryList
.push_back( pEntry
);
3338 if( _pOwner
->pHead
)
3339 pEntry
->SetBacklink( _pOwner
->pHead
->pblink
);
3342 void SvxIconChoiceCtrl_Impl::SetPositionMode( SvxIconChoiceCtrlPositionMode eMode
)
3344 if( eMode
== ePositionMode
)
3347 SvxIconChoiceCtrlPositionMode eOldMode
= ePositionMode
;
3348 ePositionMode
= eMode
;
3349 size_t nCount
= aEntries
.size();
3351 if( eOldMode
== IcnViewPositionModeAutoArrange
)
3353 // when positioning moved entries "hard", there are problems with
3354 // unwanted overlaps, as these entries aren't taken into account in
3356 if( aEntries
.size() )
3357 aAutoArrangeIdle
.Start();
3361 if( ePositionMode
== IcnViewPositionModeAutoArrange
)
3363 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
3365 SvxIconChoiceCtrlEntry
* pEntry
= aEntries
[ nCur
];
3366 if( pEntry
->GetFlags() & SvxIconViewFlags(SvxIconViewFlags::POS_LOCKED
| SvxIconViewFlags::POS_MOVED
))
3367 SetEntryPos(pEntry
, GetEntryBoundRect( pEntry
).TopLeft());
3370 if( aEntries
.size() )
3371 aAutoArrangeIdle
.Start();
3373 else if( ePositionMode
== IcnViewPositionModeAutoAdjust
)
3375 AdjustEntryAtGrid( 0 );
3379 void SvxIconChoiceCtrl_Impl::SetEntryPredecessor( SvxIconChoiceCtrlEntry
* pEntry
,
3380 SvxIconChoiceCtrlEntry
* pPredecessor
)
3382 if( !IsAutoArrange() )
3385 if( pEntry
== pPredecessor
)
3388 sal_uLong nPos1
= GetEntryListPos( pEntry
);
3393 sal_uLong nPos2
= GetEntryListPos( pPredecessor
);
3394 if( nPos1
== (nPos2
+ 1) )
3395 return; // is already the predecessor
3404 if( !pPredecessor
&& pHead
== pEntry
)
3405 return; // is already the first one
3407 bool bSetHead
= false;
3411 pPredecessor
= pHead
->pblink
;
3413 if( pEntry
== pHead
)
3415 pHead
= pHead
->pflink
;
3418 if( pEntry
!= pPredecessor
)
3421 pEntry
->SetBacklink( pPredecessor
);
3425 pEntry
->SetFlags( SvxIconViewFlags::PRED_SET
);
3426 aAutoArrangeIdle
.Start();
3429 SvxIconChoiceCtrlEntry
* SvxIconChoiceCtrl_Impl::FindEntryPredecessor( SvxIconChoiceCtrlEntry
* pEntry
,
3430 const Point
& rPosTopLeft
)
3432 Point
aPos( rPosTopLeft
); //TopLeft
3433 Rectangle
aCenterRect( CalcBmpRect( pEntry
, &aPos
));
3434 Point
aNewPos( aCenterRect
.Center() );
3435 sal_uLong nGrid
= GetPredecessorGrid( aNewPos
);
3436 size_t nCount
= aEntries
.size();
3437 if( nGrid
== ULONG_MAX
)
3439 if( nGrid
>= nCount
)
3442 return aEntries
[ nGrid
];
3444 SvxIconChoiceCtrlEntry
* pCur
= pHead
; // Grid 0
3445 // TODO: go through list from the end if nGrid > nCount/2
3446 for( sal_uLong nCur
= 0; nCur
< nGrid
; nCur
++ )
3447 pCur
= pCur
->pflink
;
3452 sal_uLong
SvxIconChoiceCtrl_Impl::GetPredecessorGrid( const Point
& rPos
) const
3455 aPos
.X() -= LROFFS_WINBORDER
;
3456 aPos
.Y() -= TBOFFS_WINBORDER
;
3457 long nMaxCol
= aVirtOutputSize
.Width() / nGridDX
;
3460 long nGridX
= aPos
.X() / nGridDX
;
3461 if( nGridX
> nMaxCol
)
3463 long nGridY
= aPos
.Y() / nGridDY
;
3464 long nGridsX
= aOutputSize
.Width() / nGridDX
;
3465 sal_uLong nGrid
= (nGridY
* nGridsX
) + nGridX
;
3466 long nMiddle
= (nGridX
* nGridDX
) + (nGridDX
/ 2);
3467 if( rPos
.X() < nMiddle
)
3477 bool SvxIconChoiceCtrl_Impl::RequestHelp( const HelpEvent
& rHEvt
)
3479 if ( !(rHEvt
.GetMode() & HelpEventMode::QUICK
) )
3482 Point
aPos( pView
->ScreenToOutputPixel(rHEvt
.GetMousePosPixel() ) );
3483 aPos
-= pView
->GetMapMode().GetOrigin();
3484 SvxIconChoiceCtrlEntry
* pEntry
= GetEntry( aPos
, true );
3489 OUString sQuickHelpText
= pEntry
->GetQuickHelpText();
3490 OUString
aEntryText( SvtIconChoiceCtrl::GetEntryText( pEntry
, false ) );
3491 Rectangle
aTextRect( CalcTextRect( pEntry
, 0, false, &aEntryText
) );
3492 if ( ( !aTextRect
.IsInside( aPos
) || aEntryText
.isEmpty() ) && sQuickHelpText
.isEmpty() )
3495 Rectangle
aOptTextRect( aTextRect
);
3496 aOptTextRect
.Bottom() = LONG_MAX
;
3497 DrawTextFlags nNewFlags
= nCurTextDrawFlags
;
3498 nNewFlags
&= ~DrawTextFlags( DrawTextFlags::Clip
| DrawTextFlags::EndEllipsis
);
3499 aOptTextRect
= pView
->GetTextRect( aOptTextRect
, aEntryText
, nNewFlags
);
3500 if ( aOptTextRect
!= aTextRect
|| !sQuickHelpText
.isEmpty() )
3502 //aTextRect.Right() = aTextRect.Left() + aRealSize.Width() + 4;
3503 Point
aPt( aOptTextRect
.TopLeft() );
3504 aPt
+= pView
->GetMapMode().GetOrigin();
3505 aPt
= pView
->OutputToScreenPixel( aPt
);
3506 // subtract border of tooltip help
3509 aOptTextRect
.SetPos( aPt
);
3511 if ( !sQuickHelpText
.isEmpty() )
3512 sHelpText
= sQuickHelpText
;
3514 sHelpText
= aEntryText
;
3515 Help::ShowQuickHelp( (vcl::Window
*)pView
, aOptTextRect
, sHelpText
, QuickHelpFlags::Left
| QuickHelpFlags::VCenter
);
3521 void SvxIconChoiceCtrl_Impl::ClearColumnList()
3530 void SvxIconChoiceCtrl_Impl::SetColumn( sal_uInt16 nIndex
, const SvxIconChoiceCtrlColumnInfo
& rInfo
)
3533 pColumns
= new SvxIconChoiceCtrlColumnInfoMap
;
3535 SvxIconChoiceCtrlColumnInfo
* pInfo
= new SvxIconChoiceCtrlColumnInfo( rInfo
);
3536 pColumns
->insert( nIndex
, pInfo
);
3538 // HACK: Detail mode is not yet fully implemented, this workaround makes it
3539 // fly with a single column
3540 if( !nIndex
&& (nWinBits
& WB_DETAILS
) )
3541 nGridDX
= pInfo
->GetWidth();
3543 if( GetUpdateMode() )
3544 Arrange( IsAutoArrange() );
3547 const SvxIconChoiceCtrlColumnInfo
* SvxIconChoiceCtrl_Impl::GetColumn( sal_uInt16 nIndex
) const
3551 SvxIconChoiceCtrlColumnInfoMap::const_iterator it
= pColumns
->find( nIndex
);
3552 if( it
== pColumns
->end() )
3557 void SvxIconChoiceCtrl_Impl::DrawHighlightFrame(vcl::RenderContext
& rRenderContext
, const Rectangle
& rBmpRect
, bool bHide
)
3559 Rectangle
aBmpRect(rBmpRect
);
3561 if (aImageSize
.Width() < 32)
3563 aBmpRect
.Right() += nBorder
;
3564 aBmpRect
.Left() -= nBorder
;
3565 aBmpRect
.Bottom() += nBorder
;
3566 aBmpRect
.Top() -= nBorder
;
3569 pView
->Invalidate(aBmpRect
);
3572 DecorationView
aDecoView(&rRenderContext
);
3573 DrawHighlightFrameStyle nDecoFlags
;
3574 if (bHighlightFramePressed
)
3575 nDecoFlags
= DrawHighlightFrameStyle::In
;
3577 nDecoFlags
= DrawHighlightFrameStyle::Out
;
3578 aDecoView
.DrawHighlightFrame(aBmpRect
, nDecoFlags
, true/*bTestBackground*/);
3582 void SvxIconChoiceCtrl_Impl::SetEntryHighlightFrame( SvxIconChoiceCtrlEntry
* pEntry
,
3583 bool bKeepHighlightFlags
)
3585 if( pEntry
== pCurHighlightFrame
)
3588 if( !bKeepHighlightFlags
)
3589 bHighlightFramePressed
= false;
3591 if (pCurHighlightFrame
)
3593 Rectangle
aInvalidationRect(GetEntryBoundRect(pCurHighlightFrame
));
3594 aInvalidationRect
.expand(5);
3595 pCurHighlightFrame
= nullptr;
3596 pView
->Invalidate(aInvalidationRect
);
3599 pCurHighlightFrame
= pEntry
;
3602 Rectangle
aInvalidationRect(GetEntryBoundRect(pEntry
));
3603 aInvalidationRect
.expand(5);
3604 pView
->Invalidate(aInvalidationRect
);
3608 void SvxIconChoiceCtrl_Impl::HideEntryHighlightFrame()
3610 if( !pCurHighlightFrame
)
3613 SvxIconChoiceCtrlEntry
* pEntry
= pCurHighlightFrame
;
3614 pCurHighlightFrame
= nullptr;
3615 Rectangle
aInvalidationRect(GetEntryBoundRect(pEntry
));
3616 aInvalidationRect
.expand(5);
3617 pView
->Invalidate(aInvalidationRect
);
3620 void SvxIconChoiceCtrl_Impl::CallSelectHandler( SvxIconChoiceCtrlEntry
* )
3622 // When single-click mode is active, the selection handler should be called
3623 // synchronously, as the selection is automatically taken away once the
3624 // mouse cursor doesn't touch the object any more. Else, we might run into
3625 // missing calls to Select if the object is selected from a mouse movement,
3626 // because when starting the timer, the mouse cursor might have already left
3628 // In special cases (=>SfxFileDialog!), synchronous calls can be forced via
3629 // WB_NOASYNCSELECTHDL.
3630 if( nWinBits
& (WB_NOASYNCSELECTHDL
| WB_HIGHLIGHTFRAME
) )
3637 aCallSelectHdlIdle
.Start();
3640 IMPL_LINK_NOARG_TYPED(SvxIconChoiceCtrl_Impl
, CallSelectHdlHdl
, Idle
*, void)
3647 void SvxIconChoiceCtrl_Impl::SetOrigin( const Point
& rPos
)
3649 MapMode
aMapMode( pView
->GetMapMode() );
3650 aMapMode
.SetOrigin( rPos
);
3651 pView
->SetMapMode( aMapMode
);
3654 void SvxIconChoiceCtrl_Impl::CallEventListeners( sal_uLong nEvent
, void* pData
)
3656 pView
->CallImplEventListeners( nEvent
, pData
);
3660 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */