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