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"
33 #include "dbpilots.hrc"
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(ModuleRes(RID_STR_GRIDWIZARD_TITLE
).toString());
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 if (!xColumnFactory
.is())
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())
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
);
133 case DataType::BOOLEAN
:
134 aColumnServiceNames
.push_back(OUString("CheckBox"));
135 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
138 case DataType::TINYINT
:
139 case DataType::SMALLINT
:
140 case DataType::INTEGER
:
141 aColumnServiceNames
.push_back(OUString("NumericField"));
142 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
145 case DataType::FLOAT
:
147 case DataType::DOUBLE
:
148 case DataType::NUMERIC
:
149 case DataType::DECIMAL
:
150 aColumnServiceNames
.push_back(OUString("FormattedField"));
151 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
155 aColumnServiceNames
.push_back(OUString("DateField"));
156 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
160 aColumnServiceNames
.push_back(OUString("TimeField"));
161 aColumnLabelPostfixes
.push_back(s_sEmptyString
);
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());
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
));
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
) );
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
)
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
))
273 if (GW_STATE_FIELDSELECTION
== _nState
)
274 defaultButton(WizardButtonFlags::NEXT
);
280 bool OGridWizard::onFinish()
282 if ( !OControlWizard::onFinish() )
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()
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
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
);
364 bool OGridFieldsSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason
)
366 if (!OGridPage::commitPage(_eReason
))
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
);
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
);
404 IMPL_LINK(OGridFieldsSelection
, OnEntrySelected
, ListBox
*, /*NOTINTERESTEDIN*/)
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
;
423 { // need to determine an insert pos which reflects the original
425 while (nInsertPos
< rMoveTo
.GetEntryCount())
427 if (reinterpret_cast<sal_IntPtr
>(rMoveTo
.GetEntryData(nInsertPos
)) > nRelativeIndex
)
433 // the text of the entry to move
434 OUString sMovingEntry
= bMoveRight
? m_pExistFields
->GetEntry(nSelected
) : m_pSelFields
->GetEntry(nSelected
);
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
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();
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();
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
);
481 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */