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