bump product version to 5.0.4.1
[LibreOffice.git] / extensions / source / dbpilots / gridwizard.cxx
blob58515c13f73b7d4eefd1a4289152a637192aa218
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "sal/config.h"
22 #include <vector>
24 #include "gridwizard.hxx"
25 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
26 #include <com/sun/star/sdbc/DataType.hpp>
27 #include <com/sun/star/form/XGridColumnFactory.hpp>
28 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
29 #include <com/sun/star/container/XNameContainer.hpp>
30 #include <sal/log.hxx>
31 #include <tools/debug.hxx>
32 #include "dbptools.hxx"
33 #include "dbpilots.hrc"
35 #define GW_STATE_DATASOURCE_SELECTION 0
36 #define GW_STATE_FIELDSELECTION 1
39 namespace dbp
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::lang;
45 using namespace ::com::sun::star::beans;
46 using namespace ::com::sun::star::sdbc;
47 using namespace ::com::sun::star::container;
48 using namespace ::com::sun::star::form;
49 using namespace ::com::sun::star::awt;
50 using namespace ::svt;
52 OGridWizard::OGridWizard( vcl::Window* _pParent,
53 const Reference< XPropertySet >& _rxObjectModel, const Reference< XComponentContext >& _rxContext )
54 :OControlWizard(_pParent, _rxObjectModel, _rxContext)
55 ,m_bHadDataSelection(true)
57 initControlSettings(&m_aSettings);
59 m_pPrevPage->SetHelpId(HID_GRIDWIZARD_PREVIOUS);
60 m_pNextPage->SetHelpId(HID_GRIDWIZARD_NEXT);
61 m_pCancel->SetHelpId(HID_GRIDWIZARD_CANCEL);
62 m_pFinish->SetHelpId(HID_GRIDWIZARD_FINISH);
63 setTitleBase(ModuleRes(RID_STR_GRIDWIZARD_TITLE).toString());
65 // if we do not need the data source selection page ...
66 if (!needDatasourceSelection())
67 { // ... skip it!
68 skip(1);
69 m_bHadDataSelection = false;
74 bool OGridWizard::approveControl(sal_Int16 _nClassId)
76 if (FormComponentType::GRIDCONTROL != _nClassId)
77 return false;
79 Reference< XGridColumnFactory > xColumnFactory(getContext().xObjectModel, UNO_QUERY);
80 if (!xColumnFactory.is())
81 return false;
83 return true;
87 void OGridWizard::implApplySettings()
89 const OControlWizardContext& rContext = getContext();
91 // the factory for the columns
92 Reference< XGridColumnFactory > xColumnFactory(rContext.xObjectModel, UNO_QUERY);
93 DBG_ASSERT(xColumnFactory.is(), "OGridWizard::implApplySettings: should never have made it 'til here!");
94 // (if we're here, what the hell happened in approveControl??)
96 // the container for the columns
97 Reference< XNameContainer > xColumnContainer(rContext.xObjectModel, UNO_QUERY);
98 DBG_ASSERT(xColumnContainer.is(), "OGridWizard::implApplySettings: no container!");
100 if (!xColumnFactory.is() || !xColumnContainer.is())
101 return;
103 static const char s_sDataFieldProperty [] = "DataField";
104 static const char s_sLabelProperty [] = "Label";
105 static const char s_sWidthProperty [] = "Width";
106 static const char s_sMouseWheelBehavior[] = "MouseWheelBehavior";
107 static const char s_sEmptyString[] = "";
109 // collect "descriptors" for the to-be-created (grid)columns
110 std::vector< OUString > aColumnServiceNames; // service names to be used with the XGridColumnFactory
111 std::vector< OUString > aColumnLabelPostfixes; // postfixes to append to the column labels
112 std::vector< OUString > aFormFieldNames; // data field names
114 aColumnServiceNames.reserve(getSettings().aSelectedFields.getLength());
115 aColumnLabelPostfixes.reserve(getSettings().aSelectedFields.getLength());
116 aFormFieldNames.reserve(getSettings().aSelectedFields.getLength());
118 // loop through the selected field names
119 const OUString* pSelectedFields = getSettings().aSelectedFields.getConstArray();
120 const OUString* pEnd = pSelectedFields + getSettings().aSelectedFields.getLength();
121 for (;pSelectedFields < pEnd; ++pSelectedFields)
123 // get the information for the selected column
124 sal_Int32 nFieldType = DataType::OTHER;
125 OControlWizardContext::TNameTypeMap::const_iterator aFind = rContext.aTypes.find(*pSelectedFields);
126 if ( aFind != rContext.aTypes.end() )
127 nFieldType = aFind->second;
129 aFormFieldNames.push_back(*pSelectedFields);
130 switch (nFieldType)
132 case DataType::BIT:
133 case DataType::BOOLEAN:
134 aColumnServiceNames.push_back(OUString("CheckBox"));
135 aColumnLabelPostfixes.push_back(s_sEmptyString);
136 break;
138 case DataType::TINYINT:
139 case DataType::SMALLINT:
140 case DataType::INTEGER:
141 aColumnServiceNames.push_back(OUString("NumericField"));
142 aColumnLabelPostfixes.push_back(s_sEmptyString);
143 break;
145 case DataType::FLOAT:
146 case DataType::REAL:
147 case DataType::DOUBLE:
148 case DataType::NUMERIC:
149 case DataType::DECIMAL:
150 aColumnServiceNames.push_back(OUString("FormattedField"));
151 aColumnLabelPostfixes.push_back(s_sEmptyString);
152 break;
154 case DataType::DATE:
155 aColumnServiceNames.push_back(OUString("DateField"));
156 aColumnLabelPostfixes.push_back(s_sEmptyString);
157 break;
159 case DataType::TIME:
160 aColumnServiceNames.push_back(OUString("TimeField"));
161 aColumnLabelPostfixes.push_back(s_sEmptyString);
162 break;
164 case DataType::TIMESTAMP:
165 aColumnServiceNames.push_back(OUString("DateField"));
166 aColumnLabelPostfixes.push_back(ModuleRes(RID_STR_DATEPOSTFIX).toString());
168 aFormFieldNames.push_back(*pSelectedFields);
169 aColumnServiceNames.push_back(OUString("TimeField"));
170 aColumnLabelPostfixes.push_back(ModuleRes(RID_STR_TIMEPOSTFIX).toString());
171 break;
173 default:
174 aColumnServiceNames.push_back(OUString("TextField"));
175 aColumnLabelPostfixes.push_back(s_sEmptyString);
179 DBG_ASSERT( aFormFieldNames.size() == aColumnServiceNames.size()
180 && aColumnServiceNames.size() == aColumnLabelPostfixes.size(),
181 "OGridWizard::implApplySettings: inconsistent descriptor sequences!");
183 // now loop through the descriptions and create the (grid)columns out of th descriptors
185 Reference< XNameAccess > xExistenceChecker(xColumnContainer.get());
187 std::vector< OUString >::const_iterator pColumnServiceName = aColumnServiceNames.begin();
188 std::vector< OUString >::const_iterator pColumnLabelPostfix = aColumnLabelPostfixes.begin();
189 std::vector< OUString >::const_iterator pFormFieldName = aFormFieldNames.begin();
190 std::vector< OUString >::const_iterator pColumnServiceNameEnd = aColumnServiceNames.end();
192 for (;pColumnServiceName < pColumnServiceNameEnd; ++pColumnServiceName, ++pColumnLabelPostfix, ++pFormFieldName)
194 // create a (grid)column for the (resultset)column
197 Reference< XPropertySet > xColumn( xColumnFactory->createColumn(*pColumnServiceName), UNO_SET_THROW );
198 Reference< XPropertySetInfo > xColumnPSI( xColumn->getPropertySetInfo(), UNO_SET_THROW );
200 OUString sColumnName(*pColumnServiceName);
201 disambiguateName(xExistenceChecker, sColumnName);
203 // the data field the column should be bound to
204 xColumn->setPropertyValue(s_sDataFieldProperty, makeAny(*pFormFieldName));
205 // the label
206 xColumn->setPropertyValue(s_sLabelProperty, makeAny(OUString(*pFormFieldName) += *pColumnLabelPostfix));
207 // the width (<void/> => column will be auto-sized)
208 xColumn->setPropertyValue(s_sWidthProperty, Any());
210 if ( xColumnPSI->hasPropertyByName( s_sMouseWheelBehavior ) )
211 xColumn->setPropertyValue( s_sMouseWheelBehavior, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) );
213 // insert the column
214 xColumnContainer->insertByName(sColumnName, makeAny(xColumn));
216 catch(const Exception&)
218 SAL_WARN( "extensions.dbpilots", "OGridWizard::implApplySettings: "
219 "unexpected exception while creating the grid column for field " <<
220 pFormFieldName->getStr() << "!" );
227 VclPtr<TabPage> OGridWizard::createPage(WizardState _nState)
229 switch (_nState)
231 case GW_STATE_DATASOURCE_SELECTION:
232 return VclPtr<OTableSelectionPage>::Create(this);
233 case GW_STATE_FIELDSELECTION:
234 return VclPtr<OGridFieldsSelection>::Create(this);
236 return VclPtr<TabPage>();
240 WizardTypes::WizardState OGridWizard::determineNextState( WizardState _nCurrentState ) const
242 switch (_nCurrentState)
244 case GW_STATE_DATASOURCE_SELECTION:
245 return GW_STATE_FIELDSELECTION;
246 case GW_STATE_FIELDSELECTION:
247 return WZS_INVALID_STATE;
250 return WZS_INVALID_STATE;
254 void OGridWizard::enterState(WizardState _nState)
256 OControlWizard::enterState(_nState);
258 enableButtons(WizardButtonFlags::PREVIOUS, m_bHadDataSelection ? (GW_STATE_DATASOURCE_SELECTION < _nState) : GW_STATE_FIELDSELECTION < _nState);
259 enableButtons(WizardButtonFlags::NEXT, GW_STATE_FIELDSELECTION != _nState);
260 if (_nState < GW_STATE_FIELDSELECTION)
261 enableButtons(WizardButtonFlags::FINISH, false);
263 if (GW_STATE_FIELDSELECTION == _nState)
264 defaultButton(WizardButtonFlags::FINISH);
268 bool OGridWizard::leaveState(WizardState _nState)
270 if (!OControlWizard::leaveState(_nState))
271 return false;
273 if (GW_STATE_FIELDSELECTION == _nState)
274 defaultButton(WizardButtonFlags::NEXT);
276 return true;
280 bool OGridWizard::onFinish()
282 if ( !OControlWizard::onFinish() )
283 return false;
285 implApplySettings();
287 return true;
290 OGridFieldsSelection::OGridFieldsSelection( OGridWizard* _pParent )
291 :OGridPage(_pParent, "GridFieldsSelection", "modules/sabpilot/ui/gridfieldsselectionpage.ui")
293 get(m_pExistFields,"existingfields");
294 get(m_pSelectOne,"fieldright");
295 get(m_pSelectAll,"allfieldsright");
296 get(m_pDeselectOne,"fieldleft");
297 get(m_pDeselectAll,"allfieldsleft");
298 get(m_pSelFields,"selectedfields");
300 enableFormDatasourceDisplay();
302 m_pSelectOne->SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveOneEntry));
303 m_pSelectAll->SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveAllEntries));
304 m_pDeselectOne->SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveOneEntry));
305 m_pDeselectAll->SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveAllEntries));
307 m_pExistFields->SetSelectHdl(LINK(this, OGridFieldsSelection, OnEntrySelected));
308 m_pSelFields->SetSelectHdl(LINK(this, OGridFieldsSelection, OnEntrySelected));
309 m_pExistFields->SetDoubleClickHdl(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked));
310 m_pSelFields->SetDoubleClickHdl(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked));
313 OGridFieldsSelection::~OGridFieldsSelection()
315 disposeOnce();
318 void OGridFieldsSelection::dispose()
320 m_pExistFields.clear();
321 m_pSelectOne.clear();
322 m_pSelectAll.clear();
323 m_pDeselectOne.clear();
324 m_pDeselectAll.clear();
325 m_pSelFields.clear();
326 OGridPage::dispose();
329 void OGridFieldsSelection::ActivatePage()
331 OGridPage::ActivatePage();
332 m_pExistFields->GrabFocus();
336 bool OGridFieldsSelection::canAdvance() const
338 return false;
339 // we're the last page in our wizard
343 void OGridFieldsSelection::initializePage()
345 OGridPage::initializePage();
347 const OControlWizardContext& rContext = getContext();
348 fillListBox(*m_pExistFields, rContext.aFieldNames);
350 m_pSelFields->Clear();
351 const OGridSettings& rSettings = getSettings();
352 const OUString* pSelected = rSettings.aSelectedFields.getConstArray();
353 const OUString* pEnd = pSelected + rSettings.aSelectedFields.getLength();
354 for (; pSelected < pEnd; ++pSelected)
356 m_pSelFields->InsertEntry(*pSelected);
357 m_pExistFields->RemoveEntry(*pSelected);
360 implCheckButtons();
364 bool OGridFieldsSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
366 if (!OGridPage::commitPage(_eReason))
367 return false;
369 OGridSettings& rSettings = getSettings();
370 sal_uInt16 nSelected = m_pSelFields->GetEntryCount();
372 rSettings.aSelectedFields.realloc(nSelected);
373 OUString* pSelected = rSettings.aSelectedFields.getArray();
375 for (sal_uInt16 i=0; i<nSelected; ++i, ++pSelected)
376 *pSelected = m_pSelFields->GetEntry(i);
378 return true;
382 void OGridFieldsSelection::implCheckButtons()
384 m_pSelectOne->Enable(m_pExistFields->GetSelectEntryCount() != 0);
385 m_pSelectAll->Enable(m_pExistFields->GetEntryCount() != 0);
387 m_pDeselectOne->Enable(m_pSelFields->GetSelectEntryCount() != 0);
388 m_pDeselectAll->Enable(m_pSelFields->GetEntryCount() != 0);
390 getDialog()->enableButtons(WizardButtonFlags::FINISH, 0 != m_pSelFields->GetEntryCount());
394 IMPL_LINK(OGridFieldsSelection, OnEntryDoubleClicked, ListBox*, _pList)
396 PushButton* pSimulateButton = m_pExistFields == _pList ? m_pSelectOne : m_pDeselectOne;
397 if (pSimulateButton->IsEnabled())
398 return OnMoveOneEntry( pSimulateButton );
399 else
400 return 1L;
404 IMPL_LINK(OGridFieldsSelection, OnEntrySelected, ListBox*, /*NOTINTERESTEDIN*/)
406 implCheckButtons();
407 return 0L;
411 IMPL_LINK(OGridFieldsSelection, OnMoveOneEntry, PushButton*, _pButton)
413 bool bMoveRight = (m_pSelectOne == _pButton);
414 ListBox& rMoveTo = bMoveRight ? *m_pSelFields : *m_pExistFields;
416 // the index of the selected entry
417 sal_uInt16 nSelected = bMoveRight ? m_pExistFields->GetSelectEntryPos() : m_pSelFields->GetSelectEntryPos();
418 // the (original) relative position of the entry
419 sal_IntPtr nRelativeIndex = reinterpret_cast<sal_IntPtr>(bMoveRight ? m_pExistFields->GetEntryData(nSelected) : m_pSelFields->GetEntryData(nSelected));
421 sal_uInt16 nInsertPos = SAL_MAX_UINT16;
422 if (!bMoveRight)
423 { // need to determine an insert pos which reflects the original
424 nInsertPos = 0;
425 while (nInsertPos < rMoveTo.GetEntryCount())
427 if (reinterpret_cast<sal_IntPtr>(rMoveTo.GetEntryData(nInsertPos)) > nRelativeIndex)
428 break;
429 ++nInsertPos;
433 // the text of the entry to move
434 OUString sMovingEntry = bMoveRight ? m_pExistFields->GetEntry(nSelected) : m_pSelFields->GetEntry(nSelected);
436 // insert the entry
437 nInsertPos = rMoveTo.InsertEntry(sMovingEntry, nInsertPos);
438 // preserve it's "relative position" entry data
439 rMoveTo.SetEntryData(nInsertPos, reinterpret_cast<void*>(nRelativeIndex));
441 // remove the entry from it's old list
442 if (bMoveRight)
444 sal_Int32 nSelectPos = m_pExistFields->GetSelectEntryPos();
445 m_pExistFields->RemoveEntry(nSelected);
446 if ((LISTBOX_ENTRY_NOTFOUND != nSelectPos) && (nSelectPos < m_pExistFields->GetEntryCount()))
447 m_pExistFields->SelectEntryPos(nSelectPos);
449 m_pExistFields->GrabFocus();
451 else
453 sal_Int32 nSelectPos = m_pSelFields->GetSelectEntryPos();
454 m_pSelFields->RemoveEntry(nSelected);
455 if ((LISTBOX_ENTRY_NOTFOUND != nSelectPos) && (nSelectPos < m_pSelFields->GetEntryCount()))
456 m_pSelFields->SelectEntryPos(nSelectPos);
458 m_pSelFields->GrabFocus();
461 implCheckButtons();
462 return 0;
466 IMPL_LINK(OGridFieldsSelection, OnMoveAllEntries, PushButton*, _pButton)
468 bool bMoveRight = (m_pSelectAll == _pButton);
469 m_pExistFields->Clear();
470 m_pSelFields->Clear();
471 fillListBox(bMoveRight ? *m_pSelFields : *m_pExistFields, getContext().aFieldNames);
473 implCheckButtons();
474 return 0;
478 } // namespace dbp
481 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */