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 : #include <tools/debug.hxx>
21 : #include <svtools/brwbox.hxx>
22 : #include "datwin.hxx"
23 : #include <svtools/colorcfg.hxx>
24 : #include <vcl/salgtype.hxx>
25 :
26 : #include <tools/multisel.hxx>
27 : #include <algorithm>
28 :
29 : using namespace ::com::sun::star::datatransfer;
30 :
31 : #define getDataWindow() ((BrowserDataWin*)pDataWin)
32 :
33 :
34 : //===================================================================
35 :
36 : DBG_NAMEEX(BrowseBox)
37 :
38 : //===================================================================
39 :
40 : extern const char* BrowseBoxCheckInvariants( const void * pVoid );
41 :
42 : //===================================================================
43 :
44 0 : void BrowseBox::StartDrag( sal_Int8 /* _nAction */, const Point& /* _rPosPixel */ )
45 : {
46 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
47 : // not interested in this event
48 0 : }
49 :
50 : //===================================================================
51 :
52 0 : sal_Int8 BrowseBox::AcceptDrop( const AcceptDropEvent& _rEvt )
53 : {
54 0 : BrowserDataWin* pDataWindow = static_cast<BrowserDataWin*>(pDataWin);
55 0 : AcceptDropEvent aTransformed( _rEvt );
56 0 : aTransformed.maPosPixel = pDataWindow->ScreenToOutputPixel( OutputToScreenPixel( _rEvt.maPosPixel ) );
57 0 : return pDataWindow->AcceptDrop( aTransformed );
58 : }
59 :
60 : //===================================================================
61 :
62 0 : sal_Int8 BrowseBox::ExecuteDrop( const ExecuteDropEvent& _rEvt )
63 : {
64 0 : BrowserDataWin* pDataWindow = static_cast<BrowserDataWin*>(pDataWin);
65 0 : ExecuteDropEvent aTransformed( _rEvt );
66 0 : aTransformed.maPosPixel = pDataWindow->ScreenToOutputPixel( OutputToScreenPixel( _rEvt.maPosPixel ) );
67 0 : return pDataWindow->ExecuteDrop( aTransformed );
68 : }
69 :
70 : //===================================================================
71 :
72 0 : sal_Int8 BrowseBox::AcceptDrop( const BrowserAcceptDropEvent& )
73 : {
74 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
75 : // not interested in this event
76 0 : return DND_ACTION_NONE;
77 : }
78 :
79 : //===================================================================
80 :
81 0 : sal_Int8 BrowseBox::ExecuteDrop( const BrowserExecuteDropEvent& )
82 : {
83 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
84 : // not interested in this event
85 0 : return DND_ACTION_NONE;
86 : }
87 :
88 : //===================================================================
89 :
90 0 : void* BrowseBox::implGetDataFlavors() const
91 : {
92 0 : if (static_cast<BrowserDataWin*>(pDataWin)->bCallingDropCallback)
93 0 : return &static_cast<BrowserDataWin*>(pDataWin)->GetDataFlavorExVector();
94 0 : return &GetDataFlavorExVector();
95 : }
96 :
97 : //===================================================================
98 :
99 0 : sal_Bool BrowseBox::IsDropFormatSupported( SotFormatStringId _nFormat )
100 : {
101 0 : if ( static_cast< BrowserDataWin* >( pDataWin )->bCallingDropCallback )
102 0 : return static_cast< BrowserDataWin* >( pDataWin )->IsDropFormatSupported( _nFormat );
103 :
104 0 : return DropTargetHelper::IsDropFormatSupported( _nFormat );
105 : }
106 :
107 : //===================================================================
108 :
109 0 : sal_Bool BrowseBox::IsDropFormatSupported( SotFormatStringId _nFormat ) const
110 : {
111 0 : return const_cast< BrowseBox* >( this )->IsDropFormatSupported( _nFormat );
112 : }
113 :
114 : //===================================================================
115 :
116 0 : sal_Bool BrowseBox::IsDropFormatSupported( const DataFlavor& _rFlavor )
117 : {
118 0 : if ( static_cast< BrowserDataWin* >( pDataWin )->bCallingDropCallback )
119 0 : return static_cast< BrowserDataWin* >( pDataWin )->IsDropFormatSupported( _rFlavor );
120 :
121 0 : return DropTargetHelper::IsDropFormatSupported( _rFlavor );
122 : }
123 :
124 : //===================================================================
125 :
126 0 : sal_Bool BrowseBox::IsDropFormatSupported( const DataFlavor& _rFlavor ) const
127 : {
128 0 : return const_cast< BrowseBox* >( this )->IsDropFormatSupported( _rFlavor );
129 : }
130 :
131 : //===================================================================
132 :
133 0 : void BrowseBox::Command( const CommandEvent& rEvt )
134 : {
135 0 : if ( !getDataWindow()->bInCommand )
136 0 : Control::Command( rEvt );
137 0 : }
138 :
139 : //===================================================================
140 :
141 0 : void BrowseBox::StateChanged( StateChangedType nStateChange )
142 : {
143 0 : Control::StateChanged( nStateChange );
144 :
145 0 : if ( STATE_CHANGE_MIRRORING == nStateChange )
146 : {
147 0 : getDataWindow()->EnableRTL( IsRTLEnabled() );
148 :
149 0 : HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
150 0 : if ( pHeaderBar )
151 0 : pHeaderBar->EnableRTL( IsRTLEnabled() );
152 0 : aHScroll.EnableRTL( IsRTLEnabled() );
153 0 : if( pVScroll )
154 0 : pVScroll->EnableRTL( IsRTLEnabled() );
155 0 : Resize();
156 : }
157 0 : else if ( STATE_CHANGE_INITSHOW == nStateChange )
158 : {
159 0 : bBootstrapped = sal_True; // must be set first!
160 :
161 0 : Resize();
162 0 : if ( bMultiSelection )
163 0 : uRow.pSel->SetTotalRange( Range( 0, nRowCount - 1 ) );
164 0 : if ( nRowCount == 0 )
165 0 : nCurRow = BROWSER_ENDOFSELECTION;
166 0 : else if ( nCurRow == BROWSER_ENDOFSELECTION )
167 0 : nCurRow = 0;
168 :
169 :
170 0 : if ( HasFocus() )
171 : {
172 0 : bSelectionIsVisible = sal_True;
173 0 : bHasFocus = sal_True;
174 : }
175 0 : UpdateScrollbars();
176 0 : AutoSizeLastColumn();
177 0 : CursorMoved();
178 : }
179 0 : else if (STATE_CHANGE_ZOOM == nStateChange)
180 : {
181 0 : pDataWin->SetZoom(GetZoom());
182 0 : HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
183 0 : if (pHeaderBar)
184 0 : pHeaderBar->SetZoom(GetZoom());
185 :
186 : // let the columns calculate their new widths and adjust the header bar
187 0 : for ( size_t nPos = 0; nPos < pCols->size(); ++nPos )
188 : {
189 0 : (*pCols)[ nPos ]->ZoomChanged(GetZoom());
190 0 : if ( pHeaderBar )
191 0 : pHeaderBar->SetItemSize( (*pCols)[ nPos ]->GetId(), (*pCols)[ nPos ]->Width() );
192 : }
193 :
194 : // all our controls have to be repositioned
195 0 : Resize();
196 : }
197 0 : else if (STATE_CHANGE_ENABLE == nStateChange)
198 : {
199 : // do we have a handle column?
200 0 : sal_Bool bHandleCol = !pCols->empty() && (0 == (*pCols)[ 0 ]->GetId());
201 : // do we have a header bar?
202 0 : sal_Bool bHeaderBar = (NULL != static_cast<BrowserDataWin&>(GetDataWindow()).pHeaderBar);
203 :
204 0 : if ( nTitleLines
205 : && ( !bHeaderBar
206 : || bHandleCol
207 : )
208 : )
209 : // we draw the text in our header bar in a color dependent on the enabled state. So if this state changed
210 : // -> redraw
211 0 : Invalidate(Rectangle(Point(0, 0), Size(GetOutputSizePixel().Width(), GetTitleHeight() - 1)));
212 : }
213 0 : }
214 :
215 : //===================================================================
216 :
217 0 : void BrowseBox::Select()
218 : {
219 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
220 0 : }
221 :
222 : //-------------------------------------------------------------------
223 :
224 0 : void BrowseBox::DoubleClick( const BrowserMouseEvent & )
225 : {
226 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
227 0 : }
228 :
229 : //-------------------------------------------------------------------
230 :
231 0 : long BrowseBox::QueryMinimumRowHeight()
232 : {
233 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
234 0 : return CalcZoom( 5 );
235 : }
236 :
237 : //-------------------------------------------------------------------
238 :
239 0 : void BrowseBox::ImplStartTracking()
240 : {
241 : DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
242 0 : }
243 :
244 : //-------------------------------------------------------------------
245 :
246 0 : void BrowseBox::ImplTracking()
247 : {
248 : DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
249 0 : }
250 :
251 : //-------------------------------------------------------------------
252 :
253 0 : void BrowseBox::ImplEndTracking()
254 : {
255 : DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
256 0 : }
257 :
258 : //-------------------------------------------------------------------
259 :
260 0 : void BrowseBox::RowHeightChanged()
261 : {
262 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
263 0 : }
264 :
265 : //-------------------------------------------------------------------
266 :
267 0 : long BrowseBox::QueryColumnResize( sal_uInt16, long nWidth )
268 : {
269 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
270 0 : return nWidth;
271 : }
272 :
273 : //-------------------------------------------------------------------
274 :
275 0 : void BrowseBox::ColumnResized( sal_uInt16 )
276 : {
277 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
278 0 : }
279 :
280 : //-------------------------------------------------------------------
281 :
282 0 : void BrowseBox::ColumnMoved( sal_uInt16 )
283 : {
284 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
285 0 : }
286 :
287 : //-------------------------------------------------------------------
288 :
289 0 : void BrowseBox::StartScroll()
290 : {
291 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
292 0 : DoHideCursor( "StartScroll" );
293 0 : }
294 :
295 : //-------------------------------------------------------------------
296 :
297 0 : void BrowseBox::EndScroll()
298 : {
299 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
300 0 : UpdateScrollbars();
301 0 : AutoSizeLastColumn();
302 0 : DoShowCursor( "EndScroll" );
303 0 : }
304 :
305 : //-------------------------------------------------------------------
306 :
307 : #ifdef _MSC_VER
308 : #pragma optimize( "", off )
309 : #endif
310 :
311 0 : void BrowseBox::ToggleSelection( sal_Bool bForce )
312 : {
313 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
314 :
315 : // selection highlight-toggling allowed?
316 0 : if ( bHideSelect )
317 : return;
318 0 : if ( !bForce &&
319 0 : ( bNotToggleSel || !IsUpdateMode() || !bSelectionIsVisible ) )
320 : return;
321 :
322 : // only highlight painted areas!
323 0 : bNotToggleSel = sal_True;
324 : if ( sal_False && !getDataWindow()->bInPaint )
325 : pDataWin->Update();
326 :
327 : // accumulate areas of rows to highlight
328 0 : RectangleList aHighlightList;
329 0 : long nLastRowInRect = 0; // for the CFront
330 :
331 : // don't highlight handle column
332 0 : BrowserColumn *pFirstCol = pCols->empty() ? NULL : (*pCols)[ 0 ];
333 0 : long nOfsX = (!pFirstCol || pFirstCol->GetId()) ? 0 : pFirstCol->Width();
334 :
335 : // accumulate old row selection
336 : long nBottomRow = nTopRow +
337 0 : pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight();
338 0 : if ( nBottomRow > GetRowCount() && GetRowCount() )
339 0 : nBottomRow = GetRowCount();
340 0 : for ( long nRow = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel;
341 : nRow != BROWSER_ENDOFSELECTION && nRow <= nBottomRow;
342 0 : nRow = bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION )
343 : {
344 0 : if ( nRow < nTopRow )
345 0 : continue;
346 :
347 : Rectangle aAddRect(
348 0 : Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
349 0 : Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
350 0 : if ( aHighlightList.size() && nLastRowInRect == ( nRow - 1 ) )
351 0 : aHighlightList[ 0 ]->Union( aAddRect );
352 : else
353 0 : aHighlightList.insert( aHighlightList.begin(), new Rectangle( aAddRect ) );
354 0 : nLastRowInRect = nRow;
355 : }
356 :
357 : // unhighlight the old selection (if any)
358 0 : for ( size_t i = aHighlightList.size(); i > 0; )
359 : {
360 0 : Rectangle *pRect = aHighlightList[ --i ];
361 0 : pDataWin->Invalidate( *pRect );
362 0 : delete pRect;
363 : }
364 0 : aHighlightList.clear();
365 :
366 : // unhighlight old column selection (if any)
367 0 : for ( long nColId = pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION;
368 : nColId != BROWSER_ENDOFSELECTION;
369 0 : nColId = pColSel->NextSelected() )
370 : {
371 : Rectangle aRect( GetFieldRectPixel(nCurRow,
372 0 : (*pCols)[ nColId ]->GetId(),
373 0 : sal_False ) );
374 0 : aRect.Left() -= MIN_COLUMNWIDTH;
375 0 : aRect.Right() += MIN_COLUMNWIDTH;
376 0 : aRect.Top() = 0;
377 0 : aRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
378 0 : pDataWin->Invalidate( aRect );
379 : }
380 :
381 0 : bNotToggleSel = sal_False;
382 : }
383 :
384 : #ifdef _MSC_VER
385 : #pragma optimize( "", on )
386 : #endif
387 :
388 : //-------------------------------------------------------------------
389 :
390 0 : void BrowseBox::DrawCursor()
391 : {
392 0 : sal_Bool bReallyHide = sal_False;
393 0 : if ( SMART_CURSOR_HIDE == bHideCursor )
394 : {
395 0 : if ( !GetSelectRowCount() && !GetSelectColumnCount() )
396 0 : bReallyHide = sal_True;
397 : }
398 0 : else if ( HARD_CURSOR_HIDE == bHideCursor )
399 : {
400 0 : bReallyHide = sal_True;
401 : }
402 :
403 0 : bReallyHide |= !bSelectionIsVisible || !IsUpdateMode() || bScrolling || nCurRow < 0;
404 :
405 0 : if (PaintCursorIfHiddenOnce())
406 0 : bReallyHide |= ( GetCursorHideCount() > 1 );
407 : else
408 0 : bReallyHide |= ( GetCursorHideCount() > 0 );
409 :
410 : // no cursor on handle column
411 0 : if ( nCurColId == HandleColumnId )
412 0 : nCurColId = GetColumnId(1);
413 :
414 : // calculate cursor rectangle
415 0 : Rectangle aCursor;
416 0 : if ( bColumnCursor )
417 : {
418 0 : aCursor = GetFieldRectPixel( nCurRow, nCurColId, sal_False );
419 0 : aCursor.Left() -= MIN_COLUMNWIDTH;
420 0 : aCursor.Right() += 1;
421 0 : aCursor.Bottom() += 1;
422 : }
423 : else
424 : aCursor = Rectangle(
425 0 : Point( ( !pCols->empty() && (*pCols)[ 0 ]->GetId() == 0 ) ?
426 0 : (*pCols)[ 0 ]->Width() : 0,
427 0 : (nCurRow - nTopRow) * GetDataRowHeight() + 1 ),
428 0 : Size( pDataWin->GetOutputSizePixel().Width() + 1,
429 0 : GetDataRowHeight() - 2 ) );
430 0 : if ( bHLines )
431 : {
432 0 : if ( !bMultiSelection )
433 0 : --aCursor.Top();
434 0 : --aCursor.Bottom();
435 : }
436 :
437 0 : if (m_aCursorColor == COL_TRANSPARENT)
438 : {
439 : // on these platforms, the StarView focus works correctly
440 0 : if ( bReallyHide )
441 0 : ((Control*)pDataWin)->HideFocus();
442 : else
443 0 : ((Control*)pDataWin)->ShowFocus( aCursor );
444 : }
445 : else
446 : {
447 0 : Color rCol = bReallyHide ? pDataWin->GetFillColor() : m_aCursorColor;
448 0 : Color aOldFillColor = pDataWin->GetFillColor();
449 0 : Color aOldLineColor = pDataWin->GetLineColor();
450 0 : pDataWin->SetFillColor();
451 0 : pDataWin->SetLineColor( rCol );
452 0 : pDataWin->DrawRect( aCursor );
453 0 : pDataWin->SetLineColor( aOldLineColor );
454 0 : pDataWin->SetFillColor( aOldFillColor );
455 : }
456 0 : }
457 :
458 : //-------------------------------------------------------------------
459 :
460 0 : sal_uLong BrowseBox::GetColumnWidth( sal_uInt16 nId ) const
461 : {
462 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
463 :
464 0 : sal_uInt16 nItemPos = GetColumnPos( nId );
465 0 : if ( nItemPos >= pCols->size() )
466 0 : return 0;
467 0 : return (*pCols)[ nItemPos ]->Width();
468 : }
469 :
470 : //-------------------------------------------------------------------
471 :
472 0 : sal_uInt16 BrowseBox::GetColumnId( sal_uInt16 nPos ) const
473 : {
474 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
475 :
476 0 : if ( nPos >= pCols->size() )
477 0 : return BROWSER_INVALIDID;
478 0 : return (*pCols)[ nPos ]->GetId();
479 : }
480 :
481 : //-------------------------------------------------------------------
482 :
483 0 : sal_uInt16 BrowseBox::GetColumnPos( sal_uInt16 nId ) const
484 : {
485 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
486 :
487 0 : for ( sal_uInt16 nPos = 0; nPos < pCols->size(); ++nPos )
488 0 : if ( (*pCols)[ nPos ]->GetId() == nId )
489 0 : return nPos;
490 0 : return BROWSER_INVALIDID;
491 : }
492 :
493 : //-------------------------------------------------------------------
494 :
495 0 : sal_Bool BrowseBox::IsFrozen( sal_uInt16 nColumnId ) const
496 : {
497 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
498 :
499 0 : for ( size_t nPos = 0; nPos < pCols->size(); ++nPos )
500 0 : if ( (*pCols)[ nPos ]->GetId() == nColumnId )
501 0 : return (*pCols)[ nPos ]->IsFrozen();
502 0 : return sal_False;
503 : }
504 :
505 : //-------------------------------------------------------------------
506 :
507 0 : void BrowseBox::ExpandRowSelection( const BrowserMouseEvent& rEvt )
508 : {
509 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
510 :
511 0 : DoHideCursor( "ExpandRowSelection" );
512 :
513 : // expand the last selection
514 0 : if ( bMultiSelection )
515 : {
516 0 : Range aJustifiedRange( aSelRange );
517 0 : aJustifiedRange.Justify();
518 :
519 0 : sal_Bool bSelectThis = ( bSelect != aJustifiedRange.IsInside( rEvt.GetRow() ) );
520 :
521 0 : if ( aJustifiedRange.IsInside( rEvt.GetRow() ) )
522 : {
523 : // down and up
524 0 : while ( rEvt.GetRow() < aSelRange.Max() )
525 : { // ZTC/Mac bug - don't put these statements together!
526 0 : SelectRow( aSelRange.Max(), bSelectThis, sal_True );
527 0 : --aSelRange.Max();
528 : }
529 0 : while ( rEvt.GetRow() > aSelRange.Max() )
530 : { // ZTC/Mac bug - don't put these statements together!
531 0 : SelectRow( aSelRange.Max(), bSelectThis, sal_True );
532 0 : ++aSelRange.Max();
533 : }
534 : }
535 : else
536 : {
537 : // up and down
538 0 : sal_Bool bOldSelecting = bSelecting;
539 0 : bSelecting = sal_True;
540 0 : while ( rEvt.GetRow() < aSelRange.Max() )
541 : { // ZTC/Mac bug - don't put these statements together!
542 0 : --aSelRange.Max();
543 0 : if ( !IsRowSelected( aSelRange.Max() ) )
544 : {
545 0 : SelectRow( aSelRange.Max(), bSelectThis, sal_True );
546 0 : bSelect = sal_True;
547 : }
548 : }
549 0 : while ( rEvt.GetRow() > aSelRange.Max() )
550 : { // ZTC/Mac bug - don't put these statements together!
551 0 : ++aSelRange.Max();
552 0 : if ( !IsRowSelected( aSelRange.Max() ) )
553 : {
554 0 : SelectRow( aSelRange.Max(), bSelectThis, sal_True );
555 0 : bSelect = sal_True;
556 : }
557 : }
558 0 : bSelecting = bOldSelecting;
559 0 : if ( bSelect )
560 0 : Select();
561 : }
562 : }
563 : else
564 0 : if ( !bMultiSelection || !IsRowSelected( rEvt.GetRow() ) )
565 0 : SelectRow( rEvt.GetRow(), sal_True );
566 :
567 0 : GoToRow( rEvt.GetRow(), sal_False );
568 0 : DoShowCursor( "ExpandRowSelection" );
569 0 : }
570 :
571 : //-------------------------------------------------------------------
572 :
573 0 : void BrowseBox::Resize()
574 : {
575 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
576 0 : if ( !bBootstrapped && IsReallyVisible() )
577 0 : BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
578 0 : if ( pCols->empty() )
579 : {
580 0 : getDataWindow()->bResizeOnPaint = sal_True;
581 0 : return;
582 : }
583 0 : getDataWindow()->bResizeOnPaint = sal_False;
584 :
585 : // calc the size of the scrollbars
586 : // (we can't ask the scrollbars for their widths cause if we're zoomed they still have to be
587 : // resized - which is done in UpdateScrollbars)
588 0 : sal_uLong nSBSize = GetSettings().GetStyleSettings().GetScrollBarSize();
589 0 : if (IsZoom())
590 0 : nSBSize = (sal_uLong)(nSBSize * (double)GetZoom());
591 :
592 0 : DoHideCursor( "Resize" );
593 0 : sal_uInt16 nOldVisibleRows = 0;
594 : //fdo#42694, post #i111125# GetDataRowHeight() can be 0
595 0 : if (GetDataRowHeight())
596 0 : nOldVisibleRows = (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
597 :
598 : // did we need a horizontal scroll bar or is there a Control Area?
599 0 : if ( !getDataWindow()->bNoHScroll &&
600 0 : ( ( pCols->size() - FrozenColCount() ) > 1 ) )
601 0 : aHScroll.Show();
602 : else
603 0 : aHScroll.Hide();
604 :
605 : // calculate the size of the data window
606 0 : long nDataHeight = GetOutputSizePixel().Height() - GetTitleHeight();
607 0 : if ( aHScroll.IsVisible() || ( nControlAreaWidth != USHRT_MAX ) )
608 0 : nDataHeight -= nSBSize;
609 :
610 0 : long nDataWidth = GetOutputSizePixel().Width();
611 0 : if ( pVScroll->IsVisible() )
612 0 : nDataWidth -= nSBSize;
613 :
614 : // adjust position and size of data window
615 : pDataWin->SetPosSizePixel(
616 0 : Point( 0, GetTitleHeight() ),
617 0 : Size( nDataWidth, nDataHeight ) );
618 :
619 0 : sal_uInt16 nVisibleRows = 0;
620 :
621 0 : if (GetDataRowHeight())
622 0 : nVisibleRows = (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
623 :
624 : // TopRow is unchanged, but the number of visible lines has changed.
625 0 : if ( nVisibleRows != nOldVisibleRows )
626 0 : VisibleRowsChanged(nTopRow, nVisibleRows);
627 :
628 0 : UpdateScrollbars();
629 :
630 : // Control-Area
631 0 : Rectangle aInvalidArea( GetControlArea() );
632 0 : aInvalidArea.Right() = GetOutputSizePixel().Width();
633 0 : aInvalidArea.Left() = 0;
634 0 : Invalidate( aInvalidArea );
635 :
636 : // external header-bar
637 0 : HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
638 0 : if ( pHeaderBar )
639 : {
640 : // take the handle column into account
641 0 : BrowserColumn *pFirstCol = (*pCols)[ 0 ];
642 0 : long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
643 0 : pHeaderBar->SetPosSizePixel( Point( nOfsX, 0 ), Size( GetOutputSizePixel().Width() - nOfsX, GetTitleHeight() ) );
644 : }
645 :
646 0 : AutoSizeLastColumn(); // adjust last column width
647 0 : DoShowCursor( "Resize" );
648 : }
649 :
650 : //-------------------------------------------------------------------
651 :
652 0 : void BrowseBox::Paint( const Rectangle& rRect )
653 : {
654 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
655 :
656 : // initializations
657 0 : if ( !bBootstrapped && IsReallyVisible() )
658 0 : BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
659 0 : if ( pCols->empty() )
660 0 : return;
661 :
662 0 : BrowserColumn *pFirstCol = (*pCols)[ 0 ];
663 0 : sal_Bool bHandleCol = pFirstCol && pFirstCol->GetId() == 0;
664 0 : sal_Bool bHeaderBar = getDataWindow()->pHeaderBar != NULL;
665 :
666 : // draw delimitational lines
667 0 : if ( !getDataWindow()->bNoHScroll )
668 0 : DrawLine( Point( 0, aHScroll.GetPosPixel().Y() ),
669 0 : Point( GetOutputSizePixel().Width(),
670 0 : aHScroll.GetPosPixel().Y() ) );
671 :
672 0 : if ( nTitleLines )
673 : {
674 0 : if ( !bHeaderBar )
675 0 : DrawLine( Point( 0, GetTitleHeight() - 1 ),
676 0 : Point( GetOutputSizePixel().Width(),
677 0 : GetTitleHeight() - 1 ) );
678 0 : else if ( bHandleCol )
679 0 : DrawLine( Point( 0, GetTitleHeight() - 1 ),
680 0 : Point( pFirstCol->Width(), GetTitleHeight() - 1 ) );
681 : }
682 :
683 : // Title Bar
684 : // If there is a handle column and if the header bar is available, only
685 : // take the HandleColumn into account
686 0 : if ( nTitleLines && (!bHeaderBar || bHandleCol) )
687 : {
688 : // iterate through columns to redraw
689 0 : long nX = 0;
690 : size_t nCol;
691 0 : for ( nCol = 0;
692 0 : nCol < pCols->size() && nX < rRect.Right();
693 : ++nCol )
694 : {
695 : // skip invisible columns between frozen and scrollable area
696 0 : if ( nCol < nFirstCol && !(*pCols)[ nCol ]->IsFrozen() )
697 0 : nCol = nFirstCol;
698 :
699 : // only the handle column?
700 0 : if (bHeaderBar && bHandleCol && nCol > 0)
701 0 : break;
702 :
703 0 : BrowserColumn *pCol = (*pCols)[ nCol ];
704 :
705 : // draw the column and increment position
706 0 : if ( pCol->Width() > 4 )
707 : {
708 : ButtonFrame aButtonFrame( Point( nX, 0 ),
709 0 : Size( pCol->Width()-1, GetTitleHeight()-1 ),
710 0 : pCol->Title(), sal_False, sal_False, !IsEnabled());
711 0 : aButtonFrame.Draw( *this );
712 0 : DrawLine( Point( nX + pCol->Width() - 1, 0 ),
713 0 : Point( nX + pCol->Width() - 1, GetTitleHeight()-1 ) );
714 : }
715 : else
716 : {
717 0 : Color aOldFillColor = GetFillColor();
718 0 : SetFillColor( Color( COL_BLACK ) );
719 0 : DrawRect( Rectangle( Point( nX, 0 ), Size( pCol->Width(), GetTitleHeight() - 1 ) ) );
720 0 : SetFillColor( aOldFillColor );
721 : }
722 :
723 : // skip column
724 0 : nX += pCol->Width();
725 : }
726 :
727 : // retouching
728 0 : if ( !bHeaderBar && nCol == pCols->size() )
729 : {
730 0 : const StyleSettings &rSettings = GetSettings().GetStyleSettings();
731 0 : Color aColFace( rSettings.GetFaceColor() );
732 0 : Color aOldFillColor = GetFillColor();
733 0 : Color aOldLineColor = GetLineColor();
734 0 : SetFillColor( aColFace );
735 0 : SetLineColor( aColFace );
736 : DrawRect( Rectangle(
737 : Point( nX, 0 ),
738 0 : Point( rRect.Right(), GetTitleHeight() - 2 ) ) );
739 0 : SetFillColor( aOldFillColor);
740 0 : SetLineColor( aOldLineColor);
741 : }
742 : }
743 : }
744 :
745 : //-------------------------------------------------------------------
746 :
747 0 : void BrowseBox::PaintRow( OutputDevice&, const Rectangle& )
748 : {
749 0 : }
750 :
751 : //-------------------------------------------------------------------
752 :
753 0 : void BrowseBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
754 : {
755 0 : sal_Bool bDrawSelection = (nFlags & WINDOW_DRAW_NOSELECTION) == 0;
756 :
757 : // we need pixel coordinates
758 0 : Size aRealSize = pDev->LogicToPixel(rSize);
759 0 : Point aRealPos = pDev->LogicToPixel(rPos);
760 :
761 0 : if ((rSize.Width() < 3) || (rSize.Height() < 3))
762 : // we want to have two pixels frame ...
763 0 : return;
764 :
765 0 : Font aFont = GetDataWindow().GetDrawPixelFont( pDev );
766 : // the 'normal' painting uses always the data window as device to output to, so we have to calc the new font
767 : // relative to the data wins current settings
768 :
769 0 : pDev->Push();
770 0 : pDev->SetMapMode();
771 0 : pDev->SetFont( aFont );
772 :
773 : // draw a frame
774 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
775 0 : pDev->SetLineColor(rStyleSettings.GetDarkShadowColor());
776 0 : pDev->DrawLine(Point(aRealPos.X(), aRealPos.Y()),
777 0 : Point(aRealPos.X(), aRealPos.Y() + aRealSize.Height() - 1));
778 0 : pDev->DrawLine(Point(aRealPos.X(), aRealPos.Y()),
779 0 : Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y()));
780 0 : pDev->SetLineColor(rStyleSettings.GetShadowColor());
781 0 : pDev->DrawLine(Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + 1),
782 0 : Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + aRealSize.Height() - 1));
783 0 : pDev->DrawLine(Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + aRealSize.Height() - 1),
784 0 : Point(aRealPos.X() + 1, aRealPos.Y() + aRealSize.Height() - 1));
785 :
786 0 : HeaderBar* pBar = getDataWindow()->pHeaderBar;
787 :
788 : // we're drawing onto a foreign device, so we have to fake the DataRowHeight for the subsequent ImplPaintData
789 : // (as it is based on the settings of our data window, not the foreign device)
790 0 : if (!nDataRowHeight)
791 0 : ImpGetDataRowHeight();
792 0 : long nHeightLogic = PixelToLogic(Size(0, nDataRowHeight), MAP_10TH_MM).Height();
793 0 : long nForeignHeightPixel = pDev->LogicToPixel(Size(0, nHeightLogic), MAP_10TH_MM).Height();
794 :
795 0 : long nOriginalHeight = nDataRowHeight;
796 0 : nDataRowHeight = nForeignHeightPixel;
797 :
798 : // this counts for the column widths, too
799 : size_t nPos;
800 0 : for ( nPos = 0; nPos < pCols->size(); ++nPos )
801 : {
802 0 : BrowserColumn* pCurrent = (*pCols)[ nPos ];
803 :
804 0 : long nWidthLogic = PixelToLogic(Size(pCurrent->Width(), 0), MAP_10TH_MM).Width();
805 0 : long nForeignWidthPixel = pDev->LogicToPixel(Size(nWidthLogic, 0), MAP_10TH_MM).Width();
806 :
807 0 : pCurrent->SetWidth(nForeignWidthPixel, GetZoom());
808 0 : if ( pBar )
809 0 : pBar->SetItemSize( pCurrent->GetId(), pCurrent->Width() );
810 : }
811 :
812 : // a smaller area for the content
813 0 : ++aRealPos.X();
814 0 : ++aRealPos.Y();
815 0 : aRealSize.Width() -= 2;
816 0 : aRealSize.Height() -= 2;
817 :
818 : // let the header bar draw itself
819 0 : if ( pBar )
820 : {
821 : // the title height with respect to the font set for the given device
822 0 : long nTitleHeight = PixelToLogic(Size(0, GetTitleHeight()), MAP_10TH_MM).Height();
823 0 : nTitleHeight = pDev->LogicToPixel(Size(0, nTitleHeight), MAP_10TH_MM).Height();
824 :
825 0 : BrowserColumn* pFirstCol = !pCols->empty() ? (*pCols)[ 0 ] : NULL;
826 :
827 0 : Point aHeaderPos(pFirstCol && (pFirstCol->GetId() == 0) ? pFirstCol->Width() : 0, 0);
828 0 : Size aHeaderSize(aRealSize.Width() - aHeaderPos.X(), nTitleHeight);
829 :
830 0 : aHeaderPos += aRealPos;
831 : // do this before converting to logics !
832 :
833 : // the header's draw expects logic coordinates, again
834 0 : aHeaderPos = pDev->PixelToLogic(aHeaderPos);
835 0 : aHeaderSize = pDev->PixelToLogic(aHeaderSize);
836 :
837 0 : pBar->Draw(pDev, aHeaderPos, aHeaderSize, nFlags);
838 :
839 : // draw the "upper left cell" (the intersection between the header bar and the handle column)
840 0 : if (( pFirstCol->GetId() == 0 ) && ( pFirstCol->Width() > 4 ))
841 : {
842 : ButtonFrame aButtonFrame( aRealPos,
843 0 : Size( pFirstCol->Width()-1, nTitleHeight-1 ),
844 0 : pFirstCol->Title(), sal_False, sal_False, !IsEnabled());
845 0 : aButtonFrame.Draw( *pDev );
846 :
847 0 : pDev->Push( PUSH_LINECOLOR );
848 0 : pDev->SetLineColor( Color( COL_BLACK ) );
849 :
850 0 : pDev->DrawLine( Point( aRealPos.X(), aRealPos.Y() + nTitleHeight-1 ),
851 0 : Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() + nTitleHeight-1 ) );
852 0 : pDev->DrawLine( Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() ),
853 0 : Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() + nTitleHeight-1 ) );
854 :
855 0 : pDev->Pop();
856 : }
857 :
858 0 : aRealPos.Y() += aHeaderSize.Height();
859 0 : aRealSize.Height() -= aHeaderSize.Height();
860 : }
861 :
862 : // draw our own content (with clipping)
863 0 : Region aRegion(Rectangle(aRealPos, aRealSize));
864 0 : pDev->SetClipRegion( pDev->PixelToLogic( aRegion ) );
865 :
866 : // do we have to paint the background
867 0 : sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && GetDataWindow().IsControlBackground();
868 0 : if ( bBackground )
869 : {
870 0 : Rectangle aRect( aRealPos, aRealSize );
871 0 : pDev->SetFillColor( GetDataWindow().GetControlBackground() );
872 0 : pDev->DrawRect( aRect );
873 : }
874 :
875 0 : ImplPaintData( *pDev, Rectangle( aRealPos, aRealSize ), sal_True, bDrawSelection );
876 :
877 : // restore the column widths/data row height
878 0 : nDataRowHeight = nOriginalHeight;
879 0 : for ( nPos = 0; nPos < pCols->size(); ++nPos )
880 : {
881 0 : BrowserColumn* pCurrent = (*pCols)[ nPos ];
882 :
883 0 : long nForeignWidthLogic = pDev->PixelToLogic(Size(pCurrent->Width(), 0), MAP_10TH_MM).Width();
884 0 : long nWidthPixel = LogicToPixel(Size(nForeignWidthLogic, 0), MAP_10TH_MM).Width();
885 :
886 0 : pCurrent->SetWidth(nWidthPixel, GetZoom());
887 0 : if ( pBar )
888 0 : pBar->SetItemSize( pCurrent->GetId(), pCurrent->Width() );
889 : }
890 :
891 0 : pDev->Pop();
892 : }
893 :
894 : //-------------------------------------------------------------------
895 :
896 0 : void BrowseBox::ImplPaintData(OutputDevice& _rOut, const Rectangle& _rRect, sal_Bool _bForeignDevice, sal_Bool _bDrawSelections)
897 : {
898 0 : Point aOverallAreaPos = _bForeignDevice ? _rRect.TopLeft() : Point(0,0);
899 0 : Size aOverallAreaSize = _bForeignDevice ? _rRect.GetSize() : GetDataWindow().GetOutputSizePixel();
900 0 : Point aOverallAreaBRPos = _bForeignDevice ? _rRect.BottomRight() : Point( aOverallAreaSize.Width(), aOverallAreaSize.Height() );
901 :
902 0 : long nDataRowHeigt = GetDataRowHeight();
903 :
904 : // compute relative rows to redraw
905 0 : sal_uLong nRelTopRow = 0;
906 0 : sal_uLong nRelBottomRow = aOverallAreaSize.Height();
907 0 : if (!_bForeignDevice && nDataRowHeigt)
908 : {
909 0 : nRelTopRow = ((sal_uLong)_rRect.Top() / nDataRowHeigt);
910 0 : nRelBottomRow = (sal_uLong)(_rRect.Bottom()) / nDataRowHeigt;
911 : }
912 :
913 : // cache frequently used values
914 0 : Point aPos( aOverallAreaPos.X(), nRelTopRow * nDataRowHeigt + aOverallAreaPos.Y() );
915 0 : _rOut.SetLineColor( Color( COL_WHITE ) );
916 0 : const AllSettings& rAllSets = _rOut.GetSettings();
917 0 : const StyleSettings &rSettings = rAllSets.GetStyleSettings();
918 0 : const Color &rHighlightTextColor = rSettings.GetHighlightTextColor();
919 0 : const Color &rHighlightFillColor = rSettings.GetHighlightColor();
920 0 : Color aOldTextColor = _rOut.GetTextColor();
921 0 : Color aOldFillColor = _rOut.GetFillColor();
922 0 : Color aOldLineColor = _rOut.GetLineColor();
923 0 : long nHLineX = 0 == (*pCols)[ 0 ]->GetId() ? (*pCols)[ 0 ]->Width() : 0;
924 0 : nHLineX += aOverallAreaPos.X();
925 :
926 0 : Color aDelimiterLineColor( ::svtools::ColorConfig().GetColorValue( ::svtools::CALCGRID ).nColor );
927 :
928 : // redraw the invalid fields
929 0 : for ( sal_uLong nRelRow = nRelTopRow;
930 : nRelRow <= nRelBottomRow && (sal_uLong)nTopRow+nRelRow < (sal_uLong)nRowCount;
931 0 : ++nRelRow, aPos.Y() += nDataRowHeigt )
932 : {
933 : // get row
934 : // check valid area, to be on the safe side:
935 : DBG_ASSERT( (sal_uInt16)(nTopRow+nRelRow) < nRowCount, "BrowseBox::ImplPaintData: invalid seek" );
936 0 : if ( (nTopRow+long(nRelRow)) < 0 || (sal_uInt16)(nTopRow+nRelRow) >= nRowCount )
937 0 : continue;
938 :
939 : // prepare row
940 0 : sal_uLong nRow = nTopRow+nRelRow;
941 0 : if ( !SeekRow( nRow) ) {
942 : OSL_FAIL("BrowseBox::ImplPaintData: SeekRow failed");
943 : }
944 0 : _rOut.SetClipRegion();
945 0 : aPos.X() = aOverallAreaPos.X();
946 :
947 :
948 : // #73325# don't paint the row outside the painting rectangle (DG)
949 : // prepare auto-highlight
950 0 : Rectangle aRowRect( Point( _rRect.TopLeft().X(), aPos.Y() ),
951 0 : Size( _rRect.GetSize().Width(), nDataRowHeigt ) );
952 0 : PaintRow( _rOut, aRowRect );
953 :
954 : sal_Bool bRowSelected = _bDrawSelections
955 0 : && !bHideSelect
956 0 : && IsRowSelected( nRow );
957 0 : if ( bRowSelected )
958 : {
959 0 : _rOut.SetTextColor( rHighlightTextColor );
960 0 : _rOut.SetFillColor( rHighlightFillColor );
961 0 : _rOut.SetLineColor();
962 0 : _rOut.DrawRect( aRowRect );
963 : }
964 :
965 : // iterate through columns to redraw
966 : size_t nCol;
967 0 : for ( nCol = 0; nCol < pCols->size(); ++nCol )
968 : {
969 : // get column
970 0 : BrowserColumn *pCol = (*pCols)[ nCol ];
971 :
972 : // at end of invalid area
973 0 : if ( aPos.X() >= _rRect.Right() )
974 0 : break;
975 :
976 : // skip invisible colums between frozen and scrollable area
977 0 : if ( nCol < nFirstCol && !pCol->IsFrozen() )
978 : {
979 0 : nCol = nFirstCol;
980 0 : pCol = (nCol < pCols->size() ) ? (*pCols)[ nCol ] : NULL;
981 0 : if (!pCol)
982 : { // FS - 21.05.99 - 66325
983 : // actually this has been fixed elsewhere (in the right place),
984 : // but let's make sure...
985 : OSL_FAIL("BrowseBox::PaintData : nFirstCol is probably invalid !");
986 0 : break;
987 : }
988 : }
989 :
990 : // prepare Column-AutoHighlight
991 : sal_Bool bColAutoHighlight = _bDrawSelections
992 : && bColumnCursor
993 0 : && IsColumnSelected( pCol->GetId() );
994 0 : if ( bColAutoHighlight )
995 : {
996 0 : _rOut.SetClipRegion();
997 0 : _rOut.SetTextColor( rHighlightTextColor );
998 0 : _rOut.SetFillColor( rHighlightFillColor );
999 0 : _rOut.SetLineColor();
1000 : Rectangle aFieldRect( aPos,
1001 0 : Size( pCol->Width(), nDataRowHeigt ) );
1002 0 : _rOut.DrawRect( aFieldRect );
1003 : }
1004 :
1005 0 : if (!m_bFocusOnlyCursor && (pCol->GetId() == GetCurColumnId()) && (nRow == (sal_uLong)GetCurRow()))
1006 0 : DrawCursor();
1007 :
1008 : // draw a single field.
1009 : // else something is drawn to, e.g. handle column
1010 0 : if (pCol->Width())
1011 : {
1012 : // clip the column's output to the field area
1013 0 : if (_bForeignDevice)
1014 : { // (not necessary if painting onto the data window)
1015 0 : Size aFieldSize(pCol->Width(), nDataRowHeigt);
1016 :
1017 0 : if (aPos.X() + aFieldSize.Width() > aOverallAreaBRPos.X())
1018 0 : aFieldSize.Width() = aOverallAreaBRPos.X() - aPos.X();
1019 :
1020 0 : if (aPos.Y() + aFieldSize.Height() > aOverallAreaBRPos.Y() + 1)
1021 : {
1022 : // for non-handle cols we don't clip vertically : we just don't draw the cell if the line isn't completely visible
1023 0 : if (pCol->GetId() != 0)
1024 0 : continue;
1025 0 : aFieldSize.Height() = aOverallAreaBRPos.Y() + 1 - aPos.Y();
1026 : }
1027 :
1028 0 : Region aClipToField(Rectangle(aPos, aFieldSize));
1029 0 : _rOut.SetClipRegion(aClipToField);
1030 : }
1031 0 : pCol->Draw( *this, _rOut, aPos, sal_False );
1032 0 : if (_bForeignDevice)
1033 0 : _rOut.SetClipRegion();
1034 : }
1035 :
1036 : // reset Column-auto-highlight
1037 0 : if ( bColAutoHighlight )
1038 : {
1039 0 : _rOut.SetTextColor( aOldTextColor );
1040 0 : _rOut.SetFillColor( aOldFillColor );
1041 0 : _rOut.SetLineColor( aOldLineColor );
1042 : }
1043 :
1044 : // skip column
1045 0 : aPos.X() += pCol->Width();
1046 : }
1047 :
1048 : // reset auto-highlight
1049 0 : if ( bRowSelected )
1050 : {
1051 0 : _rOut.SetTextColor( aOldTextColor );
1052 0 : _rOut.SetFillColor( aOldFillColor );
1053 0 : _rOut.SetLineColor( aOldLineColor );
1054 : }
1055 :
1056 0 : if ( bHLines )
1057 : {
1058 : // draw horizontal delimitation lines
1059 0 : _rOut.SetClipRegion();
1060 0 : _rOut.Push( PUSH_LINECOLOR );
1061 0 : _rOut.SetLineColor( aDelimiterLineColor );
1062 0 : long nY = aPos.Y() + nDataRowHeigt - 1;
1063 0 : if (nY <= aOverallAreaBRPos.Y())
1064 : _rOut.DrawLine( Point( nHLineX, nY ),
1065 : Point( bVLines
1066 0 : ? std::min(long(long(aPos.X()) - 1), aOverallAreaBRPos.X())
1067 0 : : aOverallAreaBRPos.X(),
1068 0 : nY ) );
1069 0 : _rOut.Pop();
1070 : }
1071 : }
1072 :
1073 0 : if (aPos.Y() > aOverallAreaBRPos.Y() + 1)
1074 0 : aPos.Y() = aOverallAreaBRPos.Y() + 1;
1075 : // needed for some of the following drawing
1076 :
1077 : // retouching
1078 0 : _rOut.SetClipRegion();
1079 0 : aOldLineColor = _rOut.GetLineColor();
1080 0 : aOldFillColor = _rOut.GetFillColor();
1081 0 : _rOut.SetFillColor( rSettings.GetFaceColor() );
1082 0 : if ( !pCols->empty() && ( (*pCols)[ 0 ]->GetId() == 0 ) && ( aPos.Y() <= _rRect.Bottom() ) )
1083 : {
1084 : // fill rectangle gray below handle column
1085 : // DG: fill it only until the end of the drawing rect and not to the end, as this may overpaint handle columns
1086 0 : _rOut.SetLineColor( Color( COL_BLACK ) );
1087 : _rOut.DrawRect( Rectangle(
1088 0 : Point( aOverallAreaPos.X() - 1, aPos.Y() - 1 ),
1089 0 : Point( aOverallAreaPos.X() + (*pCols)[ 0 ]->Width() - 1,
1090 0 : _rRect.Bottom() + 1) ) );
1091 : }
1092 0 : _rOut.SetFillColor( aOldFillColor );
1093 :
1094 : // draw vertical delimitational line between frozen and scrollable cols
1095 0 : _rOut.SetLineColor( COL_BLACK );
1096 0 : long nFrozenWidth = GetFrozenWidth()-1;
1097 0 : _rOut.DrawLine( Point( aOverallAreaPos.X() + nFrozenWidth, aPos.Y() ),
1098 0 : Point( aOverallAreaPos.X() + nFrozenWidth, bHLines
1099 0 : ? aPos.Y() - 1
1100 0 : : aOverallAreaBRPos.Y() ) );
1101 :
1102 : // draw vertical delimitational lines?
1103 0 : if ( bVLines )
1104 : {
1105 0 : _rOut.SetLineColor( aDelimiterLineColor );
1106 0 : Point aVertPos( aOverallAreaPos.X() - 1, aOverallAreaPos.Y() );
1107 0 : long nDeltaY = aOverallAreaBRPos.Y();
1108 0 : for ( size_t nCol = 0; nCol < pCols->size(); ++nCol )
1109 : {
1110 : // get column
1111 0 : BrowserColumn *pCol = (*pCols)[ nCol ];
1112 :
1113 : // skip invisible columns between frozen and scrollable area
1114 0 : if ( nCol < nFirstCol && !pCol->IsFrozen() )
1115 : {
1116 0 : nCol = nFirstCol;
1117 0 : pCol = (*pCols)[ nCol ];
1118 : }
1119 :
1120 : // skip column
1121 0 : aVertPos.X() += pCol->Width();
1122 :
1123 : // at end of invalid area
1124 : // invalid area is first reached when X > Right
1125 : // and not >=
1126 0 : if ( aVertPos.X() > _rRect.Right() )
1127 0 : break;
1128 :
1129 : // draw a single line
1130 0 : if ( pCol->GetId() != 0 )
1131 0 : _rOut.DrawLine( aVertPos, Point( aVertPos.X(),
1132 : bHLines
1133 0 : ? aPos.Y() - 1
1134 0 : : aPos.Y() + nDeltaY ) );
1135 : }
1136 : }
1137 :
1138 0 : _rOut.SetLineColor( aOldLineColor );
1139 0 : }
1140 :
1141 : //-------------------------------------------------------------------
1142 :
1143 0 : void BrowseBox::PaintData( Window& rWin, const Rectangle& rRect )
1144 : {
1145 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1146 0 : if ( !bBootstrapped && IsReallyVisible() )
1147 0 : BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
1148 :
1149 : // initializations
1150 0 : if ( !pCols || pCols->empty() || !rWin.IsUpdateMode() )
1151 0 : return;
1152 0 : if ( getDataWindow()->bResizeOnPaint )
1153 0 : Resize();
1154 : // MI: who was that? Window::Update();
1155 :
1156 0 : ImplPaintData(rWin, rRect, sal_False, sal_True);
1157 : }
1158 :
1159 : //-------------------------------------------------------------------
1160 :
1161 0 : void BrowseBox::UpdateScrollbars()
1162 : {
1163 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1164 :
1165 0 : if ( !bBootstrapped || !IsUpdateMode() )
1166 : return;
1167 :
1168 : // protect against recursion
1169 0 : BrowserDataWin *pBDW = (BrowserDataWin*) pDataWin;
1170 0 : if ( pBDW->bInUpdateScrollbars )
1171 : {
1172 0 : pBDW->bHadRecursion = sal_True;
1173 : return;
1174 : }
1175 0 : pBDW->bInUpdateScrollbars = sal_True;
1176 :
1177 : // the size of the corner window (and the width of the VSB/height of the HSB)
1178 0 : sal_uLong nCornerSize = GetSettings().GetStyleSettings().GetScrollBarSize();
1179 0 : if (IsZoom())
1180 0 : nCornerSize = (sal_uLong)(nCornerSize * (double)GetZoom());
1181 :
1182 0 : sal_Bool bNeedsVScroll = sal_False;
1183 0 : long nMaxRows = 0;
1184 0 : if (GetDataRowHeight())
1185 : {
1186 : // needs VScroll?
1187 0 : nMaxRows = (pDataWin->GetSizePixel().Height()) / GetDataRowHeight();
1188 : bNeedsVScroll = getDataWindow()->bAutoVScroll
1189 : ? nTopRow || ( nRowCount > nMaxRows )
1190 0 : : !getDataWindow()->bNoVScroll;
1191 : }
1192 0 : Size aDataWinSize = pDataWin->GetSizePixel();
1193 0 : if ( !bNeedsVScroll )
1194 : {
1195 0 : if ( pVScroll->IsVisible() )
1196 : {
1197 0 : pVScroll->Hide();
1198 0 : Size aNewSize( aDataWinSize );
1199 0 : aNewSize.Width() = GetOutputSizePixel().Width();
1200 0 : aDataWinSize = aNewSize;
1201 : }
1202 : }
1203 0 : else if ( !pVScroll->IsVisible() )
1204 : {
1205 0 : Size aNewSize( aDataWinSize );
1206 0 : aNewSize.Width() = GetOutputSizePixel().Width() - nCornerSize;
1207 0 : aDataWinSize = aNewSize;
1208 : }
1209 :
1210 : // needs HScroll?
1211 0 : sal_uLong nLastCol = GetColumnAtXPosPixel( aDataWinSize.Width() - 1 );
1212 :
1213 0 : sal_uInt16 nFrozenCols = FrozenColCount();
1214 : sal_Bool bNeedsHScroll = getDataWindow()->bAutoHScroll
1215 0 : ? ( nFirstCol > nFrozenCols ) || ( nLastCol <= pCols->size() )
1216 0 : : !getDataWindow()->bNoHScroll;
1217 0 : if ( !bNeedsHScroll )
1218 : {
1219 0 : if ( aHScroll.IsVisible() )
1220 : {
1221 0 : aHScroll.Hide();
1222 : }
1223 0 : aDataWinSize.Height() = GetOutputSizePixel().Height() - GetTitleHeight();
1224 0 : if ( nControlAreaWidth != USHRT_MAX )
1225 0 : aDataWinSize.Height() -= nCornerSize;
1226 : }
1227 0 : else if ( !aHScroll.IsVisible() )
1228 : {
1229 0 : Size aNewSize( aDataWinSize );
1230 0 : aNewSize.Height() = GetOutputSizePixel().Height() - GetTitleHeight() - nCornerSize;
1231 0 : aDataWinSize = aNewSize;
1232 : }
1233 :
1234 : // adjust position and Width of horizontal scrollbar
1235 : sal_uLong nHScrX = nControlAreaWidth == USHRT_MAX
1236 : ? 0
1237 0 : : nControlAreaWidth;
1238 :
1239 : aHScroll.SetPosSizePixel(
1240 0 : Point( nHScrX, GetOutputSizePixel().Height() - nCornerSize ),
1241 0 : Size( aDataWinSize.Width() - nHScrX, nCornerSize ) );
1242 :
1243 : // total scrollable columns
1244 0 : short nScrollCols = short(pCols->size()) - (short)nFrozenCols;
1245 :
1246 : // visible columns
1247 : short nVisibleHSize = nLastCol == BROWSER_INVALIDID
1248 0 : ? (short)( pCols->size() - nFirstCol )
1249 0 : : (short)( nLastCol - nFirstCol );
1250 :
1251 0 : short nRange = Max( nScrollCols, (short)0 );
1252 0 : aHScroll.SetVisibleSize( nVisibleHSize );
1253 0 : aHScroll.SetRange( Range( 0, nRange ));
1254 0 : if ( bNeedsHScroll && !aHScroll.IsVisible() )
1255 0 : aHScroll.Show();
1256 :
1257 : // adjust position and height of vertical scrollbar
1258 0 : pVScroll->SetPageSize( nMaxRows );
1259 :
1260 0 : if ( nTopRow > nRowCount )
1261 : {
1262 0 : nTopRow = nRowCount - 1;
1263 : OSL_FAIL("BrowseBox: nTopRow > nRowCount");
1264 : }
1265 :
1266 0 : if ( pVScroll->GetThumbPos() != nTopRow )
1267 0 : pVScroll->SetThumbPos( nTopRow );
1268 0 : long nVisibleSize = Min( Min( nRowCount, nMaxRows ), long(nRowCount-nTopRow) );
1269 0 : pVScroll->SetVisibleSize( nVisibleSize ? nVisibleSize : 1 );
1270 0 : pVScroll->SetRange( Range( 0, nRowCount ) );
1271 : pVScroll->SetPosSizePixel(
1272 0 : Point( aDataWinSize.Width(), GetTitleHeight() ),
1273 0 : Size( nCornerSize, aDataWinSize.Height()) );
1274 0 : long nLclDataRowHeight = GetDataRowHeight();
1275 0 : if ( nLclDataRowHeight > 0 && nRowCount < long( aDataWinSize.Height() / nLclDataRowHeight ) )
1276 0 : ScrollRows( -nTopRow );
1277 0 : if ( bNeedsVScroll && !pVScroll->IsVisible() )
1278 0 : pVScroll->Show();
1279 :
1280 : pDataWin->SetPosSizePixel(
1281 0 : Point( 0, GetTitleHeight() ),
1282 0 : aDataWinSize );
1283 :
1284 : // needs corner-window?
1285 : // (do that AFTER positioning BOTH scrollbars)
1286 0 : sal_uLong nActualCorderWidth = 0;
1287 0 : if (aHScroll.IsVisible() && pVScroll && pVScroll->IsVisible() )
1288 : {
1289 : // if we have both scrollbars, the corner window fills the point of intersection of these two
1290 0 : nActualCorderWidth = nCornerSize;
1291 : }
1292 0 : else if ( !aHScroll.IsVisible() && ( nControlAreaWidth != USHRT_MAX ) )
1293 : {
1294 : // if we have no horizontal scrollbar, but a control area, we need the corner window to
1295 : // fill the space between the control are and the right border
1296 0 : nActualCorderWidth = GetOutputSizePixel().Width() - nControlAreaWidth;
1297 : }
1298 0 : if ( nActualCorderWidth )
1299 : {
1300 0 : if ( !getDataWindow()->pCornerWin )
1301 0 : getDataWindow()->pCornerWin = new ScrollBarBox( this, 0 );
1302 : getDataWindow()->pCornerWin->SetPosSizePixel(
1303 0 : Point( GetOutputSizePixel().Width() - nActualCorderWidth, aHScroll.GetPosPixel().Y() ),
1304 0 : Size( nActualCorderWidth, nCornerSize ) );
1305 0 : getDataWindow()->pCornerWin->Show();
1306 : }
1307 : else
1308 0 : DELETEZ( getDataWindow()->pCornerWin );
1309 :
1310 : // scroll headerbar, if necessary
1311 0 : if ( getDataWindow()->pHeaderBar )
1312 : {
1313 0 : long nWidth = 0;
1314 0 : for ( size_t nCol = 0;
1315 0 : nCol < pCols->size() && nCol < nFirstCol;
1316 : ++nCol )
1317 : {
1318 : // not the handle column
1319 0 : if ( (*pCols)[ nCol ]->GetId() )
1320 0 : nWidth += (*pCols)[ nCol ]->Width();
1321 : }
1322 :
1323 0 : getDataWindow()->pHeaderBar->SetOffset( nWidth );
1324 : }
1325 :
1326 0 : pBDW->bInUpdateScrollbars = sal_False;
1327 0 : if ( pBDW->bHadRecursion )
1328 : {
1329 0 : pBDW->bHadRecursion = sal_False;
1330 0 : UpdateScrollbars();
1331 : }
1332 : }
1333 :
1334 : //-------------------------------------------------------------------
1335 :
1336 0 : void BrowseBox::SetUpdateMode( sal_Bool bUpdate )
1337 : {
1338 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1339 :
1340 0 : sal_Bool bWasUpdate = IsUpdateMode();
1341 0 : if ( bWasUpdate == bUpdate )
1342 0 : return;
1343 :
1344 0 : Control::SetUpdateMode( bUpdate );
1345 : // If WB_CLIPCHILDREN is st at the BrowseBox (to minimize flicker),
1346 : // the data window is not invalidated by SetUpdateMode.
1347 0 : if( bUpdate )
1348 0 : getDataWindow()->Invalidate();
1349 0 : getDataWindow()->SetUpdateMode( bUpdate );
1350 :
1351 :
1352 0 : if ( bUpdate )
1353 : {
1354 0 : if ( bBootstrapped )
1355 : {
1356 0 : UpdateScrollbars();
1357 0 : AutoSizeLastColumn();
1358 : }
1359 0 : DoShowCursor( "SetUpdateMode" );
1360 : }
1361 : else
1362 0 : DoHideCursor( "SetUpdateMode" );
1363 : }
1364 :
1365 : //-------------------------------------------------------------------
1366 :
1367 0 : sal_Bool BrowseBox::GetUpdateMode() const
1368 : {
1369 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1370 :
1371 0 : return getDataWindow()->IsUpdateMode();
1372 : }
1373 :
1374 : //-------------------------------------------------------------------
1375 :
1376 0 : long BrowseBox::GetFrozenWidth() const
1377 : {
1378 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1379 :
1380 0 : long nWidth = 0;
1381 0 : for ( size_t nCol = 0;
1382 0 : nCol < pCols->size() && (*pCols)[ nCol ]->IsFrozen();
1383 : ++nCol )
1384 0 : nWidth += (*pCols)[ nCol ]->Width();
1385 0 : return nWidth;
1386 : }
1387 :
1388 : //-------------------------------------------------------------------
1389 :
1390 0 : void BrowseBox::ColumnInserted( sal_uInt16 nPos )
1391 : {
1392 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1393 :
1394 0 : if ( pColSel )
1395 0 : pColSel->Insert( nPos );
1396 0 : UpdateScrollbars();
1397 0 : }
1398 :
1399 : //-------------------------------------------------------------------
1400 :
1401 0 : sal_uInt16 BrowseBox::FrozenColCount() const
1402 : {
1403 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1404 : sal_uInt16 nCol;
1405 0 : for ( nCol = 0;
1406 0 : nCol < pCols->size() && (*pCols)[ nCol ]->IsFrozen();
1407 : ++nCol )
1408 : /* empty loop */;
1409 0 : return nCol;
1410 : }
1411 :
1412 : //-------------------------------------------------------------------
1413 :
1414 0 : IMPL_LINK(BrowseBox,ScrollHdl,ScrollBar*,pBar)
1415 : {
1416 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1417 :
1418 0 : if ( pBar->GetDelta() == 0 )
1419 0 : return 0;
1420 :
1421 0 : if ( pBar->GetDelta() < 0 && getDataWindow()->bNoScrollBack )
1422 : {
1423 0 : UpdateScrollbars();
1424 0 : return 0;
1425 : }
1426 :
1427 0 : if ( pBar == &aHScroll )
1428 0 : ScrollColumns( aHScroll.GetDelta() );
1429 0 : if ( pBar == pVScroll )
1430 0 : ScrollRows( pVScroll->GetDelta() );
1431 :
1432 0 : return 0;
1433 : }
1434 :
1435 : //-------------------------------------------------------------------
1436 :
1437 0 : IMPL_LINK_NOARG(BrowseBox, EndScrollHdl)
1438 : {
1439 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1440 :
1441 0 : if ( getDataWindow()->bNoScrollBack )
1442 : {
1443 0 : EndScroll();
1444 0 : return 0;
1445 : }
1446 :
1447 0 : return 0;
1448 : }
1449 :
1450 : //-------------------------------------------------------------------
1451 :
1452 0 : IMPL_LINK( BrowseBox, StartDragHdl, HeaderBar*, pBar )
1453 : {
1454 0 : pBar->SetDragSize( pDataWin->GetOutputSizePixel().Height() );
1455 0 : return 0;
1456 : }
1457 :
1458 : //-------------------------------------------------------------------
1459 : // usually only the first column was resized
1460 : #ifdef _MSC_VER
1461 : #pragma optimize("",off)
1462 : #endif
1463 :
1464 0 : void BrowseBox::MouseButtonDown( const MouseEvent& rEvt )
1465 : {
1466 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1467 :
1468 0 : GrabFocus();
1469 :
1470 : // only mouse events in the title-line are supported
1471 0 : const Point &rEvtPos = rEvt.GetPosPixel();
1472 0 : if ( rEvtPos.Y() >= GetTitleHeight() )
1473 0 : return;
1474 :
1475 0 : long nX = 0;
1476 0 : long nWidth = GetOutputSizePixel().Width();
1477 0 : for ( size_t nCol = 0; nCol < pCols->size() && nX < nWidth; ++nCol )
1478 : {
1479 : // is this column visible?
1480 0 : BrowserColumn *pCol = (*pCols)[ nCol ];
1481 0 : if ( pCol->IsFrozen() || nCol >= nFirstCol )
1482 : {
1483 : // compute right end of column
1484 0 : long nR = nX + pCol->Width() - 1;
1485 :
1486 : // at the end of a column (and not handle column)?
1487 0 : if ( pCol->GetId() && Abs( nR - rEvtPos.X() ) < 2 )
1488 : {
1489 : // start resizing the column
1490 0 : bResizing = sal_True;
1491 0 : nResizeCol = nCol;
1492 0 : nDragX = nResizeX = rEvtPos.X();
1493 0 : SetPointer( Pointer( POINTER_HSPLIT ) );
1494 0 : CaptureMouse();
1495 : pDataWin->DrawLine( Point( nDragX, 0 ),
1496 0 : Point( nDragX, pDataWin->GetSizePixel().Height() ) );
1497 0 : nMinResizeX = nX + MIN_COLUMNWIDTH;
1498 0 : return;
1499 : }
1500 0 : else if ( nX < rEvtPos.X() && nR > rEvtPos.X() )
1501 : {
1502 : MouseButtonDown( BrowserMouseEvent(
1503 0 : this, rEvt, -1, nCol, pCol->GetId(), Rectangle() ) );
1504 0 : return;
1505 : }
1506 0 : nX = nR + 1;
1507 : }
1508 : }
1509 :
1510 : // event occurred out of data area
1511 0 : if ( rEvt.IsRight() )
1512 : pDataWin->Command(
1513 0 : CommandEvent( Point( 1, LONG_MAX ), COMMAND_CONTEXTMENU, sal_True ) );
1514 : else
1515 0 : SetNoSelection();
1516 : }
1517 :
1518 : #ifdef _MSC_VER
1519 : #pragma optimize("",on)
1520 : #endif
1521 :
1522 : //-------------------------------------------------------------------
1523 :
1524 0 : void BrowseBox::MouseMove( const MouseEvent& rEvt )
1525 : {
1526 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1527 : OSL_TRACE( "BrowseBox::MouseMove( MouseEvent )" );
1528 :
1529 0 : Pointer aNewPointer;
1530 :
1531 0 : sal_uInt16 nX = 0;
1532 0 : for ( size_t nCol = 0;
1533 0 : nCol < pCols->size() &&
1534 0 : ( nX + (*pCols)[ nCol ]->Width() ) < sal_uInt16(GetOutputSizePixel().Width());
1535 : ++nCol )
1536 : // is this column visible?
1537 0 : if ( (*pCols)[ nCol ]->IsFrozen() || nCol >= nFirstCol )
1538 : {
1539 : // compute right end of column
1540 0 : BrowserColumn *pCol = (*pCols)[ nCol ];
1541 0 : sal_uInt16 nR = (sal_uInt16)(nX + pCol->Width() - 1);
1542 :
1543 : // show resize-pointer?
1544 0 : if ( bResizing || ( pCol->GetId() &&
1545 0 : Abs( ((long) nR ) - rEvt.GetPosPixel().X() ) < MIN_COLUMNWIDTH ) )
1546 : {
1547 0 : aNewPointer = Pointer( POINTER_HSPLIT );
1548 0 : if ( bResizing )
1549 : {
1550 : // delete old auxiliary line
1551 0 : pDataWin->HideTracking() ;
1552 :
1553 : // check allowed width and new delta
1554 0 : nDragX = Max( rEvt.GetPosPixel().X(), nMinResizeX );
1555 0 : long nDeltaX = nDragX - nResizeX;
1556 0 : sal_uInt16 nId = GetColumnId(nResizeCol);
1557 0 : sal_uLong nOldWidth = GetColumnWidth(nId);
1558 0 : nDragX = QueryColumnResize( GetColumnId(nResizeCol),
1559 0 : nOldWidth + nDeltaX )
1560 0 : + nResizeX - nOldWidth;
1561 :
1562 : // draw new auxiliary line
1563 : pDataWin->ShowTracking( Rectangle( Point( nDragX, 0 ),
1564 0 : Size( 1, pDataWin->GetSizePixel().Height() ) ),
1565 0 : SHOWTRACK_SPLIT|SHOWTRACK_WINDOW );
1566 : }
1567 :
1568 : }
1569 :
1570 0 : nX = nR + 1;
1571 : }
1572 :
1573 0 : SetPointer( aNewPointer );
1574 0 : }
1575 :
1576 : //-------------------------------------------------------------------
1577 :
1578 0 : void BrowseBox::MouseButtonUp( const MouseEvent & rEvt )
1579 : {
1580 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1581 :
1582 0 : if ( bResizing )
1583 : {
1584 : // delete auxiliary line
1585 0 : pDataWin->HideTracking();
1586 :
1587 : // width changed?
1588 0 : nDragX = Max( rEvt.GetPosPixel().X(), nMinResizeX );
1589 0 : if ( (nDragX - nResizeX) != (long)(*pCols)[ nResizeCol ]->Width() )
1590 : {
1591 : // resize column
1592 0 : long nMaxX = pDataWin->GetSizePixel().Width();
1593 0 : nDragX = Min( nDragX, nMaxX );
1594 0 : long nDeltaX = nDragX - nResizeX;
1595 0 : sal_uInt16 nId = GetColumnId(nResizeCol);
1596 0 : SetColumnWidth( GetColumnId(nResizeCol), GetColumnWidth(nId) + nDeltaX );
1597 0 : ColumnResized( nId );
1598 : }
1599 :
1600 : // end action
1601 0 : SetPointer( Pointer() );
1602 0 : ReleaseMouse();
1603 0 : bResizing = sal_False;
1604 : }
1605 : else
1606 : MouseButtonUp( BrowserMouseEvent( (BrowserDataWin*)pDataWin,
1607 0 : MouseEvent( Point( rEvt.GetPosPixel().X(),
1608 0 : rEvt.GetPosPixel().Y() - pDataWin->GetPosPixel().Y() ),
1609 0 : rEvt.GetClicks(), rEvt.GetMode(), rEvt.GetButtons(),
1610 0 : rEvt.GetModifier() ) ) );
1611 0 : }
1612 :
1613 : //-------------------------------------------------------------------
1614 :
1615 : sal_Bool bExtendedMode = sal_False;
1616 : sal_Bool bFieldMode = sal_False;
1617 :
1618 0 : void BrowseBox::MouseButtonDown( const BrowserMouseEvent& rEvt )
1619 : {
1620 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1621 :
1622 0 : GrabFocus();
1623 :
1624 : // adjust selection while and after double-click
1625 0 : if ( rEvt.GetClicks() == 2 )
1626 : {
1627 0 : SetNoSelection();
1628 0 : if ( rEvt.GetRow() >= 0 )
1629 : {
1630 0 : GoToRow( rEvt.GetRow() );
1631 0 : SelectRow( rEvt.GetRow(), sal_True, sal_False );
1632 : }
1633 : else
1634 : {
1635 0 : if ( bColumnCursor && rEvt.GetColumn() != 0 )
1636 : {
1637 0 : if ( rEvt.GetColumn() < pCols->size() )
1638 0 : SelectColumnPos( rEvt.GetColumn(), sal_True, sal_False);
1639 : }
1640 : }
1641 0 : DoubleClick( rEvt );
1642 : }
1643 : // selections
1644 0 : else if ( ( rEvt.GetMode() & ( MOUSE_SELECT | MOUSE_SIMPLECLICK ) ) &&
1645 0 : ( bColumnCursor || rEvt.GetRow() >= 0 ) )
1646 : {
1647 0 : if ( rEvt.GetClicks() == 1 )
1648 : {
1649 : // initialise flags
1650 0 : bHit = sal_False;
1651 : a1stPoint =
1652 0 : a2ndPoint = PixelToLogic( rEvt.GetPosPixel() );
1653 :
1654 : // selection out of range?
1655 0 : if ( rEvt.GetRow() >= nRowCount ||
1656 0 : rEvt.GetColumnId() == BROWSER_INVALIDID )
1657 : {
1658 0 : SetNoSelection();
1659 0 : return;
1660 : }
1661 :
1662 : // while selecting, no cursor
1663 0 : bSelecting = sal_True;
1664 0 : DoHideCursor( "MouseButtonDown" );
1665 :
1666 : // DataRow?
1667 0 : if ( rEvt.GetRow() >= 0 )
1668 : {
1669 : // line selection?
1670 0 : if ( rEvt.GetColumnId() == HandleColumnId || !bColumnCursor )
1671 : {
1672 0 : if ( bMultiSelection )
1673 : {
1674 : // remove column-selection, if exists
1675 0 : if ( pColSel && pColSel->GetSelectCount() )
1676 : {
1677 0 : ToggleSelection();
1678 0 : if ( bMultiSelection )
1679 0 : uRow.pSel->SelectAll(sal_False);
1680 : else
1681 0 : uRow.nSel = BROWSER_ENDOFSELECTION;
1682 0 : if ( pColSel )
1683 0 : pColSel->SelectAll(sal_False);
1684 0 : bSelect = sal_True;
1685 : }
1686 :
1687 : // expanding mode?
1688 0 : if ( rEvt.GetMode() & MOUSE_RANGESELECT )
1689 : {
1690 : // select the further touched rows too
1691 0 : bSelect = sal_True;
1692 0 : ExpandRowSelection( rEvt );
1693 0 : return;
1694 : }
1695 :
1696 : // click in the selected area?
1697 0 : else if ( IsRowSelected( rEvt.GetRow() ) )
1698 : {
1699 : // wait for Drag&Drop
1700 0 : bHit = sal_True;
1701 : bExtendedMode = MOUSE_MULTISELECT ==
1702 0 : ( rEvt.GetMode() & MOUSE_MULTISELECT );
1703 0 : return;
1704 : }
1705 :
1706 : // extension mode?
1707 0 : else if ( rEvt.GetMode() & MOUSE_MULTISELECT )
1708 : {
1709 : // determine the new selection range
1710 : // and selection/deselection
1711 0 : aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
1712 : SelectRow( rEvt.GetRow(),
1713 0 : !uRow.pSel->IsSelected( rEvt.GetRow() ) );
1714 0 : bSelect = sal_True;
1715 0 : return;
1716 : }
1717 : }
1718 :
1719 : // select directly
1720 0 : SetNoSelection();
1721 0 : GoToRow( rEvt.GetRow() );
1722 0 : SelectRow( rEvt.GetRow(), sal_True );
1723 0 : aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
1724 0 : bSelect = sal_True;
1725 : }
1726 : else // Column/Field-Selection
1727 : {
1728 : // click in selected column
1729 0 : if ( IsColumnSelected( rEvt.GetColumn() ) ||
1730 0 : IsRowSelected( rEvt.GetRow() ) )
1731 : {
1732 0 : bHit = sal_True;
1733 0 : bFieldMode = sal_True;
1734 0 : return;
1735 : }
1736 :
1737 0 : SetNoSelection();
1738 0 : GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
1739 0 : bSelect = sal_True;
1740 : }
1741 : }
1742 : else
1743 : {
1744 0 : if ( bMultiSelection && rEvt.GetColumnId() == HandleColumnId )
1745 : {
1746 : // toggle all-selection
1747 0 : if ( uRow.pSel->GetSelectCount() > ( GetRowCount() / 2 ) )
1748 0 : SetNoSelection();
1749 : else
1750 0 : SelectAll();
1751 : }
1752 : else
1753 0 : SelectColumnId( rEvt.GetColumnId(), sal_True, sal_False );
1754 : }
1755 :
1756 : // turn cursor on again, if necessary
1757 0 : bSelecting = sal_False;
1758 0 : DoShowCursor( "MouseButtonDown" );
1759 0 : if ( bSelect )
1760 0 : Select();
1761 : }
1762 : }
1763 : }
1764 :
1765 : //-------------------------------------------------------------------
1766 :
1767 0 : void BrowseBox::MouseMove( const BrowserMouseEvent& )
1768 : {
1769 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1770 0 : }
1771 :
1772 : //-------------------------------------------------------------------
1773 :
1774 0 : void BrowseBox::MouseButtonUp( const BrowserMouseEvent &rEvt )
1775 : {
1776 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1777 :
1778 : // D&D was possible, but did not occur
1779 0 : if ( bHit )
1780 : {
1781 0 : aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
1782 0 : if ( bExtendedMode )
1783 0 : SelectRow( rEvt.GetRow(), sal_False );
1784 : else
1785 : {
1786 0 : SetNoSelection();
1787 0 : if ( bFieldMode )
1788 0 : GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
1789 : else
1790 : {
1791 0 : GoToRow( rEvt.GetRow() );
1792 0 : SelectRow( rEvt.GetRow(), sal_True );
1793 : }
1794 : }
1795 0 : bSelect = sal_True;
1796 0 : bExtendedMode = sal_False;
1797 0 : bFieldMode = sal_False;
1798 0 : bHit = sal_False;
1799 : }
1800 :
1801 : // activate cursor
1802 0 : if ( bSelecting )
1803 : {
1804 0 : bSelecting = sal_False;
1805 0 : DoShowCursor( "MouseButtonUp" );
1806 0 : if ( bSelect )
1807 0 : Select();
1808 : }
1809 0 : }
1810 :
1811 : //-------------------------------------------------------------------
1812 :
1813 0 : void BrowseBox::KeyInput( const KeyEvent& rEvt )
1814 : {
1815 0 : if ( !ProcessKey( rEvt ) )
1816 0 : Control::KeyInput( rEvt );
1817 0 : }
1818 :
1819 : //-------------------------------------------------------------------
1820 :
1821 0 : sal_Bool BrowseBox::ProcessKey( const KeyEvent& rEvt )
1822 : {
1823 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1824 :
1825 0 : sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
1826 0 : sal_Bool bShift = rEvt.GetKeyCode().IsShift();
1827 0 : sal_Bool bCtrl = rEvt.GetKeyCode().IsMod1();
1828 0 : sal_Bool bAlt = rEvt.GetKeyCode().IsMod2();
1829 :
1830 0 : sal_uInt16 nId = BROWSER_NONE;
1831 :
1832 0 : if ( !bAlt && !bCtrl && !bShift )
1833 : {
1834 0 : switch ( nCode )
1835 : {
1836 0 : case KEY_DOWN: nId = BROWSER_CURSORDOWN; break;
1837 0 : case KEY_UP: nId = BROWSER_CURSORUP; break;
1838 0 : case KEY_HOME: nId = BROWSER_CURSORHOME; break;
1839 0 : case KEY_END: nId = BROWSER_CURSOREND; break;
1840 : case KEY_TAB:
1841 0 : if ( !bColumnCursor )
1842 0 : break;
1843 0 : case KEY_RIGHT: nId = BROWSER_CURSORRIGHT; break;
1844 0 : case KEY_LEFT: nId = BROWSER_CURSORLEFT; break;
1845 0 : case KEY_SPACE: nId = BROWSER_SELECT; break;
1846 : }
1847 0 : if ( BROWSER_NONE != nId )
1848 0 : SetNoSelection();
1849 :
1850 0 : switch ( nCode )
1851 : {
1852 0 : case KEY_PAGEDOWN: nId = BROWSER_CURSORPAGEDOWN; break;
1853 0 : case KEY_PAGEUP: nId = BROWSER_CURSORPAGEUP; break;
1854 : }
1855 : }
1856 :
1857 0 : if ( !bAlt && !bCtrl && bShift )
1858 0 : switch ( nCode )
1859 : {
1860 0 : case KEY_DOWN: nId = BROWSER_SELECTDOWN; break;
1861 0 : case KEY_UP: nId = BROWSER_SELECTUP; break;
1862 : case KEY_TAB:
1863 0 : if ( !bColumnCursor )
1864 0 : break;
1865 0 : nId = BROWSER_CURSORLEFT; break;
1866 0 : case KEY_HOME: nId = BROWSER_SELECTHOME; break;
1867 0 : case KEY_END: nId = BROWSER_SELECTEND; break;
1868 : }
1869 :
1870 :
1871 0 : if ( !bAlt && bCtrl && !bShift )
1872 0 : switch ( nCode )
1873 : {
1874 0 : case KEY_DOWN: nId = BROWSER_CURSORDOWN; break;
1875 0 : case KEY_UP: nId = BROWSER_CURSORUP; break;
1876 0 : case KEY_PAGEDOWN: nId = BROWSER_CURSORENDOFFILE; break;
1877 0 : case KEY_PAGEUP: nId = BROWSER_CURSORTOPOFFILE; break;
1878 0 : case KEY_HOME: nId = BROWSER_CURSORTOPOFSCREEN; break;
1879 0 : case KEY_END: nId = BROWSER_CURSORENDOFSCREEN; break;
1880 0 : case KEY_SPACE: nId = BROWSER_ENHANCESELECTION; break;
1881 0 : case KEY_LEFT: nId = BROWSER_MOVECOLUMNLEFT; break;
1882 0 : case KEY_RIGHT: nId = BROWSER_MOVECOLUMNRIGHT; break;
1883 : }
1884 :
1885 0 : if ( nId != BROWSER_NONE )
1886 0 : Dispatch( nId );
1887 0 : return nId != BROWSER_NONE;
1888 : }
1889 :
1890 : //-------------------------------------------------------------------
1891 :
1892 0 : void BrowseBox::Dispatch( sal_uInt16 nId )
1893 : {
1894 : DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1895 :
1896 0 : long nRowsOnPage = pDataWin->GetSizePixel().Height() / GetDataRowHeight();
1897 0 : sal_Bool bDone = sal_False;
1898 :
1899 0 : switch ( nId )
1900 : {
1901 : case BROWSER_SELECTCOLUMN:
1902 0 : if ( ColCount() )
1903 0 : SelectColumnId( GetCurColumnId() );
1904 0 : break;
1905 :
1906 : case BROWSER_CURSORDOWN:
1907 0 : if ( ( GetCurRow() + 1 ) < nRowCount )
1908 0 : bDone = GoToRow( GetCurRow() + 1, sal_False );
1909 0 : break;
1910 : case BROWSER_CURSORUP:
1911 0 : if ( GetCurRow() > 0 )
1912 0 : bDone = GoToRow( GetCurRow() - 1, sal_False );
1913 0 : break;
1914 : case BROWSER_SELECTHOME:
1915 0 : if ( GetRowCount() )
1916 : {
1917 0 : DoHideCursor( "BROWSER_SELECTHOME" );
1918 0 : for ( long nRow = GetCurRow(); nRow >= 0; --nRow )
1919 0 : SelectRow( nRow );
1920 0 : GoToRow( 0, sal_True );
1921 0 : DoShowCursor( "BROWSER_SELECTHOME" );
1922 : }
1923 0 : break;
1924 : case BROWSER_SELECTEND:
1925 0 : if ( GetRowCount() )
1926 : {
1927 0 : DoHideCursor( "BROWSER_SELECTEND" );
1928 0 : long nRows = GetRowCount();
1929 0 : for ( long nRow = GetCurRow(); nRow < nRows; ++nRow )
1930 0 : SelectRow( nRow );
1931 0 : GoToRow( GetRowCount() - 1, sal_True );
1932 0 : DoShowCursor( "BROWSER_SELECTEND" );
1933 : }
1934 0 : break;
1935 : case BROWSER_SELECTDOWN:
1936 : {
1937 0 : if ( GetRowCount() && ( GetCurRow() + 1 ) < nRowCount )
1938 : {
1939 : // deselect the current row, if it isn't the first
1940 : // and there is no other selected row above
1941 0 : long nRow = GetCurRow();
1942 0 : sal_Bool bLocalSelect = ( !IsRowSelected( nRow ) ||
1943 0 : GetSelectRowCount() == 1 || IsRowSelected( nRow - 1 ) );
1944 0 : SelectRow( nRow, bLocalSelect, sal_True );
1945 0 : bDone = GoToRow( GetCurRow() + 1 , sal_False );
1946 0 : if ( bDone )
1947 0 : SelectRow( GetCurRow(), sal_True, sal_True );
1948 : }
1949 : else
1950 0 : bDone = ScrollRows( 1 ) != 0;
1951 0 : break;
1952 : }
1953 : case BROWSER_SELECTUP:
1954 0 : if ( GetRowCount() )
1955 : {
1956 : // deselect the current row, if it isn't the first
1957 : // and there is no other selected row under
1958 0 : long nRow = GetCurRow();
1959 0 : sal_Bool bLocalSelect = ( !IsRowSelected( nRow ) ||
1960 0 : GetSelectRowCount() == 1 || IsRowSelected( nRow + 1 ) );
1961 0 : SelectRow( nCurRow, bLocalSelect, sal_True );
1962 0 : bDone = GoToRow( nRow - 1 , sal_False );
1963 0 : if ( bDone )
1964 0 : SelectRow( GetCurRow(), sal_True, sal_True );
1965 : }
1966 0 : break;
1967 : case BROWSER_CURSORPAGEDOWN:
1968 0 : bDone = (sal_Bool)ScrollRows( nRowsOnPage );
1969 0 : break;
1970 : case BROWSER_CURSORPAGEUP:
1971 0 : bDone = (sal_Bool)ScrollRows( -nRowsOnPage );
1972 0 : break;
1973 : case BROWSER_CURSOREND:
1974 0 : if ( bColumnCursor )
1975 : {
1976 0 : sal_uInt16 nNewId = GetColumnId(ColCount() -1);
1977 0 : bDone = nNewId != HandleColumnId && GoToColumnId( nNewId );
1978 0 : break;
1979 : }
1980 : case BROWSER_CURSORENDOFFILE:
1981 0 : bDone = GoToRow( nRowCount - 1, sal_False );
1982 0 : break;
1983 : case BROWSER_CURSORRIGHT:
1984 0 : if ( bColumnCursor )
1985 : {
1986 0 : sal_uInt16 nNewPos = GetColumnPos( GetCurColumnId() ) + 1;
1987 0 : sal_uInt16 nNewId = GetColumnId( nNewPos );
1988 0 : if (nNewId != BROWSER_INVALIDID) // At end of row ?
1989 0 : bDone = GoToColumnId( nNewId );
1990 : else
1991 : {
1992 0 : sal_uInt16 nColId = GetColumnId(0);
1993 0 : if ( nColId == BROWSER_INVALIDID || nColId == HandleColumnId )
1994 0 : nColId = GetColumnId(1);
1995 0 : if ( GetRowCount() )
1996 0 : bDone = ( nCurRow < GetRowCount() - 1 ) && GoToRowColumnId( nCurRow + 1, nColId );
1997 0 : else if ( ColCount() )
1998 0 : GoToColumnId( nColId );
1999 : }
2000 : }
2001 : else
2002 0 : bDone = ScrollColumns( 1 ) != 0;
2003 0 : break;
2004 : case BROWSER_CURSORHOME:
2005 0 : if ( bColumnCursor )
2006 : {
2007 0 : sal_uInt16 nNewId = GetColumnId(1);
2008 0 : bDone = (nNewId != HandleColumnId) && GoToColumnId( nNewId );
2009 0 : break;
2010 : }
2011 : case BROWSER_CURSORTOPOFFILE:
2012 0 : bDone = GoToRow( 0, sal_False );
2013 0 : break;
2014 : case BROWSER_CURSORLEFT:
2015 0 : if ( bColumnCursor )
2016 : {
2017 0 : sal_uInt16 nNewPos = GetColumnPos( GetCurColumnId() ) - 1;
2018 0 : sal_uInt16 nNewId = GetColumnId( nNewPos );
2019 0 : if (nNewId != HandleColumnId)
2020 0 : bDone = GoToColumnId( nNewId );
2021 : else
2022 : {
2023 0 : if ( GetRowCount() )
2024 0 : bDone = (nCurRow > 0) && GoToRowColumnId(nCurRow - 1, GetColumnId(ColCount() -1));
2025 0 : else if ( ColCount() )
2026 0 : GoToColumnId( GetColumnId(ColCount() -1) );
2027 : }
2028 : }
2029 : else
2030 0 : bDone = ScrollColumns( -1 ) != 0;
2031 0 : break;
2032 : case BROWSER_ENHANCESELECTION:
2033 0 : if ( GetRowCount() )
2034 0 : SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), sal_True );
2035 0 : bDone = sal_True;
2036 0 : break;
2037 : case BROWSER_SELECT:
2038 0 : if ( GetRowCount() )
2039 0 : SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), sal_False );
2040 0 : bDone = sal_True;
2041 0 : break;
2042 : case BROWSER_MOVECOLUMNLEFT:
2043 : case BROWSER_MOVECOLUMNRIGHT:
2044 : { // check if column moving is allowed
2045 0 : BrowserHeader* pHeaderBar = getDataWindow()->pHeaderBar;
2046 0 : if ( pHeaderBar && pHeaderBar->IsDragable() )
2047 : {
2048 0 : sal_uInt16 nColId = GetCurColumnId();
2049 0 : sal_Bool bColumnSelected = IsColumnSelected(nColId);
2050 0 : sal_uInt16 nNewPos = GetColumnPos(nColId);
2051 0 : sal_Bool bMoveAllowed = sal_False;
2052 0 : if ( BROWSER_MOVECOLUMNLEFT == nId && nNewPos > 1 )
2053 0 : --nNewPos,bMoveAllowed = sal_True;
2054 0 : else if ( BROWSER_MOVECOLUMNRIGHT == nId && nNewPos < (ColCount()-1) )
2055 0 : ++nNewPos,bMoveAllowed = sal_True;
2056 :
2057 0 : if ( bMoveAllowed )
2058 : {
2059 0 : SetColumnPos( nColId, nNewPos );
2060 0 : ColumnMoved( nColId );
2061 0 : MakeFieldVisible(GetCurRow(),nColId,sal_True);
2062 0 : if ( bColumnSelected )
2063 0 : SelectColumnId(nColId);
2064 : }
2065 : }
2066 : }
2067 0 : break;
2068 : }
2069 :
2070 : //! return bDone;
2071 0 : }
2072 :
2073 : //-------------------------------------------------------------------
2074 :
2075 0 : void BrowseBox::SetCursorColor(const Color& _rCol)
2076 : {
2077 0 : if (_rCol == m_aCursorColor)
2078 0 : return;
2079 :
2080 : // ensure the cursor is hidden
2081 0 : DoHideCursor("SetCursorColor");
2082 0 : if (!m_bFocusOnlyCursor)
2083 0 : DoHideCursor("SetCursorColor - force");
2084 :
2085 0 : m_aCursorColor = _rCol;
2086 :
2087 0 : if (!m_bFocusOnlyCursor)
2088 0 : DoShowCursor("SetCursorColor - force");
2089 0 : DoShowCursor("SetCursorColor");
2090 : }
2091 : // -----------------------------------------------------------------------------
2092 0 : Rectangle BrowseBox::calcHeaderRect(sal_Bool _bIsColumnBar,sal_Bool _bOnScreen)
2093 : {
2094 0 : Window* pParent = NULL;
2095 0 : if ( !_bOnScreen )
2096 0 : pParent = GetAccessibleParentWindow();
2097 :
2098 0 : Point aTopLeft;
2099 : long nWidth;
2100 : long nHeight;
2101 0 : if ( _bIsColumnBar )
2102 : {
2103 0 : nWidth = GetDataWindow().GetOutputSizePixel().Width();
2104 0 : nHeight = GetDataRowHeight();
2105 : }
2106 : else
2107 : {
2108 0 : aTopLeft.Y() = GetDataRowHeight();
2109 0 : nWidth = GetColumnWidth(0);
2110 0 : nHeight = GetWindowExtentsRelative( pParent ).GetHeight() - aTopLeft.Y() - GetControlArea().GetSize().B();
2111 : }
2112 0 : aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
2113 0 : return Rectangle(aTopLeft,Size(nWidth,nHeight));
2114 : }
2115 : // -----------------------------------------------------------------------------
2116 0 : Rectangle BrowseBox::calcTableRect(sal_Bool _bOnScreen)
2117 : {
2118 0 : Window* pParent = NULL;
2119 0 : if ( !_bOnScreen )
2120 0 : pParent = GetAccessibleParentWindow();
2121 :
2122 0 : Rectangle aRect( GetWindowExtentsRelative( pParent ) );
2123 0 : Rectangle aRowBar = calcHeaderRect(sal_False,pParent == NULL);
2124 :
2125 0 : long nX = aRowBar.Right() - aRect.Left();
2126 0 : long nY = aRowBar.Top() - aRect.Top();
2127 0 : Size aSize(aRect.GetSize());
2128 :
2129 0 : return Rectangle(aRowBar.TopRight(), Size(aSize.A() - nX, aSize.B() - nY - aHScroll.GetSizePixel().Height()) );
2130 : }
2131 : // -----------------------------------------------------------------------------
2132 0 : Rectangle BrowseBox::GetFieldRectPixelAbs( sal_Int32 _nRowId,sal_uInt16 _nColId, sal_Bool /*_bIsHeader*/, sal_Bool _bOnScreen )
2133 : {
2134 0 : Window* pParent = NULL;
2135 0 : if ( !_bOnScreen )
2136 0 : pParent = GetAccessibleParentWindow();
2137 :
2138 0 : Rectangle aRect = GetFieldRectPixel(_nRowId,_nColId,_bOnScreen);
2139 :
2140 0 : Point aTopLeft = aRect.TopLeft();
2141 0 : aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
2142 :
2143 0 : return Rectangle(aTopLeft,aRect.GetSize());
2144 : }
2145 :
2146 : // ------------------------------------------------------------------------- EOF
2147 :
2148 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|