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 <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"
35 #define GW_STATE_DATASOURCE_SELECTION 0
36 #define GW_STATE_FIELDSELECTION 1
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())
69 m_bHadDataSelection
= false;
74 bool OGridWizard::approveControl(sal_Int16 _nClassId
)
76 if (FormComponentType::GRIDCONTROL
!= _nClassId
)
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())
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
);
127 case DataType::BOOLEAN
:
128 aColumnServiceNames
.push_back(OUString("CheckBox"));
129 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
132 case DataType::TINYINT
:
133 case DataType::SMALLINT
:
134 case DataType::INTEGER
:
135 aColumnServiceNames
.push_back(OUString("NumericField"));
136 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
139 case DataType::FLOAT
:
141 case DataType::DOUBLE
:
142 case DataType::NUMERIC
:
143 case DataType::DECIMAL
:
144 aColumnServiceNames
.push_back(OUString("FormattedField"));
145 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
149 aColumnServiceNames
.push_back(OUString("DateField"));
150 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
154 aColumnServiceNames
.push_back(OUString("TimeField"));
155 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
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
));
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
));
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
) );
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 " <<
215 ++pColumnLabelPostfix
;
222 VclPtr
<TabPage
> OGridWizard::createPage(WizardState _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
))
268 if (GW_STATE_FIELDSELECTION
== _nState
)
269 defaultButton(WizardButtonFlags::NEXT
);
275 bool OGridWizard::onFinish()
277 if ( !OControlWizard::onFinish() )
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()
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
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
);
359 bool OGridFieldsSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason
)
361 if (!OGridPage::commitPage(_eReason
))
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
);
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)
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
;
417 { // need to determine an insert pos which reflects the original
419 while (nInsertPos
< rMoveTo
.GetEntryCount())
421 if (reinterpret_cast<sal_IntPtr
>(rMoveTo
.GetEntryData(nInsertPos
)) > nRelativeIndex
)
427 // the text of the entry to move
428 OUString sMovingEntry
= bMoveRight
? m_pExistFields
->GetEntry(nSelected
) : m_pSelFields
->GetEntry(nSelected
);
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
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();
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();
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
);
473 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */