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 "sal/config.h"
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 //.........................................................................
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 //=====================================================================
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())
72 m_bHadDataSelection
= sal_False
;
76 //---------------------------------------------------------------------
77 sal_Bool
OGridWizard::approveControl(sal_Int16 _nClassId
)
79 if (FormComponentType::GRIDCONTROL
!= _nClassId
)
82 Reference
< XGridColumnFactory
> xColumnFactory(getContext().xObjectModel
, UNO_QUERY
);
83 if (!xColumnFactory
.is())
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())
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
);
136 case DataType::BOOLEAN
:
137 aColumnServiceNames
.push_back(OUString("CheckBox"));
138 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
141 case DataType::TINYINT
:
142 case DataType::SMALLINT
:
143 case DataType::INTEGER
:
144 aColumnServiceNames
.push_back(OUString("NumericField"));
145 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
148 case DataType::FLOAT
:
150 case DataType::DOUBLE
:
151 case DataType::NUMERIC
:
152 case DataType::DECIMAL
:
153 aColumnServiceNames
.push_back(OUString("FormattedField"));
154 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
158 aColumnServiceNames
.push_back(OUString("DateField"));
159 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
163 aColumnServiceNames
.push_back(OUString("TimeField"));
164 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
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
)));
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
));
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
) );
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
)
234 case GW_STATE_DATASOURCE_SELECTION
:
235 return new OTableSelectionPage(this);
236 case GW_STATE_FIELDSELECTION
:
237 return new OGridFieldsSelection(this);
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
))
277 if (GW_STATE_FIELDSELECTION
== _nState
)
278 defaultButton(WZB_NEXT
);
283 //---------------------------------------------------------------------
284 sal_Bool
OGridWizard::onFinish()
286 if ( !OControlWizard::onFinish() )
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
))
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
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
);
360 //---------------------------------------------------------------------
361 sal_Bool
OGridFieldsSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason
)
363 if (!OGridPage::commitPage(_eReason
))
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
);
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
);
400 //---------------------------------------------------------------------
401 IMPL_LINK(OGridFieldsSelection
, OnEntrySelected
, ListBox
*, /*NOTINTERESTEDIN*/)
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
;
420 { // need to determine an insert pos which reflects the original
422 while (nInsertPos
< rMoveTo
.GetEntryCount())
424 if (reinterpret_cast<sal_IntPtr
>(rMoveTo
.GetEntryData(nInsertPos
)) > nRelativeIndex
)
430 // the text of the entry to move
431 String sMovingEntry
= bMoveRight
? m_aExistFields
.GetEntry(nSelected
) : m_aSelFields
.GetEntry(nSelected
);
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
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();
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();
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
);
474 //.........................................................................
476 //.........................................................................
478 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */