/src/libreoffice/sc/source/ui/inc/csvcontrol.hxx
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 | | #pragma once |
21 | | |
22 | | #include <scdllapi.h> |
23 | | #include <address.hxx> |
24 | | #include "csvsplits.hxx" |
25 | | #include <o3tl/typed_flags_set.hxx> |
26 | | #include <rtl/ref.hxx> |
27 | | #include <vcl/weld/customweld.hxx> |
28 | | #include "AccessibleCsvControl.hxx" |
29 | | |
30 | | /** Minimum character count for a column in separators mode. */ |
31 | | const sal_Int32 CSV_MINCOLWIDTH = 8; |
32 | | /** Maximum length of a cell string. */ |
33 | | const sal_Int32 CSV_MAXSTRLEN = 0x7FFF; |
34 | | /** Transparency for header color of selected columns. */ |
35 | | const sal_uInt16 CSV_HDR_TRANSPARENCY = 85; |
36 | | /** Minimum distance to border for auto scroll. */ |
37 | | const sal_Int32 CSV_SCROLL_DIST = 3; |
38 | | |
39 | | //! TODO make string array dynamic |
40 | | const sal_Int32 CSV_PREVIEW_LINES = 32; // maximum count of preview lines |
41 | | /** Maximum count of columns. */ |
42 | | const sal_Int32 CSV_MAXCOLCOUNT = MAXCOLCOUNT; |
43 | | |
44 | | /** Default column data type. */ |
45 | | const sal_Int32 CSV_TYPE_DEFAULT = 0; |
46 | | /** Multi selection with different types. */ |
47 | | const sal_Int32 CSV_TYPE_MULTI = -1; |
48 | | /** No column selected. */ |
49 | | const sal_Int32 CSV_TYPE_NOSELECTION = -2; |
50 | | |
51 | | // External used column types. |
52 | | const sal_uInt8 SC_COL_STANDARD = 1; |
53 | | const sal_uInt8 SC_COL_TEXT = 2; |
54 | | const sal_uInt8 SC_COL_MDY = 3; |
55 | | const sal_uInt8 SC_COL_DMY = 4; |
56 | | const sal_uInt8 SC_COL_YMD = 5; |
57 | | const sal_uInt8 SC_COL_SKIP = 9; |
58 | | const sal_uInt8 SC_COL_ENGLISH = 10; |
59 | | |
60 | | /** Exported data of a column (data used in the dialog). */ |
61 | | struct ScCsvExpData |
62 | | { |
63 | | sal_Int32 mnIndex; /// Index of a column. |
64 | | sal_uInt8 mnType; /// External type of the column. |
65 | | |
66 | 0 | ScCsvExpData() : mnIndex( 0 ), mnType( SC_COL_STANDARD ) {} |
67 | | ScCsvExpData( sal_Int32 nIndex, sal_uInt8 nType ) : |
68 | 0 | mnIndex( nIndex ), mnType( nType ) {} |
69 | | }; |
70 | | |
71 | | typedef ::std::vector< ScCsvExpData > ScCsvExpDataVec; |
72 | | |
73 | | /** Specifies which element should be used to perform an action. */ |
74 | | enum ScMoveMode |
75 | | { |
76 | | MOVE_NONE, /// No action. |
77 | | MOVE_FIRST, /// First element in current context. |
78 | | MOVE_LAST, /// Last element in current context. |
79 | | MOVE_PREV, /// Predecessor of current element in current context. |
80 | | MOVE_NEXT, /// Successor of current element in current context. |
81 | | MOVE_PREVPAGE, /// Previous page relative to current context. |
82 | | MOVE_NEXTPAGE /// Next page relative to current context. |
83 | | }; |
84 | | |
85 | | /** Flags for comparison of old and new control layout data. */ |
86 | | enum class ScCsvDiff : sal_uInt32 { |
87 | | Equal = 0x0000, |
88 | | PosCount = 0x0001, |
89 | | PosOffset = 0x0002, |
90 | | HeaderWidth = 0x0004, |
91 | | CharWidth = 0x0008, |
92 | | LineCount = 0x0010, |
93 | | LineOffset = 0x0020, |
94 | | HeaderHeight = 0x0040, |
95 | | LineHeight = 0x0080, |
96 | | RulerCursor = 0x0100, |
97 | | GridCursor = 0x0200, |
98 | | |
99 | | HorizontalMask = PosCount | PosOffset | HeaderWidth | CharWidth, |
100 | | VerticalMask = LineCount | LineOffset | HeaderHeight | LineHeight |
101 | | }; |
102 | | namespace o3tl { |
103 | | template<> struct typed_flags<ScCsvDiff> : is_typed_flags<ScCsvDiff, 0x03ff> {}; |
104 | | } |
105 | | |
106 | | |
107 | | /** A structure containing all layout data valid for both ruler and data grid |
108 | | (i.e. scroll position or column width). */ |
109 | | struct ScCsvLayoutData |
110 | | { |
111 | | // horizontal settings |
112 | | sal_Int32 mnPosCount; /// Number of positions. |
113 | | sal_Int32 mnPosOffset; /// Horizontal scroll offset. |
114 | | |
115 | | sal_Int32 mnWinWidth; /// Width of ruler and data grid. |
116 | | sal_Int32 mnHdrWidth; /// Width of the header column. |
117 | | sal_Int32 mnCharWidth; /// Pixel width of one character. |
118 | | |
119 | | // vertical settings |
120 | | sal_Int32 mnLineCount; /// Number of data lines. |
121 | | sal_Int32 mnLineOffset; /// Index of first visible line (0-based). |
122 | | |
123 | | sal_Int32 mnWinHeight; /// Height of entire data grid (incl. header). |
124 | | sal_Int32 mnHdrHeight; /// Height of the header line. |
125 | | sal_Int32 mnLineHeight; /// Height of a data line. |
126 | | |
127 | | // cursor settings |
128 | | sal_Int32 mnPosCursor; /// Position of ruler cursor. |
129 | | sal_Int32 mnColCursor; /// Position of grid column cursor. |
130 | | |
131 | | mutable sal_Int32 mnNoRepaint; /// >0 = no repaint. |
132 | | bool mbAppRTL; /// true = application in RTL mode. |
133 | | |
134 | | explicit ScCsvLayoutData(); |
135 | | |
136 | | /** Returns differences to rData. |
137 | | @descr For each difference the appropriate bit is set in the returned value. */ |
138 | | ScCsvDiff GetDiff( const ScCsvLayoutData& rData ) const; |
139 | | }; |
140 | | |
141 | | inline bool operator==( const ScCsvLayoutData& rData1, const ScCsvLayoutData& rData2 ) |
142 | 0 | { |
143 | 0 | return rData1.GetDiff( rData2 ) == ScCsvDiff::Equal; |
144 | 0 | } |
145 | | |
146 | | inline bool operator!=( const ScCsvLayoutData& rData1, const ScCsvLayoutData& rData2 ) |
147 | 0 | { |
148 | 0 | return !(rData1 == rData2); |
149 | 0 | } |
150 | | |
151 | | /** Enumeration of possible commands to change any settings of the CSV controls. |
152 | | @descr Controls have to send commands instead of changing their settings directly. |
153 | | This helps to keep the different controls consistent to each other. |
154 | | A command can contain 0 to 2 sal_Int32 parameters. In the description of each |
155 | | command the required parameters are shown in brackets. [-] means no parameter. */ |
156 | | enum ScCsvCmdType |
157 | | { |
158 | | // misc |
159 | | CSVCMD_NONE, /// No command. [-] |
160 | | CSVCMD_REPAINT, /// Repaint all controls. [-] |
161 | | |
162 | | // modify horizontal dimensions |
163 | | CSVCMD_SETPOSCOUNT, /// Change position/column count. [character count] |
164 | | CSVCMD_SETPOSOFFSET, /// Change position offset (scroll pos). [position] |
165 | | CSVCMD_SETHDRWIDTH, /// Change width of the header column. [width in pixel] |
166 | | CSVCMD_SETCHARWIDTH, /// Change character pixel width. [width in pixel] |
167 | | |
168 | | // modify vertical dimensions |
169 | | CSVCMD_SETLINECOUNT, /// Change number of data lines. [line count] |
170 | | CSVCMD_SETLINEOFFSET, /// Change first visible line. [line index] |
171 | | CSVCMD_SETHDRHEIGHT, /// Change height of top header line. [height in pixel] |
172 | | CSVCMD_SETLINEHEIGHT, /// Change data line pixel height. [height in pixel} |
173 | | |
174 | | // cursors/positions |
175 | | CSVCMD_MOVERULERCURSOR, /// Move ruler cursor to new position. [position] |
176 | | CSVCMD_MOVEGRIDCURSOR, /// Move data grid cursor to new column. [position] |
177 | | CSVCMD_MAKEPOSVISIBLE, /// Move to make passed position visible (for mouse tracking). [position] |
178 | | |
179 | | // table contents |
180 | | CSVCMD_NEWCELLTEXTS, /// Recalculate splits and cell texts. [-] |
181 | | CSVCMD_UPDATECELLTEXTS, /// Update cell texts with current split settings. [-] |
182 | | CSVCMD_SETCOLUMNTYPE, /// Change data type of selected columns. [column type] |
183 | | CSVCMD_EXPORTCOLUMNTYPE, /// Send selected column type to external controls. [-] |
184 | | CSVCMD_SETFIRSTIMPORTLINE, /// Set number of first imported line. [line index] |
185 | | |
186 | | // splits |
187 | | CSVCMD_INSERTSPLIT, /// Insert a split. [position] |
188 | | CSVCMD_REMOVESPLIT, /// Remove a split. [position] |
189 | | CSVCMD_TOGGLESPLIT, /// Inserts or removes a split. [position] |
190 | | CSVCMD_MOVESPLIT, /// Move a split. [old position, new position] |
191 | | CSVCMD_REMOVEALLSPLITS /// Remove all splits. [-] |
192 | | }; |
193 | | |
194 | | /** Data for a CSV control command. The stored position data is always character based, |
195 | | it's never a column index (required for internal consistency). */ |
196 | | class ScCsvCmd |
197 | | { |
198 | | private: |
199 | | ScCsvCmdType meType; /// The command. |
200 | | sal_Int32 mnParam1; /// First parameter. |
201 | | sal_Int32 mnParam2; /// Second parameter. |
202 | | |
203 | | public: |
204 | | explicit ScCsvCmd() : meType( CSVCMD_NONE ), |
205 | 0 | mnParam1( CSV_POS_INVALID ), mnParam2( CSV_POS_INVALID ) {} |
206 | | |
207 | | inline void Set( ScCsvCmdType eType, sal_Int32 nParam1, sal_Int32 nParam2 ); |
208 | | |
209 | 0 | ScCsvCmdType GetType() const { return meType; } |
210 | 0 | sal_Int32 GetParam1() const { return mnParam1; } |
211 | 0 | sal_Int32 GetParam2() const { return mnParam2; } |
212 | | }; |
213 | | |
214 | | inline void ScCsvCmd::Set( ScCsvCmdType eType, sal_Int32 nParam1, sal_Int32 nParam2 ) |
215 | 0 | { |
216 | 0 | meType = eType; mnParam1 = nParam1; mnParam2 = nParam2; |
217 | 0 | } |
218 | | |
219 | | /** Base class for the CSV ruler and the data grid control. Implements command handling. */ |
220 | | class SAL_DLLPUBLIC_RTTI ScCsvControl : public weld::CustomWidgetController |
221 | | { |
222 | | private: |
223 | | Link<ScCsvControl&,void> maCmdHdl; /// External command handler. |
224 | | ScCsvCmd maCmd; /// Data of last command. |
225 | | const ScCsvLayoutData& mrData; /// Shared layout data. |
226 | | |
227 | | bool mbValidGfx; /// Content of virtual devices valid? |
228 | | |
229 | | protected: |
230 | | rtl::Reference<ScAccessibleCsvControl> mxAccessible; /// Reference to the accessible implementation object. |
231 | | |
232 | | public: |
233 | | explicit ScCsvControl(const ScCsvLayoutData& rData); |
234 | | virtual ~ScCsvControl() override; |
235 | | |
236 | | // event handling --------------------------------------------------------- |
237 | | |
238 | | virtual void GetFocus() override; |
239 | | virtual void LoseFocus() override; |
240 | | |
241 | | /** Sends a GetFocus or LoseFocus event to the accessibility object. */ |
242 | | void AccSendFocusEvent( bool bFocused ); |
243 | | /** Sends a caret changed event to the accessibility object. */ |
244 | | void AccSendCaretEvent(); |
245 | | /** Sends a visible area changed event to the accessibility object. */ |
246 | | void AccSendVisibleEvent(); |
247 | | /** Sends a selection changed event to the accessibility object. */ |
248 | | void AccSendSelectionEvent(); |
249 | | /** Sends a table model changed event for changed cell contents to the accessibility object. */ |
250 | | void AccSendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows = true ); |
251 | | /** Sends a table model changed event for an inserted column to the accessibility object. */ |
252 | | void AccSendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn ); |
253 | | /** Sends a table model changed event for a removed column to the accessibility object. */ |
254 | | void AccSendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn ); |
255 | | |
256 | 0 | const rtl::Reference<ScAccessibleCsvControl>& GetAccessible() const { return mxAccessible; } |
257 | | |
258 | | // repaint helpers -------------------------------------------------------- |
259 | | |
260 | | /** Sets the graphic invalid (next Redraw() will not use cached graphic). */ |
261 | 0 | void InvalidateGfx() { mbValidGfx = false; } |
262 | | /** Sets the graphic valid (next Redraw() will use cached graphic). */ |
263 | 0 | void ValidateGfx() { mbValidGfx = true; } |
264 | | /** Returns true, if cached graphic is valid. */ |
265 | 0 | bool IsValidGfx() const { return mbValidGfx; } |
266 | | |
267 | | /** Repaints all controls. |
268 | | @param bInvalidate true = invalidates graphics of this control (not all). */ |
269 | | void Repaint( bool bInvalidate = false ); |
270 | | /** Increases no-repaint counter (controls do not repaint until the last EnableRepaint()). */ |
271 | | void DisableRepaint(); |
272 | | /** Decreases no-repaint counter and repaints if counter reaches 0. */ |
273 | | void EnableRepaint(); |
274 | | /** Returns true, if controls will not repaint. */ |
275 | 0 | bool IsNoRepaint() const { return mrData.mnNoRepaint > 0; } |
276 | | |
277 | | // command handling ------------------------------------------------------- |
278 | | |
279 | | /** Sets a new command handler. */ |
280 | 0 | void SetCmdHdl( const Link<ScCsvControl&,void>& rHdl ) { maCmdHdl = rHdl; } |
281 | | /** Returns data of the last command. */ |
282 | 0 | const ScCsvCmd& GetCmd() const { return maCmd; } |
283 | | |
284 | | /** Executes a command by calling command handler. */ |
285 | | SC_DLLPUBLIC void Execute( |
286 | | ScCsvCmdType eType, |
287 | | sal_Int32 nParam1 = CSV_POS_INVALID, |
288 | | sal_Int32 nParam2 = CSV_POS_INVALID ); |
289 | | |
290 | | // layout helpers --------------------------------------------------------- |
291 | | |
292 | | /** Returns a reference to the current layout data. */ |
293 | 0 | const ScCsvLayoutData& GetLayoutData() const { return mrData; } |
294 | | /** Returns true, if the Right-to-Left layout mode is active. */ |
295 | 0 | bool IsRTL() const { return mrData.mbAppRTL; } |
296 | | |
297 | | /** Returns the number of available positions. */ |
298 | 0 | sal_Int32 GetPosCount() const { return mrData.mnPosCount; } |
299 | | /** Returns the number of visible positions. */ |
300 | | sal_Int32 GetVisPosCount() const; |
301 | | /** Returns the first visible position. */ |
302 | 0 | sal_Int32 GetFirstVisPos() const { return mrData.mnPosOffset; } |
303 | | /** Returns the last visible position. */ |
304 | 0 | sal_Int32 GetLastVisPos() const { return GetFirstVisPos() + GetVisPosCount(); } |
305 | | /** Returns highest possible position for first visible character. */ |
306 | | sal_Int32 GetMaxPosOffset() const; |
307 | | |
308 | | /** Returns true, if it is allowed to set a split at nPos. */ |
309 | | bool IsValidSplitPos( sal_Int32 nPos ) const; |
310 | | /** Returns true, if nPos is an allowed AND visible split position. */ |
311 | | bool IsVisibleSplitPos( sal_Int32 nPos ) const; |
312 | | |
313 | | /** Returns the width of the header column. */ |
314 | 0 | sal_Int32 GetHdrWidth() const { return mrData.mnHdrWidth; } |
315 | | /** Returns the width of one character column. */ |
316 | 0 | sal_Int32 GetCharWidth() const { return mrData.mnCharWidth; } |
317 | | /** Returns the start position of the header column. */ |
318 | | sal_Int32 GetHdrX() const; |
319 | | /** Returns the X position of the first pixel of the data area. */ |
320 | | sal_Int32 GetFirstX() const; |
321 | | /** Returns the X position of the last pixel of the data area. */ |
322 | | sal_Int32 GetLastX() const; |
323 | | /** Returns output X coordinate of the specified position. */ |
324 | | sal_Int32 GetX( sal_Int32 nPos ) const; |
325 | | /** Returns position from output coordinate. */ |
326 | | sal_Int32 GetPosFromX( sal_Int32 nX ) const; |
327 | | |
328 | | /** Returns the number of data lines. */ |
329 | 0 | sal_Int32 GetLineCount() const { return mrData.mnLineCount; } |
330 | | /** Returns the number of visible lines (including partly visible bottom line). */ |
331 | | SC_DLLPUBLIC sal_Int32 GetVisLineCount() const; |
332 | | /** Returns index of first visible line. */ |
333 | 0 | sal_Int32 GetFirstVisLine() const { return mrData.mnLineOffset; } |
334 | | /** Returns index of last visible line. */ |
335 | | sal_Int32 GetLastVisLine() const; |
336 | | /** Returns highest possible index for first line. */ |
337 | | sal_Int32 GetMaxLineOffset() const; |
338 | | |
339 | | /** Returns true, if nLine is a valid line index. */ |
340 | | bool IsValidLine( sal_Int32 nLine ) const; |
341 | | /** Returns true, if nLine is a valid and visible line index. */ |
342 | | bool IsVisibleLine( sal_Int32 nLine ) const; |
343 | | |
344 | | /** Returns the height of the header line. */ |
345 | 0 | sal_Int32 GetHdrHeight() const { return mrData.mnHdrHeight; } |
346 | | /** Returns the height of one line. */ |
347 | 0 | sal_Int32 GetLineHeight() const { return mrData.mnLineHeight; } |
348 | | /** Returns output Y coordinate of the specified line. */ |
349 | | sal_Int32 GetY( sal_Int32 nLine ) const; |
350 | | /** Returns line index from output coordinate. */ |
351 | | sal_Int32 GetLineFromY( sal_Int32 nY ) const; |
352 | | |
353 | | /** Returns the ruler cursor position. */ |
354 | 0 | sal_Int32 GetRulerCursorPos() const { return mrData.mnPosCursor; } |
355 | | /** Returns the data grid cursor position (not column index!). */ |
356 | 0 | sal_Int32 GetGridCursorPos() const { return mrData.mnColCursor; } |
357 | | |
358 | | // static helpers --------------------------------------------------------- |
359 | | |
360 | | /** Inverts a rectangle in the specified output device. */ |
361 | | static void ImplInvertRect( OutputDevice& rOutDev, const tools::Rectangle& rRect ); |
362 | | |
363 | | /** Returns direction code for the keys LEFT, RIGHT, HOME, END. |
364 | | @param bHomeEnd false = ignore HOME and END key. */ |
365 | | static ScMoveMode GetHorzDirection( sal_uInt16 nCode, bool bHomeEnd ); |
366 | | /** Returns direction code for the keys UP, DOWN, HOME, END, PAGE UP, PAGE DOWN. |
367 | | @param bHomeEnd false = ignore HOME and END key. */ |
368 | | static ScMoveMode GetVertDirection( sal_uInt16 nCode, bool bHomeEnd ); |
369 | | }; |
370 | | |
371 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |