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