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::beans
;
37 using namespace ::com::sun::star::container
;
38 using namespace ::com::sun::star::util
;
39 using namespace ::com::sun::star::sdbc
;
41 // OWizTypeSelectControl
42 OWizTypeSelectControl::OWizTypeSelectControl(weld::Container
* pPage
, OWizTypeSelect
* pParentTabPage
)
43 : OFieldDescControl(pPage
, nullptr)
44 , m_pParentTabPage(pParentTabPage
)
48 OWizTypeSelectControl::~OWizTypeSelectControl()
52 void OWizTypeSelectControl::ActivateAggregate( EControlType eType
)
59 case tpAutoIncrementValue
:
62 OFieldDescControl::ActivateAggregate( eType
);
66 void OWizTypeSelectControl::DeactivateAggregate( EControlType eType
)
73 case tpAutoIncrementValue
:
76 OFieldDescControl::DeactivateAggregate( eType
);
80 void OWizTypeSelectControl::CellModified(sal_Int32 nRow
, sal_uInt16 nColId
)
82 OSL_ENSURE(nRow
== -1,"nRow must be -1!");
84 weld::TreeView
* pListBox
= m_pParentTabPage
->m_xColumnNames
->GetWidget();
86 OFieldDescription
* pCurFieldDescr
= getCurrentFieldDescData();
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
)
93 setCurrentFieldDescData( pCurFieldDescr
);
95 OUString sName
= pCurFieldDescr
->GetName();
97 const OPropColumnEditCtrl
* pColumnName
= getColumnCtrl();
99 sNewName
= pColumnName
->get_text();
103 case FIELD_PROPERTY_COLUMNNAME
:
105 OCopyTableWizard
* pWiz
= m_pParentTabPage
->m_pParent
;
106 // first we have to check if this name already exists
107 bool bDoubleName
= false;
109 if ( getMetaData().is() && !getMetaData()->supportsMixedCaseQuotedIdentifiers() )
112 const sal_Int32 nCount
= pListBox
->n_children();
113 for (sal_Int32 i
=0 ; !bDoubleName
&& i
< nCount
; ++i
)
115 OUString
sEntry(pListBox
->get_text(i
));
116 bDoubleName
= sNewName
.equalsIgnoreAsciiCase(sEntry
);
118 if ( !bDoubleName
&& pWiz
->shouldCreatePrimaryKey() )
119 bDoubleName
= sNewName
.equalsIgnoreAsciiCase(pWiz
->getPrimaryKeyName());
123 bDoubleName
= ((pListBox
->find_text(sNewName
) != -1)
124 || ( pWiz
->shouldCreatePrimaryKey()
125 && pWiz
->getPrimaryKeyName() == sNewName
) );
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
);
134 m_pParentTabPage
->setDuplicateName(true);
138 OUString sOldName
= pCurFieldDescr
->GetName();
139 pCurFieldDescr
->SetName(sNewName
);
140 m_pParentTabPage
->setDuplicateName(false);
142 // now we change the name
144 ::comphelper::UStringMixEqual
aCase(bCase
);
145 for (auto & elem
: pWiz
->m_mNameMapping
)
147 if ( aCase(elem
.second
,sName
) )
149 elem
.second
= sNewName
;
154 pListBox
->remove(nPos
);
155 pListBox
->insert_text(nPos
, pCurFieldDescr
->GetName());
156 pListBox
->set_id(nPos
, weld::toId(pCurFieldDescr
));
158 pWiz
->replaceColumn(nPos
,pCurFieldDescr
,sOldName
);
162 saveCurrentFieldDescData();
165 css::lang::Locale
OWizTypeSelectControl::GetLocale() const
167 return m_pParentTabPage
->m_pParent
->GetLocale();
170 Reference
< XNumberFormatter
> OWizTypeSelectControl::GetFormatter() const
172 return m_pParentTabPage
->m_pParent
->GetFormatter();
175 TOTypeInfoSP
OWizTypeSelectControl::getTypeInfo(sal_Int32 _nPos
)
177 return m_pParentTabPage
->m_pParent
->getDestTypeInfo(_nPos
);
180 const OTypeInfoMap
* OWizTypeSelectControl::getTypeInfo() const
182 return &m_pParentTabPage
->m_pParent
->getDestTypeInfo();
185 css::uno::Reference
< css::sdbc::XDatabaseMetaData
> OWizTypeSelectControl::getMetaData()
187 return m_pParentTabPage
->m_pParent
->m_xDestConnection
->getMetaData();
190 css::uno::Reference
< css::sdbc::XConnection
> OWizTypeSelectControl::getConnection()
192 return m_pParentTabPage
->m_pParent
->m_xDestConnection
;
195 bool OWizTypeSelectControl::isAutoIncrementValueEnabled() const
197 return m_pParentTabPage
->m_bAutoIncrementEnabled
;
200 OUString
OWizTypeSelectControl::getAutoIncrementValue() const
202 return m_pParentTabPage
->m_sAutoIncrementValue
;
205 OWizTypeSelect::OWizTypeSelect(weld::Container
* pPage
, OCopyTableWizard
* pWizard
, SvStream
* pStream
)
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
)
216 , m_bAutoIncrementEnabled(false)
217 , m_bDuplicateName(false)
219 m_xColumnNames
->connect_changed(LINK(this,OWizTypeSelect
,ColumnSelectHdl
));
221 m_xTypeControl
->Init();
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
);
230 m_xColumnNames
->SetPKey( m_pParent
->supportsPrimaryKey() );
231 ::dbaui::fillAutoIncrementValue( m_pParent
->m_xDestConnection
, m_bAutoIncrementEnabled
, m_sAutoIncrementValue
);
233 catch(const Exception
&)
235 DBG_UNHANDLED_EXCEPTION("dbaccess");
239 OWizTypeSelect::~OWizTypeSelect()
243 OUString
OWizTypeSelect::GetTitle() const
245 return DBA_RES(STR_WIZ_TYPE_SELECT_TITLE
);
248 IMPL_LINK_NOARG(OWizTypeSelect
, ColumnSelectHdl
, weld::TreeView
&, void)
250 OFieldDescription
* pField
= weld::fromId
<OFieldDescription
*>(m_xColumnNames
->get_selected_id());
252 m_xTypeControl
->DisplayData(pField
);
254 m_xTypeControl
->Enable(m_xColumnNames
->count_selected_rows() == 1);
257 void OWizTypeSelect::Reset()
259 // restore original state
260 m_xColumnNames
->clear();
261 sal_Int32
nCount(0), nBreakPos
;
262 m_pParent
->CheckColumns(nBreakPos
);
264 const ODatabaseExport::TColumnVector
& rDestColumns
= m_pParent
->getDestVector();
265 for (auto const& column
: rDestColumns
)
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
);
273 m_bFirstTime
= false;
276 void OWizTypeSelect::Activate( )
278 bool bOldFirstTime
= m_bFirstTime
;
280 m_bFirstTime
= bOldFirstTime
;
282 m_xColumnNames
->select(m_nDisplayRow
);
284 ColumnSelectHdl(*m_xColumnNames
->GetWidget());
287 bool OWizTypeSelect::LeavePage()
289 bool bDuplicateName
= false;
290 OFieldDescription
* pField
= weld::fromId
<OFieldDescription
*>(m_xColumnNames
->get_selected_id());
293 m_xTypeControl
->SaveData(pField
);
294 bDuplicateName
= m_bDuplicateName
;
296 return !bDuplicateName
;
299 void OWizTypeSelect::EnableAuto(bool bEnable
)
301 m_xAutoFt
->set_visible(bEnable
);
302 m_xAutoEt
->set_visible(bEnable
);
303 m_xAutoPb
->set_visible(bEnable
);
304 m_xAutoType
->set_visible(bEnable
);
307 IMPL_LINK_NOARG(OWizTypeSelect
, ButtonClickHdl
, weld::Button
&, void)
310 m_pParent
->CheckColumns(nBreakPos
);
313 sal_uInt32 nRows
= m_xAutoEt
->get_text().toInt32();
316 sal_uInt64
const nTell
= m_pParserStream
->Tell(); // might change seek position of stream
318 createReaderAndCallParser(nRows
);
319 m_pParserStream
->Seek(nTell
);
325 OWizTypeSelectList::OWizTypeSelectList(std::unique_ptr
<weld::TreeView
> xControl
)
326 : m_xControl(std::move(xControl
))
329 m_xControl
->connect_popup_menu(LINK(this, OWizTypeSelectList
, CommandHdl
));
332 bool OWizTypeSelectList::IsPrimaryKeyAllowed() const
334 auto aRows
= m_xControl
->get_selected_rows();
335 std::sort(aRows
.begin(), aRows
.end());
337 const sal_Int32 nCount
= aRows
.size();
339 for( sal_Int32 j
= 0; m_bPKey
&& j
< nCount
; ++j
)
341 OFieldDescription
* pField
= weld::fromId
<OFieldDescription
*>(m_xControl
->get_id(aRows
[j
]));
342 if(!pField
|| pField
->getTypeInfo()->nSearchType
== ColumnSearch::NONE
)
348 void OWizTypeSelectList::setPrimaryKey(OFieldDescription
* _pFieldDescr
, sal_uInt16 _nPos
, bool _bSet
)
350 _pFieldDescr
->SetPrimaryKey(_bSet
);
353 m_xControl
->set_image(_nPos
, BMP_PRIMARY_KEY
);
355 else if( _pFieldDescr
->getTypeInfo()->bNullable
)
357 _pFieldDescr
->SetControlDefault(Any());
358 m_xControl
->set_image(_nPos
, OUString());
362 IMPL_LINK(OWizTypeSelectList
, CommandHdl
, const CommandEvent
&, rCEvt
, bool)
364 if (rCEvt
.GetCommand() != CommandEventId::ContextMenu
)
366 if (!IsPrimaryKeyAllowed())
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
)
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
) )
385 if (!bCheckOk
&& m_xControl
->is_selected(j
))
390 xContextMenu
->set_active("primarykey", true);
392 OUString
sCommand(xContextMenu
->popup_at_rect(m_xControl
.get(), tools::Rectangle(rCEvt
.GetMousePosPixel(), Size(1,1))));
393 if (sCommand
!= "primarykey")
396 for (sal_Int32 j
= 0 ; j
< nCount
; ++j
)
398 OFieldDescription
* pFieldDescr
= weld::fromId
<OFieldDescription
*>(m_xControl
->get_id(j
));
401 if(!bCheckOk
&& m_xControl
->is_selected(j
))
403 setPrimaryKey(pFieldDescr
,j
,true);
407 setPrimaryKey(pFieldDescr
,j
);
411 m_aChangeHdl
.Call(*m_xControl
);
416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */