LibreOffice Module sc (master)  1
csvtablebox.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 
20 #include <csvtablebox.hxx>
21 #include <vcl/settings.hxx>
22 
24  : mxRuler(new ScCsvRuler(maData, this))
25  , mxGrid(new ScCsvGrid(maData, rBuilder.weld_menu("popup"), this))
26  , mxScroll(rBuilder.weld_scrolled_window("scrolledwindow", true))
27  , mxRulerWeld(new weld::CustomWeld(rBuilder, "csvruler", *mxRuler))
28  , mxGridWeld(new weld::CustomWeld(rBuilder, "csvgrid", *mxGrid))
29 {
30  Size aSize(mxScroll->get_approximate_digit_width() * 67,
31  mxScroll->get_text_height() * 10);
32  // this needs to be larger than the ScCsvGrid initial size to get it
33  // to stretch to fit, see ScCsvGrid::SetDrawingArea
34  mxScroll->set_size_request(aSize.Width(), aSize.Height());
35 
36  mbFixedMode = false;
37  mnFixedWidth = 1;
38 
39  Link<ScCsvControl&,void> aLink = LINK( this, ScCsvTableBox, CsvCmdHdl );
40  mxRuler->SetCmdHdl( aLink );
41  mxGrid->SetCmdHdl( aLink );
42 
43  mxScroll->connect_hadjustment_changed(LINK(this, ScCsvTableBox, HScrollHdl));
44  mxScroll->connect_vadjustment_changed(LINK(this, ScCsvTableBox, VScrollHdl));
45 
46  maEndScrollIdle.SetPriority(TaskPriority::LOWEST);
48 
49  InitControls();
50 }
51 
53 {
54 }
55 
56 // common table box handling --------------------------------------------------
57 
59 {
60  if( !mbFixedMode )
61  return;
62 
63  // rescue data for fixed width mode
64  mnFixedWidth = mxGrid->GetPosCount();
65  maFixColStates = mxGrid->GetColumnStates();
66  // switch to separators mode
67  mbFixedMode = false;
68  // reset and reinitialize controls
69  mxGrid->DisableRepaint();
70  mxGrid->Execute( CSVCMD_SETLINEOFFSET, 0 );
71  mxGrid->Execute( CSVCMD_SETPOSCOUNT, 1 );
72  mxGrid->Execute( CSVCMD_NEWCELLTEXTS );
73  mxGrid->SetColumnStates( maSepColStates );
74  InitControls();
75  mxGrid->EnableRepaint();
76 }
77 
79 {
80  if( mbFixedMode )
81  return;
82 
83  // rescue data for separators mode
84  maSepColStates = mxGrid->GetColumnStates();
85  // switch to fixed width mode
86  mbFixedMode = true;
87  // reset and reinitialize controls
88  mxGrid->DisableRepaint();
89  mxGrid->Execute( CSVCMD_SETLINEOFFSET, 0 );
91  mxGrid->SetSplits( mxRuler->GetSplits() );
92  mxGrid->SetColumnStates( maFixColStates );
93  InitControls();
94  mxGrid->EnableRepaint();
95 }
96 
98 {
99  mxGrid->Init();
100 }
101 
103 {
104  mxGrid->UpdateLayoutData();
105 
106  mxGrid->Show();
107  if (mbFixedMode)
108  mxRuler->Show();
109  else
110  mxRuler->Hide();
111 
112  Size aWinSize = mxGrid->GetOutputSizePixel();
113  maData.mnWinWidth = aWinSize.Width();
114  maData.mnWinHeight = aWinSize.Height();
115 
116  // scrollbars always visible
117  InitHScrollBar();
118 
119  // scrollbars always visible
120  InitVScrollBar();
121 
122  // let the controls self-adjust to visible area
123  mxGrid->Execute( CSVCMD_SETPOSOFFSET, mxGrid->GetFirstVisPos() );
124  mxGrid->Execute( CSVCMD_SETLINEOFFSET, mxGrid->GetFirstVisLine() );
125 }
126 
128 {
129  int nLower = 0;
130  int nValue = mxGrid->GetFirstVisPos();
131  int nUpper = mxGrid->GetPosCount() + 2;
132  int nPageSize = mxGrid->GetVisPosCount();
133 
134  // Undo scrollbar RTL
136  nValue = nUpper - (nValue - nLower + nPageSize);
137 
138  mxScroll->hadjustment_configure(nValue, nLower, nUpper,
139  1, mxGrid->GetVisPosCount() * 3 / 4,
140  nPageSize);
141 }
142 
144 {
145  mxScroll->vadjustment_configure(mxGrid->GetFirstVisLine(), 0, mxGrid->GetLineCount() + 1,
146  1, mxGrid->GetVisLineCount() - 2,
147  mxGrid->GetVisLineCount());
148 }
149 
150 void ScCsvTableBox::MakePosVisible( sal_Int32 nPos )
151 {
152  if( (0 <= nPos) && (nPos < mxGrid->GetPosCount()) )
153  {
154  if( nPos - CSV_SCROLL_DIST + 1 <= mxGrid->GetFirstVisPos() )
155  mxGrid->Execute( CSVCMD_SETPOSOFFSET, nPos - CSV_SCROLL_DIST );
156  else if( nPos + CSV_SCROLL_DIST >= mxGrid->GetLastVisPos() )
157  mxGrid->Execute( CSVCMD_SETPOSOFFSET, nPos - mxGrid->GetVisPosCount() + CSV_SCROLL_DIST );
158  }
159 }
160 
161 // cell contents --------------------------------------------------------------
162 
164  const OUString* pTextLines, const OUString& rSepChars,
165  sal_Unicode cTextSep, bool bMergeSep, bool bRemoveSpace )
166 {
167  // assuming that pTextLines is a string array with size CSV_PREVIEW_LINES
168  // -> will be dynamic sometime
169  mxGrid->DisableRepaint();
170  sal_Int32 nEndLine = mxGrid->GetFirstVisLine() + CSV_PREVIEW_LINES;
171  const OUString* pString = pTextLines;
172  for( sal_Int32 nLine = mxGrid->GetFirstVisLine(); nLine < nEndLine; ++nLine, ++pString )
173  {
174  if( mbFixedMode )
175  mxGrid->ImplSetTextLineFix( nLine, *pString );
176  else
177  mxGrid->ImplSetTextLineSep( nLine, *pString, rSepChars, cTextSep, bMergeSep, bRemoveSpace );
178  }
179  mxGrid->EnableRepaint();
180 }
181 
182 // column settings ------------------------------------------------------------
183 
185 {
186  const sal_Int32 nTypeCount = rListBox.get_count();
187  std::vector<OUString> aTypeNames( nTypeCount );
188  for( sal_Int32 nIndex = 0; nIndex < nTypeCount; ++nIndex )
189  aTypeNames[ nIndex ] = rListBox.get_text( nIndex );
190  mxGrid->SetTypeNames( aTypeNames );
191 }
192 
194 {
195  if( mbFixedMode )
196  mxGrid->FillColumnDataFix( rOptions );
197  else
198  mxGrid->FillColumnDataSep( rOptions );
199 }
200 
201 // event handling -------------------------------------------------------------
202 
203 IMPL_LINK( ScCsvTableBox, CsvCmdHdl, ScCsvControl&, rCtrl, void )
204 {
205  const ScCsvCmd& rCmd = rCtrl.GetCmd();
206  ScCsvCmdType eType = rCmd.GetType();
207  sal_Int32 nParam1 = rCmd.GetParam1();
208  sal_Int32 nParam2 = rCmd.GetParam2();
209 
210  bool bFound = true;
211  switch( eType )
212  {
213  case CSVCMD_REPAINT:
214  if( !mxGrid->IsNoRepaint() )
215  {
216  mxGrid->Invalidate();
217  mxRuler->Invalidate();
218  InitHScrollBar();
219  InitVScrollBar();
220  }
221  break;
223  MakePosVisible( nParam1 );
224  break;
225 
226  case CSVCMD_NEWCELLTEXTS:
227  if( mbFixedMode )
228  mxGrid->Execute( CSVCMD_UPDATECELLTEXTS );
229  else
230  {
231  mxGrid->DisableRepaint();
232  ScCsvColStateVec aStates( mxGrid->GetColumnStates() );
233  sal_Int32 nPos = mxGrid->GetFirstVisPos();
234  mxGrid->Execute( CSVCMD_SETPOSCOUNT, 1 );
235  mxGrid->Execute( CSVCMD_UPDATECELLTEXTS );
236  mxGrid->Execute( CSVCMD_SETPOSOFFSET, nPos );
237  mxGrid->SetColumnStates( aStates );
238  mxGrid->EnableRepaint();
239  }
240  break;
242  maUpdateTextHdl.Call( *this );
243  break;
245  mxGrid->SetSelColumnType( nParam1 );
246  break;
248  maColTypeHdl.Call( *this );
249  break;
251  mxGrid->SetFirstImportedLine( nParam1 );
252  break;
253 
254  case CSVCMD_INSERTSPLIT:
255  OSL_ENSURE( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::InsertSplit - invalid call" );
256  if( mxRuler->GetSplitCount() + 1 < sal::static_int_cast<sal_uInt32>(CSV_MAXCOLCOUNT) )
257  {
258  mxRuler->InsertSplit( nParam1 );
259  mxGrid->InsertSplit( nParam1 );
260  }
261  break;
262  case CSVCMD_REMOVESPLIT:
263  OSL_ENSURE( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::RemoveSplit - invalid call" );
264  mxRuler->RemoveSplit( nParam1 );
265  mxGrid->RemoveSplit( nParam1 );
266  break;
267  case CSVCMD_TOGGLESPLIT:
268  mxGrid->Execute( mxRuler->HasSplit( nParam1 ) ? CSVCMD_REMOVESPLIT : CSVCMD_INSERTSPLIT, nParam1 );
269  break;
270  case CSVCMD_MOVESPLIT:
271  OSL_ENSURE( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::MoveSplit - invalid call" );
272  mxRuler->MoveSplit( nParam1, nParam2 );
273  mxGrid->MoveSplit( nParam1, nParam2 );
274  break;
276  OSL_ENSURE( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::RemoveAllSplits - invalid call" );
277  mxRuler->RemoveAllSplits();
278  mxGrid->RemoveAllSplits();
279  break;
280  default:
281  bFound = false;
282  }
283  if( bFound )
284  return;
285 
286  const ScCsvLayoutData aOldData( maData );
287  switch( eType )
288  {
289  case CSVCMD_SETPOSCOUNT:
290  maData.mnPosCount = std::max( nParam1, sal_Int32( 1 ) );
291  ImplSetPosOffset( mxGrid->GetFirstVisPos() );
292  break;
293  case CSVCMD_SETPOSOFFSET:
294  ImplSetPosOffset( nParam1 );
295  break;
296  case CSVCMD_SETHDRWIDTH:
297  maData.mnHdrWidth = std::max( nParam1, sal_Int32( 0 ) );
298  ImplSetPosOffset( mxGrid->GetFirstVisPos() );
299  break;
300  case CSVCMD_SETCHARWIDTH:
301  maData.mnCharWidth = std::max( nParam1, sal_Int32( 1 ) );
302  ImplSetPosOffset( mxGrid->GetFirstVisPos() );
303  break;
304  case CSVCMD_SETLINECOUNT:
305  maData.mnLineCount = std::max( nParam1, sal_Int32( 1 ) );
306  ImplSetLineOffset( mxGrid->GetFirstVisLine() );
307  break;
309  ImplSetLineOffset( nParam1 );
310  break;
311  case CSVCMD_SETHDRHEIGHT:
312  maData.mnHdrHeight = std::max( nParam1, sal_Int32( 0 ) );
313  ImplSetLineOffset( mxGrid->GetFirstVisLine() );
314  break;
316  maData.mnLineHeight = std::max( nParam1, sal_Int32( 1 ) );
317  ImplSetLineOffset( mxGrid->GetFirstVisLine() );
318  break;
320  maData.mnPosCursor = mxGrid->IsVisibleSplitPos( nParam1 ) ? nParam1 : CSV_POS_INVALID;
321  break;
323  maData.mnColCursor = ((0 <= nParam1) && (nParam1 < mxGrid->GetPosCount())) ? nParam1 : CSV_POS_INVALID;
324  break;
325  default:
326  {
327  // added to avoid warnings
328  }
329  }
330 
331  if( maData != aOldData )
332  {
333  mxGrid->DisableRepaint();
334  mxRuler->ApplyLayout( aOldData );
335  mxGrid->ApplyLayout( aOldData );
336  mxGrid->EnableRepaint();
337  }
338 }
339 
340 IMPL_LINK(ScCsvTableBox, HScrollHdl, weld::ScrolledWindow&, rScroll, void)
341 {
342  int nLower = 0;
343  int nValue = rScroll.hadjustment_get_value();
344  int nUpper = mxGrid->GetPosCount() + 2;
345  int nPageSize = mxGrid->GetVisPosCount();
346 
347  // Undo scrollbar RTL
349  nValue = nUpper - (nValue - nLower + nPageSize);
350 
351  mxGrid->Execute(CSVCMD_SETPOSOFFSET, nValue);
352  maEndScrollIdle.Start();
353 }
354 
355 IMPL_LINK(ScCsvTableBox, VScrollHdl, weld::ScrolledWindow&, rScroll, void)
356 {
357  mxGrid->Execute(CSVCMD_SETLINEOFFSET, rScroll.vadjustment_get_value());
358 }
359 
360 IMPL_LINK_NOARG(ScCsvTableBox, ScrollEndHdl, Timer*, void)
361 {
362  if( mxGrid->GetRulerCursorPos() != CSV_POS_INVALID )
363  mxGrid->Execute( CSVCMD_MOVERULERCURSOR, mxRuler->GetNoScrollPos( mxGrid->GetRulerCursorPos() ) );
364  if( mxGrid->GetGridCursorPos() != CSV_POS_INVALID )
365  mxGrid->Execute( CSVCMD_MOVEGRIDCURSOR, mxGrid->GetNoScrollCol( mxGrid->GetGridCursorPos() ) );
366 }
367 
368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Change data line pixel height. [height in pixel}.
Definition: csvcontrol.hxx:177
ScCsvCmdType
Enumeration of possible commands to change any settings of the CSV controls.
Definition: csvcontrol.hxx:158
bool mbFixedMode
Cached total width for fixed width mode.
Definition: csvtablebox.hxx:64
Repaint all controls. [-].
Definition: csvcontrol.hxx:165
sal_Int32 mnWinHeight
Index of first visible line (0-based).
Definition: csvcontrol.hxx:125
sal_Int32 nIndex
std::unique_ptr< ScCsvRuler > mxRuler
Current layout data of the controls.
Definition: csvtablebox.hxx:48
sal_Int32 GetParam2() const
Definition: csvcontrol.hxx:213
const sal_Int32 CSV_POS_INVALID
Constant for an invalid ruler position.
Definition: csvsplits.hxx:29
IMPL_LINK_NOARG(ScCsvTableBox, ScrollEndHdl, Timer *, void)
SAL_DLLPRIVATE void MakePosVisible(sal_Int32 nPos)
Moves controls (not cursors!) so that nPos becomes visible.
Set number of first imported line. [line index].
Definition: csvcontrol.hxx:189
virtual OUString get_text(int pos) const =0
Change position/column count. [character count].
Definition: csvcontrol.hxx:166
Update cell texts with current split settings. [-].
Definition: csvcontrol.hxx:184
void SetUniStrings(const OUString *pTextLines, const OUString &rSepChars, sal_Unicode cTextSep, bool bMergeSep, bool bRemoveSpace)
Fills all cells of all lines with the passed texts (Unicode strings).
SAL_DLLPRIVATE void InitHScrollBar()
Initializes size and position data of horizontal scrollbar.
sal_Int32 mnWinWidth
Horizontal scroll offset.
Definition: csvcontrol.hxx:117
Data for a CSV control command.
Definition: csvcontrol.hxx:198
Change width of the header column. [width in pixel].
Definition: csvcontrol.hxx:168
Change height of top header line. [height in pixel].
Definition: csvcontrol.hxx:174
Base class for the CSV ruler and the data grid control.
Definition: csvcontrol.hxx:222
A ruler control for the CSV import dialog.
Definition: csvruler.hxx:32
std::vector< sal_Int8 > maData
virtual int get_count() const =0
Move ruler cursor to new position. [position].
Definition: csvcontrol.hxx:178
constexpr tools::Long Width() const
void InitTypes(const weld::ComboBox &rListBox)
Reads UI strings for data types from the list box.
sal_uInt16 sal_Unicode
const sal_Int32 CSV_SCROLL_DIST
Minimum distance to border for auto scroll.
Definition: csvcontrol.hxx:39
void Init()
Finishes initialization.
Definition: csvtablebox.cxx:97
SAL_DLLPRIVATE void InitVScrollBar()
Initializes size and position data of vertical scrollbar.
Inserts or removes a split. [position].
Definition: csvcontrol.hxx:192
No command. [-].
Definition: csvcontrol.hxx:162
Change number of data lines. [line count].
Definition: csvcontrol.hxx:172
Remove a split. [position].
Definition: csvcontrol.hxx:191
DocumentType eType
Send selected column type to external controls. [-].
Definition: csvcontrol.hxx:186
Idle maEndScrollIdle
Handler for exporting the column type.
Definition: csvtablebox.hxx:57
void SetSeparatorsMode()
Sets the control to separators mode.
Definition: csvtablebox.cxx:58
SAL_DLLPRIVATE void InitControls()
Initializes the children controls (pos/size, scroll bars, ...).
void SetFixedWidthMode()
Sets the control to fixed width mode.
Definition: csvtablebox.cxx:78
Move data grid cursor to new column. [position].
Definition: csvcontrol.hxx:179
static bool GetLayoutRTL()
Change data type of selected columns. [column type].
Definition: csvcontrol.hxx:185
std::unique_ptr< weld::ScrolledWindow > mxScroll
Calc-like data table for fixed width mode.
Definition: csvtablebox.hxx:50
void FillColumnData(ScAsciiOptions &rOptions) const
Fills the options object with current column data.
::std::vector< ScCsvColState > ScCsvColStateVec
Definition: csvgrid.hxx:53
The control in the CSV import dialog that contains a ruler and a data grid to visualize and modify th...
Definition: csvtablebox.hxx:43
Change position offset (scroll pos). [position].
Definition: csvcontrol.hxx:167
Move to make passed position visible (for mouse tracking). [position].
Definition: csvcontrol.hxx:182
Change first visible line. [line index].
Definition: csvcontrol.hxx:173
constexpr tools::Long Height() const
IMPL_LINK(ScCsvTableBox, CsvCmdHdl, ScCsvControl &, rCtrl, void)
ScCsvColStateVec maFixColStates
Called when horizontal scrolling has ended.
Definition: csvtablebox.hxx:59
void SetInvokeHandler(const Link< Timer *, void > &rLink)
Change character pixel width. [width in pixel].
Definition: csvcontrol.hxx:171
sal_Int32 mnFixedWidth
Column states in separators mode.
Definition: csvtablebox.hxx:62
const sal_Int32 CSV_MAXCOLCOUNT
Maximum count of columns.
Definition: csvcontrol.hxx:44
sal_Int32 GetParam1() const
Definition: csvcontrol.hxx:212
Insert a split. [position].
Definition: csvcontrol.hxx:190
void SetPriority(TaskPriority ePriority)
ScCsvTableBox(weld::Builder &rBuilder)
false = Separators, true = Fixed width.
Definition: csvtablebox.cxx:23
ScCsvCmdType GetType() const
Definition: csvcontrol.hxx:211
ScCsvColStateVec maSepColStates
Column states in fixed width mode.
Definition: csvtablebox.hxx:60
ScCsvLayoutData maData
Definition: csvtablebox.hxx:46
Move a split. [old position, new position].
Definition: csvcontrol.hxx:193
Recalculate splits and cell texts. [-].
Definition: csvcontrol.hxx:183
std::unique_ptr< ScCsvGrid > mxGrid
The ruler for fixed width mode.
Definition: csvtablebox.hxx:49
const sal_Int32 CSV_PREVIEW_LINES
TODO make string array dynamic.
Definition: csvcontrol.hxx:42
sal_uInt16 nPos
sal_Int16 nValue
A data grid control for the CSV import dialog.
Definition: csvgrid.hxx:57
A structure containing all layout data valid for both ruler and data grid (i.e.
Definition: csvcontrol.hxx:111