tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / toolkit / source / controls / table / tablecontrol_impl.hxx
blobbbfc56d1092e3f3cc389f2a2f2a0f872b1ac1948
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 <com/sun/star/accessibility/XAccessible.hpp>
23 #include <controls/table/tablemodel.hxx>
24 #include <controls/table/tablecontrolinterface.hxx>
26 #include <vcl/svtaccessiblefactory.hxx>
27 #include <vcl/accessibletable.hxx>
29 #include <vcl/seleng.hxx>
31 #include <vector>
33 class ScrollBar;
34 class ScrollBarBox;
36 namespace svt::table
38 struct MutableColumnMetrics : public ColumnMetrics
40 MutableColumnMetrics()
41 :ColumnMetrics()
45 MutableColumnMetrics( tools::Long const i_startPixel, tools::Long const i_endPixel )
46 :ColumnMetrics( i_startPixel, i_endPixel )
50 tools::Long getStart() const { return nStartPixel; }
51 tools::Long getEnd() const { return nEndPixel; }
53 void move( tools::Long const i_offset ) { nStartPixel += i_offset; nEndPixel += i_offset; }
55 tools::Long getWidth() const { return nEndPixel - nStartPixel; }
58 struct ColumnInfoPositionLess
60 bool operator()( MutableColumnMetrics const& i_lhs, MutableColumnMetrics const& i_rhs )
62 return i_lhs.getEnd() < i_rhs.getStart();
66 typedef ::std::vector< MutableColumnMetrics > ColumnPositions;
68 class TableControl;
69 class TableDataWindow;
70 class TableFunctionSet;
73 //= TableControl_Impl
75 class TableControl_Impl :public ITableControl
76 ,public ITableModelListener
78 friend class TableGeometry;
79 friend class TableRowGeometry;
80 friend class TableColumnGeometry;
81 friend class SuspendInvariants;
83 private:
84 /// the control whose impl-instance we implement
85 TableControl& m_rAntiImpl;
86 /// the model of the table control
87 PTableModel m_pModel;
88 /// the input handler to use, usually the input handler as provided by ->m_pModel
89 PTableInputHandler m_pInputHandler;
90 /// info about the widths of our columns
91 ColumnPositions m_aColumnWidths;
93 /// the height of a single row in the table, measured in pixels
94 tools::Long m_nRowHeightPixel;
95 /// the height of the column header row in the table, measured in pixels
96 tools::Long m_nColHeaderHeightPixel;
97 /// the width of the row header column in the table, measured in pixels
98 tools::Long m_nRowHeaderWidthPixel;
100 /// the number of columns in the table control. Cached model value.
101 TableSize m_nColumnCount;
103 /// the number of rows in the table control. Cached model value.
104 TableSize m_nRowCount;
106 ColPos m_nCurColumn;
107 RowPos m_nCurRow;
108 ColPos m_nLeftColumn;
109 RowPos m_nTopRow;
111 sal_Int32 m_nCursorHidden;
113 /** the window to contain all data content, including header bars
115 The window's upper left corner is at position (0,0), relative to the
116 table control, which is the direct parent of the data window.
118 VclPtr<TableDataWindow> m_pDataWindow;
119 /// the vertical scrollbar, if any
120 VclPtr<ScrollBar> m_pVScroll;
121 /// the horizontal scrollbar, if any
122 VclPtr<ScrollBar> m_pHScroll;
123 VclPtr<ScrollBarBox> m_pScrollCorner;
124 //selection engine - for determining selection range, e.g. single, multiple
125 std::unique_ptr<SelectionEngine> m_pSelEngine;
126 //vector which contains the selected rows
127 std::vector<RowPos> m_aSelectedRows;
128 //part of selection engine
129 std::unique_ptr<TableFunctionSet> m_pTableFunctionSet;
130 //part of selection engine
131 RowPos m_nAnchor;
132 bool m_bUpdatingColWidths;
134 vcl::AccessibleFactoryAccess m_aFactoryAccess;
135 rtl::Reference<vcl::table::IAccessibleTableControl> m_pAccessibleTable;
137 public:
138 void setModel( const PTableModel& _pModel );
140 const PTableInputHandler& getInputHandler() const { return m_pInputHandler; }
142 RowPos getCurRow() const { return m_nCurRow; }
144 RowPos getAnchor() const { return m_nAnchor; }
145 void setAnchor( RowPos const i_anchor ) { m_nAnchor = i_anchor; }
147 RowPos getTopRow() const { return m_nTopRow; }
148 ColPos getLeftColumn() const { return m_nLeftColumn; }
150 const TableControl& getAntiImpl() const { return m_rAntiImpl; }
151 TableControl& getAntiImpl() { return m_rAntiImpl; }
153 public:
154 explicit TableControl_Impl( TableControl& _rAntiImpl );
155 virtual ~TableControl_Impl() override;
157 /** to be called when the anti-impl instance has been resized
159 void onResize();
161 /** paints the table control content which intersects with the given rectangle
163 void doPaintContent(vcl::RenderContext& rRenderContext, const tools::Rectangle& _rUpdateRect);
165 /** moves the cursor to the cell with the given coordinates
167 To ease the caller's code, the coordinates must not necessarily denote a
168 valid position. If they don't, <FALSE/> will be returned.
170 bool goTo( ColPos _nColumn, RowPos _nRow );
172 /** ensures that the given coordinate is visible
173 @param _nColumn
174 the column position which should be visible. Must be non-negative, and smaller
175 than the column count.
176 @param _nRow
177 the row position which should be visibleMust be non-negative, and smaller
178 than the row count.
180 void ensureVisible( ColPos _nColumn, RowPos _nRow );
182 /** retrieves the content of the given cell, converted to a string
184 OUString getCellContentAsString( RowPos const i_row, ColPos const i_col );
186 /** returns the position of the current row in the selection vector */
187 static int getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current);
189 void invalidateRect(const tools::Rectangle &rInvalidateRect);
191 /** ??? */
192 void invalidateSelectedRegion( RowPos _nPrevRow, RowPos _nCurRow );
194 /** invalidates the part of the data window which is covered by the given rows
195 @param i_firstRow
196 the index of the first row to include in the invalidation
197 @param i_lastRow
198 the index of the last row to include in the invalidation, or ROW_INVALID if the invalidation
199 should happen down to the bottom of the data window.
201 void invalidateRowRange( RowPos const i_firstRow, RowPos const i_lastRow );
203 /** invalidates the part of the data window which is covered by the given row
205 void invalidateRow( RowPos const i_row ) { invalidateRowRange( i_row, i_row ); }
207 /** invalidates all selected rows
209 void invalidateSelectedRows();
211 void checkCursorPosition();
213 bool hasRowSelection() const { return !m_aSelectedRows.empty(); }
214 size_t getSelectedRowCount() const { return m_aSelectedRows.size(); }
215 RowPos getSelectedRowIndex( size_t const i_selectionIndex ) const;
217 /** removes the given row index from m_aSelectedRows
219 @return
220 <TRUE/> if and only if the row was previously marked as selected
222 bool markRowAsDeselected( RowPos const i_rowIndex );
224 /** marks the given row as selected, by putting it into m_aSelectedRows
225 @return
226 <TRUE/> if and only if the row was previously <em>not</em> marked as selected
228 bool markRowAsSelected( RowPos const i_rowIndex );
230 /** marks all rows as deselected
231 @return
232 <TRUE/> if and only if the selection actually changed by this operation
234 bool markAllRowsAsDeselected();
236 /** marks all rows as selected
237 @return
238 <FALSE/> if and only if all rows were selected already.
240 bool markAllRowsAsSelected();
242 void commitAccessibleEvent( sal_Int16 const i_eventID );
243 void commitCellEvent( sal_Int16 const i_eventID, const css::uno::Any& i_newValue, const css::uno::Any& i_oldValue );
244 void commitTableEvent( sal_Int16 const i_eventID, const css::uno::Any& i_newValue, const css::uno::Any& i_oldValue );
246 // ITableControl
247 virtual void hideCursor() override;
248 virtual void showCursor() override;
249 virtual bool dispatchAction( TableControlAction _eAction ) override;
250 virtual SelectionEngine* getSelEngine() override;
251 virtual PTableModel getModel() const override;
252 virtual ColPos getCurrentColumn() const override;
253 virtual RowPos getCurrentRow() const override;
254 virtual void activateCell( ColPos const i_col, RowPos const i_row ) override;
255 virtual ::Size getTableSizePixel() const override;
256 virtual void setPointer( PointerStyle i_pointer ) override;
257 virtual void captureMouse() override;
258 virtual void releaseMouse() override;
259 virtual void invalidate( TableArea const i_what ) override;
260 virtual tools::Long pixelWidthToAppFont( tools::Long const i_pixels ) const override;
261 virtual void hideTracking() override;
262 virtual void showTracking( tools::Rectangle const & i_location, ShowTrackFlags const i_flags ) override;
263 RowPos getRowAtPoint( const Point& rPoint ) const;
264 ColPos getColAtPoint( const Point& rPoint ) const;
265 virtual TableCell hitTest( const Point& rPoint ) const override;
266 virtual ColumnMetrics getColumnMetrics( ColPos const i_column ) const override;
267 virtual bool isRowSelected( RowPos i_row ) const override;
270 tools::Long appFontWidthToPixel( tools::Long const i_appFontUnits ) const;
272 TableDataWindow& getDataWindow() { return *m_pDataWindow; }
273 const TableDataWindow& getDataWindow() const { return *m_pDataWindow; }
274 ScrollBar* getHorzScrollbar() { return m_pHScroll; }
275 ScrollBar* getVertScrollbar() { return m_pVScroll; }
277 tools::Rectangle calcHeaderRect( bool bColHeader );
278 tools::Rectangle calcHeaderCellRect( bool bColHeader, sal_Int32 nPos );
279 tools::Rectangle calcTableRect() const;
280 tools::Rectangle calcCellRect( sal_Int32 nRow, sal_Int32 nCol ) const;
282 // A11Y
283 const rtl::Reference<vcl::table::IAccessibleTableControl> &
284 getAccessible( vcl::Window& i_parentWindow );
285 void disposeAccessible();
287 bool isAccessibleAlive() const { return impl_isAccessibleAlive(); }
289 // ITableModelListener
290 virtual void rowsInserted( RowPos first, RowPos last ) override;
291 virtual void rowsRemoved( RowPos first, RowPos last ) override;
292 virtual void columnInserted() override;
293 virtual void columnRemoved() override;
294 virtual void allColumnsRemoved() override;
295 virtual void cellsUpdated( RowPos const i_firstRow, RowPos const i_lastRow ) override;
296 virtual void columnChanged( ColPos const i_column, ColumnAttributeGroup const i_attributeGroup ) override;
297 virtual void tableMetricsChanged() override;
299 private:
300 bool impl_isAccessibleAlive() const;
301 void impl_commitAccessibleEvent(
302 sal_Int16 const i_eventID,
303 css::uno::Any const & i_newValue
306 /** toggles the cursor visibility
308 The method is not bound to the classes public invariants, as it's used in
309 situations where the they must not necessarily be fulfilled.
311 void impl_ni_doSwitchCursor( bool _bOn );
313 /** returns the number of visible rows.
315 @param _bAcceptPartialRow
316 specifies whether a possible only partially visible last row is
317 counted, too.
319 TableSize impl_getVisibleRows( bool _bAcceptPartialRow ) const;
321 /** returns the number of visible columns
323 The value may change with different horizontal scroll positions, as
324 different columns have different widths. For instance, if your control is
325 100 pixels wide, and has three columns of width 50, 50, 100, respectively,
326 then this method will return either "2" or "1", depending on which column
327 is the first visible one.
329 @param _bAcceptPartialRow
330 specifies whether a possible only partially visible last row is
331 counted, too.
333 TableSize impl_getVisibleColumns( bool _bAcceptPartialCol ) const;
335 /** determines the rectangle occupied by the given cell
337 void impl_getCellRect( ColPos _nColumn, RowPos _nRow, tools::Rectangle& _rCellRect ) const;
339 /** updates all cached model values
341 The method is not bound to the classes public invariants, as it's used in
342 situations where the they must not necessarily be fulfilled.
344 void impl_ni_updateCachedModelValues();
346 /** updates the cached table metrics (row height etc.)
348 void impl_ni_updateCachedTableMetrics();
350 /** does a relayout of the table control
352 Column widths, and consequently the availability of the vertical and horizontal scrollbar, are updated
353 with a call to this method.
355 @param i_assumeInflexibleColumnsUpToIncluding
356 the index of a column up to which all columns should be considered as inflexible, or
357 <code>COL_INVALID</code>.
359 void impl_ni_relayout( ColPos const i_assumeInflexibleColumnsUpToIncluding = COL_INVALID );
361 /** calculates the new width of our columns, taking into account their min and max widths, and their relative
362 flexibility.
364 @param i_assumeInflexibleColumnsUpToIncluding
365 the index of a column up to which all columns should be considered as inflexible, or
366 <code>COL_INVALID</code>.
368 @param i_assumeVerticalScrollbar
369 controls whether or not we should assume the presence of a vertical scrollbar. If <true/>, and
370 if the model has a VerticalScrollbarVisibility != ScrollbarShowNever, the method will leave
371 space for a vertical scrollbar.
373 @return
374 the overall width of the grid, which is available for columns
376 tools::Long impl_ni_calculateColumnWidths(
377 ColPos const i_assumeInflexibleColumnsUpToIncluding,
378 bool const i_assumeVerticalScrollbar,
379 ::std::vector< tools::Long >& o_newColWidthsPixel
380 ) const;
382 /** positions all child windows, e.g. the both scrollbars, the corner window, and the data window
384 void impl_ni_positionChildWindows(
385 tools::Rectangle const & i_dataCellPlayground,
386 bool const i_verticalScrollbar,
387 bool const i_horizontalScrollbar
390 /** scrolls the view by the given number of rows
392 The method is not bound to the classes public invariants, as it's used in
393 situations where the they must not necessarily be fulfilled.
395 @return
396 the number of rows by which the viewport was scrolled. This may differ
397 from the given numbers to scroll in case the begin or the end of the
398 row range were reached.
400 TableSize impl_ni_ScrollRows( TableSize _nRowDelta );
402 /** equivalent to impl_ni_ScrollRows, but checks the instances invariants beforehand (in a non-product build only)
404 TableSize impl_scrollRows( TableSize const i_rowDelta );
406 /** scrolls the view by the given number of columns
408 The method is not bound to the classes public invariants, as it's used in
409 situations where the they must not necessarily be fulfilled.
411 @return
412 the number of columns by which the viewport was scrolled. This may differ
413 from the given numbers to scroll in case the begin or the end of the
414 column range were reached.
416 TableSize impl_ni_ScrollColumns( TableSize _nColumnDelta );
418 /** equivalent to impl_ni_ScrollColumns, but checks the instances invariants beforehand (in a non-product build only)
420 TableSize impl_scrollColumns( TableSize const i_columnDelta );
422 /** retrieves the area occupied by the totality of (at least partially) visible cells
424 The returned area includes row and column headers. Also, it takes into
425 account the fact that there might be less columns than would normally
426 find room in the control.
428 As a result of respecting the partial visibility of rows and columns,
429 the returned area might be larger than the data window's output size.
431 tools::Rectangle impl_getAllVisibleCellsArea() const;
433 /** retrieves the area occupied by all (at least partially) visible data cells.
435 Effectively, the returned area is the same as returned by ->impl_getAllVisibleCellsArea,
436 minus the row and column header areas.
438 tools::Rectangle impl_getAllVisibleDataCellArea() const;
440 /** retrieves the column which covers the given ordinate
442 ColPos impl_getColumnForOrdinate( tools::Long const i_ordinate ) const;
444 /** retrieves the row which covers the given abscissa
446 RowPos impl_getRowForAbscissa( tools::Long const i_abscissa ) const;
448 /// invalidates the window area occupied by the given column
449 void impl_invalidateColumn( ColPos const i_column );
451 DECL_LINK( OnScroll, ScrollBar*, void );
452 DECL_LINK( OnUpdateScrollbars, void*, void );
455 //see seleng.hxx, seleng.cxx, FunctionSet overridables, part of selection engine
456 class TableFunctionSet : public FunctionSet
458 private:
459 TableControl_Impl* m_pTableControl;
460 RowPos m_nCurrentRow;
462 public:
463 explicit TableFunctionSet(TableControl_Impl* _pTableControl);
464 virtual ~TableFunctionSet() override;
466 virtual void BeginDrag() override;
467 virtual void CreateAnchor() override;
468 virtual void DestroyAnchor() override;
469 virtual void SetCursorAtPoint(const Point& rPoint, bool bDontSelectAtCursor = false) override;
470 virtual bool IsSelectionAtPoint( const Point& rPoint ) override;
471 virtual void DeselectAtPoint( const Point& rPoint ) override;
472 virtual void DeselectAll() override;
476 } // namespace svt::table
480 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */