bump product version to 6.3.0.0.beta1
[LibreOffice.git] / extensions / source / dbpilots / gridwizard.cxx
blob7a3ab837497944d7271d2d7289b0c4a344890323
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 <helpids.h>
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(compmodule::ModuleRes(RID_STR_GRIDWIZARD_TITLE));
65 // if we do not need the data source selection page ...
66 if (!needDatasourceSelection())
67 { // ... skip it!
68 skip();
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 return xColumnFactory.is();
84 void OGridWizard::implApplySettings()
86 const OControlWizardContext& rContext = getContext();
88 // the factory for the columns
89 Reference< XGridColumnFactory > xColumnFactory(rContext.xObjectModel, UNO_QUERY);
90 DBG_ASSERT(xColumnFactory.is(), "OGridWizard::implApplySettings: should never have made it 'til here!");
91 // (if we're here, what the hell happened in approveControl??)
93 // the container for the columns
94 Reference< XNameContainer > xColumnContainer(rContext.xObjectModel, UNO_QUERY);
95 DBG_ASSERT(xColumnContainer.is(), "OGridWizard::implApplySettings: no container!");
97 if (!xColumnFactory.is() || !xColumnContainer.is())
98 return;
100 static const char s_sMouseWheelBehavior[] = "MouseWheelBehavior";
101 static const char s_sEmptyString[] = "";
103 // collect "descriptors" for the to-be-created (grid)columns
104 std::vector< OUString > aColumnServiceNames; // service names to be used with the XGridColumnFactory
105 std::vector< OUString > aColumnLabelPostfixes; // postfixes to append to the column labels
106 std::vector< OUString > aFormFieldNames; // data field names
108 aColumnServiceNames.reserve(getSettings().aSelectedFields.getLength());
109 aColumnLabelPostfixes.reserve(getSettings().aSelectedFields.getLength());
110 aFormFieldNames.reserve(getSettings().aSelectedFields.getLength());
112 // loop through the selected field names
113 const OUString* pSelectedFields = getSettings().aSelectedFields.getConstArray();
114 const OUString* pEnd = pSelectedFields + getSettings().aSelectedFields.getLength();
115 for (;pSelectedFields < pEnd; ++pSelectedFields)
117 // get the information for the selected column
118 sal_Int32 nFieldType = DataType::OTHER;
119 OControlWizardContext::TNameTypeMap::const_iterator aFind = rContext.aTypes.find(*pSelectedFields);
120 if ( aFind != rContext.aTypes.end() )
121 nFieldType = aFind->second;
123 aFormFieldNames.push_back(*pSelectedFields);
124 switch (nFieldType)
126 case DataType::BIT:
127 case DataType::BOOLEAN:
128 aColumnServiceNames.push_back(OUString("CheckBox"));
129 aColumnLabelPostfixes.push_back(s_sEmptyString);
130 break;
132 case DataType::TINYINT:
133 case DataType::SMALLINT:
134 case DataType::INTEGER:
135 aColumnServiceNames.push_back(OUString("NumericField"));
136 aColumnLabelPostfixes.push_back(s_sEmptyString);
137 break;
139 case DataType::FLOAT:
140 case DataType::REAL:
141 case DataType::DOUBLE:
142 case DataType::NUMERIC:
143 case DataType::DECIMAL:
144 aColumnServiceNames.push_back(OUString("FormattedField"));
145 aColumnLabelPostfixes.push_back(s_sEmptyString);
146 break;
148 case DataType::DATE:
149 aColumnServiceNames.push_back(OUString("DateField"));
150 aColumnLabelPostfixes.push_back(s_sEmptyString);
151 break;
153 case DataType::TIME:
154 aColumnServiceNames.push_back(OUString("TimeField"));
155 aColumnLabelPostfixes.push_back(s_sEmptyString);
156 break;
158 case DataType::TIMESTAMP:
159 aColumnServiceNames.push_back(OUString("DateField"));
160 aColumnLabelPostfixes.push_back(compmodule::ModuleRes(RID_STR_DATEPOSTFIX));
162 aFormFieldNames.push_back(*pSelectedFields);
163 aColumnServiceNames.push_back(OUString("TimeField"));
164 aColumnLabelPostfixes.push_back(compmodule::ModuleRes(RID_STR_TIMEPOSTFIX));
165 break;
167 default:
168 aColumnServiceNames.push_back(OUString("TextField"));
169 aColumnLabelPostfixes.push_back(s_sEmptyString);
173 DBG_ASSERT( aFormFieldNames.size() == aColumnServiceNames.size()
174 && aColumnServiceNames.size() == aColumnLabelPostfixes.size(),
175 "OGridWizard::implApplySettings: inconsistent descriptor sequences!");
177 // now loop through the descriptions and create the (grid)columns out of th descriptors
179 Reference< XNameAccess > xExistenceChecker(xColumnContainer.get());
181 std::vector< OUString >::const_iterator pColumnLabelPostfix = aColumnLabelPostfixes.begin();
182 std::vector< OUString >::const_iterator pFormFieldName = aFormFieldNames.begin();
184 for (const auto& rColumnServiceName : aColumnServiceNames)
186 // create a (grid)column for the (resultset)column
189 Reference< XPropertySet > xColumn( xColumnFactory->createColumn(rColumnServiceName), UNO_SET_THROW );
190 Reference< XPropertySetInfo > xColumnPSI( xColumn->getPropertySetInfo(), UNO_SET_THROW );
192 OUString sColumnName(rColumnServiceName);
193 disambiguateName(xExistenceChecker, sColumnName);
195 // the data field the column should be bound to
196 xColumn->setPropertyValue("DataField", makeAny(*pFormFieldName));
197 // the label
198 xColumn->setPropertyValue("Label", makeAny(*pFormFieldName + *pColumnLabelPostfix));
199 // the width (<void/> => column will be auto-sized)
200 xColumn->setPropertyValue("Width", Any());
202 if ( xColumnPSI->hasPropertyByName( s_sMouseWheelBehavior ) )
203 xColumn->setPropertyValue( s_sMouseWheelBehavior, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) );
205 // insert the column
206 xColumnContainer->insertByName(sColumnName, makeAny(xColumn));
208 catch(const Exception&)
210 SAL_WARN( "extensions.dbpilots", "OGridWizard::implApplySettings: "
211 "unexpected exception while creating the grid column for field " <<
212 *pFormFieldName );
215 ++pColumnLabelPostfix;
216 ++pFormFieldName;
222 VclPtr<TabPage> OGridWizard::createPage(WizardState _nState)
224 switch (_nState)
226 case GW_STATE_DATASOURCE_SELECTION:
227 return VclPtr<OTableSelectionPage>::Create(this);
228 case GW_STATE_FIELDSELECTION:
229 return VclPtr<OGridFieldsSelection>::Create(this);
231 return VclPtr<TabPage>();
235 WizardTypes::WizardState OGridWizard::determineNextState( WizardState _nCurrentState ) const
237 switch (_nCurrentState)
239 case GW_STATE_DATASOURCE_SELECTION:
240 return GW_STATE_FIELDSELECTION;
241 case GW_STATE_FIELDSELECTION:
242 return WZS_INVALID_STATE;
245 return WZS_INVALID_STATE;
249 void OGridWizard::enterState(WizardState _nState)
251 OControlWizard::enterState(_nState);
253 enableButtons(WizardButtonFlags::PREVIOUS, m_bHadDataSelection ? (GW_STATE_DATASOURCE_SELECTION < _nState) : GW_STATE_FIELDSELECTION < _nState);
254 enableButtons(WizardButtonFlags::NEXT, GW_STATE_FIELDSELECTION != _nState);
255 if (_nState < GW_STATE_FIELDSELECTION)
256 enableButtons(WizardButtonFlags::FINISH, false);
258 if (GW_STATE_FIELDSELECTION == _nState)
259 defaultButton(WizardButtonFlags::FINISH);
263 bool OGridWizard::leaveState(WizardState _nState)
265 if (!OControlWizard::leaveState(_nState))
266 return false;
268 if (GW_STATE_FIELDSELECTION == _nState)
269 defaultButton(WizardButtonFlags::NEXT);
271 return true;
275 bool OGridWizard::onFinish()
277 if ( !OControlWizard::onFinish() )
278 return false;
280 implApplySettings();
282 return true;
285 OGridFieldsSelection::OGridFieldsSelection( OGridWizard* _pParent )
286 :OGridPage(_pParent, "GridFieldsSelection", "modules/sabpilot/ui/gridfieldsselectionpage.ui")
288 get(m_pExistFields,"existingfields");
289 get(m_pSelectOne,"fieldright");
290 get(m_pSelectAll,"allfieldsright");
291 get(m_pDeselectOne,"fieldleft");
292 get(m_pDeselectAll,"allfieldsleft");
293 get(m_pSelFields,"selectedfields");
295 enableFormDatasourceDisplay();
297 m_pSelectOne->SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveOneEntry));
298 m_pSelectAll->SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveAllEntries));
299 m_pDeselectOne->SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveOneEntry));
300 m_pDeselectAll->SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveAllEntries));
302 m_pExistFields->SetSelectHdl(LINK(this, OGridFieldsSelection, OnEntrySelected));
303 m_pSelFields->SetSelectHdl(LINK(this, OGridFieldsSelection, OnEntrySelected));
304 m_pExistFields->SetDoubleClickHdl(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked));
305 m_pSelFields->SetDoubleClickHdl(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked));
308 OGridFieldsSelection::~OGridFieldsSelection()
310 disposeOnce();
313 void OGridFieldsSelection::dispose()
315 m_pExistFields.clear();
316 m_pSelectOne.clear();
317 m_pSelectAll.clear();
318 m_pDeselectOne.clear();
319 m_pDeselectAll.clear();
320 m_pSelFields.clear();
321 OGridPage::dispose();
324 void OGridFieldsSelection::ActivatePage()
326 OGridPage::ActivatePage();
327 m_pExistFields->GrabFocus();
331 bool OGridFieldsSelection::canAdvance() const
333 return false;
334 // we're the last page in our wizard
338 void OGridFieldsSelection::initializePage()
340 OGridPage::initializePage();
342 const OControlWizardContext& rContext = getContext();
343 fillListBox(*m_pExistFields, rContext.aFieldNames);
345 m_pSelFields->Clear();
346 const OGridSettings& rSettings = getSettings();
347 const OUString* pSelected = rSettings.aSelectedFields.getConstArray();
348 const OUString* pEnd = pSelected + rSettings.aSelectedFields.getLength();
349 for (; pSelected < pEnd; ++pSelected)
351 m_pSelFields->InsertEntry(*pSelected);
352 m_pExistFields->RemoveEntry(*pSelected);
355 implCheckButtons();
359 bool OGridFieldsSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
361 if (!OGridPage::commitPage(_eReason))
362 return false;
364 OGridSettings& rSettings = getSettings();
365 const sal_Int32 nSelected = m_pSelFields->GetEntryCount();
367 rSettings.aSelectedFields.realloc(nSelected);
368 OUString* pSelected = rSettings.aSelectedFields.getArray();
370 for (sal_Int32 i=0; i<nSelected; ++i, ++pSelected)
371 *pSelected = m_pSelFields->GetEntry(i);
373 return true;
377 void OGridFieldsSelection::implCheckButtons()
379 m_pSelectOne->Enable(m_pExistFields->GetSelectedEntryCount() != 0);
380 m_pSelectAll->Enable(m_pExistFields->GetEntryCount() != 0);
382 m_pDeselectOne->Enable(m_pSelFields->GetSelectedEntryCount() != 0);
383 m_pDeselectAll->Enable(m_pSelFields->GetEntryCount() != 0);
385 getDialog()->enableButtons(WizardButtonFlags::FINISH, 0 != m_pSelFields->GetEntryCount());
389 IMPL_LINK(OGridFieldsSelection, OnEntryDoubleClicked, ListBox&, _rList, void)
391 PushButton* pSimulateButton = m_pExistFields == &_rList ? m_pSelectOne.get() : m_pDeselectOne.get();
392 if (pSimulateButton->IsEnabled())
394 OnMoveOneEntry( pSimulateButton );
399 IMPL_LINK_NOARG(OGridFieldsSelection, OnEntrySelected, ListBox&, void)
401 implCheckButtons();
405 IMPL_LINK(OGridFieldsSelection, OnMoveOneEntry, Button*, _pButton, void)
407 bool bMoveRight = (m_pSelectOne == _pButton);
408 ListBox& rMoveTo = bMoveRight ? *m_pSelFields : *m_pExistFields;
410 // the index of the selected entry
411 const sal_Int32 nSelected = bMoveRight ? m_pExistFields->GetSelectedEntryPos() : m_pSelFields->GetSelectedEntryPos();
412 // the (original) relative position of the entry
413 sal_IntPtr nRelativeIndex = reinterpret_cast<sal_IntPtr>(bMoveRight ? m_pExistFields->GetEntryData(nSelected) : m_pSelFields->GetEntryData(nSelected));
415 sal_Int32 nInsertPos = LISTBOX_APPEND;
416 if (!bMoveRight)
417 { // need to determine an insert pos which reflects the original
418 nInsertPos = 0;
419 while (nInsertPos < rMoveTo.GetEntryCount())
421 if (reinterpret_cast<sal_IntPtr>(rMoveTo.GetEntryData(nInsertPos)) > nRelativeIndex)
422 break;
423 ++nInsertPos;
427 // the text of the entry to move
428 OUString sMovingEntry = bMoveRight ? m_pExistFields->GetEntry(nSelected) : m_pSelFields->GetEntry(nSelected);
430 // insert the entry
431 nInsertPos = rMoveTo.InsertEntry(sMovingEntry, nInsertPos);
432 // preserve it's "relative position" entry data
433 rMoveTo.SetEntryData(nInsertPos, reinterpret_cast<void*>(nRelativeIndex));
435 // remove the entry from its old list
436 if (bMoveRight)
438 sal_Int32 nSelectPos = m_pExistFields->GetSelectedEntryPos();
439 m_pExistFields->RemoveEntry(nSelected);
440 if ((LISTBOX_ENTRY_NOTFOUND != nSelectPos) && (nSelectPos < m_pExistFields->GetEntryCount()))
441 m_pExistFields->SelectEntryPos(nSelectPos);
443 m_pExistFields->GrabFocus();
445 else
447 sal_Int32 nSelectPos = m_pSelFields->GetSelectedEntryPos();
448 m_pSelFields->RemoveEntry(nSelected);
449 if ((LISTBOX_ENTRY_NOTFOUND != nSelectPos) && (nSelectPos < m_pSelFields->GetEntryCount()))
450 m_pSelFields->SelectEntryPos(nSelectPos);
452 m_pSelFields->GrabFocus();
455 implCheckButtons();
459 IMPL_LINK(OGridFieldsSelection, OnMoveAllEntries, Button*, _pButton, void)
461 bool bMoveRight = (m_pSelectAll == _pButton);
462 m_pExistFields->Clear();
463 m_pSelFields->Clear();
464 fillListBox(bMoveRight ? *m_pSelFields : *m_pExistFields, getContext().aFieldNames);
466 implCheckButtons();
470 } // namespace dbp
473 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */