Line data Source code
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 "WColumnSelect.hxx"
21 : #include "dbu_misc.hrc"
22 : #include <osl/diagnose.h>
23 : #include "WCopyTable.hxx"
24 : #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
25 : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
26 : #include <com/sun/star/sdbcx/XAppend.hpp>
27 : #include "moduledbu.hxx"
28 : #include <com/sun/star/sdbc/DataType.hpp>
29 : #include <com/sun/star/sdbc/ColumnValue.hpp>
30 : #include <com/sun/star/sdb/application/CopyTableOperation.hpp>
31 : #include "dbustrings.hrc"
32 : #include <functional>
33 : #include <o3tl/compat_functional.hxx>
34 :
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::sdbc;
39 : using namespace ::com::sun::star::sdbcx;
40 : using namespace dbaui;
41 :
42 : namespace CopyTableOperation = ::com::sun::star::sdb::application::CopyTableOperation;
43 :
44 0 : OUString OWizColumnSelect::GetTitle() const { return ModuleRes(STR_WIZ_COLUMN_SELECT_TITEL); }
45 :
46 0 : OWizardPage::OWizardPage(vcl::Window* pParent, const OString& rID, const OUString& rUIXMLDescription)
47 : : TabPage(pParent, rID, rUIXMLDescription)
48 : ,m_pParent(static_cast<OCopyTableWizard*>(pParent))
49 0 : ,m_bFirstTime(true)
50 : {
51 0 : }
52 :
53 0 : OWizardPage::~OWizardPage()
54 : {
55 0 : disposeOnce();
56 0 : }
57 :
58 0 : void OWizardPage::dispose()
59 : {
60 0 : m_pParent.clear();
61 0 : TabPage::dispose();
62 0 : }
63 :
64 : // OWizColumnSelect
65 0 : OWizColumnSelect::OWizColumnSelect( vcl::Window* pParent)
66 0 : :OWizardPage( pParent, "ApplyColPage", "dbaccess/ui/applycolpage.ui")
67 : {
68 0 : get(m_pOrgColumnNames, "from");
69 0 : get(m_pColumn_RH, "colrh");
70 0 : get(m_pColumns_RH, "colsrh");
71 0 : get(m_pColumn_LH, "collh");
72 0 : get(m_pColumns_LH, "colslh");
73 0 : get(m_pNewColumnNames, "to");
74 :
75 0 : Size aSize(approximate_char_width() * 30, GetTextHeight() * 40);
76 0 : m_pOrgColumnNames->set_width_request(aSize.Width());
77 0 : m_pOrgColumnNames->set_height_request(aSize.Height());
78 0 : m_pNewColumnNames->set_width_request(aSize.Width());
79 0 : m_pNewColumnNames->set_height_request(aSize.Height());
80 :
81 0 : m_pColumn_RH->SetClickHdl(LINK(this,OWizColumnSelect,ButtonClickHdl));
82 0 : m_pColumn_LH->SetClickHdl(LINK(this,OWizColumnSelect,ButtonClickHdl));
83 0 : m_pColumns_RH->SetClickHdl(LINK(this,OWizColumnSelect,ButtonClickHdl));
84 0 : m_pColumns_LH->SetClickHdl(LINK(this,OWizColumnSelect,ButtonClickHdl));
85 :
86 0 : m_pOrgColumnNames->EnableMultiSelection(true);
87 0 : m_pNewColumnNames->EnableMultiSelection(true);
88 :
89 0 : m_pOrgColumnNames->SetDoubleClickHdl(LINK(this,OWizColumnSelect,ListDoubleClickHdl));
90 0 : m_pNewColumnNames->SetDoubleClickHdl(LINK(this,OWizColumnSelect,ListDoubleClickHdl));
91 0 : }
92 :
93 0 : OWizColumnSelect::~OWizColumnSelect()
94 : {
95 0 : disposeOnce();
96 0 : }
97 :
98 0 : void OWizColumnSelect::dispose()
99 : {
100 0 : while ( m_pNewColumnNames->GetEntryCount() )
101 : {
102 0 : void* pData = m_pNewColumnNames->GetEntryData(0);
103 0 : if ( pData )
104 0 : delete static_cast<OFieldDescription*>(pData);
105 :
106 0 : m_pNewColumnNames->RemoveEntry(0);
107 : }
108 0 : m_pNewColumnNames->Clear();
109 0 : m_pOrgColumnNames.clear();
110 0 : m_pColumn_RH.clear();
111 0 : m_pColumns_RH.clear();
112 0 : m_pColumn_LH.clear();
113 0 : m_pColumns_LH.clear();
114 0 : m_pNewColumnNames.clear();
115 0 : OWizardPage::dispose();
116 0 : }
117 :
118 0 : void OWizColumnSelect::Reset()
119 : {
120 : // restore original state
121 0 : clearListBox(*m_pOrgColumnNames);
122 0 : clearListBox(*m_pNewColumnNames);
123 0 : m_pParent->m_mNameMapping.clear();
124 :
125 : // insert the source columns in the left listbox
126 0 : const ODatabaseExport::TColumnVector& rSrcColumns = m_pParent->getSrcVector();
127 0 : ODatabaseExport::TColumnVector::const_iterator aIter = rSrcColumns.begin();
128 0 : ODatabaseExport::TColumnVector::const_iterator aEnd = rSrcColumns.end();
129 :
130 0 : for(;aIter != aEnd;++aIter)
131 : {
132 0 : sal_uInt16 nPos = m_pOrgColumnNames->InsertEntry((*aIter)->first);
133 0 : m_pOrgColumnNames->SetEntryData(nPos,(*aIter)->second);
134 : }
135 :
136 0 : if(m_pOrgColumnNames->GetEntryCount())
137 0 : m_pOrgColumnNames->SelectEntryPos(0);
138 :
139 0 : m_bFirstTime = false;
140 0 : }
141 :
142 0 : void OWizColumnSelect::ActivatePage( )
143 : {
144 : // if there are no dest columns reset the left side with the origibnal columns
145 0 : if(m_pParent->getDestColumns().empty())
146 0 : Reset();
147 :
148 0 : clearListBox(*m_pNewColumnNames);
149 :
150 0 : const ODatabaseExport::TColumnVector& rDestColumns = m_pParent->getDestVector();
151 :
152 0 : ODatabaseExport::TColumnVector::const_iterator aIter = rDestColumns.begin();
153 0 : ODatabaseExport::TColumnVector::const_iterator aEnd = rDestColumns.end();
154 0 : for(;aIter != aEnd;++aIter)
155 : {
156 0 : sal_uInt16 nPos = m_pNewColumnNames->InsertEntry((*aIter)->first);
157 0 : m_pNewColumnNames->SetEntryData(nPos,new OFieldDescription(*((*aIter)->second)));
158 0 : m_pOrgColumnNames->RemoveEntry((*aIter)->first);
159 : }
160 0 : m_pParent->GetOKButton().Enable(m_pNewColumnNames->GetEntryCount() != 0);
161 0 : m_pParent->EnableButton(OCopyTableWizard::WIZARD_NEXT,m_pNewColumnNames->GetEntryCount() && m_pParent->getOperation() != CopyTableOperation::AppendData);
162 0 : m_pColumns_RH->GrabFocus();
163 0 : }
164 :
165 0 : bool OWizColumnSelect::LeavePage()
166 : {
167 :
168 0 : m_pParent->clearDestColumns();
169 :
170 0 : for(sal_Int32 i=0 ; i< m_pNewColumnNames->GetEntryCount();++i)
171 : {
172 0 : OFieldDescription* pField = static_cast<OFieldDescription*>(m_pNewColumnNames->GetEntryData(i));
173 : OSL_ENSURE(pField,"The field information can not be null!");
174 0 : m_pParent->insertColumn(i,pField);
175 : }
176 :
177 0 : clearListBox(*m_pNewColumnNames);
178 :
179 0 : if ( m_pParent->GetPressedButton() == OCopyTableWizard::WIZARD_NEXT
180 0 : || m_pParent->GetPressedButton() == OCopyTableWizard::WIZARD_FINISH
181 : )
182 0 : return m_pParent->getDestColumns().size() != 0;
183 : else
184 0 : return true;
185 : }
186 :
187 0 : IMPL_LINK( OWizColumnSelect, ButtonClickHdl, Button *, pButton )
188 : {
189 0 : ListBox *pLeft = NULL;
190 0 : ListBox *pRight = NULL;
191 0 : bool bAll = false;
192 :
193 0 : if (pButton == m_pColumn_RH)
194 : {
195 0 : pLeft = m_pOrgColumnNames;
196 0 : pRight = m_pNewColumnNames;
197 : }
198 0 : else if(pButton == m_pColumn_LH)
199 : {
200 0 : pLeft = m_pNewColumnNames;
201 0 : pRight = m_pOrgColumnNames;
202 : }
203 0 : else if(pButton == m_pColumns_RH)
204 : {
205 0 : pLeft = m_pOrgColumnNames;
206 0 : pRight = m_pNewColumnNames;
207 0 : bAll = true;
208 : }
209 0 : else if(pButton == m_pColumns_LH)
210 : {
211 0 : pLeft = m_pNewColumnNames;
212 0 : pRight = m_pOrgColumnNames;
213 0 : bAll = true;
214 : }
215 :
216 0 : if (!pLeft || !pRight)
217 0 : return 0;
218 :
219 0 : Reference< XDatabaseMetaData > xMetaData( m_pParent->m_xDestConnection->getMetaData() );
220 0 : OUString sExtraChars = xMetaData->getExtraNameCharacters();
221 0 : sal_Int32 nMaxNameLen = m_pParent->getMaxColumnNameLength();
222 :
223 0 : ::comphelper::UStringMixEqual aCase(xMetaData->supportsMixedCaseQuotedIdentifiers());
224 0 : ::std::vector< OUString> aRightColumns;
225 0 : fillColumns(pRight,aRightColumns);
226 :
227 0 : if(!bAll)
228 : {
229 0 : for(sal_Int32 i=0; i < pLeft->GetSelectEntryCount(); ++i)
230 0 : moveColumn(pRight,pLeft,aRightColumns,pLeft->GetSelectEntry(i),sExtraChars,nMaxNameLen,aCase);
231 :
232 0 : for(sal_uInt16 j=pLeft->GetSelectEntryCount(); j ; --j)
233 0 : pLeft->RemoveEntry(pLeft->GetSelectEntry(j-1));
234 : }
235 : else
236 : {
237 0 : sal_uInt16 nEntries = pLeft->GetEntryCount();
238 0 : for(sal_uInt16 i=0; i < nEntries; ++i)
239 0 : moveColumn(pRight,pLeft,aRightColumns,pLeft->GetEntry(i),sExtraChars,nMaxNameLen,aCase);
240 0 : for(sal_uInt16 j=pLeft->GetEntryCount(); j ; --j)
241 0 : pLeft->RemoveEntry(j-1);
242 : }
243 :
244 0 : enableButtons();
245 :
246 0 : if(m_pOrgColumnNames->GetEntryCount())
247 0 : m_pOrgColumnNames->SelectEntryPos(0);
248 :
249 0 : return 0;
250 : }
251 :
252 0 : IMPL_LINK( OWizColumnSelect, ListDoubleClickHdl, ListBox *, pListBox )
253 : {
254 : ListBox *pLeft,*pRight;
255 0 : if(pListBox == m_pOrgColumnNames)
256 : {
257 0 : pLeft = m_pOrgColumnNames;
258 0 : pRight = m_pNewColumnNames;
259 : }
260 : else
261 : {
262 0 : pRight = m_pOrgColumnNames;
263 0 : pLeft = m_pNewColumnNames;
264 : }
265 :
266 : // If database is able to process PrimaryKeys, set PrimaryKey
267 0 : Reference< XDatabaseMetaData > xMetaData( m_pParent->m_xDestConnection->getMetaData() );
268 0 : OUString sExtraChars = xMetaData->getExtraNameCharacters();
269 0 : sal_Int32 nMaxNameLen = m_pParent->getMaxColumnNameLength();
270 :
271 0 : ::comphelper::UStringMixEqual aCase(xMetaData->supportsMixedCaseQuotedIdentifiers());
272 0 : ::std::vector< OUString> aRightColumns;
273 0 : fillColumns(pRight,aRightColumns);
274 :
275 0 : for(sal_Int32 i=0; i < pLeft->GetSelectEntryCount(); ++i)
276 0 : moveColumn(pRight,pLeft,aRightColumns,pLeft->GetSelectEntry(i),sExtraChars,nMaxNameLen,aCase);
277 0 : for(sal_uInt16 j=pLeft->GetSelectEntryCount(); j ; --j)
278 0 : pLeft->RemoveEntry(pLeft->GetSelectEntry(j-1));
279 :
280 0 : enableButtons();
281 0 : return 0;
282 : }
283 :
284 0 : void OWizColumnSelect::clearListBox(ListBox& _rListBox)
285 : {
286 0 : while(_rListBox.GetEntryCount())
287 0 : _rListBox.RemoveEntry(0);
288 0 : _rListBox.Clear();
289 0 : }
290 :
291 0 : void OWizColumnSelect::fillColumns(ListBox* pRight,::std::vector< OUString> &_rRightColumns)
292 : {
293 0 : sal_uInt16 nCount = pRight->GetEntryCount();
294 0 : _rRightColumns.reserve(nCount);
295 0 : for(sal_uInt16 i=0; i < nCount;++i)
296 0 : _rRightColumns.push_back(pRight->GetEntry(i));
297 0 : }
298 :
299 0 : void OWizColumnSelect::createNewColumn( ListBox* _pListbox,
300 : OFieldDescription* _pSrcField,
301 : ::std::vector< OUString>& _rRightColumns,
302 : const OUString& _sColumnName,
303 : const OUString& _sExtraChars,
304 : sal_Int32 _nMaxNameLen,
305 : const ::comphelper::UStringMixEqual& _aCase)
306 : {
307 : OUString sConvertedName = m_pParent->convertColumnName(TMultiListBoxEntryFindFunctor(&_rRightColumns,_aCase),
308 : _sColumnName,
309 : _sExtraChars,
310 0 : _nMaxNameLen);
311 0 : OFieldDescription* pNewField = new OFieldDescription(*_pSrcField);
312 0 : pNewField->SetName(sConvertedName);
313 0 : bool bNotConvert = true;
314 0 : pNewField->SetType(m_pParent->convertType(_pSrcField->getSpecialTypeInfo(),bNotConvert));
315 0 : if ( !m_pParent->supportsPrimaryKey() )
316 0 : pNewField->SetPrimaryKey(false);
317 :
318 0 : _pListbox->SetEntryData(_pListbox->InsertEntry(sConvertedName),pNewField);
319 0 : _rRightColumns.push_back(sConvertedName);
320 :
321 0 : if ( !bNotConvert )
322 0 : m_pParent->showColumnTypeNotSupported(sConvertedName);
323 0 : }
324 :
325 0 : void OWizColumnSelect::moveColumn( ListBox* _pRight,
326 : ListBox* _pLeft,
327 : ::std::vector< OUString>& _rRightColumns,
328 : const OUString& _sColumnName,
329 : const OUString& _sExtraChars,
330 : sal_Int32 _nMaxNameLen,
331 : const ::comphelper::UStringMixEqual& _aCase)
332 : {
333 0 : if(_pRight == m_pNewColumnNames)
334 : {
335 : // we copy the column into the new format for the dest
336 0 : OFieldDescription* pSrcField = static_cast<OFieldDescription*>(_pLeft->GetEntryData(_pLeft->GetEntryPos(OUString(_sColumnName))));
337 0 : createNewColumn(_pRight,pSrcField,_rRightColumns,_sColumnName,_sExtraChars,_nMaxNameLen,_aCase);
338 : }
339 : else
340 : {
341 : // find the new column in the dest name mapping to obtain the old column
342 0 : OCopyTableWizard::TNameMapping::iterator aIter = ::std::find_if(m_pParent->m_mNameMapping.begin(),m_pParent->m_mNameMapping.end(),
343 : ::o3tl::compose1(
344 : ::std::bind2nd(_aCase, _sColumnName),
345 : ::o3tl::select2nd<OCopyTableWizard::TNameMapping::value_type>())
346 0 : );
347 :
348 : OSL_ENSURE(aIter != m_pParent->m_mNameMapping.end(),"Column must be defined");
349 0 : if ( aIter == m_pParent->m_mNameMapping.end() )
350 0 : return; // do nothing
351 0 : const ODatabaseExport::TColumns& rSrcColumns = m_pParent->getSourceColumns();
352 0 : ODatabaseExport::TColumns::const_iterator aSrcIter = rSrcColumns.find((*aIter).first);
353 0 : if ( aSrcIter != rSrcColumns.end() )
354 : {
355 : // we need also the old position of this column to insert it back on that position again
356 0 : const ODatabaseExport::TColumnVector& rSrcVector = m_pParent->getSrcVector();
357 0 : ODatabaseExport::TColumnVector::const_iterator aPos = ::std::find(rSrcVector.begin(), rSrcVector.end(), aSrcIter);
358 : OSL_ENSURE( aPos != rSrcVector.end(),"Invalid position for the iterator here!");
359 0 : ODatabaseExport::TColumnVector::size_type nPos = (aPos - rSrcVector.begin()) - adjustColumnPosition(_pLeft, _sColumnName, (aPos - rSrcVector.begin()), _aCase);
360 :
361 0 : _pRight->SetEntryData( _pRight->InsertEntry( (*aIter).first, sal::static_int_cast< sal_uInt16 >(nPos)),aSrcIter->second );
362 0 : _rRightColumns.push_back((*aIter).first);
363 0 : m_pParent->removeColumnNameFromNameMap(_sColumnName);
364 : }
365 : }
366 : }
367 :
368 : // Simply returning fields back to their original position is
369 : // not enough. We need to take into acccount what fields have
370 : // been removed earlier and adjust accordingly. Based on the
371 : // algorithm employed in moveColumn().
372 0 : sal_uInt16 OWizColumnSelect::adjustColumnPosition( ListBox* _pLeft,
373 : const OUString& _sColumnName,
374 : ODatabaseExport::TColumnVector::size_type nCurrentPos,
375 : const ::comphelper::UStringMixEqual& _aCase)
376 : {
377 0 : sal_uInt16 nAdjustedPos = 0;
378 :
379 : // if returning all entries to their original position,
380 : // then there is no need to adjust the positions.
381 0 : if (m_pColumns_LH->HasFocus())
382 0 : return nAdjustedPos;
383 :
384 0 : sal_uInt16 nCount = _pLeft->GetEntryCount();
385 0 : OUString sColumnString;
386 0 : for(sal_uInt16 i=0; i < nCount; ++i)
387 : {
388 0 : sColumnString = _pLeft->GetEntry(i);
389 0 : if(_sColumnName != sColumnString)
390 : {
391 : // find the new column in the dest name mapping to obtain the old column
392 0 : OCopyTableWizard::TNameMapping::iterator aIter = ::std::find_if(m_pParent->m_mNameMapping.begin(),m_pParent->m_mNameMapping.end(),
393 : ::o3tl::compose1(
394 : ::std::bind2nd(_aCase, sColumnString),
395 : ::o3tl::select2nd<OCopyTableWizard::TNameMapping::value_type>())
396 0 : );
397 :
398 : OSL_ENSURE(aIter != m_pParent->m_mNameMapping.end(),"Column must be defined");
399 0 : const ODatabaseExport::TColumns& rSrcColumns = m_pParent->getSourceColumns();
400 0 : ODatabaseExport::TColumns::const_iterator aSrcIter = rSrcColumns.find((*aIter).first);
401 0 : if ( aSrcIter != rSrcColumns.end() )
402 : {
403 : // we need also the old position of this column to insert it back on that position again
404 0 : const ODatabaseExport::TColumnVector& rSrcVector = m_pParent->getSrcVector();
405 0 : ODatabaseExport::TColumnVector::const_iterator aPos = ::std::find(rSrcVector.begin(), rSrcVector.end(), aSrcIter);
406 0 : ODatabaseExport::TColumnVector::size_type nPos = aPos - rSrcVector.begin();
407 0 : if( nPos < nCurrentPos)
408 : {
409 0 : nAdjustedPos++;
410 : }
411 : }
412 : }
413 : }
414 :
415 0 : return nAdjustedPos;
416 : }
417 :
418 0 : void OWizColumnSelect::enableButtons()
419 : {
420 0 : bool bEntries = m_pNewColumnNames->GetEntryCount() != 0;
421 0 : if(!bEntries)
422 0 : m_pParent->m_mNameMapping.clear();
423 :
424 0 : m_pParent->GetOKButton().Enable(bEntries);
425 0 : m_pParent->EnableButton(OCopyTableWizard::WIZARD_NEXT,bEntries && m_pParent->getOperation() != CopyTableOperation::AppendData);
426 36 : }
427 :
428 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|