tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / dbgui / csvtablebox.cxx
blobab8231013009313cbb15170b048a991fc2eac03b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <csvtablebox.hxx>
21 #include <vcl/settings.hxx>
23 ScCsvTableBox::ScCsvTableBox(weld::Builder& rBuilder)
24 : mxRuler(new ScCsvRuler(maData, this))
25 , mxGrid(new ScCsvGrid(maData, rBuilder.weld_menu(u"popup"_ustr), this))
26 , mxScroll(rBuilder.weld_scrolled_window(u"scrolledwindow"_ustr, true))
27 , mxRulerWeld(new weld::CustomWeld(rBuilder, u"csvruler"_ustr, *mxRuler))
28 , mxGridWeld(new weld::CustomWeld(rBuilder, u"csvgrid"_ustr, *mxGrid))
29 , maEndScrollIdle("ScCsvTableBox maEndScrollIdle")
31 const OutputDevice& rRefDev = mxGrid->GetDrawingArea()->get_ref_device();
32 Size aSize(rRefDev.approximate_digit_width() * 67,
33 rRefDev.GetTextHeight() * 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());
38 mbFixedMode = false;
39 mnFixedWidth = 1;
41 Link<ScCsvControl&,void> aLink = LINK( this, ScCsvTableBox, CsvCmdHdl );
42 mxRuler->SetCmdHdl( aLink );
43 mxGrid->SetCmdHdl( aLink );
45 mxScroll->connect_hadjustment_changed(LINK(this, ScCsvTableBox, HScrollHdl));
46 mxScroll->connect_vadjustment_changed(LINK(this, ScCsvTableBox, VScrollHdl));
48 maEndScrollIdle.SetPriority(TaskPriority::LOWEST);
49 maEndScrollIdle.SetInvokeHandler(LINK(this,ScCsvTableBox,ScrollEndHdl));
51 InitControls();
54 ScCsvTableBox::~ScCsvTableBox()
58 // common table box handling --------------------------------------------------
60 void ScCsvTableBox::Refresh()
62 mxGrid->DisableRepaint();
63 mxGrid->Execute( CSVCMD_SETLINEOFFSET, 0 );
64 if (mbFixedMode)
66 mxGrid->Execute( CSVCMD_SETPOSCOUNT, mnFixedWidth );
67 mxGrid->SetSplits( mxRuler->GetSplits() );
68 mxGrid->SetColumnStates( std::vector(maFixColStates) );
70 else
72 mxGrid->Execute( CSVCMD_SETPOSCOUNT, 1 );
73 mxGrid->Execute( CSVCMD_NEWCELLTEXTS );
74 mxGrid->SetColumnStates( std::vector(maSepColStates) );
76 InitControls();
77 mxGrid->EnableRepaint();
80 void ScCsvTableBox::SetSeparatorsMode()
82 if( !mbFixedMode )
83 return;
85 // rescue data for fixed width mode
86 mnFixedWidth = mxGrid->GetPosCount();
87 maFixColStates = mxGrid->GetColumnStates();
88 // switch to separators mode
89 mbFixedMode = false;
90 // reset and reinitialize controls
91 Refresh();
94 void ScCsvTableBox::SetFixedWidthMode()
96 if( mbFixedMode )
97 return;
99 // rescue data for separators mode
100 maSepColStates = mxGrid->GetColumnStates();
101 // switch to fixed width mode
102 mbFixedMode = true;
103 // reset and reinitialize controls
104 Refresh();
107 void ScCsvTableBox::Init()
109 mxGrid->Init();
112 void ScCsvTableBox::InitControls()
114 mxGrid->UpdateLayoutData();
116 mxGrid->Show();
117 if (mbFixedMode)
118 mxRuler->Show();
119 else
120 mxRuler->Hide();
122 Size aWinSize = mxGrid->GetOutputSizePixel();
123 maData.mnWinWidth = aWinSize.Width();
124 maData.mnWinHeight = aWinSize.Height();
126 // scrollbars always visible
127 InitHScrollBar();
129 // scrollbars always visible
130 InitVScrollBar();
132 // let the controls self-adjust to visible area
133 mxGrid->Execute( CSVCMD_SETPOSOFFSET, mxGrid->GetFirstVisPos() );
134 mxGrid->Execute( CSVCMD_SETLINEOFFSET, mxGrid->GetFirstVisLine() );
137 void ScCsvTableBox::InitHScrollBar()
139 int nLower = 0;
140 int nValue = mxGrid->GetFirstVisPos();
141 int nUpper = mxGrid->GetPosCount() + 2;
142 int nPageSize = mxGrid->GetVisPosCount();
144 // Undo scrollbar RTL
145 if (AllSettings::GetLayoutRTL())
146 nValue = nUpper - (nValue - nLower + nPageSize);
148 mxScroll->hadjustment_configure(nValue, nLower, nUpper,
149 1, mxGrid->GetVisPosCount() * 3 / 4,
150 nPageSize);
153 void ScCsvTableBox::InitVScrollBar()
155 mxScroll->vadjustment_configure(mxGrid->GetFirstVisLine(), 0, mxGrid->GetLineCount() + 1,
156 1, mxGrid->GetVisLineCount() - 2,
157 mxGrid->GetVisLineCount());
160 void ScCsvTableBox::MakePosVisible( sal_Int32 nPos )
162 if( (0 <= nPos) && (nPos < mxGrid->GetPosCount()) )
164 if( nPos - CSV_SCROLL_DIST + 1 <= mxGrid->GetFirstVisPos() )
165 mxGrid->Execute( CSVCMD_SETPOSOFFSET, nPos - CSV_SCROLL_DIST );
166 else if( nPos + CSV_SCROLL_DIST >= mxGrid->GetLastVisPos() )
167 mxGrid->Execute( CSVCMD_SETPOSOFFSET, nPos - mxGrid->GetVisPosCount() + CSV_SCROLL_DIST );
171 // cell contents --------------------------------------------------------------
173 void ScCsvTableBox::SetUniStrings(
174 const OUString* pTextLines, const OUString& rSepChars,
175 sal_Unicode cTextSep, bool bMergeSep, bool bRemoveSpace )
177 // assuming that pTextLines is a string array with size CSV_PREVIEW_LINES
178 // -> will be dynamic sometime
179 mxGrid->DisableRepaint();
180 sal_Int32 nEndLine = mxGrid->GetFirstVisLine() + CSV_PREVIEW_LINES;
181 const OUString* pString = pTextLines;
182 for( sal_Int32 nLine = mxGrid->GetFirstVisLine(); nLine < nEndLine; ++nLine, ++pString )
184 if( mbFixedMode )
185 mxGrid->ImplSetTextLineFix( nLine, *pString );
186 else
187 mxGrid->ImplSetTextLineSep( nLine, *pString, rSepChars, cTextSep, bMergeSep, bRemoveSpace );
189 mxGrid->EnableRepaint();
192 // column settings ------------------------------------------------------------
194 void ScCsvTableBox::InitTypes(const weld::ComboBox& rListBox)
196 const sal_Int32 nTypeCount = rListBox.get_count();
197 std::vector<OUString> aTypeNames( nTypeCount );
198 for( sal_Int32 nIndex = 0; nIndex < nTypeCount; ++nIndex )
199 aTypeNames[ nIndex ] = rListBox.get_text( nIndex );
200 mxGrid->SetTypeNames( std::move(aTypeNames) );
203 void ScCsvTableBox::FillColumnData( ScAsciiOptions& rOptions ) const
205 if( mbFixedMode )
206 mxGrid->FillColumnDataFix( rOptions );
207 else
208 mxGrid->FillColumnDataSep( rOptions );
211 // event handling -------------------------------------------------------------
213 IMPL_LINK( ScCsvTableBox, CsvCmdHdl, ScCsvControl&, rCtrl, void )
215 const ScCsvCmd& rCmd = rCtrl.GetCmd();
216 ScCsvCmdType eType = rCmd.GetType();
217 sal_Int32 nParam1 = rCmd.GetParam1();
218 sal_Int32 nParam2 = rCmd.GetParam2();
220 bool bFound = true;
221 switch( eType )
223 case CSVCMD_REPAINT:
224 if( !mxGrid->IsNoRepaint() )
226 mxGrid->Invalidate();
227 mxRuler->Invalidate();
228 InitHScrollBar();
229 InitVScrollBar();
231 break;
232 case CSVCMD_MAKEPOSVISIBLE:
233 MakePosVisible( nParam1 );
234 break;
236 case CSVCMD_NEWCELLTEXTS:
237 if( mbFixedMode )
238 mxGrid->Execute( CSVCMD_UPDATECELLTEXTS );
239 else
241 mxGrid->DisableRepaint();
242 ScCsvColStateVec aStates( mxGrid->GetColumnStates() );
243 sal_Int32 nPos = mxGrid->GetFirstVisPos();
244 mxGrid->Execute( CSVCMD_SETPOSCOUNT, 1 );
245 mxGrid->Execute( CSVCMD_UPDATECELLTEXTS );
246 mxGrid->Execute( CSVCMD_SETPOSOFFSET, nPos );
247 mxGrid->SetColumnStates( std::move(aStates) );
248 mxGrid->EnableRepaint();
250 break;
251 case CSVCMD_UPDATECELLTEXTS:
252 maUpdateTextHdl.Call( *this );
253 break;
254 case CSVCMD_SETCOLUMNTYPE:
255 mxGrid->SetSelColumnType( nParam1 );
256 break;
257 case CSVCMD_EXPORTCOLUMNTYPE:
258 maColTypeHdl.Call( *this );
259 break;
260 case CSVCMD_SETFIRSTIMPORTLINE:
261 mxGrid->SetFirstImportedLine( nParam1 );
262 break;
264 case CSVCMD_INSERTSPLIT:
265 OSL_ENSURE( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::InsertSplit - invalid call" );
266 if( mxRuler->GetSplitCount() + 1 < sal::static_int_cast<sal_uInt32>(CSV_MAXCOLCOUNT) )
268 mxRuler->InsertSplit( nParam1 );
269 mxGrid->InsertSplit( nParam1 );
271 break;
272 case CSVCMD_REMOVESPLIT:
273 OSL_ENSURE( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::RemoveSplit - invalid call" );
274 mxRuler->RemoveSplit( nParam1 );
275 mxGrid->RemoveSplit( nParam1 );
276 break;
277 case CSVCMD_TOGGLESPLIT:
278 mxGrid->Execute( mxRuler->HasSplit( nParam1 ) ? CSVCMD_REMOVESPLIT : CSVCMD_INSERTSPLIT, nParam1 );
279 break;
280 case CSVCMD_MOVESPLIT:
281 OSL_ENSURE( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::MoveSplit - invalid call" );
282 mxRuler->MoveSplit( nParam1, nParam2 );
283 mxGrid->MoveSplit( nParam1, nParam2 );
284 break;
285 case CSVCMD_REMOVEALLSPLITS:
286 OSL_ENSURE( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::RemoveAllSplits - invalid call" );
287 mxRuler->RemoveAllSplits();
288 mxGrid->RemoveAllSplits();
289 break;
290 default:
291 bFound = false;
293 if( bFound )
294 return;
296 const ScCsvLayoutData aOldData( maData );
297 switch( eType )
299 case CSVCMD_SETPOSCOUNT:
300 maData.mnPosCount = std::max( nParam1, sal_Int32( 1 ) );
301 ImplSetPosOffset( mxGrid->GetFirstVisPos() );
302 break;
303 case CSVCMD_SETPOSOFFSET:
304 ImplSetPosOffset( nParam1 );
305 break;
306 case CSVCMD_SETHDRWIDTH:
307 maData.mnHdrWidth = std::max( nParam1, sal_Int32( 0 ) );
308 ImplSetPosOffset( mxGrid->GetFirstVisPos() );
309 break;
310 case CSVCMD_SETCHARWIDTH:
311 maData.mnCharWidth = std::max( nParam1, sal_Int32( 1 ) );
312 ImplSetPosOffset( mxGrid->GetFirstVisPos() );
313 break;
314 case CSVCMD_SETLINECOUNT:
315 maData.mnLineCount = std::max( nParam1, sal_Int32( 1 ) );
316 ImplSetLineOffset( mxGrid->GetFirstVisLine() );
317 break;
318 case CSVCMD_SETLINEOFFSET:
319 ImplSetLineOffset( nParam1 );
320 break;
321 case CSVCMD_SETHDRHEIGHT:
322 maData.mnHdrHeight = std::max( nParam1, sal_Int32( 0 ) );
323 ImplSetLineOffset( mxGrid->GetFirstVisLine() );
324 break;
325 case CSVCMD_SETLINEHEIGHT:
326 maData.mnLineHeight = std::max( nParam1, sal_Int32( 1 ) );
327 ImplSetLineOffset( mxGrid->GetFirstVisLine() );
328 break;
329 case CSVCMD_MOVERULERCURSOR:
330 maData.mnPosCursor = mxGrid->IsVisibleSplitPos( nParam1 ) ? nParam1 : CSV_POS_INVALID;
331 break;
332 case CSVCMD_MOVEGRIDCURSOR:
333 maData.mnColCursor = ((0 <= nParam1) && (nParam1 < mxGrid->GetPosCount())) ? nParam1 : CSV_POS_INVALID;
334 break;
335 default:
337 // added to avoid warnings
341 if( maData != aOldData )
343 mxGrid->DisableRepaint();
344 mxRuler->ApplyLayout( aOldData );
345 mxGrid->ApplyLayout( aOldData );
346 mxGrid->EnableRepaint();
350 IMPL_LINK(ScCsvTableBox, HScrollHdl, weld::ScrolledWindow&, rScroll, void)
352 int nLower = 0;
353 int nValue = rScroll.hadjustment_get_value();
354 int nUpper = mxGrid->GetPosCount() + 2;
355 int nPageSize = mxGrid->GetVisPosCount();
357 // Undo scrollbar RTL
358 if (AllSettings::GetLayoutRTL())
359 nValue = nUpper - (nValue - nLower + nPageSize);
361 mxGrid->Execute(CSVCMD_SETPOSOFFSET, nValue);
362 maEndScrollIdle.Start();
365 IMPL_LINK(ScCsvTableBox, VScrollHdl, weld::ScrolledWindow&, rScroll, void)
367 mxGrid->Execute(CSVCMD_SETLINEOFFSET, rScroll.vadjustment_get_value());
370 IMPL_LINK_NOARG(ScCsvTableBox, ScrollEndHdl, Timer*, void)
372 if( mxGrid->GetRulerCursorPos() != CSV_POS_INVALID )
373 mxGrid->Execute( CSVCMD_MOVERULERCURSOR, mxRuler->GetNoScrollPos( mxGrid->GetRulerCursorPos() ) );
374 if( mxGrid->GetGridCursorPos() != CSV_POS_INVALID )
375 mxGrid->Execute( CSVCMD_MOVEGRIDCURSOR, mxGrid->GetNoScrollCol( mxGrid->GetGridCursorPos() ) );
378 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */