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