Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 : : *
5 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
6 : : *
7 : : * OpenOffice.org - a multi-platform office productivity suite
8 : : *
9 : : * This file is part of OpenOffice.org.
10 : : *
11 : : * OpenOffice.org is free software: you can redistribute it and/or modify
12 : : * it under the terms of the GNU Lesser General Public License version 3
13 : : * only, as published by the Free Software Foundation.
14 : : *
15 : : * OpenOffice.org is distributed in the hope that it will be useful,
16 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : : * GNU Lesser General Public License version 3 for more details
19 : : * (a copy is included in the LICENSE file that accompanied this code).
20 : : *
21 : : * You should have received a copy of the GNU Lesser General Public License
22 : : * version 3 along with OpenOffice.org. If not, see
23 : : * <http://www.openoffice.org/license.html>
24 : : * for a copy of the LGPLv3 License.
25 : : *
26 : : ************************************************************************/
27 : :
28 : : #ifndef SVTOOLS_TABLECONTROL_IMPL_HXX
29 : : #define SVTOOLS_TABLECONTROL_IMPL_HXX
30 : :
31 : : #include "svtools/table/tablemodel.hxx"
32 : : #include "svtools/table/tablecontrolinterface.hxx"
33 : :
34 : : #include "svtaccessiblefactory.hxx"
35 : :
36 : : #include <vcl/seleng.hxx>
37 : :
38 : : #include <vector>
39 : :
40 : : #include <boost/scoped_ptr.hpp>
41 : :
42 : : class ScrollBar;
43 : : class ScrollBarBox;
44 : :
45 : : //........................................................................
46 : : namespace svt { namespace table
47 : : {
48 : : //........................................................................
49 : :
50 : : struct MutableColumnMetrics : protected ColumnMetrics
51 : : {
52 : 0 : MutableColumnMetrics()
53 : 0 : :ColumnMetrics()
54 : : {
55 : 0 : }
56 : :
57 : 0 : MutableColumnMetrics( long const i_startPixel, long const i_endPixel )
58 : 0 : :ColumnMetrics( i_startPixel, i_endPixel )
59 : : {
60 : 0 : }
61 : :
62 : 0 : long getStart() const { return nStartPixel; }
63 : 0 : long getEnd() const { return nEndPixel; }
64 : :
65 : : void setEnd( long const i_end ) { nEndPixel = i_end; }
66 : 0 : void move( long const i_offset ) { nStartPixel += i_offset; nEndPixel += i_offset; }
67 : :
68 : 0 : long getWidth() const { return nEndPixel - nStartPixel; }
69 : :
70 : : ColumnMetrics const & operator()() { return *this; }
71 : : };
72 : :
73 : : struct ColumnInfoPositionLess
74 : : {
75 : 0 : bool operator()( MutableColumnMetrics const& i_lhs, MutableColumnMetrics const& i_rhs )
76 : : {
77 : 0 : return i_lhs.getEnd() < i_rhs.getStart();
78 : : }
79 : : };
80 : :
81 : : typedef ::std::vector< MutableColumnMetrics > ColumnPositions;
82 : :
83 : : class TableControl;
84 : : class TableDataWindow;
85 : : class TableFunctionSet;
86 : :
87 : : //====================================================================
88 : : //= TableControl_Impl
89 : : //====================================================================
90 : : class TableControl_Impl :public ITableControl
91 : : ,public ITableModelListener
92 : : {
93 : : friend class TableGeometry;
94 : : friend class TableRowGeometry;
95 : : friend class TableColumnGeometry;
96 : : friend class SuspendInvariants;
97 : :
98 : : private:
99 : : /// the control whose impl-instance we implemnt
100 : : TableControl& m_rAntiImpl;
101 : : /// the model of the table control
102 : : PTableModel m_pModel;
103 : : /// the input handler to use, usually the input handler as provided by ->m_pModel
104 : : PTableInputHandler m_pInputHandler;
105 : : /// info about the widths of our columns
106 : : ColumnPositions m_aColumnWidths;
107 : :
108 : : /// the height of a single row in the table, measured in pixels
109 : : long m_nRowHeightPixel;
110 : : /// the height of the column header row in the table, measured in pixels
111 : : long m_nColHeaderHeightPixel;
112 : : /// the width of the row header column in the table, measured in pixels
113 : : long m_nRowHeaderWidthPixel;
114 : :
115 : : /// the number of columns in the table control. Cached model value.
116 : : TableSize m_nColumnCount;
117 : :
118 : : /// the number of rows in the table control. Cached model value.
119 : : TableSize m_nRowCount;
120 : :
121 : : /// denotes whether or not the columns fitted into the available width, last time we checked
122 : : long m_bColumnsFit;
123 : :
124 : : ColPos m_nCurColumn;
125 : : RowPos m_nCurRow;
126 : : ColPos m_nLeftColumn;
127 : : RowPos m_nTopRow;
128 : :
129 : : sal_Int32 m_nCursorHidden;
130 : :
131 : : /** the window to contain all data content, including header bars
132 : :
133 : : The window's upper left corner is at position (0,0), relative to the
134 : : table control, which is the direct parent of the data window.
135 : : */
136 : : ::boost::scoped_ptr< TableDataWindow >
137 : : m_pDataWindow;
138 : : /// the vertical scrollbar, if any
139 : : ScrollBar* m_pVScroll;
140 : : /// the horizontal scrollbar, if any
141 : : ScrollBar* m_pHScroll;
142 : : ScrollBarBox* m_pScrollCorner;
143 : : //selection engine - for determining selection range, e.g. single, multiple
144 : : SelectionEngine* m_pSelEngine;
145 : : //vector which contains the selected rows
146 : : std::vector<RowPos> m_aSelectedRows;
147 : : //part of selection engine
148 : : TableFunctionSet* m_pTableFunctionSet;
149 : : //part of selection engine
150 : : RowPos m_nAnchor;
151 : : bool m_bUpdatingColWidths;
152 : :
153 : : Link m_aSelectHdl;
154 : :
155 : : AccessibleFactoryAccess m_aFactoryAccess;
156 : : IAccessibleTableControl* m_pAccessibleTable;
157 : :
158 : : #if DBG_UTIL
159 : : #define INV_SCROLL_POSITION 1
160 : : /** represents a bitmask of invariants to check
161 : :
162 : : Actually, impl_checkInvariants checks more invariants than denoted in this
163 : : bit mask, but only those present here can be disabled temporarily.
164 : : */
165 : : sal_Int32 m_nRequiredInvariants;
166 : : #endif
167 : :
168 : : public:
169 : : void setModel( PTableModel _pModel );
170 : :
171 : 0 : inline const PTableInputHandler& getInputHandler() const { return m_pInputHandler; }
172 : :
173 : 0 : inline RowPos getCurRow() const { return m_nCurRow; }
174 : : inline void setCurRow( RowPos i_curRow ){ m_nCurRow = i_curRow; }
175 : :
176 : 0 : RowPos getAnchor() const { return m_nAnchor; }
177 : 0 : void setAnchor( RowPos const i_anchor ) { m_nAnchor = i_anchor; }
178 : :
179 : 0 : inline RowPos getTopRow() const { return m_nTopRow; }
180 : 0 : inline ColPos getLeftColumn() const { return m_nLeftColumn; }
181 : :
182 : : inline const TableControl& getAntiImpl() const { return m_rAntiImpl; }
183 : 0 : inline TableControl& getAntiImpl() { return m_rAntiImpl; }
184 : :
185 : : public:
186 : : TableControl_Impl( TableControl& _rAntiImpl );
187 : : ~TableControl_Impl();
188 : :
189 : : #if DBG_UTIL
190 : : const sal_Char* impl_checkInvariants() const;
191 : : #endif
192 : : /** to be called when the anti-impl instance has been resized
193 : : */
194 : : void onResize();
195 : :
196 : : /** paints the table control content which intersects with the given rectangle
197 : : */
198 : : void doPaintContent( const Rectangle& _rUpdateRect );
199 : :
200 : : /** moves the cursor to the cell with the given coordinates
201 : :
202 : : To ease the caller's code, the coordinates must not necessarily denote a
203 : : valid position. If they don't, <FALSE/> will be returned.
204 : : */
205 : : bool goTo( ColPos _nColumn, RowPos _nRow );
206 : :
207 : : /** ensures that the given coordinate is visible
208 : : @param _nColumn
209 : : the column position which should be visible. Must be non-negative, and smaller
210 : : than the column count.
211 : : @param _nRow
212 : : the row position which should be visibleMust be non-negative, and smaller
213 : : than the row count.
214 : : @param _bAcceptPartialVisibility
215 : : <TRUE/> if it's okay that the given cooordinate is only partially visible
216 : : */
217 : : void ensureVisible( ColPos _nColumn, RowPos _nRow, bool _bAcceptPartialVisibility );
218 : :
219 : : /** retrieves the content of the given cell, converted to a string
220 : : */
221 : : ::rtl::OUString getCellContentAsString( RowPos const i_row, ColPos const i_col );
222 : :
223 : : /** returns the position of the current row in the selection vector */
224 : : int getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current);
225 : :
226 : : /** _rCellRect contains the region, which should be invalidate after some action e.g. selecting row*/
227 : : void invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect );
228 : :
229 : : /** invalidates the part of the data window which is covered by the given row
230 : : @param i_firstRow
231 : : the index of the first row to include in the invalidation
232 : : @param i_lastRow
233 : : the index of the last row to include in the invalidation, or ROW_INVALID if the invalidation
234 : : should happen down to the bottom of the data window.
235 : : */
236 : : void invalidateRowRange( RowPos const i_firstRow, RowPos const i_lastRow );
237 : :
238 : : void checkCursorPosition();
239 : :
240 : 0 : bool hasRowSelection() const { return !m_aSelectedRows.empty(); }
241 : 0 : size_t getSelectedRowCount() const { return m_aSelectedRows.size(); }
242 : : RowPos getSelectedRowIndex( size_t const i_selectionIndex ) const;
243 : :
244 : : /** removes the given row index from m_aSelectedRows
245 : :
246 : : @return
247 : : <TRUE/> if and only if the row was previously marked as selected
248 : : */
249 : : bool markRowAsDeselected( RowPos const i_rowIndex );
250 : :
251 : : /** marks the given row as selectged, by putting it into m_aSelectedRows
252 : : @return
253 : : <TRUE/> if and only if the row was previously <em>not</em> marked as selected
254 : : */
255 : : bool markRowAsSelected( RowPos const i_rowIndex );
256 : :
257 : : /** marks all rows as deselected
258 : : @return
259 : : <TRUE/> if and only if the selection actually changed by this operation
260 : : */
261 : : bool markAllRowsAsDeselected();
262 : :
263 : : /** marks all rows as selected
264 : : @return
265 : : <FALSE/> if and only if all rows were selected already.
266 : : */
267 : : bool markAllRowsAsSelected();
268 : :
269 : : void setSelectHandler( Link const & i_selectHandler ) { m_aSelectHdl = i_selectHandler; }
270 : 0 : Link const& getSelectHandler() const { return m_aSelectHdl; }
271 : :
272 : : // ITableControl
273 : : virtual void hideCursor();
274 : : virtual void showCursor();
275 : : virtual bool dispatchAction( TableControlAction _eAction );
276 : : virtual SelectionEngine* getSelEngine();
277 : : virtual PTableModel getModel() const;
278 : : virtual ColPos getCurrentColumn() const;
279 : : virtual RowPos getCurrentRow() const;
280 : : virtual bool activateCell( ColPos const i_col, RowPos const i_row );
281 : : virtual ::Size getTableSizePixel() const;
282 : : virtual void setPointer( Pointer const & i_pointer );
283 : : virtual void captureMouse();
284 : : virtual void releaseMouse();
285 : : virtual void invalidate( TableArea const i_what );
286 : : virtual long pixelWidthToAppFont( long const i_pixels ) const;
287 : : virtual void hideTracking();
288 : : virtual void showTracking( Rectangle const & i_location, sal_uInt16 const i_flags );
289 : : virtual RowPos getRowAtPoint( const Point& rPoint ) const;
290 : : virtual ColPos getColAtPoint( const Point& rPoint ) const;
291 : : virtual TableCell hitTest( const Point& rPoint ) const;
292 : : virtual ColumnMetrics getColumnMetrics( ColPos const i_column ) const;
293 : : virtual bool isRowSelected( RowPos i_row ) const;
294 : :
295 : :
296 : 0 : TableDataWindow& getDataWindow() { return *m_pDataWindow; }
297 : : const TableDataWindow& getDataWindow() const { return *m_pDataWindow; }
298 : : ScrollBar* getHorzScrollbar();
299 : : ScrollBar* getVertScrollbar();
300 : :
301 : : Rectangle calcHeaderRect(bool bColHeader);
302 : : Rectangle calcTableRect();
303 : :
304 : : // A11Y
305 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
306 : : getAccessible( Window& i_parentWindow );
307 : : void disposeAccessible();
308 : :
309 : : // ITableModelListener
310 : : virtual void rowsInserted( RowPos first, RowPos last );
311 : : virtual void rowsRemoved( RowPos first, RowPos last );
312 : : virtual void columnInserted( ColPos const i_colIndex );
313 : : virtual void columnRemoved( ColPos const i_colIndex );
314 : : virtual void allColumnsRemoved();
315 : : virtual void cellsUpdated( ColPos const i_firstCol, ColPos i_lastCol, RowPos const i_firstRow, RowPos const i_lastRow );
316 : : virtual void columnChanged( ColPos const i_column, ColumnAttributeGroup const i_attributeGroup );
317 : : virtual void tableMetricsChanged();
318 : :
319 : : private:
320 : : bool impl_isAccessibleAlive() const;
321 : : void impl_commitAccessibleEvent(
322 : : sal_Int16 const i_eventID,
323 : : ::com::sun::star::uno::Any const & i_newValue,
324 : : ::com::sun::star::uno::Any const & i_oldValue
325 : : );
326 : :
327 : : /** toggles the cursor visibility
328 : :
329 : : The method is not bound to the classes public invariants, as it's used in
330 : : situations where the they must not necessarily be fullfilled.
331 : : */
332 : : void impl_ni_doSwitchCursor( bool _bOn );
333 : :
334 : : /** returns the number of visible rows.
335 : :
336 : : @param _bAcceptPartialRow
337 : : specifies whether a possible only partially visible last row is
338 : : counted, too.
339 : : */
340 : : TableSize impl_getVisibleRows( bool _bAcceptPartialRow ) const;
341 : :
342 : : /** returns the number of visible columns
343 : :
344 : : The value may change with different horizontal scroll positions, as
345 : : different columns have different widths. For instance, if your control is
346 : : 100 pixels wide, and has three columns of width 50, 50, 100, respectively,
347 : : then this method will return either "2" or "1", depending on which column
348 : : is the first visible one.
349 : :
350 : : @param _bAcceptPartialRow
351 : : specifies whether a possible only partially visible last row is
352 : : counted, too.
353 : : */
354 : : TableSize impl_getVisibleColumns( bool _bAcceptPartialCol ) const;
355 : :
356 : : /** determines the rectangle occupied by the given cell
357 : : */
358 : : void impl_getCellRect( ColPos _nColumn, RowPos _nRow, Rectangle& _rCellRect ) const;
359 : :
360 : : /** updates all cached model values
361 : :
362 : : The method is not bound to the classes public invariants, as it's used in
363 : : situations where the they must not necessarily be fullfilled.
364 : : */
365 : : void impl_ni_updateCachedModelValues();
366 : :
367 : : /** updates the cached table metrics (row height etc.)
368 : : */
369 : : void impl_ni_updateCachedTableMetrics();
370 : :
371 : : /** updates ->m_aColumnWidthsPixel with the current pixel widths of all model columns
372 : :
373 : : The method is not bound to the classes public invariants, as it's used in
374 : : situations where the they must not necessarily be fullfilled.
375 : :
376 : : @param i_assumeInflexibleColumnsUpToIncluding
377 : : the index of a column up to which all columns should be considered as inflexible, or
378 : : <code>COL_INVALID</code>.
379 : : */
380 : : void impl_ni_updateColumnWidths( ColPos const i_assumeInflexibleColumnsUpToIncluding = COL_INVALID );
381 : :
382 : : /** updates the scrollbars of the control
383 : :
384 : : The method is not bound to the classes public invariants, as it's used in
385 : : situations where the they must not necessarily be fullfilled.
386 : :
387 : : This includes both the existence of the scrollbars, and their
388 : : state.
389 : : */
390 : : void impl_ni_updateScrollbars();
391 : :
392 : : /** scrolls the view by the given number of rows
393 : :
394 : : The method is not bound to the classes public invariants, as it's used in
395 : : situations where the they must not necessarily be fullfilled.
396 : :
397 : : @return
398 : : the number of rows by which the viewport was scrolled. This may differ
399 : : from the given numbers to scroll in case the begin or the end of the
400 : : row range were reached.
401 : : */
402 : : TableSize impl_ni_ScrollRows( TableSize _nRowDelta );
403 : :
404 : : /** equivalent to impl_ni_ScrollRows, but checks the instances invariants beforehand (in a non-product build only)
405 : : */
406 : : TableSize impl_scrollRows( TableSize const i_rowDelta );
407 : :
408 : : /** scrolls the view by the given number of columns
409 : :
410 : : The method is not bound to the classes public invariants, as it's used in
411 : : situations where the they must not necessarily be fullfilled.
412 : :
413 : : @return
414 : : the number of columns by which the viewport was scrolled. This may differ
415 : : from the given numbers to scroll in case the begin or the end of the
416 : : column range were reached.
417 : : */
418 : : TableSize impl_ni_ScrollColumns( TableSize _nColumnDelta );
419 : :
420 : : /** equivalent to impl_ni_ScrollColumns, but checks the instances invariants beforehand (in a non-product build only)
421 : : */
422 : : TableSize impl_scrollColumns( TableSize const i_columnDelta );
423 : :
424 : : /** retrieves the area occupied by the totality of (at least partially) visible cells
425 : :
426 : : The returned area includes row and column headers. Also, it takes into
427 : : account the the fact that there might be less columns than would normally
428 : : find room in the control.
429 : :
430 : : As a result of respecting the partial visibility of rows and columns,
431 : : the returned area might be larger than the data window's output size.
432 : : */
433 : : Rectangle impl_getAllVisibleCellsArea() const;
434 : :
435 : : /** retrieves the area occupied by all (at least partially) visible data cells.
436 : :
437 : : Effectively, the returned area is the same as returned by ->impl_getAllVisibleCellsArea,
438 : : minus the row and column header areas.
439 : : */
440 : : Rectangle impl_getAllVisibleDataCellArea() const;
441 : :
442 : : /** retrieves the column which covers the given ordinate
443 : : */
444 : : ColPos impl_getColumnForOrdinate( long const i_ordinate ) const;
445 : :
446 : : /** retrieves the row which covers the given abscissa
447 : : */
448 : : RowPos impl_getRowForAbscissa( long const i_abscissa ) const;
449 : :
450 : : /// invalidates the window area occupied by the given column
451 : : void impl_invalidateColumn( ColPos const i_column );
452 : :
453 : : DECL_LINK( OnScroll, ScrollBar* );
454 : : DECL_LINK( OnUpdateScrollbars, void* );
455 : : };
456 : :
457 : : //see seleng.hxx, seleng.cxx, FunctionSet overridables, part of selection engine
458 : : class TableFunctionSet : public FunctionSet
459 : : {
460 : : private:
461 : : TableControl_Impl* m_pTableControl;
462 : : RowPos m_nCurrentRow;
463 : :
464 : : public:
465 : : TableFunctionSet(TableControl_Impl* _pTableControl);
466 : : virtual ~TableFunctionSet();
467 : :
468 : : virtual void BeginDrag();
469 : : virtual void CreateAnchor();
470 : : virtual void DestroyAnchor();
471 : : virtual sal_Bool SetCursorAtPoint(const Point& rPoint, sal_Bool bDontSelectAtCursor);
472 : : virtual sal_Bool IsSelectionAtPoint( const Point& rPoint );
473 : : virtual void DeselectAtPoint( const Point& rPoint );
474 : : virtual void DeselectAll();
475 : : };
476 : :
477 : :
478 : : //........................................................................
479 : : } } // namespace svt::table
480 : : //........................................................................
481 : :
482 : : #endif // SVTOOLS_TABLECONTROL_IMPL_HXX
483 : :
484 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|