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 <svtools/brwbox.hxx>
27 #include <svtools/brwhead.hxx>
28 #include "datwin.hxx"
29 #include <tools/debug.hxx>
30 #include <tools/stream.hxx>
31
32 #include <functional>
33 #include <algorithm>
34 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
35 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
36 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
37 #include <com/sun/star/accessibility/XAccessible.hpp>
38 #include <tools/multisel.hxx>
39 #include "brwimpl.hxx"
40
41 DBG_NAME(BrowseBox)
42
43 extern const char* BrowseBoxCheckInvariants( const void* pVoid );
44
45 DECLARE_LIST( BrowserColumns, BrowserColumn* )
46
47 #define SCROLL_FLAGS (SCROLL_CLIP | SCROLL_NOCHILDREN)
48 #define getDataWindow() ((BrowserDataWin*)pDataWin)
49
50 using namespace com::sun::star::accessibility::AccessibleEventId;
51 using namespace com::sun::star::accessibility::AccessibleTableModelChangeType;
52 using com::sun::star::accessibility::AccessibleTableModelChange;
53 using com::sun::star::lang::XComponent;
54 using namespace ::com::sun::star::uno;
55 using namespace svt;
56
57 //-------------------------------------------------------------------
58
59 #ifdef DBG_MI
DoLog_Impl(const BrowseBox * pThis,const char * pWhat,const char * pWho)60 void DoLog_Impl( const BrowseBox *pThis, const char *pWhat, const char *pWho )
61 {
62 SvFileStream aLog( "d:\\cursor.log", STREAM_WRITE|STREAM_NOCREATE );
63 if ( aLog.IsOpen() )
64 {
65 aLog.Seek( STREAM_SEEK_TO_END );
66 String aEntry( (long) pThis );
67 aEntry += "(row=";
68 aEntry += pThis->GetCurRow();
69 aEntry += "): ";
70 aEntry += pWhat;
71 aEntry += " from ";
72 aEntry += pWho;
73 aEntry += " => ";
74 aEntry += pThis->GetCursorHideCount();
75 aLog.WriteLine( aEntry );
76 }
77 }
78 #endif
79
80 namespace
81 {
disposeAndClearHeaderCell(::svt::BrowseBoxImpl::THeaderCellMap & _rHeaderCell)82 void disposeAndClearHeaderCell(::svt::BrowseBoxImpl::THeaderCellMap& _rHeaderCell)
83 {
84 ::std::for_each(
85 _rHeaderCell.begin(),
86 _rHeaderCell.end(),
87 ::svt::BrowseBoxImpl::THeaderCellMapFunctorDispose()
88 );
89 _rHeaderCell.clear();
90 }
91 }
92
93 //===================================================================
94
ConstructImpl(BrowserMode nMode)95 void BrowseBox::ConstructImpl( BrowserMode nMode )
96 {
97 DBG_TRACE1( "BrowseBox: %p->ConstructImpl", this );
98 bMultiSelection = sal_False;
99 pColSel = 0;
100 pDataWin = 0;
101 pVScroll = 0;
102
103 pDataWin = new BrowserDataWin( this );
104 pCols = new BrowserColumns;
105 m_pImpl.reset( new ::svt::BrowseBoxImpl() );
106
107 aGridLineColor = Color( COL_LIGHTGRAY );
108 InitSettings_Impl( this );
109 InitSettings_Impl( pDataWin );
110
111 bBootstrapped = sal_False;
112 nDataRowHeight = 0;
113 nTitleLines = 1;
114 nFirstCol = 0;
115 nTopRow = 0;
116 nCurRow = BROWSER_ENDOFSELECTION;
117 nCurColId = 0;
118 bResizing = sal_False;
119 bSelect = sal_False;
120 bSelecting = sal_False;
121 bScrolling = sal_False;
122 bSelectionIsVisible = sal_False;
123 bNotToggleSel = sal_False;
124 bRowDividerDrag = sal_False;
125 bHit = sal_False;
126 mbInteractiveRowHeight = sal_False;
127 bHideSelect = sal_False;
128 bHideCursor = NO_CURSOR_HIDE;
129 nRowCount = 0;
130 m_bFocusOnlyCursor = sal_True;
131 m_aCursorColor = COL_TRANSPARENT;
132 m_nCurrentMode = 0;
133 nControlAreaWidth = USHRT_MAX;
134 uRow.nSel = BROWSER_ENDOFSELECTION;
135
136 aHScroll.SetLineSize(1);
137 aHScroll.SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
138 aHScroll.SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
139 pDataWin->Show();
140
141 SetMode( nMode );
142 bSelectionIsVisible = bKeepHighlight;
143 bHasFocus = HasChildPathFocus();
144 getDataWindow()->nCursorHidden =
145 ( bHasFocus ? 0 : 1 ) + ( GetUpdateMode() ? 0 : 1 );
146 LOG( this, "ConstructImpl", "*" );
147 }
148
149 //-------------------------------------------------------------------
150
BrowseBox(Window * pParent,WinBits nBits,BrowserMode nMode)151 BrowseBox::BrowseBox( Window* pParent, WinBits nBits, BrowserMode nMode )
152 :Control( pParent, nBits | WB_3DLOOK )
153 ,DragSourceHelper( this )
154 ,DropTargetHelper( this )
155 ,aHScroll( this, WinBits( WB_HSCROLL ) )
156 {
157 DBG_CTOR( BrowseBox, NULL );
158 ConstructImpl( nMode );
159 }
160
161 //-------------------------------------------------------------------
162
BrowseBox(Window * pParent,const ResId & rId,BrowserMode nMode)163 BrowseBox::BrowseBox( Window* pParent, const ResId& rId, BrowserMode nMode )
164 :Control( pParent, rId )
165 ,DragSourceHelper( this )
166 ,DropTargetHelper( this )
167 ,aHScroll( this, WinBits(WB_HSCROLL) )
168 {
169 DBG_CTOR( BrowseBox, NULL );
170 ConstructImpl(nMode);
171 }
172 //-------------------------------------------------------------------
173
~BrowseBox()174 BrowseBox::~BrowseBox()
175 {
176 DBG_DTOR(BrowseBox,BrowseBoxCheckInvariants);
177 DBG_TRACE1( "BrowseBox: %p~", this );
178
179 if ( m_pImpl->m_pAccessible )
180 {
181 disposeAndClearHeaderCell(m_pImpl->m_aColHeaderCellMap);
182 disposeAndClearHeaderCell(m_pImpl->m_aRowHeaderCellMap);
183 m_pImpl->m_pAccessible->dispose();
184 }
185
186 Hide();
187 delete getDataWindow()->pHeaderBar;
188 delete getDataWindow()->pCornerWin;
189 delete pDataWin;
190 delete pVScroll;
191
192 // free columns-space
193 for ( sal_uInt16 n = 0; n < pCols->Count(); ++n )
194 delete pCols->GetObject(n);
195 delete pCols;
196 delete pColSel;
197 if ( bMultiSelection )
198 delete uRow.pSel;
199 }
200
201 //-------------------------------------------------------------------
202
GetCursorHideCount() const203 short BrowseBox::GetCursorHideCount() const
204 {
205 return getDataWindow()->nCursorHidden;
206 }
207
208 //-------------------------------------------------------------------
209
DoShowCursor(const char * pWhoLogs)210 void BrowseBox::DoShowCursor( const char *
211 #ifdef DBG_MI
212 pWhoLogs
213 #endif
214 )
215 {
216 short nHiddenCount = --getDataWindow()->nCursorHidden;
217 if (PaintCursorIfHiddenOnce())
218 {
219 if (1 == nHiddenCount)
220 DrawCursor();
221 }
222 else
223 {
224 if (0 == nHiddenCount)
225 DrawCursor();
226 }
227 LOG( this, "DoShowCursor", pWhoLogs );
228 }
229
230 //-------------------------------------------------------------------
231
DoHideCursor(const char * pWhoLogs)232 void BrowseBox::DoHideCursor( const char *
233 #ifdef DBG_MI
234 pWhoLogs
235 #endif
236 )
237 {
238 short nHiddenCount = ++getDataWindow()->nCursorHidden;
239 if (PaintCursorIfHiddenOnce())
240 {
241 if (2 == nHiddenCount)
242 DrawCursor();
243 }
244 else
245 {
246 if (1 == nHiddenCount)
247 DrawCursor();
248 }
249 LOG( this, "DoHideCursor", pWhoLogs );
250 }
251
252 //-------------------------------------------------------------------
253
SetRealRowCount(const String & rRealRowCount)254 void BrowseBox::SetRealRowCount( const String &rRealRowCount )
255 {
256 getDataWindow()->aRealRowCount = rRealRowCount;
257 }
258
259 //-------------------------------------------------------------------
260
SetFont(const Font & rNewFont)261 void BrowseBox::SetFont( const Font& rNewFont )
262 {
263 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
264 pDataWin->SetFont( rNewFont );
265 ImpGetDataRowHeight();
266 }
267
268 //-------------------------------------------------------------------
269
GetDefaultColumnWidth(const String & _rText) const270 sal_uLong BrowseBox::GetDefaultColumnWidth( const String& _rText ) const
271 {
272 return GetDataWindow().GetTextWidth( _rText ) + GetDataWindow().GetTextWidth( '0' ) * 4;
273 }
274
275 //-------------------------------------------------------------------
276
InsertHandleColumn(sal_uLong nWidth)277 void BrowseBox::InsertHandleColumn( sal_uLong nWidth )
278 {
279 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
280
281 pCols->Insert( new BrowserColumn( 0, Image(), String(), nWidth, GetZoom(), 0 ), (sal_uLong) 0 );
282 FreezeColumn( 0 );
283
284 // Headerbar anpassen
285 if ( getDataWindow()->pHeaderBar )
286 {
287 getDataWindow()->pHeaderBar->SetPosSizePixel(
288 Point(nWidth, 0),
289 Size( GetOutputSizePixel().Width() - nWidth, GetTitleHeight() )
290 );
291 }
292
293 /*if ( getDataWindow()->pHeaderBar )
294 getDataWindow()->pHeaderBar->InsertItem( USHRT_MAX - 1,
295 "", nWidth, HIB_FIXEDPOS|HIB_FIXED, 0 );*/
296 ColumnInserted( 0 );
297 }
298
299 //-------------------------------------------------------------------
InsertDataColumn(sal_uInt16 nItemId,const Image & rImage,long nWidth,HeaderBarItemBits nBits,sal_uInt16 nPos)300 void BrowseBox::InsertDataColumn( sal_uInt16 nItemId, const Image& rImage,
301 long nWidth, HeaderBarItemBits nBits, sal_uInt16 nPos )
302 {
303 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
304
305 pCols->Insert( new BrowserColumn( nItemId, rImage, String(), nWidth, GetZoom(), nBits ),
306 Min( nPos, (sal_uInt16)(pCols->Count()) ) );
307 if ( nCurColId == 0 )
308 nCurColId = nItemId;
309 if ( getDataWindow()->pHeaderBar )
310 {
311 // Handlecolumn nicht in der Headerbar
312 sal_uInt16 nHeaderPos = nPos;
313 if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
314 nHeaderPos--;
315 getDataWindow()->pHeaderBar->InsertItem(
316 nItemId, rImage, nWidth, nBits, nHeaderPos );
317 }
318 ColumnInserted( nPos );
319 }
320
321 //-------------------------------------------------------------------
322
InsertDataColumn(sal_uInt16 nItemId,const XubString & rText,long nWidth,HeaderBarItemBits nBits,sal_uInt16 nPos)323 void BrowseBox::InsertDataColumn( sal_uInt16 nItemId, const XubString& rText,
324 long nWidth, HeaderBarItemBits nBits, sal_uInt16 nPos )
325 {
326 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
327
328 pCols->Insert( new BrowserColumn( nItemId, Image(), rText, nWidth, GetZoom(), nBits ),
329 Min( nPos, (sal_uInt16)(pCols->Count()) ) );
330 if ( nCurColId == 0 )
331 nCurColId = nItemId;
332
333 if ( getDataWindow()->pHeaderBar )
334 {
335 // Handlecolumn nicht in der Headerbar
336 sal_uInt16 nHeaderPos = nPos;
337 if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
338 nHeaderPos--;
339 getDataWindow()->pHeaderBar->InsertItem(
340 nItemId, rText, nWidth, nBits, nHeaderPos );
341 }
342 ColumnInserted( nPos );
343 }
344
345 //-------------------------------------------------------------------
346
InsertDataColumn(sal_uInt16 nItemId,const Image & rImage,const XubString & rText,long nWidth,HeaderBarItemBits nBits,sal_uInt16 nPos,const String * pHelpText)347 void BrowseBox::InsertDataColumn( sal_uInt16 nItemId,
348 const Image& rImage, const XubString& rText,
349 long nWidth, HeaderBarItemBits nBits, sal_uInt16 nPos,
350 const String* pHelpText )
351 {
352 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
353
354 pCols->Insert( new BrowserColumn( nItemId, rImage, rText, nWidth, GetZoom(), nBits ),
355 Min( nPos, (sal_uInt16)(pCols->Count()) ) );
356 if ( nCurColId == 0 )
357 nCurColId = nItemId;
358 if ( getDataWindow()->pHeaderBar )
359 {
360 // Handlecolumn nicht in der Headerbar
361 sal_uInt16 nHeaderPos = nPos;
362 if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
363 nHeaderPos--;
364
365 getDataWindow()->pHeaderBar->InsertItem(
366 nItemId, rImage, rText, nWidth, nBits, nHeaderPos );
367 if( pHelpText && !rText.Len() )
368 {
369 getDataWindow()->pHeaderBar->SetHelpText(
370 nItemId, *pHelpText );
371 }
372 }
373 ColumnInserted( nPos );
374 }
375 //-------------------------------------------------------------------
ToggleSelectedColumn()376 sal_uInt16 BrowseBox::ToggleSelectedColumn()
377 {
378 sal_uInt16 nSelectedColId = USHRT_MAX;
379 if ( pColSel && pColSel->GetSelectCount() )
380 {
381 DoHideCursor( "ToggleSelectedColumn" );
382 ToggleSelection();
383 nSelectedColId = pCols->GetObject(pColSel->FirstSelected())->GetId();
384 pColSel->SelectAll(sal_False);
385 }
386 return nSelectedColId;
387 }
388 // -----------------------------------------------------------------------------
SetToggledSelectedColumn(sal_uInt16 _nSelectedColumnId)389 void BrowseBox::SetToggledSelectedColumn(sal_uInt16 _nSelectedColumnId)
390 {
391 if ( pColSel && _nSelectedColumnId != USHRT_MAX )
392 {
393 pColSel->Select( GetColumnPos( _nSelectedColumnId ) );
394 ToggleSelection();
395 DBG_TRACE1( "BrowseBox: %p->SetToggledSelectedColumn", this );
396 DoShowCursor( "SetToggledSelectedColumn" );
397 }
398 }
399 // -----------------------------------------------------------------------------
FreezeColumn(sal_uInt16 nItemId,sal_Bool bFreeze)400 void BrowseBox::FreezeColumn( sal_uInt16 nItemId, sal_Bool bFreeze )
401 {
402 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
403
404 // never unfreeze the handle-column
405 if ( nItemId == 0 && !bFreeze )
406 return;
407
408 // get the position in the current array
409 sal_uInt16 nItemPos = GetColumnPos( nItemId );
410 if ( nItemPos >= pCols->Count() )
411 // not available!
412 return;
413
414 // doesn't the state change?
415 if ( pCols->GetObject(nItemPos)->IsFrozen() == bFreeze )
416 return;
417
418 // remark the column selection
419 sal_uInt16 nSelectedColId = ToggleSelectedColumn();
420
421 // freeze or unfreeze?
422 if ( bFreeze )
423 {
424 // to be moved?
425 if ( nItemPos != 0 && !pCols->GetObject(nItemPos-1)->IsFrozen() )
426 {
427 // move to the right of the last frozen column
428 sal_uInt16 nFirstScrollable = FrozenColCount();
429 BrowserColumn *pColumn = pCols->GetObject(nItemPos);
430 pCols->Remove( (sal_uLong) nItemPos );
431 nItemPos = nFirstScrollable;
432 pCols->Insert( pColumn, (sal_uLong) nItemPos );
433 }
434
435 // adjust the number of the first scrollable and visible column
436 if ( nFirstCol <= nItemPos )
437 nFirstCol = nItemPos + 1;
438 }
439 else
440 {
441 // to be moved?
442 if ( nItemPos != FrozenColCount()-1 )
443 {
444 // move to the leftmost scrollable column
445 sal_uInt16 nFirstScrollable = FrozenColCount();
446 BrowserColumn *pColumn = pCols->GetObject(nItemPos);
447 pCols->Remove( (sal_uLong) nItemPos );
448 nItemPos = nFirstScrollable;
449 pCols->Insert( pColumn, (sal_uLong) nItemPos );
450 }
451
452 // adjust the number of the first scrollable and visible column
453 nFirstCol = nItemPos;
454 }
455
456 // toggle the freeze-state of the column
457 pCols->GetObject(nItemPos)->Freeze( bFreeze );
458
459 // align the scrollbar-range
460 UpdateScrollbars();
461
462 // repaint
463 Control::Invalidate();
464 getDataWindow()->Invalidate();
465
466 // remember the column selection
467 SetToggledSelectedColumn(nSelectedColId);
468 }
469
470 //-------------------------------------------------------------------
471
SetColumnPos(sal_uInt16 nColumnId,sal_uInt16 nPos)472 void BrowseBox::SetColumnPos( sal_uInt16 nColumnId, sal_uInt16 nPos )
473 {
474 // never set pos of the handle-column
475 if ( nColumnId == 0 )
476 return;
477
478 // do not move handle column
479 if (nPos == 0 && !pCols->GetObject(0)->GetId())
480 return;
481
482 // get the position in the current array
483 sal_uInt16 nOldPos = GetColumnPos( nColumnId );
484 if ( nOldPos >= pCols->Count() )
485 // not available!
486 return;
487
488 // does the state change?
489 if (nOldPos != nPos)
490 {
491 // remark the column selection
492 sal_uInt16 nSelectedColId = ToggleSelectedColumn();
493
494 // determine old column area
495 Size aDataWinSize( pDataWin->GetSizePixel() );
496 if ( getDataWindow()->pHeaderBar )
497 aDataWinSize.Height() += getDataWindow()->pHeaderBar->GetSizePixel().Height();
498
499 Rectangle aFromRect( GetFieldRect( nColumnId) );
500 aFromRect.Right() += 2*MIN_COLUMNWIDTH;
501
502 sal_uInt16 nNextPos = nOldPos + 1;
503 if ( nOldPos > nPos )
504 nNextPos = nOldPos - 1;
505
506 BrowserColumn *pNextCol = pCols->GetObject(nNextPos);
507 Rectangle aNextRect(GetFieldRect( pNextCol->GetId() ));
508
509 // move column internally
510 pCols->Insert( pCols->Remove( nOldPos ), nPos );
511
512 // determine new column area
513 Rectangle aToRect( GetFieldRect( nColumnId ) );
514 aToRect.Right() += 2*MIN_COLUMNWIDTH;
515
516 // do scroll, let redraw
517 if( pDataWin->GetBackground().IsScrollable() )
518 {
519 long nScroll = -aFromRect.GetWidth();
520 Rectangle aScrollArea;
521 if ( nOldPos > nPos )
522 {
523 long nFrozenWidth = GetFrozenWidth();
524 if ( aToRect.Left() < nFrozenWidth )
525 aToRect.Left() = nFrozenWidth;
526 aScrollArea = Rectangle(Point(aToRect.Left(),0),
527 Point(aNextRect.Right(),aDataWinSize.Height()));
528 nScroll *= -1; // reverse direction
529 }
530 else
531 aScrollArea = Rectangle(Point(aNextRect.Left(),0),
532 Point(aToRect.Right(),aDataWinSize.Height()));
533
534 pDataWin->Scroll( nScroll, 0, aScrollArea );
535 aToRect.Top() = 0;
536 aToRect.Bottom() = aScrollArea.Bottom();
537 Invalidate( aToRect );
538 }
539 else
540 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
541
542 // adjust header bar positions
543 if ( getDataWindow()->pHeaderBar )
544 {
545 sal_uInt16 nNewPos = nPos;
546 if ( !GetColumnId(0) )
547 --nNewPos;
548 getDataWindow()->pHeaderBar->MoveItem(nColumnId,nNewPos);
549 }
550 // remember the column selection
551 SetToggledSelectedColumn(nSelectedColId);
552
553 if ( isAccessibleAlive() )
554 {
555 commitTableEvent(
556 TABLE_MODEL_CHANGED,
557 makeAny( AccessibleTableModelChange(
558 DELETE,
559 0,
560 GetRowCount(),
561 nOldPos,
562 nOldPos
563 )
564 ),
565 Any()
566 );
567
568 commitTableEvent(
569 TABLE_MODEL_CHANGED,
570 makeAny( AccessibleTableModelChange(
571 INSERT,
572 0,
573 GetRowCount(),
574 nPos,
575 nPos
576 )
577 ),
578 Any()
579 );
580 }
581 }
582
583 }
584
585 //-------------------------------------------------------------------
586
SetColumnMode(sal_uInt16 nColumnId,BrowserColumnMode nFlags)587 void BrowseBox::SetColumnMode( sal_uInt16 nColumnId, BrowserColumnMode nFlags )
588 {
589 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
590
591 // never set mode of the handle-column
592 if ( nColumnId == 0 )
593 return;
594
595 // get the position in the current array
596 sal_uInt16 nColumnPos = GetColumnPos( nColumnId );
597 if ( nColumnPos >= pCols->Count() )
598 // not available!
599 return;
600
601 // does the state change?
602 BrowserColumn *pCol = pCols->GetObject(nColumnPos);
603 if ( pCol->Flags() != nFlags )
604 {
605 pCol->Flags() = sal::static_int_cast< HeaderBarItemBits >(nFlags);
606
607 // redraw visible colums
608 if ( GetUpdateMode() && ( pCol->IsFrozen() || nColumnPos > nFirstCol ) )
609 Invalidate( Rectangle( Point(0,0),
610 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
611 }
612 }
613
614 //-------------------------------------------------------------------
615
SetColumnTitle(sal_uInt16 nItemId,const String & rTitle)616 void BrowseBox::SetColumnTitle( sal_uInt16 nItemId, const String& rTitle )
617 {
618 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
619
620 // never set title of the handle-column
621 if ( nItemId == 0 )
622 return;
623
624 // get the position in the current array
625 sal_uInt16 nItemPos = GetColumnPos( nItemId );
626 if ( nItemPos >= pCols->Count() )
627 // not available!
628 return;
629
630 // does the state change?
631 BrowserColumn *pCol = pCols->GetObject(nItemPos);
632 if ( pCol->Title() != rTitle )
633 {
634 ::rtl::OUString sNew(rTitle);
635 ::rtl::OUString sOld(pCol->Title());
636
637 pCol->Title() = rTitle;
638
639 // Headerbar-Column anpassen
640 if ( getDataWindow()->pHeaderBar )
641 getDataWindow()->pHeaderBar->SetItemText(
642 nItemId ? nItemId : USHRT_MAX - 1, rTitle );
643 else
644 {
645 // redraw visible colums
646 if ( GetUpdateMode() && ( pCol->IsFrozen() || nItemPos > nFirstCol ) )
647 Invalidate( Rectangle( Point(0,0),
648 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
649 }
650
651 if ( isAccessibleAlive() )
652 {
653 commitTableEvent( TABLE_COLUMN_DESCRIPTION_CHANGED,
654 makeAny( sNew ),
655 makeAny( sOld )
656 );
657 }
658 }
659 }
660
661 //-------------------------------------------------------------------
662
SetColumnWidth(sal_uInt16 nItemId,sal_uLong nWidth)663 void BrowseBox::SetColumnWidth( sal_uInt16 nItemId, sal_uLong nWidth )
664 {
665 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
666
667 // get the position in the current array
668 sal_uInt16 nItemPos = GetColumnPos( nItemId );
669 if ( nItemPos >= pCols->Count() )
670 return;
671
672 // does the state change?
673 nWidth = QueryColumnResize( nItemId, nWidth );
674 if ( nWidth >= LONG_MAX || pCols->GetObject(nItemPos)->Width() != nWidth )
675 {
676 long nOldWidth = pCols->GetObject(nItemPos)->Width();
677
678 // ggf. letzte Spalte anpassen
679 if ( IsVisible() && nItemPos == pCols->Count() - 1 )
680 {
681 long nMaxWidth = pDataWin->GetSizePixel().Width();
682 nMaxWidth -= getDataWindow()->bAutoSizeLastCol
683 ? GetFieldRect(nItemId).Left()
684 : GetFrozenWidth();
685 if ( ( (BrowserDataWin*)pDataWin )->bAutoSizeLastCol || nWidth > (sal_uLong)nMaxWidth )
686 {
687 nWidth = nMaxWidth > 16 ? nMaxWidth : nOldWidth;
688 nWidth = QueryColumnResize( nItemId, nWidth );
689 }
690 }
691
692 // OV
693 // In AutoSizeLastColumn() wird SetColumnWidth mit nWidth==0xffff
694 // gerufen. Deshalb muss hier nochmal geprueft werden, ob sich die
695 // Breite tatsaechlich geaendert hat.
696 if( (sal_uLong)nOldWidth == nWidth )
697 return;
698
699 // soll die Aenderung sofort dargestellt werden?
700 sal_Bool bUpdate = GetUpdateMode() &&
701 ( pCols->GetObject(nItemPos)->IsFrozen() || nItemPos >= nFirstCol );
702
703 if ( bUpdate )
704 {
705 // Selection hiden
706 DoHideCursor( "SetColumnWidth" );
707 ToggleSelection();
708 //!getDataWindow()->Update();
709 //!Control::Update();
710 }
711
712 // Breite setzen
713 pCols->GetObject(nItemPos)->SetWidth(nWidth, GetZoom());
714 #if 0
715 if ( nItemPos != pCols->Count() - 1 )
716 {
717 long nLastColMaxWidth = pDataWin->GetSizePixel().Width() -
718 GetFieldRect(GetColumnId(pCols->Count()-1)).Left();
719 pCols->GetObject(pCols->Count()-1)->Width() = nLastColMaxWidth;
720 }
721 #endif
722
723 // scroll and invalidate
724 if ( bUpdate )
725 {
726 // X-Pos der veraenderten Spalte ermitteln
727 long nX = 0;
728 for ( sal_uInt16 nCol = 0; nCol < nItemPos; ++nCol )
729 {
730 BrowserColumn *pCol = pCols->GetObject(nCol);
731 if ( pCol->IsFrozen() || nCol >= nFirstCol )
732 nX += pCol->Width();
733 }
734
735 // eigentliches scroll+invalidate
736 pDataWin->SetClipRegion();
737 sal_Bool bSelVis = bSelectionIsVisible;
738 bSelectionIsVisible = sal_False;
739 if( GetBackground().IsScrollable() )
740 {
741
742 Rectangle aScrRect( nX + std::min( (sal_uLong)nOldWidth, nWidth ), 0,
743 GetSizePixel().Width() , // the header is longer than the datawin
744 pDataWin->GetPosPixel().Y() - 1 );
745 Control::Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
746 aScrRect.Bottom() = pDataWin->GetSizePixel().Height();
747 getDataWindow()->Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
748 Rectangle aInvRect( nX, 0, nX + std::max( nWidth, (sal_uLong)nOldWidth ), USHRT_MAX );
749 Control::Invalidate( aInvRect, INVALIDATE_NOCHILDREN );
750 ( (BrowserDataWin*)pDataWin )->Invalidate( aInvRect );
751 }
752 else
753 {
754 Control::Invalidate( INVALIDATE_NOCHILDREN );
755 getDataWindow()->Window::Invalidate( INVALIDATE_NOCHILDREN );
756 }
757
758
759 //!getDataWindow()->Update();
760 //!Control::Update();
761 bSelectionIsVisible = bSelVis;
762 ToggleSelection();
763 DoShowCursor( "SetColumnWidth" );
764 }
765 UpdateScrollbars();
766
767 // Headerbar-Column anpassen
768 if ( getDataWindow()->pHeaderBar )
769 getDataWindow()->pHeaderBar->SetItemSize(
770 nItemId ? nItemId : USHRT_MAX - 1, nWidth );
771
772 // adjust last column
773 if ( nItemPos != pCols->Count() - 1 )
774 AutoSizeLastColumn();
775
776 }
777 }
778
779 //-------------------------------------------------------------------
780
AutoSizeLastColumn()781 void BrowseBox::AutoSizeLastColumn()
782 {
783 if ( getDataWindow()->bAutoSizeLastCol &&
784 getDataWindow()->GetUpdateMode() )
785 {
786 sal_uInt16 nId = GetColumnId( (sal_uInt16)pCols->Count() - 1 );
787 SetColumnWidth( nId, LONG_MAX );
788 ColumnResized( nId );
789 }
790 }
791
792 //-------------------------------------------------------------------
793
RemoveColumn(sal_uInt16 nItemId)794 void BrowseBox::RemoveColumn( sal_uInt16 nItemId )
795 {
796 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
797
798 // Spaltenposition ermitteln
799 sal_uInt16 nPos = GetColumnPos(nItemId);
800 if ( nPos >= ColCount() )
801 // nicht vorhanden
802 return;
803
804 // Spaltenselektion korrigieren
805 if ( pColSel )
806 pColSel->Remove( nPos );
807
808 // Spaltencursor korrigieren
809 if ( nCurColId == nItemId )
810 nCurColId = 0;
811
812 // Spalte entfernen
813 delete( pCols->Remove( (sal_uLong) nPos ));
814 // OJ #93534#
815 if ( nFirstCol >= nPos && nFirstCol > FrozenColCount() )
816 {
817 OSL_ENSURE(nFirstCol > 0,"FirstCol must be greater zero!");
818 --nFirstCol;
819 }
820
821 // Handlecolumn nicht in der Headerbar
822 if (nItemId)
823 {
824 if ( getDataWindow()->pHeaderBar )
825 getDataWindow()->pHeaderBar->RemoveItem( nItemId );
826 }
827 else
828 {
829 // Headerbar anpassen
830 if ( getDataWindow()->pHeaderBar )
831 {
832 getDataWindow()->pHeaderBar->SetPosSizePixel(
833 Point(0, 0),
834 Size( GetOutputSizePixel().Width(), GetTitleHeight() )
835 );
836 }
837 }
838
839 // vertikalen Scrollbar korrigieren
840 UpdateScrollbars();
841
842 // ggf. Repaint ausl"osen
843 if ( GetUpdateMode() )
844 {
845 getDataWindow()->Invalidate();
846 Control::Invalidate();
847 if ( getDataWindow()->bAutoSizeLastCol && nPos ==ColCount() )
848 SetColumnWidth( GetColumnId( nPos - 1 ), LONG_MAX );
849 }
850
851 if ( isAccessibleAlive() )
852 {
853 commitTableEvent(
854 TABLE_MODEL_CHANGED,
855 makeAny( AccessibleTableModelChange( DELETE,
856 0,
857 GetRowCount(),
858 nPos,
859 nPos
860 )
861 ),
862 Any()
863 );
864
865 commitHeaderBarEvent(
866 CHILD,
867 Any(),
868 makeAny( CreateAccessibleColumnHeader( nPos ) ),
869 sal_True
870 );
871 }
872 }
873
874 //-------------------------------------------------------------------
875
RemoveColumns()876 void BrowseBox::RemoveColumns()
877 {
878 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
879
880 unsigned int nOldCount = pCols->Count();
881 // alle Spalten entfernen
882 while ( pCols->Count() )
883 delete ( pCols->Remove( (sal_uLong) 0 ));
884
885 // Spaltenselektion korrigieren
886 if ( pColSel )
887 {
888 pColSel->SelectAll(sal_False);
889 pColSel->SetTotalRange( Range( 0, 0 ) );
890 }
891
892 // Spaltencursor korrigieren
893 nCurColId = 0;
894 nFirstCol = 0;
895
896 if ( getDataWindow()->pHeaderBar )
897 getDataWindow()->pHeaderBar->Clear( );
898
899 // vertikalen Scrollbar korrigieren
900 UpdateScrollbars();
901
902 // ggf. Repaint ausl"osen
903 if ( GetUpdateMode() )
904 {
905 getDataWindow()->Invalidate();
906 Control::Invalidate();
907 }
908
909 if ( isAccessibleAlive() )
910 {
911 if ( pCols->Count() != nOldCount )
912 {
913 // all columns should be removed, so we remove the column header bar and append it again
914 // to avoid to notify every column remove
915 commitBrowseBoxEvent(
916 CHILD,
917 Any(),
918 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR))
919 );
920
921 // and now append it again
922 commitBrowseBoxEvent(
923 CHILD,
924 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR)),
925 Any()
926 );
927
928 // notify a table model change
929 commitTableEvent(
930 TABLE_MODEL_CHANGED,
931 makeAny ( AccessibleTableModelChange( DELETE,
932 0,
933 GetRowCount(),
934 0,
935 nOldCount
936 )
937 ),
938 Any()
939 );
940 }
941 }
942 }
943
944 //-------------------------------------------------------------------
945
GetColumnTitle(sal_uInt16 nId) const946 String BrowseBox::GetColumnTitle( sal_uInt16 nId ) const
947 {
948 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
949
950 sal_uInt16 nItemPos = GetColumnPos( nId );
951 if ( nItemPos >= pCols->Count() )
952 return String();
953 return pCols->GetObject(nItemPos)->Title();
954 }
955
956 //-------------------------------------------------------------------
957
GetRowCount() const958 long BrowseBox::GetRowCount() const
959 {
960 return nRowCount;
961 }
962
963 //-------------------------------------------------------------------
964
ColCount() const965 sal_uInt16 BrowseBox::ColCount() const
966 {
967 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
968
969 return (sal_uInt16) pCols->Count();
970 }
971
972 //-------------------------------------------------------------------
973
ImpGetDataRowHeight() const974 long BrowseBox::ImpGetDataRowHeight() const
975 {
976 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
977
978 BrowseBox *pThis = (BrowseBox*)this;
979 pThis->nDataRowHeight = pThis->CalcReverseZoom(pDataWin->GetTextHeight() + 2);
980 pThis->Resize();
981 getDataWindow()->Invalidate();
982 return nDataRowHeight;
983 }
984
985 //-------------------------------------------------------------------
986
SetDataRowHeight(long nPixel)987 void BrowseBox::SetDataRowHeight( long nPixel )
988 {
989 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
990
991 nDataRowHeight = CalcReverseZoom(nPixel);
992 Resize();
993 getDataWindow()->Invalidate();
994 }
995
996 //-------------------------------------------------------------------
997
SetTitleLines(sal_uInt16 nLines)998 void BrowseBox::SetTitleLines( sal_uInt16 nLines )
999 {
1000 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1001
1002 nTitleLines = nLines;
1003 }
1004
1005 //-------------------------------------------------------------------
1006
ScrollColumns(long nCols)1007 long BrowseBox::ScrollColumns( long nCols )
1008 {
1009 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1010
1011 if ( nFirstCol + nCols < 0 ||
1012 nFirstCol + nCols >= (long)pCols->Count() )
1013 //?MI: pCols->GetObject( nFirstCol + nCols )->IsFrozen() )
1014 return 0;
1015
1016 // implicitly hides cursor while scrolling
1017 StartScroll();
1018 bScrolling = sal_True;
1019 sal_Bool bScrollable = pDataWin->GetBackground().IsScrollable();
1020 sal_Bool bInvalidateView = sal_False;
1021
1022 // scrolling one column to the right?
1023 if ( nCols == 1 )
1024 {
1025 // update internal value and scrollbar
1026 ++nFirstCol;
1027 aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
1028
1029 if ( !bScrollable )
1030 {
1031 bInvalidateView = sal_True;
1032 }
1033 else
1034 {
1035 long nDelta = pCols->GetObject(nFirstCol-1)->Width();
1036 long nFrozenWidth = GetFrozenWidth();
1037
1038 Rectangle aScrollRect( Point( nFrozenWidth + nDelta, 0 ),
1039 Size ( GetOutputSizePixel().Width() - nFrozenWidth - nDelta,
1040 GetTitleHeight() - 1
1041 ) );
1042
1043 // scroll the header bar area (if there is no dedicated HeaderBar control)
1044 if ( !getDataWindow()->pHeaderBar && nTitleLines )
1045 {
1046 // actually scroll
1047 Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS );
1048
1049 // invalidate the area of the column which was scrolled out to the left hand side
1050 Rectangle aInvalidateRect( aScrollRect );
1051 aInvalidateRect.Left() = nFrozenWidth;
1052 aInvalidateRect.Right() = nFrozenWidth + nDelta - 1;
1053 Invalidate( aInvalidateRect );
1054 }
1055
1056 // scroll the data-area
1057 aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
1058
1059 // actually scroll
1060 pDataWin->Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS );
1061
1062 // invalidate the area of the column which was scrolled out to the left hand side
1063 aScrollRect.Left() = nFrozenWidth;
1064 aScrollRect.Right() = nFrozenWidth + nDelta - 1;
1065 getDataWindow()->Invalidate( aScrollRect );
1066 }
1067 }
1068
1069 // scrolling one column to the left?
1070 else if ( nCols == -1 )
1071 {
1072 --nFirstCol;
1073 aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
1074
1075 if ( !bScrollable )
1076 {
1077 bInvalidateView = sal_True;
1078 }
1079 else
1080 {
1081 long nDelta = pCols->GetObject(nFirstCol)->Width();
1082 long nFrozenWidth = GetFrozenWidth();
1083
1084 Rectangle aScrollRect( Point( nFrozenWidth, 0 ),
1085 Size ( GetOutputSizePixel().Width() - nFrozenWidth,
1086 GetTitleHeight() - 1
1087 ) );
1088
1089 // scroll the header bar area (if there is no dedicated HeaderBar control)
1090 if ( !getDataWindow()->pHeaderBar && nTitleLines )
1091 {
1092 Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS );
1093 }
1094
1095 // scroll the data-area
1096 aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
1097 pDataWin->Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS );
1098 }
1099 }
1100 else
1101 {
1102 if ( GetUpdateMode() )
1103 {
1104 Invalidate( Rectangle(
1105 Point( GetFrozenWidth(), 0 ),
1106 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
1107 getDataWindow()->Invalidate( Rectangle(
1108 Point( GetFrozenWidth(), 0 ),
1109 pDataWin->GetSizePixel() ) );
1110 }
1111
1112 nFirstCol = nFirstCol + (sal_uInt16)nCols;
1113 aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
1114 }
1115
1116 // ggf. externe Headerbar anpassen
1117 if ( getDataWindow()->pHeaderBar )
1118 {
1119 long nWidth = 0;
1120 for ( sal_uInt16 nCol = 0;
1121 nCol < pCols->Count() && nCol < nFirstCol;
1122 ++nCol )
1123 {
1124 // HandleColumn nicht
1125 if ( pCols->GetObject(nCol)->GetId() )
1126 nWidth += pCols->GetObject(nCol)->Width();
1127 }
1128
1129 getDataWindow()->pHeaderBar->SetOffset( nWidth );
1130 }
1131
1132 if( bInvalidateView )
1133 {
1134 Control::Invalidate( INVALIDATE_NOCHILDREN );
1135 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1136 }
1137
1138 // implicitly show cursor after scrolling
1139 if ( nCols )
1140 {
1141 getDataWindow()->Update();
1142 Update();
1143 }
1144 bScrolling = sal_False;
1145 EndScroll();
1146
1147 return nCols;
1148 }
1149
1150 //-------------------------------------------------------------------
1151
ScrollRows(long nRows)1152 long BrowseBox::ScrollRows( long nRows )
1153 {
1154 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1155
1156 // out of range?
1157 if ( getDataWindow()->bNoScrollBack && nRows < 0 )
1158 return 0;
1159
1160 // compute new top row
1161 long nTmpMin = Min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
1162
1163 long nNewTopRow = Max( (long)nTmpMin, (long)0 );
1164
1165 if ( nNewTopRow == nTopRow )
1166 return 0;
1167
1168 sal_uInt16 nVisibleRows =
1169 (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
1170
1171 VisibleRowsChanged(nNewTopRow, nVisibleRows);
1172
1173 // compute new top row again (nTopRow might have changed!)
1174 nTmpMin = Min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
1175
1176 nNewTopRow = Max( (long)nTmpMin, (long)0 );
1177
1178 StartScroll();
1179
1180 // scroll area on screen and/or repaint
1181 long nDeltaY = GetDataRowHeight() * ( nNewTopRow - nTopRow );
1182 long nOldTopRow = nTopRow;
1183 nTopRow = nNewTopRow;
1184
1185 if ( GetUpdateMode() )
1186 {
1187 pVScroll->SetRange( Range( 0L, nRowCount ) );
1188 pVScroll->SetThumbPos( nTopRow );
1189
1190 if( pDataWin->GetBackground().IsScrollable() &&
1191 Abs( nDeltaY ) > 0 &&
1192 Abs( nDeltaY ) < pDataWin->GetSizePixel().Height() )
1193 {
1194 pDataWin->Scroll( 0, (short)-nDeltaY, SCROLL_FLAGS );
1195 }
1196 else
1197 getDataWindow()->Invalidate();
1198
1199 if ( nTopRow - nOldTopRow )
1200 getDataWindow()->Update();
1201 }
1202
1203 EndScroll();
1204
1205 return nTopRow - nOldTopRow;
1206 }
1207
1208 //-------------------------------------------------------------------
1209
ScrollPages(long)1210 long BrowseBox::ScrollPages( long )
1211 {
1212 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1213
1214 return ScrollRows( pDataWin->GetSizePixel().Height() / GetDataRowHeight() );
1215 }
1216
1217 //-------------------------------------------------------------------
1218
RowModified(long nRow,sal_uInt16 nColId)1219 void BrowseBox::RowModified( long nRow, sal_uInt16 nColId )
1220 {
1221 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1222
1223 if ( !GetUpdateMode() )
1224 return;
1225
1226 Rectangle aRect;
1227 if ( nColId == USHRT_MAX )
1228 // invalidate the whole row
1229 aRect = Rectangle( Point( 0, (nRow-nTopRow) * GetDataRowHeight() ),
1230 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
1231 else
1232 {
1233 // invalidate the specific field
1234 aRect = GetFieldRectPixel( nRow, nColId, sal_False );
1235 }
1236 getDataWindow()->Invalidate( aRect );
1237 }
1238
1239 //-------------------------------------------------------------------
1240
Clear()1241 void BrowseBox::Clear()
1242 {
1243 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1244
1245 // adjust the total number of rows
1246 DoHideCursor( "Clear" );
1247 long nOldRowCount = nRowCount;
1248 nRowCount = 0;
1249 nCurRow = BROWSER_ENDOFSELECTION;
1250 nTopRow = 0;
1251 nCurColId = 0;
1252
1253 // nFirstCol darf nicht zurueckgesetzt werden, da ansonsten das Scrollen
1254 // total durcheinander kommt
1255 // nFirstCol darf nur beim Hinzufuegen oder Loeschen von Spalten geaendert werden
1256 // nFirstCol = 0; ->Falsch!!!!
1257 aHScroll.SetThumbPos( 0 );
1258 pVScroll->SetThumbPos( 0 );
1259
1260 Invalidate();
1261 UpdateScrollbars();
1262 SetNoSelection();
1263 DoShowCursor( "Clear" );
1264 CursorMoved();
1265
1266 if ( isAccessibleAlive() )
1267 {
1268 // all rows should be removed, so we remove the row header bar and append it again
1269 // to avoid to notify every row remove
1270 if ( nOldRowCount != nRowCount )
1271 {
1272 commitBrowseBoxEvent(
1273 CHILD,
1274 Any(),
1275 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) )
1276 );
1277
1278 // and now append it again
1279 commitBrowseBoxEvent(
1280 CHILD,
1281 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) ),
1282 Any()
1283 );
1284
1285 // notify a table model change
1286 commitTableEvent(
1287 TABLE_MODEL_CHANGED,
1288 makeAny( AccessibleTableModelChange( DELETE,
1289 0,
1290 nOldRowCount,
1291 0,
1292 GetColumnCount())
1293 ),
1294 Any()
1295 );
1296 }
1297 }
1298 }
1299 // -----------------------------------------------------------------------------
RowInserted(long nRow,long nNumRows,sal_Bool bDoPaint,sal_Bool bKeepSelection)1300 void BrowseBox::RowInserted( long nRow, long nNumRows, sal_Bool bDoPaint, sal_Bool bKeepSelection )
1301 {
1302 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1303
1304 if (nRow < 0)
1305 nRow = 0;
1306 else if (nRow > nRowCount) // maximal = nRowCount
1307 nRow = nRowCount;
1308
1309 if ( nNumRows <= 0 )
1310 return;
1311
1312 #if 0
1313 // Zerlegung in einzelne RowInserted-Aufrufe:
1314 if (nNumRows > 1)
1315 {
1316 for (long i = 0; i < nNumRows; i++)
1317 RowInserted(nRow + i,1,bDoPaint);
1318 return;
1319 }
1320 #endif
1321
1322 // adjust total row count
1323 sal_Bool bLastRow = nRow >= nRowCount;
1324 nRowCount += nNumRows;
1325
1326 DoHideCursor( "RowInserted" );
1327
1328 // must we paint the new rows?
1329 long nOldCurRow = nCurRow;
1330 Size aSz = pDataWin->GetOutputSizePixel();
1331 if ( bDoPaint && nRow >= nTopRow &&
1332 nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
1333 {
1334 long nY = (nRow-nTopRow) * GetDataRowHeight();
1335 if ( !bLastRow )
1336 {
1337 // scroll down the rows behind the new row
1338 pDataWin->SetClipRegion();
1339 if( pDataWin->GetBackground().IsScrollable() )
1340 {
1341 pDataWin->Scroll( 0, GetDataRowHeight() * nNumRows,
1342 Rectangle( Point( 0, nY ),
1343 Size( aSz.Width(), aSz.Height() - nY ) ),
1344 SCROLL_FLAGS );
1345 }
1346 else
1347 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1348 }
1349 else
1350 // scroll would cause a repaint, so we must explicitly invalidate
1351 pDataWin->Invalidate( Rectangle( Point( 0, nY ),
1352 Size( aSz.Width(), nNumRows * GetDataRowHeight() ) ) );
1353 }
1354
1355 // ggf. Top-Row korrigieren
1356 if ( nRow < nTopRow )
1357 nTopRow += nNumRows;
1358
1359 // adjust the selection
1360 if ( bMultiSelection )
1361 uRow.pSel->Insert( nRow, nNumRows );
1362 else if ( uRow.nSel != BROWSER_ENDOFSELECTION && nRow <= uRow.nSel )
1363 uRow.nSel += nNumRows;
1364
1365 // adjust the cursor
1366 if ( nCurRow == BROWSER_ENDOFSELECTION )
1367 GoToRow( 0, sal_False, bKeepSelection );
1368 else if ( nRow <= nCurRow )
1369 GoToRow( nCurRow += nNumRows, sal_False, bKeepSelection );
1370
1371 // adjust the vertical scrollbar
1372 if ( bDoPaint )
1373 {
1374 UpdateScrollbars();
1375 AutoSizeLastColumn();
1376 }
1377
1378 DoShowCursor( "RowInserted" );
1379 // notify accessible that rows were inserted
1380 if ( isAccessibleAlive() )
1381 {
1382 commitTableEvent(
1383 TABLE_MODEL_CHANGED,
1384 makeAny( AccessibleTableModelChange(
1385 INSERT,
1386 nRow,
1387 nRow + nNumRows,
1388 0,
1389 GetColumnCount()
1390 )
1391 ),
1392 Any()
1393 );
1394
1395 for (sal_Int32 i = nRow+1 ; i <= nRowCount ; ++i)
1396 {
1397 commitHeaderBarEvent(
1398 CHILD,
1399 makeAny( CreateAccessibleRowHeader( i ) ),
1400 Any(),
1401 sal_False
1402 );
1403 }
1404 }
1405
1406 if ( nCurRow != nOldCurRow )
1407 CursorMoved();
1408
1409 DBG_ASSERT(nRowCount > 0,"BrowseBox: nRowCount <= 0");
1410 DBG_ASSERT(nCurRow >= 0,"BrowseBox: nCurRow < 0");
1411 DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
1412 }
1413
1414 //-------------------------------------------------------------------
1415
RowRemoved(long nRow,long nNumRows,sal_Bool bDoPaint)1416 void BrowseBox::RowRemoved( long nRow, long nNumRows, sal_Bool bDoPaint )
1417 {
1418 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1419
1420 if ( nRow < 0 )
1421 nRow = 0;
1422 else if ( nRow >= nRowCount )
1423 nRow = nRowCount - 1;
1424
1425 if ( nNumRows <= 0 )
1426 return;
1427
1428 if ( nRowCount <= 0 )
1429 return;
1430
1431 if ( bDoPaint )
1432 {
1433 // hide cursor and selection
1434 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
1435 ToggleSelection();
1436 DoHideCursor( "RowRemoved" );
1437 }
1438
1439 // adjust total row count
1440 nRowCount -= nNumRows;
1441 if (nRowCount < 0) nRowCount = 0;
1442 long nOldCurRow = nCurRow;
1443
1444 // adjust the selection
1445 if ( bMultiSelection )
1446 // uRow.pSel->Remove( nRow, nNumRows );
1447 for ( long i = 0; i < nNumRows; i++ )
1448 uRow.pSel->Remove( nRow );
1449 else if ( nRow < uRow.nSel && uRow.nSel >= nNumRows )
1450 uRow.nSel -= nNumRows;
1451 else if ( nRow <= uRow.nSel )
1452 uRow.nSel = BROWSER_ENDOFSELECTION;
1453
1454 // adjust the cursor
1455 if ( nRowCount == 0 ) // don't compare nRowCount with nNumRows as nNumRows already was subtracted from nRowCount
1456 nCurRow = BROWSER_ENDOFSELECTION;
1457 else if ( nRow < nCurRow )
1458 {
1459 nCurRow -= Min( nCurRow - nRow, nNumRows );
1460 // with the above nCurRow points a) to the first row after the removed block or b) to the same line
1461 // as before, but moved up nNumRows
1462 // case a) needs an additional correction if the last n lines were deleted, as 'the first row after the
1463 // removed block' is an invalid position then
1464 // FS - 09/28/99 - 68429
1465 if (nCurRow == nRowCount)
1466 --nCurRow;
1467 }
1468 else if( nRow == nCurRow && nCurRow == nRowCount )
1469 nCurRow = nRowCount-1;
1470
1471 // is the deleted row visible?
1472 Size aSz = pDataWin->GetOutputSizePixel();
1473 if ( nRow >= nTopRow &&
1474 nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
1475 {
1476 if ( bDoPaint )
1477 {
1478 // scroll up the rows behind the deleted row
1479 // if there are Rows behind
1480 if (nRow < nRowCount)
1481 {
1482 long nY = (nRow-nTopRow) * GetDataRowHeight();
1483 pDataWin->SetClipRegion();
1484 if( pDataWin->GetBackground().IsScrollable() )
1485 {
1486 pDataWin->Scroll( 0, - (short) GetDataRowHeight() * nNumRows,
1487 Rectangle( Point( 0, nY ), Size( aSz.Width(),
1488 aSz.Height() - nY + nNumRows*GetDataRowHeight() ) ),
1489 SCROLL_FLAGS );
1490 }
1491 else
1492 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1493 }
1494 else
1495 {
1496 // Repaint the Rect of the deleted row
1497 Rectangle aRect(
1498 Point( 0, (nRow-nTopRow)*GetDataRowHeight() ),
1499 Size( pDataWin->GetSizePixel().Width(),
1500 nNumRows * GetDataRowHeight() ) );
1501 pDataWin->Invalidate( aRect );
1502 }
1503 }
1504 }
1505 // is the deleted row above of the visible area?
1506 else if ( nRow < nTopRow )
1507 nTopRow = nTopRow >= nNumRows ? nTopRow-nNumRows : 0;
1508
1509 if ( bDoPaint )
1510 {
1511 // reshow cursor and selection
1512 ToggleSelection();
1513 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
1514 DoShowCursor( "RowRemoved" );
1515
1516 // adjust the vertical scrollbar
1517 UpdateScrollbars();
1518 AutoSizeLastColumn();
1519 }
1520
1521 if ( isAccessibleAlive() )
1522 {
1523 if ( nRowCount == 0 )
1524 {
1525 // all columns should be removed, so we remove the column header bar and append it again
1526 // to avoid to notify every column remove
1527 commitBrowseBoxEvent(
1528 CHILD,
1529 Any(),
1530 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) )
1531 );
1532
1533 // and now append it again
1534 commitBrowseBoxEvent(
1535 CHILD,
1536 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_ROWHEADERBAR)),
1537 Any()
1538 );
1539 commitBrowseBoxEvent(
1540 CHILD,
1541 Any(),
1542 makeAny( m_pImpl->getAccessibleTable() )
1543 );
1544
1545 // and now append it again
1546 commitBrowseBoxEvent(
1547 CHILD,
1548 makeAny( m_pImpl->getAccessibleTable() ),
1549 Any()
1550 );
1551 }
1552 else
1553 {
1554 commitTableEvent(
1555 TABLE_MODEL_CHANGED,
1556 makeAny( AccessibleTableModelChange(
1557 DELETE,
1558 nRow,
1559 nRow + nNumRows,
1560 0,
1561 GetColumnCount()
1562 )
1563 ),
1564 Any()
1565 );
1566
1567 for (sal_Int32 i = nRow+1 ; i <= (nRow+nNumRows) ; ++i)
1568 {
1569 commitHeaderBarEvent(
1570 CHILD,
1571 Any(),
1572 makeAny( CreateAccessibleRowHeader( i ) ),
1573 sal_False
1574 );
1575 }
1576 }
1577 }
1578
1579 if ( nOldCurRow != nCurRow )
1580 CursorMoved();
1581
1582 DBG_ASSERT(nRowCount >= 0,"BrowseBox: nRowCount < 0");
1583 DBG_ASSERT(nCurRow >= 0 || nRowCount == 0,"BrowseBox: nCurRow < 0 && nRowCount != 0");
1584 DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
1585 }
1586
1587 //-------------------------------------------------------------------
1588
GoToRow(long nRow)1589 sal_Bool BrowseBox::GoToRow( long nRow)
1590 {
1591 return GoToRow(nRow, sal_False, sal_False);
1592 }
1593
1594 //-------------------------------------------------------------------
1595
GoToRowAndDoNotModifySelection(long nRow)1596 sal_Bool BrowseBox::GoToRowAndDoNotModifySelection( long nRow )
1597 {
1598 return GoToRow( nRow, sal_False, sal_True );
1599 }
1600
1601 //-------------------------------------------------------------------
GoToRow(long nRow,sal_Bool bRowColMove,sal_Bool bKeepSelection)1602 sal_Bool BrowseBox::GoToRow( long nRow, sal_Bool bRowColMove, sal_Bool bKeepSelection )
1603 {
1604 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1605
1606 long nOldCurRow = nCurRow;
1607
1608 // nothing to do?
1609 if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) )
1610 return sal_True;
1611
1612 // out of range?
1613 if ( nRow < 0 || nRow >= nRowCount )
1614 return sal_False;
1615
1616 // nicht erlaubt?
1617 if ( ( !bRowColMove && !IsCursorMoveAllowed( nRow, nCurColId ) ) )
1618 return sal_False;
1619
1620 if ( getDataWindow()->bNoScrollBack && nRow < nTopRow )
1621 nRow = nTopRow;
1622
1623 // compute the last visible row
1624 Size aSz( pDataWin->GetSizePixel() );
1625 sal_uInt16 nVisibleRows = sal_uInt16( aSz.Height() / GetDataRowHeight() - 1 );
1626 long nLastRow = nTopRow + nVisibleRows;
1627
1628 // suspend Updates
1629 getDataWindow()->EnterUpdateLock();
1630
1631 // ggf. altes Highlight weg
1632 if ( !bMultiSelection && !bKeepSelection )
1633 ToggleSelection();
1634 DoHideCursor( "GoToRow" );
1635
1636 // must we scroll?
1637 sal_Bool bWasVisible = bSelectionIsVisible;
1638 if (! bMultiSelection)
1639 {
1640 if( !bKeepSelection )
1641 bSelectionIsVisible = sal_False;
1642 }
1643 if ( nRow < nTopRow )
1644 ScrollRows( nRow - nTopRow );
1645 else if ( nRow > nLastRow )
1646 ScrollRows( nRow - nLastRow );
1647 bSelectionIsVisible = bWasVisible;
1648
1649 // adjust cursor (selection) and thumb
1650 if ( GetUpdateMode() )
1651 pVScroll->SetThumbPos( nTopRow );
1652
1653 // relative positioning (because nCurRow might have changed in the meantime)!
1654 if (nCurRow != BROWSER_ENDOFSELECTION )
1655 nCurRow = nCurRow + (nRow - nOldCurRow);
1656
1657 // make sure that the current position is valid
1658 if (nCurRow == BROWSER_ENDOFSELECTION && nRowCount > 0)
1659 nCurRow = 0;
1660 else if ( nCurRow >= nRowCount )
1661 nCurRow = nRowCount - 1;
1662 aSelRange = Range( nCurRow, nCurRow );
1663
1664 // ggf. neues Highlight anzeigen
1665 if ( !bMultiSelection && !bKeepSelection )
1666 uRow.nSel = nRow;
1667
1668 // resume Updates
1669 getDataWindow()->LeaveUpdateLock();
1670
1671 // Cursor+Highlight
1672 if ( !bMultiSelection && !bKeepSelection)
1673 ToggleSelection();
1674 DoShowCursor( "GoToRow" );
1675 if ( !bRowColMove && nOldCurRow != nCurRow )
1676 CursorMoved();
1677
1678 if ( !bMultiSelection && !bKeepSelection )
1679 {
1680 if ( !bSelecting )
1681 Select();
1682 else
1683 bSelect = sal_True;
1684 }
1685 return sal_True;
1686 }
1687
1688 //-------------------------------------------------------------------
1689
GoToColumnId(sal_uInt16 nColId)1690 sal_Bool BrowseBox::GoToColumnId( sal_uInt16 nColId)
1691 {
1692 return GoToColumnId(nColId,sal_True,sal_False);
1693 }
1694
1695
GoToColumnId(sal_uInt16 nColId,sal_Bool bMakeVisible,sal_Bool bRowColMove)1696 sal_Bool BrowseBox::GoToColumnId( sal_uInt16 nColId, sal_Bool bMakeVisible, sal_Bool bRowColMove)
1697 {
1698 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1699
1700 if (!bColumnCursor)
1701 return sal_False;
1702
1703 // erlaubt?
1704 if (!bRowColMove && !IsCursorMoveAllowed( nCurRow, nColId ) )
1705 return sal_False;
1706
1707 if ( nColId != nCurColId || (bMakeVisible && !IsFieldVisible(nCurRow, nColId, sal_True)))
1708 {
1709 sal_uInt16 nNewPos = GetColumnPos(nColId);
1710 BrowserColumn* pColumn = pCols->GetObject( nNewPos );
1711 DBG_ASSERT( pColumn, "no column object - invalid id?" );
1712 if ( !pColumn )
1713 return sal_False;
1714
1715 DoHideCursor( "GoToColumnId" );
1716 nCurColId = nColId;
1717
1718 sal_uInt16 nFirstPos = nFirstCol;
1719 sal_uInt16 nWidth = (sal_uInt16)pColumn->Width();
1720 sal_uInt16 nLastPos = GetColumnAtXPosPixel(
1721 pDataWin->GetSizePixel().Width()-nWidth, sal_False );
1722 sal_uInt16 nFrozen = FrozenColCount();
1723 if ( bMakeVisible && nLastPos &&
1724 nNewPos >= nFrozen && ( nNewPos < nFirstPos || nNewPos > nLastPos ) )
1725 {
1726 if ( nNewPos < nFirstPos )
1727 ScrollColumns( nNewPos-nFirstPos );
1728 else if ( nNewPos > nLastPos )
1729 ScrollColumns( nNewPos-nLastPos );
1730 }
1731
1732 DoShowCursor( "GoToColumnId" );
1733 if (!bRowColMove)
1734 CursorMoved();
1735 return sal_True;
1736 }
1737 return sal_True;
1738 }
1739
1740 //-------------------------------------------------------------------
1741
GoToRowColumnId(long nRow,sal_uInt16 nColId)1742 sal_Bool BrowseBox::GoToRowColumnId( long nRow, sal_uInt16 nColId )
1743 {
1744 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1745
1746 // out of range?
1747 if ( nRow < 0 || nRow >= nRowCount )
1748 return sal_False;
1749
1750 if (!bColumnCursor)
1751 return sal_False;
1752
1753 // nothing to do ?
1754 if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) &&
1755 nColId == nCurColId && IsFieldVisible(nCurRow, nColId, sal_True))
1756 return sal_True;
1757
1758 // erlaubt?
1759 if (!IsCursorMoveAllowed(nRow, nColId))
1760 return sal_False;
1761
1762 DoHideCursor( "GoToRowColumnId" );
1763 sal_Bool bMoved = GoToRow(nRow, sal_True) && GoToColumnId(nColId, sal_True, sal_True);
1764 DoShowCursor( "GoToRowColumnId" );
1765
1766 if (bMoved)
1767 CursorMoved();
1768
1769 return bMoved;
1770 }
1771
1772 //-------------------------------------------------------------------
1773
SetNoSelection()1774 void BrowseBox::SetNoSelection()
1775 {
1776 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1777
1778 // is there no selection
1779 if ( ( !pColSel || !pColSel->GetSelectCount() ) &&
1780 ( ( !bMultiSelection && uRow.nSel == BROWSER_ENDOFSELECTION ) ||
1781 ( bMultiSelection && !uRow.pSel->GetSelectCount() ) ) )
1782 // nothing to do
1783 return;
1784
1785 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
1786 ToggleSelection();
1787
1788 // unselect all
1789 if ( bMultiSelection )
1790 uRow.pSel->SelectAll(sal_False);
1791 else
1792 uRow.nSel = BROWSER_ENDOFSELECTION;
1793 if ( pColSel )
1794 pColSel->SelectAll(sal_False);
1795 if ( !bSelecting )
1796 Select();
1797 else
1798 bSelect = sal_True;
1799
1800 // restore screen
1801 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
1802
1803 if ( isAccessibleAlive() )
1804 {
1805 commitTableEvent(
1806 SELECTION_CHANGED,
1807 Any(),
1808 Any()
1809 );
1810 }
1811 }
1812
1813 //-------------------------------------------------------------------
1814
SetSelection(const MultiSelection & rSel)1815 void BrowseBox::SetSelection( const MultiSelection &rSel )
1816 {
1817 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1818 DBG_ASSERT( bMultiSelection, "SetSelection only allowed with Multi-Selection-Mode" );
1819
1820 // prepare inverted areas
1821 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
1822 ToggleSelection();
1823
1824 // assign Selection
1825 *uRow.pSel = rSel;
1826
1827 // only highlight painted areas
1828 pDataWin->Update();
1829
1830 // notify derived class
1831 if ( !bSelecting )
1832 Select();
1833 else
1834 bSelect = sal_True;
1835
1836 // restore screen
1837 ToggleSelection();
1838 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
1839
1840 if ( isAccessibleAlive() )
1841 {
1842 commitTableEvent(
1843 SELECTION_CHANGED,
1844 Any(),
1845 Any()
1846 );
1847 }
1848 }
1849
1850 //-------------------------------------------------------------------
1851
SelectAll()1852 void BrowseBox::SelectAll()
1853 {
1854 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1855
1856 if ( !bMultiSelection )
1857 return;
1858
1859 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
1860 ToggleSelection();
1861
1862 // select all rows
1863 if ( pColSel )
1864 pColSel->SelectAll(sal_False);
1865 uRow.pSel->SelectAll(sal_True);
1866
1867 // Handle-Column nicht highlighten
1868 BrowserColumn *pFirstCol = pCols->GetObject(0);
1869 long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
1870
1871 // highlight the row selection
1872 if ( !bHideSelect )
1873 {
1874 Rectangle aHighlightRect;
1875 sal_uInt16 nVisibleRows =
1876 (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
1877 for ( long nRow = Max( nTopRow, uRow.pSel->FirstSelected() );
1878 nRow != BROWSER_ENDOFSELECTION && nRow < nTopRow + nVisibleRows;
1879 nRow = uRow.pSel->NextSelected() )
1880 aHighlightRect.Union( Rectangle(
1881 Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
1882 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) ) );
1883 pDataWin->Invalidate( aHighlightRect );
1884 }
1885
1886 if ( !bSelecting )
1887 Select();
1888 else
1889 bSelect = sal_True;
1890
1891 // restore screen
1892 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
1893
1894 if ( isAccessibleAlive() )
1895 {
1896 commitTableEvent(
1897 SELECTION_CHANGED,
1898 Any(),
1899 Any()
1900 );
1901 commitHeaderBarEvent(
1902 SELECTION_CHANGED,
1903 Any(),
1904 Any(),
1905 sal_True
1906 ); // column header event
1907
1908 commitHeaderBarEvent(
1909 SELECTION_CHANGED,
1910 Any(),
1911 Any(),
1912 sal_False
1913 ); // row header event
1914 }
1915 }
1916
1917 //-------------------------------------------------------------------
1918
SelectRow(long nRow,sal_Bool _bSelect,sal_Bool bExpand)1919 void BrowseBox::SelectRow( long nRow, sal_Bool _bSelect, sal_Bool bExpand )
1920 {
1921 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1922
1923 if ( !bMultiSelection )
1924 {
1925 // deselecting is impossible, selecting via cursor
1926 if ( _bSelect )
1927 GoToRow(nRow, sal_False);
1928 return;
1929 }
1930
1931 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
1932
1933 // remove old selection?
1934 if ( !bExpand || !bMultiSelection )
1935 {
1936 ToggleSelection();
1937 if ( bMultiSelection )
1938 uRow.pSel->SelectAll(sal_False);
1939 else
1940 uRow.nSel = BROWSER_ENDOFSELECTION;
1941 if ( pColSel )
1942 pColSel->SelectAll(sal_False);
1943 }
1944
1945 // set new selection
1946 if ( !bHideSelect
1947 && ( ( bMultiSelection
1948 && uRow.pSel->GetTotalRange().Max() >= nRow
1949 && uRow.pSel->Select( nRow, _bSelect )
1950 )
1951 || ( !bMultiSelection
1952 && ( uRow.nSel = nRow ) != BROWSER_ENDOFSELECTION )
1953 )
1954 )
1955 {
1956 // Handle-Column nicht highlighten
1957 BrowserColumn *pFirstCol = pCols->GetObject(0);
1958 long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
1959
1960 // highlight only newly selected part
1961 Rectangle aRect(
1962 Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
1963 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
1964 pDataWin->Invalidate( aRect );
1965 }
1966
1967 if ( !bSelecting )
1968 Select();
1969 else
1970 bSelect = sal_True;
1971
1972 // restore screen
1973 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
1974
1975 if ( isAccessibleAlive() )
1976 {
1977 commitTableEvent(
1978 SELECTION_CHANGED,
1979 Any(),
1980 Any()
1981 );
1982 commitHeaderBarEvent(
1983 SELECTION_CHANGED,
1984 Any(),
1985 Any(),
1986 sal_False
1987 ); // row header event
1988 }
1989 }
1990
1991 //-------------------------------------------------------------------
1992
GetSelectRowCount() const1993 long BrowseBox::GetSelectRowCount() const
1994 {
1995 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1996
1997 return bMultiSelection ? uRow.pSel->GetSelectCount() :
1998 uRow.nSel == BROWSER_ENDOFSELECTION ? 0 : 1;
1999 }
2000
2001 //-------------------------------------------------------------------
2002
SelectColumnPos(sal_uInt16 nNewColPos,sal_Bool _bSelect,sal_Bool bMakeVisible)2003 void BrowseBox::SelectColumnPos( sal_uInt16 nNewColPos, sal_Bool _bSelect, sal_Bool bMakeVisible )
2004 {
2005 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2006
2007 if ( !bColumnCursor || nNewColPos == BROWSER_INVALIDID )
2008 return;
2009
2010 if ( !bMultiSelection )
2011 {
2012 if ( _bSelect )
2013 GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
2014 return;
2015 }
2016 else
2017 {
2018 if ( !GoToColumnId( pCols->GetObject( nNewColPos )->GetId(), bMakeVisible ) )
2019 return;
2020 }
2021
2022 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
2023 ToggleSelection();
2024 if ( bMultiSelection )
2025 uRow.pSel->SelectAll(sal_False);
2026 else
2027 uRow.nSel = BROWSER_ENDOFSELECTION;
2028 pColSel->SelectAll(sal_False);
2029
2030 if ( pColSel->Select( nNewColPos, _bSelect ) )
2031 {
2032 // GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
2033
2034 // only highlight painted areas
2035 pDataWin->Update();
2036 Rectangle aFieldRectPix( GetFieldRectPixel( nCurRow, nCurColId, sal_False ) );
2037 Rectangle aRect(
2038 Point( aFieldRectPix.Left() - MIN_COLUMNWIDTH, 0 ),
2039 Size( pCols->GetObject(nNewColPos)->Width(),
2040 pDataWin->GetOutputSizePixel().Height() ) );
2041 pDataWin->Invalidate( aRect );
2042 if ( !bSelecting )
2043 Select();
2044 else
2045 bSelect = sal_True;
2046
2047 if ( isAccessibleAlive() )
2048 {
2049 commitTableEvent(
2050 SELECTION_CHANGED,
2051 Any(),
2052 Any()
2053 );
2054 commitHeaderBarEvent(
2055 SELECTION_CHANGED,
2056 Any(),
2057 Any(),
2058 sal_True
2059 ); // column header event
2060 }
2061 }
2062
2063 // restore screen
2064 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
2065 }
2066
2067 //-------------------------------------------------------------------
2068
GetSelectColumnCount() const2069 sal_uInt16 BrowseBox::GetSelectColumnCount() const
2070 {
2071 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2072
2073 // while bAutoSelect (==!pColSel), 1 if any rows (yes rows!) else none
2074 return pColSel ? (sal_uInt16) pColSel->GetSelectCount() :
2075 nCurRow >= 0 ? 1 : 0;
2076 }
2077
2078 //-------------------------------------------------------------------
FirstSelectedColumn() const2079 long BrowseBox::FirstSelectedColumn( ) const
2080 {
2081 return pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION;
2082 }
2083
2084 //-------------------------------------------------------------------
NextSelectedColumn() const2085 long BrowseBox::NextSelectedColumn( ) const
2086 {
2087 return pColSel ? pColSel->NextSelected() : BROWSER_ENDOFSELECTION;
2088 }
2089
2090 //-------------------------------------------------------------------
2091
FirstSelectedRow(sal_Bool bInverse)2092 long BrowseBox::FirstSelectedRow( sal_Bool bInverse )
2093 {
2094 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2095
2096 return bMultiSelection ? uRow.pSel->FirstSelected(bInverse) : uRow.nSel;
2097 }
2098
2099 //-------------------------------------------------------------------
2100
NextSelectedRow()2101 long BrowseBox::NextSelectedRow()
2102 {
2103 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2104
2105 return bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION;
2106 }
2107
2108 //-------------------------------------------------------------------
2109
PrevSelectedRow()2110 long BrowseBox::PrevSelectedRow()
2111 {
2112 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2113
2114 return bMultiSelection ? uRow.pSel->PrevSelected() : BROWSER_ENDOFSELECTION;
2115 }
2116
2117 //-------------------------------------------------------------------
2118
LastSelectedRow()2119 long BrowseBox::LastSelectedRow()
2120 {
2121 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2122
2123 return bMultiSelection ? uRow.pSel->LastSelected() : uRow.nSel;
2124 }
2125
2126 //-------------------------------------------------------------------
2127
IsRowSelected(long nRow) const2128 bool BrowseBox::IsRowSelected( long nRow ) const
2129 {
2130 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2131
2132 return bMultiSelection ? uRow.pSel->IsSelected(nRow) : nRow == uRow.nSel;
2133 }
2134
2135 //-------------------------------------------------------------------
2136
IsColumnSelected(sal_uInt16 nColumnId) const2137 bool BrowseBox::IsColumnSelected( sal_uInt16 nColumnId ) const
2138 {
2139 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2140
2141 return pColSel ? pColSel->IsSelected( GetColumnPos(nColumnId) ) :
2142 nCurColId == nColumnId;
2143 }
2144
2145 //-------------------------------------------------------------------
2146
IsAllSelected() const2147 sal_Bool BrowseBox::IsAllSelected() const
2148 {
2149 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2150
2151 return bMultiSelection && uRow.pSel->IsAllSelected();
2152 }
2153
2154 //-------------------------------------------------------------------
2155
MakeFieldVisible(long nRow,sal_uInt16 nColId,sal_Bool bComplete)2156 sal_Bool BrowseBox::MakeFieldVisible
2157 (
2158 long nRow, // Zeilen-Nr des Feldes (beginnend mit 0)
2159 sal_uInt16 nColId, // Spalten-Id des Feldes
2160 sal_Bool bComplete // (== sal_False), sal_True => vollst"andig sichtbar machen
2161 )
2162
2163 /* [Beschreibung]
2164
2165 Macht das durch 'nRow' und 'nColId' beschriebene Feld durch
2166 entsprechendes scrollen sichtbar. Ist 'bComplete' gesetzt, dann wird
2167 gefordert, da\s das Feld ganz sichtbar wird.
2168
2169 [R"uckgabewert]
2170
2171 sal_Bool sal_True
2172 Das angegebene Feld wurde sichtbar gemacht, bzw. war
2173 bereits sichtbar.
2174
2175 sal_False
2176 Das angegebene Feld konnte nicht sichtbar bzw. bei
2177 'bComplete' nicht vollst"andig sichtbar gemacht werden.
2178 */
2179
2180 {
2181 Size aTestSize = pDataWin->GetSizePixel();
2182
2183 if ( !bBootstrapped ||
2184 ( aTestSize.Width() == 0 && aTestSize.Height() == 0 ) )
2185 return sal_False;
2186
2187 // ist es schon sichtbar?
2188 sal_Bool bVisible = IsFieldVisible( nRow, nColId, bComplete );
2189 if ( bVisible )
2190 return sal_True;
2191
2192 // Spaltenposition und Feld-Rechteck und Ausgabebereich berechnen
2193 sal_uInt16 nColPos = GetColumnPos( nColId );
2194 Rectangle aFieldRect = GetFieldRectPixel( nRow, nColId, sal_False );
2195 Rectangle aDataRect = Rectangle( Point(0, 0), pDataWin->GetSizePixel() );
2196
2197 // links au\serhalb?
2198 if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
2199 // => nach rechts scrollen
2200 ScrollColumns( nColPos - nFirstCol );
2201
2202 // solange rechts au\serhalb
2203 while ( aDataRect.Right() < ( bComplete
2204 ? aFieldRect.Right()
2205 : aFieldRect.Left()+aFieldRect.GetWidth()/2 ) )
2206 {
2207 // => nach links scrollen
2208 if ( ScrollColumns( 1 ) != 1 )
2209 // nichts mehr zu scrollen
2210 break;
2211 aFieldRect = GetFieldRectPixel( nRow, nColId, sal_False );
2212 }
2213
2214 // oben au\serhalb?
2215 if ( nRow < nTopRow )
2216 // nach unten scrollen
2217 ScrollRows( nRow - nTopRow );
2218
2219 // unten au\serhalb?
2220 long nBottomRow = nTopRow + GetVisibleRows();
2221 // OV: damit nBottomRow die Nummer der letzten sichtbaren Zeile ist
2222 // (Zaehlung ab Null!), muss sie dekrementiert werden.
2223 // Beispiel: BrowseBox enthaelt genau einen Eintrag. nBottomRow := 0 + 1 - 1
2224 if( nBottomRow )
2225 nBottomRow--;
2226
2227 if ( nRow > nBottomRow )
2228 // nach oben scrollen
2229 ScrollRows( nRow - nBottomRow );
2230
2231 // jetzt kann es immer noch nicht passen, z.B. weil Window zu klein
2232 return IsFieldVisible( nRow, nColId, bComplete );
2233 }
2234
2235 //-------------------------------------------------------------------
2236
IsFieldVisible(long nRow,sal_uInt16 nColumnId,sal_Bool bCompletely) const2237 sal_Bool BrowseBox::IsFieldVisible( long nRow, sal_uInt16 nColumnId,
2238 sal_Bool bCompletely ) const
2239 {
2240 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2241
2242 // durch frozen-Column verdeckt?
2243 sal_uInt16 nColPos = GetColumnPos( nColumnId );
2244 if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
2245 return sal_False;
2246
2247 Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
2248 if ( aRect.IsEmpty() )
2249 return sal_False;
2250
2251 // get the visible area
2252 Rectangle aOutRect( Point(0, 0), pDataWin->GetOutputSizePixel() );
2253
2254 if ( bCompletely )
2255 // test if the field is completely visible
2256 return aOutRect.IsInside( aRect );
2257 else
2258 // test if the field is partly of completely visible
2259 return !aOutRect.Intersection( aRect ).IsEmpty();
2260 }
2261
2262 //-------------------------------------------------------------------
2263
GetFieldRectPixel(long nRow,sal_uInt16 nColumnId,sal_Bool bRelToBrowser) const2264 Rectangle BrowseBox::GetFieldRectPixel( long nRow, sal_uInt16 nColumnId,
2265 sal_Bool bRelToBrowser) const
2266 {
2267 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2268
2269 // get the rectangle relative to DataWin
2270 Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
2271 if ( aRect.IsEmpty() )
2272 return aRect;
2273
2274 // adjust relative to BrowseBox's output area
2275 Point aTopLeft( aRect.TopLeft() );
2276 if ( bRelToBrowser )
2277 {
2278 aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
2279 aTopLeft = ScreenToOutputPixel( aTopLeft );
2280 }
2281
2282 return Rectangle( aTopLeft, aRect.GetSize() );
2283 }
2284
2285 //-------------------------------------------------------------------
2286
GetRowRectPixel(long nRow,sal_Bool bRelToBrowser) const2287 Rectangle BrowseBox::GetRowRectPixel( long nRow, sal_Bool bRelToBrowser ) const
2288 {
2289 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2290
2291 // get the rectangle relative to DataWin
2292 Rectangle aRect;
2293 if ( nTopRow > nRow )
2294 // row is above visible area
2295 return aRect;
2296 aRect = Rectangle(
2297 Point( 0, GetDataRowHeight() * (nRow-nTopRow) ),
2298 Size( pDataWin->GetOutputSizePixel().Width(), GetDataRowHeight() ) );
2299 if ( aRect.TopLeft().Y() > pDataWin->GetOutputSizePixel().Height() )
2300 // row is below visible area
2301 return aRect;
2302
2303 // adjust relative to BrowseBox's output area
2304 Point aTopLeft( aRect.TopLeft() );
2305 if ( bRelToBrowser )
2306 {
2307 aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
2308 aTopLeft = ScreenToOutputPixel( aTopLeft );
2309 }
2310
2311 return Rectangle( aTopLeft, aRect.GetSize() );
2312 }
2313
2314 //-------------------------------------------------------------------
2315
ImplFieldRectPixel(long nRow,sal_uInt16 nColumnId) const2316 Rectangle BrowseBox::ImplFieldRectPixel( long nRow, sal_uInt16 nColumnId ) const
2317 {
2318 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2319
2320 // compute the X-coordinte realtiv to DataWin by accumulation
2321 long nColX = 0;
2322 sal_uInt16 nFrozenCols = FrozenColCount();
2323 sal_uInt16 nCol;
2324 for ( nCol = 0;
2325 nCol < pCols->Count() && pCols->GetObject(nCol)->GetId() != nColumnId;
2326 ++nCol )
2327 if ( pCols->GetObject(nCol)->IsFrozen() || nCol >= nFirstCol )
2328 nColX += pCols->GetObject(nCol)->Width();
2329
2330 if ( nCol >= pCols->Count() || ( nCol >= nFrozenCols && nCol < nFirstCol ) )
2331 return Rectangle();
2332
2333 // compute the Y-coordinate relative to DataWin
2334 long nRowY = GetDataRowHeight();
2335 if ( nRow != BROWSER_ENDOFSELECTION ) // #105497# OJ
2336 nRowY = ( nRow - nTopRow ) * GetDataRowHeight();
2337
2338 // assemble the Rectangle relative to DataWin
2339 return Rectangle(
2340 Point( nColX + MIN_COLUMNWIDTH, nRowY ),
2341 Size( pCols->GetObject(nCol)->Width() - 2*MIN_COLUMNWIDTH,
2342 GetDataRowHeight() - 1 ) );
2343 }
2344
2345 //-------------------------------------------------------------------
2346
GetRowAtYPosPixel(long nY,sal_Bool bRelToBrowser) const2347 long BrowseBox::GetRowAtYPosPixel( long nY, sal_Bool bRelToBrowser ) const
2348 {
2349 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2350
2351 // compute the Y-coord
2352 if ( bRelToBrowser )
2353 {
2354 Point aDataTopLeft = pDataWin->OutputToScreenPixel( Point(0, 0) );
2355 Point aTopLeft = OutputToScreenPixel( Point(0, 0) );
2356 nY -= aDataTopLeft.Y() - aTopLeft.Y();
2357 }
2358
2359 // no row there (e.g. in the header)
2360 if ( nY < 0 || nY >= pDataWin->GetOutputSizePixel().Height() )
2361 return -1;
2362
2363 return nY / GetDataRowHeight() + nTopRow;
2364 }
2365
2366 //-------------------------------------------------------------------
2367
GetFieldRect(sal_uInt16 nColumnId) const2368 Rectangle BrowseBox::GetFieldRect( sal_uInt16 nColumnId ) const
2369 {
2370 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2371
2372 return GetFieldRectPixel( nCurRow, nColumnId );
2373 }
2374
2375 //-------------------------------------------------------------------
2376
GetColumnAtXPosPixel(long nX,sal_Bool) const2377 sal_uInt16 BrowseBox::GetColumnAtXPosPixel( long nX, sal_Bool ) const
2378 {
2379 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2380
2381 // accumulate the withds of the visible columns
2382 long nColX = 0;
2383 sal_uInt16 nCol;
2384 for ( nCol = 0; nCol < sal_uInt16(pCols->Count()); ++nCol )
2385 {
2386 BrowserColumn *pCol = pCols->GetObject(nCol);
2387 if ( pCol->IsFrozen() || nCol >= nFirstCol )
2388 nColX += pCol->Width();
2389
2390 if ( nColX > nX )
2391 return nCol;
2392 }
2393
2394 return BROWSER_INVALIDID;
2395 }
2396
2397 //-------------------------------------------------------------------
2398
ReserveControlArea(sal_uInt16 nWidth)2399 void BrowseBox::ReserveControlArea( sal_uInt16 nWidth )
2400 {
2401 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2402
2403 if ( nWidth != nControlAreaWidth )
2404 {
2405 OSL_ENSURE(nWidth,"Control aera of 0 is not allowed, Use USHRT_MAX instead!");
2406 nControlAreaWidth = nWidth;
2407 UpdateScrollbars();
2408 }
2409 }
2410
2411 //-------------------------------------------------------------------
2412
GetControlArea() const2413 Rectangle BrowseBox::GetControlArea() const
2414 {
2415 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2416
2417 return Rectangle(
2418 Point( 0, GetOutputSizePixel().Height() - aHScroll.GetSizePixel().Height() ),
2419 Size( GetOutputSizePixel().Width() - aHScroll.GetSizePixel().Width(),
2420 aHScroll.GetSizePixel().Height() ) );
2421 }
2422
2423 //-------------------------------------------------------------------
2424
SetMode(BrowserMode nMode)2425 void BrowseBox::SetMode( BrowserMode nMode )
2426 {
2427 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2428
2429 #ifdef DBG_MIx
2430 Sound::Beep();
2431 nMode =
2432 // BROWSER_COLUMNSELECTION |
2433 // BROWSER_MULTISELECTION |
2434 BROWSER_THUMBDRAGGING |
2435 BROWSER_KEEPHIGHLIGHT |
2436 BROWSER_HLINES |
2437 BROWSER_VLINES |
2438 // BROWSER_HIDECURSOR |
2439 // BROWSER_NO_HSCROLL |
2440 // BROWSER_NO_SCROLLBACK |
2441 BROWSER_AUTO_VSCROLL |
2442 BROWSER_AUTO_HSCROLL |
2443 BROWSER_TRACKING_TIPS |
2444 // BROWSER_HIGHLIGHT_NONE |
2445 BROWSER_HEADERBAR_NEW |
2446 // BROWSER_AUTOSIZE_LASTCOL |
2447 0;
2448 #endif
2449
2450 getDataWindow()->bAutoHScroll = BROWSER_AUTO_HSCROLL == ( nMode & BROWSER_AUTO_HSCROLL );
2451 getDataWindow()->bAutoVScroll = BROWSER_AUTO_VSCROLL == ( nMode & BROWSER_AUTO_VSCROLL );
2452 getDataWindow()->bNoHScroll = BROWSER_NO_HSCROLL == ( nMode & BROWSER_NO_HSCROLL );
2453 getDataWindow()->bNoVScroll = BROWSER_NO_VSCROLL == ( nMode & BROWSER_NO_VSCROLL );
2454
2455 DBG_ASSERT( !( getDataWindow()->bAutoHScroll && getDataWindow()->bNoHScroll ),
2456 "BrowseBox::SetMode: AutoHScroll *and* NoHScroll?" );
2457 DBG_ASSERT( !( getDataWindow()->bAutoVScroll && getDataWindow()->bNoVScroll ),
2458 "BrowseBox::SetMode: AutoVScroll *and* NoVScroll?" );
2459 if ( getDataWindow()->bAutoHScroll )
2460 getDataWindow()->bNoHScroll = sal_False;
2461 if ( getDataWindow()->bAutoVScroll )
2462 getDataWindow()->bNoVScroll = sal_False;
2463
2464 if ( getDataWindow()->bNoHScroll )
2465 aHScroll.Hide();
2466
2467 nControlAreaWidth = USHRT_MAX;
2468
2469 getDataWindow()->bNoScrollBack =
2470 BROWSER_NO_SCROLLBACK == ( nMode & BROWSER_NO_SCROLLBACK);
2471
2472 long nOldRowSel = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel;
2473 MultiSelection *pOldRowSel = bMultiSelection ? uRow.pSel : 0;
2474 MultiSelection *pOldColSel = pColSel;
2475
2476 delete pVScroll;
2477
2478 bThumbDragging = ( nMode & BROWSER_THUMBDRAGGING ) == BROWSER_THUMBDRAGGING;
2479 bMultiSelection = ( nMode & BROWSER_MULTISELECTION ) == BROWSER_MULTISELECTION;
2480 bColumnCursor = ( nMode & BROWSER_COLUMNSELECTION ) == BROWSER_COLUMNSELECTION;
2481 bKeepHighlight = ( nMode & BROWSER_KEEPSELECTION ) == BROWSER_KEEPSELECTION;
2482
2483 bHideSelect = ((nMode & BROWSER_HIDESELECT) == BROWSER_HIDESELECT);
2484 // default: do not hide the cursor at all (untaken scrolling and such)
2485 bHideCursor = NO_CURSOR_HIDE;
2486
2487 if ( BROWSER_SMART_HIDECURSOR == ( nMode & BROWSER_SMART_HIDECURSOR ) )
2488 { // smart cursor hide overrules hard cursor hide
2489 bHideCursor = SMART_CURSOR_HIDE;
2490 }
2491 else if ( BROWSER_HIDECURSOR == ( nMode & BROWSER_HIDECURSOR ) )
2492 {
2493 bHideCursor = HARD_CURSOR_HIDE;
2494 }
2495
2496 m_bFocusOnlyCursor = ((nMode & BROWSER_CURSOR_WO_FOCUS) == 0);
2497
2498 bHLines = ( nMode & BROWSER_HLINESFULL ) == BROWSER_HLINESFULL;
2499 bVLines = ( nMode & BROWSER_VLINESFULL ) == BROWSER_VLINESFULL;
2500 bHDots = ( nMode & BROWSER_HLINESDOTS ) == BROWSER_HLINESDOTS;
2501 bVDots = ( nMode & BROWSER_VLINESDOTS ) == BROWSER_VLINESDOTS;
2502
2503 WinBits nVScrollWinBits =
2504 WB_VSCROLL | ( ( nMode & BROWSER_THUMBDRAGGING ) ? WB_DRAG : 0 );
2505 pVScroll = ( nMode & BROWSER_TRACKING_TIPS ) == BROWSER_TRACKING_TIPS
2506 ? new BrowserScrollBar( this, nVScrollWinBits,
2507 (BrowserDataWin*) pDataWin )
2508 : new ScrollBar( this, nVScrollWinBits );
2509 pVScroll->SetLineSize( 1 );
2510 pVScroll->SetPageSize(1);
2511 pVScroll->SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
2512 pVScroll->SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
2513
2514 getDataWindow()->bAutoSizeLastCol =
2515 BROWSER_AUTOSIZE_LASTCOL == ( nMode & BROWSER_AUTOSIZE_LASTCOL );
2516 getDataWindow()->bOwnDataChangedHdl =
2517 BROWSER_OWN_DATACHANGED == ( nMode & BROWSER_OWN_DATACHANGED );
2518
2519 // Headerbar erzeugen, was passiert, wenn eine erzeugt werden mu� und schon Spalten bestehen ?
2520 if ( BROWSER_HEADERBAR_NEW == ( nMode & BROWSER_HEADERBAR_NEW ) )
2521 {
2522 if (!getDataWindow()->pHeaderBar)
2523 getDataWindow()->pHeaderBar = CreateHeaderBar( this );
2524 }
2525 else
2526 {
2527 DELETEZ(getDataWindow()->pHeaderBar);
2528 }
2529
2530
2531
2532 if ( bColumnCursor )
2533 {
2534 pColSel = pOldColSel ? pOldColSel : new MultiSelection;
2535 pColSel->SetTotalRange( Range( 0, pCols->Count()-1 ) );
2536 }
2537 else
2538 {
2539 pColSel = 0;
2540 delete pColSel;
2541 }
2542
2543 if ( bMultiSelection )
2544 {
2545 if ( pOldRowSel )
2546 uRow.pSel = pOldRowSel;
2547 else
2548 uRow.pSel = new MultiSelection;
2549 }
2550 else
2551 {
2552 uRow.nSel = nOldRowSel;
2553 delete pOldRowSel;
2554 }
2555
2556 if ( bBootstrapped )
2557 {
2558 StateChanged( STATE_CHANGE_INITSHOW );
2559 if ( bMultiSelection && !pOldRowSel &&
2560 nOldRowSel != BROWSER_ENDOFSELECTION )
2561 uRow.pSel->Select( nOldRowSel );
2562 }
2563
2564 if ( pDataWin )
2565 pDataWin->Invalidate();
2566
2567 // kein Cursor auf Handle-Column
2568 if ( nCurColId == 0 )
2569 nCurColId = GetColumnId( 1 );
2570
2571 m_nCurrentMode = nMode;
2572 }
2573
2574 //-------------------------------------------------------------------
2575
VisibleRowsChanged(long,sal_uInt16)2576 void BrowseBox::VisibleRowsChanged( long, sal_uInt16 )
2577 {
2578 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2579
2580 // Das alte Verhalten: NumRows automatisch korrigieren:
2581 if ( nRowCount < GetRowCount() )
2582 {
2583 RowInserted(nRowCount,GetRowCount() - nRowCount,sal_False);
2584 }
2585 else if ( nRowCount > GetRowCount() )
2586 {
2587 RowRemoved(nRowCount-(nRowCount - GetRowCount()),nRowCount - GetRowCount(),sal_False);
2588 }
2589 }
2590
2591 //-------------------------------------------------------------------
2592
IsCursorMoveAllowed(long,sal_uInt16) const2593 sal_Bool BrowseBox::IsCursorMoveAllowed( long, sal_uInt16 ) const
2594
2595 /* [Beschreibung]
2596
2597 Diese virtuelle Methode wird immer gerufen bevor der Cursor direkt
2598 bewegt werden soll. Durch 'return sal_False' kann verhindert werden, da\s
2599 dies geschieht, wenn z.B. ein Datensatz irgendwelchen Rules widerspricht.
2600
2601 Diese Methode wird nicht gerufen, wenn die Cursorbewegung durch
2602 ein L"oschen oder Einf"ugen (einer Zeile/Spalte) ausgel"ost wird, also
2603 genaugenommen nur eine Cursor-Korrektur vorliegt.
2604
2605 Die Basisimplementierung liefert derzeit immer sal_True.
2606 */
2607
2608 {
2609 return sal_True;
2610 }
2611
2612 //-------------------------------------------------------------------
2613
GetDataRowHeight() const2614 long BrowseBox::GetDataRowHeight() const
2615 {
2616 return CalcZoom(nDataRowHeight ? nDataRowHeight : ImpGetDataRowHeight());
2617 }
2618
2619 //-------------------------------------------------------------------
2620
GetEventWindow() const2621 Window& BrowseBox::GetEventWindow() const
2622 {
2623 return *getDataWindow()->pEventWin;
2624 }
2625
2626 //-------------------------------------------------------------------
2627
CreateHeaderBar(BrowseBox * pParent)2628 BrowserHeader* BrowseBox::CreateHeaderBar( BrowseBox* pParent )
2629 {
2630 BrowserHeader* pNewBar = new BrowserHeader( pParent );
2631 pNewBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
2632 return pNewBar;
2633 }
2634
SetHeaderBar(BrowserHeader * pHeaderBar)2635 void BrowseBox::SetHeaderBar( BrowserHeader* pHeaderBar )
2636 {
2637 delete ( (BrowserDataWin*)pDataWin )->pHeaderBar;
2638 ( (BrowserDataWin*)pDataWin )->pHeaderBar = pHeaderBar;
2639 ( (BrowserDataWin*)pDataWin )->pHeaderBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
2640 }
2641 //-------------------------------------------------------------------
2642
2643 #ifdef DBG_UTIL
BrowseBoxCheckInvariants(const void * pVoid)2644 const char* BrowseBoxCheckInvariants( const void * pVoid )
2645 {
2646 const BrowseBox * p = (const BrowseBox *)pVoid;
2647
2648 if (p->nRowCount < 0) return "BrowseBox: nRowCount < 0";
2649 if (p->nTopRow < 0) return "BrowseBox: nTopRow < 0";
2650 if (p->nTopRow >= p->nRowCount && p->nRowCount != 0) return "BrowseBox: nTopRow >= nRowCount && nRowCount != 0";
2651 if (p->nCurRow < -1) return "BrowseBox: nCurRow < -1";
2652 if (p->nCurRow > p->nRowCount) return "BrowseBox: nCurRow > nRowCount";
2653
2654 // Leider waehrend der Bearbeitung nicht immer der Fall:
2655 //if (p->nCurRow < 0 && p->nRowCount != 0) return "nCurRow < 0 && nRowCount != 0";
2656 //if (p->nCurRow >= p->nRowCount && p->nRowCount != 0) return "nCurRow >= nRowCount && nRowCount != 0";
2657
2658 return NULL;
2659 }
2660 #endif
2661
2662 //-------------------------------------------------------------------
GetTitleHeight() const2663 long BrowseBox::GetTitleHeight() const
2664 {
2665 long nHeight;
2666 // ask the header bar for the text height (if possible), as the header bar's font is adjusted with
2667 // our (and the header's) zoom factor
2668 HeaderBar* pHeaderBar = ( (BrowserDataWin*)pDataWin )->pHeaderBar;
2669 if ( pHeaderBar )
2670 nHeight = pHeaderBar->GetTextHeight();
2671 else
2672 nHeight = GetTextHeight();
2673
2674 return nTitleLines ? nTitleLines * nHeight + 4 : 0;
2675 }
2676
2677 //-------------------------------------------------------------------
CalcReverseZoom(long nVal)2678 long BrowseBox::CalcReverseZoom(long nVal)
2679 {
2680 if (IsZoom())
2681 {
2682 const Fraction& rZoom = GetZoom();
2683 double n = (double)nVal;
2684 n *= (double)rZoom.GetDenominator();
2685 n /= (double)rZoom.GetNumerator();
2686 nVal = n>0 ? (long)(n + 0.5) : -(long)(-n + 0.5);
2687 }
2688
2689 return nVal;
2690 }
2691
2692 //-------------------------------------------------------------------
GetHeaderBar() const2693 HeaderBar* BrowseBox::GetHeaderBar() const
2694 {
2695 return getDataWindow()->pHeaderBar;
2696 }
2697 //-------------------------------------------------------------------
2698
CursorMoved()2699 void BrowseBox::CursorMoved()
2700 {
2701 // before implementing more here, please adjust the EditBrowseBox
2702 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2703
2704 if ( isAccessibleAlive() && HasFocus() )
2705 commitTableEvent(
2706 ACTIVE_DESCENDANT_CHANGED,
2707 makeAny( CreateAccessibleCell( GetCurRow(),GetColumnPos( GetCurColumnId() ) ) ),
2708 Any()
2709 );
2710 }
2711
2712 //-------------------------------------------------------------------
2713
LoseFocus()2714 void BrowseBox::LoseFocus()
2715 {
2716 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2717 DBG_TRACE1( "BrowseBox: %p->LoseFocus", this );
2718
2719 if ( bHasFocus )
2720 {
2721 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
2722 DoHideCursor( "LoseFocus" );
2723
2724 if ( !bKeepHighlight )
2725 {
2726 ToggleSelection();
2727 bSelectionIsVisible = sal_False;
2728 }
2729
2730 bHasFocus = sal_False;
2731 }
2732 Control::LoseFocus();
2733 }
2734
2735 //-------------------------------------------------------------------
2736
GetFocus()2737 void BrowseBox::GetFocus()
2738 {
2739 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2740 DBG_TRACE1( "BrowseBox: %p->GetFocus", this );
2741
2742 if ( !bHasFocus )
2743 {
2744 if ( !bSelectionIsVisible )
2745 {
2746 bSelectionIsVisible = sal_True;
2747 if ( bBootstrapped )
2748 ToggleSelection();
2749 }
2750
2751 bHasFocus = sal_True;
2752 DoShowCursor( "GetFocus" );
2753 }
2754 Control::GetFocus();
2755 }
2756
2757
2758