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