LibreOffice Module dbaccess (master) 1
WTypeSelect.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 <WTypeSelect.hxx>
21#include <bitmaps.hlst>
23#include <osl/diagnose.h>
24#include <FieldDescriptions.hxx>
25#include <WCopyTable.hxx>
26#include <strings.hrc>
27#include <tools/stream.hxx>
28#include <vcl/commandevent.hxx>
29#include <vcl/svapp.hxx>
30#include <UITools.hxx>
31#include <core_resource.hxx>
32#include <FieldControls.hxx>
33
34using namespace ::dbaui;
35using namespace ::com::sun::star::uno;
36using namespace ::com::sun::star::beans;
37using namespace ::com::sun::star::container;
38using namespace ::com::sun::star::util;
39using namespace ::com::sun::star::sdbc;
40
41// OWizTypeSelectControl
42OWizTypeSelectControl::OWizTypeSelectControl(weld::Container* pPage, OWizTypeSelect* pParentTabPage)
43 : OFieldDescControl(pPage, nullptr)
44 , m_pParentTabPage(pParentTabPage)
45{
46}
47
49{
50}
51
53{
54 switch(eType )
55 {
56 case tpFormat:
57 case tpDefault:
58 case tpAutoIncrement:
60 break;
61 default:
63 }
64}
65
67{
68 switch(eType )
69 {
70 case tpFormat:
71 case tpDefault:
72 case tpAutoIncrement:
74 break;
75 default:
77 }
78}
79
80void OWizTypeSelectControl::CellModified(sal_Int32 nRow, sal_uInt16 nColId )
81{
82 OSL_ENSURE(nRow == -1,"nRow must be -1!");
83
84 weld::TreeView* pListBox = m_pParentTabPage->m_xColumnNames->GetWidget();
85
87
88 const sal_Int32 nPos = pListBox->find_text(pCurFieldDescr->GetName());
89 pCurFieldDescr = weld::fromId<OFieldDescription*>(pListBox->get_id(nPos));
90 OSL_ENSURE( pCurFieldDescr, "OWizTypeSelectControl::CellModified: Columnname/type not found in the listbox!" );
91 if ( !pCurFieldDescr )
92 return;
93 setCurrentFieldDescData( pCurFieldDescr );
94
95 OUString sName = pCurFieldDescr->GetName();
96 OUString sNewName;
97 const OPropColumnEditCtrl* pColumnName = getColumnCtrl();
98 if ( pColumnName )
99 sNewName = pColumnName->get_text();
100
101 switch(nColId)
102 {
104 {
105 OCopyTableWizard* pWiz = m_pParentTabPage->m_pParent;
106 // first we have to check if this name already exists
107 bool bDoubleName = false;
108 bool bCase = true;
109 if ( getMetaData().is() && !getMetaData()->supportsMixedCaseQuotedIdentifiers() )
110 {
111 bCase = false;
112 const sal_Int32 nCount = pListBox->n_children();
113 for (sal_Int32 i=0 ; !bDoubleName && i < nCount ; ++i)
114 {
115 OUString sEntry(pListBox->get_text(i));
116 bDoubleName = sNewName.equalsIgnoreAsciiCase(sEntry);
117 }
118 if ( !bDoubleName && pWiz->shouldCreatePrimaryKey() )
119 bDoubleName = sNewName.equalsIgnoreAsciiCase(pWiz->getPrimaryKeyName());
120
121 }
122 else
123 bDoubleName = ((pListBox->find_text(sNewName) != -1)
124 || ( pWiz->shouldCreatePrimaryKey()
125 && pWiz->getPrimaryKeyName() == sNewName) );
126
127 if ( bDoubleName )
128 {
129 OUString strMessage = DBA_RES(STR_TABLEDESIGN_DUPLICATE_NAME);
130 strMessage = strMessage.replaceFirst("$column$", sNewName);
131 pWiz->showError(strMessage);
132 pCurFieldDescr->SetName(sName);
133 DisplayData(pCurFieldDescr);
135 return;
136 }
137
138 OUString sOldName = pCurFieldDescr->GetName();
139 pCurFieldDescr->SetName(sNewName);
141
142 // now we change the name
143
145 for (auto & elem : pWiz->m_mNameMapping)
146 {
147 if ( aCase(elem.second,sName) )
148 {
149 elem.second = sNewName;
150 break;
151 }
152 }
153
154 pListBox->remove(nPos);
155 pListBox->insert_text(nPos, pCurFieldDescr->GetName());
156 pListBox->set_id(nPos, weld::toId(pCurFieldDescr));
157
158 pWiz->replaceColumn(nPos,pCurFieldDescr,sOldName);
159 }
160 break;
161 }
163}
164
165css::lang::Locale OWizTypeSelectControl::GetLocale() const
166{
167 return m_pParentTabPage->m_pParent->GetLocale();
168}
169
171{
172 return m_pParentTabPage->m_pParent->GetFormatter();
173}
174
176{
177 return m_pParentTabPage->m_pParent->getDestTypeInfo(_nPos);
178}
179
181{
182 return &m_pParentTabPage->m_pParent->getDestTypeInfo();
183}
184
185css::uno::Reference< css::sdbc::XDatabaseMetaData> OWizTypeSelectControl::getMetaData()
186{
187 return m_pParentTabPage->m_pParent->m_xDestConnection->getMetaData();
188}
189
190css::uno::Reference< css::sdbc::XConnection> OWizTypeSelectControl::getConnection()
191{
192 return m_pParentTabPage->m_pParent->m_xDestConnection;
193}
194
196{
198}
199
201{
203}
204
206 : OWizardPage(pPage, pWizard, "dbaccess/ui/typeselectpage.ui", "TypeSelect")
207 , m_xColumnNames(new OWizTypeSelectList(m_xBuilder->weld_tree_view("columnnames")))
208 , m_xControlContainer(m_xBuilder->weld_container("control_container"))
209 , m_xTypeControl(new OWizTypeSelectControl(m_xControlContainer.get(), this))
210 , m_xAutoType(m_xBuilder->weld_label("autotype"))
211 , m_xAutoFt(m_xBuilder->weld_label("autolabel"))
212 , m_xAutoEt(m_xBuilder->weld_spin_button("auto"))
213 , m_xAutoPb(m_xBuilder->weld_button("autobutton"))
214 , m_pParserStream(pStream)
215 , m_nDisplayRow(0)
216 , m_bAutoIncrementEnabled(false)
217 , m_bDuplicateName(false)
218{
219 m_xColumnNames->connect_changed(LINK(this,OWizTypeSelect,ColumnSelectHdl));
220
221 m_xTypeControl->Init();
222
223 m_xAutoEt->set_text("10");
224 m_xAutoEt->set_digits(0);
225 m_xAutoPb->connect_clicked(LINK(this,OWizTypeSelect,ButtonClickHdl));
226 m_xColumnNames->set_selection_mode(SelectionMode::Multiple);
227
228 try
229 {
230 m_xColumnNames->SetPKey( m_pParent->supportsPrimaryKey() );
232 }
233 catch(const Exception&)
234 {
235 DBG_UNHANDLED_EXCEPTION("dbaccess");
236 }
237}
238
240{
241}
242
244{
245 return DBA_RES(STR_WIZ_TYPE_SELECT_TITLE);
246}
247
248IMPL_LINK_NOARG(OWizTypeSelect, ColumnSelectHdl, weld::TreeView&, void)
249{
250 OFieldDescription* pField = weld::fromId<OFieldDescription*>(m_xColumnNames->get_selected_id());
251 if (pField)
252 m_xTypeControl->DisplayData(pField);
253
254 m_xTypeControl->Enable(m_xColumnNames->count_selected_rows() == 1);
255}
256
258{
259 // restore original state
260 m_xColumnNames->clear();
261 sal_Int32 nCount(0), nBreakPos;
262 m_pParent->CheckColumns(nBreakPos);
263
264 const ODatabaseExport::TColumnVector& rDestColumns = m_pParent->getDestVector();
265 for (auto const& column : rDestColumns)
266 {
267 OUString sId(weld::toId(column->second));
268 m_xColumnNames->append(sId, column->first);
269 if (column->second->IsPrimaryKey())
270 m_xColumnNames->set_image(nCount, BMP_PRIMARY_KEY);
271 ++nCount;
272 }
273 m_bFirstTime = false;
274}
275
277{
278 bool bOldFirstTime = m_bFirstTime;
279 Reset();
280 m_bFirstTime = bOldFirstTime;
281
283 m_nDisplayRow = 0;
284 ColumnSelectHdl(*m_xColumnNames->GetWidget());
285}
286
288{
289 bool bDuplicateName = false;
290 OFieldDescription* pField = weld::fromId<OFieldDescription*>(m_xColumnNames->get_selected_id());
291 if ( pField )
292 {
293 m_xTypeControl->SaveData(pField);
294 bDuplicateName = m_bDuplicateName;
295 }
296 return !bDuplicateName;
297}
298
300{
301 m_xAutoFt->set_visible(bEnable);
302 m_xAutoEt->set_visible(bEnable);
303 m_xAutoPb->set_visible(bEnable);
304 m_xAutoType->set_visible(bEnable);
305}
306
307IMPL_LINK_NOARG(OWizTypeSelect, ButtonClickHdl, weld::Button&, void)
308{
309 sal_Int32 nBreakPos;
310 m_pParent->CheckColumns(nBreakPos);
311
312 // fill column list
313 sal_uInt32 nRows = m_xAutoEt->get_text().toInt32();
314 if(m_pParserStream)
315 {
316 sal_uInt64 const nTell = m_pParserStream->Tell(); // might change seek position of stream
317
318 createReaderAndCallParser(nRows);
319 m_pParserStream->Seek(nTell);
320 }
321
322 Activate();
323}
324
325OWizTypeSelectList::OWizTypeSelectList(std::unique_ptr<weld::TreeView> xControl)
326 : m_xControl(std::move(xControl))
327 , m_bPKey(false)
328{
329 m_xControl->connect_popup_menu(LINK(this, OWizTypeSelectList, CommandHdl));
330}
331
333{
334 auto aRows = m_xControl->get_selected_rows();
335 std::sort(aRows.begin(), aRows.end());
336
337 const sal_Int32 nCount = aRows.size();
338
339 for( sal_Int32 j = 0; m_bPKey && j < nCount; ++j )
340 {
341 OFieldDescription* pField = weld::fromId<OFieldDescription*>(m_xControl->get_id(aRows[j]));
342 if(!pField || pField->getTypeInfo()->nSearchType == ColumnSearch::NONE)
343 return false;
344 }
345 return true;
346}
347
348void OWizTypeSelectList::setPrimaryKey(OFieldDescription* _pFieldDescr, sal_uInt16 _nPos, bool _bSet)
349{
350 _pFieldDescr->SetPrimaryKey(_bSet);
351 if( _bSet )
352 {
353 m_xControl->set_image(_nPos, BMP_PRIMARY_KEY);
354 }
355 else if( _pFieldDescr->getTypeInfo()->bNullable )
356 {
357 _pFieldDescr->SetControlDefault(Any());
358 m_xControl->set_image(_nPos, OUString());
359 }
360}
361
362IMPL_LINK(OWizTypeSelectList, CommandHdl, const CommandEvent&, rCEvt, bool)
363{
364 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
365 return false;
366 if (!IsPrimaryKeyAllowed())
367 return false;
368
369 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xControl.get(), "dbaccess/ui/keymenu.ui"));
370 auto xContextMenu = xBuilder->weld_menu("menu");
371 // Should primary key checkbox be checked?
372 const sal_Int32 nCount = m_xControl->n_children();
373 bool bCheckOk = false;
374 for(sal_Int32 j = 0 ; j < nCount ; ++j)
375 {
376 OFieldDescription* pFieldDescr = weld::fromId<OFieldDescription*>(m_xControl->get_id(j));
377 // if at least one of the fields is selected but not in the primary key,
378 // or is in the primary key but not selected, then don't check the
379 // primary key checkbox.
380 if( pFieldDescr && pFieldDescr->IsPrimaryKey() != m_xControl->is_selected(j) )
381 {
382 bCheckOk = false;
383 break;
384 }
385 if (!bCheckOk && m_xControl->is_selected(j))
386 bCheckOk = true;
387 }
388
389 if (bCheckOk)
390 xContextMenu->set_active("primarykey", true);
391
392 OUString sCommand(xContextMenu->popup_at_rect(m_xControl.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
393 if (sCommand != "primarykey")
394 return true;
395
396 for (sal_Int32 j = 0 ; j < nCount; ++j)
397 {
398 OFieldDescription* pFieldDescr = weld::fromId<OFieldDescription*>(m_xControl->get_id(j));
399 if (pFieldDescr)
400 {
401 if(!bCheckOk && m_xControl->is_selected(j))
402 {
403 setPrimaryKey(pFieldDescr,j,true);
404 }
405 else
406 {
407 setPrimaryKey(pFieldDescr,j);
408 }
409 }
410 }
411 m_aChangeHdl.Call(*m_xControl);
412
413 return true;
414}
415
416/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define FIELD_PROPERTY_COLUMNNAME
OptionalString sName
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
const OUString & getPrimaryKeyName() const
returns the name of the primary key
Definition: WCopyTable.hxx:366
void replaceColumn(sal_Int32 _nPos, OFieldDescription *_pField, const OUString &_sOldName)
replaces a field description with another one.
Definition: WCopyTable.cxx:974
TNameMapping m_mNameMapping
Definition: WCopyTable.hxx:240
bool shouldCreatePrimaryKey() const
returns whether a primary key should be created in the target database
Definition: WCopyTable.hxx:353
void showError(const OUString &_sErrorMessage)
std::vector< TColumns::const_iterator > TColumnVector
Definition: DExport.hxx:58
virtual void ActivateAggregate(EControlType eType)
OFieldDescription * getCurrentFieldDescData()
void DisplayData(OFieldDescription *pFieldDescr)
void setCurrentFieldDescData(OFieldDescription *_pDesc)
const OPropColumnEditCtrl * getColumnCtrl() const
virtual void DeactivateAggregate(EControlType eType)
void SetControlDefault(const css::uno::Any &_rControlDefault)
const TOTypeInfoSP & getTypeInfo() const
void SetPrimaryKey(bool _bPKey)
void SetName(const OUString &_rName)
OUString get_text() const
virtual css::lang::Locale GetLocale() const override
virtual bool isAutoIncrementValueEnabled() const override
OWizTypeSelect * m_pParentTabPage
Definition: WTypeSelect.hxx:34
virtual ~OWizTypeSelectControl() override
Definition: WTypeSelect.cxx:48
virtual css::uno::Reference< css::sdbc::XDatabaseMetaData > getMetaData() override
virtual void DeactivateAggregate(EControlType eType) override
Definition: WTypeSelect.cxx:66
virtual css::uno::Reference< css::util::XNumberFormatter > GetFormatter() const override
virtual OUString getAutoIncrementValue() const override
virtual void ActivateAggregate(EControlType eType) override
Definition: WTypeSelect.cxx:52
virtual void CellModified(sal_Int32 nRow, sal_uInt16 nColId) override
Definition: WTypeSelect.cxx:80
virtual const OTypeInfoMap * getTypeInfo() const override
virtual css::uno::Reference< css::sdbc::XConnection > getConnection() override
OWizTypeSelectList(std::unique_ptr< weld::TreeView > xControl)
void setPrimaryKey(OFieldDescription *_pFieldDescr, sal_uInt16 _nPos, bool _bSet=false)
std::unique_ptr< weld::TreeView > m_xControl
Definition: WTypeSelect.hxx:59
bool IsPrimaryKeyAllowed() const
std::unique_ptr< weld::Label > m_xAutoType
std::unique_ptr< OWizTypeSelectControl > m_xTypeControl
void setDuplicateName(bool _bDuplicateName)
virtual void Reset() override
std::unique_ptr< weld::Label > m_xAutoFt
std::unique_ptr< weld::SpinButton > m_xAutoEt
OWizTypeSelect(weld::Container *pParent, OCopyTableWizard *pWizard, SvStream *pStream=nullptr)
void EnableAuto(bool bEnable)
OUString m_sAutoIncrementValue
virtual ~OWizTypeSelect() override
std::unique_ptr< weld::Button > m_xAutoPb
std::unique_ptr< OWizTypeSelectList > m_xColumnNames
virtual void Activate() override
virtual OUString GetTitle() const override
virtual bool LeavePage() override
virtual int find_text(const OUString &rText) const=0
virtual OUString get_text(int row, int col=-1) const=0
virtual int n_children() const=0
void insert_text(int pos, const OUString &rStr)
virtual void remove(int pos)=0
virtual void set_id(int row, const OUString &rId)=0
virtual OUString get_id(int pos) const=0
#define DBA_RES(id)
int nCount
#define DBG_UNHANDLED_EXCEPTION(...)
OUString eType
Definition: generalpage.cxx:78
sal_uInt16 nPos
@ Exception
std::multimap< DataTypeEnum, OExtendedTypeInfo * > OTypeInfoMap
IMPL_LINK_NOARG(OApplicationController, OnClipboardChanged, TransferableDataHelper *, void)
void fillAutoIncrementValue(const css::uno::Reference< css::beans::XPropertySet > &_xDatasource, bool &_rAutoIncrementValueEnabled, OUString &_rsAutoIncrementValue)
fills the bool and string value with information out of the datasource info property
IMPL_LINK(OApplicationController, OnSelectContainer, void *, _pType, void)
std::shared_ptr< OTypeInfo > TOTypeInfoSP
Definition: TypeInfo.hxx:99
EControlType
Definition: QEnumTypes.hxx:63
@ tpDefault
Definition: QEnumTypes.hxx:64
@ tpFormat
Definition: QEnumTypes.hxx:70
@ tpAutoIncrementValue
Definition: QEnumTypes.hxx:75
@ tpAutoIncrement
Definition: QEnumTypes.hxx:71
int i
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
OUString toId(const void *pValue)
OUString sId
Definition: unodatbr.cxx:1040
Reference< XControl > m_xControl
sal_Int32 _nPos