Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / toolkit / source / controls / table / tablecontrol_impl.hxx
blob9e4d0649729f4cf65ef898599fca9dda4c1b91bd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #pragma once
22 #include <controls/table/tablemodel.hxx>
23 #include <controls/table/tablecontrolinterface.hxx>
25 #include <vcl/svtaccessiblefactory.hxx>
26 #include <vcl/accessibletable.hxx>
28 #include <vcl/seleng.hxx>
30 #include <vector>
32 class ScrollBar;
33 class ScrollBarBox;
35 namespace svt::table
37 struct MutableColumnMetrics : public ColumnMetrics
39 MutableColumnMetrics()
40 :ColumnMetrics()
44 MutableColumnMetrics( tools::Long const i_startPixel, tools::Long const i_endPixel )
45 :ColumnMetrics( i_startPixel, i_endPixel )
49 tools::Long getStart() const { return nStartPixel; }
50 tools::Long getEnd() const { return nEndPixel; }
52 void move( tools::Long const i_offset ) { nStartPixel += i_offset; nEndPixel += i_offset; }
54 tools::Long getWidth() const { return nEndPixel - nStartPixel; }
57 struct ColumnInfoPositionLess
59 bool operator()( MutableColumnMetrics const& i_lhs, MutableColumnMetrics const& i_rhs )
61 return i_lhs.getEnd() < i_rhs.getStart();
65 typedef ::std::vector< MutableColumnMetrics > ColumnPositions;
67 class TableControl;
68 class TableDataWindow;
69 class TableFunctionSet;
72 //= TableControl_Impl
74 class TableControl_Impl :public ITableControl
75 ,public ITableModelListener
77 friend class TableGeometry;
78 friend class TableRowGeometry;
79 friend class TableColumnGeometry;
80 friend class SuspendInvariants;
82 private:
83 /// the control whose impl-instance we implement
84 TableControl& m_rAntiImpl;
85 /// the model of the table control
86 PTableModel m_pModel;
87 /// the input handler to use, usually the input handler as provided by ->m_pModel
88 PTableInputHandler m_pInputHandler;
89 /// info about the widths of our columns
90 ColumnPositions m_aColumnWidths;
92 /// the height of a single row in the table, measured in pixels
93 tools::Long m_nRowHeightPixel;
94 /// the height of the column header row in the table, measured in pixels
95 tools::Long m_nColHeaderHeightPixel;
96 /// the width of the row header column in the table, measured in pixels
97 tools::Long m_nRowHeaderWidthPixel;
99 /// the number of columns in the table control. Cached model value.
100 TableSize m_nColumnCount;
102 /// the number of rows in the table control. Cached model value.
103 TableSize m_nRowCount;
105 ColPos m_nCurColumn;
106 RowPos m_nCurRow;
107 ColPos m_nLeftColumn;
108 RowPos m_nTopRow;
110 sal_Int32 m_nCursorHidden;
112 /** the window to contain all data content, including header bars
114 The window's upper left corner is at position (0,0), relative to the
115 table control, which is the direct parent of the data window.
117 VclPtr<TableDataWindow> m_pDataWindow;
118 /// the vertical scrollbar, if any
119 VclPtr<ScrollBar> m_pVScroll;
120 /// the horizontal scrollbar, if any
121 VclPtr<ScrollBar> m_pHScroll;
122 VclPtr<ScrollBarBox> m_pScrollCorner;
123 //selection engine - for determining selection range, e.g. single, multiple
124 std::unique_ptr<SelectionEngine> m_pSelEngine;
125 //vector which contains the selected rows
126 std::vector<RowPos> m_aSelectedRows;
127 //part of selection engine
128 std::unique_ptr<TableFunctionSet> m_pTableFunctionSet;
129 //part of selection engine
130 RowPos m_nAnchor;
131 bool m_bUpdatingColWidths;
133 vcl::AccessibleFactoryAccess m_aFactoryAccess;
134 vcl::table::IAccessibleTableControl* m_pAccessibleTable;
136 public:
137 void setModel( const PTableModel& _pModel );
139 const PTableInputHandler& getInputHandler() const { return m_pInputHandler; }
141 RowPos getCurRow() const { return m_nCurRow; }
143 RowPos getAnchor() const { return m_nAnchor; }
144 void setAnchor( RowPos const i_anchor ) { m_nAnchor = i_anchor; }
146 RowPos getTopRow() const { return m_nTopRow; }
147 ColPos getLeftColumn() const { return m_nLeftColumn; }
149 const TableControl& getAntiImpl() const { return m_rAntiImpl; }
150 TableControl& getAntiImpl() { return m_rAntiImpl; }
152 public:
153 explicit TableControl_Impl( TableControl& _rAntiImpl );
154 virtual ~TableControl_Impl() override;
156 /** to be called when the anti-impl instance has been resized
158 void onResize();
160 /** paints the table control content which intersects with the given rectangle
162 void doPaintContent(vcl::RenderContext& rRenderContext, const tools::Rectangle& _rUpdateRect);
164 /** moves the cursor to the cell with the given coordinates
166 To ease the caller's code, the coordinates must not necessarily denote a
167 valid position. If they don't, <FALSE/> will be returned.
169 bool goTo( ColPos _nColumn, RowPos _nRow );
171 /** ensures that the given coordinate is visible
172 @param _nColumn
173 the column position which should be visible. Must be non-negative, and smaller
174 than the column count.
175 @param _nRow
176 the row position which should be visibleMust be non-negative, and smaller
177 than the row count.
179 void ensureVisible( ColPos _nColumn, RowPos _nRow );
181 /** retrieves the content of the given cell, converted to a string
183 OUString getCellContentAsString( RowPos const i_row, ColPos const i_col );
185 /** returns the position of the current row in the selection vector */
186 static int getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current);
188 void invalidateRect(const tools::Rectangle &rInvalidateRect);
190 /** ??? */
191 void invalidateSelectedRegion( RowPos _nPrevRow, RowPos _nCurRow );
193 /** invalidates the part of the data window which is covered by the given rows
194 @param i_firstRow
195 the index of the first row to include in the invalidation
196 @param i_lastRow
197 the index of the last row to include in the invalidation, or ROW_INVALID if the invalidation
198 should happen down to the bottom of the data window.
200 void invalidateRowRange( RowPos const i_firstRow, RowPos const i_lastRow );
202 /** invalidates the part of the data window which is covered by the given row
204 void invalidateRow( RowPos const i_row ) { invalidateRowRange( i_row, i_row ); }
206 /** invalidates all selected rows
208 void invalidateSelectedRows();
210 void checkCursorPosition();
212 bool hasRowSelection() const { return !m_aSelectedRows.empty(); }
213 size_t getSelectedRowCount() const { return m_aSelectedRows.size(); }
214 RowPos getSelectedRowIndex( size_t const i_selectionIndex ) const;
216 /** removes the given row index from m_aSelectedRows
218 @return
219 <TRUE/> if and only if the row was previously marked as selected
221 bool markRowAsDeselected( RowPos const i_rowIndex );
223 /** marks the given row as selected, by putting it into m_aSelectedRows
224 @return
225 <TRUE/> if and only if the row was previously <em>not</em> marked as selected
227 bool markRowAsSelected( RowPos const i_rowIndex );
229 /** marks all rows as deselected
230 @return
231 <TRUE/> if and only if the selection actually changed by this operation
233 bool markAllRowsAsDeselected();
235 /** marks all rows as selected
236 @return
237 <FALSE/> if and only if all rows were selected already.
239 bool markAllRowsAsSelected();
241 void commitAccessibleEvent( sal_Int16 const i_eventID );
242 void commitCellEvent( sal_Int16 const i_eventID, const css::uno::Any& i_newValue, const css::uno::Any& i_oldValue );
243 void commitTableEvent( sal_Int16 const i_eventID, const css::uno::Any& i_newValue, const css::uno::Any& i_oldValue );
245 // ITableControl
246 virtual void hideCursor() override;
247 virtual void showCursor() override;
248 virtual bool dispatchAction( TableControlAction _eAction ) override;
249 virtual SelectionEngine* getSelEngine() override;
250 virtual PTableModel getModel() const override;
251 virtual ColPos getCurrentColumn() const override;
252 virtual RowPos getCurrentRow() const override;
253 virtual void activateCell( ColPos const i_col, RowPos const i_row ) override;
254 virtual ::Size getTableSizePixel() const override;
255 virtual void setPointer( PointerStyle i_pointer ) override;
256 virtual void captureMouse() override;
257 virtual void releaseMouse() override;
258 virtual void invalidate( TableArea const i_what ) override;
259 virtual tools::Long pixelWidthToAppFont( tools::Long const i_pixels ) const override;
260 virtual void hideTracking() override;
261 virtual void showTracking( tools::Rectangle const & i_location, ShowTrackFlags const i_flags ) override;
262 RowPos getRowAtPoint( const Point& rPoint ) const;
263 ColPos getColAtPoint( const Point& rPoint ) const;
264 virtual TableCell hitTest( const Point& rPoint ) const override;
265 virtual ColumnMetrics getColumnMetrics( ColPos const i_column ) const override;
266 virtual bool isRowSelected( RowPos i_row ) const override;
269 tools::Long appFontWidthToPixel( tools::Long const i_appFontUnits ) const;
271 TableDataWindow& getDataWindow() { return *m_pDataWindow; }
272 const TableDataWindow& getDataWindow() const { return *m_pDataWindow; }
273 ScrollBar* getHorzScrollbar() { return m_pHScroll; }
274 ScrollBar* getVertScrollbar() { return m_pVScroll; }
276 tools::Rectangle calcHeaderRect( bool bColHeader );
277 tools::Rectangle calcHeaderCellRect( bool bColHeader, sal_Int32 nPos );
278 tools::Rectangle calcTableRect() const;
279 tools::Rectangle calcCellRect( sal_Int32 nRow, sal_Int32 nCol ) const;
281 // A11Y
282 css::uno::Reference< css::accessibility::XAccessible >
283 getAccessible( vcl::Window& i_parentWindow );
284 void disposeAccessible();
286 bool isAccessibleAlive() const { return impl_isAccessibleAlive(); }
288 // ITableModelListener
289 virtual void rowsInserted( RowPos first, RowPos last ) override;
290 virtual void rowsRemoved( RowPos first, RowPos last ) override;
291 virtual void columnInserted() override;
292 virtual void columnRemoved() override;
293 virtual void allColumnsRemoved() override;
294 virtual void cellsUpdated( RowPos const i_firstRow, RowPos const i_lastRow ) override;
295 virtual void columnChanged( ColPos const i_column, ColumnAttributeGroup const i_attributeGroup ) override;
296 virtual void tableMetricsChanged() override;
298 private:
299 bool impl_isAccessibleAlive() const;
300 void impl_commitAccessibleEvent(
301 sal_Int16 const i_eventID,
302 css::uno::Any const & i_newValue
305 /** toggles the cursor visibility
307 The method is not bound to the classes public invariants, as it's used in
308 situations where the they must not necessarily be fulfilled.
310 void impl_ni_doSwitchCursor( bool _bOn );
312 /** returns the number of visible rows.
314 @param _bAcceptPartialRow
315 specifies whether a possible only partially visible last row is
316 counted, too.
318 TableSize impl_getVisibleRows( bool _bAcceptPartialRow ) const;
320 /** returns the number of visible columns
322 The value may change with different horizontal scroll positions, as
323 different columns have different widths. For instance, if your control is
324 100 pixels wide, and has three columns of width 50, 50, 100, respectively,
325 then this method will return either "2" or "1", depending on which column
326 is the first visible one.
328 @param _bAcceptPartialRow
329 specifies whether a possible only partially visible last row is
330 counted, too.
332 TableSize impl_getVisibleColumns( bool _bAcceptPartialCol ) const;
334 /** determines the rectangle occupied by the given cell
336 void impl_getCellRect( ColPos _nColumn, RowPos _nRow, tools::Rectangle& _rCellRect ) const;
338 /** updates all cached model values
340 The method is not bound to the classes public invariants, as it's used in
341 situations where the they must not necessarily be fulfilled.
343 void impl_ni_updateCachedModelValues();
345 /** updates the cached table metrics (row height etc.)
347 void impl_ni_updateCachedTableMetrics();
349 /** does a relayout of the table control
351 Column widths, and consequently the availability of the vertical and horizontal scrollbar, are updated
352 with a call to this method.
354 @param i_assumeInflexibleColumnsUpToIncluding
355 the index of a column up to which all columns should be considered as inflexible, or
356 <code>COL_INVALID</code>.
358 void impl_ni_relayout( ColPos const i_assumeInflexibleColumnsUpToIncluding = COL_INVALID );
360 /** calculates the new width of our columns, taking into account their min and max widths, and their relative
361 flexibility.
363 @param i_assumeInflexibleColumnsUpToIncluding
364 the index of a column up to which all columns should be considered as inflexible, or
365 <code>COL_INVALID</code>.
367 @param i_assumeVerticalScrollbar
368 controls whether or not we should assume the presence of a vertical scrollbar. If <true/>, and
369 if the model has a VerticalScrollbarVisibility != ScrollbarShowNever, the method will leave
370 space for a vertical scrollbar.
372 @return
373 the overall width of the grid, which is available for columns
375 tools::Long impl_ni_calculateColumnWidths(
376 ColPos const i_assumeInflexibleColumnsUpToIncluding,
377 bool const i_assumeVerticalScrollbar,
378 ::std::vector< tools::Long >& o_newColWidthsPixel
379 ) const;
381 /** positions all child windows, e.g. the both scrollbars, the corner window, and the data window
383 void impl_ni_positionChildWindows(
384 tools::Rectangle const & i_dataCellPlayground,
385 bool const i_verticalScrollbar,
386 bool const i_horizontalScrollbar
389 /** scrolls the view by the given number of rows
391 The method is not bound to the classes public invariants, as it's used in
392 situations where the they must not necessarily be fulfilled.
394 @return
395 the number of rows by which the viewport was scrolled. This may differ
396 from the given numbers to scroll in case the begin or the end of the
397 row range were reached.
399 TableSize impl_ni_ScrollRows( TableSize _nRowDelta );
401 /** equivalent to impl_ni_ScrollRows, but checks the instances invariants beforehand (in a non-product build only)
403 TableSize impl_scrollRows( TableSize const i_rowDelta );
405 /** scrolls the view by the given number of columns
407 The method is not bound to the classes public invariants, as it's used in
408 situations where the they must not necessarily be fulfilled.
410 @return
411 the number of columns by which the viewport was scrolled. This may differ
412 from the given numbers to scroll in case the begin or the end of the
413 column range were reached.
415 TableSize impl_ni_ScrollColumns( TableSize _nColumnDelta );
417 /** equivalent to impl_ni_ScrollColumns, but checks the instances invariants beforehand (in a non-product build only)
419 TableSize impl_scrollColumns( TableSize const i_columnDelta );
421 /** retrieves the area occupied by the totality of (at least partially) visible cells
423 The returned area includes row and column headers. Also, it takes into
424 account the fact that there might be less columns than would normally
425 find room in the control.
427 As a result of respecting the partial visibility of rows and columns,
428 the returned area might be larger than the data window's output size.
430 tools::Rectangle impl_getAllVisibleCellsArea() const;
432 /** retrieves the area occupied by all (at least partially) visible data cells.
434 Effectively, the returned area is the same as returned by ->impl_getAllVisibleCellsArea,
435 minus the row and column header areas.
437 tools::Rectangle impl_getAllVisibleDataCellArea() const;
439 /** retrieves the column which covers the given ordinate
441 ColPos impl_getColumnForOrdinate( tools::Long const i_ordinate ) const;
443 /** retrieves the row which covers the given abscissa
445 RowPos impl_getRowForAbscissa( tools::Long const i_abscissa ) const;
447 /// invalidates the window area occupied by the given column
448 void impl_invalidateColumn( ColPos const i_column );
450 DECL_LINK( OnScroll, ScrollBar*, void );
451 DECL_LINK( OnUpdateScrollbars, void*, void );
454 //see seleng.hxx, seleng.cxx, FunctionSet overridables, part of selection engine
455 class TableFunctionSet : public FunctionSet
457 private:
458 TableControl_Impl* m_pTableControl;
459 RowPos m_nCurrentRow;
461 public:
462 explicit TableFunctionSet(TableControl_Impl* _pTableControl);
463 virtual ~TableFunctionSet() override;
465 virtual void BeginDrag() override;
466 virtual void CreateAnchor() override;
467 virtual void DestroyAnchor() override;
468 virtual void SetCursorAtPoint(const Point& rPoint, bool bDontSelectAtCursor = false) override;
469 virtual bool IsSelectionAtPoint( const Point& rPoint ) override;
470 virtual void DeselectAtPoint( const Point& rPoint ) override;
471 virtual void DeselectAll() override;
475 } // namespace svt::table
479 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */