tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / dbaccess / source / ui / dlg / TextConnectionHelper.cxx
blobe186b139c4e150debe25adf127442e675056385d
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 <core_resource.hxx>
21 #include "TextConnectionHelper.hxx"
22 #include <strings.hrc>
23 #include <strings.hxx>
24 #include <svl/itemset.hxx>
25 #include <svl/stritem.hxx>
26 #include <svl/eitem.hxx>
27 #include <dsitems.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/weld.hxx>
30 #include <vcl/mnemonic.hxx>
31 #include <o3tl/string_view.hxx>
33 namespace
36 OUString lcl_getListEntry(std::u16string_view rStr, sal_Int32& rIdx)
38 const OUString sTkn {o3tl::getToken(rStr, 0, '\t', rIdx )};
39 if (rIdx>=0)
41 size_t nFnd = rStr.find('\t', rIdx);
42 if (nFnd == std::u16string_view::npos)
43 rIdx = -1;
44 else
46 rIdx = nFnd + 1;
47 if (rIdx >= static_cast<sal_Int32>(rStr.size()))
48 rIdx = -1;
51 return sTkn;
56 namespace dbaui
59 OTextConnectionHelper::OTextConnectionHelper(weld::Widget* pParent, const short _nAvailableSections)
60 : m_aFieldSeparatorList (DBA_RES(STR_AUTOFIELDSEPARATORLIST))
61 , m_aTextSeparatorList (STR_AUTOTEXTSEPARATORLIST)
62 , m_aTextNone (DBA_RES(STR_AUTOTEXT_FIELD_SEP_NONE))
63 , m_nAvailableSections( _nAvailableSections )
64 , m_xBuilder(Application::CreateBuilder(pParent, u"dbaccess/ui/textpage.ui"_ustr))
65 , m_xContainer(m_xBuilder->weld_widget(u"TextPage"_ustr))
66 , m_xExtensionHeader(m_xBuilder->weld_widget(u"extensionframe"_ustr))
67 , m_xAccessTextFiles(m_xBuilder->weld_radio_button(u"textfile"_ustr))
68 , m_xAccessCSVFiles(m_xBuilder->weld_radio_button(u"csvfile"_ustr))
69 , m_xAccessOtherFiles(m_xBuilder->weld_radio_button(u"custom"_ustr))
70 , m_xOwnExtension(m_xBuilder->weld_entry(u"extension"_ustr))
71 , m_xExtensionExample(m_xBuilder->weld_label(u"example"_ustr))
72 , m_xFormatHeader(m_xBuilder->weld_widget(u"formatframe"_ustr))
73 , m_xFieldSeparatorLabel(m_xBuilder->weld_label(u"fieldlabel"_ustr))
74 , m_xFieldSeparator(m_xBuilder->weld_combo_box(u"fieldseparator"_ustr))
75 , m_xTextSeparatorLabel(m_xBuilder->weld_label(u"textlabel"_ustr))
76 , m_xTextSeparator(m_xBuilder->weld_combo_box(u"textseparator"_ustr))
77 , m_xDecimalSeparatorLabel(m_xBuilder->weld_label(u"decimallabel"_ustr))
78 , m_xDecimalSeparator(m_xBuilder->weld_combo_box(u"decimalseparator"_ustr))
79 , m_xThousandsSeparatorLabel(m_xBuilder->weld_label(u"thousandslabel"_ustr))
80 , m_xThousandsSeparator(m_xBuilder->weld_combo_box(u"thousandsseparator"_ustr))
81 , m_xRowHeader(m_xBuilder->weld_check_button(u"containsheaders"_ustr))
82 , m_xCharSetHeader(m_xBuilder->weld_widget(u"charsetframe"_ustr))
83 , m_xCharSetLabel(m_xBuilder->weld_label(u"charsetlabel"_ustr))
84 , m_xCharSet(new CharSetListBox(m_xBuilder->weld_combo_box(u"charset"_ustr)))
86 for(sal_Int32 nIdx {0}; nIdx>=0;)
87 m_xFieldSeparator->append_text( lcl_getListEntry(m_aFieldSeparatorList, nIdx) );
89 for(sal_Int32 nIdx {0}; nIdx>=0;)
90 m_xTextSeparator->append_text( lcl_getListEntry(m_aTextSeparatorList, nIdx) );
91 m_xTextSeparator->append_text(m_aTextNone);
93 m_xOwnExtension->connect_changed(LINK(this, OTextConnectionHelper, OnEditModified));
94 m_xAccessTextFiles->connect_toggled(LINK(this, OTextConnectionHelper, OnSetExtensionHdl));
95 m_xAccessCSVFiles->connect_toggled(LINK(this, OTextConnectionHelper, OnSetExtensionHdl));
96 m_xAccessOtherFiles->connect_toggled(LINK(this, OTextConnectionHelper, OnSetExtensionHdl));
97 m_xAccessCSVFiles->set_active(true);
99 struct SectionDescriptor
101 short nFlag;
102 weld::Widget* pFrame;
103 } const aSections[] = {
104 { TC_EXTENSION, m_xExtensionHeader.get() },
105 { TC_SEPARATORS, m_xFormatHeader.get() },
106 { TC_HEADER, m_xRowHeader.get() },
107 { TC_CHARSET, m_xCharSetHeader.get() }
110 for (auto const & section: aSections)
112 if ( ( m_nAvailableSections & section.nFlag ) != 0 )
114 // the section is visible, no need to do anything here
115 continue;
118 // hide all elements from this section
119 section.pFrame->hide();
122 m_xContainer->show();
125 IMPL_LINK_NOARG(OTextConnectionHelper, OnEditModified, weld::Entry&, void)
127 m_aGetExtensionHandler.Call(this);
130 IMPL_LINK_NOARG(OTextConnectionHelper, OnSetExtensionHdl, weld::Toggleable&, void)
132 bool bDoEnable = m_xAccessOtherFiles->get_active();
133 m_xOwnExtension->set_sensitive(bDoEnable);
134 m_xExtensionExample->set_sensitive(bDoEnable);
135 m_aGetExtensionHandler.Call(this);
138 void OTextConnectionHelper::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
140 _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xFieldSeparator.get()));
141 _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xTextSeparator.get()));
142 _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xDecimalSeparator.get()));
143 _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xThousandsSeparator.get()));
144 _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xRowHeader.get()));
145 _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xCharSet->get_widget()));
148 void OTextConnectionHelper::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
150 _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFieldSeparatorLabel.get()));
151 _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xTextSeparatorLabel.get()));
152 _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xDecimalSeparatorLabel.get()));
153 _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xThousandsSeparatorLabel.get()));
154 _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Widget>(m_xCharSetHeader.get()));
155 _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xCharSetLabel.get()));
156 _rControlList.emplace_back(new ODisableWidgetWrapper<weld::ComboBox>(m_xCharSet->get_widget()));
159 void OTextConnectionHelper::implInitControls(const SfxItemSet& _rSet, bool _bValid)
161 if ( !_bValid )
162 return;
164 const SfxStringItem* pDelItem = _rSet.GetItem<SfxStringItem>(DSID_FIELDDELIMITER);
165 const SfxStringItem* pStrItem = _rSet.GetItem<SfxStringItem>(DSID_TEXTDELIMITER);
166 const SfxStringItem* pDecdelItem = _rSet.GetItem<SfxStringItem>(DSID_DECIMALDELIMITER);
167 const SfxStringItem* pThodelItem = _rSet.GetItem<SfxStringItem>(DSID_THOUSANDSDELIMITER);
168 const SfxStringItem* pExtensionItem = _rSet.GetItem<SfxStringItem>(DSID_TEXTFILEEXTENSION);
169 const SfxStringItem* pCharsetItem = _rSet.GetItem<SfxStringItem>(DSID_CHARSET);
171 if ( ( m_nAvailableSections & TC_EXTENSION ) != 0 )
173 m_aOldExtension = pExtensionItem->GetValue();
174 SetExtension( m_aOldExtension );
177 if ( ( m_nAvailableSections & TC_HEADER ) != 0 )
179 const SfxBoolItem* pHdrItem = _rSet.GetItem<SfxBoolItem>(DSID_TEXTFILEHEADER);
180 m_xRowHeader->set_active(pHdrItem->GetValue());
183 if ( ( m_nAvailableSections & TC_SEPARATORS ) != 0 )
185 SetSeparator(*m_xFieldSeparator, m_aFieldSeparatorList, pDelItem->GetValue());
186 SetSeparator(*m_xTextSeparator, m_aTextSeparatorList, pStrItem->GetValue());
187 m_xDecimalSeparator->set_entry_text( pDecdelItem->GetValue() );
188 m_xThousandsSeparator->set_entry_text( pThodelItem->GetValue() );
191 if ( ( m_nAvailableSections & TC_CHARSET ) != 0 )
193 m_xCharSet->SelectEntryByIanaName( pCharsetItem->GetValue() );
197 bool OTextConnectionHelper::prepareLeave()
199 OUString sExtension = GetExtension();
200 OUString aErrorText;
201 weld::Widget* pErrorWin = nullptr;
202 OUString aDelText(m_xFieldSeparator->get_active_text());
203 if(aDelText.isEmpty())
204 { // No FieldSeparator
205 aErrorText = DBA_RES(STR_AUTODELIMITER_MISSING);
206 aErrorText = aErrorText.replaceFirst("#1",m_xFieldSeparatorLabel->get_label());
207 pErrorWin = m_xFieldSeparator.get();
209 else if (m_xDecimalSeparator->get_active_text().isEmpty())
210 { // No DecimalSeparator
211 aErrorText = DBA_RES(STR_AUTODELIMITER_MISSING);
212 aErrorText = aErrorText.replaceFirst("#1",m_xDecimalSeparatorLabel->get_label());
213 pErrorWin = m_xDecimalSeparator.get();
215 else if (m_xTextSeparator->get_active_text() == m_xFieldSeparator->get_active_text())
216 { // Field and TextSeparator must not be the same
217 aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
218 aErrorText = aErrorText.replaceFirst("#1",m_xTextSeparatorLabel->get_label());
219 aErrorText = aErrorText.replaceFirst("#2",m_xFieldSeparatorLabel->get_label());
220 pErrorWin = m_xTextSeparator.get();
222 else if (m_xDecimalSeparator->get_active_text() == m_xThousandsSeparator->get_active_text())
223 { // Thousands and DecimalSeparator must not be the same
224 aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
225 aErrorText = aErrorText.replaceFirst("#1",m_xDecimalSeparatorLabel->get_label());
226 aErrorText = aErrorText.replaceFirst("#2",m_xThousandsSeparatorLabel->get_label());
227 pErrorWin = m_xDecimalSeparator.get();
229 else if (m_xFieldSeparator->get_active_text() == m_xThousandsSeparator->get_active_text())
230 { // Thousands and FieldSeparator must not be the same
231 aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
232 aErrorText = aErrorText.replaceFirst("#1",m_xFieldSeparatorLabel->get_label());
233 aErrorText = aErrorText.replaceFirst("#2",m_xThousandsSeparatorLabel->get_label());
234 pErrorWin = m_xFieldSeparator.get();
236 else if (m_xFieldSeparator->get_active_text() == m_xDecimalSeparator->get_active_text())
237 { // Tenner and FieldSeparator must not be the same
238 aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
239 aErrorText = aErrorText.replaceFirst("#1",m_xFieldSeparatorLabel->get_label());
240 aErrorText = aErrorText.replaceFirst("#2",m_xDecimalSeparatorLabel->get_label());
241 pErrorWin = m_xFieldSeparator.get();
243 else if (m_xTextSeparator->get_active_text() == m_xThousandsSeparator->get_active_text())
244 { // Thousands and TextSeparator must not be the same
245 aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
246 aErrorText = aErrorText.replaceFirst("#1",m_xTextSeparatorLabel->get_label());
247 aErrorText = aErrorText.replaceFirst("#2",m_xThousandsSeparatorLabel->get_label());
248 pErrorWin = m_xTextSeparator.get();
250 else if (m_xTextSeparator->get_active_text() == m_xDecimalSeparator->get_active_text())
251 { // Tenner and TextSeparator must not be the same
252 aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
253 aErrorText = aErrorText.replaceFirst("#1",m_xTextSeparatorLabel->get_label());
254 aErrorText = aErrorText.replaceFirst("#2",m_xDecimalSeparatorLabel->get_label());
255 pErrorWin = m_xTextSeparator.get();
257 else if ((sExtension.indexOf('*') != -1) || (sExtension.indexOf('?') != -1))
259 aErrorText = DBA_RES(STR_AUTONO_WILDCARDS);
260 aErrorText = aErrorText.replaceFirst("#1",sExtension);
261 pErrorWin = m_xOwnExtension.get();
263 else
264 return true;
265 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xContainer.get(),
266 VclMessageType::Warning, VclButtonsType::Ok,
267 MnemonicGenerator::EraseAllMnemonicChars(aErrorText)));
268 xBox->run();
269 pErrorWin->grab_focus();
270 return false;
273 bool OTextConnectionHelper::FillItemSet( SfxItemSet& rSet, const bool _bChangedSomething )
275 bool bChangedSomething = _bChangedSomething;
277 if ( ( m_nAvailableSections & TC_EXTENSION ) != 0 )
279 OUString sExtension = GetExtension();
280 if( m_aOldExtension != sExtension )
282 rSet.Put( SfxStringItem( DSID_TEXTFILEEXTENSION, sExtension ) );
283 bChangedSomething = true;
287 if ( ( m_nAvailableSections & TC_HEADER ) != 0 )
289 if (m_xRowHeader->get_state_changed_from_saved())
291 rSet.Put(SfxBoolItem(DSID_TEXTFILEHEADER, m_xRowHeader->get_active()));
292 bChangedSomething = true;
296 if ( ( m_nAvailableSections & TC_SEPARATORS ) != 0 )
298 if (m_xFieldSeparator->get_value_changed_from_saved())
300 rSet.Put( SfxStringItem(DSID_FIELDDELIMITER, GetSeparator( *m_xFieldSeparator, m_aFieldSeparatorList) ) );
301 bChangedSomething = true;
303 if (m_xTextSeparator->get_value_changed_from_saved())
305 rSet.Put( SfxStringItem(DSID_TEXTDELIMITER, GetSeparator( *m_xTextSeparator, m_aTextSeparatorList) ) );
306 bChangedSomething = true;
309 if (m_xDecimalSeparator->get_value_changed_from_saved())
311 rSet.Put( SfxStringItem(DSID_DECIMALDELIMITER, m_xDecimalSeparator->get_active_text().copy(0, 1) ) );
312 bChangedSomething = true;
314 if (m_xThousandsSeparator->get_value_changed_from_saved())
316 rSet.Put( SfxStringItem(DSID_THOUSANDSDELIMITER, m_xThousandsSeparator->get_active_text().copy(0,1) ) );
317 bChangedSomething = true;
321 if ( ( m_nAvailableSections & TC_CHARSET ) != 0 )
323 if ( m_xCharSet->StoreSelectedCharSet( rSet, DSID_CHARSET ) )
324 bChangedSomething = true;
327 return bChangedSomething;
330 void OTextConnectionHelper::SetExtension(const OUString& _rVal)
332 if (_rVal == "txt")
333 m_xAccessTextFiles->set_active(true);
334 else if (_rVal == "csv")
335 m_xAccessCSVFiles->set_active(true);
336 else
338 m_xAccessOtherFiles->set_active(true);
339 m_xExtensionExample->set_label(_rVal);
343 OUString OTextConnectionHelper::GetExtension() const
345 OUString sExtension;
346 if (m_xAccessTextFiles->get_active())
347 sExtension = "txt";
348 else if (m_xAccessCSVFiles->get_active())
349 sExtension = "csv";
350 else
352 sExtension = m_xOwnExtension->get_text();
353 if ( sExtension.startsWith("*.") )
354 sExtension = sExtension.copy(2);
356 return sExtension;
359 OUString OTextConnectionHelper::GetSeparator(const weld::ComboBox& rBox, std::u16string_view rList)
361 sal_Unicode const nTok = '\t';
362 int nPos(rBox.find_text(rBox.get_active_text()));
364 if (nPos == -1)
365 return rBox.get_active_text();
367 if ( m_xTextSeparator.get() != &rBox || nPos != (rBox.get_count()-1) )
368 return OUString(
369 static_cast< sal_Unicode >( o3tl::toInt32(o3tl::getToken(rList, (nPos*2)+1, nTok )) ));
370 // somewhat strange ... translates for instance an "32" into " "
371 return OUString();
374 void OTextConnectionHelper::SetSeparator( weld::ComboBox& rBox, std::u16string_view rList, const OUString& rVal )
376 if (rVal.getLength()==1)
378 const sal_Unicode nVal {rVal[0]};
379 for(sal_Int32 nIdx {0}; nIdx>=0;)
381 sal_Int32 nPrevIdx {nIdx};
382 if (static_cast<sal_Unicode>(o3tl::toInt32(o3tl::getToken(rList, 1, '\t', nIdx))) == nVal)
384 rBox.set_entry_text(OUString(o3tl::getToken(rList,0, '\t', nPrevIdx)));
385 return;
388 rBox.set_entry_text( rVal );
390 else if ( m_xTextSeparator.get() == &rBox && rVal.isEmpty() )
391 rBox.set_entry_text(m_aTextNone);
392 else
393 rBox.set_entry_text(rVal.copy(0, 1));
397 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */