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>
33 #include <svtools/ivctrl.hxx>
34 #include "imivctl.hxx"
35 #include <svtools/svmedit.hxx>
40 #define IMPICNVIEW_ACC_RETURN 1
41 #define IMPICNVIEW_ACC_ESCAPE 2
43 #define DRAWTEXT_FLAGS_ICON \
44 ( TEXT_DRAW_CENTER | TEXT_DRAW_TOP | TEXT_DRAW_ENDELLIPSIS | \
45 TEXT_DRAW_CLIP | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MNEMONIC )
47 #define DRAWTEXT_FLAGS_SMALLICON (TEXT_DRAW_LEFT|TEXT_DRAW_ENDELLIPSIS|TEXT_DRAW_CLIP)
49 #define EVENTID_SHOW_CURSOR ((void*)1)
50 #define EVENTID_ADJUST_SCROLLBARS ((void*)2)
52 struct SvxIconChoiceCtrlEntry_Impl
54 SvxIconChoiceCtrlEntry
* _pEntry
;
56 SvxIconChoiceCtrlEntry_Impl( SvxIconChoiceCtrlEntry
* pEntry
, const Rectangle
& rBoundRect
)
57 : _pEntry( pEntry
), _aPos( rBoundRect
.TopLeft()) {}
60 static sal_Bool bEndScrollInvalidate
= sal_True
;
62 class IcnViewEdit_Impl
: public MultiLineEdit
65 Accelerator aAccReturn
;
66 Accelerator aAccEscape
;
69 sal_Bool bAlreadyInCallback
;
72 void CallCallBackHdl_Impl();
73 DECL_LINK(Timeout_Impl
, void *);
74 DECL_LINK( ReturnHdl_Impl
, Accelerator
* );
75 DECL_LINK( EscapeHdl_Impl
, Accelerator
* );
80 SvtIconChoiceCtrl
* pParent
,
83 const OUString
& rData
,
84 const Link
& rNotifyEditEnd
);
87 virtual void KeyInput( const KeyEvent
& rKEvt
);
88 virtual long PreNotify( NotifyEvent
& rNEvt
);
89 sal_Bool
EditingCanceled() const { return bCanceled
; }
90 void StopEditing( sal_Bool bCancel
= sal_False
);
91 sal_Bool
IsGrabFocus() const { return bGrabFocus
; }
94 SvxIconChoiceCtrl_Impl::SvxIconChoiceCtrl_Impl(
95 SvtIconChoiceCtrl
* pCurView
,
99 aVerSBar( pCurView
, WB_DRAG
| WB_VSCROLL
),
100 aHorSBar( pCurView
, WB_DRAG
| WB_HSCROLL
),
101 aScrBarBox( pCurView
),
102 aImageSize( 32, 32 ),
105 bChooseWithCursor
=sal_False
;
108 pCurHighlightFrame
= 0;
115 bUpdateMode
= sal_True
;
116 bEntryEditingEnabled
= sal_False
;
117 bHighlightFramePressed
= sal_False
;
118 eSelectionMode
= MULTIPLE_SELECTION
;
120 pZOrderList
= new SvxIconChoiceCtrlEntryList_impl();
121 ePositionMode
= IcnViewPositionModeFree
;
122 SetStyle( nWinStyle
);
124 nUserEventAdjustScrBars
= 0;
125 nUserEventShowCursor
= 0;
126 nMaxVirtWidth
= DEFAULT_MAX_VIRT_WIDTH
;
127 nMaxVirtHeight
= DEFAULT_MAX_VIRT_HEIGHT
;
132 eTextMode
= IcnShowTextShort
;
133 pImpCursor
= new IcnCursor_Impl( this );
134 pGridMap
= new IcnGridMap_Impl( this );
136 aVerSBar
.SetScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl
, ScrollUpDownHdl
) );
137 aHorSBar
.SetScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl
, ScrollLeftRightHdl
) );
138 Link
aEndScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl
, EndScrollHdl
) );
139 aVerSBar
.SetEndScrollHdl( aEndScrollHdl
);
140 aHorSBar
.SetEndScrollHdl( aEndScrollHdl
);
142 nHorSBarHeight
= aHorSBar
.GetSizePixel().Height();
143 nVerSBarWidth
= aVerSBar
.GetSizePixel().Width();
145 aEditTimer
.SetTimeout( 800 );
146 aEditTimer
.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl
,EditTimeoutHdl
));
147 aAutoArrangeTimer
.SetTimeout( 100 );
148 aAutoArrangeTimer
.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl
,AutoArrangeHdl
));
149 aCallSelectHdlTimer
.SetTimeout( 500 );
150 aCallSelectHdlTimer
.SetTimeoutHdl( LINK(this,SvxIconChoiceCtrl_Impl
,CallSelectHdlHdl
));
152 aDocRectChangedTimer
.SetTimeout( 50 );
153 aDocRectChangedTimer
.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl
,DocRectChangedHdl
));
154 aVisRectChangedTimer
.SetTimeout( 50 );
155 aVisRectChangedTimer
.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl
,VisRectChangedHdl
));
159 SetGrid( Size(100, 70) );
162 SvxIconChoiceCtrl_Impl::~SvxIconChoiceCtrl_Impl()
175 delete pEntryPaintDev
;
176 ClearSelectedRectList();
180 void SvxIconChoiceCtrl_Impl::Clear( sal_Bool bInCtor
)
182 StopEntryEditing( sal_True
);
184 pCurHighlightFrame
= 0;
187 ShowCursor( sal_False
);
188 bBoundRectsDirty
= sal_False
;
191 nFlags
&= ~(F_PAINTED
| F_MOVED_ENTRIES
);
197 aVirtOutputSize
.Width() = 0;
198 aVirtOutputSize
.Height() = 0;
199 Size
aSize( pView
->GetOutputSizePixel() );
200 nMaxVirtWidth
= aSize
.Width() - nVerSBarWidth
;
201 if( nMaxVirtWidth
<= 0 )
202 nMaxVirtWidth
= DEFAULT_MAX_VIRT_WIDTH
;
203 nMaxVirtHeight
= aSize
.Height() - nHorSBarHeight
;
204 if( nMaxVirtHeight
<= 0 )
205 nMaxVirtHeight
= DEFAULT_MAX_VIRT_HEIGHT
;
206 pZOrderList
->clear();
207 SetOrigin( Point() );
209 pView
->Invalidate(INVALIDATE_NOCHILDREN
);
212 size_t nCount
= aEntries
.size();
213 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
215 SvxIconChoiceCtrlEntry
* pCur
= aEntries
[ nCur
];
223 void SvxIconChoiceCtrl_Impl::SetStyle( WinBits nWinStyle
)
225 nWinBits
= nWinStyle
;
226 nCurTextDrawFlags
= DRAWTEXT_FLAGS_ICON
;
227 if( nWinBits
& (WB_SMALLICON
| WB_DETAILS
) )
228 nCurTextDrawFlags
= DRAWTEXT_FLAGS_SMALLICON
;
229 if( nWinBits
& WB_NOSELECTION
)
230 eSelectionMode
= NO_SELECTION
;
231 if( !(nWinStyle
& (WB_ALIGN_TOP
| WB_ALIGN_LEFT
)))
232 nWinBits
|= WB_ALIGN_LEFT
;
233 if( (nWinStyle
& WB_DETAILS
))
236 SetColumn( 0, SvxIconChoiceCtrlColumnInfo( 0, 100, IcnViewAlignLeft
));
240 IMPL_LINK( SvxIconChoiceCtrl_Impl
, ScrollUpDownHdl
, ScrollBar
*, pScrollBar
)
242 StopEntryEditing( sal_True
);
243 // arrow up: delta=-1; arrow down: delta=+1
244 Scroll( 0, pScrollBar
->GetDelta(), sal_True
);
245 bEndScrollInvalidate
= sal_True
;
249 IMPL_LINK( SvxIconChoiceCtrl_Impl
, ScrollLeftRightHdl
, ScrollBar
*, pScrollBar
)
251 StopEntryEditing( sal_True
);
252 // arrow left: delta=-1; arrow right: delta=+1
253 Scroll( pScrollBar
->GetDelta(), 0, sal_True
);
254 bEndScrollInvalidate
= sal_True
;
258 IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl
, EndScrollHdl
)
260 if( pView
->HasBackground() && !pView
->GetBackground().IsScrollable() &&
261 bEndScrollInvalidate
)
263 pView
->Invalidate(INVALIDATE_NOCHILDREN
);
268 void SvxIconChoiceCtrl_Impl::FontModified()
274 DELETEZ(pEntryPaintDev
);
275 SetDefaultTextSize();
276 ShowCursor( sal_False
);
277 ShowCursor( sal_True
);
280 void SvxIconChoiceCtrl_Impl::InsertEntry( SvxIconChoiceCtrlEntry
* pEntry
, size_t nPos
,
284 aEntries
.insert( nPos
, pEntry
);
285 if( (nFlags
& F_ENTRYLISTPOS_VALID
) && nPos
>= aEntries
.size() - 1 )
286 pEntry
->nPos
= aEntries
.size() - 1;
288 nFlags
&= ~F_ENTRYLISTPOS_VALID
;
290 pZOrderList
->push_back( pEntry
);
294 Size
aSize( CalcBoundingSize( pEntry
) );
295 SetBoundingRect_Impl( pEntry
, *pPos
, aSize
);
296 SetEntryPos( pEntry
, *pPos
, sal_False
, sal_True
, sal_True
/*keep grid map*/ );
297 pEntry
->nFlags
|= ICNVIEW_FLAG_POS_MOVED
;
298 SetEntriesMoved( sal_True
);
302 // If the UpdateMode is sal_True, don't set all bounding rectangles to
303 // 'to be checked', but only the bounding rectangle of the new entry.
304 // Thus, don't call InvalidateBoundingRect!
305 pEntry
->aRect
.Right() = LONG_MAX
;
308 FindBoundingRect( pEntry
);
309 Rectangle
aOutputArea( GetOutputRect() );
310 pGridMap
->OccupyGrids( pEntry
);
311 if( !aOutputArea
.IsOver( pEntry
->aRect
) )
312 return; // is invisible
313 pView
->Invalidate( pEntry
->aRect
);
316 InvalidateBoundingRect( pEntry
->aRect
);
320 void SvxIconChoiceCtrl_Impl::CreateAutoMnemonics( MnemonicGenerator
* _pGenerator
)
322 ::std::auto_ptr
< MnemonicGenerator
> pAutoDeleteOwnGenerator
;
325 _pGenerator
= new MnemonicGenerator
;
326 pAutoDeleteOwnGenerator
.reset( _pGenerator
);
329 sal_uLong nEntryCount
= GetEntryCount();
332 // insert texts in generator
333 for( i
= 0; i
< nEntryCount
; ++i
)
335 DBG_ASSERT( GetEntry( i
), "-SvxIconChoiceCtrl_Impl::CreateAutoMnemonics(): more expected than provided!" );
337 _pGenerator
->RegisterMnemonic( GetEntry( i
)->GetText() );
340 // exchange texts with generated mnemonics
341 for( i
= 0; i
< nEntryCount
; ++i
)
343 SvxIconChoiceCtrlEntry
* pEntry
= GetEntry( i
);
344 OUString aTxt
= pEntry
->GetText();
346 OUString aNewText
= _pGenerator
->CreateMnemonic( aTxt
);
347 if( aNewText
!= aTxt
)
348 pEntry
->SetText( aNewText
);
352 Rectangle
SvxIconChoiceCtrl_Impl::GetOutputRect() const
354 Point
aOrigin( pView
->GetMapMode().GetOrigin() );
356 return Rectangle( aOrigin
, aOutputSize
);
359 void SvxIconChoiceCtrl_Impl::SetListPositions()
361 if( nFlags
& F_ENTRYLISTPOS_VALID
)
364 size_t nCount
= aEntries
.size();
365 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
367 SvxIconChoiceCtrlEntry
* pEntry
= aEntries
[ nCur
];
370 nFlags
|= F_ENTRYLISTPOS_VALID
;
373 void SvxIconChoiceCtrl_Impl::SelectEntry( SvxIconChoiceCtrlEntry
* pEntry
, sal_Bool bSelect
,
374 sal_Bool bCallHdl
, sal_Bool bAdd
, sal_Bool bSyncPaint
)
376 if( eSelectionMode
== NO_SELECTION
)
381 if ( 0 == ( nFlags
& F_CLEARING_SELECTION
) )
383 nFlags
|= F_CLEARING_SELECTION
;
384 DeselectAllBut( pEntry
, sal_True
);
385 nFlags
&= ~F_CLEARING_SELECTION
;
388 if( pEntry
->IsSelected() != bSelect
)
391 sal_uInt16 nEntryFlags
= pEntry
->GetFlags();
394 nEntryFlags
|= ICNVIEW_FLAG_SELECTED
;
395 pEntry
->AssignFlags( nEntryFlags
);
398 CallSelectHandler( pEntry
);
402 nEntryFlags
&= ~( ICNVIEW_FLAG_SELECTED
);
403 pEntry
->AssignFlags( nEntryFlags
);
406 CallSelectHandler( 0 );
408 EntrySelected( pEntry
, bSelect
, bSyncPaint
);
412 void SvxIconChoiceCtrl_Impl::EntrySelected( SvxIconChoiceCtrlEntry
* pEntry
, sal_Bool bSelect
,
413 sal_Bool bSyncPaint
)
415 // When using SingleSelection, make sure that the cursor is always placed
416 // over the (only) selected entry. (But only if a cursor exists.)
417 if( bSelect
&& pCursor
&&
418 eSelectionMode
== SINGLE_SELECTION
&&
422 //DBG_ASSERT(pView->GetSelectionCount()==1,"selection count?")
425 // Not when dragging though, else the loop in SelectRect doesn't work
427 if( !(nFlags
& F_SELECTING_RECT
) )
431 if( pEntry
== pCursor
)
432 ShowCursor( sal_False
);
433 if( pView
->IsTracking() && (bSelect
|| !pView
->HasBackground()) ) // always synchronous when tracking
434 PaintEntry( pEntry
);
435 else if( bSyncPaint
) // synchronous & with a virtual OutDev!
436 PaintEntryVirtOutDev( pEntry
);
439 pView
->Invalidate( CalcFocusRect( pEntry
) );
441 if( pEntry
== pCursor
)
442 ShowCursor( sal_True
);
445 // #i101012# emit vcl event LISTBOX_SELECT only in case that the given entry is selected.
448 CallEventListeners( VCLEVENT_LISTBOX_SELECT
, pEntry
);
452 void SvxIconChoiceCtrl_Impl::ResetVirtSize()
455 aVirtOutputSize
.Width() = 0;
456 aVirtOutputSize
.Height() = 0;
457 const size_t nCount
= aEntries
.size();
458 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
460 SvxIconChoiceCtrlEntry
* pCur
= aEntries
[ nCur
];
461 pCur
->ClearFlags( ICNVIEW_FLAG_POS_MOVED
);
462 if( pCur
->IsPosLocked() )
464 // adapt (among others) VirtSize
465 if( !IsBoundingRectValid( pCur
->aRect
) )
466 FindBoundingRect( pCur
);
468 AdjustVirtSize( pCur
->aRect
);
471 InvalidateBoundingRect( pCur
->aRect
);
474 if( !(nWinBits
& (WB_NOVSCROLL
| WB_NOHSCROLL
)) )
476 Size
aRealOutputSize( pView
->GetOutputSizePixel() );
477 if( aVirtOutputSize
.Width() < aRealOutputSize
.Width() ||
478 aVirtOutputSize
.Height() < aRealOutputSize
.Height() )
480 sal_uLong nGridCount
= IcnGridMap_Impl::GetGridCount(
481 aRealOutputSize
, (sal_uInt16
)nGridDX
, (sal_uInt16
)nGridDY
);
482 if( nGridCount
< nCount
)
484 if( nWinBits
& WB_ALIGN_TOP
)
485 nMaxVirtWidth
= aRealOutputSize
.Width() - nVerSBarWidth
;
486 else // WB_ALIGN_LEFT
487 nMaxVirtHeight
= aRealOutputSize
.Height() - nHorSBarHeight
;
497 void SvxIconChoiceCtrl_Impl::AdjustVirtSize( const Rectangle
& rRect
)
499 long nHeightOffs
= 0;
502 if( aVirtOutputSize
.Width() < (rRect
.Right()+LROFFS_WINBORDER
) )
503 nWidthOffs
= (rRect
.Right()+LROFFS_WINBORDER
) - aVirtOutputSize
.Width();
505 if( aVirtOutputSize
.Height() < (rRect
.Bottom()+TBOFFS_WINBORDER
) )
506 nHeightOffs
= (rRect
.Bottom()+TBOFFS_WINBORDER
) - aVirtOutputSize
.Height();
508 if( nWidthOffs
|| nHeightOffs
)
511 aVirtOutputSize
.Width() += nWidthOffs
;
512 aRange
.Max() = aVirtOutputSize
.Width();
513 aHorSBar
.SetRange( aRange
);
515 aVirtOutputSize
.Height() += nHeightOffs
;
516 aRange
.Max() = aVirtOutputSize
.Height();
517 aVerSBar
.SetRange( aRange
);
520 pGridMap
->OutputSizeChanged();
526 void SvxIconChoiceCtrl_Impl::InitPredecessors()
528 DBG_ASSERT(!pHead
,"SvxIconChoiceCtrl_Impl::InitPredecessors() >> Already initialized");
529 size_t nCount
= aEntries
.size();
532 SvxIconChoiceCtrlEntry
* pPrev
= aEntries
[ 0 ];
533 for( size_t nCur
= 1; nCur
<= nCount
; nCur
++ )
535 pPrev
->ClearFlags( ICNVIEW_FLAG_POS_LOCKED
| ICNVIEW_FLAG_POS_MOVED
|
536 ICNVIEW_FLAG_PRED_SET
);
538 SvxIconChoiceCtrlEntry
* pNext
;
540 pNext
= aEntries
[ 0 ];
542 pNext
= aEntries
[ nCur
];
543 pPrev
->pflink
= pNext
;
544 pNext
->pblink
= pPrev
;
547 pHead
= aEntries
[ 0 ];
551 nFlags
&= ~F_MOVED_ENTRIES
;
554 void SvxIconChoiceCtrl_Impl::ClearPredecessors()
558 size_t nCount
= aEntries
.size();
559 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
561 SvxIconChoiceCtrlEntry
* pCur
= aEntries
[ nCur
];
564 pCur
->ClearFlags( ICNVIEW_FLAG_PRED_SET
);
570 void SvxIconChoiceCtrl_Impl::Arrange( sal_Bool bKeepPredecessors
, long nSetMaxVirtWidth
, long nSetMaxVirtHeight
)
572 if ( nSetMaxVirtWidth
!= 0 )
573 nMaxVirtWidth
= nSetMaxVirtWidth
;
575 nMaxVirtWidth
= aOutputSize
.Width();
577 if ( nSetMaxVirtHeight
!= 0 )
578 nMaxVirtHeight
= nSetMaxVirtHeight
;
580 nMaxVirtHeight
= aOutputSize
.Height();
582 ImpArrange( bKeepPredecessors
);
585 void SvxIconChoiceCtrl_Impl::ImpArrange( sal_Bool bKeepPredecessors
)
587 static Point aEmptyPoint
;
589 sal_Bool bOldUpdate
= bUpdateMode
;
590 Rectangle
aCurOutputArea( GetOutputRect() );
591 if( (nWinBits
& WB_SMART_ARRANGE
) && aCurOutputArea
.TopLeft() != aEmptyPoint
)
592 bUpdateMode
= sal_False
;
593 aAutoArrangeTimer
.Stop();
594 nFlags
&= ~F_MOVED_ENTRIES
;
595 nFlags
|= F_ARRANGING
;
597 ShowCursor( sal_False
);
599 if( !bKeepPredecessors
)
601 bBoundRectsDirty
= sal_False
;
602 SetOrigin( Point() );
604 RecalcAllBoundingRectsSmart();
605 // TODO: the invalidation in the detail view should be more intelligent
606 //if( !(nWinBits & WB_DETAILS ))
607 pView
->Invalidate( INVALIDATE_NOCHILDREN
);
608 nFlags
&= ~F_ARRANGING
;
609 if( (nWinBits
& WB_SMART_ARRANGE
) && aCurOutputArea
.TopLeft() != aEmptyPoint
)
611 MakeVisible( aCurOutputArea
);
612 SetUpdateMode( bOldUpdate
);
614 ShowCursor( sal_True
);
617 void SvxIconChoiceCtrl_Impl::Paint( const Rectangle
& rRect
)
619 bEndScrollInvalidate
= sal_False
;
621 #if defined(OV_DRAWGRID)
622 Color
aOldColor ( pView
->GetLineColor() );
623 Color
aColor( COL_BLACK
);
624 pView
->SetLineColor( aColor
);
625 Point
aOffs( pView
->GetMapMode().GetOrigin());
626 Size
aXSize( pView
->GetOutputSizePixel() );
629 Point
aStart( LROFFS_WINBORDER
, 0 );
630 Point
aEnd( LROFFS_WINBORDER
, aXSize
.Height());
633 pView
->DrawLine( aStart
, aEnd
);
636 Point
aStart( 0, TBOFFS_WINBORDER
);
637 Point
aEnd( aXSize
.Width(), TBOFFS_WINBORDER
);
640 pView
->DrawLine( aStart
, aEnd
);
643 for( long nDX
= nGridDX
; nDX
<= aXSize
.Width(); nDX
+= nGridDX
)
645 Point
aStart( nDX
+LROFFS_WINBORDER
, 0 );
646 Point
aEnd( nDX
+LROFFS_WINBORDER
, aXSize
.Height());
649 pView
->DrawLine( aStart
, aEnd
);
651 for( long nDY
= nGridDY
; nDY
<= aXSize
.Height(); nDY
+= nGridDY
)
653 Point
aStart( 0, nDY
+TBOFFS_WINBORDER
);
654 Point
aEnd( aXSize
.Width(), nDY
+TBOFFS_WINBORDER
);
657 pView
->DrawLine( aStart
, aEnd
);
659 pView
->SetLineColor( aOldColor
);
663 if( !aEntries
.size() )
667 // set cursor to item with focus-flag
668 sal_Bool bfound
= sal_False
;
669 for ( sal_uLong i
= 0; i
< pView
->GetEntryCount() && !bfound
; i
++)
671 SvxIconChoiceCtrlEntry
* pEntry
= pView
->GetEntry ( i
);
672 if( pEntry
->IsFocused() )
680 pCursor
= aEntries
[ 0 ];
683 // Show Focus at Init-Time
684 if ( pView
->HasFocus() )
687 size_t nCount
= pZOrderList
->size();
691 sal_Bool bResetClipRegion
= sal_False
;
692 if( !pView
->IsClipRegion() )
694 Region
const aOutputArea( GetOutputRect() );
695 bResetClipRegion
= sal_True
;
696 pView
->SetClipRegion( aOutputArea
);
699 SvxIconChoiceCtrlEntryList_impl
* pNewZOrderList
= new SvxIconChoiceCtrlEntryList_impl();
700 SvxIconChoiceCtrlEntryList_impl
* pPaintedEntries
= new SvxIconChoiceCtrlEntryList_impl();
705 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[ nPos
];
706 const Rectangle
& rBoundRect
= GetEntryBoundRect( pEntry
);
707 if( rRect
.IsOver( rBoundRect
) )
709 PaintEntry( pEntry
, rBoundRect
.TopLeft(), pView
, sal_True
);
710 // set entries to Top if they are being repainted
711 pPaintedEntries
->push_back( pEntry
);
714 pNewZOrderList
->push_back( pEntry
);
720 pZOrderList
= pNewZOrderList
;
721 nCount
= pPaintedEntries
->size();
724 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
725 pZOrderList
->push_back( (*pPaintedEntries
)[ nCur
] );
727 delete pPaintedEntries
;
729 if( bResetClipRegion
)
730 pView
->SetClipRegion();
733 void SvxIconChoiceCtrl_Impl::RepaintEntries( sal_uInt16 nEntryFlagsMask
)
735 const size_t nCount
= pZOrderList
->size();
739 sal_Bool bResetClipRegion
= sal_False
;
740 Rectangle
aOutRect( GetOutputRect() );
741 if( !pView
->IsClipRegion() )
743 bResetClipRegion
= sal_True
;
744 pView
->SetClipRegion(Region(aOutRect
));
746 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
748 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[ nCur
];
749 if( pEntry
->GetFlags() & nEntryFlagsMask
)
751 const Rectangle
& rBoundRect
= GetEntryBoundRect( pEntry
);
752 if( aOutRect
.IsOver( rBoundRect
) )
753 PaintEntry( pEntry
, rBoundRect
.TopLeft() );
756 if( bResetClipRegion
)
757 pView
->SetClipRegion();
761 void SvxIconChoiceCtrl_Impl::InitScrollBarBox()
763 aScrBarBox
.SetSizePixel( Size(nVerSBarWidth
-1, nHorSBarHeight
-1) );
764 Size
aSize( pView
->GetOutputSizePixel() );
765 aScrBarBox
.SetPosPixel( Point(aSize
.Width()-nVerSBarWidth
+1, aSize
.Height()-nHorSBarHeight
+1));
768 sal_Bool
SvxIconChoiceCtrl_Impl::MouseButtonDown( const MouseEvent
& rMEvt
)
770 sal_Bool bHandled
= sal_True
;
771 bHighlightFramePressed
= sal_False
;
773 sal_Bool bGotFocus
= (sal_Bool
)(!pView
->HasFocus() && !(nWinBits
& WB_NOPOINTERFOCUS
));
774 if( !(nWinBits
& WB_NOPOINTERFOCUS
) )
777 Point
aDocPos( rMEvt
.GetPosPixel() );
778 if(aDocPos
.X()>=aOutputSize
.Width() || aDocPos
.Y()>=aOutputSize
.Height())
781 SvxIconChoiceCtrlEntry
* pEntry
= GetEntry( aDocPos
, sal_True
);
783 MakeEntryVisible( pEntry
, sal_False
);
785 if( rMEvt
.IsShift() && eSelectionMode
!= SINGLE_SELECTION
)
788 SetCursor_Impl( pCursor
, pEntry
, rMEvt
.IsMod1(), rMEvt
.IsShift(), sal_True
);
792 if( pAnchor
&& (rMEvt
.IsShift() || rMEvt
.IsMod1())) // keyboard selection?
794 DBG_ASSERT(eSelectionMode
!= SINGLE_SELECTION
,"Invalid selection mode");
796 nFlags
|= F_ADD_MODE
;
798 if( rMEvt
.IsShift() )
800 Rectangle
aRect( GetEntryBoundRect( pAnchor
));
802 aRect
.Union( GetEntryBoundRect( pEntry
) );
805 Rectangle
aTempRect( aDocPos
, Size(1,1));
806 aRect
.Union( aTempRect
);
808 aCurSelectionRect
= aRect
;
809 SelectRect( aRect
, (nFlags
& F_ADD_MODE
)!=0, &aSelectedRectList
);
811 else if( rMEvt
.IsMod1() )
813 AddSelectedRect( aCurSelectionRect
);
815 aCurSelectionRect
.SetPos( aDocPos
);
818 if( !pEntry
&& !(nWinBits
& WB_NODRAGSELECTION
))
819 pView
->StartTracking( STARTTRACK_SCROLLREPEAT
);
826 if( eSelectionMode
== MULTIPLE_SELECTION
)
828 if( !rMEvt
.IsMod1() ) // Ctrl
833 ClearSelectedRectList();
837 nFlags
|= F_ADD_MODE
;
838 aCurSelectionRect
.SetPos( aDocPos
);
839 pView
->StartTracking( STARTTRACK_SCROLLREPEAT
);
842 bHandled
= sal_False
;
846 sal_Bool bSelected
= pEntry
->IsSelected();
847 sal_Bool bEditingEnabled
= IsEntryEditingEnabled();
849 if( rMEvt
.GetClicks() == 2 )
851 DeselectAllBut( pEntry
);
852 SelectEntry( pEntry
, sal_True
, sal_True
, sal_False
, sal_True
);
859 if( rMEvt
.IsMod2() ) // Alt?
861 if( bEntryEditingEnabled
&& pEntry
&&
862 pEntry
->IsSelected())
864 if( pView
->EditingEntry( pEntry
))
868 else if( eSelectionMode
== SINGLE_SELECTION
)
870 DeselectAllBut( pEntry
);
872 if( bEditingEnabled
&& bSelected
&& !rMEvt
.GetModifier() &&
873 rMEvt
.IsLeft() && IsTextHit( pEntry
, aDocPos
) )
875 nFlags
|= F_START_EDITTIMER_IN_MOUSEUP
;
878 else if( eSelectionMode
== NO_SELECTION
)
880 if( rMEvt
.IsLeft() && (nWinBits
& WB_HIGHLIGHTFRAME
) )
882 pCurHighlightFrame
= 0; // force repaint of frame
883 bHighlightFramePressed
= sal_True
;
884 SetEntryHighlightFrame( pEntry
, sal_True
);
889 if( !rMEvt
.GetModifier() && rMEvt
.IsLeft() )
893 DeselectAllBut( pEntry
, sal_True
/* paint synchronously */ );
895 SelectEntry( pEntry
, sal_True
, sal_True
, sal_False
, sal_True
);
899 // deselect only in the Up, if the Move happened via D&D!
900 nFlags
|= F_DOWN_DESELECT
;
901 if( bEditingEnabled
&& IsTextHit( pEntry
, aDocPos
) &&
904 nFlags
|= F_START_EDITTIMER_IN_MOUSEUP
;
908 else if( rMEvt
.IsMod1() )
909 nFlags
|= F_DOWN_CTRL
;
915 sal_Bool
SvxIconChoiceCtrl_Impl::MouseButtonUp( const MouseEvent
& rMEvt
)
917 sal_Bool bHandled
= sal_False
;
918 if( rMEvt
.IsRight() && (nFlags
& (F_DOWN_CTRL
| F_DOWN_DESELECT
) ))
920 nFlags
&= ~(F_DOWN_CTRL
| F_DOWN_DESELECT
);
924 Point
aDocPos( rMEvt
.GetPosPixel() );
926 SvxIconChoiceCtrlEntry
* pDocEntry
= GetEntry( aDocPos
);
929 if( nFlags
& F_DOWN_CTRL
)
931 // Ctrl & MultiSelection
932 ToggleSelection( pDocEntry
);
933 SetCursor( pDocEntry
);
936 else if( nFlags
& F_DOWN_DESELECT
)
938 DeselectAllBut( pDocEntry
);
939 SetCursor( pDocEntry
);
940 SelectEntry( pDocEntry
, sal_True
, sal_True
, sal_False
, sal_True
);
945 nFlags
&= ~(F_DOWN_CTRL
| F_DOWN_DESELECT
);
946 if( nFlags
& F_START_EDITTIMER_IN_MOUSEUP
)
950 nFlags
&= ~F_START_EDITTIMER_IN_MOUSEUP
;
953 if((nWinBits
& WB_HIGHLIGHTFRAME
) && bHighlightFramePressed
&& pCurHighlightFrame
)
956 SvxIconChoiceCtrlEntry
* pEntry
= pCurHighlightFrame
;
957 pCurHighlightFrame
= 0; // force repaint of frame
958 bHighlightFramePressed
= sal_False
;
959 SetEntryHighlightFrame( pEntry
, sal_True
);
961 pHdlEntry
= pCurHighlightFrame
;
965 SvxIconChoiceCtrlEntry
* pOldCursor
= pCursor
;
966 SetCursor_Impl( pOldCursor
, pHdlEntry
, sal_False
, sal_False
, sal_True
);
973 sal_Bool
SvxIconChoiceCtrl_Impl::MouseMove( const MouseEvent
& rMEvt
)
975 const Point
aDocPos( pView
->PixelToLogic(rMEvt
.GetPosPixel()) );
977 if( pView
->IsTracking() )
979 else if( nWinBits
& WB_HIGHLIGHTFRAME
)
981 SvxIconChoiceCtrlEntry
* pEntry
= GetEntry( aDocPos
, sal_True
);
982 SetEntryHighlightFrame( pEntry
);
989 void SvxIconChoiceCtrl_Impl::SetCursor_Impl( SvxIconChoiceCtrlEntry
* pOldCursor
,
990 SvxIconChoiceCtrlEntry
* pNewCursor
, sal_Bool bMod1
, sal_Bool bShift
, sal_Bool bPaintSync
)
994 SvxIconChoiceCtrlEntry
* pFilterEntry
= 0;
995 sal_Bool bDeselectAll
= sal_False
;
996 if( eSelectionMode
!= SINGLE_SELECTION
)
998 if( !bMod1
&& !bShift
)
999 bDeselectAll
= sal_True
;
1000 else if( bShift
&& !bMod1
&& !pAnchor
)
1002 bDeselectAll
= sal_True
;
1003 pFilterEntry
= pOldCursor
;
1007 DeselectAllBut( pFilterEntry
, bPaintSync
);
1008 ShowCursor( sal_False
);
1009 MakeEntryVisible( pNewCursor
);
1010 SetCursor( pNewCursor
);
1011 if( bMod1
&& !bShift
)
1015 AddSelectedRect( pAnchor
, pOldCursor
);
1022 pAnchor
= pOldCursor
;
1023 if ( nWinBits
& WB_ALIGN_LEFT
)
1024 SelectRange( pAnchor
, pNewCursor
, (nFlags
& F_ADD_MODE
)!=0 );
1026 SelectRect(pAnchor
,pNewCursor
,(nFlags
& F_ADD_MODE
)!=0,&aSelectedRectList
);
1030 SelectEntry( pCursor
, sal_True
, sal_True
, sal_False
, bPaintSync
);
1031 aCurSelectionRect
= GetEntryBoundRect( pCursor
);
1036 sal_Bool
SvxIconChoiceCtrl_Impl::KeyInput( const KeyEvent
& rKEvt
)
1040 sal_Bool bMod2
= rKEvt
.GetKeyCode().IsMod2();
1041 sal_Unicode cChar
= rKEvt
.GetCharCode();
1042 sal_uLong nPos
= (sal_uLong
)-1;
1043 if ( bMod2
&& cChar
&& IsMnemonicChar( cChar
, nPos
) )
1045 // shortcut is clicked
1046 SvxIconChoiceCtrlEntry
* pNewCursor
= GetEntry( nPos
);
1047 SvxIconChoiceCtrlEntry
* pOldCursor
= pCursor
;
1048 if ( pNewCursor
!= pOldCursor
)
1049 SetCursor_Impl( pOldCursor
, pNewCursor
, sal_False
, sal_False
, sal_False
);
1054 // no actions with <ALT>
1057 sal_Bool bKeyUsed
= sal_True
;
1058 sal_Bool bMod1
= rKEvt
.GetKeyCode().IsMod1();
1059 sal_Bool bShift
= rKEvt
.GetKeyCode().IsShift();
1061 if( eSelectionMode
== SINGLE_SELECTION
|| eSelectionMode
== NO_SELECTION
)
1068 nFlags
|= F_ADD_MODE
;
1070 SvxIconChoiceCtrlEntry
* pNewCursor
;
1071 SvxIconChoiceCtrlEntry
* pOldCursor
= pCursor
;
1073 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
1080 MakeEntryVisible( pCursor
);
1081 if( nCode
== KEY_UP
)
1082 pNewCursor
= pImpCursor
->GoUpDown(pCursor
,sal_False
);
1084 pNewCursor
= pImpCursor
->GoPageUpDown(pCursor
,sal_False
);
1085 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, sal_True
);
1088 Rectangle
aRect( GetEntryBoundRect( pCursor
) );
1091 aRect
.Bottom() -= aRect
.Top();
1093 MakeVisible( aRect
);
1097 if ( bChooseWithCursor
&& pNewCursor
!= NULL
)
1099 pHdlEntry
= pNewCursor
;//GetCurEntry();
1100 pCurHighlightFrame
= pHdlEntry
;
1102 pCurHighlightFrame
= NULL
;
1111 if( nCode
== KEY_DOWN
)
1112 pNewCursor
=pImpCursor
->GoUpDown( pCursor
,sal_True
);
1114 pNewCursor
=pImpCursor
->GoPageUpDown( pCursor
,sal_True
);
1115 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, sal_True
);
1117 if ( bChooseWithCursor
&& pNewCursor
!= NULL
)
1119 pHdlEntry
= pNewCursor
;//GetCurEntry();
1120 pCurHighlightFrame
= pHdlEntry
;
1122 pCurHighlightFrame
= NULL
;
1130 pNewCursor
=pImpCursor
->GoLeftRight(pCursor
,sal_True
);
1131 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, sal_True
);
1138 MakeEntryVisible( pCursor
);
1139 pNewCursor
= pImpCursor
->GoLeftRight(pCursor
,sal_False
);
1140 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, sal_True
);
1143 Rectangle
aRect( GetEntryBoundRect(pCursor
));
1146 aRect
.Right() -= aRect
.Left();
1148 MakeVisible( aRect
);
1155 if( !bMod1
&& !bShift
)
1156 EditTimeoutHdl( 0 );
1158 bKeyUsed
= sal_False
;
1162 if( rKEvt
.GetKeyCode().IsShift() )
1164 if( nFlags
& F_ADD_MODE
)
1165 nFlags
&= (~F_ADD_MODE
);
1167 nFlags
|= F_ADD_MODE
;
1170 bKeyUsed
= sal_False
;
1174 if( pCursor
&& eSelectionMode
!= SINGLE_SELECTION
)
1178 //SelectAll( sal_False );
1180 ClearSelectedRectList();
1182 // click Icon with spacebar
1183 SetEntryHighlightFrame( GetCurEntry(), sal_True
);
1185 pHdlEntry
= pCurHighlightFrame
;
1186 pCurHighlightFrame
=0;
1189 ToggleSelection( pCursor
);
1195 if( rKEvt
.GetKeyCode().IsShift() )
1198 pView
->SetEntryTextMode( IcnShowTextFull
, pCursor
);
1200 if( rKEvt
.GetKeyCode().IsMod1() )
1203 pView
->SetEntryTextMode( IcnShowTextShort
, pCursor
);
1211 if( bMod1
&& (eSelectionMode
!= SINGLE_SELECTION
))
1212 SelectAll( sal_True
);
1214 bKeyUsed
= sal_False
;
1222 bKeyUsed
= sal_False
;
1228 if( pCursor
&& bEntryEditingEnabled
)
1229 /*pView->*/EditEntry( pCursor
);
1232 bKeyUsed
= sal_False
;
1238 pNewCursor
= aEntries
[ aEntries
.size() - 1 ];
1239 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, sal_True
);
1246 pNewCursor
= aEntries
[ 0 ];
1247 SetCursor_Impl( pOldCursor
, pNewCursor
, bMod1
, bShift
, sal_True
);
1252 bKeyUsed
= sal_False
;
1258 // recalculate TopLeft of scrollbars (but not their sizes!)
1259 void SvxIconChoiceCtrl_Impl::PositionScrollBars( long nRealWidth
, long nRealHeight
)
1261 // horizontal scrollbar
1262 Point
aPos( 0, nRealHeight
);
1263 aPos
.Y() -= nHorSBarHeight
;
1265 if( aHorSBar
.GetPosPixel() != aPos
)
1266 aHorSBar
.SetPosPixel( aPos
);
1268 // vertical scrollbar
1269 aPos
.X() = nRealWidth
; aPos
.Y() = 0;
1270 aPos
.X() -= nVerSBarWidth
;
1274 if( aVerSBar
.GetPosPixel() != aPos
)
1275 aVerSBar
.SetPosPixel( aPos
);
1278 void SvxIconChoiceCtrl_Impl::AdjustScrollBars( sal_Bool
)
1280 Rectangle
aOldOutRect( GetOutputRect() );
1281 long nVirtHeight
= aVirtOutputSize
.Height();
1282 long nVirtWidth
= aVirtOutputSize
.Width();
1284 Size
aOSize( pView
->Control::GetOutputSizePixel() );
1285 long nRealHeight
= aOSize
.Height();
1286 long nRealWidth
= aOSize
.Width();
1288 PositionScrollBars( nRealWidth
, nRealHeight
);
1290 const MapMode
& rMapMode
= pView
->GetMapMode();
1291 Point
aOrigin( rMapMode
.GetOrigin() );
1294 if( nRealWidth
> nVirtWidth
)
1295 nVisibleWidth
= nVirtWidth
+ aOrigin
.X();
1297 nVisibleWidth
= nRealWidth
;
1299 long nVisibleHeight
;
1300 if( nRealHeight
> nVirtHeight
)
1301 nVisibleHeight
= nVirtHeight
+ aOrigin
.Y();
1303 nVisibleHeight
= nRealHeight
;
1305 sal_Bool bVerSBar
= ( nWinBits
& WB_VSCROLL
) != 0;
1306 sal_Bool bHorSBar
= ( nWinBits
& WB_HSCROLL
) != 0;
1307 sal_Bool bNoVerSBar
= ( nWinBits
& WB_NOVSCROLL
) != 0;
1308 sal_Bool bNoHorSBar
= ( nWinBits
& WB_NOHSCROLL
) != 0;
1310 sal_uInt16 nResult
= 0;
1313 // activate vertical scrollbar?
1314 if( !bNoVerSBar
&& (bVerSBar
|| ( nVirtHeight
> nVisibleHeight
)) )
1317 nRealWidth
-= nVerSBarWidth
;
1319 if( nRealWidth
> nVirtWidth
)
1320 nVisibleWidth
= nVirtWidth
+ aOrigin
.X();
1322 nVisibleWidth
= nRealWidth
;
1324 nFlags
|= F_HOR_SBARSIZE_WITH_VBAR
;
1326 // activate horizontal scrollbar?
1327 if( !bNoHorSBar
&& (bHorSBar
|| (nVirtWidth
> nVisibleWidth
)) )
1330 nRealHeight
-= nHorSBarHeight
;
1332 if( nRealHeight
> nVirtHeight
)
1333 nVisibleHeight
= nVirtHeight
+ aOrigin
.Y();
1335 nVisibleHeight
= nRealHeight
;
1337 // do we need a vertical scrollbar after all?
1338 if( !(nResult
& 0x0001) && // only if not already there
1339 ( !bNoVerSBar
&& ((nVirtHeight
> nVisibleHeight
) || bVerSBar
)) )
1341 nResult
= 3; // both turned on
1342 nRealWidth
-= nVerSBarWidth
;
1344 if( nRealWidth
> nVirtWidth
)
1345 nVisibleWidth
= nVirtWidth
+ aOrigin
.X();
1347 nVisibleWidth
= nRealWidth
;
1349 nFlags
|= F_VER_SBARSIZE_WITH_HBAR
;
1354 // size vertical scrollbar
1355 long nThumb
= aVerSBar
.GetThumbPos();
1356 Size
aSize( nVerSBarWidth
, nRealHeight
);
1357 aSize
.Height() += 2;
1358 if( aSize
!= aVerSBar
.GetSizePixel() )
1359 aVerSBar
.SetSizePixel( aSize
);
1360 aVerSBar
.SetVisibleSize( nVisibleHeight
);
1361 aVerSBar
.SetPageSize( GetScrollBarPageSize( nVisibleHeight
));
1363 if( nResult
& 0x0001 )
1365 aVerSBar
.SetThumbPos( nThumb
);
1370 aVerSBar
.SetThumbPos( 0 );
1374 // size horizontal scrollbar
1375 nThumb
= aHorSBar
.GetThumbPos();
1376 aSize
.Width() = nRealWidth
;
1377 aSize
.Height() = nHorSBarHeight
;
1379 if( nResult
& 0x0001 ) // vertical scrollbar?
1384 if( aSize
!= aHorSBar
.GetSizePixel() )
1385 aHorSBar
.SetSizePixel( aSize
);
1386 aHorSBar
.SetVisibleSize( nVisibleWidth
);
1387 aHorSBar
.SetPageSize( GetScrollBarPageSize(nVisibleWidth
));
1388 if( nResult
& 0x0002 )
1390 aHorSBar
.SetThumbPos( nThumb
);
1395 aHorSBar
.SetThumbPos( 0 );
1399 aOutputSize
.Width() = nRealWidth
;
1400 if( nResult
& 0x0002 ) // horizontal scrollbar ?
1401 nRealHeight
++; // because lower border is clipped
1402 aOutputSize
.Height() = nRealHeight
;
1404 Rectangle
aNewOutRect( GetOutputRect() );
1405 if( aNewOutRect
!= aOldOutRect
&& pView
->HasBackground() )
1407 Wallpaper
aPaper( pView
->GetBackground() );
1408 aPaper
.SetRect( aNewOutRect
);
1409 pView
->SetBackground( aPaper
);
1412 if( (nResult
& (0x0001|0x0002)) == (0x0001|0x0002) )
1418 void SvxIconChoiceCtrl_Impl::Resize()
1422 aOutputSize
= pView
->GetOutputSizePixel();
1423 pImpCursor
->Clear();
1424 pGridMap
->OutputSizeChanged();
1426 const Size
& rSize
= pView
->Control::GetOutputSizePixel();
1427 PositionScrollBars( rSize
.Width(), rSize
.Height() );
1428 // The scrollbars are shown/hidden asynchronously, so derived classes can
1429 // do an Arrange during Resize, without the scrollbars suddenly turning
1430 // on and off again.
1431 // If an event is already underway, we don't need to send a new one, at least
1432 // as long as there is only one event type.
1433 if ( ! nUserEventAdjustScrBars
)
1434 nUserEventAdjustScrBars
=
1435 Application::PostUserEvent( LINK( this, SvxIconChoiceCtrl_Impl
, UserEventHdl
),
1436 EVENTID_ADJUST_SCROLLBARS
);
1438 if( pView
->HasBackground() && !pView
->GetBackground().IsScrollable() )
1440 Rectangle
aRect( GetOutputRect());
1441 Wallpaper
aPaper( pView
->GetBackground() );
1442 aPaper
.SetRect( aRect
);
1443 pView
->SetBackground( aPaper
);
1448 sal_Bool
SvxIconChoiceCtrl_Impl::CheckHorScrollBar()
1450 if( !pZOrderList
|| !aHorSBar
.IsVisible() )
1452 const MapMode
& rMapMode
= pView
->GetMapMode();
1453 Point
aOrigin( rMapMode
.GetOrigin() );
1454 if(!( nWinBits
& WB_HSCROLL
) && !aOrigin
.X() )
1456 long nWidth
= aOutputSize
.Width();
1457 const size_t nCount
= pZOrderList
->size();
1458 long nMostRight
= 0;
1459 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
1461 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[ nCur
];
1462 long nRight
= GetEntryBoundRect(pEntry
).Right();
1463 if( nRight
> nWidth
)
1465 if( nRight
> nMostRight
)
1466 nMostRight
= nRight
;
1469 aOutputSize
.Height() += nHorSBarHeight
;
1470 aVirtOutputSize
.Width() = nMostRight
;
1471 aHorSBar
.SetThumbPos( 0 );
1473 aRange
.Max() = nMostRight
- 1;
1474 aHorSBar
.SetRange( aRange
);
1475 if( aVerSBar
.IsVisible() )
1477 Size
aSize( aVerSBar
.GetSizePixel());
1478 aSize
.Height() += nHorSBarHeight
;
1479 aVerSBar
.SetSizePixel( aSize
);
1486 sal_Bool
SvxIconChoiceCtrl_Impl::CheckVerScrollBar()
1488 if( !pZOrderList
|| !aVerSBar
.IsVisible() )
1490 const MapMode
& rMapMode
= pView
->GetMapMode();
1491 Point
aOrigin( rMapMode
.GetOrigin() );
1492 if(!( nWinBits
& WB_VSCROLL
) && !aOrigin
.Y() )
1495 long nHeight
= aOutputSize
.Height();
1496 const size_t nCount
= pZOrderList
->size();
1497 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
1499 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[ nCur
];
1500 long nBottom
= GetEntryBoundRect(pEntry
).Bottom();
1501 if( nBottom
> nHeight
)
1503 if( nBottom
> nDeepest
)
1507 aOutputSize
.Width() += nVerSBarWidth
;
1508 aVirtOutputSize
.Height() = nDeepest
;
1509 aVerSBar
.SetThumbPos( 0 );
1511 aRange
.Max() = nDeepest
- 1;
1512 aVerSBar
.SetRange( aRange
);
1513 if( aHorSBar
.IsVisible() )
1515 Size
aSize( aHorSBar
.GetSizePixel());
1516 aSize
.Width() += nVerSBarWidth
;
1517 aHorSBar
.SetSizePixel( aSize
);
1525 // hides scrollbars if they're unnecessary
1526 void SvxIconChoiceCtrl_Impl::CheckScrollBars()
1528 CheckVerScrollBar();
1529 if( CheckHorScrollBar() )
1530 CheckVerScrollBar();
1531 if( aVerSBar
.IsVisible() && aHorSBar
.IsVisible() )
1538 void SvxIconChoiceCtrl_Impl::GetFocus()
1540 RepaintEntries( ICNVIEW_FLAG_SELECTED
);
1543 pCursor
->SetFlags( ICNVIEW_FLAG_FOCUSED
);
1544 ShowCursor( sal_True
);
1548 void SvxIconChoiceCtrl_Impl::LoseFocus()
1552 pCursor
->ClearFlags( ICNVIEW_FLAG_FOCUSED
);
1553 ShowCursor( sal_False
);
1556 // pView->Invalidate ( aFocus.aRect );
1558 RepaintEntries( ICNVIEW_FLAG_SELECTED
);
1561 void SvxIconChoiceCtrl_Impl::SetUpdateMode( sal_Bool bUpdate
)
1563 if( bUpdate
!= bUpdateMode
)
1565 bUpdateMode
= bUpdate
;
1569 pImpCursor
->Clear();
1571 pView
->Invalidate(INVALIDATE_NOCHILDREN
);
1576 void SvxIconChoiceCtrl_Impl::PaintEntry( SvxIconChoiceCtrlEntry
* pEntry
, sal_Bool bIsBackgroundPainted
)
1578 Point
aPos( GetEntryPos( pEntry
) );
1579 PaintEntry( pEntry
, aPos
, 0, bIsBackgroundPainted
);
1582 // priorities of the emphasis: bDropTarget => bCursored => bSelected
1583 void SvxIconChoiceCtrl_Impl::PaintEmphasis(
1584 const Rectangle
& rTextRect
, const Rectangle
& rImageRect
,
1585 sal_Bool bSelected
, sal_Bool bDropTarget
, sal_Bool bCursored
, OutputDevice
* pOut
,
1586 sal_Bool bIsBackgroundPainted
)
1588 static Color
aTransparent( COL_TRANSPARENT
);
1593 #ifdef OV_CHECK_EMPH_RECTS
1595 Color
aXOld( pOut
->GetFillColor() );
1596 pOut
->SetFillColor( Color( COL_GREEN
));
1597 pOut
->DrawRect( rTextRect
);
1598 pOut
->DrawRect( rImageRect
);
1599 pOut
->SetFillColor( aXOld
);
1603 const StyleSettings
& rSettings
= pOut
->GetSettings().GetStyleSettings();
1604 Color
aOldFillColor( pOut
->GetFillColor() );
1606 sal_Bool bSolidTextRect
= sal_False
;
1607 sal_Bool bSolidImageRect
= sal_False
;
1609 if( bDropTarget
&& ( eSelectionMode
!= NO_SELECTION
) )
1611 pOut
->SetFillColor( rSettings
.GetHighlightColor() );
1612 bSolidTextRect
= sal_True
;
1613 bSolidImageRect
= sal_True
;
1617 if ( !bSelected
|| bCursored
)
1619 if( !pView
->HasFontFillColor() )
1620 pOut
->SetFillColor( pOut
->GetBackground().GetColor() );
1623 const Color
& rFillColor
= pView
->GetFont().GetFillColor();
1624 pOut
->SetFillColor( rFillColor
);
1625 if( rFillColor
!= aTransparent
)
1626 bSolidTextRect
= sal_True
;
1631 // draw text rectangle
1632 if( !bSolidTextRect
)
1634 if( !bIsBackgroundPainted
)
1635 pOut
->Erase( rTextRect
);
1639 Color aOldLineColor
;
1642 aOldLineColor
= pOut
->GetLineColor();
1643 pOut
->SetLineColor( Color( COL_GRAY
) );
1645 pOut
->DrawRect( rTextRect
);
1647 pOut
->SetLineColor( aOldLineColor
);
1650 // draw image rectangle
1651 if( !bSolidImageRect
)
1653 if( !bIsBackgroundPainted
)
1654 pOut
->Erase( rImageRect
);
1656 // the emphasis of the images has to be drawn by the derived class (in the
1657 // virtual function DrawEntryImage)
1659 // pOut->DrawRect( rImageRect );
1661 pOut
->SetFillColor( aOldFillColor
);
1665 void SvxIconChoiceCtrl_Impl::PaintItem( const Rectangle
& rRect
,
1666 IcnViewFieldType eItem
, SvxIconChoiceCtrlEntry
* pEntry
, sal_uInt16 nPaintFlags
,
1667 OutputDevice
* pOut
, const OUString
* pStr
, ::vcl::ControlLayoutData
* _pLayoutData
)
1669 if( eItem
== IcnViewFieldTypeText
)
1673 aText
= pView
->GetEntryText( pEntry
, sal_False
);
1679 pOut
->DrawText( rRect
, aText
, nCurTextDrawFlags
,
1680 &_pLayoutData
->m_aUnicodeBoundRects
, &_pLayoutData
->m_aDisplayText
);
1684 Color aOldFontColor
= pOut
->GetTextColor();
1685 if ( pView
->AutoFontColor() )
1687 Color
aBkgColor( pOut
->GetBackground().GetColor() );
1689 sal_uInt16 nColor
= ( aBkgColor
.GetRed() + aBkgColor
.GetGreen() + aBkgColor
.GetBlue() ) / 3;
1691 aFontColor
.SetColor ( COL_BLACK
);
1693 aFontColor
.SetColor( COL_WHITE
);
1694 pOut
->SetTextColor( aFontColor
);
1697 pOut
->DrawText( rRect
, aText
, nCurTextDrawFlags
);
1699 if ( pView
->AutoFontColor() )
1700 pOut
->SetTextColor( aOldFontColor
);
1702 if( pEntry
->IsFocused() )
1704 Rectangle
aRect ( CalcFocusRect( (SvxIconChoiceCtrlEntry
*)pEntry
) );
1705 /*pView->*/ShowFocus( aRect
);
1706 DrawFocusRect( pOut
);
1712 Point
aPos( rRect
.TopLeft() );
1713 if( nPaintFlags
& PAINTFLAG_HOR_CENTERED
)
1714 aPos
.X() += (rRect
.GetWidth() - aImageSize
.Width() ) / 2;
1715 if( nPaintFlags
& PAINTFLAG_VER_CENTERED
)
1716 aPos
.Y() += (rRect
.GetHeight() - aImageSize
.Height() ) / 2;
1717 pView
->DrawEntryImage( pEntry
, aPos
, *pOut
);
1721 void SvxIconChoiceCtrl_Impl::PaintEntryVirtOutDev( SvxIconChoiceCtrlEntry
* pEntry
)
1723 #ifdef OV_NO_VIRT_OUTDEV
1724 PaintEntry( pEntry
);
1726 if( !pEntryPaintDev
)
1728 pEntryPaintDev
= new VirtualDevice( *pView
);
1729 pEntryPaintDev
->SetFont( pView
->GetFont() );
1730 pEntryPaintDev
->SetLineColor();
1731 //pEntryPaintDev->SetBackground( pView->GetBackground() );
1733 const Rectangle
& rRect
= GetEntryBoundRect( pEntry
);
1734 Rectangle
aOutRect( GetOutputRect() );
1735 if( !rRect
.IsOver( aOutRect
) )
1737 Wallpaper
aPaper( pView
->GetBackground() );
1738 Rectangle
aRect( aPaper
.GetRect() );
1740 // move rectangle, so the bounding rectangle of the entry lies in
1741 // VirtOut-Dev at 0,0
1742 aRect
.Move( -rRect
.Left(), -rRect
.Top() );
1743 aPaper
.SetRect( aRect
);
1744 pEntryPaintDev
->SetBackground( aPaper
);
1745 pEntryPaintDev
->SetFont( pView
->GetFont() );
1747 Size
aSize( rRect
.GetSize() );
1748 pEntryPaintDev
->SetOutputSizePixel( aSize
);
1749 pEntryPaintDev
->DrawOutDev(
1750 Point(), aSize
, rRect
.TopLeft(), aSize
, *pView
);
1752 PaintEntry( pEntry
, Point(), pEntryPaintDev
);
1764 void SvxIconChoiceCtrl_Impl::PaintEntry( SvxIconChoiceCtrlEntry
* pEntry
, const Point
& rPos
,
1765 OutputDevice
* pOut
, sal_Bool bIsBackgroundPainted
)
1770 sal_Bool bSelected
= sal_False
;
1772 if( eSelectionMode
!= NO_SELECTION
)
1773 bSelected
= pEntry
->IsSelected();
1775 sal_Bool bCursored
= pEntry
->IsCursored();
1776 sal_Bool bDropTarget
= pEntry
->IsDropTarget();
1777 sal_Bool bNoEmphasis
= pEntry
->IsBlockingEmphasis();
1779 Font
aTempFont( pOut
->GetFont() );
1783 if ( pView->AutoFontColor() )
1785 aTempFont.SetColor ( aFontColor );
1789 OUString
aEntryText( pView
->GetEntryText( pEntry
, sal_False
) );
1790 Rectangle
aTextRect( CalcTextRect(pEntry
,&rPos
,sal_False
,&aEntryText
));
1791 Rectangle
aBmpRect( CalcBmpRect(pEntry
, &rPos
) );
1793 sal_Bool bShowSelection
=
1794 ( ( ( bSelected
&& !bCursored
)
1798 && ( eSelectionMode
!= NO_SELECTION
)
1800 sal_Bool bActiveSelection
= ( 0 != ( nWinBits
& WB_NOHIDESELECTION
) ) || pView
->HasFocus();
1802 if ( bShowSelection
)
1804 const StyleSettings
& rSettings
= pOut
->GetSettings().GetStyleSettings();
1805 Font
aNewFont( aTempFont
);
1807 // font fill colors that are attributed "hard" need corresponding "hard"
1808 // attributed highlight colors
1809 if( pView
->HasFontFillColor() )
1811 if( (nWinBits
& WB_NOHIDESELECTION
) || pView
->HasFocus() )
1812 aNewFont
.SetFillColor( rSettings
.GetHighlightColor() );
1814 aNewFont
.SetFillColor( rSettings
.GetDeactiveColor() );
1817 Color aWinCol
= rSettings
.GetWindowTextColor();
1818 if ( !bActiveSelection
&& rSettings
.GetFaceColor().IsBright() == aWinCol
.IsBright() )
1819 aNewFont
.SetColor( rSettings
.GetWindowTextColor() );
1821 aNewFont
.SetColor( rSettings
.GetHighlightTextColor() );
1823 pOut
->SetFont( aNewFont
);
1825 pOut
->SetFillColor( pOut
->GetBackground().GetColor() );
1826 pOut
->DrawRect( CalcFocusRect( pEntry
) );
1827 pOut
->SetFillColor( );
1830 sal_Bool bResetClipRegion
= sal_False
;
1831 if( !pView
->IsClipRegion() && (aVerSBar
.IsVisible() || aHorSBar
.IsVisible()) )
1833 Rectangle
aOutputArea( GetOutputRect() );
1834 if( aOutputArea
.IsOver(aTextRect
) || aOutputArea
.IsOver(aBmpRect
) )
1836 pView
->SetClipRegion(Region(aOutputArea
));
1837 bResetClipRegion
= sal_True
;
1841 #ifdef OV_DRAWBOUNDRECT
1843 Color aXOldColor
= pOut
->GetLineColor();
1844 pOut
->SetLineColor( Color( COL_LIGHTRED
) );
1845 Rectangle
aXRect( pEntry
->aRect
);
1846 aXRect
.SetPos( rPos
);
1847 pOut
->DrawRect( aXRect
);
1848 pOut
->SetLineColor( aXOldColor
);
1852 sal_Bool bLargeIconMode
= WB_ICON
== ( nWinBits
& (VIEWMODE_MASK
) );
1853 sal_uInt16 nBmpPaintFlags
= PAINTFLAG_VER_CENTERED
;
1854 if ( bLargeIconMode
)
1855 nBmpPaintFlags
|= PAINTFLAG_HOR_CENTERED
;
1856 sal_uInt16 nTextPaintFlags
= bLargeIconMode
? PAINTFLAG_HOR_CENTERED
: PAINTFLAG_VER_CENTERED
;
1859 PaintEmphasis(aTextRect
,aBmpRect
,bSelected
,bDropTarget
,bCursored
,pOut
,bIsBackgroundPainted
);
1861 if ( bShowSelection
)
1862 pView
->DrawSelectionBackground( CalcFocusRect( pEntry
),
1863 bActiveSelection
? 1 : 2 /* highlight */, sal_False
/* check */, sal_True
/* border */, sal_False
/* ext border only */ );
1865 PaintItem( aBmpRect
, IcnViewFieldTypeImage
, pEntry
, nBmpPaintFlags
, pOut
);
1867 PaintItem( aTextRect
, IcnViewFieldTypeText
, pEntry
,
1868 nTextPaintFlags
, pOut
);
1870 // draw highlight frame
1871 if( pEntry
== pCurHighlightFrame
&& !bNoEmphasis
)
1872 DrawHighlightFrame( pOut
, CalcFocusRect( pEntry
), sal_False
);
1874 pOut
->SetFont( aTempFont
);
1875 if( bResetClipRegion
)
1876 pView
->SetClipRegion();
1879 void SvxIconChoiceCtrl_Impl::SetEntryPos( SvxIconChoiceCtrlEntry
* pEntry
, const Point
& rPos
,
1880 sal_Bool bAdjustAtGrid
, sal_Bool bCheckScrollBars
, sal_Bool bKeepGridMap
)
1882 ShowCursor( sal_False
);
1883 Rectangle
aBoundRect( GetEntryBoundRect( pEntry
));
1884 pView
->Invalidate( aBoundRect
);
1886 if( !IsAutoArrange() )
1888 sal_Bool bAdjustVirtSize
= sal_False
;
1889 if( rPos
!= aBoundRect
.TopLeft() )
1892 pEntry
->aGridRect
.TopLeft() - pEntry
->aRect
.TopLeft() );
1893 pImpCursor
->Clear();
1896 aBoundRect
.SetPos( rPos
);
1897 pEntry
->aRect
= aBoundRect
;
1898 pEntry
->aGridRect
.SetPos( rPos
+ aGridOffs
);
1899 bAdjustVirtSize
= sal_True
;
1903 if( bAdjustVirtSize
)
1905 // By aligning the (in some cases newly positioned) entry, it
1906 // can become completely visible again, so that maybe we don't
1907 // need a scrollbar after all. To avoid suddenly turning the
1908 // scrollbar(s) on and then off again, we use the aligned
1909 // bounding rectangle of the entry to enlarge the virtual
1910 // output size. The virtual size has to be adapted, because
1911 // AdjustEntryAtGrid depends on it.
1912 const Rectangle
& rBoundRect
= GetEntryBoundRect( pEntry
);
1913 Rectangle
aCenterRect( CalcBmpRect( pEntry
, 0 ));
1914 Point
aNewPos( AdjustAtGrid( aCenterRect
, rBoundRect
) );
1915 Rectangle
aNewBoundRect( aNewPos
, pEntry
->aRect
.GetSize());
1916 AdjustVirtSize( aNewBoundRect
);
1917 bAdjustVirtSize
= sal_False
;
1919 AdjustEntryAtGrid( pEntry
);
1922 if( bAdjustVirtSize
)
1923 AdjustVirtSize( pEntry
->aRect
);
1925 if( bCheckScrollBars
&& bUpdateMode
)
1928 pView
->Invalidate( pEntry
->aRect
);
1929 pGridMap
->OccupyGrids( pEntry
);
1933 SvxIconChoiceCtrlEntry
* pPrev
= FindEntryPredecessor( pEntry
, rPos
);
1934 SetEntryPredecessor( pEntry
, pPrev
);
1935 aAutoArrangeTimer
.Start();
1937 ShowCursor( sal_True
);
1940 void SvxIconChoiceCtrl_Impl::SetNoSelection()
1942 // block recursive calls via SelectEntry
1943 if( !(nFlags
& F_CLEARING_SELECTION
))
1945 nFlags
|= F_CLEARING_SELECTION
;
1946 DeselectAllBut( 0, sal_True
);
1947 nFlags
&= ~F_CLEARING_SELECTION
;
1951 SvxIconChoiceCtrlEntry
* SvxIconChoiceCtrl_Impl::GetEntry( const Point
& rDocPos
, sal_Bool bHit
)
1953 CheckBoundingRects();
1954 // search through z-order list from the end
1955 size_t nCount
= pZOrderList
->size();
1959 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[ nCount
];
1960 if( pEntry
->aRect
.IsInside( rDocPos
) )
1964 Rectangle aRect
= CalcBmpRect( pEntry
);
1966 aRect
.Bottom() += 3;
1969 if( aRect
.IsInside( rDocPos
) )
1971 aRect
= CalcTextRect( pEntry
);
1972 if( aRect
.IsInside( rDocPos
) )
1982 Point
SvxIconChoiceCtrl_Impl::GetEntryPos( SvxIconChoiceCtrlEntry
* pEntry
)
1984 return pEntry
->aRect
.TopLeft();
1987 void SvxIconChoiceCtrl_Impl::MakeEntryVisible( SvxIconChoiceCtrlEntry
* pEntry
, sal_Bool bBound
)
1991 const Rectangle
& rRect
= GetEntryBoundRect( pEntry
);
1992 MakeVisible( rRect
);
1996 Rectangle aRect
= CalcBmpRect( pEntry
);
1997 aRect
.Union( CalcTextRect( pEntry
) );
1998 aRect
.Top() += TBOFFS_BOUND
;
1999 aRect
.Bottom() += TBOFFS_BOUND
;
2000 aRect
.Left() += LROFFS_BOUND
;
2001 aRect
.Right() += LROFFS_BOUND
;
2002 MakeVisible( aRect
);
2006 const Rectangle
& SvxIconChoiceCtrl_Impl::GetEntryBoundRect( SvxIconChoiceCtrlEntry
* pEntry
)
2008 if( !IsBoundingRectValid( pEntry
->aRect
))
2009 FindBoundingRect( pEntry
);
2010 return pEntry
->aRect
;
2013 Rectangle
SvxIconChoiceCtrl_Impl::CalcBmpRect( SvxIconChoiceCtrlEntry
* pEntry
, const Point
* pPos
)
2015 Rectangle aBound
= GetEntryBoundRect( pEntry
);
2017 aBound
.SetPos( *pPos
);
2018 Point
aPos( aBound
.TopLeft() );
2020 switch( nWinBits
& (VIEWMODE_MASK
) )
2024 aPos
.X() += ( aBound
.GetWidth() - aImageSize
.Width() ) / 2;
2025 return Rectangle( aPos
, aImageSize
);
2030 aPos
.Y() += ( aBound
.GetHeight() - aImageSize
.Height() ) / 2;
2031 //TODO: determine horizontal distance to bounding rectangle
2032 return Rectangle( aPos
, aImageSize
);
2035 OSL_FAIL("IconView: Viewmode not set");
2040 Rectangle
SvxIconChoiceCtrl_Impl::CalcTextRect( SvxIconChoiceCtrlEntry
* pEntry
,
2041 const Point
* pEntryPos
, sal_Bool bEdit
, const OUString
* pStr
)
2043 OUString aEntryText
;
2045 aEntryText
= pView
->GetEntryText( pEntry
, bEdit
);
2049 const Rectangle
aMaxTextRect( CalcMaxTextRect( pEntry
) );
2050 Rectangle
aBound( GetEntryBoundRect( pEntry
) );
2052 aBound
.SetPos( *pEntryPos
);
2054 Rectangle
aTextRect( aMaxTextRect
);
2056 aTextRect
= pView
->GetTextRect( aTextRect
, aEntryText
, nCurTextDrawFlags
);
2058 Size
aTextSize( aTextRect
.GetSize() );
2060 Point
aPos( aBound
.TopLeft() );
2061 long nBoundWidth
= aBound
.GetWidth();
2062 long nBoundHeight
= aBound
.GetHeight();
2064 switch( nWinBits
& (VIEWMODE_MASK
) )
2067 aPos
.Y() += aImageSize
.Height();
2068 aPos
.Y() += VER_DIST_BMP_STRING
;
2069 // at little more space when editing
2073 long nMinWidth
= (( (aImageSize
.Width()*10) / 100 ) * 2 ) +
2075 if( nMinWidth
> nBoundWidth
)
2076 nMinWidth
= nBoundWidth
;
2078 if( aTextSize
.Width() < nMinWidth
)
2079 aTextSize
.Width() = nMinWidth
;
2081 // when editing, overlap with the area below is allowed
2082 Size aOptSize
= aMaxTextRect
.GetSize();
2083 if( aOptSize
.Height() > aTextSize
.Height() )
2084 aTextSize
.Height() = aOptSize
.Height();
2086 aPos
.X() += (nBoundWidth
- aTextSize
.Width()) / 2;
2091 aPos
.X() += aImageSize
.Width();
2092 aPos
.X() += HOR_DIST_BMP_STRING
;
2093 aPos
.Y() += (nBoundHeight
- aTextSize
.Height()) / 2;
2096 return Rectangle( aPos
, aTextSize
);
2100 long SvxIconChoiceCtrl_Impl::CalcBoundingWidth( SvxIconChoiceCtrlEntry
* pEntry
) const
2102 long nStringWidth
= GetItemSize( pEntry
, IcnViewFieldTypeText
).Width();
2103 // nStringWidth += 2*LROFFS_TEXT;
2106 switch( nWinBits
& (VIEWMODE_MASK
) )
2109 nWidth
= std::max( nStringWidth
, aImageSize
.Width() );
2114 nWidth
= aImageSize
.Width();
2115 nWidth
+= HOR_DIST_BMP_STRING
;
2116 nWidth
+= nStringWidth
;
2122 long SvxIconChoiceCtrl_Impl::CalcBoundingHeight( SvxIconChoiceCtrlEntry
* pEntry
) const
2124 long nStringHeight
= GetItemSize( pEntry
, IcnViewFieldTypeText
).Height();
2127 switch( nWinBits
& (VIEWMODE_MASK
) )
2130 nHeight
= aImageSize
.Height();
2131 nHeight
+= VER_DIST_BMP_STRING
;
2132 nHeight
+= nStringHeight
;
2137 nHeight
= std::max( aImageSize
.Height(), nStringHeight
);
2140 if( nHeight
> nMaxBoundHeight
)
2142 ((SvxIconChoiceCtrl_Impl
*)this)->nMaxBoundHeight
= nHeight
;
2143 ((SvxIconChoiceCtrl_Impl
*)this)->aHorSBar
.SetLineSize( GetScrollBarLineSize() );
2144 ((SvxIconChoiceCtrl_Impl
*)this)->aVerSBar
.SetLineSize( GetScrollBarLineSize() );
2149 Size
SvxIconChoiceCtrl_Impl::CalcBoundingSize( SvxIconChoiceCtrlEntry
* pEntry
) const
2151 return Size( CalcBoundingWidth( pEntry
),
2152 CalcBoundingHeight( pEntry
) );
2155 void SvxIconChoiceCtrl_Impl::RecalcAllBoundingRectsSmart()
2157 nMaxBoundHeight
= 0;
2158 pZOrderList
->clear();
2160 SvxIconChoiceCtrlEntry
* pEntry
;
2161 const size_t nCount
= aEntries
.size();
2163 if( !IsAutoArrange() || !pHead
)
2165 for( nCur
= 0; nCur
< nCount
; nCur
++ )
2167 pEntry
= aEntries
[ nCur
];
2168 if( IsBoundingRectValid( pEntry
->aRect
))
2170 Size
aBoundSize( pEntry
->aRect
.GetSize() );
2171 if( aBoundSize
.Height() > nMaxBoundHeight
)
2172 nMaxBoundHeight
= aBoundSize
.Height();
2175 FindBoundingRect( pEntry
);
2176 pZOrderList
->push_back( pEntry
);
2183 while( nCur
!= nCount
)
2185 DBG_ASSERT(pEntry
->pflink
&&pEntry
->pblink
,"SvxIconChoiceCtrl_Impl::RecalcAllBoundingRect > Bad link(s)");
2186 if( IsBoundingRectValid( pEntry
->aRect
))
2188 Size
aBoundSize( pEntry
->aRect
.GetSize() );
2189 if( aBoundSize
.Height() > nMaxBoundHeight
)
2190 nMaxBoundHeight
= aBoundSize
.Height();
2193 FindBoundingRect( pEntry
);
2194 pZOrderList
->push_back( pEntry
);
2195 pEntry
= pEntry
->pflink
;
2202 void SvxIconChoiceCtrl_Impl::FindBoundingRect( SvxIconChoiceCtrlEntry
* pEntry
)
2204 DBG_ASSERT(!pEntry
->IsPosLocked(),"Locked entry pos in FindBoundingRect");
2205 if( pEntry
->IsPosLocked() && IsBoundingRectValid( pEntry
->aRect
) )
2207 AdjustVirtSize( pEntry
->aRect
);
2210 Size
aSize( CalcBoundingSize( pEntry
) );
2211 Point
aPos(pGridMap
->GetGridRect(pGridMap
->GetUnoccupiedGrid(sal_True
)).TopLeft());
2212 SetBoundingRect_Impl( pEntry
, aPos
, aSize
);
2215 void SvxIconChoiceCtrl_Impl::SetBoundingRect_Impl( SvxIconChoiceCtrlEntry
* pEntry
, const Point
& rPos
,
2216 const Size
& /*rBoundingSize*/ )
2218 Rectangle
aGridRect( rPos
, Size(nGridDX
, nGridDY
) );
2219 pEntry
->aGridRect
= aGridRect
;
2221 AdjustVirtSize( pEntry
->aRect
);
2222 pGridMap
->OccupyGrids( pEntry
);
2226 void SvxIconChoiceCtrl_Impl::SetCursor( SvxIconChoiceCtrlEntry
* pEntry
, sal_Bool bSyncSingleSelection
,
2227 sal_Bool bShowFocusAsync
)
2229 if( pEntry
== pCursor
)
2231 if( pCursor
&& eSelectionMode
== SINGLE_SELECTION
&& bSyncSingleSelection
&&
2232 !pCursor
->IsSelected() )
2233 SelectEntry( pCursor
, sal_True
, sal_True
);
2236 ShowCursor( sal_False
);
2237 SvxIconChoiceCtrlEntry
* pOldCursor
= pCursor
;
2241 pOldCursor
->ClearFlags( ICNVIEW_FLAG_FOCUSED
);
2242 if( eSelectionMode
== SINGLE_SELECTION
&& bSyncSingleSelection
)
2243 SelectEntry( pOldCursor
, sal_False
, sal_True
); // deselect old cursor
2248 pCursor
->SetFlags( ICNVIEW_FLAG_FOCUSED
);
2249 if( eSelectionMode
== SINGLE_SELECTION
&& bSyncSingleSelection
)
2250 SelectEntry( pCursor
, sal_True
, sal_True
);
2251 if( !bShowFocusAsync
)
2252 ShowCursor( sal_True
);
2255 if( !nUserEventShowCursor
)
2256 nUserEventShowCursor
=
2257 Application::PostUserEvent( LINK( this, SvxIconChoiceCtrl_Impl
, UserEventHdl
),
2258 EVENTID_SHOW_CURSOR
);
2264 void SvxIconChoiceCtrl_Impl::ShowCursor( sal_Bool bShow
)
2266 if( !pCursor
|| !bShow
|| !pView
->HasFocus() )
2271 Rectangle
aRect ( CalcFocusRect( pCursor
) );
2272 /*pView->*/ShowFocus( aRect
);
2276 void SvxIconChoiceCtrl_Impl::HideDDIcon()
2284 void SvxIconChoiceCtrl_Impl::ImpHideDDIcon()
2288 Size
aSize( pDDDev
->GetOutputSizePixel() );
2290 pView
->DrawOutDev( aDDLastRectPos
, aSize
, Point(), aSize
, *pDDDev
);
2294 sal_Bool
SvxIconChoiceCtrl_Impl::HandleScrollCommand( const CommandEvent
& rCmd
)
2296 Rectangle
aDocRect( GetDocumentRect() );
2297 Rectangle
aVisRect( GetVisibleRect() );
2298 if( aVisRect
.IsInside( aDocRect
))
2300 Size
aDocSize( aDocRect
.GetSize() );
2301 Size
aVisSize( aVisRect
.GetSize() );
2302 sal_Bool bHor
= aDocSize
.Width() > aVisSize
.Width();
2303 sal_Bool bVer
= aDocSize
.Height() > aVisSize
.Height();
2305 long nScrollDX
= 0, nScrollDY
= 0;
2307 switch( rCmd
.GetCommand() )
2309 case COMMAND_STARTAUTOSCROLL
:
2311 pView
->EndTracking();
2312 sal_uInt16 nScrollFlags
= 0;
2314 nScrollFlags
|= AUTOSCROLL_HORZ
;
2316 nScrollFlags
|= AUTOSCROLL_VERT
;
2319 pView
->StartAutoScroll( nScrollFlags
);
2327 const CommandWheelData
* pData
= rCmd
.GetWheelData();
2328 if( pData
&& (COMMAND_WHEEL_SCROLL
== pData
->GetMode()) && !pData
->IsHorz() )
2330 sal_uLong nScrollLines
= pData
->GetScrollLines();
2331 if( nScrollLines
== COMMAND_WHEEL_PAGESCROLL
)
2333 nScrollDY
= GetScrollBarPageSize( aVisSize
.Width() );
2334 if( pData
->GetDelta() < 0 )
2339 nScrollDY
= pData
->GetNotchDelta() * (long)nScrollLines
;
2340 nScrollDY
*= GetScrollBarLineSize();
2346 case COMMAND_AUTOSCROLL
:
2348 const CommandScrollData
* pData
= rCmd
.GetAutoScrollData();
2351 nScrollDX
= pData
->GetDeltaX() * GetScrollBarLineSize();
2352 nScrollDY
= pData
->GetDeltaY() * GetScrollBarLineSize();
2358 if( nScrollDX
|| nScrollDY
)
2360 aVisRect
.Top() -= nScrollDY
;
2361 aVisRect
.Bottom() -= nScrollDY
;
2362 aVisRect
.Left() -= nScrollDX
;
2363 aVisRect
.Right() -= nScrollDX
;
2364 MakeVisible( aVisRect
);
2371 void SvxIconChoiceCtrl_Impl::Command( const CommandEvent
& rCEvt
)
2373 // scroll mouse event?
2374 if( (rCEvt
.GetCommand() == COMMAND_WHEEL
) ||
2375 (rCEvt
.GetCommand() == COMMAND_STARTAUTOSCROLL
) ||
2376 (rCEvt
.GetCommand() == COMMAND_AUTOSCROLL
) )
2378 if( HandleScrollCommand( rCEvt
) )
2383 void SvxIconChoiceCtrl_Impl::ToTop( SvxIconChoiceCtrlEntry
* pEntry
)
2385 if( !pZOrderList
->empty()
2386 && pEntry
!= pZOrderList
->back()
2389 SvxIconChoiceCtrlEntryList_impl::iterator it
= pZOrderList
->begin();
2390 it
!= pZOrderList
->end();
2393 if ( *it
== pEntry
)
2395 pZOrderList
->erase( it
);
2396 pZOrderList
->push_back( pEntry
);
2403 void SvxIconChoiceCtrl_Impl::ClipAtVirtOutRect( Rectangle
& rRect
) const
2405 if( rRect
.Bottom() >= aVirtOutputSize
.Height() )
2406 rRect
.Bottom() = aVirtOutputSize
.Height() - 1;
2407 if( rRect
.Right() >= aVirtOutputSize
.Width() )
2408 rRect
.Right() = aVirtOutputSize
.Width() - 1;
2409 if( rRect
.Top() < 0 )
2411 if( rRect
.Left() < 0 )
2415 // rRect: area of the document (in document coordinates) that we want to make
2417 // bScrBar == sal_True: rectangle was calculated because of a scrollbar event
2419 void SvxIconChoiceCtrl_Impl::MakeVisible( const Rectangle
& rRect
, sal_Bool bScrBar
,
2420 sal_Bool bCallRectChangedHdl
)
2422 Rectangle
aVirtRect( rRect
);
2423 ClipAtVirtOutRect( aVirtRect
);
2424 Point
aOrigin( pView
->GetMapMode().GetOrigin() );
2425 // convert to document coordinate
2427 Rectangle
aOutputArea( GetOutputRect() );
2428 if( aOutputArea
.IsInside( aVirtRect
) )
2429 return; // is already visible
2432 if( aVirtRect
.Top() < aOutputArea
.Top() )
2434 // scroll up (nDy < 0)
2435 nDy
= aVirtRect
.Top() - aOutputArea
.Top();
2437 else if( aVirtRect
.Bottom() > aOutputArea
.Bottom() )
2439 // scroll down (nDy > 0)
2440 nDy
= aVirtRect
.Bottom() - aOutputArea
.Bottom();
2446 if( aVirtRect
.Left() < aOutputArea
.Left() )
2448 // scroll to the left (nDx < 0)
2449 nDx
= aVirtRect
.Left() - aOutputArea
.Left();
2451 else if( aVirtRect
.Right() > aOutputArea
.Right() )
2453 // scroll to the right (nDx > 0)
2454 nDx
= aVirtRect
.Right() - aOutputArea
.Right();
2461 aOutputArea
.SetPos( aOrigin
);
2462 if( GetUpdateMode() )
2466 ShowCursor( sal_False
);
2469 // invert origin for SV (so we can scroll/paint using document coordinates)
2471 SetOrigin( aOrigin
);
2473 sal_Bool bScrollable
= pView
->GetBackground().IsScrollable();
2474 if( pView
->HasBackground() && !bScrollable
)
2476 Rectangle
aRect( GetOutputRect());
2477 Wallpaper
aPaper( pView
->GetBackground() );
2478 aPaper
.SetRect( aRect
);
2479 pView
->SetBackground( aPaper
);
2482 if( bScrollable
&& GetUpdateMode() )
2484 // scroll in reverse direction!
2485 pView
->Control::Scroll( -nDx
, -nDy
, aOutputArea
,
2486 SCROLL_NOCHILDREN
| SCROLL_USECLIPREGION
| SCROLL_CLIP
);
2489 pView
->Invalidate(INVALIDATE_NOCHILDREN
);
2491 if( aHorSBar
.IsVisible() || aVerSBar
.IsVisible() )
2497 if(aHorSBar
.IsVisible() && aHorSBar
.GetThumbPos() != aOrigin
.X())
2498 aHorSBar
.SetThumbPos( aOrigin
.X() );
2499 if(aVerSBar
.IsVisible() && aVerSBar
.GetThumbPos() != aOrigin
.Y())
2500 aVerSBar
.SetThumbPos( aOrigin
.Y() );
2504 if( GetUpdateMode() )
2505 ShowCursor( sal_True
);
2507 // check if we still need scrollbars
2509 if( bScrollable
&& GetUpdateMode() )
2512 // If the requested area can not be made completely visible, the
2513 // Vis-Rect-Changed handler is called in any case. This case may occur e.g.
2514 // if only few pixels of the lower border are invisible, but a scrollbar has
2515 // a larger line size.
2516 if( bCallRectChangedHdl
|| GetOutputRect() != rRect
)
2520 sal_uLong
SvxIconChoiceCtrl_Impl::GetSelectionCount() const
2522 if( (nWinBits
& WB_HIGHLIGHTFRAME
) && pCurHighlightFrame
)
2524 return nSelectionCount
;
2527 void SvxIconChoiceCtrl_Impl::ToggleSelection( SvxIconChoiceCtrlEntry
* pEntry
)
2530 if( pEntry
->IsSelected() )
2534 SelectEntry( pEntry
, bSel
, sal_True
, sal_True
);
2537 void SvxIconChoiceCtrl_Impl::DeselectAllBut( SvxIconChoiceCtrlEntry
* pThisEntryNot
,
2538 sal_Bool bPaintSync
)
2540 ClearSelectedRectList();
2542 // TODO: work through z-order list, if necessary!
2544 size_t nCount
= aEntries
.size();
2545 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
2547 SvxIconChoiceCtrlEntry
* pEntry
= aEntries
[ nCur
];
2548 if( pEntry
!= pThisEntryNot
&& pEntry
->IsSelected() )
2549 SelectEntry( pEntry
, sal_False
, sal_True
, sal_True
, bPaintSync
);
2552 nFlags
&= (~F_ADD_MODE
);
2555 Size
SvxIconChoiceCtrl_Impl::GetMinGrid() const
2557 Size
aMinSize( aImageSize
);
2558 aMinSize
.Width() += 2 * LROFFS_BOUND
;
2559 aMinSize
.Height() += TBOFFS_BOUND
; // single offset is enough (FileDlg)
2560 OUString
aStrDummy( "XXX" );
2561 Size
aTextSize( pView
->GetTextWidth( aStrDummy
), pView
->GetTextHeight() );
2562 if( nWinBits
& WB_ICON
)
2564 aMinSize
.Height() += VER_DIST_BMP_STRING
;
2565 aMinSize
.Height() += aTextSize
.Height();
2569 aMinSize
.Width() += HOR_DIST_BMP_STRING
;
2570 aMinSize
.Width() += aTextSize
.Width();
2575 void SvxIconChoiceCtrl_Impl::SetGrid( const Size
& rSize
)
2577 Size
aSize( rSize
);
2578 Size
aMinSize( GetMinGrid() );
2579 if( aSize
.Width() < aMinSize
.Width() )
2580 aSize
.Width() = aMinSize
.Width();
2581 if( aSize
.Height() < aMinSize
.Height() )
2582 aSize
.Height() = aMinSize
.Height();
2584 nGridDX
= aSize
.Width();
2585 // HACK: Detail mode is not yet fully implemented, this workaround makes it
2586 // fly with a single column
2587 if( nWinBits
& WB_DETAILS
)
2589 const SvxIconChoiceCtrlColumnInfo
* pCol
= GetColumn( 0 );
2591 ((SvxIconChoiceCtrlColumnInfo
*)pCol
)->SetWidth( nGridDX
);
2593 nGridDY
= aSize
.Height();
2594 SetDefaultTextSize();
2597 // Calculates the maximum size that the text rectangle may use within its
2598 // bounding rectangle. In WB_ICON mode with IcnShowTextFull, Bottom is set to
2601 Rectangle
SvxIconChoiceCtrl_Impl::CalcMaxTextRect( const SvxIconChoiceCtrlEntry
* pEntry
) const
2603 Rectangle aBoundRect
;
2604 // avoid infinite recursion: don't calculate the bounding rectangle here
2605 if( IsBoundingRectValid( pEntry
->aRect
) )
2606 aBoundRect
= pEntry
->aRect
;
2608 aBoundRect
= pEntry
->aGridRect
;
2610 Rectangle
aBmpRect( ((SvxIconChoiceCtrl_Impl
*)this)->CalcBmpRect(
2611 (SvxIconChoiceCtrlEntry
*)pEntry
) );
2612 if( nWinBits
& WB_ICON
)
2614 aBoundRect
.Top() = aBmpRect
.Bottom();
2615 aBoundRect
.Top() += VER_DIST_BMP_STRING
;
2616 if( aBoundRect
.Top() > aBoundRect
.Bottom())
2617 aBoundRect
.Top() = aBoundRect
.Bottom();
2618 aBoundRect
.Left() += LROFFS_BOUND
;
2619 aBoundRect
.Left()++;
2620 aBoundRect
.Right() -= LROFFS_BOUND
;
2621 aBoundRect
.Right()--;
2622 if( aBoundRect
.Left() > aBoundRect
.Right())
2623 aBoundRect
.Left() = aBoundRect
.Right();
2624 if( GetEntryTextModeSmart( pEntry
) == IcnShowTextFull
)
2625 aBoundRect
.Bottom() = LONG_MAX
;
2629 aBoundRect
.Left() = aBmpRect
.Right();
2630 aBoundRect
.Left() += HOR_DIST_BMP_STRING
;
2631 aBoundRect
.Right() -= LROFFS_BOUND
;
2632 if( aBoundRect
.Left() > aBoundRect
.Right() )
2633 aBoundRect
.Left() = aBoundRect
.Right();
2634 long nHeight
= aBoundRect
.GetSize().Height();
2635 nHeight
= nHeight
- aDefaultTextSize
.Height();
2637 aBoundRect
.Top() += nHeight
;
2638 aBoundRect
.Bottom() -= nHeight
;
2643 void SvxIconChoiceCtrl_Impl::SetDefaultTextSize()
2646 nDY
-= aImageSize
.Height();
2647 nDY
-= VER_DIST_BMP_STRING
;
2648 nDY
-= 2*TBOFFS_BOUND
;
2653 nDX
-= 2*LROFFS_BOUND
;
2658 long nHeight
= pView
->GetTextHeight();
2661 aDefaultTextSize
= Size( nDX
, nDY
);
2665 void SvxIconChoiceCtrl_Impl::Center( SvxIconChoiceCtrlEntry
* pEntry
) const
2667 pEntry
->aRect
= pEntry
->aGridRect
;
2668 Size
aSize( CalcBoundingSize( pEntry
) );
2669 if( nWinBits
& WB_ICON
)
2671 // center horizontally
2672 long nBorder
= pEntry
->aGridRect
.GetWidth() - aSize
.Width();
2673 pEntry
->aRect
.Left() += nBorder
/ 2;
2674 pEntry
->aRect
.Right() -= nBorder
/ 2;
2676 // center vertically
2677 pEntry
->aRect
.Bottom() = pEntry
->aRect
.Top() + aSize
.Height();
2681 // The deltas are the offsets by which the view is moved on the document.
2682 // left, up: offsets < 0
2683 // right, down: offsets > 0
2684 void SvxIconChoiceCtrl_Impl::Scroll( long nDeltaX
, long nDeltaY
, sal_Bool bScrollBar
)
2686 const MapMode
& rMapMode
= pView
->GetMapMode();
2687 Point
aOrigin( rMapMode
.GetOrigin() );
2688 // convert to document coordinate
2690 aOrigin
.Y() += nDeltaY
;
2691 aOrigin
.X() += nDeltaX
;
2692 Rectangle
aRect( aOrigin
, aOutputSize
);
2693 MakeVisible( aRect
, bScrollBar
);
2697 const Size
& SvxIconChoiceCtrl_Impl::GetItemSize( SvxIconChoiceCtrlEntry
*,
2698 IcnViewFieldType eItem
) const
2700 if( eItem
== IcnViewFieldTypeText
)
2701 return aDefaultTextSize
;
2705 Rectangle
SvxIconChoiceCtrl_Impl::CalcFocusRect( SvxIconChoiceCtrlEntry
* pEntry
)
2707 Rectangle
aTextRect( CalcTextRect( pEntry
) );
2708 Rectangle
aBoundRect( GetEntryBoundRect( pEntry
) );
2710 aBoundRect
.Left(), aBoundRect
.Top() - 1, aBoundRect
.Right() - 1,
2711 aTextRect
.Bottom() + 1);
2714 // the hot spot is the inner 50 % of the rectangle
2715 static Rectangle
GetHotSpot( const Rectangle
& rRect
)
2717 Rectangle
aResult( rRect
);
2719 Size
aSize( rRect
.GetSize() );
2720 long nDelta
= aSize
.Width() / 4;
2721 aResult
.Left() += nDelta
;
2722 aResult
.Right() -= nDelta
;
2723 nDelta
= aSize
.Height() / 4;
2724 aResult
.Top() += nDelta
;
2725 aResult
.Bottom() -= nDelta
;
2729 void SvxIconChoiceCtrl_Impl::SelectRect( SvxIconChoiceCtrlEntry
* pEntry1
, SvxIconChoiceCtrlEntry
* pEntry2
,
2730 sal_Bool bAdd
, std::vector
<Rectangle
*>* pOtherRects
)
2732 DBG_ASSERT(pEntry1
&& pEntry2
,"SelectEntry: Invalid Entry-Ptr");
2733 Rectangle
aRect( GetEntryBoundRect( pEntry1
) );
2734 aRect
.Union( GetEntryBoundRect( pEntry2
) );
2735 SelectRect( aRect
, bAdd
, pOtherRects
);
2738 void SvxIconChoiceCtrl_Impl::SelectRect( const Rectangle
& rRect
, bool bAdd
,
2739 std::vector
<Rectangle
*>* pOtherRects
)
2741 aCurSelectionRect
= rRect
;
2742 if( !pZOrderList
|| !pZOrderList
->size() )
2745 // set flag, so ToTop won't be called in Select
2746 sal_Bool bAlreadySelectingRect
= nFlags
& F_SELECTING_RECT
? sal_True
: sal_False
;
2747 nFlags
|= F_SELECTING_RECT
;
2749 CheckBoundingRects();
2751 const size_t nCount
= pZOrderList
->size();
2753 Rectangle
aRect( rRect
);
2755 bool bCalcOverlap
= (bAdd
&& pOtherRects
&& !pOtherRects
->empty()) ? true : false;
2757 sal_Bool bResetClipRegion
= sal_False
;
2758 if( !pView
->IsClipRegion() )
2760 bResetClipRegion
= sal_True
;
2761 pView
->SetClipRegion(Region(GetOutputRect()));
2764 for( size_t nPos
= 0; nPos
< nCount
; nPos
++ )
2766 SvxIconChoiceCtrlEntry
* pEntry
= (*pZOrderList
)[ nPos
];
2768 if( !IsBoundingRectValid( pEntry
->aRect
))
2769 FindBoundingRect( pEntry
);
2770 Rectangle
aBoundRect( GetHotSpot( pEntry
->aRect
) );
2771 sal_Bool bSelected
= pEntry
->IsSelected();
2775 bOverlaps
= IsOver( pOtherRects
, aBoundRect
);
2777 bOverlaps
= sal_False
;
2778 sal_Bool bOver
= aRect
.IsOver( aBoundRect
);
2780 if( bOver
&& !bOverlaps
)
2782 // is inside the new selection rectangle and outside of any old one
2785 SelectEntry( pEntry
, sal_True
, sal_True
, sal_True
);
2789 // is outside of the selection rectangle
2792 SelectEntry( pEntry
, sal_False
, sal_True
, sal_True
);
2794 else if( bAdd
&& bOverlaps
)
2796 // The entry is inside an old (=>span multiple rectangles with Ctrl)
2797 // selection rectangle.
2799 // There is still a bug here! The selection status of an entry in a
2800 // previous rectangle has to be restored, if it was touched by the
2801 // current selection rectangle but is not inside it any more.
2802 // For simplicity's sake, let's assume that all entries in the old
2803 // rectangles were correctly selected. It is wrong to just deselect
2804 // the intersection.
2805 // Possible solution: remember a snapshot of the selection before
2806 // spanning the rectangle.
2807 if( aBoundRect
.IsOver( rRect
))
2809 // deselect intersection between old rectangles and current rectangle
2811 SelectEntry( pEntry
, sal_False
, sal_True
, sal_True
);
2815 // select entry of an old rectangle
2817 SelectEntry( pEntry
, sal_True
, sal_True
, sal_True
);
2820 else if( !bOver
&& bSelected
)
2822 // this entry is completely outside the rectangle => deselect it
2823 SelectEntry( pEntry
, sal_False
, sal_True
, sal_True
);
2827 if( !bAlreadySelectingRect
)
2828 nFlags
&= ~F_SELECTING_RECT
;
2831 if( bResetClipRegion
)
2832 pView
->SetClipRegion();
2835 void SvxIconChoiceCtrl_Impl::SelectRange(
2836 SvxIconChoiceCtrlEntry
* pStart
,
2837 SvxIconChoiceCtrlEntry
* pEnd
,
2840 sal_uLong nFront
= GetEntryListPos( pStart
);
2841 sal_uLong nBack
= GetEntryListPos( pEnd
);
2842 sal_uLong nFirst
= std::min( nFront
, nBack
);
2843 sal_uLong nLast
= std::max( nFront
, nBack
);
2845 SvxIconChoiceCtrlEntry
* pEntry
;
2849 // deselect everything before the first entry if not in
2851 for ( i
=0; i
<nFirst
; i
++ )
2853 pEntry
= GetEntry( i
);
2854 if( pEntry
->IsSelected() )
2855 SelectEntry( pEntry
, sal_False
, sal_True
, sal_True
, sal_True
);
2859 // select everything between nFirst and nLast
2860 for ( i
=nFirst
; i
<=nLast
; i
++ )
2862 pEntry
= GetEntry( i
);
2863 if( ! pEntry
->IsSelected() )
2864 SelectEntry( pEntry
, sal_True
, sal_True
, sal_True
, sal_True
);
2869 // deselect everything behind the last entry if not in
2871 sal_uLong nEnd
= GetEntryCount();
2872 for ( ; i
<nEnd
; i
++ )
2874 pEntry
= GetEntry( i
);
2875 if( pEntry
->IsSelected() )
2876 SelectEntry( pEntry
, sal_False
, sal_True
, sal_True
, sal_True
);
2881 bool SvxIconChoiceCtrl_Impl::IsOver( std::vector
<Rectangle
*>* pRectList
, const Rectangle
& rBoundRect
) const
2883 const sal_uInt16 nCount
= pRectList
->size();
2884 for( sal_uInt16 nCur
= 0; nCur
< nCount
; nCur
++ )
2886 Rectangle
* pRect
= (*pRectList
)[ nCur
];
2887 if( rBoundRect
.IsOver( *pRect
))
2893 void SvxIconChoiceCtrl_Impl::AddSelectedRect( SvxIconChoiceCtrlEntry
* pEntry1
,
2894 SvxIconChoiceCtrlEntry
* pEntry2
)
2896 DBG_ASSERT(pEntry1
&& pEntry2
,"SelectEntry: Invalid Entry-Ptr");
2897 Rectangle
aRect( GetEntryBoundRect( pEntry1
) );
2898 aRect
.Union( GetEntryBoundRect( pEntry2
) );
2899 AddSelectedRect( aRect
);
2902 void SvxIconChoiceCtrl_Impl::AddSelectedRect( const Rectangle
& rRect
)
2904 Rectangle
* pRect
= new Rectangle( rRect
);
2906 aSelectedRectList
.push_back( pRect
);
2909 void SvxIconChoiceCtrl_Impl::ClearSelectedRectList()
2911 const sal_uInt16 nCount
= aSelectedRectList
.size();
2912 for( sal_uInt16 nCur
= 0; nCur
< nCount
; nCur
++ )
2914 Rectangle
* pRect
= aSelectedRectList
[ nCur
];
2917 aSelectedRectList
.clear();
2920 IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl
, AutoArrangeHdl
)
2922 aAutoArrangeTimer
.Stop();
2923 Arrange( IsAutoArrange() );
2927 IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl
, VisRectChangedHdl
)
2929 aVisRectChangedTimer
.Stop();
2930 pView
->VisibleRectChanged();
2934 IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl
, DocRectChangedHdl
)
2936 aDocRectChangedTimer
.Stop();
2937 pView
->DocumentRectChanged();
2941 sal_Bool
SvxIconChoiceCtrl_Impl::IsTextHit( SvxIconChoiceCtrlEntry
* pEntry
, const Point
& rDocPos
)
2943 Rectangle
aRect( CalcTextRect( pEntry
));
2944 if( aRect
.IsInside( rDocPos
) )
2949 IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl
, EditTimeoutHdl
)
2951 SvxIconChoiceCtrlEntry
* pEntry
= GetCurEntry();
2952 if( bEntryEditingEnabled
&& pEntry
&&
2953 pEntry
->IsSelected())
2955 if( pView
->EditingEntry( pEntry
))
2956 EditEntry( pEntry
);
2963 // Function to align entries to the grid
2966 // pStart == 0: align all entries
2967 // else: align all entries of the row from pStart on (including pStart)
2968 void SvxIconChoiceCtrl_Impl::AdjustEntryAtGrid( SvxIconChoiceCtrlEntry
* pStart
)
2970 IconChoiceMap aLists
;
2971 pImpCursor
->CreateGridAjustData( aLists
, pStart
);
2972 for (IconChoiceMap::const_iterator iter
= aLists
.begin();
2973 iter
!= aLists
.end(); ++iter
)
2975 AdjustAtGrid(iter
->second
, pStart
);
2977 IcnCursor_Impl::DestroyGridAdjustData( aLists
);
2981 // align a row, might expand width, doesn't break the line
2982 void SvxIconChoiceCtrl_Impl::AdjustAtGrid( const SvxIconChoiceCtrlEntryPtrVec
& rRow
, SvxIconChoiceCtrlEntry
* pStart
)
2994 for( sal_uInt16 nCur
= 0; nCur
< rRow
.size(); nCur
++ )
2996 SvxIconChoiceCtrlEntry
* pCur
= rRow
[ nCur
];
2997 if( !bGo
&& pCur
== pStart
)
3000 // SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pCur);
3001 // Decisive (for our eye) is the bitmap, else, the entry might jump too
3002 // much within long texts.
3003 const Rectangle
& rBoundRect
= GetEntryBoundRect( pCur
);
3004 Rectangle
aCenterRect( CalcBmpRect( pCur
, 0 ));
3005 if( bGo
&& !pCur
->IsPosLocked() )
3007 long nWidth
= aCenterRect
.GetSize().Width();
3008 Point
aNewPos( AdjustAtGrid( aCenterRect
, rBoundRect
) );
3009 while( aNewPos
.X() < nCurRight
)
3010 aNewPos
.X() += nGridDX
;
3011 if( aNewPos
!= rBoundRect
.TopLeft() )
3013 SetEntryPos( pCur
, aNewPos
);
3014 pCur
->SetFlags( ICNVIEW_FLAG_POS_MOVED
);
3015 nFlags
|= F_MOVED_ENTRIES
;
3017 nCurRight
= aNewPos
.X() + nWidth
;
3021 nCurRight
= rBoundRect
.Right();
3026 // Aligns a rectangle to the grid, but doesn't guarantee that the new position
3027 // is vacant. The position can be used for SetEntryPos. The CenterRect describes
3028 // a part of the bounding rectangle that is used for calculating the target
3030 Point
SvxIconChoiceCtrl_Impl::AdjustAtGrid( const Rectangle
& rCenterRect
,
3031 const Rectangle
& rBoundRect
) const
3033 Point
aPos( rCenterRect
.TopLeft() );
3034 Size
aSize( rCenterRect
.GetSize() );
3036 aPos
.X() -= LROFFS_WINBORDER
;
3037 aPos
.Y() -= TBOFFS_WINBORDER
;
3039 // align (the center of the rectangle is the reference)
3040 short nGridX
= (short)((aPos
.X()+(aSize
.Width()/2)) / nGridDX
);
3041 short nGridY
= (short)((aPos
.Y()+(aSize
.Height()/2)) / nGridDY
);
3042 aPos
.X() = nGridX
* nGridDX
;
3043 aPos
.Y() = nGridY
* nGridDY
;
3044 // horizontal center
3045 aPos
.X() += (nGridDX
- rBoundRect
.GetSize().Width() ) / 2;
3047 aPos
.X() += LROFFS_WINBORDER
;
3048 aPos
.Y() += TBOFFS_WINBORDER
;
3053 void SvxIconChoiceCtrl_Impl::SetEntryTextMode( SvxIconChoiceCtrlTextMode eMode
, SvxIconChoiceCtrlEntry
* pEntry
)
3057 if( eTextMode
!= eMode
)
3059 if( eTextMode
== IcnShowTextDontKnow
)
3060 eTextMode
= IcnShowTextShort
;
3062 Arrange( sal_True
);
3067 if( pEntry
->eTextMode
!= eMode
)
3069 pEntry
->eTextMode
= eMode
;
3070 InvalidateEntry( pEntry
);
3071 pView
->Invalidate( GetEntryBoundRect( pEntry
) );
3072 AdjustVirtSize( pEntry
->aRect
);
3077 SvxIconChoiceCtrlTextMode
SvxIconChoiceCtrl_Impl::GetEntryTextModeSmart( const SvxIconChoiceCtrlEntry
* pEntry
) const
3079 DBG_ASSERT(pEntry
,"GetEntryTextModeSmart: Entry not set");
3080 SvxIconChoiceCtrlTextMode eMode
= pEntry
->GetTextMode();
3081 if( eMode
== IcnShowTextDontKnow
)
3086 ////////////////////////////////////////////////////////////////////////////////////////////////
3088 // Draw my own focusrect, because the focusrect of the outputdevice has got the inverted color
3089 // of the background. But what will we see, if the backgroundcolor is gray ? - We will see
3090 // a gray focusrect on a gray background !!!
3092 void SvxIconChoiceCtrl_Impl::ShowFocus ( Rectangle
& rRect
)
3094 Color
aBkgColor ( pView
->GetBackground().GetColor() );
3096 sal_uInt16 nColor
= ( aBkgColor
.GetRed() + aBkgColor
.GetGreen() + aBkgColor
.GetBlue() ) / 3;
3098 aPenColor
.SetColor ( COL_BLACK
);
3100 aPenColor
.SetColor( COL_WHITE
);
3102 aFocus
.bOn
= sal_True
;
3103 aFocus
.aPenColor
= aPenColor
;
3104 aFocus
.aRect
= rRect
;
3107 void SvxIconChoiceCtrl_Impl::DrawFocusRect ( OutputDevice
* pOut
)
3109 pOut
->SetLineColor( aFocus
.aPenColor
);
3110 pOut
->SetFillColor();
3111 Polygon
aPolygon ( aFocus
.aRect
);
3113 LineInfo
aLineInfo ( LINE_DASH
);
3115 aLineInfo
.SetDashLen ( 1 );
3117 aLineInfo
.SetDotLen ( 1L );
3118 aLineInfo
.SetDistance ( 1L );
3119 aLineInfo
.SetDotCount ( 1 );
3121 pOut
->DrawPolyLine ( aPolygon
, aLineInfo
);
3124 sal_Bool
SvxIconChoiceCtrl_Impl::IsMnemonicChar( sal_Unicode cChar
, sal_uLong
& rPos
) const
3126 sal_Bool bRet
= sal_False
;
3127 const vcl::I18nHelper
& rI18nHelper
= Application::GetSettings().GetUILocaleI18nHelper();
3128 size_t nEntryCount
= GetEntryCount();
3129 for ( size_t i
= 0; i
< nEntryCount
; ++i
)
3131 if ( rI18nHelper
.MatchMnemonic( GetEntry( i
)->GetText(), cChar
) )
3143 ////////////////////////////////////////////////////////////////////////////////////////////////
3145 IMPL_LINK(SvxIconChoiceCtrl_Impl
, UserEventHdl
, void*, nId
)
3147 if( nId
== EVENTID_ADJUST_SCROLLBARS
)
3149 nUserEventAdjustScrBars
= 0;
3152 else if( nId
== EVENTID_SHOW_CURSOR
)
3154 nUserEventShowCursor
= 0;
3155 ShowCursor( sal_True
);
3160 void SvxIconChoiceCtrl_Impl::CancelUserEvents()
3162 if( nUserEventAdjustScrBars
)
3164 Application::RemoveUserEvent( nUserEventAdjustScrBars
);
3165 nUserEventAdjustScrBars
= 0;
3167 if( nUserEventShowCursor
)
3169 Application::RemoveUserEvent( nUserEventShowCursor
);
3170 nUserEventShowCursor
= 0;
3174 void SvxIconChoiceCtrl_Impl::InvalidateEntry( SvxIconChoiceCtrlEntry
* pEntry
)
3176 if( pEntry
== pCursor
)
3177 ShowCursor( sal_False
);
3178 pView
->Invalidate( pEntry
->aRect
);
3180 pView
->Invalidate( pEntry
->aRect
);
3181 if( pEntry
== pCursor
)
3182 ShowCursor( sal_True
);
3185 void SvxIconChoiceCtrl_Impl::EditEntry( SvxIconChoiceCtrlEntry
* pEntry
)
3187 DBG_ASSERT(pEntry
,"EditEntry: Entry not set");
3191 StopEntryEditing( sal_True
);
3195 pCurEditedEntry
= pEntry
;
3196 OUString
aEntryText( pView
->GetEntryText( pEntry
, sal_True
) );
3197 Rectangle
aRect( CalcTextRect( pEntry
, 0, sal_True
, &aEntryText
) );
3198 MakeVisible( aRect
);
3199 Point
aPos( aRect
.TopLeft() );
3200 aPos
= pView
->GetPixelPos( aPos
);
3201 aRect
.SetPos( aPos
);
3203 pEdit
= new IcnViewEdit_Impl(
3208 LINK( this, SvxIconChoiceCtrl_Impl
, TextEditEndedHdl
) );
3211 IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl
, TextEditEndedHdl
)
3213 DBG_ASSERT(pEdit
,"TextEditEnded: pEdit not set");
3216 pCurEditedEntry
= 0;
3219 DBG_ASSERT(pCurEditedEntry
,"TextEditEnded: pCurEditedEntry not set");
3221 if( !pCurEditedEntry
)
3224 if( pEdit
->IsGrabFocus() )
3230 if ( !pEdit
->EditingCanceled() )
3231 aText
= pEdit
->GetText();
3233 aText
= pEdit
->GetSavedValue();
3235 if( pView
->EditedEntry( pCurEditedEntry
, aText
, pEdit
->EditingCanceled() ) )
3236 InvalidateEntry( pCurEditedEntry
);
3237 if( !GetSelectionCount() )
3238 SelectEntry( pCurEditedEntry
, sal_True
);
3241 if( pEdit
->IsGrabFocus() )
3243 // The edit can not be deleted here, because it is not within a handler. It
3244 // will be deleted in the dtor or in the next EditEntry.
3245 pCurEditedEntry
= 0;
3249 void SvxIconChoiceCtrl_Impl::StopEntryEditing( sal_Bool bCancel
)
3252 pEdit
->StopEditing( bCancel
);
3255 SvxIconChoiceCtrlEntry
* SvxIconChoiceCtrl_Impl::GetFirstSelectedEntry( sal_uLong
& rPos
) const
3257 if( !GetSelectionCount() )
3260 if( (nWinBits
& WB_HIGHLIGHTFRAME
) && (eSelectionMode
== NO_SELECTION
) )
3262 rPos
= pView
->GetEntryListPos( pCurHighlightFrame
);
3263 return pCurHighlightFrame
;
3266 size_t nCount
= aEntries
.size();
3269 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
3271 SvxIconChoiceCtrlEntry
* pEntry
= aEntries
[ nCur
];
3272 if( pEntry
->IsSelected() )
3281 SvxIconChoiceCtrlEntry
* pEntry
= pHead
;
3284 if( pEntry
->IsSelected() )
3286 rPos
= GetEntryListPos( pEntry
);
3289 pEntry
= pEntry
->pflink
;
3290 if( nCount
&& pEntry
== pHead
)
3292 OSL_FAIL("SvxIconChoiceCtrl_Impl::GetFirstSelectedEntry > infinite loop!");
3300 void SvxIconChoiceCtrl_Impl::SelectAll( sal_Bool bSelect
, sal_Bool bPaint
)
3304 size_t nCount
= aEntries
.size();
3305 for( size_t nCur
= 0; nCur
< nCount
&& (bSelect
|| GetSelectionCount() ); nCur
++ )
3307 SvxIconChoiceCtrlEntry
* pEntry
= aEntries
[ nCur
];
3308 SelectEntry( pEntry
, bSelect
, sal_True
, sal_True
, bPaint
);
3310 nFlags
&= (~F_ADD_MODE
);
3314 IcnViewEdit_Impl::IcnViewEdit_Impl( SvtIconChoiceCtrl
* pParent
, const Point
& rPos
,
3315 const Size
& rSize
, const OUString
& rData
, const Link
& rNotifyEditEnd
) :
3316 MultiLineEdit( pParent
, (pParent
->GetStyle() & WB_ICON
) ? WB_CENTER
: WB_LEFT
),
3317 aCallBackHdl( rNotifyEditEnd
),
3318 bCanceled( sal_False
),
3319 bAlreadyInCallback( sal_False
),
3320 bGrabFocus( sal_False
)
3322 Font
aFont( pParent
->GetPointFont() );
3323 aFont
.SetTransparent( sal_False
);
3324 SetControlFont( aFont
);
3325 if( !pParent
->HasFontFillColor() )
3327 Color
aColor( pParent
->GetBackground().GetColor() );
3328 SetControlBackground( aColor
);
3331 SetControlBackground( aFont
.GetFillColor() );
3332 SetControlForeground( aFont
.GetColor() );
3333 SetPosPixel( rPos
);
3334 SetSizePixel( CalcAdjustedSize(rSize
) );
3338 aAccReturn
.InsertItem( IMPICNVIEW_ACC_RETURN
, KeyCode(KEY_RETURN
) );
3339 aAccEscape
.InsertItem( IMPICNVIEW_ACC_ESCAPE
, KeyCode(KEY_ESCAPE
) );
3341 aAccReturn
.SetActivateHdl( LINK( this, IcnViewEdit_Impl
, ReturnHdl_Impl
) );
3342 aAccEscape
.SetActivateHdl( LINK( this, IcnViewEdit_Impl
, EscapeHdl_Impl
) );
3343 GetpApp()->InsertAccel( &aAccReturn
);//, ACCEL_ALWAYS );
3344 GetpApp()->InsertAccel( &aAccEscape
);//, ACCEL_ALWAYS );
3349 IcnViewEdit_Impl::~IcnViewEdit_Impl()
3351 if( !bAlreadyInCallback
)
3353 GetpApp()->RemoveAccel( &aAccReturn
);
3354 GetpApp()->RemoveAccel( &aAccEscape
);
3358 void IcnViewEdit_Impl::CallCallBackHdl_Impl()
3361 if ( !bAlreadyInCallback
)
3363 bAlreadyInCallback
= sal_True
;
3364 GetpApp()->RemoveAccel( &aAccReturn
);
3365 GetpApp()->RemoveAccel( &aAccEscape
);
3367 aCallBackHdl
.Call( this );
3371 IMPL_LINK_NOARG(IcnViewEdit_Impl
, Timeout_Impl
)
3373 CallCallBackHdl_Impl();
3377 IMPL_LINK( IcnViewEdit_Impl
, ReturnHdl_Impl
, Accelerator
*, EMPTYARG
)
3379 bCanceled
= sal_False
;
3380 bGrabFocus
= sal_True
;
3381 CallCallBackHdl_Impl();
3385 IMPL_LINK( IcnViewEdit_Impl
, EscapeHdl_Impl
, Accelerator
*, EMPTYARG
)
3387 bCanceled
= sal_True
;
3388 bGrabFocus
= sal_True
;
3389 CallCallBackHdl_Impl();
3393 void IcnViewEdit_Impl::KeyInput( const KeyEvent
& rKEvt
)
3395 KeyCode aCode
= rKEvt
.GetKeyCode();
3396 sal_uInt16 nCode
= aCode
.GetCode();
3401 bCanceled
= sal_True
;
3402 bGrabFocus
= sal_True
;
3403 CallCallBackHdl_Impl();
3407 bCanceled
= sal_False
;
3408 bGrabFocus
= sal_True
;
3409 CallCallBackHdl_Impl();
3413 MultiLineEdit::KeyInput( rKEvt
);
3417 long IcnViewEdit_Impl::PreNotify( NotifyEvent
& rNEvt
)
3419 if( rNEvt
.GetType() == EVENT_LOSEFOCUS
)
3421 if ( !bAlreadyInCallback
&&
3422 ((!Application::GetFocusWindow()) || !IsChild(Application::GetFocusWindow())))
3424 bCanceled
= sal_False
;
3425 aTimer
.SetTimeout(10);
3426 aTimer
.SetTimeoutHdl(LINK(this,IcnViewEdit_Impl
,Timeout_Impl
));
3433 void IcnViewEdit_Impl::StopEditing( sal_Bool bCancel
)
3435 if ( !bAlreadyInCallback
)
3437 bCanceled
= bCancel
;
3438 CallCallBackHdl_Impl();
3442 sal_uLong
SvxIconChoiceCtrl_Impl::GetEntryListPos( SvxIconChoiceCtrlEntry
* pEntry
) const
3444 if( !(nFlags
& F_ENTRYLISTPOS_VALID
))
3445 ((SvxIconChoiceCtrl_Impl
*)this)->SetListPositions();
3446 return pEntry
->nPos
;
3449 void SvxIconChoiceCtrl_Impl::InitSettings()
3451 const StyleSettings
& rStyleSettings
= pView
->GetSettings().GetStyleSettings();
3453 if( !pView
->HasFont() )
3455 // unit (from settings) is Point
3456 Font
aFont( rStyleSettings
.GetFieldFont() );
3457 //const Font& rFont = pView->GetFont();
3458 //if( pView->HasFontTextColor() )
3459 aFont
.SetColor( rStyleSettings
.GetWindowTextColor() );
3460 //if( pView->HasFontFillColor() )
3461 //aFont.SetFillColor( rFont.GetFillColor() );
3462 pView
->SetPointFont( aFont
);
3463 SetDefaultTextSize();
3466 //if( !pView->HasFontTextColor() )
3467 pView
->SetTextColor( rStyleSettings
.GetFieldTextColor() );
3468 //if( !pView->HasFontFillColor() )
3469 pView
->SetTextFillColor();
3471 //if( !pView->HasBackground() )
3472 pView
->SetBackground( rStyleSettings
.GetFieldColor());
3474 long nScrBarSize
= rStyleSettings
.GetScrollBarSize();
3475 if( nScrBarSize
!= nHorSBarHeight
|| nScrBarSize
!= nVerSBarWidth
)
3477 nHorSBarHeight
= nScrBarSize
;
3478 Size
aSize( aHorSBar
.GetSizePixel() );
3479 aSize
.Height() = nScrBarSize
;
3481 aHorSBar
.SetSizePixel( aSize
);
3483 nVerSBarWidth
= nScrBarSize
;
3484 aSize
= aVerSBar
.GetSizePixel();
3485 aSize
.Width() = nScrBarSize
;
3487 aVerSBar
.SetSizePixel( aSize
);
3489 Size
aOSize( pView
->Control::GetOutputSizePixel() );
3490 PositionScrollBars( aOSize
.Width(), aOSize
.Height() );
3495 EntryList_Impl::EntryList_Impl( SvxIconChoiceCtrl_Impl
* pOwner
) :
3501 EntryList_Impl::~EntryList_Impl()
3506 void EntryList_Impl::clear()
3509 maIconChoiceCtrlEntryList
.clear();
3512 void EntryList_Impl::insert( size_t nPos
, SvxIconChoiceCtrlEntry
* pEntry
)
3514 if ( nPos
< maIconChoiceCtrlEntryList
.size() ) {
3515 maIconChoiceCtrlEntryList
.insert( maIconChoiceCtrlEntryList
.begin() + nPos
, pEntry
);
3517 maIconChoiceCtrlEntryList
.push_back( pEntry
);
3519 if( _pOwner
->pHead
)
3520 pEntry
->SetBacklink( _pOwner
->pHead
->pblink
);
3523 void SvxIconChoiceCtrl_Impl::SetPositionMode( SvxIconChoiceCtrlPositionMode eMode
)
3525 if( eMode
== ePositionMode
)
3528 SvxIconChoiceCtrlPositionMode eOldMode
= ePositionMode
;
3529 ePositionMode
= eMode
;
3530 size_t nCount
= aEntries
.size();
3532 if( eOldMode
== IcnViewPositionModeAutoArrange
)
3534 // when positioning moved entries "hard", there are problems with
3535 // unwanted overlaps, as these entries aren't taken into account in
3537 if( aEntries
.size() )
3538 aAutoArrangeTimer
.Start();
3542 if( ePositionMode
== IcnViewPositionModeAutoArrange
)
3544 for( size_t nCur
= 0; nCur
< nCount
; nCur
++ )
3546 SvxIconChoiceCtrlEntry
* pEntry
= aEntries
[ nCur
];
3547 if( pEntry
->GetFlags() & (ICNVIEW_FLAG_POS_LOCKED
| ICNVIEW_FLAG_POS_MOVED
))
3548 SetEntryPos(pEntry
, GetEntryBoundRect( pEntry
).TopLeft());
3551 if( aEntries
.size() )
3552 aAutoArrangeTimer
.Start();
3554 else if( ePositionMode
== IcnViewPositionModeAutoAdjust
)
3556 AdjustEntryAtGrid( 0 );
3560 void SvxIconChoiceCtrl_Impl::SetEntryPredecessor( SvxIconChoiceCtrlEntry
* pEntry
,
3561 SvxIconChoiceCtrlEntry
* pPredecessor
)
3563 if( !IsAutoArrange() )
3566 if( pEntry
== pPredecessor
)
3569 sal_uLong nPos1
= GetEntryListPos( pEntry
);
3574 sal_uLong nPos2
= GetEntryListPos( pPredecessor
);
3575 if( nPos1
== (nPos2
+ 1) )
3576 return; // is already the predecessor
3585 if( !pPredecessor
&& pHead
== pEntry
)
3586 return; // is already the first one
3588 sal_Bool bSetHead
= sal_False
;
3591 bSetHead
= sal_True
;
3592 pPredecessor
= pHead
->pblink
;
3594 if( pEntry
== pHead
)
3596 pHead
= pHead
->pflink
;
3597 bSetHead
= sal_False
;
3599 if( pEntry
!= pPredecessor
)
3602 pEntry
->SetBacklink( pPredecessor
);
3606 pEntry
->SetFlags( ICNVIEW_FLAG_PRED_SET
);
3607 aAutoArrangeTimer
.Start();
3610 SvxIconChoiceCtrlEntry
* SvxIconChoiceCtrl_Impl::FindEntryPredecessor( SvxIconChoiceCtrlEntry
* pEntry
,
3611 const Point
& rPosTopLeft
)
3613 Point
aPos( rPosTopLeft
); //TopLeft
3614 Rectangle
aCenterRect( CalcBmpRect( pEntry
, &aPos
));
3615 Point
aNewPos( aCenterRect
.Center() );
3616 sal_uLong nGrid
= GetPredecessorGrid( aNewPos
);
3617 size_t nCount
= aEntries
.size();
3618 if( nGrid
== ULONG_MAX
)
3620 if( nGrid
>= nCount
)
3623 return aEntries
[ nGrid
];
3625 SvxIconChoiceCtrlEntry
* pCur
= pHead
; // Grid 0
3626 // TODO: go through list from the end if nGrid > nCount/2
3627 for( sal_uLong nCur
= 0; nCur
< nGrid
; nCur
++ )
3628 pCur
= pCur
->pflink
;
3633 sal_uLong
SvxIconChoiceCtrl_Impl::GetPredecessorGrid( const Point
& rPos
) const
3636 aPos
.X() -= LROFFS_WINBORDER
;
3637 aPos
.Y() -= TBOFFS_WINBORDER
;
3638 sal_uInt16 nMaxCol
= (sal_uInt16
)(aVirtOutputSize
.Width() / nGridDX
);
3641 sal_uInt16 nGridX
= (sal_uInt16
)(aPos
.X() / nGridDX
);
3642 if( nGridX
> nMaxCol
)
3644 sal_uInt16 nGridY
= (sal_uInt16
)(aPos
.Y() / nGridDY
);
3645 sal_uInt16 nGridsX
= (sal_uInt16
)(aOutputSize
.Width() / nGridDX
);
3646 sal_uLong nGrid
= (nGridY
* nGridsX
) + nGridX
;
3647 long nMiddle
= (nGridX
* nGridDX
) + (nGridDX
/ 2);
3648 if( rPos
.X() < nMiddle
)
3658 sal_Bool
SvxIconChoiceCtrl_Impl::RequestHelp( const HelpEvent
& rHEvt
)
3660 if ( !(rHEvt
.GetMode() & HELPMODE_QUICK
) )
3663 Point
aPos( pView
->ScreenToOutputPixel(rHEvt
.GetMousePosPixel() ) );
3664 aPos
-= pView
->GetMapMode().GetOrigin();
3665 SvxIconChoiceCtrlEntry
* pEntry
= GetEntry( aPos
, sal_True
);
3670 OUString sQuickHelpText
= pEntry
->GetQuickHelpText();
3671 OUString
aEntryText( pView
->GetEntryText( pEntry
, sal_False
) );
3672 Rectangle
aTextRect( CalcTextRect( pEntry
, 0, sal_False
, &aEntryText
) );
3673 if ( ( !aTextRect
.IsInside( aPos
) || aEntryText
.isEmpty() ) && sQuickHelpText
.isEmpty() )
3676 Rectangle
aOptTextRect( aTextRect
);
3677 aOptTextRect
.Bottom() = LONG_MAX
;
3678 sal_uInt16 nNewFlags
= nCurTextDrawFlags
;
3679 nNewFlags
&= ~( TEXT_DRAW_CLIP
| TEXT_DRAW_ENDELLIPSIS
);
3680 aOptTextRect
= pView
->GetTextRect( aOptTextRect
, aEntryText
, nNewFlags
);
3681 if ( aOptTextRect
!= aTextRect
|| !sQuickHelpText
.isEmpty() )
3683 //aTextRect.Right() = aTextRect.Left() + aRealSize.Width() + 4;
3684 Point
aPt( aOptTextRect
.TopLeft() );
3685 aPt
+= pView
->GetMapMode().GetOrigin();
3686 aPt
= pView
->OutputToScreenPixel( aPt
);
3687 // subtract border of tooltip help
3690 aOptTextRect
.SetPos( aPt
);
3692 if ( !sQuickHelpText
.isEmpty() )
3693 sHelpText
= sQuickHelpText
;
3695 sHelpText
= aEntryText
;
3696 Help::ShowQuickHelp( (Window
*)pView
, aOptTextRect
, sHelpText
, QUICKHELP_LEFT
| QUICKHELP_VCENTER
);
3702 void SvxIconChoiceCtrl_Impl::ClearColumnList()
3711 void SvxIconChoiceCtrl_Impl::SetColumn( sal_uInt16 nIndex
, const SvxIconChoiceCtrlColumnInfo
& rInfo
)
3714 pColumns
= new SvxIconChoiceCtrlColumnInfoMap
;
3716 SvxIconChoiceCtrlColumnInfo
* pInfo
= new SvxIconChoiceCtrlColumnInfo( rInfo
);
3717 pColumns
->insert( nIndex
, pInfo
);
3719 // HACK: Detail mode is not yet fully implemented, this workaround makes it
3720 // fly with a single column
3721 if( !nIndex
&& (nWinBits
& WB_DETAILS
) )
3722 nGridDX
= pInfo
->GetWidth();
3724 if( GetUpdateMode() )
3725 Arrange( IsAutoArrange() );
3728 const SvxIconChoiceCtrlColumnInfo
* SvxIconChoiceCtrl_Impl::GetColumn( sal_uInt16 nIndex
) const
3732 SvxIconChoiceCtrlColumnInfoMap::const_iterator it
= pColumns
->find( nIndex
);
3733 if( it
== pColumns
->end() )
3738 void SvxIconChoiceCtrl_Impl::DrawHighlightFrame(
3739 OutputDevice
* pOut
, const Rectangle
& rBmpRect
, sal_Bool bHide
)
3741 Rectangle
aBmpRect( rBmpRect
);
3743 if( aImageSize
.Width() < 32 )
3745 aBmpRect
.Right() += nBorder
;
3746 aBmpRect
.Left() -= nBorder
;
3747 aBmpRect
.Bottom() += nBorder
;
3748 aBmpRect
.Top() -= nBorder
;
3751 pView
->Invalidate( aBmpRect
);
3754 DecorationView
aDecoView( pOut
);
3755 sal_uInt16 nDecoFlags
;
3756 if ( bHighlightFramePressed
)
3757 nDecoFlags
= FRAME_HIGHLIGHT_TESTBACKGROUND
| FRAME_HIGHLIGHT_IN
;
3759 nDecoFlags
= FRAME_HIGHLIGHT_TESTBACKGROUND
| FRAME_HIGHLIGHT_OUT
;
3760 aDecoView
.DrawHighlightFrame( aBmpRect
, nDecoFlags
);
3764 void SvxIconChoiceCtrl_Impl::SetEntryHighlightFrame( SvxIconChoiceCtrlEntry
* pEntry
,
3765 sal_Bool bKeepHighlightFlags
)
3767 if( pEntry
== pCurHighlightFrame
)
3770 if( !bKeepHighlightFlags
)
3771 bHighlightFramePressed
= sal_False
;
3773 HideEntryHighlightFrame();
3774 pCurHighlightFrame
= pEntry
;
3777 Rectangle
aBmpRect( CalcFocusRect(pEntry
) );
3778 DrawHighlightFrame( pView
, aBmpRect
, sal_False
);
3782 void SvxIconChoiceCtrl_Impl::HideEntryHighlightFrame()
3784 if( !pCurHighlightFrame
)
3787 SvxIconChoiceCtrlEntry
* pEntry
= pCurHighlightFrame
;
3788 pCurHighlightFrame
= 0;
3789 Rectangle
aBmpRect( CalcFocusRect(pEntry
) );
3790 DrawHighlightFrame( pView
, aBmpRect
, sal_True
);
3793 void SvxIconChoiceCtrl_Impl::CallSelectHandler( SvxIconChoiceCtrlEntry
* )
3795 // When single-click mode is active, the selection handler should be called
3796 // synchronously, as the selection is automatically taken away once the
3797 // mouse cursor doesn't touch the object any more. Else, we might run into
3798 // missing calls to Select if the object is selected from a mouse movement,
3799 // because when starting the timer, the mouse cursor might have already left
3801 // In special cases (=>SfxFileDialog!), synchronous calls can be forced via
3802 // WB_NOASYNCSELECTHDL.
3803 if( nWinBits
& (WB_NOASYNCSELECTHDL
| WB_HIGHLIGHTFRAME
) )
3810 aCallSelectHdlTimer
.Start();
3813 IMPL_LINK_NOARG(SvxIconChoiceCtrl_Impl
, CallSelectHdlHdl
)
3821 void SvxIconChoiceCtrl_Impl::SetOrigin( const Point
& rPos
, sal_Bool bDoNotUpdateWallpaper
)
3823 MapMode
aMapMode( pView
->GetMapMode() );
3824 aMapMode
.SetOrigin( rPos
);
3825 pView
->SetMapMode( aMapMode
);
3826 if( !bDoNotUpdateWallpaper
)
3828 sal_Bool bScrollable
= pView
->GetBackground().IsScrollable();
3829 if( pView
->HasBackground() && !bScrollable
)
3831 Rectangle
aRect( GetOutputRect());
3832 Wallpaper
aPaper( pView
->GetBackground() );
3833 aPaper
.SetRect( aRect
);
3834 pView
->SetBackground( aPaper
);
3839 void SvxIconChoiceCtrl_Impl::CallEventListeners( sal_uLong nEvent
, void* pData
)
3841 pView
->CallImplEventListeners( nEvent
, pData
);
3845 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */