bump product version to 4.1.6.2
[LibreOffice.git] / extensions / source / dbpilots / gridwizard.cxx
blobd0885644cedde23cd51ed0502e279e983232a02c
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 <tools/string.hxx>
28 #include <com/sun/star/form/XGridColumnFactory.hpp>
29 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
30 #include <com/sun/star/container/XNameContainer.hpp>
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
38 //.........................................................................
39 namespace dbp
41 //.........................................................................
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 //=====================================================================
53 //= OGridWizard
54 //=====================================================================
55 //---------------------------------------------------------------------
56 OGridWizard::OGridWizard( Window* _pParent,
57 const Reference< XPropertySet >& _rxObjectModel, const Reference< XComponentContext >& _rxContext )
58 :OControlWizard(_pParent, ModuleRes(RID_DLG_GRIDWIZARD), _rxObjectModel, _rxContext)
59 ,m_bHadDataSelection(sal_True)
61 initControlSettings(&m_aSettings);
63 m_pPrevPage->SetHelpId(HID_GRIDWIZARD_PREVIOUS);
64 m_pNextPage->SetHelpId(HID_GRIDWIZARD_NEXT);
65 m_pCancel->SetHelpId(HID_GRIDWIZARD_CANCEL);
66 m_pFinish->SetHelpId(HID_GRIDWIZARD_FINISH);
68 // if we do not need the data source selection page ...
69 if (!needDatasourceSelection())
70 { // ... skip it!
71 skip(1);
72 m_bHadDataSelection = sal_False;
76 //---------------------------------------------------------------------
77 sal_Bool OGridWizard::approveControl(sal_Int16 _nClassId)
79 if (FormComponentType::GRIDCONTROL != _nClassId)
80 return sal_False;
82 Reference< XGridColumnFactory > xColumnFactory(getContext().xObjectModel, UNO_QUERY);
83 if (!xColumnFactory.is())
84 return sal_False;
86 return sal_True;
89 //---------------------------------------------------------------------
90 void OGridWizard::implApplySettings()
92 const OControlWizardContext& rContext = getContext();
94 // the factory for the columns
95 Reference< XGridColumnFactory > xColumnFactory(rContext.xObjectModel, UNO_QUERY);
96 DBG_ASSERT(xColumnFactory.is(), "OGridWizard::implApplySettings: should never have made it 'til here!");
97 // (if we're here, what the hell happened in approveControl??)
99 // the container for the columns
100 Reference< XNameContainer > xColumnContainer(rContext.xObjectModel, UNO_QUERY);
101 DBG_ASSERT(xColumnContainer.is(), "OGridWizard::implApplySettings: no container!");
103 if (!xColumnFactory.is() || !xColumnContainer.is())
104 return;
106 static const OUString s_sDataFieldProperty ("DataField");
107 static const OUString s_sLabelProperty ("Label");
108 static const OUString s_sWidthProperty ("Width");
109 static const OUString s_sMouseWheelBehavior ("MouseWheelBehavior");
110 static const OUString s_sEmptyString;
112 // collect "descriptors" for the to-be-created (grid)columns
113 std::vector< OUString > aColumnServiceNames; // service names to be used with the XGridColumnFactory
114 std::vector< OUString > aColumnLabelPostfixes; // postfixes to append to the column labels
115 std::vector< OUString > aFormFieldNames; // data field names
117 aColumnServiceNames.reserve(getSettings().aSelectedFields.getLength());
118 aColumnLabelPostfixes.reserve(getSettings().aSelectedFields.getLength());
119 aFormFieldNames.reserve(getSettings().aSelectedFields.getLength());
121 // loop through the selected field names
122 const OUString* pSelectedFields = getSettings().aSelectedFields.getConstArray();
123 const OUString* pEnd = pSelectedFields + getSettings().aSelectedFields.getLength();
124 for (;pSelectedFields < pEnd; ++pSelectedFields)
126 // get the information for the selected column
127 sal_Int32 nFieldType = DataType::OTHER;
128 OControlWizardContext::TNameTypeMap::const_iterator aFind = rContext.aTypes.find(*pSelectedFields);
129 if ( aFind != rContext.aTypes.end() )
130 nFieldType = aFind->second;
132 aFormFieldNames.push_back(*pSelectedFields);
133 switch (nFieldType)
135 case DataType::BIT:
136 case DataType::BOOLEAN:
137 aColumnServiceNames.push_back(OUString("CheckBox"));
138 aColumnLabelPostfixes.push_back(s_sEmptyString);
139 break;
141 case DataType::TINYINT:
142 case DataType::SMALLINT:
143 case DataType::INTEGER:
144 aColumnServiceNames.push_back(OUString("NumericField"));
145 aColumnLabelPostfixes.push_back(s_sEmptyString);
146 break;
148 case DataType::FLOAT:
149 case DataType::REAL:
150 case DataType::DOUBLE:
151 case DataType::NUMERIC:
152 case DataType::DECIMAL:
153 aColumnServiceNames.push_back(OUString("FormattedField"));
154 aColumnLabelPostfixes.push_back(s_sEmptyString);
155 break;
157 case DataType::DATE:
158 aColumnServiceNames.push_back(OUString("DateField"));
159 aColumnLabelPostfixes.push_back(s_sEmptyString);
160 break;
162 case DataType::TIME:
163 aColumnServiceNames.push_back(OUString("TimeField"));
164 aColumnLabelPostfixes.push_back(s_sEmptyString);
165 break;
167 case DataType::TIMESTAMP:
168 aColumnServiceNames.push_back(OUString("DateField"));
169 aColumnLabelPostfixes.push_back(String(ModuleRes(RID_STR_DATEPOSTFIX)));
171 aFormFieldNames.push_back(*pSelectedFields);
172 aColumnServiceNames.push_back(OUString("TimeField"));
173 aColumnLabelPostfixes.push_back(String(ModuleRes(RID_STR_TIMEPOSTFIX)));
174 break;
176 default:
177 aColumnServiceNames.push_back(OUString("TextField"));
178 aColumnLabelPostfixes.push_back(s_sEmptyString);
182 DBG_ASSERT( aFormFieldNames.size() == aColumnServiceNames.size()
183 && aColumnServiceNames.size() == aColumnLabelPostfixes.size(),
184 "OGridWizard::implApplySettings: inconsistent descriptor sequences!");
186 // now loop through the descriptions and create the (grid)columns out of th descriptors
188 Reference< XNameAccess > xExistenceChecker(xColumnContainer.get());
190 std::vector< OUString >::const_iterator pColumnServiceName = aColumnServiceNames.begin();
191 std::vector< OUString >::const_iterator pColumnLabelPostfix = aColumnLabelPostfixes.begin();
192 std::vector< OUString >::const_iterator pFormFieldName = aFormFieldNames.begin();
193 std::vector< OUString >::const_iterator pColumnServiceNameEnd = aColumnServiceNames.end();
195 for (;pColumnServiceName < pColumnServiceNameEnd; ++pColumnServiceName, ++pColumnLabelPostfix, ++pFormFieldName)
197 // create a (grid)column for the (resultset)column
200 Reference< XPropertySet > xColumn( xColumnFactory->createColumn(*pColumnServiceName), UNO_SET_THROW );
201 Reference< XPropertySetInfo > xColumnPSI( xColumn->getPropertySetInfo(), UNO_SET_THROW );
203 OUString sColumnName(*pColumnServiceName);
204 disambiguateName(xExistenceChecker, sColumnName);
206 // the data field the column should be bound to
207 xColumn->setPropertyValue(s_sDataFieldProperty, makeAny(*pFormFieldName));
208 // the label
209 xColumn->setPropertyValue(s_sLabelProperty, makeAny(OUString(*pFormFieldName) += *pColumnLabelPostfix));
210 // the width (<void/> => column will be auto-sized)
211 xColumn->setPropertyValue(s_sWidthProperty, Any());
213 if ( xColumnPSI->hasPropertyByName( s_sMouseWheelBehavior ) )
214 xColumn->setPropertyValue( s_sMouseWheelBehavior, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) );
216 // insert the column
217 xColumnContainer->insertByName(sColumnName, makeAny(xColumn));
219 catch(const Exception&)
221 SAL_WARN( "extensions.dbpilots", "OGridWizard::implApplySettings: " <<
222 "unexpected exception while creating the grid column for field " <<
223 pFormFieldName->getStr() << "!" );
229 //---------------------------------------------------------------------
230 OWizardPage* OGridWizard::createPage(WizardState _nState)
232 switch (_nState)
234 case GW_STATE_DATASOURCE_SELECTION:
235 return new OTableSelectionPage(this);
236 case GW_STATE_FIELDSELECTION:
237 return new OGridFieldsSelection(this);
240 return NULL;
243 //---------------------------------------------------------------------
244 WizardTypes::WizardState OGridWizard::determineNextState( WizardState _nCurrentState ) const
246 switch (_nCurrentState)
248 case GW_STATE_DATASOURCE_SELECTION:
249 return GW_STATE_FIELDSELECTION;
250 case GW_STATE_FIELDSELECTION:
251 return WZS_INVALID_STATE;
254 return WZS_INVALID_STATE;
257 //---------------------------------------------------------------------
258 void OGridWizard::enterState(WizardState _nState)
260 OControlWizard::enterState(_nState);
262 enableButtons(WZB_PREVIOUS, m_bHadDataSelection ? (GW_STATE_DATASOURCE_SELECTION < _nState) : GW_STATE_FIELDSELECTION < _nState);
263 enableButtons(WZB_NEXT, GW_STATE_FIELDSELECTION != _nState);
264 if (_nState < GW_STATE_FIELDSELECTION)
265 enableButtons(WZB_FINISH, sal_False);
267 if (GW_STATE_FIELDSELECTION == _nState)
268 defaultButton(WZB_FINISH);
271 //---------------------------------------------------------------------
272 sal_Bool OGridWizard::leaveState(WizardState _nState)
274 if (!OControlWizard::leaveState(_nState))
275 return sal_False;
277 if (GW_STATE_FIELDSELECTION == _nState)
278 defaultButton(WZB_NEXT);
280 return sal_True;
283 //---------------------------------------------------------------------
284 sal_Bool OGridWizard::onFinish()
286 if ( !OControlWizard::onFinish() )
287 return sal_False;
289 implApplySettings();
291 return sal_True;
294 //=====================================================================
295 //= OGridFieldsSelection
296 //=====================================================================
297 //---------------------------------------------------------------------
298 OGridFieldsSelection::OGridFieldsSelection( OGridWizard* _pParent )
299 :OGridPage(_pParent, ModuleRes(RID_PAGE_GW_FIELDSELECTION))
300 ,m_aFrame (this, ModuleRes(FL_FRAME))
301 ,m_aExistFieldsLabel (this, ModuleRes(FT_EXISTING_FIELDS))
302 ,m_aExistFields (this, ModuleRes(LB_EXISTING_FIELDS))
303 ,m_aSelectOne (this, ModuleRes(PB_FIELDRIGHT))
304 ,m_aSelectAll (this, ModuleRes(PB_ALLFIELDSRIGHT))
305 ,m_aDeselectOne (this, ModuleRes(PB_FIELDLEFT))
306 ,m_aDeselectAll (this, ModuleRes(PB_ALLFIELDSLEFT))
307 ,m_aSelFieldsLabel (this, ModuleRes(FT_SELECTED_FIELDS))
308 ,m_aSelFields (this, ModuleRes(LB_SELECTED_FIELDS))
310 FreeResource();
312 enableFormDatasourceDisplay();
314 m_aSelectOne.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveOneEntry));
315 m_aSelectAll.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveAllEntries));
316 m_aDeselectOne.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveOneEntry));
317 m_aDeselectAll.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveAllEntries));
319 m_aExistFields.SetSelectHdl(LINK(this, OGridFieldsSelection, OnEntrySelected));
320 m_aSelFields.SetSelectHdl(LINK(this, OGridFieldsSelection, OnEntrySelected));
321 m_aExistFields.SetDoubleClickHdl(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked));
322 m_aSelFields.SetDoubleClickHdl(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked));
325 //---------------------------------------------------------------------
326 void OGridFieldsSelection::ActivatePage()
328 OGridPage::ActivatePage();
329 m_aExistFields.GrabFocus();
332 //---------------------------------------------------------------------
333 bool OGridFieldsSelection::canAdvance() const
335 return false;
336 // we're the last page in our wizard
339 //---------------------------------------------------------------------
340 void OGridFieldsSelection::initializePage()
342 OGridPage::initializePage();
344 const OControlWizardContext& rContext = getContext();
345 fillListBox(m_aExistFields, rContext.aFieldNames);
347 m_aSelFields.Clear();
348 const OGridSettings& rSettings = getSettings();
349 const OUString* pSelected = rSettings.aSelectedFields.getConstArray();
350 const OUString* pEnd = pSelected + rSettings.aSelectedFields.getLength();
351 for (; pSelected < pEnd; ++pSelected)
353 m_aSelFields.InsertEntry(*pSelected);
354 m_aExistFields.RemoveEntry(*pSelected);
357 implCheckButtons();
360 //---------------------------------------------------------------------
361 sal_Bool OGridFieldsSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
363 if (!OGridPage::commitPage(_eReason))
364 return sal_False;
366 OGridSettings& rSettings = getSettings();
367 sal_uInt16 nSelected = m_aSelFields.GetEntryCount();
369 rSettings.aSelectedFields.realloc(nSelected);
370 OUString* pSelected = rSettings.aSelectedFields.getArray();
372 for (sal_uInt16 i=0; i<nSelected; ++i, ++pSelected)
373 *pSelected = m_aSelFields.GetEntry(i);
375 return sal_True;
378 //---------------------------------------------------------------------
379 void OGridFieldsSelection::implCheckButtons()
381 m_aSelectOne.Enable(m_aExistFields.GetSelectEntryCount() != 0);
382 m_aSelectAll.Enable(m_aExistFields.GetEntryCount() != 0);
384 m_aDeselectOne.Enable(m_aSelFields.GetSelectEntryCount() != 0);
385 m_aDeselectAll.Enable(m_aSelFields.GetEntryCount() != 0);
387 getDialog()->enableButtons(WZB_FINISH, 0 != m_aSelFields.GetEntryCount());
390 //---------------------------------------------------------------------
391 IMPL_LINK(OGridFieldsSelection, OnEntryDoubleClicked, ListBox*, _pList)
393 PushButton* pSimulateButton = &m_aExistFields == _pList ? &m_aSelectOne : &m_aDeselectOne;
394 if (pSimulateButton->IsEnabled())
395 return OnMoveOneEntry( pSimulateButton );
396 else
397 return 1L;
400 //---------------------------------------------------------------------
401 IMPL_LINK(OGridFieldsSelection, OnEntrySelected, ListBox*, /*NOTINTERESTEDIN*/)
403 implCheckButtons();
404 return 0L;
407 //---------------------------------------------------------------------
408 IMPL_LINK(OGridFieldsSelection, OnMoveOneEntry, PushButton*, _pButton)
410 sal_Bool bMoveRight = (&m_aSelectOne == _pButton);
411 ListBox& rMoveTo = bMoveRight ? m_aSelFields : m_aExistFields;
413 // the index of the selected entry
414 sal_uInt16 nSelected = bMoveRight ? m_aExistFields.GetSelectEntryPos() : m_aSelFields.GetSelectEntryPos();
415 // the (original) relative position of the entry
416 sal_IntPtr nRelativeIndex = reinterpret_cast<sal_IntPtr>(bMoveRight ? m_aExistFields.GetEntryData(nSelected) : m_aSelFields.GetEntryData(nSelected));
418 sal_uInt16 nInsertPos = LISTBOX_APPEND;
419 if (!bMoveRight)
420 { // need to determine an insert pos which reflects the original
421 nInsertPos = 0;
422 while (nInsertPos < rMoveTo.GetEntryCount())
424 if (reinterpret_cast<sal_IntPtr>(rMoveTo.GetEntryData(nInsertPos)) > nRelativeIndex)
425 break;
426 ++nInsertPos;
430 // the text of the entry to move
431 String sMovingEntry = bMoveRight ? m_aExistFields.GetEntry(nSelected) : m_aSelFields.GetEntry(nSelected);
433 // insert the entry
434 nInsertPos = rMoveTo.InsertEntry(sMovingEntry, nInsertPos);
435 // preserve it's "relative position" entry data
436 rMoveTo.SetEntryData(nInsertPos, reinterpret_cast<void*>(nRelativeIndex));
438 // remove the entry from it's old list
439 if (bMoveRight)
441 sal_uInt16 nSelectPos = m_aExistFields.GetSelectEntryPos();
442 m_aExistFields.RemoveEntry(nSelected);
443 if ((LISTBOX_ENTRY_NOTFOUND != nSelectPos) && (nSelectPos < m_aExistFields.GetEntryCount()))
444 m_aExistFields.SelectEntryPos(nSelectPos);
446 m_aExistFields.GrabFocus();
448 else
450 sal_uInt16 nSelectPos = m_aSelFields.GetSelectEntryPos();
451 m_aSelFields.RemoveEntry(nSelected);
452 if ((LISTBOX_ENTRY_NOTFOUND != nSelectPos) && (nSelectPos < m_aSelFields.GetEntryCount()))
453 m_aSelFields.SelectEntryPos(nSelectPos);
455 m_aSelFields.GrabFocus();
458 implCheckButtons();
459 return 0;
462 //---------------------------------------------------------------------
463 IMPL_LINK(OGridFieldsSelection, OnMoveAllEntries, PushButton*, _pButton)
465 sal_Bool bMoveRight = (&m_aSelectAll == _pButton);
466 m_aExistFields.Clear();
467 m_aSelFields.Clear();
468 fillListBox(bMoveRight ? m_aSelFields : m_aExistFields, getContext().aFieldNames);
470 implCheckButtons();
471 return 0;
474 //.........................................................................
475 } // namespace dbp
476 //.........................................................................
478 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */