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 <tools/diagnose_ex.h>
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
= reinterpret_cast< OFieldDescription
* >( pListBox
->get_id(nPos
).toInt64() );
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
, OUString::number(reinterpret_cast<sal_Int64
>(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_xColumns(m_xBuilder
->weld_label("columns"))
209 , m_xControlContainer(m_xBuilder
->weld_container("control_container"))
210 , m_xTypeControl(new OWizTypeSelectControl(m_xControlContainer
.get(), this))
211 , m_xAutoType(m_xBuilder
->weld_label("autotype"))
212 , m_xAutoFt(m_xBuilder
->weld_label("autolabel"))
213 , m_xAutoEt(m_xBuilder
->weld_spin_button("auto"))
214 , m_xAutoPb(m_xBuilder
->weld_button("autobutton"))
215 , m_pParserStream(pStream
)
217 , m_bAutoIncrementEnabled(false)
218 , m_bDuplicateName(false)
220 m_xColumnNames
->connect_changed(LINK(this,OWizTypeSelect
,ColumnSelectHdl
));
222 m_xTypeControl
->Init();
224 m_xAutoEt
->set_text("10");
225 m_xAutoEt
->set_digits(0);
226 m_xAutoPb
->connect_clicked(LINK(this,OWizTypeSelect
,ButtonClickHdl
));
227 m_xColumnNames
->set_selection_mode(SelectionMode::Multiple
);
231 m_xColumnNames
->SetPKey( m_pParent
->supportsPrimaryKey() );
232 ::dbaui::fillAutoIncrementValue( m_pParent
->m_xDestConnection
, m_bAutoIncrementEnabled
, m_sAutoIncrementValue
);
234 catch(const Exception
&)
236 DBG_UNHANDLED_EXCEPTION("dbaccess");
240 OWizTypeSelect::~OWizTypeSelect()
244 OUString
OWizTypeSelect::GetTitle() const
246 return DBA_RES(STR_WIZ_TYPE_SELECT_TITLE
);
249 IMPL_LINK_NOARG(OWizTypeSelect
, ColumnSelectHdl
, weld::TreeView
&, void)
251 OFieldDescription
* pField
= reinterpret_cast<OFieldDescription
*>(m_xColumnNames
->get_selected_id().toInt64());
253 m_xTypeControl
->DisplayData(pField
);
255 m_xTypeControl
->Enable(m_xColumnNames
->count_selected_rows() == 1);
258 void OWizTypeSelect::Reset()
260 // restore original state
261 m_xColumnNames
->clear();
262 sal_Int32
nCount(0), nBreakPos
;
263 m_pParent
->CheckColumns(nBreakPos
);
265 const ODatabaseExport::TColumnVector
& rDestColumns
= m_pParent
->getDestVector();
266 for (auto const& column
: rDestColumns
)
268 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(column
->second
)));
269 m_xColumnNames
->append(sId
, column
->first
);
270 if (column
->second
->IsPrimaryKey())
271 m_xColumnNames
->set_image(nCount
, BMP_PRIMARY_KEY
);
274 m_bFirstTime
= false;
277 void OWizTypeSelect::Activate( )
279 bool bOldFirstTime
= m_bFirstTime
;
281 m_bFirstTime
= bOldFirstTime
;
283 m_xColumnNames
->select(m_nDisplayRow
);
285 ColumnSelectHdl(*m_xColumnNames
->GetWidget());
288 bool OWizTypeSelect::LeavePage()
290 bool bDuplicateName
= false;
291 OFieldDescription
* pField
= reinterpret_cast<OFieldDescription
*>(m_xColumnNames
->get_selected_id().toInt64());
294 m_xTypeControl
->SaveData(pField
);
295 bDuplicateName
= m_bDuplicateName
;
297 return !bDuplicateName
;
300 void OWizTypeSelect::EnableAuto(bool bEnable
)
302 m_xAutoFt
->set_visible(bEnable
);
303 m_xAutoEt
->set_visible(bEnable
);
304 m_xAutoPb
->set_visible(bEnable
);
305 m_xAutoType
->set_visible(bEnable
);
308 IMPL_LINK_NOARG(OWizTypeSelect
, ButtonClickHdl
, weld::Button
&, void)
311 m_pParent
->CheckColumns(nBreakPos
);
314 sal_uInt32 nRows
= m_xAutoEt
->get_text().toInt32();
317 sal_uInt64
const nTell
= m_pParserStream
->Tell(); // might change seek position of stream
319 createReaderAndCallParser(nRows
);
320 m_pParserStream
->Seek(nTell
);
326 OWizTypeSelectList::OWizTypeSelectList(std::unique_ptr
<weld::TreeView
> xControl
)
327 : m_xControl(std::move(xControl
))
330 m_xControl
->connect_popup_menu(LINK(this, OWizTypeSelectList
, CommandHdl
));
333 bool OWizTypeSelectList::IsPrimaryKeyAllowed() const
335 auto aRows
= m_xControl
->get_selected_rows();
336 std::sort(aRows
.begin(), aRows
.end());
338 const sal_Int32 nCount
= aRows
.size();
340 for( sal_Int32 j
= 0; m_bPKey
&& j
< nCount
; ++j
)
342 OFieldDescription
* pField
= reinterpret_cast<OFieldDescription
*>(m_xControl
->get_id(aRows
[j
]).toInt64());
343 if(!pField
|| pField
->getTypeInfo()->nSearchType
== ColumnSearch::NONE
)
349 void OWizTypeSelectList::setPrimaryKey(OFieldDescription
* _pFieldDescr
, sal_uInt16 _nPos
, bool _bSet
)
351 _pFieldDescr
->SetPrimaryKey(_bSet
);
354 m_xControl
->set_image(_nPos
, BMP_PRIMARY_KEY
);
356 else if( _pFieldDescr
->getTypeInfo()->bNullable
)
358 _pFieldDescr
->SetControlDefault(Any());
359 m_xControl
->set_image(_nPos
, OUString());
363 IMPL_LINK(OWizTypeSelectList
, CommandHdl
, const CommandEvent
&, rCEvt
, bool)
365 if (rCEvt
.GetCommand() != CommandEventId::ContextMenu
)
367 if (!IsPrimaryKeyAllowed())
370 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(m_xControl
.get(), "dbaccess/ui/keymenu.ui"));
371 auto xContextMenu
= xBuilder
->weld_menu("menu");
372 // Should primary key checkbox be checked?
373 const sal_Int32 nCount
= m_xControl
->n_children();
374 bool bCheckOk
= false;
375 for(sal_Int32 j
= 0 ; j
< nCount
; ++j
)
377 OFieldDescription
* pFieldDescr
= reinterpret_cast<OFieldDescription
*>(m_xControl
->get_id(j
).toInt64());
378 // if at least one of the fields is selected but not in the primary key,
379 // or is in the primary key but not selected, then don't check the
380 // primary key checkbox.
381 if( pFieldDescr
&& pFieldDescr
->IsPrimaryKey() != m_xControl
->is_selected(j
) )
386 if (!bCheckOk
&& m_xControl
->is_selected(j
))
391 xContextMenu
->set_active("primarykey", true);
393 OString
sCommand(xContextMenu
->popup_at_rect(m_xControl
.get(), tools::Rectangle(rCEvt
.GetMousePosPixel(), Size(1,1))));
394 if (sCommand
== "primarykey")
396 for (sal_Int32 j
= 0 ; j
< nCount
; ++j
)
398 OFieldDescription
* pFieldDescr
= reinterpret_cast<OFieldDescription
*>(m_xControl
->get_id(j
).toInt64());
401 if(!bCheckOk
&& m_xControl
->is_selected(j
))
403 setPrimaryKey(pFieldDescr
,j
,true);
407 setPrimaryKey(pFieldDescr
,j
);
411 m_aChangeHdl
.Call(*m_xControl
);
417 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */