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 "listcombowizard.hxx"
21 #include "commonpagesdbp.hxx"
22 #include <com/sun/star/sdbc/XConnection.hpp>
23 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
24 #include <com/sun/star/container/XNameAccess.hpp>
25 #include <com/sun/star/form/ListSourceType.hpp>
26 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
27 #include <tools/debug.hxx>
28 #include <comphelper/diagnose_ex.hxx>
29 #include <connectivity/dbtools.hxx>
31 #include <osl/diagnose.h>
38 using namespace ::com::sun::star::uno
;
39 using namespace ::com::sun::star::beans
;
40 using namespace ::com::sun::star::sdbc
;
41 using namespace ::com::sun::star::sdbcx
;
42 using namespace ::com::sun::star::container
;
43 using namespace ::com::sun::star::form
;
44 using namespace ::dbtools
;
46 OListComboWizard::OListComboWizard(weld::Window
* _pParent
,
47 const Reference
< XPropertySet
>& _rxObjectModel
, const Reference
< XComponentContext
>& _rxContext
)
48 : OControlWizard(_pParent
, _rxObjectModel
, _rxContext
)
50 , m_bHadDataSelection(true)
52 initControlSettings(&m_aSettings
);
54 m_xPrevPage
->set_help_id(HID_LISTWIZARD_PREVIOUS
);
55 m_xNextPage
->set_help_id(HID_LISTWIZARD_NEXT
);
56 m_xCancel
->set_help_id(HID_LISTWIZARD_CANCEL
);
57 m_xFinish
->set_help_id(HID_LISTWIZARD_FINISH
);
59 // if we do not need the data source selection page ...
60 if (!needDatasourceSelection())
63 m_bHadDataSelection
= false;
67 bool OListComboWizard::approveControl(sal_Int16 _nClassId
)
71 case FormComponentType::LISTBOX
:
73 setTitleBase(compmodule::ModuleRes(RID_STR_LISTWIZARD_TITLE
));
75 case FormComponentType::COMBOBOX
:
77 setTitleBase(compmodule::ModuleRes(RID_STR_COMBOWIZARD_TITLE
));
83 std::unique_ptr
<BuilderPage
> OListComboWizard::createPage(WizardState _nState
)
85 OUString
sIdent(OUString::number(_nState
));
86 weld::Container
* pPageContainer
= m_xAssistant
->append_page(sIdent
);
90 case LCW_STATE_DATASOURCE_SELECTION
:
91 return std::make_unique
<OTableSelectionPage
>(pPageContainer
, this);
92 case LCW_STATE_TABLESELECTION
:
93 return std::make_unique
<OContentTableSelection
>(pPageContainer
, this);
94 case LCW_STATE_FIELDSELECTION
:
95 return std::make_unique
<OContentFieldSelection
>(pPageContainer
, this);
96 case LCW_STATE_FIELDLINK
:
97 return std::make_unique
<OLinkFieldsPage
>(pPageContainer
, this);
98 case LCW_STATE_COMBODBFIELD
:
99 return std::make_unique
<OComboDBFieldPage
>(pPageContainer
, this);
105 vcl::WizardTypes::WizardState
OListComboWizard::determineNextState( WizardState _nCurrentState
) const
107 switch (_nCurrentState
)
109 case LCW_STATE_DATASOURCE_SELECTION
:
110 return LCW_STATE_TABLESELECTION
;
111 case LCW_STATE_TABLESELECTION
:
112 return LCW_STATE_FIELDSELECTION
;
113 case LCW_STATE_FIELDSELECTION
:
114 return getFinalState();
117 return WZS_INVALID_STATE
;
120 void OListComboWizard::enterState(WizardState _nState
)
122 OControlWizard::enterState(_nState
);
124 enableButtons(WizardButtonFlags::PREVIOUS
, m_bHadDataSelection
? (LCW_STATE_DATASOURCE_SELECTION
< _nState
) : LCW_STATE_TABLESELECTION
< _nState
);
125 enableButtons(WizardButtonFlags::NEXT
, getFinalState() != _nState
);
126 if (_nState
< getFinalState())
127 enableButtons(WizardButtonFlags::FINISH
, false);
129 if (getFinalState() == _nState
)
130 defaultButton(WizardButtonFlags::FINISH
);
134 bool OListComboWizard::leaveState(WizardState _nState
)
136 if (!OControlWizard::leaveState(_nState
))
139 if (getFinalState() == _nState
)
140 defaultButton(WizardButtonFlags::NEXT
);
146 void OListComboWizard::implApplySettings()
150 // for quoting identifiers, we need the connection meta data
151 Reference
< XConnection
> xConn
= getFormConnection();
152 DBG_ASSERT(xConn
.is(), "OListComboWizard::implApplySettings: no connection, unable to quote!");
153 Reference
< XDatabaseMetaData
> xMetaData
;
155 xMetaData
= xConn
->getMetaData();
160 OUString sQuoteString
= xMetaData
->getIdentifierQuoteString();
161 if (isListBox()) // only when we have a listbox this should be not empty
162 getSettings().sLinkedListField
= quoteName(sQuoteString
, getSettings().sLinkedListField
);
164 OUString sCatalog
, sSchema
, sName
;
165 ::dbtools::qualifiedNameComponents( xMetaData
, getSettings().sListContentTable
, sCatalog
, sSchema
, sName
, ::dbtools::EComposeRule::InDataManipulation
);
166 getSettings().sListContentTable
= ::dbtools::composeTableNameForSelect( xConn
, sCatalog
, sSchema
, sName
);
168 getSettings().sListContentField
= quoteName(sQuoteString
, getSettings().sListContentField
);
171 // ListSourceType: SQL
172 getContext().xObjectModel
->setPropertyValue(u
"ListSourceType"_ustr
, Any(sal_Int32(ListSourceType_SQL
)));
177 getContext().xObjectModel
->setPropertyValue(u
"BoundColumn"_ustr
, Any(sal_Int16(1)));
179 Sequence
< OUString
> aListSource
{
180 // build the statement to set as list source
182 getSettings().sListContentField
+ ", " + getSettings().sLinkedListField
+
183 " FROM " + getSettings().sListContentTable
)
185 getContext().xObjectModel
->setPropertyValue(u
"ListSource"_ustr
, Any(aListSource
));
189 // build the statement to set as list source
190 OUString sStatement
= "SELECT DISTINCT " +
191 getSettings().sListContentField
+
192 " FROM " + getSettings().sListContentTable
;
193 getContext().xObjectModel
->setPropertyValue( u
"ListSource"_ustr
, Any(sStatement
));
197 getContext().xObjectModel
->setPropertyValue(u
"DataField"_ustr
, Any(getSettings().sLinkedFormField
));
199 catch(const Exception
&)
201 OSL_FAIL("OListComboWizard::implApplySettings: could not set the property values for the listbox!");
206 bool OListComboWizard::onFinish()
208 if ( !OControlWizard::onFinish() )
215 Reference
< XNameAccess
> OLCPage::getTables() const
217 Reference
< XConnection
> xConn
= getFormConnection();
218 DBG_ASSERT(xConn
.is(), "OLCPage::getTables: should have an active connection when reaching this page!");
220 Reference
< XTablesSupplier
> xSuppTables(xConn
, UNO_QUERY
);
221 Reference
< XNameAccess
> xTables
;
222 if (xSuppTables
.is())
223 xTables
= xSuppTables
->getTables();
225 DBG_ASSERT(xTables
.is() || !xConn
.is(), "OLCPage::getTables: got no tables from the connection!");
231 Sequence
< OUString
> OLCPage::getTableFields()
233 Reference
< XNameAccess
> xTables
= getTables();
234 Sequence
< OUString
> aColumnNames
;
239 // the list table as XColumnsSupplier
240 Reference
< XColumnsSupplier
> xSuppCols
;
241 xTables
->getByName(getSettings().sListContentTable
) >>= xSuppCols
;
242 DBG_ASSERT(xSuppCols
.is(), "OLCPage::getTableFields: no columns supplier!");
245 Reference
< XNameAccess
> xColumns
;
247 xColumns
= xSuppCols
->getColumns();
251 aColumnNames
= xColumns
->getElementNames();
253 catch(const Exception
&)
255 TOOLS_WARN_EXCEPTION( "extensions.dbpilots", "OLinkFieldsPage::initializePage: caught an exception while retrieving the columns");
261 OContentTableSelection::OContentTableSelection(weld::Container
* pPage
, OListComboWizard
* pWizard
)
262 : OLCPage(pPage
, pWizard
, u
"modules/sabpilot/ui/contenttablepage.ui"_ustr
, u
"TableSelectionPage"_ustr
)
263 , m_xSelectTable(m_xBuilder
->weld_tree_view(u
"table"_ustr
))
265 enableFormDatasourceDisplay();
267 m_xSelectTable
->connect_row_activated(LINK(this, OContentTableSelection
, OnTableDoubleClicked
));
268 m_xSelectTable
->connect_selection_changed(
269 LINK(this, OContentTableSelection
, OnTableSelected
));
272 OContentTableSelection::~OContentTableSelection()
276 void OContentTableSelection::Activate()
279 m_xSelectTable
->grab_focus();
282 bool OContentTableSelection::canAdvance() const
284 if (!OLCPage::canAdvance())
287 return 0 != m_xSelectTable
->count_selected_rows();
290 IMPL_LINK_NOARG( OContentTableSelection
, OnTableSelected
, weld::TreeView
&, void )
292 updateDialogTravelUI();
295 IMPL_LINK( OContentTableSelection
, OnTableDoubleClicked
, weld::TreeView
&, _rListBox
, bool )
297 if (_rListBox
.count_selected_rows())
298 getDialog()->travelNext();
302 void OContentTableSelection::initializePage()
304 OLCPage::initializePage();
306 // fill the list with the table name
307 m_xSelectTable
->clear();
310 Reference
< XNameAccess
> xTables
= getTables();
311 Sequence
< OUString
> aTableNames
;
313 aTableNames
= xTables
->getElementNames();
314 fillListBox(*m_xSelectTable
, aTableNames
);
316 catch(const Exception
&)
318 OSL_FAIL("OContentTableSelection::initializePage: could not retrieve the table names!");
321 m_xSelectTable
->select_text(getSettings().sListContentTable
);
325 bool OContentTableSelection::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason
)
327 if (!OLCPage::commitPage(_eReason
))
330 OListComboSettings
& rSettings
= getSettings();
331 rSettings
.sListContentTable
= m_xSelectTable
->get_selected_text();
332 if (rSettings
.sListContentTable
.isEmpty() && (::vcl::WizardTypes::eTravelBackward
!= _eReason
))
333 // need to select a table
339 OContentFieldSelection::OContentFieldSelection(weld::Container
* pPage
, OListComboWizard
* pWizard
)
340 : OLCPage(pPage
, pWizard
, u
"modules/sabpilot/ui/contentfieldpage.ui"_ustr
, u
"FieldSelectionPage"_ustr
)
341 , m_xSelectTableField(m_xBuilder
->weld_tree_view(u
"selectfield"_ustr
))
342 , m_xDisplayedField(m_xBuilder
->weld_entry(u
"displayfield"_ustr
))
343 , m_xInfo(m_xBuilder
->weld_label(u
"info"_ustr
))
345 m_xInfo
->set_label(compmodule::ModuleRes( isListBox() ? RID_STR_FIELDINFO_LISTBOX
: RID_STR_FIELDINFO_COMBOBOX
));
346 m_xSelectTableField
->connect_selection_changed(
347 LINK(this, OContentFieldSelection
, OnFieldSelected
));
348 m_xSelectTableField
->connect_row_activated(LINK(this, OContentFieldSelection
, OnTableDoubleClicked
));
351 OContentFieldSelection::~OContentFieldSelection()
355 void OContentFieldSelection::initializePage()
357 OLCPage::initializePage();
359 // fill the list of fields
360 fillListBox(*m_xSelectTableField
, getTableFields());
362 m_xSelectTableField
->select_text(getSettings().sListContentField
);
363 m_xDisplayedField
->set_text(getSettings().sListContentField
);
366 bool OContentFieldSelection::canAdvance() const
368 if (!OLCPage::canAdvance())
371 return 0 != m_xSelectTableField
->count_selected_rows();
374 IMPL_LINK_NOARG( OContentFieldSelection
, OnTableDoubleClicked
, weld::TreeView
&, bool )
376 if (m_xSelectTableField
->count_selected_rows())
377 getDialog()->travelNext();
381 IMPL_LINK_NOARG( OContentFieldSelection
, OnFieldSelected
, weld::TreeView
&, void )
383 updateDialogTravelUI();
384 m_xDisplayedField
->set_text(m_xSelectTableField
->get_selected_text());
387 bool OContentFieldSelection::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason
)
389 if (!OLCPage::commitPage(_eReason
))
392 getSettings().sListContentField
= m_xSelectTableField
->get_selected_text();
397 OLinkFieldsPage::OLinkFieldsPage(weld::Container
* pPage
, OListComboWizard
* pWizard
)
398 : OLCPage(pPage
, pWizard
, u
"modules/sabpilot/ui/fieldlinkpage.ui"_ustr
, u
"FieldLinkPage"_ustr
)
399 , m_xValueListField(m_xBuilder
->weld_combo_box(u
"valuefield"_ustr
))
400 , m_xTableField(m_xBuilder
->weld_combo_box(u
"listtable"_ustr
))
402 m_xValueListField
->connect_changed(LINK(this, OLinkFieldsPage
, OnSelectionModified
));
403 m_xTableField
->connect_changed(LINK(this, OLinkFieldsPage
, OnSelectionModified
));
406 OLinkFieldsPage::~OLinkFieldsPage()
410 void OLinkFieldsPage::Activate()
413 m_xValueListField
->grab_focus();
416 void OLinkFieldsPage::initializePage()
418 OLCPage::initializePage();
420 // fill the value list
421 fillListBox(*m_xValueListField
, getContext().aFieldNames
);
422 // fill the table field list
423 fillListBox(*m_xTableField
, getTableFields());
425 // the initial selections
426 m_xValueListField
->set_entry_text(getSettings().sLinkedFormField
);
427 m_xTableField
->set_entry_text(getSettings().sLinkedListField
);
432 bool OLinkFieldsPage::canAdvance() const
434 // we're on the last page here, no travelNext allowed ...
438 void OLinkFieldsPage::implCheckFinish()
440 bool bInvalidSelection
= (-1 == m_xValueListField
->find_text(m_xValueListField
->get_active_text()));
441 bInvalidSelection
|= (-1 == m_xTableField
->find_text(m_xTableField
->get_active_text()));
442 getDialog()->enableButtons(WizardButtonFlags::FINISH
, !bInvalidSelection
);
445 IMPL_LINK_NOARG(OLinkFieldsPage
, OnSelectionModified
, weld::ComboBox
&, void)
450 bool OLinkFieldsPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason
)
452 if (!OLCPage::commitPage(_eReason
))
455 getSettings().sLinkedFormField
= m_xValueListField
->get_active_text();
456 getSettings().sLinkedListField
= m_xTableField
->get_active_text();
461 OComboDBFieldPage::OComboDBFieldPage(weld::Container
* pPage
, OControlWizard
* pWizard
)
462 : ODBFieldPage(pPage
, pWizard
)
464 setDescriptionText(compmodule::ModuleRes(RID_STR_COMBOWIZ_DBFIELD
));
467 OUString
& OComboDBFieldPage::getDBFieldSetting()
469 return static_cast<OListComboWizard
*>(getDialog())->getSettings().sLinkedFormField
;
472 void OComboDBFieldPage::Activate()
474 ODBFieldPage::Activate();
475 getDialog()->enableButtons(WizardButtonFlags::FINISH
, true);
478 bool OComboDBFieldPage::canAdvance() const
480 // we're on the last page here, no travelNext allowed ...
487 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */