LibreOffice Module extensions (master) 1
listcombowizard.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
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>
30#include <helpids.h>
31#include <osl/diagnose.h>
32
33
34namespace dbp
35{
36
37
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::lang;
40 using namespace ::com::sun::star::beans;
41 using namespace ::com::sun::star::sdbc;
42 using namespace ::com::sun::star::sdbcx;
43 using namespace ::com::sun::star::container;
44 using namespace ::com::sun::star::form;
45 using namespace ::dbtools;
46
48 const Reference< XPropertySet >& _rxObjectModel, const Reference< XComponentContext >& _rxContext )
49 : OControlWizard(_pParent, _rxObjectModel, _rxContext)
50 , m_bListBox(false)
51 , m_bHadDataSelection(true)
52 {
54
56 m_xNextPage->set_help_id(HID_LISTWIZARD_NEXT);
57 m_xCancel->set_help_id(HID_LISTWIZARD_CANCEL);
58 m_xFinish->set_help_id(HID_LISTWIZARD_FINISH);
59
60 // if we do not need the data source selection page ...
62 { // ... skip it!
63 skip();
64 m_bHadDataSelection = false;
65 }
66 }
67
68 bool OListComboWizard::approveControl(sal_Int16 _nClassId)
69 {
70 switch (_nClassId)
71 {
72 case FormComponentType::LISTBOX:
73 m_bListBox = true;
74 setTitleBase(compmodule::ModuleRes(RID_STR_LISTWIZARD_TITLE));
75 return true;
76 case FormComponentType::COMBOBOX:
77 m_bListBox = false;
78 setTitleBase(compmodule::ModuleRes(RID_STR_COMBOWIZARD_TITLE));
79 return true;
80 }
81 return false;
82 }
83
84 std::unique_ptr<BuilderPage> OListComboWizard::createPage(WizardState _nState)
85 {
86 OUString sIdent(OUString::number(_nState));
87 weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
88
89 switch (_nState)
90 {
92 return std::make_unique<OTableSelectionPage>(pPageContainer, this);
94 return std::make_unique<OContentTableSelection>(pPageContainer, this);
96 return std::make_unique<OContentFieldSelection>(pPageContainer, this);
98 return std::make_unique<OLinkFieldsPage>(pPageContainer, this);
100 return std::make_unique<OComboDBFieldPage>(pPageContainer, this);
101 }
102
103 return nullptr;
104 }
105
107 {
108 switch (_nCurrentState)
109 {
115 return getFinalState();
116 }
117
118 return WZS_INVALID_STATE;
119 }
120
122 {
124
125 enableButtons(WizardButtonFlags::PREVIOUS, m_bHadDataSelection ? (LCW_STATE_DATASOURCE_SELECTION < _nState) : LCW_STATE_TABLESELECTION < _nState);
126 enableButtons(WizardButtonFlags::NEXT, getFinalState() != _nState);
127 if (_nState < getFinalState())
128 enableButtons(WizardButtonFlags::FINISH, false);
129
130 if (getFinalState() == _nState)
131 defaultButton(WizardButtonFlags::FINISH);
132 }
133
134
136 {
137 if (!OControlWizard::leaveState(_nState))
138 return false;
139
140 if (getFinalState() == _nState)
141 defaultButton(WizardButtonFlags::NEXT);
142
143 return true;
144 }
145
146
148 {
149 try
150 {
151 // for quoting identifiers, we need the connection meta data
152 Reference< XConnection > xConn = getFormConnection();
153 DBG_ASSERT(xConn.is(), "OListComboWizard::implApplySettings: no connection, unable to quote!");
154 Reference< XDatabaseMetaData > xMetaData;
155 if (xConn.is())
156 xMetaData = xConn->getMetaData();
157
158 // do some quotings
159 if (xMetaData.is())
160 {
161 OUString sQuoteString = xMetaData->getIdentifierQuoteString();
162 if (isListBox()) // only when we have a listbox this should be not empty
163 getSettings().sLinkedListField = quoteName(sQuoteString, getSettings().sLinkedListField);
164
165 OUString sCatalog, sSchema, sName;
166 ::dbtools::qualifiedNameComponents( xMetaData, getSettings().sListContentTable, sCatalog, sSchema, sName, ::dbtools::EComposeRule::InDataManipulation );
167 getSettings().sListContentTable = ::dbtools::composeTableNameForSelect( xConn, sCatalog, sSchema, sName );
168
169 getSettings().sListContentField = quoteName(sQuoteString, getSettings().sListContentField);
170 }
171
172 // ListSourceType: SQL
173 getContext().xObjectModel->setPropertyValue("ListSourceType", Any(sal_Int32(ListSourceType_SQL)));
174
175 if (isListBox())
176 {
177 // BoundColumn: 1
178 getContext().xObjectModel->setPropertyValue("BoundColumn", Any(sal_Int16(1)));
179
180 // build the statement to set as list source
181 OUString sStatement = "SELECT " +
183 " FROM " + getSettings().sListContentTable;
184 Sequence< OUString > aListSource { sStatement };
185 getContext().xObjectModel->setPropertyValue("ListSource", Any(aListSource));
186 }
187 else
188 {
189 // build the statement to set as list source
190 OUString sStatement = "SELECT DISTINCT " +
192 " FROM " + getSettings().sListContentTable;
193 getContext().xObjectModel->setPropertyValue( "ListSource", Any(sStatement));
194 }
195
196 // the bound field
197 getContext().xObjectModel->setPropertyValue("DataField", Any(getSettings().sLinkedFormField));
198 }
199 catch(const Exception&)
200 {
201 OSL_FAIL("OListComboWizard::implApplySettings: could not set the property values for the listbox!");
202 }
203 }
204
205
207 {
209 return false;
210
212 return true;
213 }
214
215 Reference< XNameAccess > OLCPage::getTables() const
216 {
217 Reference< XConnection > xConn = getFormConnection();
218 DBG_ASSERT(xConn.is(), "OLCPage::getTables: should have an active connection when reaching this page!");
219
220 Reference< XTablesSupplier > xSuppTables(xConn, UNO_QUERY);
221 Reference< XNameAccess > xTables;
222 if (xSuppTables.is())
223 xTables = xSuppTables->getTables();
224
225 DBG_ASSERT(xTables.is() || !xConn.is(), "OLCPage::getTables: got no tables from the connection!");
226
227 return xTables;
228 }
229
230
231 Sequence< OUString > OLCPage::getTableFields()
232 {
233 Reference< XNameAccess > xTables = getTables();
234 Sequence< OUString > aColumnNames;
235 if (xTables.is())
236 {
237 try
238 {
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!");
243
244 // the columns
245 Reference< XNameAccess > xColumns;
246 if (xSuppCols.is())
247 xColumns = xSuppCols->getColumns();
248
249 // the column names
250 if (xColumns.is())
251 aColumnNames = xColumns->getElementNames();
252 }
253 catch(const Exception&)
254 {
255 TOOLS_WARN_EXCEPTION( "extensions.dbpilots", "OLinkFieldsPage::initializePage: caught an exception while retrieving the columns");
256 }
257 }
258 return aColumnNames;
259 }
260
262 : OLCPage(pPage, pWizard, "modules/sabpilot/ui/contenttablepage.ui", "TableSelectionPage")
263 , m_xSelectTable(m_xBuilder->weld_tree_view("table"))
264 {
266
267 m_xSelectTable->connect_row_activated(LINK(this, OContentTableSelection, OnTableDoubleClicked));
268 m_xSelectTable->connect_changed(LINK(this, OContentTableSelection, OnTableSelected));
269 }
270
272 {
273 }
274
276 {
278 m_xSelectTable->grab_focus();
279 }
280
282 {
283 if (!OLCPage::canAdvance())
284 return false;
285
286 return 0 != m_xSelectTable->count_selected_rows();
287 }
288
290 {
291 updateDialogTravelUI();
292 }
293
294 IMPL_LINK( OContentTableSelection, OnTableDoubleClicked, weld::TreeView&, _rListBox, bool )
295 {
296 if (_rListBox.count_selected_rows())
297 getDialog()->travelNext();
298 return true;
299 }
300
302 {
304
305 // fill the list with the table name
306 m_xSelectTable->clear();
307 try
308 {
309 Reference< XNameAccess > xTables = getTables();
310 Sequence< OUString > aTableNames;
311 if (xTables.is())
312 aTableNames = xTables->getElementNames();
313 fillListBox(*m_xSelectTable, aTableNames);
314 }
315 catch(const Exception&)
316 {
317 OSL_FAIL("OContentTableSelection::initializePage: could not retrieve the table names!");
318 }
319
320 m_xSelectTable->select_text(getSettings().sListContentTable);
321 }
322
323
325 {
326 if (!OLCPage::commitPage(_eReason))
327 return false;
328
329 OListComboSettings& rSettings = getSettings();
330 rSettings.sListContentTable = m_xSelectTable->get_selected_text();
331 if (rSettings.sListContentTable.isEmpty() && (::vcl::WizardTypes::eTravelBackward != _eReason))
332 // need to select a table
333 return false;
334
335 return true;
336 }
337
339 : OLCPage(pPage, pWizard, "modules/sabpilot/ui/contentfieldpage.ui", "FieldSelectionPage")
340 , m_xSelectTableField(m_xBuilder->weld_tree_view("selectfield"))
341 , m_xDisplayedField(m_xBuilder->weld_entry("displayfield"))
342 , m_xInfo(m_xBuilder->weld_label("info"))
343 {
344 m_xInfo->set_label(compmodule::ModuleRes( isListBox() ? RID_STR_FIELDINFO_LISTBOX : RID_STR_FIELDINFO_COMBOBOX));
345 m_xSelectTableField->connect_changed(LINK(this, OContentFieldSelection, OnFieldSelected));
346 m_xSelectTableField->connect_row_activated(LINK(this, OContentFieldSelection, OnTableDoubleClicked));
347 }
348
350 {
351 }
352
354 {
356
357 // fill the list of fields
359
360 m_xSelectTableField->select_text(getSettings().sListContentField);
361 m_xDisplayedField->set_text(getSettings().sListContentField);
362 }
363
365 {
366 if (!OLCPage::canAdvance())
367 return false;
368
369 return 0 != m_xSelectTableField->count_selected_rows();
370 }
371
373 {
374 if (m_xSelectTableField->count_selected_rows())
375 getDialog()->travelNext();
376 return true;
377 }
378
380 {
381 updateDialogTravelUI();
382 m_xDisplayedField->set_text(m_xSelectTableField->get_selected_text());
383 }
384
386 {
387 if (!OLCPage::commitPage(_eReason))
388 return false;
389
390 getSettings().sListContentField = m_xSelectTableField->get_selected_text();
391
392 return true;
393 }
394
396 : OLCPage(pPage, pWizard, "modules/sabpilot/ui/fieldlinkpage.ui", "FieldLinkPage")
397 , m_xValueListField(m_xBuilder->weld_combo_box("valuefield"))
398 , m_xTableField(m_xBuilder->weld_combo_box("listtable"))
399 {
400 m_xValueListField->connect_changed(LINK(this, OLinkFieldsPage, OnSelectionModified));
401 m_xTableField->connect_changed(LINK(this, OLinkFieldsPage, OnSelectionModified));
402 }
403
405 {
406 }
407
409 {
411 m_xValueListField->grab_focus();
412 }
413
415 {
417
418 // fill the value list
420 // fill the table field list
422
423 // the initial selections
424 m_xValueListField->set_entry_text(getSettings().sLinkedFormField);
425 m_xTableField->set_entry_text(getSettings().sLinkedListField);
426
428 }
429
431 {
432 // we're on the last page here, no travelNext allowed ...
433 return false;
434 }
435
437 {
438 bool bInvalidSelection = (-1 == m_xValueListField->find_text(m_xValueListField->get_active_text()));
439 bInvalidSelection |= (-1 == m_xTableField->find_text(m_xTableField->get_active_text()));
440 getDialog()->enableButtons(WizardButtonFlags::FINISH, !bInvalidSelection);
441 }
442
443 IMPL_LINK_NOARG(OLinkFieldsPage, OnSelectionModified, weld::ComboBox&, void)
444 {
445 implCheckFinish();
446 }
447
449 {
450 if (!OLCPage::commitPage(_eReason))
451 return false;
452
453 getSettings().sLinkedFormField = m_xValueListField->get_active_text();
454 getSettings().sLinkedListField = m_xTableField->get_active_text();
455
456 return true;
457 }
458
460 : ODBFieldPage(pPage, pWizard)
461 {
462 setDescriptionText(compmodule::ModuleRes(RID_STR_COMBOWIZ_DBFIELD));
463 }
464
466 {
467 return static_cast<OListComboWizard*>(getDialog())->getSettings().sLinkedFormField;
468 }
469
471 {
473 getDialog()->enableButtons(WizardButtonFlags::FINISH, true);
474 }
475
477 {
478 // we're on the last page here, no travelNext allowed ...
479 return false;
480 }
481
482} // namespace dbp
483
484
485/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sSchema
OptionalString sCatalog
const char *const aFieldNames[]
virtual OUString & getDBFieldSetting() override
virtual bool canAdvance() const override
virtual void Activate() override
OComboDBFieldPage(weld::Container *pPage, OControlWizard *pWizard)
std::unique_ptr< weld::Label > m_xInfo
virtual bool commitPage(::vcl::WizardTypes::CommitPageReason _eReason) override
std::unique_ptr< weld::TreeView > m_xSelectTableField
virtual void initializePage() override
OContentFieldSelection(weld::Container *pPage, OListComboWizard *pWizard)
virtual bool canAdvance() const override
std::unique_ptr< weld::Entry > m_xDisplayedField
virtual ~OContentFieldSelection() override
virtual void Activate() override
virtual bool canAdvance() const override
virtual void initializePage() override
virtual bool commitPage(::vcl::WizardTypes::CommitPageReason _eReason) override
OContentTableSelection(weld::Container *pPage, OListComboWizard *pWizard)
virtual ~OContentTableSelection() override
std::unique_ptr< weld::TreeView > m_xSelectTable
OControlWizard * getDialog()
css::uno::Reference< css::sdbc::XConnection > getFormConnection() const
virtual void initializePage() override
const OControlWizardContext & getContext() const
static void fillListBox(weld::TreeView &_rList, const css::uno::Sequence< OUString > &_rItems)
void initControlSettings(OControlWizardSettings *_pSettings)
css::uno::Reference< css::sdbc::XConnection > getFormConnection() const
const OControlWizardContext & getContext() const
void setDescriptionText(const OUString &rDesc)
css::uno::Reference< css::container::XNameAccess > getTables() const
OListComboSettings & getSettings()
css::uno::Sequence< OUString > getTableFields()
virtual bool canAdvance() const override
virtual void initializePage() override
std::unique_ptr< weld::ComboBox > m_xTableField
virtual bool commitPage(::vcl::WizardTypes::CommitPageReason _eReason) override
OLinkFieldsPage(weld::Container *pPage, OListComboWizard *pWizard)
virtual ~OLinkFieldsPage() override
std::unique_ptr< weld::ComboBox > m_xValueListField
virtual void Activate() override
virtual bool approveControl(sal_Int16 _nClassId) override
OListComboSettings m_aSettings
virtual bool onFinish() override
virtual void enterState(WizardState _nState) override
virtual bool leaveState(WizardState _nState) override
OListComboWizard(weld::Window *pParent, const css::uno::Reference< css::beans::XPropertySet > &_rxObjectModel, const css::uno::Reference< css::uno::XComponentContext > &_rxContext)
virtual WizardState determineNextState(WizardState _nCurrentState) const override
WizardState getFinalState() const
virtual std::unique_ptr< BuilderPage > createPage(WizardState _nState) override
OListComboSettings & getSettings()
virtual bool canAdvance() const override
virtual bool commitPage(WizardTypes::CommitPageReason _eReason) override
virtual void Activate() override
virtual bool leaveState(WizardTypes::WizardState nState)
std::unique_ptr< weld::Button > m_xNextPage
std::unique_ptr< weld::Button > m_xCancel
virtual bool onFinish()
void defaultButton(WizardButtonFlags _nWizardButtonFlags)
std::unique_ptr< weld::Button > m_xPrevPage
void enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable)
std::unique_ptr< weld::Button > m_xFinish
virtual void enterState(WizardTypes::WizardState _nState)
void setTitleBase(const OUString &_rTitleBase)
std::unique_ptr< weld::Assistant > m_xAssistant
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
Reference< beans::XPropertySetInfo > m_xInfo
OUString sName
constexpr OUStringLiteral HID_LISTWIZARD_NEXT
Definition: helpids.h:71
constexpr OUStringLiteral HID_LISTWIZARD_PREVIOUS
Definition: helpids.h:70
constexpr OUStringLiteral HID_LISTWIZARD_CANCEL
Definition: helpids.h:72
constexpr OUStringLiteral HID_LISTWIZARD_FINISH
Definition: helpids.h:73
#define LCW_STATE_COMBODBFIELD
#define LCW_STATE_FIELDLINK
#define LCW_STATE_TABLESELECTION
#define LCW_STATE_FIELDSELECTION
#define LCW_STATE_DATASOURCE_SELECTION
@ Exception
OUString ModuleRes(TranslateId pId)
IMPL_LINK_NOARG(OTableSelectionPage, OnSearchClicked, weld::Button &, void)
IMPL_LINK(OTableSelectionPage, OnListboxDoubleClicked, weld::TreeView &, _rBox, bool)
OUString quoteName(std::u16string_view _rQuote, const OUString &_rName)
sal_Int16 WizardState
css::uno::Reference< css::beans::XPropertySet > xObjectModel
#define WZS_INVALID_STATE