Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <svtools/brwbox.hxx>
21 : #include <svtools/brwhead.hxx>
22 : #include <o3tl/numeric.hxx>
23 : #include "datwin.hxx"
24 : #include <tools/debug.hxx>
25 : #include <tools/stream.hxx>
26 :
27 : #include <functional>
28 : #include <algorithm>
29 : #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
30 : #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
31 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
32 : #include <com/sun/star/accessibility/XAccessible.hpp>
33 : #include <tools/multisel.hxx>
34 : #include "brwimpl.hxx"
35 :
36 :
37 : #define SCROLL_FLAGS (SCROLL_CLIP | SCROLL_NOCHILDREN)
38 : #define getDataWindow() (static_cast<BrowserDataWin*>(pDataWin))
39 :
40 : using namespace com::sun::star::accessibility::AccessibleEventId;
41 : using namespace com::sun::star::accessibility::AccessibleTableModelChangeType;
42 : using com::sun::star::accessibility::AccessibleTableModelChange;
43 : using com::sun::star::lang::XComponent;
44 : using namespace ::com::sun::star::uno;
45 : using namespace svt;
46 :
47 : namespace
48 : {
49 0 : void disposeAndClearHeaderCell(::svt::BrowseBoxImpl::THeaderCellMap& _rHeaderCell)
50 : {
51 : ::std::for_each(
52 : _rHeaderCell.begin(),
53 : _rHeaderCell.end(),
54 : ::svt::BrowseBoxImpl::THeaderCellMapFunctorDispose()
55 0 : );
56 0 : _rHeaderCell.clear();
57 0 : }
58 : }
59 :
60 :
61 :
62 41 : void BrowseBox::ConstructImpl( BrowserMode nMode )
63 : {
64 : OSL_TRACE( "BrowseBox: %p->ConstructImpl", this );
65 41 : bMultiSelection = false;
66 41 : pColSel = 0;
67 41 : pDataWin = 0;
68 41 : pVScroll = 0;
69 :
70 41 : pDataWin = new BrowserDataWin( this );
71 41 : pCols = new BrowserColumns;
72 41 : m_pImpl.reset( new ::svt::BrowseBoxImpl() );
73 :
74 41 : aGridLineColor = Color( COL_LIGHTGRAY );
75 41 : InitSettings_Impl( this );
76 41 : InitSettings_Impl( pDataWin );
77 :
78 41 : bBootstrapped = false;
79 41 : nDataRowHeight = 0;
80 41 : nTitleLines = 1;
81 41 : nFirstCol = 0;
82 41 : nTopRow = 0;
83 41 : nCurRow = BROWSER_ENDOFSELECTION;
84 41 : nCurColId = 0;
85 41 : bResizing = false;
86 41 : bSelect = false;
87 41 : bSelecting = false;
88 41 : bScrolling = false;
89 41 : bSelectionIsVisible = false;
90 41 : bNotToggleSel = false;
91 41 : bRowDividerDrag = false;
92 41 : bHit = false;
93 41 : mbInteractiveRowHeight = false;
94 41 : bHideSelect = false;
95 41 : bHideCursor = TRISTATE_FALSE;
96 41 : nRowCount = 0;
97 41 : m_bFocusOnlyCursor = true;
98 41 : m_aCursorColor = COL_TRANSPARENT;
99 41 : m_nCurrentMode = 0;
100 41 : nControlAreaWidth = USHRT_MAX;
101 41 : uRow.nSel = BROWSER_ENDOFSELECTION;
102 :
103 41 : aHScroll.SetLineSize(1);
104 41 : aHScroll.SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
105 41 : aHScroll.SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
106 41 : pDataWin->Show();
107 :
108 41 : SetMode( nMode );
109 41 : bSelectionIsVisible = bKeepHighlight;
110 41 : bHasFocus = HasChildPathFocus();
111 : getDataWindow()->nCursorHidden =
112 41 : ( bHasFocus ? 0 : 1 ) + ( GetUpdateMode() ? 0 : 1 );
113 41 : }
114 :
115 :
116 :
117 41 : BrowseBox::BrowseBox( vcl::Window* pParent, WinBits nBits, BrowserMode nMode )
118 : :Control( pParent, nBits | WB_3DLOOK )
119 : ,DragSourceHelper( this )
120 : ,DropTargetHelper( this )
121 41 : ,aHScroll( this, WinBits( WB_HSCROLL ) )
122 : {
123 41 : ConstructImpl( nMode );
124 41 : }
125 :
126 :
127 :
128 0 : BrowseBox::BrowseBox( vcl::Window* pParent, const ResId& rId, BrowserMode nMode )
129 : :Control( pParent, rId )
130 : ,DragSourceHelper( this )
131 : ,DropTargetHelper( this )
132 0 : ,aHScroll( this, WinBits(WB_HSCROLL) )
133 : {
134 0 : ConstructImpl(nMode);
135 0 : }
136 :
137 :
138 82 : BrowseBox::~BrowseBox()
139 : {
140 : OSL_TRACE( "BrowseBox: %p~", this );
141 :
142 41 : if ( m_pImpl->m_pAccessible )
143 : {
144 0 : disposeAndClearHeaderCell(m_pImpl->m_aColHeaderCellMap);
145 0 : disposeAndClearHeaderCell(m_pImpl->m_aRowHeaderCellMap);
146 0 : m_pImpl->m_pAccessible->dispose();
147 : }
148 :
149 41 : Hide();
150 41 : delete getDataWindow()->pHeaderBar;
151 41 : delete getDataWindow()->pCornerWin;
152 41 : delete pDataWin;
153 41 : delete pVScroll;
154 :
155 : // free columns-space
156 41 : for ( size_t i = 0, n = pCols->size(); i < n; ++i )
157 0 : delete (*pCols)[ i ];
158 41 : pCols->clear();
159 41 : delete pCols;
160 41 : delete pColSel;
161 41 : if ( bMultiSelection )
162 41 : delete uRow.pSel;
163 41 : }
164 :
165 :
166 :
167 246 : short BrowseBox::GetCursorHideCount() const
168 : {
169 246 : return getDataWindow()->nCursorHidden;
170 : }
171 :
172 :
173 :
174 618 : void BrowseBox::DoShowCursor( const char * )
175 : {
176 618 : short nHiddenCount = --getDataWindow()->nCursorHidden;
177 618 : if (PaintCursorIfHiddenOnce())
178 : {
179 172 : if (1 == nHiddenCount)
180 123 : DrawCursor();
181 : }
182 : else
183 : {
184 446 : if (0 == nHiddenCount)
185 0 : DrawCursor();
186 : }
187 618 : }
188 :
189 :
190 :
191 618 : void BrowseBox::DoHideCursor( const char * )
192 : {
193 618 : short nHiddenCount = ++getDataWindow()->nCursorHidden;
194 618 : if (PaintCursorIfHiddenOnce())
195 : {
196 172 : if (2 == nHiddenCount)
197 123 : DrawCursor();
198 : }
199 : else
200 : {
201 446 : if (1 == nHiddenCount)
202 0 : DrawCursor();
203 : }
204 618 : }
205 :
206 :
207 :
208 128 : void BrowseBox::SetRealRowCount( const OUString &rRealRowCount )
209 : {
210 128 : getDataWindow()->aRealRowCount = rRealRowCount;
211 128 : }
212 :
213 :
214 :
215 0 : void BrowseBox::SetFont( const vcl::Font& rNewFont )
216 : {
217 0 : pDataWin->SetFont( rNewFont );
218 0 : ImpGetDataRowHeight();
219 0 : }
220 :
221 :
222 :
223 171 : sal_uLong BrowseBox::GetDefaultColumnWidth( const OUString& _rText ) const
224 : {
225 171 : return GetDataWindow().GetTextWidth( _rText ) + GetDataWindow().GetTextWidth(OUString('0')) * 4;
226 : }
227 :
228 :
229 :
230 68 : void BrowseBox::InsertHandleColumn( sal_uLong nWidth )
231 : {
232 :
233 : #if OSL_DEBUG_LEVEL > 0
234 : OSL_ENSURE( ColCount() == 0 || (*pCols)[0]->GetId() != HandleColumnId , "BrowseBox::InsertHandleColumn: there is already a handle column" );
235 : {
236 : BrowserColumns::iterator iCol = pCols->begin();
237 : const BrowserColumns::iterator colsEnd = pCols->end();
238 : if ( iCol < colsEnd )
239 : for (++iCol; iCol < colsEnd; ++iCol)
240 : OSL_ENSURE( (*iCol)->GetId() != HandleColumnId, "BrowseBox::InsertHandleColumn: there is a non-Handle column with handle ID" );
241 : }
242 : #endif
243 :
244 68 : pCols->insert( pCols->begin(), new BrowserColumn( 0, Image(), OUString(), nWidth, GetZoom() ) );
245 68 : FreezeColumn( 0 );
246 :
247 : // adjust headerbar
248 68 : if ( getDataWindow()->pHeaderBar )
249 : {
250 : getDataWindow()->pHeaderBar->SetPosSizePixel(
251 : Point(nWidth, 0),
252 204 : Size( GetOutputSizePixel().Width() - nWidth, GetTitleHeight() )
253 204 : );
254 : }
255 :
256 68 : ColumnInserted( 0 );
257 68 : }
258 :
259 :
260 :
261 140 : void BrowseBox::InsertDataColumn( sal_uInt16 nItemId, const OUString& rText,
262 : long nWidth, HeaderBarItemBits nBits, sal_uInt16 nPos )
263 : {
264 :
265 : OSL_ENSURE( nItemId != HandleColumnId, "BrowseBox::InsertDataColumn: nItemId is HandleColumnId" );
266 : OSL_ENSURE( nItemId != BROWSER_INVALIDID, "BrowseBox::InsertDataColumn: nItemId is reserved value BROWSER_INVALIDID" );
267 :
268 : #if OSL_DEBUG_LEVEL > 0
269 : {
270 : const BrowserColumns::iterator colsEnd = pCols->end();
271 : for (BrowserColumns::iterator iCol = pCols->begin(); iCol < colsEnd; ++iCol)
272 : OSL_ENSURE( (*iCol)->GetId() != nItemId, "BrowseBox::InsertDataColumn: duplicate column Id" );
273 : }
274 : #endif
275 :
276 140 : if ( nPos < pCols->size() )
277 : {
278 6 : BrowserColumns::iterator it = pCols->begin();
279 6 : ::std::advance( it, nPos );
280 6 : pCols->insert( it, new BrowserColumn( nItemId, Image(), rText, nWidth, GetZoom() ) );
281 : }
282 : else
283 : {
284 134 : pCols->push_back( new BrowserColumn( nItemId, Image(), rText, nWidth, GetZoom() ) );
285 : }
286 140 : if ( nCurColId == 0 )
287 0 : nCurColId = nItemId;
288 :
289 140 : if ( getDataWindow()->pHeaderBar )
290 : {
291 : // Handle column not in the header bar
292 140 : sal_uInt16 nHeaderPos = nPos;
293 140 : if (nHeaderPos != HEADERBAR_APPEND && GetColumnId(0) == HandleColumnId )
294 102 : nHeaderPos--;
295 : getDataWindow()->pHeaderBar->InsertItem(
296 140 : nItemId, rText, nWidth, nBits, nHeaderPos );
297 : }
298 140 : ColumnInserted( nPos );
299 140 : }
300 :
301 :
302 68 : sal_uInt16 BrowseBox::ToggleSelectedColumn()
303 : {
304 68 : sal_uInt16 nSelectedColId = BROWSER_INVALIDID;
305 68 : if ( pColSel && pColSel->GetSelectCount() )
306 : {
307 0 : DoHideCursor( "ToggleSelectedColumn" );
308 0 : ToggleSelection();
309 0 : nSelectedColId = (*pCols)[ pColSel->FirstSelected() ]->GetId();
310 0 : pColSel->SelectAll(false);
311 : }
312 68 : return nSelectedColId;
313 : }
314 :
315 68 : void BrowseBox::SetToggledSelectedColumn(sal_uInt16 _nSelectedColumnId)
316 : {
317 68 : if ( pColSel && _nSelectedColumnId != BROWSER_INVALIDID )
318 : {
319 0 : pColSel->Select( GetColumnPos( _nSelectedColumnId ) );
320 0 : ToggleSelection();
321 : OSL_TRACE( "BrowseBox: %p->SetToggledSelectedColumn", this );
322 0 : DoShowCursor( "SetToggledSelectedColumn" );
323 : }
324 68 : }
325 :
326 68 : void BrowseBox::FreezeColumn( sal_uInt16 nItemId, bool bFreeze )
327 : {
328 :
329 : // never unfreeze the handle-column
330 68 : if ( nItemId == HandleColumnId && !bFreeze )
331 0 : return;
332 :
333 : // get the position in the current array
334 68 : size_t nItemPos = GetColumnPos( nItemId );
335 68 : if ( nItemPos >= pCols->size() )
336 : // not available!
337 0 : return;
338 :
339 : // doesn't the state change?
340 68 : if ( (*pCols)[ nItemPos ]->IsFrozen() == bFreeze )
341 0 : return;
342 :
343 : // remark the column selection
344 68 : sal_uInt16 nSelectedColId = ToggleSelectedColumn();
345 :
346 : // freeze or unfreeze?
347 68 : if ( bFreeze )
348 : {
349 : // to be moved?
350 68 : if ( nItemPos != 0 && !(*pCols)[ nItemPos-1 ]->IsFrozen() )
351 : {
352 : // move to the right of the last frozen column
353 0 : sal_uInt16 nFirstScrollable = FrozenColCount();
354 0 : BrowserColumn *pColumn = (*pCols)[ nItemPos ];
355 0 : BrowserColumns::iterator it = pCols->begin();
356 0 : ::std::advance( it, nItemPos );
357 0 : pCols->erase( it );
358 0 : nItemPos = nFirstScrollable;
359 0 : it = pCols->begin();
360 0 : ::std::advance( it, nItemPos );
361 0 : pCols->insert( it, pColumn );
362 : }
363 :
364 : // adjust the number of the first scrollable and visible column
365 68 : if ( nFirstCol <= nItemPos )
366 68 : nFirstCol = nItemPos + 1;
367 : }
368 : else
369 : {
370 : // to be moved?
371 0 : if ( (sal_Int32)nItemPos != FrozenColCount()-1 )
372 : {
373 : // move to the leftmost scrollable column
374 0 : sal_uInt16 nFirstScrollable = FrozenColCount();
375 0 : BrowserColumn *pColumn = (*pCols)[ nItemPos ];
376 0 : BrowserColumns::iterator it = pCols->begin();
377 0 : ::std::advance( it, nItemPos );
378 0 : pCols->erase( it );
379 0 : nItemPos = nFirstScrollable;
380 0 : it = pCols->begin();
381 0 : ::std::advance( it, nItemPos );
382 0 : pCols->insert( it, pColumn );
383 : }
384 :
385 : // adjust the number of the first scrollable and visible column
386 0 : nFirstCol = nItemPos;
387 : }
388 :
389 : // toggle the freeze-state of the column
390 68 : (*pCols)[ nItemPos ]->Freeze( bFreeze );
391 :
392 : // align the scrollbar-range
393 68 : UpdateScrollbars();
394 :
395 : // repaint
396 68 : Control::Invalidate();
397 68 : getDataWindow()->Invalidate();
398 :
399 : // remember the column selection
400 68 : SetToggledSelectedColumn(nSelectedColId);
401 : }
402 :
403 :
404 :
405 0 : void BrowseBox::SetColumnPos( sal_uInt16 nColumnId, sal_uInt16 nPos )
406 : {
407 : // never set pos of the handle column
408 0 : if ( nColumnId == HandleColumnId )
409 0 : return;
410 :
411 : // get the position in the current array
412 0 : sal_uInt16 nOldPos = GetColumnPos( nColumnId );
413 0 : if ( nOldPos >= pCols->size() )
414 : // not available!
415 0 : return;
416 :
417 : // does the state change?
418 0 : if (nOldPos != nPos)
419 : {
420 : // remark the column selection
421 0 : sal_uInt16 nSelectedColId = ToggleSelectedColumn();
422 :
423 : // determine old column area
424 0 : Size aDataWinSize( pDataWin->GetSizePixel() );
425 0 : if ( getDataWindow()->pHeaderBar )
426 0 : aDataWinSize.Height() += getDataWindow()->pHeaderBar->GetSizePixel().Height();
427 :
428 0 : Rectangle aFromRect( GetFieldRect( nColumnId) );
429 0 : aFromRect.Right() += 2*MIN_COLUMNWIDTH;
430 :
431 0 : sal_uInt16 nNextPos = nOldPos + 1;
432 0 : if ( nOldPos > nPos )
433 0 : nNextPos = nOldPos - 1;
434 :
435 0 : BrowserColumn *pNextCol = (*pCols)[ nNextPos ];
436 0 : Rectangle aNextRect(GetFieldRect( pNextCol->GetId() ));
437 :
438 : // move column internally
439 : {
440 0 : BrowserColumns::iterator it = pCols->begin();
441 0 : ::std::advance( it, nOldPos );
442 0 : BrowserColumn* pTemp = *it;
443 0 : pCols->erase( it );
444 0 : it = pCols->begin();
445 0 : ::std::advance( it, nPos );
446 0 : pCols->insert( it, pTemp );
447 : }
448 :
449 : // determine new column area
450 0 : Rectangle aToRect( GetFieldRect( nColumnId ) );
451 0 : aToRect.Right() += 2*MIN_COLUMNWIDTH;
452 :
453 : // do scroll, let redraw
454 0 : if( pDataWin->GetBackground().IsScrollable() )
455 : {
456 0 : long nScroll = -aFromRect.GetWidth();
457 0 : Rectangle aScrollArea;
458 0 : if ( nOldPos > nPos )
459 : {
460 0 : long nFrozenWidth = GetFrozenWidth();
461 0 : if ( aToRect.Left() < nFrozenWidth )
462 0 : aToRect.Left() = nFrozenWidth;
463 0 : aScrollArea = Rectangle(Point(aToRect.Left(),0),
464 0 : Point(aNextRect.Right(),aDataWinSize.Height()));
465 0 : nScroll *= -1; // reverse direction
466 : }
467 : else
468 0 : aScrollArea = Rectangle(Point(aNextRect.Left(),0),
469 0 : Point(aToRect.Right(),aDataWinSize.Height()));
470 :
471 0 : pDataWin->Scroll( nScroll, 0, aScrollArea );
472 0 : aToRect.Top() = 0;
473 0 : aToRect.Bottom() = aScrollArea.Bottom();
474 0 : Invalidate( aToRect );
475 : }
476 : else
477 0 : pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
478 :
479 : // adjust header bar positions
480 0 : if ( getDataWindow()->pHeaderBar )
481 : {
482 0 : sal_uInt16 nNewPos = nPos;
483 0 : if ( GetColumnId(0) == HandleColumnId )
484 0 : --nNewPos;
485 0 : getDataWindow()->pHeaderBar->MoveItem(nColumnId,nNewPos);
486 : }
487 : // remember the column selection
488 0 : SetToggledSelectedColumn(nSelectedColId);
489 :
490 0 : if ( isAccessibleAlive() )
491 : {
492 : commitTableEvent(
493 : TABLE_MODEL_CHANGED,
494 : makeAny( AccessibleTableModelChange(
495 : DELETE,
496 : 0,
497 0 : GetRowCount(),
498 : nOldPos,
499 : nOldPos
500 : )
501 : ),
502 : Any()
503 0 : );
504 :
505 : commitTableEvent(
506 : TABLE_MODEL_CHANGED,
507 : makeAny( AccessibleTableModelChange(
508 : INSERT,
509 : 0,
510 0 : GetRowCount(),
511 : nPos,
512 : nPos
513 : )
514 : ),
515 : Any()
516 0 : );
517 : }
518 : }
519 :
520 : }
521 :
522 :
523 :
524 0 : void BrowseBox::SetColumnTitle( sal_uInt16 nItemId, const OUString& rTitle )
525 : {
526 :
527 : // never set title of the handle-column
528 0 : if ( nItemId == HandleColumnId )
529 0 : return;
530 :
531 : // get the position in the current array
532 0 : sal_uInt16 nItemPos = GetColumnPos( nItemId );
533 0 : if ( nItemPos >= pCols->size() )
534 : // not available!
535 0 : return;
536 :
537 : // does the state change?
538 0 : BrowserColumn *pCol = (*pCols)[ nItemPos ];
539 0 : if ( pCol->Title() != rTitle )
540 : {
541 0 : OUString sNew(rTitle);
542 0 : OUString sOld(pCol->Title());
543 :
544 0 : pCol->Title() = rTitle;
545 :
546 : // adjust headerbar column
547 0 : if ( getDataWindow()->pHeaderBar )
548 0 : getDataWindow()->pHeaderBar->SetItemText( nItemId, rTitle );
549 : else
550 : {
551 : // redraw visible columns
552 0 : if ( GetUpdateMode() && ( pCol->IsFrozen() || nItemPos > nFirstCol ) )
553 : Invalidate( Rectangle( Point(0,0),
554 0 : Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
555 : }
556 :
557 0 : if ( isAccessibleAlive() )
558 : {
559 : commitTableEvent( TABLE_COLUMN_DESCRIPTION_CHANGED,
560 : makeAny( sNew ),
561 : makeAny( sOld )
562 0 : );
563 0 : }
564 : }
565 : }
566 :
567 :
568 :
569 0 : void BrowseBox::SetColumnWidth( sal_uInt16 nItemId, sal_uLong nWidth )
570 : {
571 :
572 : // get the position in the current array
573 0 : size_t nItemPos = GetColumnPos( nItemId );
574 0 : if ( nItemPos >= pCols->size() )
575 0 : return;
576 :
577 : // does the state change?
578 0 : nWidth = QueryColumnResize( nItemId, nWidth );
579 0 : if ( nWidth >= LONG_MAX || (*pCols)[ nItemPos ]->Width() != nWidth )
580 : {
581 0 : long nOldWidth = (*pCols)[ nItemPos ]->Width();
582 :
583 : // adjust last column, if necessary
584 0 : if ( IsVisible() && nItemPos == pCols->size() - 1 )
585 : {
586 0 : long nMaxWidth = pDataWin->GetSizePixel().Width();
587 : nMaxWidth -= getDataWindow()->bAutoSizeLastCol
588 0 : ? GetFieldRect(nItemId).Left()
589 0 : : GetFrozenWidth();
590 0 : if ( static_cast<BrowserDataWin*>(pDataWin )->bAutoSizeLastCol || nWidth > (sal_uLong)nMaxWidth )
591 : {
592 0 : nWidth = nMaxWidth > 16 ? nMaxWidth : nOldWidth;
593 0 : nWidth = QueryColumnResize( nItemId, nWidth );
594 : }
595 : }
596 :
597 : // OV
598 : // In AutoSizeLastColumn(), we call SetColumnWidth with nWidth==0xffff.
599 : // Thus, check here, if the width has actually changed.
600 0 : if( (sal_uLong)nOldWidth == nWidth )
601 0 : return;
602 :
603 : // do we want to display the change immediately?
604 0 : bool bUpdate = GetUpdateMode() &&
605 0 : ( (*pCols)[ nItemPos ]->IsFrozen() || nItemPos >= nFirstCol );
606 :
607 0 : if ( bUpdate )
608 : {
609 : // Selection hidden
610 0 : DoHideCursor( "SetColumnWidth" );
611 0 : ToggleSelection();
612 : //!getDataWindow()->Update();
613 : //!Control::Update();
614 : }
615 :
616 : // set width
617 0 : (*pCols)[ nItemPos ]->SetWidth(nWidth, GetZoom());
618 :
619 : // scroll and invalidate
620 0 : if ( bUpdate )
621 : {
622 : // get X-Pos of the column changed
623 0 : long nX = 0;
624 0 : for ( sal_uInt16 nCol = 0; nCol < nItemPos; ++nCol )
625 : {
626 0 : BrowserColumn *pCol = (*pCols)[ nCol ];
627 0 : if ( pCol->IsFrozen() || nCol >= nFirstCol )
628 0 : nX += pCol->Width();
629 : }
630 :
631 : // actually scroll+invalidate
632 0 : pDataWin->SetClipRegion();
633 0 : bool bSelVis = bSelectionIsVisible;
634 0 : bSelectionIsVisible = false;
635 0 : if( GetBackground().IsScrollable() )
636 : {
637 :
638 0 : Rectangle aScrRect( nX + std::min( (sal_uLong)nOldWidth, nWidth ), 0,
639 0 : GetSizePixel().Width() , // the header is longer than the datawin
640 0 : pDataWin->GetPosPixel().Y() - 1 );
641 0 : Control::Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
642 0 : aScrRect.Bottom() = pDataWin->GetSizePixel().Height();
643 0 : getDataWindow()->Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
644 0 : Rectangle aInvRect( nX, 0, nX + std::max( nWidth, (sal_uLong)nOldWidth ), USHRT_MAX );
645 0 : Control::Invalidate( aInvRect, INVALIDATE_NOCHILDREN );
646 0 : static_cast<BrowserDataWin*>( pDataWin )->Invalidate( aInvRect );
647 : }
648 : else
649 : {
650 0 : Control::Invalidate( INVALIDATE_NOCHILDREN );
651 0 : getDataWindow()->Window::Invalidate( INVALIDATE_NOCHILDREN );
652 : }
653 :
654 :
655 : //!getDataWindow()->Update();
656 : //!Control::Update();
657 0 : bSelectionIsVisible = bSelVis;
658 0 : ToggleSelection();
659 0 : DoShowCursor( "SetColumnWidth" );
660 : }
661 0 : UpdateScrollbars();
662 :
663 : // adjust headerbar column
664 0 : if ( getDataWindow()->pHeaderBar )
665 : getDataWindow()->pHeaderBar->SetItemSize(
666 0 : nItemId ? nItemId : USHRT_MAX - 1, nWidth );
667 :
668 : // adjust last column
669 0 : if ( nItemPos != pCols->size() - 1 )
670 0 : AutoSizeLastColumn();
671 :
672 : }
673 : }
674 :
675 :
676 :
677 537 : void BrowseBox::AutoSizeLastColumn()
678 : {
679 537 : if ( getDataWindow()->bAutoSizeLastCol &&
680 0 : getDataWindow()->GetUpdateMode() )
681 : {
682 0 : sal_uInt16 nId = GetColumnId( (sal_uInt16)pCols->size() - 1 );
683 0 : SetColumnWidth( nId, LONG_MAX );
684 0 : ColumnResized( nId );
685 : }
686 537 : }
687 :
688 :
689 :
690 45 : void BrowseBox::RemoveColumn( sal_uInt16 nItemId )
691 : {
692 :
693 : // get column position
694 45 : sal_uInt16 nPos = GetColumnPos(nItemId);
695 45 : if ( nPos >= ColCount() )
696 : // not available
697 45 : return;
698 :
699 : // correct column selection
700 45 : if ( pColSel )
701 45 : pColSel->Remove( nPos );
702 :
703 : // correct column cursor
704 45 : if ( nCurColId == nItemId )
705 0 : nCurColId = 0;
706 :
707 : // delete column
708 45 : BrowserColumns::iterator it = pCols->begin();
709 45 : ::std::advance( it, nPos );
710 45 : delete *it;
711 45 : pCols->erase( it );
712 45 : if ( nFirstCol >= nPos && nFirstCol > FrozenColCount() )
713 : {
714 : OSL_ENSURE(nFirstCol > 0,"FirstCol must be greater zero!");
715 25 : --nFirstCol;
716 : }
717 :
718 : // handlecolumn not in headerbar
719 45 : if (nItemId)
720 : {
721 20 : if ( getDataWindow()->pHeaderBar )
722 20 : getDataWindow()->pHeaderBar->RemoveItem( nItemId );
723 : }
724 : else
725 : {
726 : // adjust headerbar
727 25 : if ( getDataWindow()->pHeaderBar )
728 : {
729 : getDataWindow()->pHeaderBar->SetPosSizePixel(
730 : Point(0, 0),
731 75 : Size( GetOutputSizePixel().Width(), GetTitleHeight() )
732 75 : );
733 : }
734 : }
735 :
736 : // correct vertical scrollbar
737 45 : UpdateScrollbars();
738 :
739 : // trigger repaint, if necessary
740 45 : if ( GetUpdateMode() )
741 : {
742 45 : getDataWindow()->Invalidate();
743 45 : Control::Invalidate();
744 45 : if ( getDataWindow()->bAutoSizeLastCol && nPos ==ColCount() )
745 0 : SetColumnWidth( GetColumnId( nPos - 1 ), LONG_MAX );
746 : }
747 :
748 45 : if ( isAccessibleAlive() )
749 : {
750 : commitTableEvent(
751 : TABLE_MODEL_CHANGED,
752 : makeAny( AccessibleTableModelChange( DELETE,
753 : 0,
754 0 : GetRowCount(),
755 : nPos,
756 : nPos
757 : )
758 : ),
759 : Any()
760 0 : );
761 :
762 : commitHeaderBarEvent(
763 : CHILD,
764 : Any(),
765 0 : makeAny( CreateAccessibleColumnHeader( nPos ) ),
766 : true
767 0 : );
768 : }
769 : }
770 :
771 :
772 :
773 43 : void BrowseBox::RemoveColumns()
774 : {
775 :
776 43 : size_t nOldCount = pCols->size();
777 :
778 : // remove all columns
779 206 : for ( size_t i = 0; i < nOldCount; ++i )
780 163 : delete (*pCols)[ i ];
781 43 : pCols->clear();
782 :
783 : // correct column selection
784 43 : if ( pColSel )
785 : {
786 43 : pColSel->SelectAll(false);
787 43 : pColSel->SetTotalRange( Range( 0, 0 ) );
788 : }
789 :
790 : // correct column cursor
791 43 : nCurColId = 0;
792 43 : nFirstCol = 0;
793 :
794 43 : if ( getDataWindow()->pHeaderBar )
795 43 : getDataWindow()->pHeaderBar->Clear( );
796 :
797 : // correct vertical scrollbar
798 43 : UpdateScrollbars();
799 :
800 : // trigger repaint if necessary
801 43 : if ( GetUpdateMode() )
802 : {
803 43 : getDataWindow()->Invalidate();
804 43 : Control::Invalidate();
805 : }
806 :
807 43 : if ( isAccessibleAlive() )
808 : {
809 0 : if ( pCols->size() != nOldCount )
810 : {
811 : // all columns should be removed, so we remove the column header bar and append it again
812 : // to avoid to notify every column remove
813 : commitBrowseBoxEvent(
814 : CHILD,
815 : Any(),
816 : makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR))
817 0 : );
818 :
819 : // and now append it again
820 : commitBrowseBoxEvent(
821 : CHILD,
822 : makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR)),
823 : Any()
824 0 : );
825 :
826 : // notify a table model change
827 : commitTableEvent(
828 : TABLE_MODEL_CHANGED,
829 : makeAny ( AccessibleTableModelChange( DELETE,
830 : 0,
831 0 : GetRowCount(),
832 : 0,
833 : nOldCount
834 : )
835 : ),
836 : Any()
837 0 : );
838 : }
839 : }
840 43 : }
841 :
842 :
843 :
844 0 : OUString BrowseBox::GetColumnTitle( sal_uInt16 nId ) const
845 : {
846 :
847 0 : sal_uInt16 nItemPos = GetColumnPos( nId );
848 0 : if ( nItemPos >= pCols->size() )
849 0 : return OUString();
850 0 : return (*pCols)[ nItemPos ]->Title();
851 : }
852 :
853 :
854 :
855 192 : long BrowseBox::GetRowCount() const
856 : {
857 192 : return nRowCount;
858 : }
859 :
860 :
861 :
862 47 : sal_uInt16 BrowseBox::ColCount() const
863 : {
864 :
865 47 : return (sal_uInt16) pCols->size();
866 : }
867 :
868 :
869 :
870 132 : long BrowseBox::ImpGetDataRowHeight() const
871 : {
872 :
873 132 : BrowseBox *pThis = (BrowseBox*)this;
874 132 : pThis->nDataRowHeight = pThis->CalcReverseZoom(pDataWin->GetTextHeight() + 2);
875 132 : pThis->Resize();
876 132 : getDataWindow()->Invalidate();
877 132 : return nDataRowHeight;
878 : }
879 :
880 :
881 :
882 91 : void BrowseBox::SetDataRowHeight( long nPixel )
883 : {
884 :
885 91 : nDataRowHeight = CalcReverseZoom(nPixel);
886 91 : Resize();
887 91 : getDataWindow()->Invalidate();
888 91 : }
889 :
890 :
891 :
892 0 : void BrowseBox::SetTitleLines( sal_uInt16 nLines )
893 : {
894 :
895 0 : nTitleLines = nLines;
896 0 : }
897 :
898 :
899 :
900 0 : long BrowseBox::ScrollColumns( long nCols )
901 : {
902 :
903 0 : if ( nFirstCol + nCols < 0 ||
904 0 : nFirstCol + nCols >= (long)pCols->size() )
905 0 : return 0;
906 :
907 : // implicitly hides cursor while scrolling
908 0 : StartScroll();
909 0 : bScrolling = true;
910 0 : bool bScrollable = pDataWin->GetBackground().IsScrollable();
911 0 : bool bInvalidateView = false;
912 :
913 : // scrolling one column to the right?
914 0 : if ( nCols == 1 )
915 : {
916 : // update internal value and scrollbar
917 0 : ++nFirstCol;
918 0 : aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
919 :
920 0 : if ( !bScrollable )
921 : {
922 0 : bInvalidateView = true;
923 : }
924 : else
925 : {
926 0 : long nDelta = (*pCols)[ nFirstCol-1 ]->Width();
927 0 : long nFrozenWidth = GetFrozenWidth();
928 :
929 : Rectangle aScrollRect( Point( nFrozenWidth + nDelta, 0 ),
930 0 : Size ( GetOutputSizePixel().Width() - nFrozenWidth - nDelta,
931 0 : GetTitleHeight() - 1
932 0 : ) );
933 :
934 : // scroll the header bar area (if there is no dedicated HeaderBar control)
935 0 : if ( !getDataWindow()->pHeaderBar && nTitleLines )
936 : {
937 : // actually scroll
938 0 : Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS );
939 :
940 : // invalidate the area of the column which was scrolled out to the left hand side
941 0 : Rectangle aInvalidateRect( aScrollRect );
942 0 : aInvalidateRect.Left() = nFrozenWidth;
943 0 : aInvalidateRect.Right() = nFrozenWidth + nDelta - 1;
944 0 : Invalidate( aInvalidateRect );
945 : }
946 :
947 : // scroll the data-area
948 0 : aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
949 :
950 : // actually scroll
951 0 : pDataWin->Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS );
952 :
953 : // invalidate the area of the column which was scrolled out to the left hand side
954 0 : aScrollRect.Left() = nFrozenWidth;
955 0 : aScrollRect.Right() = nFrozenWidth + nDelta - 1;
956 0 : getDataWindow()->Invalidate( aScrollRect );
957 : }
958 : }
959 :
960 : // scrolling one column to the left?
961 0 : else if ( nCols == -1 )
962 : {
963 0 : --nFirstCol;
964 0 : aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
965 :
966 0 : if ( !bScrollable )
967 : {
968 0 : bInvalidateView = true;
969 : }
970 : else
971 : {
972 0 : long nDelta = (*pCols)[ nFirstCol ]->Width();
973 0 : long nFrozenWidth = GetFrozenWidth();
974 :
975 : Rectangle aScrollRect( Point( nFrozenWidth, 0 ),
976 0 : Size ( GetOutputSizePixel().Width() - nFrozenWidth,
977 0 : GetTitleHeight() - 1
978 0 : ) );
979 :
980 : // scroll the header bar area (if there is no dedicated HeaderBar control)
981 0 : if ( !getDataWindow()->pHeaderBar && nTitleLines )
982 : {
983 0 : Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS );
984 : }
985 :
986 : // scroll the data-area
987 0 : aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
988 0 : pDataWin->Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS );
989 : }
990 : }
991 : else
992 : {
993 0 : if ( GetUpdateMode() )
994 : {
995 : Invalidate( Rectangle(
996 : Point( GetFrozenWidth(), 0 ),
997 0 : Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
998 : getDataWindow()->Invalidate( Rectangle(
999 : Point( GetFrozenWidth(), 0 ),
1000 0 : pDataWin->GetSizePixel() ) );
1001 : }
1002 :
1003 0 : nFirstCol = nFirstCol + (sal_uInt16)nCols;
1004 0 : aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
1005 : }
1006 :
1007 : // adjust external headerbar, if necessary
1008 0 : if ( getDataWindow()->pHeaderBar )
1009 : {
1010 0 : long nWidth = 0;
1011 0 : for ( size_t nCol = 0;
1012 0 : nCol < pCols->size() && nCol < nFirstCol;
1013 : ++nCol )
1014 : {
1015 : // not the handle column
1016 0 : if ( (*pCols)[ nCol ]->GetId() )
1017 0 : nWidth += (*pCols)[ nCol ]->Width();
1018 : }
1019 :
1020 0 : getDataWindow()->pHeaderBar->SetOffset( nWidth );
1021 : }
1022 :
1023 0 : if( bInvalidateView )
1024 : {
1025 0 : Control::Invalidate( INVALIDATE_NOCHILDREN );
1026 0 : pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1027 : }
1028 :
1029 : // implicitly show cursor after scrolling
1030 0 : if ( nCols )
1031 : {
1032 0 : getDataWindow()->Update();
1033 0 : Update();
1034 : }
1035 0 : bScrolling = false;
1036 0 : EndScroll();
1037 :
1038 0 : return nCols;
1039 : }
1040 :
1041 :
1042 :
1043 505 : long BrowseBox::ScrollRows( long nRows )
1044 : {
1045 :
1046 : // out of range?
1047 505 : if ( getDataWindow()->bNoScrollBack && nRows < 0 )
1048 0 : return 0;
1049 :
1050 : // compute new top row
1051 505 : long nTmpMin = std::min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
1052 :
1053 505 : long nNewTopRow = std::max( (long)nTmpMin, (long)0 );
1054 :
1055 505 : if ( nNewTopRow == nTopRow )
1056 505 : return 0;
1057 :
1058 : sal_uInt16 nVisibleRows =
1059 0 : (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
1060 :
1061 0 : VisibleRowsChanged(nNewTopRow, nVisibleRows);
1062 :
1063 : // compute new top row again (nTopRow might have changed!)
1064 0 : nTmpMin = std::min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
1065 :
1066 0 : nNewTopRow = std::max( (long)nTmpMin, (long)0 );
1067 :
1068 0 : StartScroll();
1069 :
1070 : // scroll area on screen and/or repaint
1071 0 : long nDeltaY = GetDataRowHeight() * ( nNewTopRow - nTopRow );
1072 0 : long nOldTopRow = nTopRow;
1073 0 : nTopRow = nNewTopRow;
1074 :
1075 0 : if ( GetUpdateMode() )
1076 : {
1077 0 : pVScroll->SetRange( Range( 0L, nRowCount ) );
1078 0 : pVScroll->SetThumbPos( nTopRow );
1079 :
1080 0 : if( pDataWin->GetBackground().IsScrollable() &&
1081 0 : std::abs( nDeltaY ) > 0 &&
1082 0 : std::abs( nDeltaY ) < pDataWin->GetSizePixel().Height() )
1083 : {
1084 0 : pDataWin->Scroll( 0, (short)-nDeltaY, SCROLL_FLAGS );
1085 : }
1086 : else
1087 0 : getDataWindow()->Invalidate();
1088 :
1089 0 : if ( nTopRow - nOldTopRow )
1090 0 : getDataWindow()->Update();
1091 : }
1092 :
1093 0 : EndScroll();
1094 :
1095 0 : return nTopRow - nOldTopRow;
1096 : }
1097 :
1098 :
1099 :
1100 50 : void BrowseBox::RowModified( long nRow, sal_uInt16 nColId )
1101 : {
1102 :
1103 50 : if ( !GetUpdateMode() )
1104 50 : return;
1105 :
1106 50 : Rectangle aRect;
1107 50 : if ( nColId == BROWSER_INVALIDID )
1108 : // invalidate the whole row
1109 4 : aRect = Rectangle( Point( 0, (nRow-nTopRow) * GetDataRowHeight() ),
1110 8 : Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
1111 : else
1112 : {
1113 : // invalidate the specific field
1114 46 : aRect = GetFieldRectPixel( nRow, nColId, false );
1115 : }
1116 50 : getDataWindow()->Invalidate( aRect );
1117 : }
1118 :
1119 :
1120 :
1121 4 : void BrowseBox::Clear()
1122 : {
1123 :
1124 : // adjust the total number of rows
1125 4 : DoHideCursor( "Clear" );
1126 4 : long nOldRowCount = nRowCount;
1127 4 : nRowCount = 0;
1128 4 : if(bMultiSelection)
1129 : {
1130 : assert(uRow.pSel);
1131 4 : *uRow.pSel = MultiSelection();
1132 : }
1133 : else
1134 0 : uRow.nSel = BROWSER_ENDOFSELECTION;
1135 4 : nCurRow = BROWSER_ENDOFSELECTION;
1136 4 : nTopRow = 0;
1137 4 : nCurColId = 0;
1138 :
1139 : // nFirstCol may not be reset, else the scrolling code will become confused.
1140 : // nFirstCol may only be changed when adding or deleting columns
1141 : // nFirstCol = 0; -> wrong!
1142 4 : aHScroll.SetThumbPos( 0 );
1143 4 : pVScroll->SetThumbPos( 0 );
1144 :
1145 4 : Invalidate();
1146 4 : UpdateScrollbars();
1147 4 : SetNoSelection();
1148 4 : DoShowCursor( "Clear" );
1149 4 : CursorMoved();
1150 :
1151 4 : if ( isAccessibleAlive() )
1152 : {
1153 : // all rows should be removed, so we remove the row header bar and append it again
1154 : // to avoid to notify every row remove
1155 0 : if ( nOldRowCount != nRowCount )
1156 : {
1157 : commitBrowseBoxEvent(
1158 : CHILD,
1159 : Any(),
1160 : makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) )
1161 0 : );
1162 :
1163 : // and now append it again
1164 : commitBrowseBoxEvent(
1165 : CHILD,
1166 : makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) ),
1167 : Any()
1168 0 : );
1169 :
1170 : // notify a table model change
1171 : commitTableEvent(
1172 : TABLE_MODEL_CHANGED,
1173 : makeAny( AccessibleTableModelChange( DELETE,
1174 : 0,
1175 : nOldRowCount,
1176 : 0,
1177 0 : GetColumnCount())
1178 : ),
1179 : Any()
1180 0 : );
1181 : }
1182 : }
1183 4 : }
1184 :
1185 2 : void BrowseBox::RowInserted( long nRow, long nNumRows, bool bDoPaint, bool bKeepSelection )
1186 : {
1187 :
1188 2 : if (nRow < 0)
1189 0 : nRow = 0;
1190 2 : else if (nRow > nRowCount) // maximal = nRowCount
1191 0 : nRow = nRowCount;
1192 :
1193 2 : if ( nNumRows <= 0 )
1194 2 : return;
1195 :
1196 : // adjust total row count
1197 2 : bool bLastRow = nRow >= nRowCount;
1198 2 : nRowCount += nNumRows;
1199 :
1200 2 : DoHideCursor( "RowInserted" );
1201 :
1202 : // must we paint the new rows?
1203 2 : long nOldCurRow = nCurRow;
1204 2 : Size aSz = pDataWin->GetOutputSizePixel();
1205 2 : if ( bDoPaint && nRow >= nTopRow &&
1206 0 : nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
1207 : {
1208 0 : long nY = (nRow-nTopRow) * GetDataRowHeight();
1209 0 : if ( !bLastRow )
1210 : {
1211 : // scroll down the rows behind the new row
1212 0 : pDataWin->SetClipRegion();
1213 0 : if( pDataWin->GetBackground().IsScrollable() )
1214 : {
1215 0 : pDataWin->Scroll( 0, GetDataRowHeight() * nNumRows,
1216 : Rectangle( Point( 0, nY ),
1217 0 : Size( aSz.Width(), aSz.Height() - nY ) ),
1218 0 : SCROLL_FLAGS );
1219 : }
1220 : else
1221 0 : pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1222 : }
1223 : else
1224 : // scroll would cause a repaint, so we must explicitly invalidate
1225 : pDataWin->Invalidate( Rectangle( Point( 0, nY ),
1226 0 : Size( aSz.Width(), nNumRows * GetDataRowHeight() ) ) );
1227 : }
1228 :
1229 : // correct top row if necessary
1230 2 : if ( nRow < nTopRow )
1231 0 : nTopRow += nNumRows;
1232 :
1233 : // adjust the selection
1234 2 : if ( bMultiSelection )
1235 2 : uRow.pSel->Insert( nRow, nNumRows );
1236 0 : else if ( uRow.nSel != BROWSER_ENDOFSELECTION && nRow <= uRow.nSel )
1237 0 : uRow.nSel += nNumRows;
1238 :
1239 : // adjust the cursor
1240 2 : if ( nCurRow == BROWSER_ENDOFSELECTION )
1241 2 : GoToRow( 0, false, bKeepSelection );
1242 0 : else if ( nRow <= nCurRow )
1243 0 : GoToRow( nCurRow += nNumRows, false, bKeepSelection );
1244 :
1245 : // adjust the vertical scrollbar
1246 2 : if ( bDoPaint )
1247 : {
1248 0 : UpdateScrollbars();
1249 0 : AutoSizeLastColumn();
1250 : }
1251 :
1252 2 : DoShowCursor( "RowInserted" );
1253 : // notify accessible that rows were inserted
1254 2 : if ( isAccessibleAlive() )
1255 : {
1256 : commitTableEvent(
1257 : TABLE_MODEL_CHANGED,
1258 : makeAny( AccessibleTableModelChange(
1259 : INSERT,
1260 : nRow,
1261 : nRow + nNumRows,
1262 : 0,
1263 0 : GetColumnCount()
1264 : )
1265 : ),
1266 : Any()
1267 0 : );
1268 :
1269 0 : for (sal_Int32 i = nRow+1 ; i <= nRowCount ; ++i)
1270 : {
1271 : commitHeaderBarEvent(
1272 : CHILD,
1273 0 : makeAny( CreateAccessibleRowHeader( i ) ),
1274 : Any(),
1275 : false
1276 0 : );
1277 : }
1278 : }
1279 :
1280 2 : if ( nCurRow != nOldCurRow )
1281 2 : CursorMoved();
1282 :
1283 : DBG_ASSERT(nRowCount > 0,"BrowseBox: nRowCount <= 0");
1284 : DBG_ASSERT(nCurRow >= 0,"BrowseBox: nCurRow < 0");
1285 : DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
1286 : }
1287 :
1288 :
1289 :
1290 0 : void BrowseBox::RowRemoved( long nRow, long nNumRows, bool bDoPaint )
1291 : {
1292 :
1293 0 : if ( nRow < 0 )
1294 0 : nRow = 0;
1295 0 : else if ( nRow >= nRowCount )
1296 0 : nRow = nRowCount - 1;
1297 :
1298 0 : if ( nNumRows <= 0 )
1299 0 : return;
1300 :
1301 0 : if ( nRowCount <= 0 )
1302 0 : return;
1303 :
1304 0 : if ( bDoPaint )
1305 : {
1306 : // hide cursor and selection
1307 : OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1308 0 : ToggleSelection();
1309 0 : DoHideCursor( "RowRemoved" );
1310 : }
1311 :
1312 : // adjust total row count
1313 0 : nRowCount -= nNumRows;
1314 0 : if (nRowCount < 0) nRowCount = 0;
1315 0 : long nOldCurRow = nCurRow;
1316 :
1317 : // adjust the selection
1318 0 : if ( bMultiSelection )
1319 : // uRow.pSel->Remove( nRow, nNumRows );
1320 0 : for ( long i = 0; i < nNumRows; i++ )
1321 0 : uRow.pSel->Remove( nRow );
1322 0 : else if ( nRow < uRow.nSel && uRow.nSel >= nNumRows )
1323 0 : uRow.nSel -= nNumRows;
1324 0 : else if ( nRow <= uRow.nSel )
1325 0 : uRow.nSel = BROWSER_ENDOFSELECTION;
1326 :
1327 : // adjust the cursor
1328 0 : if ( nRowCount == 0 ) // don't compare nRowCount with nNumRows as nNumRows already was subtracted from nRowCount
1329 0 : nCurRow = BROWSER_ENDOFSELECTION;
1330 0 : else if ( nRow < nCurRow )
1331 : {
1332 0 : nCurRow -= std::min( nCurRow - nRow, nNumRows );
1333 : // with the above nCurRow points a) to the first row after the removed block or b) to the same line
1334 : // as before, but moved up nNumRows
1335 : // case a) needs an additional correction if the last n lines were deleted, as 'the first row after the
1336 : // removed block' is an invalid position then
1337 : // FS - 09/28/99 - 68429
1338 0 : if (nCurRow == nRowCount)
1339 0 : --nCurRow;
1340 : }
1341 0 : else if( nRow == nCurRow && nCurRow == nRowCount )
1342 0 : nCurRow = nRowCount-1;
1343 :
1344 : // is the deleted row visible?
1345 0 : Size aSz = pDataWin->GetOutputSizePixel();
1346 0 : if ( nRow >= nTopRow &&
1347 0 : nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
1348 : {
1349 0 : if ( bDoPaint )
1350 : {
1351 : // scroll up the rows behind the deleted row
1352 : // if there are Rows behind
1353 0 : if (nRow < nRowCount)
1354 : {
1355 0 : long nY = (nRow-nTopRow) * GetDataRowHeight();
1356 0 : pDataWin->SetClipRegion();
1357 0 : if( pDataWin->GetBackground().IsScrollable() )
1358 : {
1359 0 : pDataWin->Scroll( 0, - (short) GetDataRowHeight() * nNumRows,
1360 0 : Rectangle( Point( 0, nY ), Size( aSz.Width(),
1361 0 : aSz.Height() - nY + nNumRows*GetDataRowHeight() ) ),
1362 0 : SCROLL_FLAGS );
1363 : }
1364 : else
1365 0 : pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1366 : }
1367 : else
1368 : {
1369 : // Repaint the Rect of the deleted row
1370 : Rectangle aRect(
1371 0 : Point( 0, (nRow-nTopRow)*GetDataRowHeight() ),
1372 0 : Size( pDataWin->GetSizePixel().Width(),
1373 0 : nNumRows * GetDataRowHeight() ) );
1374 0 : pDataWin->Invalidate( aRect );
1375 : }
1376 : }
1377 : }
1378 : // is the deleted row above of the visible area?
1379 0 : else if ( nRow < nTopRow )
1380 0 : nTopRow = nTopRow >= nNumRows ? nTopRow-nNumRows : 0;
1381 :
1382 0 : if ( bDoPaint )
1383 : {
1384 : // reshow cursor and selection
1385 0 : ToggleSelection();
1386 : OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1387 0 : DoShowCursor( "RowRemoved" );
1388 :
1389 : // adjust the vertical scrollbar
1390 0 : UpdateScrollbars();
1391 0 : AutoSizeLastColumn();
1392 : }
1393 :
1394 0 : if ( isAccessibleAlive() )
1395 : {
1396 0 : if ( nRowCount == 0 )
1397 : {
1398 : // all columns should be removed, so we remove the column header bar and append it again
1399 : // to avoid to notify every column remove
1400 : commitBrowseBoxEvent(
1401 : CHILD,
1402 : Any(),
1403 : makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) )
1404 0 : );
1405 :
1406 : // and now append it again
1407 : commitBrowseBoxEvent(
1408 : CHILD,
1409 : makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_ROWHEADERBAR)),
1410 : Any()
1411 0 : );
1412 : commitBrowseBoxEvent(
1413 : CHILD,
1414 : Any(),
1415 : makeAny( m_pImpl->getAccessibleTable() )
1416 0 : );
1417 :
1418 : // and now append it again
1419 : commitBrowseBoxEvent(
1420 : CHILD,
1421 : makeAny( m_pImpl->getAccessibleTable() ),
1422 : Any()
1423 0 : );
1424 : }
1425 : else
1426 : {
1427 : commitTableEvent(
1428 : TABLE_MODEL_CHANGED,
1429 : makeAny( AccessibleTableModelChange(
1430 : DELETE,
1431 : nRow,
1432 : nRow + nNumRows,
1433 : 0,
1434 0 : GetColumnCount()
1435 : )
1436 : ),
1437 : Any()
1438 0 : );
1439 :
1440 0 : for (sal_Int32 i = nRow+1 ; i <= (nRow+nNumRows) ; ++i)
1441 : {
1442 : commitHeaderBarEvent(
1443 : CHILD,
1444 : Any(),
1445 0 : makeAny( CreateAccessibleRowHeader( i ) ),
1446 : false
1447 0 : );
1448 : }
1449 : }
1450 : }
1451 :
1452 0 : if ( nOldCurRow != nCurRow )
1453 0 : CursorMoved();
1454 :
1455 : DBG_ASSERT(nRowCount >= 0,"BrowseBox: nRowCount < 0");
1456 : DBG_ASSERT(nCurRow >= 0 || nRowCount == 0,"BrowseBox: nCurRow < 0 && nRowCount != 0");
1457 : DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
1458 : }
1459 :
1460 :
1461 :
1462 0 : bool BrowseBox::GoToRow( long nRow)
1463 : {
1464 0 : return GoToRow(nRow, false, false);
1465 : }
1466 :
1467 :
1468 :
1469 4 : bool BrowseBox::GoToRow( long nRow, bool bRowColMove, bool bKeepSelection )
1470 : {
1471 :
1472 4 : long nOldCurRow = nCurRow;
1473 :
1474 : // nothing to do?
1475 4 : if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) )
1476 2 : return true;
1477 :
1478 : // out of range?
1479 2 : if ( nRow < 0 || nRow >= nRowCount )
1480 0 : return false;
1481 :
1482 : // not allowed?
1483 2 : if ( ( !bRowColMove && !IsCursorMoveAllowed( nRow, nCurColId ) ) )
1484 0 : return false;
1485 :
1486 2 : if ( getDataWindow()->bNoScrollBack && nRow < nTopRow )
1487 0 : nRow = nTopRow;
1488 :
1489 : // compute the last visible row
1490 2 : Size aSz( pDataWin->GetSizePixel() );
1491 2 : sal_uInt16 nVisibleRows = sal_uInt16( aSz.Height() / GetDataRowHeight() - 1 );
1492 2 : long nLastRow = nTopRow + nVisibleRows;
1493 :
1494 : // suspend Updates
1495 2 : getDataWindow()->EnterUpdateLock();
1496 :
1497 : // remove old highlight, if necessary
1498 2 : if ( !bMultiSelection && !bKeepSelection )
1499 0 : ToggleSelection();
1500 2 : DoHideCursor( "GoToRow" );
1501 :
1502 : // must we scroll?
1503 2 : bool bWasVisible = bSelectionIsVisible;
1504 2 : if (! bMultiSelection)
1505 : {
1506 0 : if( !bKeepSelection )
1507 0 : bSelectionIsVisible = false;
1508 : }
1509 2 : if ( nRow < nTopRow )
1510 0 : ScrollRows( nRow - nTopRow );
1511 2 : else if ( nRow > nLastRow )
1512 0 : ScrollRows( nRow - nLastRow );
1513 2 : bSelectionIsVisible = bWasVisible;
1514 :
1515 : // adjust cursor (selection) and thumb
1516 2 : if ( GetUpdateMode() )
1517 2 : pVScroll->SetThumbPos( nTopRow );
1518 :
1519 : // relative positioning (because nCurRow might have changed in the meantime)!
1520 2 : if (nCurRow != BROWSER_ENDOFSELECTION )
1521 0 : nCurRow = nCurRow + (nRow - nOldCurRow);
1522 :
1523 : // make sure that the current position is valid
1524 2 : if (nCurRow == BROWSER_ENDOFSELECTION && nRowCount > 0)
1525 2 : nCurRow = 0;
1526 0 : else if ( nCurRow >= nRowCount )
1527 0 : nCurRow = nRowCount - 1;
1528 2 : aSelRange = Range( nCurRow, nCurRow );
1529 :
1530 : // display new highlight if necessary
1531 2 : if ( !bMultiSelection && !bKeepSelection )
1532 0 : uRow.nSel = nRow;
1533 :
1534 : // resume Updates
1535 2 : getDataWindow()->LeaveUpdateLock();
1536 :
1537 : // Cursor+Highlight
1538 2 : if ( !bMultiSelection && !bKeepSelection)
1539 0 : ToggleSelection();
1540 2 : DoShowCursor( "GoToRow" );
1541 2 : if ( !bRowColMove && nOldCurRow != nCurRow )
1542 2 : CursorMoved();
1543 :
1544 2 : if ( !bMultiSelection && !bKeepSelection )
1545 : {
1546 0 : if ( !bSelecting )
1547 0 : Select();
1548 : else
1549 0 : bSelect = true;
1550 : }
1551 2 : return true;
1552 : }
1553 :
1554 :
1555 :
1556 0 : bool BrowseBox::GoToColumnId( sal_uInt16 nColId)
1557 : {
1558 0 : return GoToColumnId(nColId, true, false);
1559 : }
1560 :
1561 :
1562 2 : bool BrowseBox::GoToColumnId( sal_uInt16 nColId, bool bMakeVisible, bool bRowColMove)
1563 : {
1564 2 : if (!bColumnCursor)
1565 0 : return false;
1566 :
1567 : // allowed?
1568 2 : if (!bRowColMove && !IsCursorMoveAllowed( nCurRow, nColId ) )
1569 0 : return false;
1570 :
1571 2 : if ( nColId != nCurColId || (bMakeVisible && !IsFieldVisible(nCurRow, nColId, true)))
1572 : {
1573 2 : sal_uInt16 nNewPos = GetColumnPos(nColId);
1574 2 : BrowserColumn* pColumn = (nNewPos < pCols->size()) ? (*pCols)[ nNewPos ] : NULL;
1575 : DBG_ASSERT( pColumn, "no column object - invalid id?" );
1576 2 : if ( !pColumn )
1577 0 : return false;
1578 :
1579 2 : DoHideCursor( "GoToColumnId" );
1580 2 : nCurColId = nColId;
1581 :
1582 2 : bool bScrolled = false;
1583 :
1584 2 : sal_uInt16 nFirstPos = nFirstCol;
1585 2 : sal_uInt16 nWidth = (sal_uInt16)pColumn->Width();
1586 : sal_uInt16 nLastPos = GetColumnAtXPosPixel(
1587 2 : pDataWin->GetSizePixel().Width()-nWidth, false );
1588 2 : sal_uInt16 nFrozen = FrozenColCount();
1589 2 : if ( bMakeVisible && nLastPos &&
1590 2 : nNewPos >= nFrozen && ( nNewPos < nFirstPos || nNewPos > nLastPos ) )
1591 : {
1592 0 : if ( nNewPos < nFirstPos )
1593 0 : ScrollColumns( nNewPos-nFirstPos );
1594 0 : else if ( nNewPos > nLastPos )
1595 0 : ScrollColumns( nNewPos-nLastPos );
1596 0 : bScrolled = true;
1597 : }
1598 :
1599 2 : DoShowCursor( "GoToColumnId" );
1600 2 : if (!bRowColMove)
1601 : {
1602 : //try to move to nCurRow, nColId
1603 0 : CursorMoveAttempt aAttempt(nCurRow, nColId, bScrolled);
1604 : //Detect if we are already in a call to BrowseBox::GoToColumnId
1605 : //but the the attempt is impossible and we are simply recursing
1606 : //into BrowseBox::GoToColumnId with the same impossible to
1607 : //fulfill conditions
1608 0 : if (m_aGotoStack.empty() || aAttempt != m_aGotoStack.top())
1609 : {
1610 0 : m_aGotoStack.push(aAttempt);
1611 0 : CursorMoved();
1612 0 : m_aGotoStack.pop();
1613 : }
1614 : }
1615 2 : return true;
1616 : }
1617 0 : return true;
1618 : }
1619 :
1620 :
1621 :
1622 2 : bool BrowseBox::GoToRowColumnId( long nRow, sal_uInt16 nColId )
1623 : {
1624 :
1625 : // out of range?
1626 2 : if ( nRow < 0 || nRow >= nRowCount )
1627 0 : return false;
1628 :
1629 2 : if (!bColumnCursor)
1630 0 : return false;
1631 :
1632 : // nothing to do ?
1633 8 : if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) &&
1634 4 : nColId == nCurColId && IsFieldVisible(nCurRow, nColId, true))
1635 0 : return true;
1636 :
1637 : // allowed?
1638 2 : if (!IsCursorMoveAllowed(nRow, nColId))
1639 0 : return false;
1640 :
1641 2 : DoHideCursor( "GoToRowColumnId" );
1642 2 : bool bMoved = GoToRow(nRow, true) && GoToColumnId(nColId, true, true);
1643 2 : DoShowCursor( "GoToRowColumnId" );
1644 :
1645 2 : if (bMoved)
1646 2 : CursorMoved();
1647 :
1648 2 : return bMoved;
1649 : }
1650 :
1651 :
1652 :
1653 4 : void BrowseBox::SetNoSelection()
1654 : {
1655 :
1656 : // is there no selection
1657 12 : if ( ( !pColSel || !pColSel->GetSelectCount() ) &&
1658 4 : ( ( !bMultiSelection && uRow.nSel == BROWSER_ENDOFSELECTION ) ||
1659 4 : ( bMultiSelection && !uRow.pSel->GetSelectCount() ) ) )
1660 : // nothing to do
1661 8 : return;
1662 :
1663 : OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1664 0 : ToggleSelection();
1665 :
1666 : // unselect all
1667 0 : if ( bMultiSelection )
1668 0 : uRow.pSel->SelectAll(false);
1669 : else
1670 0 : uRow.nSel = BROWSER_ENDOFSELECTION;
1671 0 : if ( pColSel )
1672 0 : pColSel->SelectAll(false);
1673 0 : if ( !bSelecting )
1674 0 : Select();
1675 : else
1676 0 : bSelect = true;
1677 :
1678 : // restore screen
1679 : OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1680 :
1681 0 : if ( isAccessibleAlive() )
1682 : {
1683 : commitTableEvent(
1684 : SELECTION_CHANGED,
1685 : Any(),
1686 : Any()
1687 0 : );
1688 : }
1689 : }
1690 :
1691 :
1692 :
1693 0 : void BrowseBox::SelectAll()
1694 : {
1695 :
1696 0 : if ( !bMultiSelection )
1697 0 : return;
1698 :
1699 : OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1700 0 : ToggleSelection();
1701 :
1702 : // select all rows
1703 0 : if ( pColSel )
1704 0 : pColSel->SelectAll(false);
1705 0 : uRow.pSel->SelectAll(true);
1706 :
1707 : // don't highlight handle column
1708 0 : BrowserColumn *pFirstCol = (*pCols)[ 0 ];
1709 0 : long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
1710 :
1711 : // highlight the row selection
1712 0 : if ( !bHideSelect )
1713 : {
1714 0 : Rectangle aHighlightRect;
1715 : sal_uInt16 nVisibleRows =
1716 0 : (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
1717 0 : for ( long nRow = std::max( nTopRow, uRow.pSel->FirstSelected() );
1718 0 : nRow != BROWSER_ENDOFSELECTION && nRow < nTopRow + nVisibleRows;
1719 0 : nRow = uRow.pSel->NextSelected() )
1720 : aHighlightRect.Union( Rectangle(
1721 0 : Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
1722 0 : Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) ) );
1723 0 : pDataWin->Invalidate( aHighlightRect );
1724 : }
1725 :
1726 0 : if ( !bSelecting )
1727 0 : Select();
1728 : else
1729 0 : bSelect = true;
1730 :
1731 : // restore screen
1732 : OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1733 :
1734 0 : if ( isAccessibleAlive() )
1735 : {
1736 : commitTableEvent(
1737 : SELECTION_CHANGED,
1738 : Any(),
1739 : Any()
1740 0 : );
1741 : commitHeaderBarEvent(
1742 : SELECTION_CHANGED,
1743 : Any(),
1744 : Any(),
1745 : true
1746 0 : ); // column header event
1747 :
1748 : commitHeaderBarEvent(
1749 : SELECTION_CHANGED,
1750 : Any(),
1751 : Any(),
1752 : false
1753 0 : ); // row header event
1754 : }
1755 : }
1756 :
1757 :
1758 :
1759 0 : void BrowseBox::SelectRow( long nRow, bool _bSelect, bool bExpand )
1760 : {
1761 :
1762 0 : if ( !bMultiSelection )
1763 : {
1764 : // deselecting is impossible, selecting via cursor
1765 0 : if ( _bSelect )
1766 0 : GoToRow(nRow, false);
1767 0 : return;
1768 : }
1769 :
1770 : OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1771 :
1772 : // remove old selection?
1773 0 : if ( !bExpand || !bMultiSelection )
1774 : {
1775 0 : ToggleSelection();
1776 0 : if ( bMultiSelection )
1777 0 : uRow.pSel->SelectAll(false);
1778 : else
1779 0 : uRow.nSel = BROWSER_ENDOFSELECTION;
1780 0 : if ( pColSel )
1781 0 : pColSel->SelectAll(false);
1782 : }
1783 :
1784 : // set new selection
1785 0 : if ( !bHideSelect
1786 0 : && ( ( bMultiSelection
1787 0 : && uRow.pSel->GetTotalRange().Max() >= nRow
1788 0 : && uRow.pSel->Select( nRow, _bSelect )
1789 : )
1790 0 : || ( !bMultiSelection
1791 0 : && ( uRow.nSel = nRow ) != BROWSER_ENDOFSELECTION )
1792 : )
1793 : )
1794 : {
1795 : // don't highlight handle column
1796 0 : BrowserColumn *pFirstCol = (*pCols)[ 0 ];
1797 0 : long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
1798 :
1799 : // highlight only newly selected part
1800 : Rectangle aRect(
1801 0 : Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
1802 0 : Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
1803 0 : pDataWin->Invalidate( aRect );
1804 : }
1805 :
1806 0 : if ( !bSelecting )
1807 0 : Select();
1808 : else
1809 0 : bSelect = true;
1810 :
1811 : // restore screen
1812 : OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1813 :
1814 0 : if ( isAccessibleAlive() )
1815 : {
1816 : commitTableEvent(
1817 : SELECTION_CHANGED,
1818 : Any(),
1819 : Any()
1820 0 : );
1821 : commitHeaderBarEvent(
1822 : SELECTION_CHANGED,
1823 : Any(),
1824 : Any(),
1825 : false
1826 0 : ); // row header event
1827 : }
1828 : }
1829 :
1830 :
1831 :
1832 258 : long BrowseBox::GetSelectRowCount() const
1833 : {
1834 :
1835 258 : return bMultiSelection ? uRow.pSel->GetSelectCount() :
1836 516 : uRow.nSel == BROWSER_ENDOFSELECTION ? 0 : 1;
1837 : }
1838 :
1839 :
1840 :
1841 0 : void BrowseBox::SelectColumnPos( sal_uInt16 nNewColPos, bool _bSelect, bool bMakeVisible )
1842 : {
1843 :
1844 0 : if ( !bColumnCursor || nNewColPos == BROWSER_INVALIDID )
1845 0 : return;
1846 :
1847 0 : if ( !bMultiSelection )
1848 : {
1849 0 : if ( _bSelect )
1850 0 : GoToColumnId( (*pCols)[ nNewColPos ]->GetId(), bMakeVisible );
1851 0 : return;
1852 : }
1853 : else
1854 : {
1855 0 : if ( !GoToColumnId( (*pCols)[ nNewColPos ]->GetId(), bMakeVisible ) )
1856 0 : return;
1857 : }
1858 :
1859 : OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1860 0 : ToggleSelection();
1861 0 : if ( bMultiSelection )
1862 0 : uRow.pSel->SelectAll(false);
1863 : else
1864 0 : uRow.nSel = BROWSER_ENDOFSELECTION;
1865 0 : pColSel->SelectAll(false);
1866 :
1867 0 : if ( pColSel->Select( nNewColPos, _bSelect ) )
1868 : {
1869 : // GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
1870 :
1871 : // only highlight painted areas
1872 0 : pDataWin->Update();
1873 0 : Rectangle aFieldRectPix( GetFieldRectPixel( nCurRow, nCurColId, false ) );
1874 : Rectangle aRect(
1875 0 : Point( aFieldRectPix.Left() - MIN_COLUMNWIDTH, 0 ),
1876 0 : Size( (*pCols)[ nNewColPos ]->Width(),
1877 0 : pDataWin->GetOutputSizePixel().Height() ) );
1878 0 : pDataWin->Invalidate( aRect );
1879 0 : if ( !bSelecting )
1880 0 : Select();
1881 : else
1882 0 : bSelect = true;
1883 :
1884 0 : if ( isAccessibleAlive() )
1885 : {
1886 : commitTableEvent(
1887 : SELECTION_CHANGED,
1888 : Any(),
1889 : Any()
1890 0 : );
1891 : commitHeaderBarEvent(
1892 : SELECTION_CHANGED,
1893 : Any(),
1894 : Any(),
1895 : true
1896 0 : ); // column header event
1897 : }
1898 : }
1899 :
1900 : // restore screen
1901 : OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1902 : }
1903 :
1904 :
1905 :
1906 75 : sal_uInt16 BrowseBox::GetSelectColumnCount() const
1907 : {
1908 :
1909 : // while bAutoSelect (==!pColSel), 1 if any rows (yes rows!) else none
1910 75 : return pColSel ? (sal_uInt16) pColSel->GetSelectCount() :
1911 150 : nCurRow >= 0 ? 1 : 0;
1912 : }
1913 :
1914 :
1915 0 : long BrowseBox::FirstSelectedColumn( ) const
1916 : {
1917 0 : return pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION;
1918 : }
1919 :
1920 :
1921 :
1922 0 : long BrowseBox::FirstSelectedRow( bool bInverse )
1923 : {
1924 :
1925 0 : return bMultiSelection ? uRow.pSel->FirstSelected(bInverse) : uRow.nSel;
1926 : }
1927 :
1928 :
1929 :
1930 0 : long BrowseBox::NextSelectedRow()
1931 : {
1932 :
1933 0 : return bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION;
1934 : }
1935 :
1936 :
1937 :
1938 0 : long BrowseBox::LastSelectedRow()
1939 : {
1940 :
1941 0 : return bMultiSelection ? uRow.pSel->LastSelected() : uRow.nSel;
1942 : }
1943 :
1944 :
1945 :
1946 16 : bool BrowseBox::IsRowSelected( long nRow ) const
1947 : {
1948 :
1949 16 : return bMultiSelection ? uRow.pSel->IsSelected(nRow) : nRow == uRow.nSel;
1950 : }
1951 :
1952 :
1953 :
1954 96 : bool BrowseBox::IsColumnSelected( sal_uInt16 nColumnId ) const
1955 : {
1956 :
1957 96 : return pColSel ? pColSel->IsSelected( GetColumnPos(nColumnId) ) :
1958 192 : nCurColId == nColumnId;
1959 : }
1960 :
1961 :
1962 :
1963 0 : bool BrowseBox::MakeFieldVisible
1964 : (
1965 : long nRow, // line number of the field (starting with 0)
1966 : sal_uInt16 nColId, // column ID of the field
1967 : bool bComplete // (== false), true => make visible in its entirety
1968 : )
1969 :
1970 : /* [Description]
1971 :
1972 : Makes visible the field described in 'nRow' and 'nColId' by scrolling
1973 : accordingly. If 'bComplete' is set, the field should become visible in its
1974 : entirety.
1975 :
1976 : [Returned Value]
1977 :
1978 : bool true
1979 : The given field is already visible or was already visible.
1980 :
1981 : false
1982 : The given field could not be made visible or in the case of
1983 : 'bComplete' could not be made visible in its entirety.
1984 : */
1985 :
1986 : {
1987 0 : Size aTestSize = pDataWin->GetSizePixel();
1988 :
1989 0 : if ( !bBootstrapped ||
1990 0 : ( aTestSize.Width() == 0 && aTestSize.Height() == 0 ) )
1991 0 : return false;
1992 :
1993 : // is it visible already?
1994 0 : bool bVisible = IsFieldVisible( nRow, nColId, bComplete );
1995 0 : if ( bVisible )
1996 0 : return true;
1997 :
1998 : // calculate column position, field rectangle and painting area
1999 0 : sal_uInt16 nColPos = GetColumnPos( nColId );
2000 0 : Rectangle aFieldRect = GetFieldRectPixel( nRow, nColId, false );
2001 0 : Rectangle aDataRect = Rectangle( Point(0, 0), pDataWin->GetSizePixel() );
2002 :
2003 : // positioned outside on the left?
2004 0 : if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
2005 : // => scroll to the right
2006 0 : ScrollColumns( nColPos - nFirstCol );
2007 :
2008 : // while outside on the right
2009 0 : while ( aDataRect.Right() < ( bComplete
2010 0 : ? aFieldRect.Right()
2011 0 : : aFieldRect.Left()+aFieldRect.GetWidth()/2 ) )
2012 : {
2013 : // => scroll to the left
2014 0 : if ( ScrollColumns( 1 ) != 1 )
2015 : // no more need to scroll
2016 0 : break;
2017 0 : aFieldRect = GetFieldRectPixel( nRow, nColId, false );
2018 : }
2019 :
2020 : // positioned outside above?
2021 0 : if ( nRow < nTopRow )
2022 : // scroll further to the bottom
2023 0 : ScrollRows( nRow - nTopRow );
2024 :
2025 : // positioned outside below?
2026 0 : long nBottomRow = nTopRow + GetVisibleRows();
2027 : // decrement nBottomRow to make it the number of the last visible line
2028 : // (count starts with 0!).
2029 : // Example: BrowseBox contains exactly one entry. nBottomRow := 0 + 1 - 1
2030 0 : if( nBottomRow )
2031 0 : nBottomRow--;
2032 :
2033 0 : if ( nRow > nBottomRow )
2034 : // scroll further to the top
2035 0 : ScrollRows( nRow - nBottomRow );
2036 :
2037 : // it might still not actually fit, e.g. if the window is too small
2038 0 : return IsFieldVisible( nRow, nColId, bComplete );
2039 : }
2040 :
2041 :
2042 :
2043 0 : bool BrowseBox::IsFieldVisible( long nRow, sal_uInt16 nColumnId,
2044 : bool bCompletely ) const
2045 : {
2046 :
2047 : // hidden by frozen column?
2048 0 : sal_uInt16 nColPos = GetColumnPos( nColumnId );
2049 0 : if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
2050 0 : return false;
2051 :
2052 0 : Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
2053 0 : if ( aRect.IsEmpty() )
2054 0 : return false;
2055 :
2056 : // get the visible area
2057 0 : Rectangle aOutRect( Point(0, 0), pDataWin->GetOutputSizePixel() );
2058 :
2059 0 : if ( bCompletely )
2060 : // test if the field is completely visible
2061 0 : return aOutRect.IsInside( aRect );
2062 : else
2063 : // test if the field is partly of completely visible
2064 0 : return !aOutRect.Intersection( aRect ).IsEmpty();
2065 : }
2066 :
2067 :
2068 :
2069 294 : Rectangle BrowseBox::GetFieldRectPixel( long nRow, sal_uInt16 nColumnId,
2070 : bool bRelToBrowser) const
2071 : {
2072 :
2073 : // get the rectangle relative to DataWin
2074 294 : Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
2075 294 : if ( aRect.IsEmpty() )
2076 246 : return aRect;
2077 :
2078 : // adjust relative to BrowseBox's output area
2079 48 : Point aTopLeft( aRect.TopLeft() );
2080 48 : if ( bRelToBrowser )
2081 : {
2082 0 : aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
2083 0 : aTopLeft = ScreenToOutputPixel( aTopLeft );
2084 : }
2085 :
2086 48 : return Rectangle( aTopLeft, aRect.GetSize() );
2087 : }
2088 :
2089 :
2090 :
2091 0 : Rectangle BrowseBox::GetRowRectPixel( long nRow, bool bRelToBrowser ) const
2092 : {
2093 :
2094 : // get the rectangle relative to DataWin
2095 0 : Rectangle aRect;
2096 0 : if ( nTopRow > nRow )
2097 : // row is above visible area
2098 0 : return aRect;
2099 : aRect = Rectangle(
2100 0 : Point( 0, GetDataRowHeight() * (nRow-nTopRow) ),
2101 0 : Size( pDataWin->GetOutputSizePixel().Width(), GetDataRowHeight() ) );
2102 0 : if ( aRect.TopLeft().Y() > pDataWin->GetOutputSizePixel().Height() )
2103 : // row is below visible area
2104 0 : return aRect;
2105 :
2106 : // adjust relative to BrowseBox's output area
2107 0 : Point aTopLeft( aRect.TopLeft() );
2108 0 : if ( bRelToBrowser )
2109 : {
2110 0 : aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
2111 0 : aTopLeft = ScreenToOutputPixel( aTopLeft );
2112 : }
2113 :
2114 0 : return Rectangle( aTopLeft, aRect.GetSize() );
2115 : }
2116 :
2117 :
2118 :
2119 294 : Rectangle BrowseBox::ImplFieldRectPixel( long nRow, sal_uInt16 nColumnId ) const
2120 : {
2121 :
2122 : // compute the X-coordinate relative to DataWin by accumulation
2123 294 : long nColX = 0;
2124 294 : sal_uInt16 nFrozenCols = FrozenColCount();
2125 : size_t nCol;
2126 1744 : for ( nCol = 0;
2127 872 : nCol < pCols->size() && (*pCols)[ nCol ]->GetId() != nColumnId;
2128 : ++nCol )
2129 578 : if ( (*pCols)[ nCol ]->IsFrozen() || nCol >= nFirstCol )
2130 578 : nColX += (*pCols)[ nCol ]->Width();
2131 :
2132 294 : if ( nCol >= pCols->size() || ( nCol >= nFrozenCols && nCol < nFirstCol ) )
2133 246 : return Rectangle();
2134 :
2135 : // compute the Y-coordinate relative to DataWin
2136 48 : long nRowY = GetDataRowHeight();
2137 48 : if ( nRow != BROWSER_ENDOFSELECTION ) // #105497# OJ
2138 4 : nRowY = ( nRow - nTopRow ) * GetDataRowHeight();
2139 :
2140 : // assemble the Rectangle relative to DataWin
2141 : return Rectangle(
2142 : Point( nColX + MIN_COLUMNWIDTH, nRowY ),
2143 48 : Size( (*pCols)[ nCol ]->Width() - 2*MIN_COLUMNWIDTH,
2144 96 : GetDataRowHeight() - 1 ) );
2145 : }
2146 :
2147 :
2148 :
2149 0 : long BrowseBox::GetRowAtYPosPixel( long nY, bool bRelToBrowser ) const
2150 : {
2151 :
2152 : // compute the Y-coordinate
2153 0 : if ( bRelToBrowser )
2154 : {
2155 0 : Point aDataTopLeft = pDataWin->OutputToScreenPixel( Point(0, 0) );
2156 0 : Point aTopLeft = OutputToScreenPixel( Point(0, 0) );
2157 0 : nY -= aDataTopLeft.Y() - aTopLeft.Y();
2158 : }
2159 :
2160 : // no row there (e.g. in the header)
2161 0 : if ( nY < 0 || nY >= pDataWin->GetOutputSizePixel().Height() )
2162 0 : return -1;
2163 :
2164 0 : return nY / GetDataRowHeight() + nTopRow;
2165 : }
2166 :
2167 :
2168 :
2169 0 : Rectangle BrowseBox::GetFieldRect( sal_uInt16 nColumnId ) const
2170 : {
2171 :
2172 0 : return GetFieldRectPixel( nCurRow, nColumnId );
2173 : }
2174 :
2175 :
2176 :
2177 513 : sal_uInt16 BrowseBox::GetColumnAtXPosPixel( long nX, bool ) const
2178 : {
2179 :
2180 : // accumulate the widths of the visible columns
2181 513 : long nColX = 0;
2182 1908 : for ( size_t nCol = 0; nCol < pCols->size(); ++nCol )
2183 : {
2184 1459 : BrowserColumn *pCol = (*pCols)[ nCol ];
2185 1459 : if ( pCol->IsFrozen() || nCol >= nFirstCol )
2186 1459 : nColX += pCol->Width();
2187 :
2188 1459 : if ( nColX > nX )
2189 64 : return nCol;
2190 : }
2191 :
2192 449 : return BROWSER_INVALIDID;
2193 : }
2194 :
2195 :
2196 :
2197 288 : void BrowseBox::ReserveControlArea( sal_uInt16 nWidth )
2198 : {
2199 :
2200 288 : if ( nWidth != nControlAreaWidth )
2201 : {
2202 : OSL_ENSURE(nWidth,"Control area of 0 is not allowed, Use USHRT_MAX instead!");
2203 46 : nControlAreaWidth = nWidth;
2204 46 : UpdateScrollbars();
2205 : }
2206 288 : }
2207 :
2208 :
2209 :
2210 1485 : Rectangle BrowseBox::GetControlArea() const
2211 : {
2212 :
2213 : return Rectangle(
2214 4455 : Point( 0, GetOutputSizePixel().Height() - aHScroll.GetSizePixel().Height() ),
2215 4455 : Size( GetOutputSizePixel().Width() - aHScroll.GetSizePixel().Width(),
2216 10395 : aHScroll.GetSizePixel().Height() ) );
2217 : }
2218 :
2219 :
2220 :
2221 124 : void BrowseBox::SetMode( BrowserMode nMode )
2222 : {
2223 :
2224 124 : getDataWindow()->bAutoHScroll = BROWSER_AUTO_HSCROLL == ( nMode & BROWSER_AUTO_HSCROLL );
2225 124 : getDataWindow()->bAutoVScroll = BROWSER_AUTO_VSCROLL == ( nMode & BROWSER_AUTO_VSCROLL );
2226 124 : getDataWindow()->bNoHScroll = BROWSER_NO_HSCROLL == ( nMode & BROWSER_NO_HSCROLL );
2227 124 : getDataWindow()->bNoVScroll = BROWSER_NO_VSCROLL == ( nMode & BROWSER_NO_VSCROLL );
2228 :
2229 : DBG_ASSERT( !( getDataWindow()->bAutoHScroll && getDataWindow()->bNoHScroll ),
2230 : "BrowseBox::SetMode: AutoHScroll *and* NoHScroll?" );
2231 : DBG_ASSERT( !( getDataWindow()->bAutoVScroll && getDataWindow()->bNoVScroll ),
2232 : "BrowseBox::SetMode: AutoVScroll *and* NoVScroll?" );
2233 124 : if ( getDataWindow()->bAutoHScroll )
2234 29 : getDataWindow()->bNoHScroll = false;
2235 124 : if ( getDataWindow()->bAutoVScroll )
2236 29 : getDataWindow()->bNoVScroll = false;
2237 :
2238 124 : if ( getDataWindow()->bNoHScroll )
2239 0 : aHScroll.Hide();
2240 :
2241 124 : nControlAreaWidth = USHRT_MAX;
2242 :
2243 : getDataWindow()->bNoScrollBack =
2244 124 : BROWSER_NO_SCROLLBACK == ( nMode & BROWSER_NO_SCROLLBACK);
2245 :
2246 124 : long nOldRowSel = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel;
2247 124 : MultiSelection *pOldRowSel = bMultiSelection ? uRow.pSel : 0;
2248 124 : MultiSelection *pOldColSel = pColSel;
2249 :
2250 124 : delete pVScroll;
2251 :
2252 124 : bThumbDragging = ( nMode & BROWSER_THUMBDRAGGING ) == BROWSER_THUMBDRAGGING;
2253 124 : bMultiSelection = ( nMode & BROWSER_MULTISELECTION ) == BROWSER_MULTISELECTION;
2254 124 : bColumnCursor = ( nMode & BROWSER_COLUMNSELECTION ) == BROWSER_COLUMNSELECTION;
2255 124 : bKeepHighlight = ( nMode & BROWSER_KEEPSELECTION ) == BROWSER_KEEPSELECTION;
2256 :
2257 124 : bHideSelect = ((nMode & BROWSER_HIDESELECT) == BROWSER_HIDESELECT);
2258 : // default: do not hide the cursor at all (untaken scrolling and such)
2259 124 : bHideCursor = TRISTATE_FALSE;
2260 :
2261 124 : if ( BROWSER_SMART_HIDECURSOR == ( nMode & BROWSER_SMART_HIDECURSOR ) )
2262 : { // smart cursor hide overrules hard cursor hide
2263 0 : bHideCursor = TRISTATE_INDET;
2264 : }
2265 124 : else if ( BROWSER_HIDECURSOR == ( nMode & BROWSER_HIDECURSOR ) )
2266 : {
2267 2 : bHideCursor = TRISTATE_TRUE;
2268 : }
2269 :
2270 124 : m_bFocusOnlyCursor = ((nMode & BROWSER_CURSOR_WO_FOCUS) == 0);
2271 :
2272 124 : bHLines = ( nMode & BROWSER_HLINESFULL ) == BROWSER_HLINESFULL;
2273 124 : bVLines = ( nMode & BROWSER_VLINESFULL ) == BROWSER_VLINESFULL;
2274 124 : bHDots = ( nMode & BROWSER_HLINESDOTS ) == BROWSER_HLINESDOTS;
2275 124 : bVDots = ( nMode & BROWSER_VLINESDOTS ) == BROWSER_VLINESDOTS;
2276 :
2277 : WinBits nVScrollWinBits =
2278 124 : WB_VSCROLL | ( ( nMode & BROWSER_THUMBDRAGGING ) ? WB_DRAG : 0 );
2279 124 : pVScroll = ( nMode & BROWSER_TRACKING_TIPS ) == BROWSER_TRACKING_TIPS
2280 : ? new BrowserScrollBar( this, nVScrollWinBits,
2281 124 : static_cast<BrowserDataWin*>( pDataWin ) )
2282 248 : : new ScrollBar( this, nVScrollWinBits );
2283 124 : pVScroll->SetLineSize( 1 );
2284 124 : pVScroll->SetPageSize(1);
2285 124 : pVScroll->SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
2286 124 : pVScroll->SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
2287 :
2288 : getDataWindow()->bAutoSizeLastCol =
2289 124 : BROWSER_AUTOSIZE_LASTCOL == ( nMode & BROWSER_AUTOSIZE_LASTCOL );
2290 : getDataWindow()->bOwnDataChangedHdl =
2291 124 : BROWSER_OWN_DATACHANGED == ( nMode & BROWSER_OWN_DATACHANGED );
2292 :
2293 : // create a headerbar. what happens, if a headerbar has to be created and
2294 : // there already are columns?
2295 124 : if ( BROWSER_HEADERBAR_NEW == ( nMode & BROWSER_HEADERBAR_NEW ) )
2296 : {
2297 124 : if (!getDataWindow()->pHeaderBar)
2298 41 : getDataWindow()->pHeaderBar = CreateHeaderBar( this );
2299 : }
2300 : else
2301 : {
2302 0 : DELETEZ(getDataWindow()->pHeaderBar);
2303 : }
2304 :
2305 :
2306 :
2307 124 : if ( bColumnCursor )
2308 : {
2309 124 : pColSel = pOldColSel ? pOldColSel : new MultiSelection;
2310 124 : pColSel->SetTotalRange( Range( 0, pCols->size()-1 ) );
2311 : }
2312 : else
2313 : {
2314 0 : delete pColSel;
2315 0 : pColSel = 0;
2316 : }
2317 :
2318 124 : if ( bMultiSelection )
2319 : {
2320 124 : if ( pOldRowSel )
2321 83 : uRow.pSel = pOldRowSel;
2322 : else
2323 41 : uRow.pSel = new MultiSelection;
2324 : }
2325 : else
2326 : {
2327 0 : uRow.nSel = nOldRowSel;
2328 0 : delete pOldRowSel;
2329 : }
2330 :
2331 124 : if ( bBootstrapped )
2332 : {
2333 20 : StateChanged( StateChangedType::INITSHOW );
2334 20 : if ( bMultiSelection && !pOldRowSel &&
2335 : nOldRowSel != BROWSER_ENDOFSELECTION )
2336 0 : uRow.pSel->Select( nOldRowSel );
2337 : }
2338 :
2339 124 : if ( pDataWin )
2340 124 : pDataWin->Invalidate();
2341 :
2342 : // no cursor on handle column
2343 124 : if ( nCurColId == HandleColumnId )
2344 41 : nCurColId = GetColumnId( 1 );
2345 :
2346 124 : m_nCurrentMode = nMode;
2347 124 : }
2348 :
2349 :
2350 :
2351 0 : void BrowseBox::VisibleRowsChanged( long, sal_uInt16 )
2352 : {
2353 :
2354 : // old behavior: automatically correct NumRows:
2355 0 : if ( nRowCount < GetRowCount() )
2356 : {
2357 0 : RowInserted(nRowCount,GetRowCount() - nRowCount, false);
2358 : }
2359 0 : else if ( nRowCount > GetRowCount() )
2360 : {
2361 0 : RowRemoved(nRowCount-(nRowCount - GetRowCount()),nRowCount - GetRowCount(), false);
2362 : }
2363 0 : }
2364 :
2365 :
2366 :
2367 0 : bool BrowseBox::IsCursorMoveAllowed( long, sal_uInt16 ) const
2368 :
2369 : /* [Description]
2370 :
2371 : This virtual method is always called before the cursor is moved directly.
2372 : By means of 'return sal_False', we avoid doing this if e.g. a record
2373 : contradicts any rules.
2374 :
2375 : This method is not called, if the cursor movement results from removing or
2376 : deleting a row/column (thus, in cases where only a "cursor correction" happens).
2377 :
2378 : The base implementation currently always returns true.
2379 : */
2380 :
2381 : {
2382 0 : return true;
2383 : }
2384 :
2385 :
2386 :
2387 3775 : long BrowseBox::GetDataRowHeight() const
2388 : {
2389 3775 : return CalcZoom(nDataRowHeight ? nDataRowHeight : ImpGetDataRowHeight());
2390 : }
2391 :
2392 :
2393 :
2394 41 : BrowserHeader* BrowseBox::CreateHeaderBar( BrowseBox* pParent )
2395 : {
2396 41 : BrowserHeader* pNewBar = new BrowserHeader( pParent );
2397 41 : pNewBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
2398 41 : return pNewBar;
2399 : }
2400 :
2401 41 : void BrowseBox::SetHeaderBar( BrowserHeader* pHeaderBar )
2402 : {
2403 41 : delete static_cast<BrowserDataWin*>(pDataWin)->pHeaderBar;
2404 41 : static_cast<BrowserDataWin*>( pDataWin )->pHeaderBar = pHeaderBar;
2405 41 : static_cast<BrowserDataWin*>( pDataWin )->pHeaderBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
2406 41 : }
2407 :
2408 3176 : long BrowseBox::GetTitleHeight() const
2409 : {
2410 : long nHeight;
2411 : // ask the header bar for the text height (if possible), as the header bar's font is adjusted with
2412 : // our (and the header's) zoom factor
2413 3176 : HeaderBar* pHeaderBar = static_cast<BrowserDataWin*>( pDataWin )->pHeaderBar;
2414 3176 : if ( pHeaderBar )
2415 3135 : nHeight = pHeaderBar->GetTextHeight();
2416 : else
2417 41 : nHeight = GetTextHeight();
2418 :
2419 3176 : return nTitleLines ? nTitleLines * nHeight + 4 : 0;
2420 : }
2421 :
2422 223 : long BrowseBox::CalcReverseZoom(long nVal)
2423 : {
2424 223 : if (IsZoom())
2425 : {
2426 0 : const Fraction& rZoom = GetZoom();
2427 0 : double n = (double)nVal;
2428 0 : n *= (double)rZoom.GetDenominator();
2429 0 : if (!rZoom.GetNumerator())
2430 0 : throw o3tl::divide_by_zero();
2431 0 : n /= (double)rZoom.GetNumerator();
2432 0 : nVal = n>0 ? (long)(n + 0.5) : -(long)(-n + 0.5);
2433 : }
2434 :
2435 223 : return nVal;
2436 : }
2437 :
2438 0 : void BrowseBox::CursorMoved()
2439 : {
2440 : // before implementing more here, please adjust the EditBrowseBox
2441 :
2442 0 : if ( isAccessibleAlive() && HasFocus() )
2443 : commitTableEvent(
2444 : ACTIVE_DESCENDANT_CHANGED,
2445 0 : makeAny( CreateAccessibleCell( GetCurRow(),GetColumnPos( GetCurColumnId() ) ) ),
2446 : Any()
2447 0 : );
2448 0 : }
2449 :
2450 0 : void BrowseBox::LoseFocus()
2451 : {
2452 : OSL_TRACE( "BrowseBox: %p->LoseFocus", this );
2453 :
2454 0 : if ( bHasFocus )
2455 : {
2456 : OSL_TRACE( "BrowseBox: %p->HideCursor", this );
2457 0 : DoHideCursor( "LoseFocus" );
2458 :
2459 0 : if ( !bKeepHighlight )
2460 : {
2461 0 : ToggleSelection();
2462 0 : bSelectionIsVisible = false;
2463 : }
2464 :
2465 0 : bHasFocus = false;
2466 : }
2467 0 : Control::LoseFocus();
2468 0 : }
2469 :
2470 :
2471 :
2472 0 : void BrowseBox::GetFocus()
2473 : {
2474 : OSL_TRACE( "BrowseBox: %p->GetFocus", this );
2475 :
2476 0 : if ( !bHasFocus )
2477 : {
2478 0 : if ( !bSelectionIsVisible )
2479 : {
2480 0 : bSelectionIsVisible = true;
2481 0 : if ( bBootstrapped )
2482 0 : ToggleSelection();
2483 : }
2484 :
2485 0 : bHasFocus = true;
2486 0 : DoShowCursor( "GetFocus" );
2487 : }
2488 0 : Control::GetFocus();
2489 1227 : }
2490 :
2491 :
2492 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|