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