xref: /AOO41X/main/svtools/source/brwbox/brwbox2.cxx (revision 5900e8ec128faec89519683efce668ccd8cc6084)
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 neccessary 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 occured 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