LibreOffice Module toolkit (master) 1
mousefunction.cxx
Go to the documentation of this file.
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
23
25#include <vcl/ptrstyle.hxx>
26
27namespace svt::table
28{
29
30
31 //= ColumnResize
32
33
35 {
36 Point const aPoint = i_event.GetPosPixel();
37
39 {
40 // if we hit a column divider, change the mouse pointer accordingly
41 PointerStyle aNewPointer( PointerStyle::Arrow );
42 TableCell const tableCell = i_tableControl.hitTest( aPoint );
43 if ( ( tableCell.nRow == ROW_COL_HEADERS ) && ( tableCell.eArea == ColumnDivider ) )
44 {
45 aNewPointer = PointerStyle::HSplit;
46 }
47 i_tableControl.setPointer( aNewPointer );
48
49 return SkipFunction; // TODO: is this correct?
50 }
51
52 ::Size const tableSize = i_tableControl.getTableSizePixel();
53
54 // set proper pointer
55 PointerStyle aNewPointer( PointerStyle::Arrow );
56 ColumnMetrics const & columnMetrics( i_tableControl.getColumnMetrics( m_nResizingColumn ) );
57 if ( ( aPoint.X() > tableSize.Width() )
58 || ( aPoint.X() < columnMetrics.nStartPixel )
59 )
60 {
61 aNewPointer = PointerStyle::NotAllowed;
62 }
63 else
64 {
65 aNewPointer = PointerStyle::HSplit;
66 }
67 i_tableControl.setPointer( aNewPointer );
68
69 // show tracking line
70 i_tableControl.hideTracking();
71 i_tableControl.showTracking(
73 Point( aPoint.X(), 0 ),
74 Size( 1, tableSize.Height() )
75 ),
76 ShowTrackFlags::Split | ShowTrackFlags::TrackWindow
77 );
78
79 return ContinueFunction;
80 }
81
82
84 {
86 {
87 OSL_ENSURE( false, "ColumnResize::handleMouseDown: suspicious: MouseButtonDown while still tracking?" );
88 return ContinueFunction;
89 }
90
91 TableCell const tableCell( i_tableControl.hitTest( i_event.GetPosPixel() ) );
92 if ( tableCell.nRow == ROW_COL_HEADERS )
93 {
94 if ( ( tableCell.nColumn != COL_INVALID )
95 && ( tableCell.eArea == ColumnDivider )
96 )
97 {
98 m_nResizingColumn = tableCell.nColumn;
99 i_tableControl.captureMouse();
100 return ActivateFunction;
101 }
102 }
103
104 return SkipFunction;
105 }
106
107
109 {
111 return SkipFunction;
112
113 Point const aPoint = i_event.GetPosPixel();
114
115 i_tableControl.hideTracking();
116 PColumnModel const pColumn = i_tableControl.getModel()->getColumnModel( m_nResizingColumn );
117 tools::Long const maxWidthLogical = pColumn->getMaxWidth();
118 tools::Long const minWidthLogical = pColumn->getMinWidth();
119
120 // new position of mouse
121 tools::Long const requestedEnd = aPoint.X();
122
123 // old position of right border
124 tools::Long const oldEnd = i_tableControl.getColumnMetrics( m_nResizingColumn ).nEndPixel;
125
126 // position of left border if cursor in the to-be-resized column
127 tools::Long const columnStart = i_tableControl.getColumnMetrics( m_nResizingColumn ).nStartPixel;
128 tools::Long const requestedWidth = requestedEnd - columnStart;
129 // TODO: this is not correct, strictly: It assumes that the mouse was pressed exactly on the "end" pos,
130 // but for a while now, we have relaxed this, and allow clicking a few pixels aside, too
131
132 if ( requestedEnd >= columnStart )
133 {
134 tools::Long requestedWidthLogical = i_tableControl.pixelWidthToAppFont( requestedWidth );
135 // respect column width limits
136 if ( oldEnd > requestedEnd )
137 {
138 // column has become smaller, check against minimum width
139 if ( ( minWidthLogical != 0 ) && ( requestedWidthLogical < minWidthLogical ) )
140 requestedWidthLogical = minWidthLogical;
141 }
142 else if ( oldEnd < requestedEnd )
143 {
144 // column has become larger, check against max width
145 if ( ( maxWidthLogical != 0 ) && ( requestedWidthLogical >= maxWidthLogical ) )
146 requestedWidthLogical = maxWidthLogical;
147 }
148 pColumn->setWidth( requestedWidthLogical );
149 i_tableControl.invalidate( TableArea::All );
150 }
151
152 i_tableControl.setPointer( PointerStyle::Arrow );
153 i_tableControl.releaseMouse();
154
156 return DeactivateFunction;
157 }
158
159
160 //= RowSelection
161
162
164 {
165 return SkipFunction;
166 }
167
168
170 {
171 bool handled = false;
172
173 TableCell const tableCell( i_tableControl.hitTest( i_event.GetPosPixel() ) );
174 if ( tableCell.nRow >= 0 )
175 {
176 if ( i_tableControl.getSelEngine()->GetSelectionMode() == SelectionMode::NONE )
177 {
178 i_tableControl.activateCell( tableCell.nColumn, tableCell.nRow );
179 handled = true;
180 }
181 else
182 {
183 handled = i_tableControl.getSelEngine()->SelMouseButtonDown( i_event );
184 }
185 }
186
187 if ( handled )
188 m_bActive = true;
189 return handled ? ActivateFunction : SkipFunction;
190 }
191
192
194 {
195 TableCell const tableCell = i_tableControl.hitTest( i_event.GetPosPixel() );
196 if ( tableCell.nRow >= 0 )
197 {
198 if ( i_tableControl.getSelEngine()->GetSelectionMode() != SelectionMode::NONE )
199 {
200 i_tableControl.getSelEngine()->SelMouseButtonUp( i_event );
201 }
202 }
203 if ( m_bActive )
204 {
205 m_bActive = false;
206 return DeactivateFunction;
207 }
208 return SkipFunction;
209 }
210
211
212 //= ColumnSortHandler
213
214
216 {
217 return SkipFunction;
218 }
219
220
222 {
224 {
225 OSL_ENSURE( false, "ColumnSortHandler::handleMouseDown: called while already active - suspicious!" );
226 return ContinueFunction;
227 }
228
229 if ( i_tableControl.getModel()->getSortAdapter() == nullptr )
230 // no sorting support at the model
231 return SkipFunction;
232
233 TableCell const tableCell( i_tableControl.hitTest( i_event.GetPosPixel() ) );
234 if ( ( tableCell.nRow != ROW_COL_HEADERS ) || ( tableCell.nColumn < 0 ) )
235 return SkipFunction;
236
237 // TODO: ensure the column header is rendered in some special way, indicating its current state
238
239 m_nActiveColumn = tableCell.nColumn;
240 return ActivateFunction;
241 }
242
243
245 {
247 return SkipFunction;
248
249 TableCell const tableCell( i_tableControl.hitTest( i_event.GetPosPixel() ) );
250 if ( ( tableCell.nRow == ROW_COL_HEADERS ) && ( tableCell.nColumn == m_nActiveColumn ) )
251 {
252 ITableDataSort* pSort = i_tableControl.getModel()->getSortAdapter();
253 ENSURE_OR_RETURN( pSort != nullptr, "ColumnSortHandler::handleMouseUp: somebody is mocking with us!", DeactivateFunction );
254 // in handleMousButtonDown, the model claimed to have sort support ...
255
257 ColumnSort const aCurrentSort = pSort->getCurrentSortOrder();
258 if ( aCurrentSort.nColumnPos == m_nActiveColumn )
259 // invert existing sort order
260 eSortDirection = ( aCurrentSort.eSortDirection == ColumnSortAscending ) ? ColumnSortDescending : ColumnSortAscending;
261
262 pSort->sortByColumn( m_nActiveColumn, eSortDirection );
263 }
264
266 return DeactivateFunction;
267 }
268
269
270} // namespace svt::table
271
272
273/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const Point & GetPosPixel() const
constexpr tools::Long X() const
SelectionMode GetSelectionMode() const
bool SelMouseButtonDown(const MouseEvent &rMEvt)
bool SelMouseButtonUp(const MouseEvent &rMEvt)
constexpr tools::Long Height() const
constexpr tools::Long Width() const
virtual FunctionResult handleMouseDown(ITableControl &i_tableControl, MouseEvent const &i_event) override
virtual FunctionResult handleMouseUp(ITableControl &i_tableControl, MouseEvent const &i_event) override
virtual FunctionResult handleMouseMove(ITableControl &i_tableControl, MouseEvent const &i_event) override
virtual FunctionResult handleMouseDown(ITableControl &i_tableControl, MouseEvent const &i_event) override
virtual FunctionResult handleMouseMove(ITableControl &i_tableControl, MouseEvent const &i_event) override
virtual FunctionResult handleMouseUp(ITableControl &i_tableControl, MouseEvent const &i_event) override
defines a callback interface to be implemented by a concrete table control
virtual void activateCell(ColPos const i_col, RowPos const i_row)=0
activates the given cell
virtual ::Size getTableSizePixel() const =0
retrieves the size of the table window, in pixels
virtual void captureMouse()=0
captures the mouse to the table window
virtual PTableModel getModel() const =0
returns the table model
virtual void setPointer(PointerStyle i_pointer)=0
sets a new mouse pointer for the table window
virtual void hideTracking()=0
hides a previously shown tracking rectangle
virtual SelectionEngine * getSelEngine()=0
returns selection engine
virtual tools::Long pixelWidthToAppFont(tools::Long const i_pixels) const =0
calculates a width, given in pixels, into an AppFont-based width
virtual void releaseMouse()=0
releases the mouse, after it had previously been captured
virtual void showTracking(tools::Rectangle const &i_location, ShowTrackFlags const i_flags)=0
shows a tracking rectangle
virtual void invalidate(TableArea const i_what)=0
invalidates the table window
virtual ColumnMetrics getColumnMetrics(ColPos const i_column) const =0
retrieves the metrics for a given column
virtual TableCell hitTest(const Point &rPoint) const =0
does a hit test for the given pixel coordinates
provides sorting functionality for the data underlying an ITableModel
Definition: tablesort.hxx:58
virtual ColumnSort getCurrentSortOrder() const =0
retrieves the current sort order of the data
virtual void sortByColumn(ColPos const i_column, ColumnSortDirection const i_sortDirection)=0
sorts the rows in the model by the given column's data, in the given direction.
virtual FunctionResult handleMouseDown(ITableControl &i_tableControl, MouseEvent const &i_event) override
virtual FunctionResult handleMouseUp(ITableControl &i_tableControl, MouseEvent const &i_event) override
virtual FunctionResult handleMouseMove(ITableControl &i_tableControl, MouseEvent const &i_event) override
#define ENSURE_OR_RETURN(c, m, r)
@ ColumnSortDescending
Definition: tablesort.hxx:33
@ ColumnSortAscending
Definition: tablesort.hxx:32
std::shared_ptr< IColumnModel > PColumnModel
Definition: tablemodel.hxx:234
long Long
PointerStyle
tools::Long nEndPixel
the end of the column, in pixels, plus 1.
tools::Long nStartPixel
the start of the column, in pixels.
ColumnSortDirection eSortDirection
Definition: tablesort.hxx:42
#define COL_INVALID
denotes an invalid column index
Definition: tabletypes.hxx:44
#define ROW_COL_HEADERS
denotes the row containing the column headers
Definition: tabletypes.hxx:41