1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <WTypeSelect.hxx>
21 #include <bitmaps.hlst>
22 #include <comphelper/diagnose_ex.hxx>
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>
34 using namespace ::dbaui
;
35 using namespace ::com::sun::star::uno
;
36 using namespace ::com::sun::star::container
;
37 using namespace ::com::sun::star::util
;
38 using namespace ::com::sun::star::sdbc
;
40 // OWizTypeSelectControl
41 OWizTypeSelectControl::OWizTypeSelectControl(weld::Container
* pPage
, OWizTypeSelect
* pParentTabPage
)
42 : OFieldDescControl(pPage
, nullptr)
43 , m_pParentTabPage(pParentTabPage
)
47 OWizTypeSelectControl::~OWizTypeSelectControl()
51 void OWizTypeSelectControl::ActivateAggregate( EControlType eType
)
58 case tpAutoIncrementValue
:
61 OFieldDescControl::ActivateAggregate( eType
);
65 void OWizTypeSelectControl::DeactivateAggregate( EControlType eType
)
72 case tpAutoIncrementValue
:
75 OFieldDescControl::DeactivateAggregate( eType
);
79 void OWizTypeSelectControl::CellModified(sal_Int32 nRow
, sal_uInt16 nColId
)
81 OSL_ENSURE(nRow
== -1,"nRow must be -1!");
83 weld::TreeView
* pListBox
= m_pParentTabPage
->m_xColumnNames
->GetWidget();
85 OFieldDescription
* pCurFieldDescr
= getCurrentFieldDescData();
87 const sal_Int32 nPos
= pListBox
->find_text(pCurFieldDescr
->GetName());
88 pCurFieldDescr
= weld::fromId
<OFieldDescription
*>(pListBox
->get_id(nPos
));
89 OSL_ENSURE( pCurFieldDescr
, "OWizTypeSelectControl::CellModified: Columnname/type not found in the listbox!" );
90 if ( !pCurFieldDescr
)
92 setCurrentFieldDescData( pCurFieldDescr
);
94 OUString sName
= pCurFieldDescr
->GetName();
96 const OPropColumnEditCtrl
* pColumnName
= getColumnCtrl();
98 sNewName
= pColumnName
->get_text();
102 case FIELD_PROPERTY_COLUMNNAME
:
104 OCopyTableWizard
* pWiz
= m_pParentTabPage
->m_pParent
;
105 // first we have to check if this name already exists
106 bool bDoubleName
= false;
108 if ( getMetaData().is() && !getMetaData()->supportsMixedCaseQuotedIdentifiers() )
111 const sal_Int32 nCount
= pListBox
->n_children();
112 for (sal_Int32 i
=0 ; !bDoubleName
&& i
< nCount
; ++i
)
114 OUString
sEntry(pListBox
->get_text(i
));
115 bDoubleName
= sNewName
.equalsIgnoreAsciiCase(sEntry
);
117 if ( !bDoubleName
&& pWiz
->shouldCreatePrimaryKey() )
118 bDoubleName
= sNewName
.equalsIgnoreAsciiCase(pWiz
->getPrimaryKeyName());
122 bDoubleName
= ((pListBox
->find_text(sNewName
) != -1)
123 || ( pWiz
->shouldCreatePrimaryKey()
124 && pWiz
->getPrimaryKeyName() == sNewName
) );
128 OUString strMessage
= DBA_RES(STR_TABLEDESIGN_DUPLICATE_NAME
);
129 strMessage
= strMessage
.replaceFirst("$column$", sNewName
);
130 pWiz
->showError(strMessage
);
131 pCurFieldDescr
->SetName(sName
);
132 DisplayData(pCurFieldDescr
);
133 m_pParentTabPage
->setDuplicateName(true);
137 OUString sOldName
= pCurFieldDescr
->GetName();
138 pCurFieldDescr
->SetName(sNewName
);
139 m_pParentTabPage
->setDuplicateName(false);
141 // now we change the name
143 ::comphelper::UStringMixEqual
aCase(bCase
);
144 for (auto & elem
: pWiz
->m_mNameMapping
)
146 if ( aCase(elem
.second
,sName
) )
148 elem
.second
= sNewName
;
153 pListBox
->remove(nPos
);
154 pListBox
->insert_text(nPos
, pCurFieldDescr
->GetName());
155 pListBox
->set_id(nPos
, weld::toId(pCurFieldDescr
));
157 pWiz
->replaceColumn(nPos
,pCurFieldDescr
,sOldName
);
161 saveCurrentFieldDescData();
164 css::lang::Locale
OWizTypeSelectControl::GetLocale() const
166 return m_pParentTabPage
->m_pParent
->GetLocale();
169 Reference
< XNumberFormatter
> OWizTypeSelectControl::GetFormatter() const
171 return m_pParentTabPage
->m_pParent
->GetFormatter();
174 TOTypeInfoSP
OWizTypeSelectControl::getTypeInfo(sal_Int32 _nPos
)
176 return m_pParentTabPage
->m_pParent
->getDestTypeInfo(_nPos
);
179 const OTypeInfoMap
* OWizTypeSelectControl::getTypeInfo() const
181 return &m_pParentTabPage
->m_pParent
->getDestTypeInfo();
184 css::uno::Reference
< css::sdbc::XDatabaseMetaData
> OWizTypeSelectControl::getMetaData()
186 return m_pParentTabPage
->m_pParent
->m_xDestConnection
->getMetaData();
189 css::uno::Reference
< css::sdbc::XConnection
> OWizTypeSelectControl::getConnection()
191 return m_pParentTabPage
->m_pParent
->m_xDestConnection
;
194 bool OWizTypeSelectControl::isAutoIncrementValueEnabled() const
196 return m_pParentTabPage
->m_bAutoIncrementEnabled
;
199 OUString
OWizTypeSelectControl::getAutoIncrementValue() const
201 return m_pParentTabPage
->m_sAutoIncrementValue
;
204 OWizTypeSelect::OWizTypeSelect(weld::Container
* pPage
, OCopyTableWizard
* pWizard
, SvStream
* pStream
)
205 : OWizardPage(pPage
, pWizard
, u
"dbaccess/ui/typeselectpage.ui"_ustr
, u
"TypeSelect"_ustr
)
206 , m_xColumnNames(new OWizTypeSelectList(m_xBuilder
->weld_tree_view(u
"columnnames"_ustr
)))
207 , m_xControlContainer(m_xBuilder
->weld_container(u
"control_container"_ustr
))
208 , m_xTypeControl(new OWizTypeSelectControl(m_xControlContainer
.get(), this))
209 , m_xAutoType(m_xBuilder
->weld_label(u
"autotype"_ustr
))
210 , m_xAutoFt(m_xBuilder
->weld_label(u
"autolabel"_ustr
))
211 , m_xAutoEt(m_xBuilder
->weld_spin_button(u
"auto"_ustr
))
212 , m_xAutoPb(m_xBuilder
->weld_button(u
"autobutton"_ustr
))
213 , m_pParserStream(pStream
)
215 , m_bAutoIncrementEnabled(false)
216 , m_bDuplicateName(false)
218 m_xColumnNames
->connect_changed(LINK(this,OWizTypeSelect
,ColumnSelectHdl
));
220 m_xTypeControl
->Init();
222 m_xAutoEt
->set_text(u
"10"_ustr
);
223 m_xAutoEt
->set_digits(0);
224 m_xAutoPb
->connect_clicked(LINK(this,OWizTypeSelect
,ButtonClickHdl
));
225 m_xColumnNames
->set_selection_mode(SelectionMode::Multiple
);
229 m_xColumnNames
->SetPKey( m_pParent
->supportsPrimaryKey() );
230 ::dbaui::fillAutoIncrementValue( m_pParent
->m_xDestConnection
, m_bAutoIncrementEnabled
, m_sAutoIncrementValue
);
232 catch(const Exception
&)
234 DBG_UNHANDLED_EXCEPTION("dbaccess");
238 OWizTypeSelect::~OWizTypeSelect()
242 OUString
OWizTypeSelect::GetTitle() const
244 return DBA_RES(STR_WIZ_TYPE_SELECT_TITLE
);
247 IMPL_LINK_NOARG(OWizTypeSelect
, ColumnSelectHdl
, weld::TreeView
&, void)
249 OFieldDescription
* pField
= weld::fromId
<OFieldDescription
*>(m_xColumnNames
->get_selected_id());
251 m_xTypeControl
->DisplayData(pField
);
253 m_xTypeControl
->Enable(m_xColumnNames
->count_selected_rows() == 1);
256 void OWizTypeSelect::Reset()
258 // restore original state
259 m_xColumnNames
->clear();
260 sal_Int32
nCount(0), nBreakPos
;
261 m_pParent
->CheckColumns(nBreakPos
);
263 const ODatabaseExport::TColumnVector
& rDestColumns
= m_pParent
->getDestVector();
264 for (auto const& column
: rDestColumns
)
266 OUString
sId(weld::toId(column
->second
));
267 m_xColumnNames
->append(sId
, column
->first
);
268 if (column
->second
->IsPrimaryKey())
269 m_xColumnNames
->set_image(nCount
, BMP_PRIMARY_KEY
);
272 m_bFirstTime
= false;
275 void OWizTypeSelect::Activate( )
277 bool bOldFirstTime
= m_bFirstTime
;
279 m_bFirstTime
= bOldFirstTime
;
281 m_xColumnNames
->select(m_nDisplayRow
);
283 ColumnSelectHdl(*m_xColumnNames
->GetWidget());
286 bool OWizTypeSelect::LeavePage()
288 bool bDuplicateName
= false;
289 OFieldDescription
* pField
= weld::fromId
<OFieldDescription
*>(m_xColumnNames
->get_selected_id());
292 m_xTypeControl
->SaveData(pField
);
293 bDuplicateName
= m_bDuplicateName
;
295 return !bDuplicateName
;
298 void OWizTypeSelect::EnableAuto(bool bEnable
)
300 m_xAutoFt
->set_visible(bEnable
);
301 m_xAutoEt
->set_visible(bEnable
);
302 m_xAutoPb
->set_visible(bEnable
);
303 m_xAutoType
->set_visible(bEnable
);
306 IMPL_LINK_NOARG(OWizTypeSelect
, ButtonClickHdl
, weld::Button
&, void)
309 m_pParent
->CheckColumns(nBreakPos
);
312 sal_uInt32 nRows
= m_xAutoEt
->get_text().toInt32();
315 sal_uInt64
const nTell
= m_pParserStream
->Tell(); // might change seek position of stream
317 createReaderAndCallParser(nRows
);
318 m_pParserStream
->Seek(nTell
);
324 OWizTypeSelectList::OWizTypeSelectList(std::unique_ptr
<weld::TreeView
> xControl
)
325 : m_xControl(std::move(xControl
))
328 m_xControl
->connect_popup_menu(LINK(this, OWizTypeSelectList
, CommandHdl
));
331 bool OWizTypeSelectList::IsPrimaryKeyAllowed() const
333 auto aRows
= m_xControl
->get_selected_rows();
334 std::sort(aRows
.begin(), aRows
.end());
336 const sal_Int32 nCount
= aRows
.size();
338 for( sal_Int32 j
= 0; m_bPKey
&& j
< nCount
; ++j
)
340 OFieldDescription
* pField
= weld::fromId
<OFieldDescription
*>(m_xControl
->get_id(aRows
[j
]));
341 if(!pField
|| pField
->getTypeInfo()->nSearchType
== ColumnSearch::NONE
)
347 void OWizTypeSelectList::setPrimaryKey(OFieldDescription
* _pFieldDescr
, sal_uInt16 _nPos
, bool _bSet
)
349 _pFieldDescr
->SetPrimaryKey(_bSet
);
352 m_xControl
->set_image(_nPos
, BMP_PRIMARY_KEY
);
354 else if( _pFieldDescr
->getTypeInfo()->bNullable
)
356 _pFieldDescr
->SetControlDefault(Any());
357 m_xControl
->set_image(_nPos
, OUString());
361 IMPL_LINK(OWizTypeSelectList
, CommandHdl
, const CommandEvent
&, rCEvt
, bool)
363 if (rCEvt
.GetCommand() != CommandEventId::ContextMenu
)
365 if (!IsPrimaryKeyAllowed())
368 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(m_xControl
.get(), u
"dbaccess/ui/keymenu.ui"_ustr
));
369 auto xContextMenu
= xBuilder
->weld_menu(u
"menu"_ustr
);
370 // Should primary key checkbox be checked?
371 const sal_Int32 nCount
= m_xControl
->n_children();
372 bool bCheckOk
= false;
373 for(sal_Int32 j
= 0 ; j
< nCount
; ++j
)
375 OFieldDescription
* pFieldDescr
= weld::fromId
<OFieldDescription
*>(m_xControl
->get_id(j
));
376 // if at least one of the fields is selected but not in the primary key,
377 // or is in the primary key but not selected, then don't check the
378 // primary key checkbox.
379 if( pFieldDescr
&& pFieldDescr
->IsPrimaryKey() != m_xControl
->is_selected(j
) )
384 if (!bCheckOk
&& m_xControl
->is_selected(j
))
389 xContextMenu
->set_active(u
"primarykey"_ustr
, true);
391 OUString
sCommand(xContextMenu
->popup_at_rect(m_xControl
.get(), tools::Rectangle(rCEvt
.GetMousePosPixel(), Size(1,1))));
392 if (sCommand
!= "primarykey")
395 for (sal_Int32 j
= 0 ; j
< nCount
; ++j
)
397 OFieldDescription
* pFieldDescr
= weld::fromId
<OFieldDescription
*>(m_xControl
->get_id(j
));
400 if(!bCheckOk
&& m_xControl
->is_selected(j
))
402 setPrimaryKey(pFieldDescr
,j
,true);
406 setPrimaryKey(pFieldDescr
,j
);
410 m_aChangeHdl
.Call(*m_xControl
);
415 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */