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