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