summaryrefslogtreecommitdiffstats
path: root/extensions/source/dbpilots
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /extensions/source/dbpilots
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'extensions/source/dbpilots')
-rw-r--r--extensions/source/dbpilots/commonpagesdbp.cxx447
-rw-r--r--extensions/source/dbpilots/commonpagesdbp.hxx123
-rw-r--r--extensions/source/dbpilots/controlwizard.cxx663
-rw-r--r--extensions/source/dbpilots/controlwizard.hxx151
-rw-r--r--extensions/source/dbpilots/dbp.component31
-rw-r--r--extensions/source/dbpilots/dbpservices.cxx65
-rw-r--r--extensions/source/dbpilots/dbpservices.hxx34
-rw-r--r--extensions/source/dbpilots/dbptools.cxx62
-rw-r--r--extensions/source/dbpilots/dbptools.hxx40
-rw-r--r--extensions/source/dbpilots/dbptypes.hxx43
-rw-r--r--extensions/source/dbpilots/gridwizard.cxx446
-rw-r--r--extensions/source/dbpilots/gridwizard.hxx106
-rw-r--r--extensions/source/dbpilots/groupboxwiz.cxx463
-rw-r--r--extensions/source/dbpilots/groupboxwiz.hxx183
-rw-r--r--extensions/source/dbpilots/listcombowizard.cxx485
-rw-r--r--extensions/source/dbpilots/listcombowizard.hxx181
-rw-r--r--extensions/source/dbpilots/moduledbp.cxx22
-rw-r--r--extensions/source/dbpilots/optiongrouplayouter.cxx203
-rw-r--r--extensions/source/dbpilots/optiongrouplayouter.hxx61
-rw-r--r--extensions/source/dbpilots/unoautopilot.hxx131
-rw-r--r--extensions/source/dbpilots/wizardcontext.hxx85
-rw-r--r--extensions/source/dbpilots/wizardservices.cxx98
-rw-r--r--extensions/source/dbpilots/wizardservices.hxx63
23 files changed, 4186 insertions, 0 deletions
diff --git a/extensions/source/dbpilots/commonpagesdbp.cxx b/extensions/source/dbpilots/commonpagesdbp.cxx
new file mode 100644
index 000000000..883f1a785
--- /dev/null
+++ b/extensions/source/dbpilots/commonpagesdbp.cxx
@@ -0,0 +1,447 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "commonpagesdbp.hxx"
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <componentmodule.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/interaction.hxx>
+#include <connectivity/dbtools.hxx>
+#include <sfx2/docfilt.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <svl/filenotation.hxx>
+#include <osl/diagnose.h>
+
+namespace dbp
+{
+
+
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::task;
+ using namespace ::comphelper;
+
+ OTableSelectionPage::OTableSelectionPage(weld::Container* pPage, OControlWizard* pWizard)
+ : OControlWizardPage(pPage, pWizard, "modules/sabpilot/ui/tableselectionpage.ui", "TableSelectionPage")
+ , m_xTable(m_xBuilder->weld_tree_view("table"))
+ , m_xDatasource(m_xBuilder->weld_tree_view("datasource"))
+ , m_xDatasourceLabel(m_xBuilder->weld_label("datasourcelabel"))
+ , m_xSearchDatabase(m_xBuilder->weld_button("search"))
+ , m_xSourceBox(m_xBuilder->weld_container("sourcebox"))
+ {
+ try
+ {
+ m_xDSContext = getContext().xDatasourceContext;
+ if (m_xDSContext.is())
+ fillListBox(*m_xDatasource, m_xDSContext->getElementNames());
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("OTableSelectionPage::OTableSelectionPage: could not collect the data source names!");
+ }
+
+ m_xDatasource->connect_changed(LINK(this, OTableSelectionPage, OnListboxSelection));
+ m_xTable->connect_changed(LINK(this, OTableSelectionPage, OnListboxSelection));
+ m_xTable->connect_row_activated(LINK(this, OTableSelectionPage, OnListboxDoubleClicked));
+ m_xSearchDatabase->connect_clicked(LINK(this, OTableSelectionPage, OnSearchClicked));
+ }
+
+ OTableSelectionPage::~OTableSelectionPage()
+ {
+ }
+
+ void OTableSelectionPage::Activate()
+ {
+ OControlWizardPage::Activate();
+ m_xDatasource->grab_focus();
+ }
+
+ bool OTableSelectionPage::canAdvance() const
+ {
+ if (!OControlWizardPage::canAdvance())
+ return false;
+
+ if (0 == m_xDatasource->count_selected_rows())
+ return false;
+
+ if (0 == m_xTable->count_selected_rows())
+ return false;
+
+ return true;
+ }
+
+ void OTableSelectionPage::initializePage()
+ {
+ OControlWizardPage::initializePage();
+
+ const OControlWizardContext& rContext = getContext();
+ try
+ {
+ OUString sDataSourceName;
+ rContext.xForm->getPropertyValue("DataSourceName") >>= sDataSourceName;
+
+ Reference< XConnection > xConnection;
+ bool bEmbedded = ::dbtools::isEmbeddedInDatabase( rContext.xForm, xConnection );
+ if ( bEmbedded )
+ {
+ m_xSourceBox->hide();
+ m_xDatasource->append_text(sDataSourceName);
+ }
+ m_xDatasource->select_text(sDataSourceName);
+
+ implFillTables(xConnection);
+
+ OUString sCommand;
+ OSL_VERIFY( rContext.xForm->getPropertyValue("Command") >>= sCommand );
+ sal_Int32 nCommandType = CommandType::TABLE;
+ OSL_VERIFY( rContext.xForm->getPropertyValue("CommandType") >>= nCommandType );
+
+ // search the entry of the given type with the given name
+ for (sal_Int32 nLookup = 0; nLookup < m_xTable->n_children(); ++nLookup)
+ {
+ if (sCommand == m_xTable->get_text(nLookup))
+ {
+ if (m_xTable->get_id(nLookup).toInt32() == nCommandType)
+ {
+ m_xTable->select( nLookup );
+ break;
+ }
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.abpilot", "OTableSelectionPage::initializePage");
+ }
+ }
+
+ bool OTableSelectionPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!OControlWizardPage::commitPage(_eReason))
+ return false;
+
+ const OControlWizardContext& rContext = getContext();
+ try
+ {
+ Reference< XConnection > xOldConn;
+ if ( !rContext.bEmbedded )
+ {
+ xOldConn = getFormConnection();
+
+ OUString sDataSource = m_xDatasource->get_selected_text();
+ rContext.xForm->setPropertyValue("DataSourceName", makeAny( sDataSource ) );
+ }
+ OUString sCommand = m_xTable->get_selected_text();
+ sal_Int32 nCommandType = m_xTable->get_selected_id().toInt32();
+
+ rContext.xForm->setPropertyValue("Command", makeAny( sCommand ) );
+ rContext.xForm->setPropertyValue("CommandType", makeAny( nCommandType ) );
+
+ if ( !rContext.bEmbedded )
+ setFormConnection( xOldConn, false );
+
+ if (!updateContext())
+ return false;
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.dbpilots", "OTableSelectionPage::commitPage");
+ }
+
+ return true;
+ }
+
+ IMPL_LINK_NOARG( OTableSelectionPage, OnSearchClicked, weld::Button&, void )
+ {
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
+ FileDialogFlags::NONE, getDialog()->getDialog());
+ aFileDlg.SetDisplayDirectory( SvtPathOptions().GetWorkPath() );
+
+ std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetFilterByName("StarOffice XML (Base)");
+ OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
+ if ( pFilter )
+ {
+ aFileDlg.AddFilter(pFilter->GetUIName(),pFilter->GetDefaultExtension());
+ }
+
+ if (ERRCODE_NONE == aFileDlg.Execute())
+ {
+ OUString sDataSourceName = aFileDlg.GetPath();
+ ::svt::OFileNotation aFileNotation(sDataSourceName);
+ sDataSourceName = aFileNotation.get(::svt::OFileNotation::N_SYSTEM);
+ m_xDatasource->append_text(sDataSourceName);
+ m_xDatasource->select_text(sDataSourceName);
+ LINK(this, OTableSelectionPage, OnListboxSelection).Call(*m_xDatasource);
+ }
+ }
+
+ IMPL_LINK(OTableSelectionPage, OnListboxDoubleClicked, weld::TreeView&, _rBox, bool)
+ {
+ if (_rBox.count_selected_rows())
+ getDialog()->travelNext();
+ return true;
+ }
+
+ IMPL_LINK(OTableSelectionPage, OnListboxSelection, weld::TreeView&, _rBox, void)
+ {
+ if (m_xDatasource.get() == &_rBox)
+ { // new data source selected
+ implFillTables();
+ }
+
+ updateDialogTravelUI();
+ }
+
+ namespace
+ {
+ void lcl_fillEntries(weld::TreeView& rListBox, const Sequence<OUString>& rNames, const OUString& rImage, sal_Int32 nCommandType)
+ {
+ for (auto const & name : rNames)
+ {
+ rListBox.append(OUString::number(nCommandType), name, rImage);
+ }
+ }
+ }
+
+ void OTableSelectionPage::implFillTables(const Reference< XConnection >& _rxConn)
+ {
+ m_xTable->clear();
+
+ weld::WaitObject aWaitCursor(getDialog()->getDialog());
+
+ // will be the table tables of the selected data source
+ Sequence< OUString > aTableNames;
+ Sequence< OUString > aQueryNames;
+
+ // connect to the data source
+ Any aSQLException;
+ Reference< XConnection > xConn = _rxConn;
+ if ( !xConn.is() )
+ {
+ if (!m_xDSContext.is())
+ return;
+ // connect to the data source
+ try
+ {
+ OUString sCurrentDatasource = m_xDatasource->get_selected_text();
+ if (!sCurrentDatasource.isEmpty())
+ {
+ // obtain the DS object
+ Reference< XCompletedConnection > xDatasource;
+ // check if I know this one otherwise transform it into a file URL
+ if ( !m_xDSContext->hasByName(sCurrentDatasource) )
+ {
+ ::svt::OFileNotation aFileNotation(sCurrentDatasource);
+ sCurrentDatasource = aFileNotation.get(::svt::OFileNotation::N_URL);
+ }
+
+ if (m_xDSContext->getByName(sCurrentDatasource) >>= xDatasource)
+ { // connect
+ // get the default SDB interaction handler
+ Reference< XInteractionHandler > xHandler = getDialog()->getInteractionHandler(getDialog()->getDialog());
+ if (!xHandler.is() )
+ return;
+ xConn = xDatasource->connectWithCompletion(xHandler);
+ setFormConnection( xConn );
+ }
+ else
+ {
+ OSL_FAIL("OTableSelectionPage::implFillTables: invalid data source object returned by the context");
+ }
+ }
+ }
+ catch(const SQLContext& e) { aSQLException <<= e; }
+ catch(const SQLWarning& e) { aSQLException <<= e; }
+ catch(const SQLException& e) { aSQLException <<= e; }
+ catch (const Exception&)
+ {
+ OSL_FAIL("OTableSelectionPage::implFillTables: could not fill the table list!");
+ }
+ }
+
+ // will be the table tables of the selected data source
+ if ( xConn.is() )
+ {
+ try
+ {
+ // get the tables
+ Reference< XTablesSupplier > xSupplTables(xConn, UNO_QUERY);
+ if ( xSupplTables.is() )
+ {
+ Reference< XNameAccess > xTables = xSupplTables->getTables();
+ if (xTables.is())
+ aTableNames = xTables->getElementNames();
+ }
+
+ // and the queries
+ Reference< XQueriesSupplier > xSuppQueries( xConn, UNO_QUERY );
+ if ( xSuppQueries.is() )
+ {
+ Reference< XNameAccess > xQueries = xSuppQueries->getQueries();
+ if ( xQueries.is() )
+ aQueryNames = xQueries->getElementNames();
+ }
+ }
+ catch(const SQLContext& e) { aSQLException <<= e; }
+ catch(const SQLWarning& e) { aSQLException <<= e; }
+ catch(const SQLException& e) { aSQLException <<= e; }
+ catch (const Exception&)
+ {
+ OSL_FAIL("OTableSelectionPage::implFillTables: could not fill the table list!");
+ }
+ }
+
+
+ if ( aSQLException.hasValue() )
+ { // an SQLException (or derivee) was thrown ...
+ Reference< XInteractionRequest > xRequest = new OInteractionRequest(aSQLException);
+ try
+ {
+ // get the default SDB interaction handler
+ Reference< XInteractionHandler > xHandler = getDialog()->getInteractionHandler(getDialog()->getDialog());
+ if ( xHandler.is() )
+ xHandler->handle(xRequest);
+ }
+ catch(const Exception&) { }
+ return;
+ }
+
+ lcl_fillEntries(*m_xTable, aTableNames, BMP_TABLE, CommandType::TABLE);
+ lcl_fillEntries(*m_xTable, aQueryNames, BMP_QUERY, CommandType::QUERY);
+ }
+
+ OMaybeListSelectionPage::OMaybeListSelectionPage(weld::Container* pPage, OControlWizard* pWizard, const OUString& rUIXMLDescription, const OString& rID)
+ : OControlWizardPage(pPage, pWizard, rUIXMLDescription, rID)
+ , m_pYes(nullptr)
+ , m_pNo(nullptr)
+ , m_pList(nullptr)
+ {
+ }
+
+ OMaybeListSelectionPage::~OMaybeListSelectionPage()
+ {
+ }
+
+ void OMaybeListSelectionPage::announceControls(weld::RadioButton& _rYesButton, weld::RadioButton& _rNoButton, weld::ComboBox& _rSelection)
+ {
+ m_pYes = &_rYesButton;
+ m_pNo = &_rNoButton;
+ m_pList = &_rSelection;
+
+ m_pYes->connect_clicked(LINK(this, OMaybeListSelectionPage, OnRadioSelected));
+ m_pNo->connect_clicked(LINK(this, OMaybeListSelectionPage, OnRadioSelected));
+ implEnableWindows();
+ }
+
+ IMPL_LINK_NOARG( OMaybeListSelectionPage, OnRadioSelected, weld::Button&, void )
+ {
+ implEnableWindows();
+ }
+
+ void OMaybeListSelectionPage::implInitialize(const OUString& _rSelection)
+ {
+ DBG_ASSERT(m_pYes, "OMaybeListSelectionPage::implInitialize: no controls announced!");
+ bool bIsSelection = ! _rSelection.isEmpty();
+ m_pYes->set_active(bIsSelection);
+ m_pNo->set_active(!bIsSelection);
+ m_pList->set_sensitive(bIsSelection);
+
+ m_pList->set_active_text(bIsSelection ? _rSelection : OUString());
+ }
+
+ void OMaybeListSelectionPage::implCommit(OUString& _rSelection)
+ {
+ _rSelection = m_pYes->get_active() ? m_pList->get_active_text() : OUString();
+ }
+
+ void OMaybeListSelectionPage::implEnableWindows()
+ {
+ m_pList->set_sensitive(m_pYes->get_active());
+ }
+
+ void OMaybeListSelectionPage::Activate()
+ {
+ OControlWizardPage::Activate();
+
+ DBG_ASSERT(m_pYes, "OMaybeListSelectionPage::Activate: no controls announced!");
+ if (m_pYes->get_active())
+ m_pList->grab_focus();
+ else
+ m_pNo->grab_focus();
+ }
+
+ ODBFieldPage::ODBFieldPage(weld::Container* pPage, OControlWizard* pWizard)
+ : OMaybeListSelectionPage(pPage, pWizard, "modules/sabpilot/ui/optiondbfieldpage.ui", "OptionDBField")
+ , m_xDescription(m_xBuilder->weld_label("explLabel"))
+ , m_xStoreYes(m_xBuilder->weld_radio_button("yesRadiobutton"))
+ , m_xStoreNo(m_xBuilder->weld_radio_button("noRadiobutton"))
+ , m_xStoreWhere(m_xBuilder->weld_combo_box("storeInFieldCombobox"))
+ {
+ SetPageTitle(compmodule::ModuleRes(RID_STR_OPTION_DB_FIELD_TITLE));
+
+ announceControls(*m_xStoreYes, *m_xStoreNo, *m_xStoreWhere);
+ }
+
+ ODBFieldPage::~ODBFieldPage()
+ {
+ }
+
+ void ODBFieldPage::initializePage()
+ {
+ OMaybeListSelectionPage::initializePage();
+
+ // fill the fields page
+ fillListBox(*m_xStoreWhere, getContext().aFieldNames);
+
+ implInitialize(getDBFieldSetting());
+ }
+
+ bool ODBFieldPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!OMaybeListSelectionPage::commitPage(_eReason))
+ return false;
+
+ implCommit(getDBFieldSetting());
+
+ return true;
+ }
+
+
+} // namespace dbp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/commonpagesdbp.hxx b/extensions/source/dbpilots/commonpagesdbp.hxx
new file mode 100644
index 000000000..5d93b9301
--- /dev/null
+++ b/extensions/source/dbpilots/commonpagesdbp.hxx
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_COMMONPAGESDBP_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_COMMONPAGESDBP_HXX
+
+#include "controlwizard.hxx"
+#include <vcl/weld.hxx>
+#include <com/sun/star/sdb/XDatabaseContext.hpp>
+
+namespace dbp
+{
+ class OTableSelectionPage final : public OControlWizardPage
+ {
+ std::unique_ptr<weld::TreeView> m_xTable;
+ std::unique_ptr<weld::TreeView> m_xDatasource;
+ std::unique_ptr<weld::Label> m_xDatasourceLabel;
+ std::unique_ptr<weld::Button> m_xSearchDatabase;
+ std::unique_ptr<weld::Container> m_xSourceBox;
+
+ css::uno::Reference< css::sdb::XDatabaseContext >
+ m_xDSContext;
+
+ public:
+ explicit OTableSelectionPage(weld::Container* pPage, OControlWizard* pParent);
+ virtual ~OTableSelectionPage() override;
+
+ private:
+ // BuilderPage overridables
+ void Activate() override;
+
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+
+ DECL_LINK( OnListboxSelection, weld::TreeView&, void );
+ DECL_LINK( OnListboxDoubleClicked, weld::TreeView&, bool );
+ DECL_LINK( OnSearchClicked, weld::Button&, void );
+
+ void implFillTables(const css::uno::Reference< css::sdbc::XConnection >&
+ _rxConn = css::uno::Reference< css::sdbc::XConnection >());
+
+ // OControlWizardPage overridables
+ virtual bool canAdvance() const override;
+ };
+
+ class OMaybeListSelectionPage : public OControlWizardPage
+ {
+ weld::RadioButton* m_pYes;
+ weld::RadioButton* m_pNo;
+ weld::ComboBox* m_pList;
+
+ public:
+ OMaybeListSelectionPage(weld::Container* pPage, OControlWizard* pWizard, const OUString& rUIXMLDescription, const OString& rID);
+ virtual ~OMaybeListSelectionPage() override;
+
+ protected:
+ DECL_LINK( OnRadioSelected, weld::Button&, void );
+
+ // BuilderPage overridables
+ void Activate() override;
+
+ // own helper
+ void announceControls(
+ weld::RadioButton& _rYesButton,
+ weld::RadioButton& _rNoButton,
+ weld::ComboBox& _rSelection);
+
+ void implEnableWindows();
+
+ void implInitialize(const OUString& _rSelection);
+ void implCommit(OUString& _rSelection);
+ };
+
+ class ODBFieldPage : public OMaybeListSelectionPage
+ {
+ protected:
+ std::unique_ptr<weld::Label> m_xDescription;
+ std::unique_ptr<weld::RadioButton> m_xStoreYes;
+ std::unique_ptr<weld::RadioButton> m_xStoreNo;
+ std::unique_ptr<weld::ComboBox> m_xStoreWhere;
+
+ public:
+ explicit ODBFieldPage(weld::Container* pPage, OControlWizard* pWizard);
+ virtual ~ODBFieldPage() override;
+
+ protected:
+ void setDescriptionText(const OUString& rDesc)
+ {
+ m_xDescription->set_label(rDesc);
+ }
+
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+
+ // own overridables
+ virtual OUString& getDBFieldSetting() = 0;
+ };
+
+
+} // namespace dbp
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_COMMONPAGESDBP_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/controlwizard.cxx b/extensions/source/dbpilots/controlwizard.cxx
new file mode 100644
index 000000000..18b3c9489
--- /dev/null
+++ b/extensions/source/dbpilots/controlwizard.cxx
@@ -0,0 +1,663 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "controlwizard.hxx"
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/sdbc/XPreparedStatement.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <comphelper/interaction.hxx>
+#include <vcl/stdtext.hxx>
+#include <connectivity/conncleanup.hxx>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <tools/urlobj.hxx>
+#include <osl/diagnose.h>
+
+#define WIZARD_SIZE_X 60
+#define WIZARD_SIZE_Y 23
+
+namespace dbp
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::drawing;
+ using namespace ::com::sun::star::frame;
+ using namespace ::com::sun::star::sheet;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::task;
+ using namespace ::comphelper;
+ using namespace ::dbtools;
+
+ struct OAccessRegulator
+ {
+ friend class OControlWizardPage;
+
+ protected:
+ OAccessRegulator() { }
+ };
+
+ OControlWizardPage::OControlWizardPage(weld::Container* pPage, OControlWizard* pWizard, const OUString& rUIXMLDescription, const OString& rID)
+ : OControlWizardPage_Base(pPage, pWizard, rUIXMLDescription, rID)
+ , m_pDialog(pWizard)
+ {
+ m_xContainer->set_size_request(m_xContainer->get_approximate_digit_width() * WIZARD_SIZE_X,
+ m_xContainer->get_text_height() * WIZARD_SIZE_Y);
+ }
+
+ OControlWizardPage::~OControlWizardPage()
+ {
+ }
+
+ OControlWizard* OControlWizardPage::getDialog()
+ {
+ return m_pDialog;
+ }
+
+ const OControlWizard* OControlWizardPage::getDialog() const
+ {
+ return m_pDialog;
+ }
+
+ bool OControlWizardPage::updateContext()
+ {
+ return m_pDialog->updateContext(OAccessRegulator());
+ }
+
+ Reference< XConnection > OControlWizardPage::getFormConnection() const
+ {
+ return m_pDialog->getFormConnection(OAccessRegulator());
+ }
+
+ void OControlWizardPage::setFormConnection( const Reference< XConnection >& _rxConn, bool _bAutoDispose )
+ {
+ m_pDialog->setFormConnection( OAccessRegulator(), _rxConn, _bAutoDispose );
+ }
+
+ const OControlWizardContext& OControlWizardPage::getContext() const
+ {
+ return m_pDialog->getContext();
+ }
+
+ void OControlWizardPage::fillListBox(weld::TreeView& _rList, const Sequence< OUString >& _rItems)
+ {
+ _rList.clear();
+ const OUString* pItems = _rItems.getConstArray();
+ const OUString* pEnd = pItems + _rItems.getLength();
+ sal_Int32 nIndex = 0;
+ for (;pItems < pEnd; ++pItems, ++nIndex)
+ {
+ _rList.append(OUString::number(nIndex), *pItems);
+ }
+ }
+
+ void OControlWizardPage::fillListBox(weld::ComboBox& _rList, const Sequence< OUString >& _rItems)
+ {
+ _rList.clear();
+ const OUString* pItems = _rItems.getConstArray();
+ const OUString* pEnd = pItems + _rItems.getLength();
+ for (;pItems < pEnd; ++pItems)
+ {
+ _rList.append_text(*pItems);
+ }
+ }
+
+ void OControlWizardPage::enableFormDatasourceDisplay()
+ {
+ if (m_xFormContentType)
+ // nothing to do
+ return;
+
+ m_xFrame = m_xBuilder->weld_frame("sourceframe");
+ m_xFrame->show();
+ m_xFormContentType = m_xBuilder->weld_label("contenttype");
+ m_xFormContentTypeLabel = m_xBuilder->weld_label("contenttypelabel");
+ m_xFormDatasource = m_xBuilder->weld_label("datasource");
+ m_xFormDatasourceLabel = m_xBuilder->weld_label("datasourcelabel");
+ m_xFormTable = m_xBuilder->weld_label("formtable");
+ m_xFormTableLabel = m_xBuilder->weld_label("formtablelabel");
+
+ const OControlWizardContext& rContext = getContext();
+ if ( rContext.bEmbedded )
+ {
+ m_xFormDatasourceLabel->hide();
+ m_xFormDatasource->hide();
+ }
+ }
+
+ void OControlWizardPage::initializePage()
+ {
+ if (m_xFormDatasource && m_xFormContentTypeLabel && m_xFormTable)
+ {
+ const OControlWizardContext& rContext = getContext();
+ OUString sDataSource;
+ OUString sCommand;
+ sal_Int32 nCommandType = CommandType::COMMAND;
+ try
+ {
+ rContext.xForm->getPropertyValue("DataSourceName") >>= sDataSource;
+ rContext.xForm->getPropertyValue("Command") >>= sCommand;
+ rContext.xForm->getPropertyValue("CommandType") >>= nCommandType;
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.dbpilots", "OControlWizardPage::initializePage");
+ }
+
+ INetURLObject aURL( sDataSource );
+ if( aURL.GetProtocol() != INetProtocol::NotValid )
+ sDataSource = aURL.GetLastName(INetURLObject::DecodeMechanism::WithCharset);
+ m_xFormDatasource->set_label(sDataSource);
+ m_xFormTable->set_label(sCommand);
+
+ const char* pCommandTypeResourceId = nullptr;
+ switch (nCommandType)
+ {
+ case CommandType::TABLE:
+ pCommandTypeResourceId = RID_STR_TYPE_TABLE;
+ break;
+
+ case CommandType::QUERY:
+ pCommandTypeResourceId = RID_STR_TYPE_QUERY;
+ break;
+
+ default:
+ pCommandTypeResourceId = RID_STR_TYPE_COMMAND;
+ break;
+ }
+ m_xFormContentType->set_label(compmodule::ModuleRes(pCommandTypeResourceId));
+ }
+
+ OControlWizardPage_Base::initializePage();
+ }
+
+ OControlWizard::OControlWizard(weld::Window* _pParent,
+ const Reference< XPropertySet >& _rxObjectModel, const Reference< XComponentContext >& _rxContext )
+ : WizardMachine(_pParent, WizardButtonFlags::CANCEL | WizardButtonFlags::PREVIOUS | WizardButtonFlags::NEXT | WizardButtonFlags::FINISH)
+ , m_xContext(_rxContext)
+ {
+ m_aContext.xObjectModel = _rxObjectModel;
+ initContext();
+
+ defaultButton(WizardButtonFlags::NEXT);
+ enableButtons(WizardButtonFlags::FINISH, false);
+ }
+
+ OControlWizard::~OControlWizard()
+ {
+ }
+
+ short OControlWizard::run()
+ {
+ // get the class id of the control we're dealing with
+ sal_Int16 nClassId = FormComponentType::CONTROL;
+ try
+ {
+ getContext().xObjectModel->getPropertyValue("ClassId") >>= nClassId;
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("OControlWizard::activate: could not obtain the class id!");
+ }
+ if (!approveControl(nClassId))
+ {
+ // TODO: MessageBox or exception
+ return RET_CANCEL;
+ }
+
+ ActivatePage();
+
+ m_xAssistant->set_current_page(0);
+
+ return OControlWizard_Base::run();
+ }
+
+ void OControlWizard::implDetermineShape()
+ {
+ Reference< XIndexAccess > xPageObjects = m_aContext.xDrawPage;
+ DBG_ASSERT(xPageObjects.is(), "OControlWizard::implDetermineShape: invalid page!");
+
+ // for comparing the model
+ Reference< XControlModel > xModelCompare(m_aContext.xObjectModel, UNO_QUERY);
+
+ if (!xPageObjects.is())
+ return;
+
+ // loop through all objects of the page
+ sal_Int32 nObjects = xPageObjects->getCount();
+ Reference< XControlShape > xControlShape;
+ Reference< XControlModel > xControlModel;
+ for (sal_Int32 i=0; i<nObjects; ++i)
+ {
+ if (xPageObjects->getByIndex(i) >>= xControlShape)
+ { // it _is_ a control shape
+ xControlModel = xControlShape->getControl();
+ DBG_ASSERT(xControlModel.is(), "OControlWizard::implDetermineShape: control shape without model!");
+ if (xModelCompare.get() == xControlModel.get())
+ {
+ m_aContext.xObjectShape = xControlShape;
+ break;
+ }
+ }
+ }
+ }
+
+
+ void OControlWizard::implDetermineForm()
+ {
+ Reference< XChild > xModelAsChild(m_aContext.xObjectModel, UNO_QUERY);
+ Reference< XInterface > xControlParent;
+ if (xModelAsChild.is())
+ xControlParent = xModelAsChild->getParent();
+
+ m_aContext.xForm.set(xControlParent, UNO_QUERY);
+ m_aContext.xRowSet.set(xControlParent, UNO_QUERY);
+ DBG_ASSERT(m_aContext.xForm.is() && m_aContext.xRowSet.is(),
+ "OControlWizard::implDetermineForm: missing some interfaces of the control parent!");
+
+ }
+
+
+ void OControlWizard::implDeterminePage()
+ {
+ try
+ {
+ // get the document model
+ Reference< XChild > xControlAsChild(m_aContext.xObjectModel, UNO_QUERY);
+ Reference< XChild > xModelSearch(xControlAsChild->getParent(), UNO_QUERY);
+
+ Reference< XModel > xModel(xModelSearch, UNO_QUERY);
+ while (xModelSearch.is() && !xModel.is())
+ {
+ xModelSearch.set(xModelSearch->getParent(), UNO_QUERY);
+ xModel.set(xModelSearch, UNO_QUERY);
+ }
+
+ Reference< XDrawPage > xPage;
+ if (xModel.is())
+ {
+ m_aContext.xDocumentModel = xModel;
+
+ Reference< XDrawPageSupplier > xPageSupp(xModel, UNO_QUERY);
+ if (xPageSupp.is())
+ { // it's a document with only one page -> Writer
+ xPage = xPageSupp->getDrawPage();
+ }
+ else
+ {
+ // get the controller currently working on this model
+ Reference< XController > xController = xModel->getCurrentController();
+ DBG_ASSERT(xController.is(), "OControlWizard::implDeterminePage: no current controller!");
+
+ // maybe it's a spreadsheet
+ Reference< XSpreadsheetView > xView(xController, UNO_QUERY);
+ if (xView.is())
+ { // okay, it is one
+ Reference< XSpreadsheet > xSheet = xView->getActiveSheet();
+ xPageSupp.set(xSheet, UNO_QUERY);
+ DBG_ASSERT(xPageSupp.is(), "OControlWizard::implDeterminePage: a spreadsheet which is no page supplier!");
+ if (xPageSupp.is())
+ xPage = xPageSupp->getDrawPage();
+ }
+ else
+ { // can be a draw/impress doc only
+ Reference< XDrawView > xDrawView(xController, UNO_QUERY);
+ DBG_ASSERT(xDrawView.is(), "OControlWizard::implDeterminePage: no alternatives left ... can't determine the page!");
+ if (xDrawView.is())
+ xPage = xDrawView->getCurrentPage();
+ }
+ }
+ }
+ else
+ {
+ DBG_ASSERT(xPage.is(), "OControlWizard::implDeterminePage: can't determine the page (no model)!");
+ }
+ m_aContext.xDrawPage = xPage;
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.dbpilots", "OControlWizard::implDeterminePage");
+ }
+ }
+
+
+ void OControlWizard::implGetDSContext()
+ {
+ try
+ {
+ DBG_ASSERT(m_xContext.is(), "OControlWizard::implGetDSContext: invalid service factory!");
+
+ m_aContext.xDatasourceContext = DatabaseContext::create(m_xContext);
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("OControlWizard::implGetDSContext: invalid database context!");
+ }
+ }
+
+
+ Reference< XConnection > OControlWizard::getFormConnection(const OAccessRegulator&) const
+ {
+ return getFormConnection();
+ }
+
+ Reference< XConnection > OControlWizard::getFormConnection() const
+ {
+ Reference< XConnection > xConn;
+ try
+ {
+ if ( !::dbtools::isEmbeddedInDatabase(m_aContext.xForm,xConn) )
+ m_aContext.xForm->getPropertyValue("ActiveConnection") >>= xConn;
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.dbpilots", "OControlWizard::getFormConnection");
+ }
+ return xConn;
+ }
+
+
+ void OControlWizard::setFormConnection( const OAccessRegulator& _rAccess, const Reference< XConnection >& _rxConn, bool _bAutoDispose )
+ {
+ try
+ {
+ Reference< XConnection > xOldConn = getFormConnection(_rAccess);
+ if (xOldConn.get() == _rxConn.get())
+ return;
+
+ disposeComponent(xOldConn);
+
+ // set the new connection
+ if ( _bAutoDispose )
+ {
+ // for this, use an AutoDisposer (so the conn is cleaned up when the form dies or gets another connection)
+ Reference< XRowSet > xFormRowSet( m_aContext.xForm, UNO_QUERY );
+ new OAutoConnectionDisposer( xFormRowSet, _rxConn );
+ }
+ else
+ {
+ m_aContext.xForm->setPropertyValue("ActiveConnection", makeAny( _rxConn ) );
+ }
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "extensions.dbpilots", "OControlWizard::setFormConnection");
+ }
+ }
+
+
+ bool OControlWizard::updateContext(const OAccessRegulator&)
+ {
+ return initContext();
+ }
+
+ Reference< XInteractionHandler > OControlWizard::getInteractionHandler(weld::Window* _pWindow) const
+ {
+ Reference< XInteractionHandler > xHandler;
+ try
+ {
+ xHandler.set( InteractionHandler::createWithParent(m_xContext, nullptr), UNO_QUERY_THROW );
+ }
+ catch(const Exception&) { }
+ if (!xHandler.is())
+ {
+ const OUString sInteractionHandlerServiceName("com.sun.star.task.InteractionHandler");
+ ShowServiceNotAvailableError(_pWindow, sInteractionHandlerServiceName, true);
+ }
+ return xHandler;
+ }
+
+ bool OControlWizard::initContext()
+ {
+ DBG_ASSERT(m_aContext.xObjectModel.is(), "OGroupBoxWizard::initContext: have no control model to work with!");
+ if (!m_aContext.xObjectModel.is())
+ return false;
+
+ // reset the context
+ m_aContext.xForm.clear();
+ m_aContext.xRowSet.clear();
+ m_aContext.xDocumentModel.clear();
+ m_aContext.xDrawPage.clear();
+ m_aContext.xObjectShape.clear();
+ m_aContext.aFieldNames.realloc(0);
+
+ m_aContext.xObjectContainer.clear();
+ m_aContext.aTypes.clear();
+ m_aContext.bEmbedded = false;
+
+ Any aSQLException;
+ Reference< XPreparedStatement > xStatement;
+ try
+ {
+ // get the datasource context
+ implGetDSContext();
+
+ // first, determine the form the control belongs to
+ implDetermineForm();
+
+ // need the page, too
+ implDeterminePage();
+
+ // the shape of the control
+ implDetermineShape();
+
+ // get the columns of the object the settings refer to
+ Reference< XNameAccess > xColumns;
+
+ if (m_aContext.xForm.is())
+ {
+ // collect some properties of the form
+ OUString sObjectName = ::comphelper::getString(m_aContext.xForm->getPropertyValue("Command"));
+ sal_Int32 nObjectType = ::comphelper::getINT32(m_aContext.xForm->getPropertyValue("CommandType"));
+
+ // calculate the connection the rowset is working with
+ Reference< XConnection > xConnection;
+ m_aContext.bEmbedded = ::dbtools::isEmbeddedInDatabase( m_aContext.xForm, xConnection );
+ if ( !m_aContext.bEmbedded )
+ xConnection = ::dbtools::connectRowset( m_aContext.xRowSet, m_xContext, nullptr );
+
+ // get the fields
+ if (xConnection.is())
+ {
+ switch (nObjectType)
+ {
+ case 0:
+ {
+ Reference< XTablesSupplier > xSupplyTables(xConnection, UNO_QUERY);
+ if (xSupplyTables.is() && xSupplyTables->getTables().is() && xSupplyTables->getTables()->hasByName(sObjectName))
+ {
+ Reference< XColumnsSupplier > xSupplyColumns;
+ m_aContext.xObjectContainer = xSupplyTables->getTables();
+ m_aContext.xObjectContainer->getByName(sObjectName) >>= xSupplyColumns;
+ DBG_ASSERT(xSupplyColumns.is(), "OControlWizard::initContext: invalid table columns!");
+ xColumns = xSupplyColumns->getColumns();
+ }
+ }
+ break;
+ case 1:
+ {
+ Reference< XQueriesSupplier > xSupplyQueries(xConnection, UNO_QUERY);
+ if (xSupplyQueries.is() && xSupplyQueries->getQueries().is() && xSupplyQueries->getQueries()->hasByName(sObjectName))
+ {
+ Reference< XColumnsSupplier > xSupplyColumns;
+ m_aContext.xObjectContainer = xSupplyQueries->getQueries();
+ m_aContext.xObjectContainer->getByName(sObjectName) >>= xSupplyColumns;
+ DBG_ASSERT(xSupplyColumns.is(), "OControlWizard::initContext: invalid query columns!");
+ xColumns = xSupplyColumns->getColumns();
+ }
+ }
+ break;
+ default:
+ {
+ xStatement = xConnection->prepareStatement(sObjectName);
+
+ // not interested in any results, only in the fields
+ Reference< XPropertySet > xStatementProps(xStatement, UNO_QUERY);
+ xStatementProps->setPropertyValue("MaxRows", makeAny(sal_Int32(0)));
+
+ // TODO: think about handling local SQLExceptions here ...
+ Reference< XColumnsSupplier > xSupplyCols(xStatement->executeQuery(), UNO_QUERY);
+ if (xSupplyCols.is())
+ xColumns = xSupplyCols->getColumns();
+ }
+ }
+ }
+ }
+
+ if (xColumns.is())
+ {
+ m_aContext.aFieldNames = xColumns->getElementNames();
+ const OUString* pBegin = m_aContext.aFieldNames.getConstArray();
+ const OUString* pEnd = pBegin + m_aContext.aFieldNames.getLength();
+ for(;pBegin != pEnd;++pBegin)
+ {
+ sal_Int32 nFieldType = DataType::OTHER;
+ try
+ {
+ Reference< XPropertySet > xColumn;
+ xColumns->getByName(*pBegin) >>= xColumn;
+ xColumn->getPropertyValue("Type") >>= nFieldType;
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("OControlWizard::initContext: unexpected exception while gathering column information!");
+ }
+ m_aContext.aTypes.emplace(*pBegin,nFieldType);
+ }
+ }
+ }
+ catch(const SQLContext& e) { aSQLException <<= e; }
+ catch(const SQLWarning& e) { aSQLException <<= e; }
+ catch(const SQLException& e) { aSQLException <<= e; }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "extensions.dbpilots", "OControlWizard::initContext: could not retrieve the control context");
+ }
+
+ ::comphelper::disposeComponent(xStatement);
+
+ if (aSQLException.hasValue())
+ { // an SQLException (or derivee) was thrown ...
+
+ // prepend an extra SQLContext explaining what we were doing
+ SQLContext aContext;
+ aContext.Message = compmodule::ModuleRes(RID_STR_COULDNOTOPENTABLE);
+ aContext.NextException = aSQLException;
+
+ // create an interaction handler to display this exception
+ Reference< XInteractionHandler > xHandler = getInteractionHandler(m_xAssistant.get());
+ if ( !xHandler.is() )
+ return false;
+
+ Reference< XInteractionRequest > xRequest = new OInteractionRequest(makeAny(aContext));
+ try
+ {
+ xHandler->handle(xRequest);
+ }
+ catch(const Exception&) { }
+ return false;
+ }
+
+ return m_aContext.aFieldNames.hasElements();
+ }
+
+
+ void OControlWizard::commitControlSettings(OControlWizardSettings const * _pSettings)
+ {
+ DBG_ASSERT(m_aContext.xObjectModel.is(), "OControlWizard::commitControlSettings: have no control model to work with!");
+ if (!m_aContext.xObjectModel.is())
+ return;
+
+ // the only thing we have at the moment is the label
+ try
+ {
+ Reference< XPropertySetInfo > xInfo = m_aContext.xObjectModel->getPropertySetInfo();
+ if (xInfo.is() && xInfo->hasPropertyByName("Label"))
+ {
+ OUString sControlLabel(_pSettings->sControlLabel);
+ m_aContext.xObjectModel->setPropertyValue(
+ "Label",
+ makeAny(sControlLabel)
+ );
+ }
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "extensions.dbpilots", "OControlWizard::commitControlSettings: could not commit the basic control settings!");
+ }
+ }
+
+
+ void OControlWizard::initControlSettings(OControlWizardSettings* _pSettings)
+ {
+ DBG_ASSERT(m_aContext.xObjectModel.is(), "OControlWizard::initControlSettings: have no control model to work with!");
+ if (!m_aContext.xObjectModel.is())
+ return;
+
+ // initialize some settings from the control model give
+ try
+ {
+ OUString sLabelPropertyName("Label");
+ Reference< XPropertySetInfo > xInfo = m_aContext.xObjectModel->getPropertySetInfo();
+ if (xInfo.is() && xInfo->hasPropertyByName(sLabelPropertyName))
+ {
+ OUString sControlLabel;
+ m_aContext.xObjectModel->getPropertyValue(sLabelPropertyName) >>= sControlLabel;
+ _pSettings->sControlLabel = sControlLabel;
+ }
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "extensions.dbpilots", "OControlWizard::initControlSettings: could not retrieve the basic control settings!");
+ }
+ }
+
+
+ bool OControlWizard::needDatasourceSelection()
+ {
+ // lemme see ...
+ return !getContext().aFieldNames.hasElements();
+ // if we got fields, the data source is valid ...
+ }
+
+
+} // namespace dbp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/controlwizard.hxx b/extensions/source/dbpilots/controlwizard.hxx
new file mode 100644
index 000000000..f918a5a94
--- /dev/null
+++ b/extensions/source/dbpilots/controlwizard.hxx
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_CONTROLWIZARD_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_CONTROLWIZARD_HXX
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <vcl/weld.hxx>
+#include <vcl/wizardmachine.hxx>
+#include "dbptypes.hxx"
+#include <strings.hrc>
+#include <componentmodule.hxx>
+#include "wizardcontext.hxx"
+
+class ResId;
+
+namespace dbp
+{
+ struct OControlWizardSettings
+ {
+ OUString sControlLabel;
+ };
+
+ class OControlWizard;
+ typedef ::vcl::OWizardPage OControlWizardPage_Base;
+ class OControlWizardPage : public OControlWizardPage_Base
+ {
+ OControlWizard* m_pDialog;
+ std::unique_ptr<weld::Label> m_xFormDatasourceLabel;
+ std::unique_ptr<weld::Label> m_xFormDatasource;
+ std::unique_ptr<weld::Label> m_xFormContentTypeLabel;
+ std::unique_ptr<weld::Label> m_xFormContentType;
+ std::unique_ptr<weld::Label> m_xFormTableLabel;
+ std::unique_ptr<weld::Label> m_xFormTable;
+ std::unique_ptr<weld::Frame> m_xFrame;
+
+ protected:
+ OControlWizard* getDialog();
+ const OControlWizard* getDialog() const;
+ const OControlWizardContext& getContext() const;
+ bool updateContext();
+ void setFormConnection(const css::uno::Reference< css::sdbc::XConnection >& _rxConn, bool _bAutoDispose = true );
+ css::uno::Reference< css::sdbc::XConnection >
+ getFormConnection() const;
+ public:
+ OControlWizardPage(weld::Container* pPage, OControlWizard* pWizard, const OUString& rUIXMLDescription, const OString& rID);
+ virtual ~OControlWizardPage() override;
+
+ protected:
+ static void fillListBox(
+ weld::TreeView& _rList,
+ const css::uno::Sequence< OUString >& _rItems);
+ static void fillListBox(
+ weld::ComboBox& _rList,
+ const css::uno::Sequence< OUString >& _rItems);
+
+ protected:
+ void enableFormDatasourceDisplay();
+
+ protected:
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ };
+
+ struct OAccessRegulator;
+
+ typedef ::vcl::WizardMachine OControlWizard_Base;
+ class OControlWizard : public OControlWizard_Base
+ {
+ private:
+ OControlWizardContext m_aContext;
+ css::uno::Reference< css::uno::XComponentContext >
+ m_xContext;
+
+ public:
+ OControlWizard(
+ weld::Window* _pParent,
+ const css::uno::Reference< css::beans::XPropertySet >& _rxObjectModel,
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext
+ );
+ virtual ~OControlWizard() override;
+
+ // make the same base class methods public
+ using OControlWizard_Base::travelNext;
+
+ public:
+ const css::uno::Reference< css::uno::XComponentContext >&
+ getComponentContext() const { return m_xContext; }
+
+ const OControlWizardContext& getContext() const { return m_aContext; }
+ bool updateContext(const OAccessRegulator&);
+ void setFormConnection(const OAccessRegulator&, const css::uno::Reference< css::sdbc::XConnection >& _rxConn, bool _bAutoDispose );
+ css::uno::Reference< css::sdbc::XConnection >
+ getFormConnection(const OAccessRegulator&) const;
+
+ /** returns the com.sun.star.task.InteractionHandler
+ @param _pWindow The window will be used when an error message has to be shown.
+ */
+ css::uno::Reference< css::task::XInteractionHandler > getInteractionHandler(weld::Window* _pWindow) const;
+
+ protected:
+ // initialize the derivees settings (which have to be derived from OControlWizardSettings)
+ // with some common data extracted from the control model
+ void initControlSettings(OControlWizardSettings* _pSettings);
+ // commit the control-relevant settings
+ void commitControlSettings(OControlWizardSettings const * _pSettings);
+
+ bool needDatasourceSelection();
+
+ css::uno::Reference< css::sdbc::XConnection >
+ getFormConnection() const;
+
+ virtual bool approveControl(sal_Int16 _nClassId) = 0;
+
+ virtual short run() override;
+
+ private:
+ bool initContext();
+
+ void implGetDSContext();
+ void implDetermineForm();
+ void implDeterminePage();
+ void implDetermineShape();
+ };
+
+
+} // namespace dbp
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_CONTROLWIZARD_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/dbp.component b/extensions/source/dbpilots/dbp.component
new file mode 100644
index 000000000..5fb935309
--- /dev/null
+++ b/extensions/source/dbpilots/dbp.component
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+
+<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
+ prefix="dbp" xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="org.openoffice.comp.dbp.OGridWizard">
+ <service name="com.sun.star.sdb.GridControlAutoPilot"/>
+ </implementation>
+ <implementation name="org.openoffice.comp.dbp.OGroupBoxWizard">
+ <service name="com.sun.star.sdb.GroupBoxAutoPilot"/>
+ </implementation>
+ <implementation name="org.openoffice.comp.dbp.OListComboWizard">
+ <service name="com.sun.star.sdb.ListComboBoxAutoPilot"/>
+ </implementation>
+</component>
diff --git a/extensions/source/dbpilots/dbpservices.cxx b/extensions/source/dbpilots/dbpservices.cxx
new file mode 100644
index 000000000..fd2f472ae
--- /dev/null
+++ b/extensions/source/dbpilots/dbpservices.cxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <componentmodule.hxx>
+#include "dbpservices.hxx"
+#include <mutex>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+
+extern "C" {
+
+static void dbp_initializeModule()
+{
+ std::once_flag aInit;
+ std::call_once(aInit, [&]()
+ {
+ createRegistryInfo_OGroupBoxWizard();
+ createRegistryInfo_OListComboWizard();
+ createRegistryInfo_OGridWizard();
+ return true;
+ });
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT void* dbp_component_getFactory(
+ const char* pImplementationName,
+ void* pServiceManager,
+ void* /*pRegistryKey*/)
+{
+ dbp_initializeModule();
+
+ Reference< XInterface > xRet;
+ if (pServiceManager && pImplementationName)
+ {
+ xRet = compmodule::OModule::getComponentFactory(
+ OUString::createFromAscii(pImplementationName),
+ static_cast< XMultiServiceFactory* >(pServiceManager));
+ }
+
+ if (xRet.is())
+ xRet->acquire();
+ return xRet.get();
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/dbpservices.hxx b/extensions/source/dbpilots/dbpservices.hxx
new file mode 100644
index 000000000..2feea60c1
--- /dev/null
+++ b/extensions/source/dbpilots/dbpservices.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_DBPSERVICES_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_DBPSERVICES_HXX
+
+#include <sal/config.h>
+
+extern "C" {
+
+void createRegistryInfo_OGridWizard();
+void createRegistryInfo_OGroupBoxWizard();
+void createRegistryInfo_OListComboWizard();
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/dbptools.cxx b/extensions/source/dbpilots/dbptools.cxx
new file mode 100644
index 000000000..1b647e84c
--- /dev/null
+++ b/extensions/source/dbpilots/dbptools.cxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "dbptools.hxx"
+#include <tools/debug.hxx>
+#include <osl/diagnose.h>
+
+
+namespace dbp
+{
+
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::container;
+
+
+ void disambiguateName(const Reference< XNameAccess >& _rxContainer, OUString& _rElementsName)
+ {
+ DBG_ASSERT(_rxContainer.is(), "::dbp::disambiguateName: invalid container!");
+ if (!_rxContainer.is())
+ return;
+
+ try
+ {
+ OUString sBase(_rElementsName);
+ for (sal_Int32 i=1; i<0x7FFFFFFF; ++i)
+ {
+ _rElementsName = sBase;
+ _rElementsName += OUString::number(i);
+ if (!_rxContainer->hasByName(_rElementsName))
+ return;
+ }
+ // can't do anything ... no free names
+ _rElementsName = sBase;
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("::dbp::disambiguateName: something went (strangely) wrong!");
+ }
+ }
+
+
+} // namespace dbp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/dbptools.hxx b/extensions/source/dbpilots/dbptools.hxx
new file mode 100644
index 000000000..548949e8b
--- /dev/null
+++ b/extensions/source/dbpilots/dbptools.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_DBPTOOLS_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_DBPTOOLS_HXX
+
+#include <com/sun/star/container/XNameAccess.hpp>
+
+
+namespace dbp
+{
+
+
+ void disambiguateName(
+ const css::uno::Reference< css::container::XNameAccess >& _rxContainer,
+ OUString& _rElementsName);
+
+
+} // namespace dbp
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_DBPTOOLS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/dbptypes.hxx b/extensions/source/dbpilots/dbptypes.hxx
new file mode 100644
index 000000000..976e4f24d
--- /dev/null
+++ b/extensions/source/dbpilots/dbptypes.hxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_DBPTYPES_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_DBPTYPES_HXX
+
+#include <sal/config.h>
+
+#include <rtl/ustring.hxx>
+
+#include <map>
+#include <set>
+
+
+namespace dbp
+{
+
+
+ typedef std::set<OUString> StringBag;
+ typedef std::map<sal_uInt32, OUString> MapInt2String;
+
+
+} // namespace dbp
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_DBPTYPES_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/gridwizard.cxx b/extensions/source/dbpilots/gridwizard.cxx
new file mode 100644
index 000000000..c78b5d930
--- /dev/null
+++ b/extensions/source/dbpilots/gridwizard.cxx
@@ -0,0 +1,446 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <vector>
+
+#include "gridwizard.hxx"
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/form/XGridColumnFactory.hpp>
+#include <com/sun/star/awt/MouseWheelBehavior.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <sal/log.hxx>
+#include <tools/debug.hxx>
+#include "dbptools.hxx"
+#include <helpids.h>
+
+#define GW_STATE_DATASOURCE_SELECTION 0
+#define GW_STATE_FIELDSELECTION 1
+
+
+namespace dbp
+{
+
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::awt;
+
+ OGridWizard::OGridWizard(weld::Window* _pParent,
+ const Reference< XPropertySet >& _rxObjectModel, const Reference< XComponentContext >& _rxContext )
+ : OControlWizard(_pParent, _rxObjectModel, _rxContext)
+ , m_bHadDataSelection(true)
+ {
+ initControlSettings(&m_aSettings);
+
+ m_xPrevPage->set_help_id(HID_GRIDWIZARD_PREVIOUS);
+ m_xNextPage->set_help_id(HID_GRIDWIZARD_NEXT);
+ m_xCancel->set_help_id(HID_GRIDWIZARD_CANCEL);
+ m_xFinish->set_help_id(HID_GRIDWIZARD_FINISH);
+ setTitleBase(compmodule::ModuleRes(RID_STR_GRIDWIZARD_TITLE));
+
+ // if we do not need the data source selection page ...
+ if (!needDatasourceSelection())
+ { // ... skip it!
+ skip();
+ m_bHadDataSelection = false;
+ }
+ }
+
+ bool OGridWizard::approveControl(sal_Int16 _nClassId)
+ {
+ if (FormComponentType::GRIDCONTROL != _nClassId)
+ return false;
+
+ Reference< XGridColumnFactory > xColumnFactory(getContext().xObjectModel, UNO_QUERY);
+ return xColumnFactory.is();
+ }
+
+ void OGridWizard::implApplySettings()
+ {
+ const OControlWizardContext& rContext = getContext();
+
+ // the factory for the columns
+ Reference< XGridColumnFactory > xColumnFactory(rContext.xObjectModel, UNO_QUERY);
+ DBG_ASSERT(xColumnFactory.is(), "OGridWizard::implApplySettings: should never have made it 'til here!");
+ // (if we're here, what the hell happened in approveControl??)
+
+ // the container for the columns
+ Reference< XNameContainer > xColumnContainer(rContext.xObjectModel, UNO_QUERY);
+ DBG_ASSERT(xColumnContainer.is(), "OGridWizard::implApplySettings: no container!");
+
+ if (!xColumnFactory.is() || !xColumnContainer.is())
+ return;
+
+ static const char s_sMouseWheelBehavior[] = "MouseWheelBehavior";
+ static const char s_sEmptyString[] = "";
+
+ // collect "descriptors" for the to-be-created (grid)columns
+ std::vector< OUString > aColumnServiceNames; // service names to be used with the XGridColumnFactory
+ std::vector< OUString > aColumnLabelPostfixes; // postfixes to append to the column labels
+ std::vector< OUString > aFormFieldNames; // data field names
+
+ aColumnServiceNames.reserve(getSettings().aSelectedFields.getLength());
+ aColumnLabelPostfixes.reserve(getSettings().aSelectedFields.getLength());
+ aFormFieldNames.reserve(getSettings().aSelectedFields.getLength());
+
+ // loop through the selected field names
+ const OUString* pSelectedFields = getSettings().aSelectedFields.getConstArray();
+ const OUString* pEnd = pSelectedFields + getSettings().aSelectedFields.getLength();
+ for (;pSelectedFields < pEnd; ++pSelectedFields)
+ {
+ // get the information for the selected column
+ sal_Int32 nFieldType = DataType::OTHER;
+ OControlWizardContext::TNameTypeMap::const_iterator aFind = rContext.aTypes.find(*pSelectedFields);
+ if ( aFind != rContext.aTypes.end() )
+ nFieldType = aFind->second;
+
+ aFormFieldNames.push_back(*pSelectedFields);
+ switch (nFieldType)
+ {
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ aColumnServiceNames.push_back(OUString("CheckBox"));
+ aColumnLabelPostfixes.push_back(s_sEmptyString);
+ break;
+
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ case DataType::INTEGER:
+ aColumnServiceNames.push_back(OUString("NumericField"));
+ aColumnLabelPostfixes.push_back(s_sEmptyString);
+ break;
+
+ case DataType::FLOAT:
+ case DataType::REAL:
+ case DataType::DOUBLE:
+ case DataType::NUMERIC:
+ case DataType::DECIMAL:
+ aColumnServiceNames.push_back(OUString("FormattedField"));
+ aColumnLabelPostfixes.push_back(s_sEmptyString);
+ break;
+
+ case DataType::DATE:
+ aColumnServiceNames.push_back(OUString("DateField"));
+ aColumnLabelPostfixes.push_back(s_sEmptyString);
+ break;
+
+ case DataType::TIME:
+ aColumnServiceNames.push_back(OUString("TimeField"));
+ aColumnLabelPostfixes.push_back(s_sEmptyString);
+ break;
+
+ case DataType::TIMESTAMP:
+ aColumnServiceNames.push_back(OUString("DateField"));
+ aColumnLabelPostfixes.push_back(compmodule::ModuleRes(RID_STR_DATEPOSTFIX));
+
+ aFormFieldNames.push_back(*pSelectedFields);
+ aColumnServiceNames.push_back(OUString("TimeField"));
+ aColumnLabelPostfixes.push_back(compmodule::ModuleRes(RID_STR_TIMEPOSTFIX));
+ break;
+
+ default:
+ aColumnServiceNames.push_back(OUString("TextField"));
+ aColumnLabelPostfixes.push_back(s_sEmptyString);
+ }
+ }
+
+ DBG_ASSERT( aFormFieldNames.size() == aColumnServiceNames.size()
+ && aColumnServiceNames.size() == aColumnLabelPostfixes.size(),
+ "OGridWizard::implApplySettings: inconsistent descriptor sequences!");
+
+ // now loop through the descriptions and create the (grid)columns out of th descriptors
+ {
+ Reference< XNameAccess > xExistenceChecker(xColumnContainer.get());
+
+ std::vector< OUString >::const_iterator pColumnLabelPostfix = aColumnLabelPostfixes.begin();
+ std::vector< OUString >::const_iterator pFormFieldName = aFormFieldNames.begin();
+
+ for (const auto& rColumnServiceName : aColumnServiceNames)
+ {
+ // create a (grid)column for the (resultset)column
+ try
+ {
+ Reference< XPropertySet > xColumn( xColumnFactory->createColumn(rColumnServiceName), UNO_SET_THROW );
+ Reference< XPropertySetInfo > xColumnPSI( xColumn->getPropertySetInfo(), UNO_SET_THROW );
+
+ OUString sColumnName(rColumnServiceName);
+ disambiguateName(xExistenceChecker, sColumnName);
+
+ // the data field the column should be bound to
+ xColumn->setPropertyValue("DataField", makeAny(*pFormFieldName));
+ // the label
+ xColumn->setPropertyValue("Label", makeAny(*pFormFieldName + *pColumnLabelPostfix));
+ // the width (<void/> => column will be auto-sized)
+ xColumn->setPropertyValue("Width", Any());
+
+ if ( xColumnPSI->hasPropertyByName( s_sMouseWheelBehavior ) )
+ xColumn->setPropertyValue( s_sMouseWheelBehavior, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) );
+
+ // insert the column
+ xColumnContainer->insertByName(sColumnName, makeAny(xColumn));
+ }
+ catch(const Exception&)
+ {
+ SAL_WARN( "extensions.dbpilots", "OGridWizard::implApplySettings: "
+ "unexpected exception while creating the grid column for field " <<
+ *pFormFieldName );
+ }
+
+ ++pColumnLabelPostfix;
+ ++pFormFieldName;
+ }
+ }
+ }
+
+ std::unique_ptr<BuilderPage> OGridWizard::createPage(WizardState _nState)
+ {
+ OString sIdent(OString::number(_nState));
+ weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
+
+ switch (_nState)
+ {
+ case GW_STATE_DATASOURCE_SELECTION:
+ return std::make_unique<OTableSelectionPage>(pPageContainer, this);
+ case GW_STATE_FIELDSELECTION:
+ return std::make_unique<OGridFieldsSelection>(pPageContainer, this);
+ }
+
+ return nullptr;
+ }
+
+ vcl::WizardTypes::WizardState OGridWizard::determineNextState( WizardState _nCurrentState ) const
+ {
+ switch (_nCurrentState)
+ {
+ case GW_STATE_DATASOURCE_SELECTION:
+ return GW_STATE_FIELDSELECTION;
+ case GW_STATE_FIELDSELECTION:
+ return WZS_INVALID_STATE;
+ }
+
+ return WZS_INVALID_STATE;
+ }
+
+ void OGridWizard::enterState(WizardState _nState)
+ {
+ OControlWizard::enterState(_nState);
+
+ enableButtons(WizardButtonFlags::PREVIOUS, m_bHadDataSelection ? (GW_STATE_DATASOURCE_SELECTION < _nState) : GW_STATE_FIELDSELECTION < _nState);
+ enableButtons(WizardButtonFlags::NEXT, GW_STATE_FIELDSELECTION != _nState);
+ if (_nState < GW_STATE_FIELDSELECTION)
+ enableButtons(WizardButtonFlags::FINISH, false);
+
+ if (GW_STATE_FIELDSELECTION == _nState)
+ defaultButton(WizardButtonFlags::FINISH);
+ }
+
+
+ bool OGridWizard::leaveState(WizardState _nState)
+ {
+ if (!OControlWizard::leaveState(_nState))
+ return false;
+
+ if (GW_STATE_FIELDSELECTION == _nState)
+ defaultButton(WizardButtonFlags::NEXT);
+
+ return true;
+ }
+
+
+ bool OGridWizard::onFinish()
+ {
+ if ( !OControlWizard::onFinish() )
+ return false;
+
+ implApplySettings();
+
+ return true;
+ }
+
+ OGridFieldsSelection::OGridFieldsSelection(weld::Container* pPage, OGridWizard* pWizard)
+ : OGridPage(pPage, pWizard, "modules/sabpilot/ui/gridfieldsselectionpage.ui", "GridFieldsSelection")
+ , m_xExistFields(m_xBuilder->weld_tree_view("existingfields"))
+ , m_xSelectOne(m_xBuilder->weld_button("fieldright"))
+ , m_xSelectAll(m_xBuilder->weld_button("allfieldsright"))
+ , m_xDeselectOne(m_xBuilder->weld_button("fieldleft"))
+ , m_xDeselectAll(m_xBuilder->weld_button("allfieldsleft"))
+ , m_xSelFields(m_xBuilder->weld_tree_view("selectedfields"))
+ {
+ enableFormDatasourceDisplay();
+
+ m_xSelectOne->connect_clicked(LINK(this, OGridFieldsSelection, OnMoveOneEntry));
+ m_xSelectAll->connect_clicked(LINK(this, OGridFieldsSelection, OnMoveAllEntries));
+ m_xDeselectOne->connect_clicked(LINK(this, OGridFieldsSelection, OnMoveOneEntry));
+ m_xDeselectAll->connect_clicked(LINK(this, OGridFieldsSelection, OnMoveAllEntries));
+
+ m_xExistFields->connect_changed(LINK(this, OGridFieldsSelection, OnEntrySelected));
+ m_xSelFields->connect_changed(LINK(this, OGridFieldsSelection, OnEntrySelected));
+ m_xExistFields->connect_row_activated(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked));
+ m_xSelFields->connect_row_activated(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked));
+ }
+
+ OGridFieldsSelection::~OGridFieldsSelection()
+ {
+ }
+
+ void OGridFieldsSelection::Activate()
+ {
+ OGridPage::Activate();
+ m_xExistFields->grab_focus();
+ }
+
+ bool OGridFieldsSelection::canAdvance() const
+ {
+ return false;
+ // we're the last page in our wizard
+ }
+
+ void OGridFieldsSelection::initializePage()
+ {
+ OGridPage::initializePage();
+
+ const OControlWizardContext& rContext = getContext();
+ fillListBox(*m_xExistFields, rContext.aFieldNames);
+
+ m_xSelFields->clear();
+ const OGridSettings& rSettings = getSettings();
+ const OUString* pSelected = rSettings.aSelectedFields.getConstArray();
+ const OUString* pEnd = pSelected + rSettings.aSelectedFields.getLength();
+ for (; pSelected < pEnd; ++pSelected)
+ {
+ m_xSelFields->append_text(*pSelected);
+ m_xExistFields->remove_text(*pSelected);
+ }
+
+ implCheckButtons();
+ }
+
+ bool OGridFieldsSelection::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!OGridPage::commitPage(_eReason))
+ return false;
+
+ OGridSettings& rSettings = getSettings();
+ const sal_Int32 nSelected = m_xSelFields->n_children();
+
+ rSettings.aSelectedFields.realloc(nSelected);
+ OUString* pSelected = rSettings.aSelectedFields.getArray();
+
+ for (sal_Int32 i=0; i<nSelected; ++i, ++pSelected)
+ *pSelected = m_xSelFields->get_text(i);
+
+ return true;
+ }
+
+ void OGridFieldsSelection::implCheckButtons()
+ {
+ m_xSelectOne->set_sensitive(m_xExistFields->count_selected_rows() != 0);
+ m_xSelectAll->set_sensitive(m_xExistFields->n_children() != 0);
+
+ m_xDeselectOne->set_sensitive(m_xSelFields->count_selected_rows() != 0);
+ m_xDeselectAll->set_sensitive(m_xSelFields->n_children() != 0);
+
+ getDialog()->enableButtons(WizardButtonFlags::FINISH, 0 != m_xSelFields->n_children());
+ }
+
+ IMPL_LINK(OGridFieldsSelection, OnEntryDoubleClicked, weld::TreeView&, rList, bool)
+ {
+ weld::Button* pSimulateButton = m_xExistFields.get() == &rList ? m_xSelectOne.get() : m_xDeselectOne.get();
+ if (pSimulateButton->get_sensitive())
+ OnMoveOneEntry(*pSimulateButton);
+ return true;
+ }
+
+ IMPL_LINK_NOARG(OGridFieldsSelection, OnEntrySelected, weld::TreeView&, void)
+ {
+ implCheckButtons();
+ }
+
+ IMPL_LINK(OGridFieldsSelection, OnMoveOneEntry, weld::Button&, rButton, void)
+ {
+ bool bMoveRight = (m_xSelectOne.get() == &rButton);
+ weld::TreeView& rMoveTo = bMoveRight ? *m_xSelFields : *m_xExistFields;
+
+ // the index of the selected entry
+ const sal_Int32 nSelected = bMoveRight ? m_xExistFields->get_selected_index() : m_xSelFields->get_selected_index();
+ // the (original) relative position of the entry
+ int nRelativeIndex = bMoveRight ? m_xExistFields->get_id(nSelected).toInt32() : m_xSelFields->get_id(nSelected).toInt32();
+
+ sal_Int32 nInsertPos = -1;
+ if (!bMoveRight)
+ { // need to determine an insert pos which reflects the original
+ nInsertPos = 0;
+ while (nInsertPos < rMoveTo.n_children())
+ {
+ if (rMoveTo.get_id(nInsertPos).toInt32() > nRelativeIndex)
+ break;
+ ++nInsertPos;
+ }
+ }
+
+ // the text of the entry to move
+ OUString sMovingEntry = bMoveRight ? m_xExistFields->get_text(nSelected) : m_xSelFields->get_text(nSelected);
+
+ // insert the entry preserving it's "relative position" entry data
+ OUString sId(OUString::number(nRelativeIndex));
+ rMoveTo.insert(nullptr, nInsertPos, &sMovingEntry, &sId, nullptr, nullptr, nullptr, false, nullptr);
+
+ // remove the entry from its old list
+ if (bMoveRight)
+ {
+ sal_Int32 nSelectPos = m_xExistFields->get_selected_index();
+ m_xExistFields->remove(nSelected);
+ if ((nSelectPos != -1) && (nSelectPos < m_xExistFields->n_children()))
+ m_xExistFields->select(nSelectPos);
+
+ m_xExistFields->grab_focus();
+ }
+ else
+ {
+ sal_Int32 nSelectPos = m_xSelFields->get_selected_index();
+ m_xSelFields->remove(nSelected);
+ if ((nSelectPos != -1) && (nSelectPos < m_xSelFields->n_children()))
+ m_xSelFields->select(nSelectPos);
+
+ m_xSelFields->grab_focus();
+ }
+
+ implCheckButtons();
+ }
+
+ IMPL_LINK(OGridFieldsSelection, OnMoveAllEntries, weld::Button&, rButton, void)
+ {
+ bool bMoveRight = (m_xSelectAll.get() == &rButton);
+ m_xExistFields->clear();
+ m_xSelFields->clear();
+ fillListBox(bMoveRight ? *m_xSelFields : *m_xExistFields, getContext().aFieldNames);
+
+ implCheckButtons();
+ }
+
+} // namespace dbp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/gridwizard.hxx b/extensions/source/dbpilots/gridwizard.hxx
new file mode 100644
index 000000000..5eb9732bd
--- /dev/null
+++ b/extensions/source/dbpilots/gridwizard.hxx
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_GRIDWIZARD_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_GRIDWIZARD_HXX
+
+#include "controlwizard.hxx"
+#include "commonpagesdbp.hxx"
+
+using vcl::WizardTypes::WizardState;
+using vcl::WizardTypes::CommitPageReason;
+
+namespace dbp
+{
+ struct OGridSettings : public OControlWizardSettings
+ {
+ css::uno::Sequence< OUString > aSelectedFields;
+ };
+
+ class OGridWizard final : public OControlWizard
+ {
+ OGridSettings m_aSettings;
+ bool m_bHadDataSelection : 1;
+
+ public:
+ OGridWizard(weld::Window* _pParent,
+ const css::uno::Reference< css::beans::XPropertySet >& _rxObjectModel,
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext);
+
+ OGridSettings& getSettings() { return m_aSettings; }
+
+ private:
+ // OWizardMachine overridables
+ virtual std::unique_ptr<BuilderPage> createPage( WizardState _nState ) override;
+ virtual WizardState determineNextState( WizardState _nCurrentState ) const override;
+ virtual void enterState( WizardState _nState ) override;
+ virtual bool leaveState( WizardState _nState ) override;
+ virtual bool onFinish() override;
+
+ virtual bool approveControl(sal_Int16 _nClassId) override;
+
+ void implApplySettings();
+ };
+
+ class OGridPage : public OControlWizardPage
+ {
+ public:
+ OGridPage(weld::Container* pPage, OGridWizard* pWizard, const OUString& rUIXMLDescription, const OString& rID)
+ : OControlWizardPage(pPage, pWizard, rUIXMLDescription, rID)
+ {
+ }
+ protected:
+ OGridSettings& getSettings() { return static_cast<OGridWizard*>(getDialog())->getSettings(); }
+ };
+
+ class OGridFieldsSelection final : public OGridPage
+ {
+ std::unique_ptr<weld::TreeView> m_xExistFields;
+ std::unique_ptr<weld::Button> m_xSelectOne;
+ std::unique_ptr<weld::Button> m_xSelectAll;
+ std::unique_ptr<weld::Button> m_xDeselectOne;
+ std::unique_ptr<weld::Button> m_xDeselectAll;
+ std::unique_ptr<weld::TreeView> m_xSelFields;
+
+ public:
+ explicit OGridFieldsSelection(weld::Container* pPage, OGridWizard* pWizard);
+ virtual ~OGridFieldsSelection() override;
+
+ private:
+ // BuilderPage overridables
+ virtual void Activate() override;
+
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+ virtual bool canAdvance() const override;
+
+ DECL_LINK(OnMoveOneEntry, weld::Button&, void);
+ DECL_LINK(OnMoveAllEntries, weld::Button&, void);
+ DECL_LINK(OnEntrySelected, weld::TreeView&, void);
+ DECL_LINK(OnEntryDoubleClicked, weld::TreeView&, bool);
+
+ void implCheckButtons();
+ };
+} // namespace dbp
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_GRIDWIZARD_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/groupboxwiz.cxx b/extensions/source/dbpilots/groupboxwiz.cxx
new file mode 100644
index 000000000..6892536ae
--- /dev/null
+++ b/extensions/source/dbpilots/groupboxwiz.cxx
@@ -0,0 +1,463 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "groupboxwiz.hxx"
+#include "commonpagesdbp.hxx"
+#include <tools/debug.hxx>
+#include "optiongrouplayouter.hxx"
+#include <helpids.h>
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+
+#define GBW_STATE_OPTIONLIST 0
+#define GBW_STATE_DEFAULTOPTION 1
+#define GBW_STATE_OPTIONVALUES 2
+#define GBW_STATE_DBFIELD 3
+#define GBW_STATE_FINALIZE 4
+
+namespace dbp
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::form;
+
+ OGroupBoxWizard::OGroupBoxWizard(weld::Window* _pParent,
+ const Reference< XPropertySet >& _rxObjectModel, const Reference< XComponentContext >& _rxContext )
+ : OControlWizard(_pParent, _rxObjectModel, _rxContext)
+ , m_bVisitedDefault(false)
+ , m_bVisitedDB(false)
+ {
+ initControlSettings(&m_aSettings);
+
+ m_xPrevPage->set_help_id(HID_GROUPWIZARD_PREVIOUS);
+ m_xNextPage->set_help_id(HID_GROUPWIZARD_NEXT);
+ m_xCancel->set_help_id(HID_GROUPWIZARD_CANCEL);
+ m_xFinish->set_help_id(HID_GROUPWIZARD_FINISH);
+ setTitleBase(compmodule::ModuleRes(RID_STR_GROUPWIZARD_TITLE));
+ }
+
+ bool OGroupBoxWizard::approveControl(sal_Int16 _nClassId)
+ {
+ return FormComponentType::GROUPBOX == _nClassId;
+ }
+
+ std::unique_ptr<BuilderPage> OGroupBoxWizard::createPage(::vcl::WizardTypes::WizardState _nState)
+ {
+ OString sIdent(OString::number(_nState));
+ weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
+
+ switch (_nState)
+ {
+ case GBW_STATE_OPTIONLIST:
+ return std::make_unique<ORadioSelectionPage>(pPageContainer, this);
+
+ case GBW_STATE_DEFAULTOPTION:
+ return std::make_unique<ODefaultFieldSelectionPage>(pPageContainer, this);
+
+ case GBW_STATE_OPTIONVALUES:
+ return std::make_unique<OOptionValuesPage>(pPageContainer, this);
+
+ case GBW_STATE_DBFIELD:
+ return std::make_unique<OOptionDBFieldPage>(pPageContainer, this);
+
+ case GBW_STATE_FINALIZE:
+ return std::make_unique<OFinalizeGBWPage>(pPageContainer, this);
+ }
+
+ return nullptr;
+ }
+
+ vcl::WizardTypes::WizardState OGroupBoxWizard::determineNextState( ::vcl::WizardTypes::WizardState _nCurrentState ) const
+ {
+ switch (_nCurrentState)
+ {
+ case GBW_STATE_OPTIONLIST:
+ return GBW_STATE_DEFAULTOPTION;
+
+ case GBW_STATE_DEFAULTOPTION:
+ return GBW_STATE_OPTIONVALUES;
+
+ case GBW_STATE_OPTIONVALUES:
+ if (getContext().aFieldNames.hasElements())
+ return GBW_STATE_DBFIELD;
+ else
+ return GBW_STATE_FINALIZE;
+
+ case GBW_STATE_DBFIELD:
+ return GBW_STATE_FINALIZE;
+ }
+
+ return WZS_INVALID_STATE;
+ }
+
+ void OGroupBoxWizard::enterState(::vcl::WizardTypes::WizardState _nState)
+ {
+ // some stuff to do before calling the base class (modifying our settings)
+ switch (_nState)
+ {
+ case GBW_STATE_DEFAULTOPTION:
+ if (!m_bVisitedDefault)
+ { // assume that the first of the radio buttons should be selected
+ DBG_ASSERT(m_aSettings.aLabels.size(), "OGroupBoxWizard::enterState: should never have reached this state!");
+ m_aSettings.sDefaultField = m_aSettings.aLabels[0];
+ }
+ m_bVisitedDefault = true;
+ break;
+
+ case GBW_STATE_DBFIELD:
+ if (!m_bVisitedDB)
+ { // try to generate a default for the DB field
+ // (simply use the first field in the DB names collection)
+ if (getContext().aFieldNames.hasElements())
+ m_aSettings.sDBField = getContext().aFieldNames[0];
+ }
+ m_bVisitedDB = true;
+ break;
+ }
+
+ // setting the def button... to be done before the base class is called, too, 'cause the base class
+ // calls the pages, which are allowed to override our def button behaviour
+ defaultButton(GBW_STATE_FINALIZE == _nState ? WizardButtonFlags::FINISH : WizardButtonFlags::NEXT);
+
+ // allow "finish" on the last page only
+ enableButtons(WizardButtonFlags::FINISH, GBW_STATE_FINALIZE == _nState);
+ // allow previous on all pages but the first one
+ enableButtons(WizardButtonFlags::PREVIOUS, GBW_STATE_OPTIONLIST != _nState);
+ // allow next on all pages but the last one
+ enableButtons(WizardButtonFlags::NEXT, GBW_STATE_FINALIZE != _nState);
+
+ OControlWizard::enterState(_nState);
+ }
+
+ bool OGroupBoxWizard::onFinish()
+ {
+ // commit the basic control settings
+ commitControlSettings(&m_aSettings);
+
+ // create the radio buttons
+ try
+ {
+ OOptionGroupLayouter aLayouter( getComponentContext() );
+ aLayouter.doLayout(getContext(), getSettings());
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("OGroupBoxWizard::createRadios: caught an exception while creating the radio shapes!");
+ }
+
+ return OControlWizard::onFinish();
+ }
+
+ ORadioSelectionPage::ORadioSelectionPage(weld::Container* pPage, OControlWizard* pWizard)
+ : OGBWPage(pPage, pWizard, "modules/sabpilot/ui/groupradioselectionpage.ui", "GroupRadioSelectionPage")
+ , m_xRadioName(m_xBuilder->weld_entry("radiolabels"))
+ , m_xMoveRight(m_xBuilder->weld_button("toright"))
+ , m_xMoveLeft(m_xBuilder->weld_button("toleft"))
+ , m_xExistingRadios(m_xBuilder->weld_tree_view("radiobuttons"))
+ {
+ if (getContext().aFieldNames.hasElements())
+ {
+ enableFormDatasourceDisplay();
+ }
+
+ m_xMoveLeft->connect_clicked(LINK(this, ORadioSelectionPage, OnMoveEntry));
+ m_xMoveRight->connect_clicked(LINK(this, ORadioSelectionPage, OnMoveEntry));
+ m_xRadioName->connect_changed(LINK(this, ORadioSelectionPage, OnNameModified));
+ m_xExistingRadios->connect_changed(LINK(this, ORadioSelectionPage, OnEntrySelected));
+
+ implCheckMoveButtons();
+ m_xExistingRadios->set_selection_mode(SelectionMode::Multiple);
+
+ getDialog()->defaultButton(m_xMoveRight.get());
+ }
+
+ ORadioSelectionPage::~ORadioSelectionPage()
+ {
+ }
+
+ void ORadioSelectionPage::Activate()
+ {
+ OGBWPage::Activate();
+ m_xRadioName->grab_focus();
+ }
+
+ void ORadioSelectionPage::initializePage()
+ {
+ OGBWPage::initializePage();
+
+ m_xRadioName->set_text("");
+
+ // no need to initialize the list of radios here
+ // (we're the only one affecting this special setting, so it will be in the same state as last time this
+ // page was committed)
+
+ implCheckMoveButtons();
+ }
+
+ bool ORadioSelectionPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!OGBWPage::commitPage(_eReason))
+ return false;
+
+ // copy the names of the radio buttons to be inserted
+ // and initialize the values
+ OOptionGroupSettings& rSettings = getSettings();
+ rSettings.aLabels.clear();
+ rSettings.aValues.clear();
+ rSettings.aLabels.reserve(m_xExistingRadios->n_children());
+ rSettings.aValues.reserve(m_xExistingRadios->n_children());
+ for (sal_Int32 i=0; i<m_xExistingRadios->n_children(); ++i)
+ {
+ rSettings.aLabels.push_back(m_xExistingRadios->get_text(i));
+ rSettings.aValues.push_back(OUString::number((i + 1)));
+ }
+
+ return true;
+ }
+
+ IMPL_LINK( ORadioSelectionPage, OnMoveEntry, weld::Button&, rButton, void )
+ {
+ bool bMoveLeft = (m_xMoveLeft.get() == &rButton);
+ if (bMoveLeft)
+ {
+ while (m_xExistingRadios->count_selected_rows())
+ m_xExistingRadios->remove(m_xExistingRadios->get_selected_index());
+ }
+ else
+ {
+ m_xExistingRadios->append_text(m_xRadioName->get_text());
+ m_xRadioName->set_text("");
+ }
+
+ implCheckMoveButtons();
+
+ //adjust the focus
+ if (bMoveLeft)
+ m_xExistingRadios->grab_focus();
+ else
+ m_xRadioName->grab_focus();
+ }
+
+ IMPL_LINK_NOARG( ORadioSelectionPage, OnEntrySelected, weld::TreeView&, void )
+ {
+ implCheckMoveButtons();
+ }
+
+ IMPL_LINK_NOARG( ORadioSelectionPage, OnNameModified, weld::Entry&, void )
+ {
+ implCheckMoveButtons();
+ }
+
+ bool ORadioSelectionPage::canAdvance() const
+ {
+ return 0 != m_xExistingRadios->n_children();
+ }
+
+ void ORadioSelectionPage::implCheckMoveButtons()
+ {
+ bool bHaveSome = (0 != m_xExistingRadios->n_children());
+ bool bSelectedSome = (0 != m_xExistingRadios->count_selected_rows());
+ bool bUnfinishedInput = !m_xRadioName->get_text().isEmpty();
+
+ m_xMoveLeft->set_sensitive(bSelectedSome);
+ m_xMoveRight->set_sensitive(bUnfinishedInput);
+
+ getDialog()->enableButtons(WizardButtonFlags::NEXT, bHaveSome);
+
+ if (bUnfinishedInput)
+ {
+ if (!m_xMoveRight->get_has_default())
+ getDialog()->defaultButton(m_xMoveRight.get());
+ }
+ else
+ {
+ if (m_xMoveRight->get_has_default())
+ getDialog()->defaultButton(WizardButtonFlags::NEXT);
+ }
+ }
+
+ ODefaultFieldSelectionPage::ODefaultFieldSelectionPage(weld::Container* pPage, OControlWizard* pWizard)
+ : OMaybeListSelectionPage(pPage, pWizard, "modules/sabpilot/ui/defaultfieldselectionpage.ui", "DefaultFieldSelectionPage")
+ , m_xDefSelYes(m_xBuilder->weld_radio_button("defaultselectionyes"))
+ , m_xDefSelNo(m_xBuilder->weld_radio_button("defaultselectionno"))
+ , m_xDefSelection(m_xBuilder->weld_combo_box("defselectionfield"))
+ {
+ announceControls(*m_xDefSelYes, *m_xDefSelNo, *m_xDefSelection);
+ }
+
+ ODefaultFieldSelectionPage::~ODefaultFieldSelectionPage()
+ {
+ }
+
+ void ODefaultFieldSelectionPage::initializePage()
+ {
+ OMaybeListSelectionPage::initializePage();
+
+ const OOptionGroupSettings& rSettings = getSettings();
+
+ // fill the listbox
+ m_xDefSelection->clear();
+ for (auto const& label : rSettings.aLabels)
+ m_xDefSelection->append_text(label);
+
+ implInitialize(rSettings.sDefaultField);
+ }
+
+ bool ODefaultFieldSelectionPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!OMaybeListSelectionPage::commitPage(_eReason))
+ return false;
+
+ OOptionGroupSettings& rSettings = getSettings();
+ implCommit(rSettings.sDefaultField);
+
+ return true;
+ }
+
+ OOptionValuesPage::OOptionValuesPage(weld::Container* pPage, OControlWizard* pWizard)
+ : OGBWPage(pPage, pWizard, "modules/sabpilot/ui/optionvaluespage.ui", "OptionValuesPage")
+ , m_xValue(m_xBuilder->weld_entry("optionvalue"))
+ , m_xOptions(m_xBuilder->weld_tree_view("radiobuttons"))
+ , m_nLastSelection(::vcl::WizardTypes::WizardState(-1))
+ {
+ m_xOptions->connect_changed(LINK(this, OOptionValuesPage, OnOptionSelected));
+ }
+
+ OOptionValuesPage::~OOptionValuesPage()
+ {
+ }
+
+ IMPL_LINK_NOARG( OOptionValuesPage, OnOptionSelected, weld::TreeView&, void )
+ {
+ implTraveledOptions();
+ }
+
+ void OOptionValuesPage::Activate()
+ {
+ OGBWPage::Activate();
+ m_xValue->grab_focus();
+ }
+
+ void OOptionValuesPage::implTraveledOptions()
+ {
+ if (::vcl::WizardTypes::WizardState(-1) != m_nLastSelection)
+ {
+ // save the value for the last option
+ DBG_ASSERT(o3tl::make_unsigned(m_nLastSelection) < m_aUncommittedValues.size(), "OOptionValuesPage::implTraveledOptions: invalid previous selection index!");
+ m_aUncommittedValues[m_nLastSelection] = m_xValue->get_text();
+ }
+
+ m_nLastSelection = m_xOptions->get_selected_index();
+ DBG_ASSERT(o3tl::make_unsigned(m_nLastSelection) < m_aUncommittedValues.size(), "OOptionValuesPage::implTraveledOptions: invalid new selection index!");
+ m_xValue->set_text(m_aUncommittedValues[m_nLastSelection]);
+ }
+
+ void OOptionValuesPage::initializePage()
+ {
+ OGBWPage::initializePage();
+
+ const OOptionGroupSettings& rSettings = getSettings();
+ DBG_ASSERT(rSettings.aLabels.size(), "OOptionValuesPage::initializePage: no options!!");
+ DBG_ASSERT(rSettings.aLabels.size() == rSettings.aValues.size(), "OOptionValuesPage::initializePage: inconsistent data!");
+
+ // fill the list with all available options
+ m_xOptions->clear();
+ m_nLastSelection = -1;
+ for (auto const& label : rSettings.aLabels)
+ m_xOptions->append_text(label);
+
+ // remember the values ... can't set them directly in the settings without the explicit commit call
+ // so we need have a copy of the values
+ m_aUncommittedValues = rSettings.aValues;
+
+ // select the first entry
+ m_xOptions->select(0);
+ implTraveledOptions();
+ }
+
+ bool OOptionValuesPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!OGBWPage::commitPage(_eReason))
+ return false;
+
+ OOptionGroupSettings& rSettings = getSettings();
+
+ // commit the current value
+ implTraveledOptions();
+ // copy the uncommitted values
+ rSettings.aValues = m_aUncommittedValues;
+
+ return true;
+ }
+
+ OOptionDBFieldPage::OOptionDBFieldPage(weld::Container* pPage, OControlWizard* pWizard)
+ : ODBFieldPage(pPage, pWizard)
+ {
+ setDescriptionText(compmodule::ModuleRes(RID_STR_GROUPWIZ_DBFIELD));
+ }
+
+ OUString& OOptionDBFieldPage::getDBFieldSetting()
+ {
+ return static_cast<OGroupBoxWizard*>(getDialog())->getSettings().sDBField;
+ }
+
+ OFinalizeGBWPage::OFinalizeGBWPage(weld::Container* pPage, OControlWizard* pWizard)
+ : OGBWPage(pPage, pWizard, "modules/sabpilot/ui/optionsfinalpage.ui", "OptionsFinalPage")
+ , m_xName(m_xBuilder->weld_entry("nameit"))
+ {
+ }
+
+ OFinalizeGBWPage::~OFinalizeGBWPage()
+ {
+ }
+
+ void OFinalizeGBWPage::Activate()
+ {
+ OGBWPage::Activate();
+ m_xName->grab_focus();
+ }
+
+ bool OFinalizeGBWPage::canAdvance() const
+ {
+ return false;
+ }
+
+ void OFinalizeGBWPage::initializePage()
+ {
+ OGBWPage::initializePage();
+
+ const OOptionGroupSettings& rSettings = getSettings();
+ m_xName->set_text(rSettings.sControlLabel);
+ }
+
+ bool OFinalizeGBWPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!OGBWPage::commitPage(_eReason))
+ return false;
+
+ getSettings().sControlLabel = m_xName->get_text();
+
+ return true;
+ }
+
+} // namespace dbp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/groupboxwiz.hxx b/extensions/source/dbpilots/groupboxwiz.hxx
new file mode 100644
index 000000000..b9f375865
--- /dev/null
+++ b/extensions/source/dbpilots/groupboxwiz.hxx
@@ -0,0 +1,183 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_GROUPBOXWIZ_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_GROUPBOXWIZ_HXX
+
+#include "controlwizard.hxx"
+#include "commonpagesdbp.hxx"
+
+using vcl::WizardTypes::WizardState;
+using vcl::WizardTypes::CommitPageReason;
+
+namespace dbp
+{
+
+ struct OOptionGroupSettings : public OControlWizardSettings
+ {
+ std::vector<OUString> aLabels;
+ std::vector<OUString> aValues;
+ OUString sDefaultField;
+ OUString sDBField;
+ };
+
+ class OGroupBoxWizard final : public OControlWizard
+ {
+ OOptionGroupSettings m_aSettings;
+
+ bool m_bVisitedDefault : 1;
+ bool m_bVisitedDB : 1;
+
+ public:
+ OGroupBoxWizard(
+ weld::Window* _pParent,
+ const css::uno::Reference< css::beans::XPropertySet >& _rxObjectModel,
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext
+ );
+
+ OOptionGroupSettings& getSettings() { return m_aSettings; }
+
+ private:
+ // OWizardMachine overridables
+ virtual std::unique_ptr<BuilderPage> createPage( WizardState _nState ) override;
+ virtual WizardState determineNextState( WizardState _nCurrentState ) const override;
+ virtual void enterState( WizardState _nState ) override;
+ virtual bool onFinish() override;
+
+ virtual bool approveControl(sal_Int16 _nClassId) override;
+ };
+
+ class OGBWPage : public OControlWizardPage
+ {
+ public:
+ OGBWPage(weld::Container* pPage, OControlWizard* pWizard, const OUString& rUIXMLDescription, const OString& rID)
+ : OControlWizardPage(pPage, pWizard, rUIXMLDescription, rID)
+ {
+ }
+
+ protected:
+ OOptionGroupSettings& getSettings() { return static_cast<OGroupBoxWizard*>(getDialog())->getSettings(); }
+ };
+
+ class ORadioSelectionPage final : public OGBWPage
+ {
+ std::unique_ptr<weld::Entry> m_xRadioName;
+ std::unique_ptr<weld::Button> m_xMoveRight;
+ std::unique_ptr<weld::Button> m_xMoveLeft;
+ std::unique_ptr<weld::TreeView> m_xExistingRadios;
+
+ public:
+ explicit ORadioSelectionPage(weld::Container* pPage, OControlWizard* pWizard);
+ virtual ~ORadioSelectionPage() override;
+
+ private:
+ // BuilderPage overridables
+ void Activate() override;
+
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+ virtual bool canAdvance() const override;
+
+ DECL_LINK( OnMoveEntry, weld::Button&, void );
+ DECL_LINK( OnEntrySelected, weld::TreeView&, void );
+ DECL_LINK( OnNameModified, weld::Entry&, void );
+
+ void implCheckMoveButtons();
+ };
+
+ class ODefaultFieldSelectionPage final : public OMaybeListSelectionPage
+ {
+ std::unique_ptr<weld::RadioButton> m_xDefSelYes;
+ std::unique_ptr<weld::RadioButton> m_xDefSelNo;
+ std::unique_ptr<weld::ComboBox> m_xDefSelection;
+
+ public:
+ explicit ODefaultFieldSelectionPage(weld::Container* pPage, OControlWizard* pWizard);
+ virtual ~ODefaultFieldSelectionPage() override;
+
+ private:
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+
+ OOptionGroupSettings& getSettings() { return static_cast<OGroupBoxWizard*>(getDialog())->getSettings(); }
+ };
+
+ class OOptionValuesPage final : public OGBWPage
+ {
+ std::unique_ptr<weld::Entry> m_xValue;
+ std::unique_ptr<weld::TreeView> m_xOptions;
+
+ std::vector<OUString> m_aUncommittedValues;
+ ::vcl::WizardTypes::WizardState
+ m_nLastSelection;
+
+ public:
+ explicit OOptionValuesPage(weld::Container* pPage, OControlWizard* pWizard);
+ virtual ~OOptionValuesPage() override;
+
+ private:
+ // BuilderPage overridables
+ void Activate() override;
+
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+
+ void implTraveledOptions();
+
+ DECL_LINK( OnOptionSelected, weld::TreeView&, void );
+ };
+
+ class OOptionDBFieldPage : public ODBFieldPage
+ {
+ public:
+ explicit OOptionDBFieldPage(weld::Container* pPage, OControlWizard* pWizard);
+
+ protected:
+ // ODBFieldPage overridables
+ virtual OUString& getDBFieldSetting() override;
+ };
+
+ class OFinalizeGBWPage final : public OGBWPage
+ {
+ std::unique_ptr<weld::Entry> m_xName;
+
+ public:
+ explicit OFinalizeGBWPage(weld::Container* pPage, OControlWizard* pWizard);
+ virtual ~OFinalizeGBWPage() override;
+
+ private:
+ // BuilderPage overridables
+ void Activate() override;
+
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+ virtual bool canAdvance() const override;
+ };
+
+
+} // namespace dbp
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_GROUPBOXWIZ_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/listcombowizard.cxx b/extensions/source/dbpilots/listcombowizard.cxx
new file mode 100644
index 000000000..cde03e223
--- /dev/null
+++ b/extensions/source/dbpilots/listcombowizard.cxx
@@ -0,0 +1,485 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "listcombowizard.hxx"
+#include "commonpagesdbp.hxx"
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/form/ListSourceType.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <connectivity/dbtools.hxx>
+#include <helpids.h>
+#include <osl/diagnose.h>
+
+
+namespace dbp
+{
+
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::form;
+ using namespace ::dbtools;
+
+ OListComboWizard::OListComboWizard(weld::Window* _pParent,
+ const Reference< XPropertySet >& _rxObjectModel, const Reference< XComponentContext >& _rxContext )
+ : OControlWizard(_pParent, _rxObjectModel, _rxContext)
+ , m_bListBox(false)
+ , m_bHadDataSelection(true)
+ {
+ initControlSettings(&m_aSettings);
+
+ m_xPrevPage->set_help_id(HID_LISTWIZARD_PREVIOUS);
+ m_xNextPage->set_help_id(HID_LISTWIZARD_NEXT);
+ m_xCancel->set_help_id(HID_LISTWIZARD_CANCEL);
+ m_xFinish->set_help_id(HID_LISTWIZARD_FINISH);
+
+ // if we do not need the data source selection page ...
+ if (!needDatasourceSelection())
+ { // ... skip it!
+ skip();
+ m_bHadDataSelection = false;
+ }
+ }
+
+ bool OListComboWizard::approveControl(sal_Int16 _nClassId)
+ {
+ switch (_nClassId)
+ {
+ case FormComponentType::LISTBOX:
+ m_bListBox = true;
+ setTitleBase(compmodule::ModuleRes(RID_STR_LISTWIZARD_TITLE));
+ return true;
+ case FormComponentType::COMBOBOX:
+ m_bListBox = false;
+ setTitleBase(compmodule::ModuleRes(RID_STR_COMBOWIZARD_TITLE));
+ return true;
+ }
+ return false;
+ }
+
+ std::unique_ptr<BuilderPage> OListComboWizard::createPage(WizardState _nState)
+ {
+ OString sIdent(OString::number(_nState));
+ weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
+
+ switch (_nState)
+ {
+ case LCW_STATE_DATASOURCE_SELECTION:
+ return std::make_unique<OTableSelectionPage>(pPageContainer, this);
+ case LCW_STATE_TABLESELECTION:
+ return std::make_unique<OContentTableSelection>(pPageContainer, this);
+ case LCW_STATE_FIELDSELECTION:
+ return std::make_unique<OContentFieldSelection>(pPageContainer, this);
+ case LCW_STATE_FIELDLINK:
+ return std::make_unique<OLinkFieldsPage>(pPageContainer, this);
+ case LCW_STATE_COMBODBFIELD:
+ return std::make_unique<OComboDBFieldPage>(pPageContainer, this);
+ }
+
+ return nullptr;
+ }
+
+ vcl::WizardTypes::WizardState OListComboWizard::determineNextState( WizardState _nCurrentState ) const
+ {
+ switch (_nCurrentState)
+ {
+ case LCW_STATE_DATASOURCE_SELECTION:
+ return LCW_STATE_TABLESELECTION;
+ case LCW_STATE_TABLESELECTION:
+ return LCW_STATE_FIELDSELECTION;
+ case LCW_STATE_FIELDSELECTION:
+ return getFinalState();
+ }
+
+ return WZS_INVALID_STATE;
+ }
+
+ void OListComboWizard::enterState(WizardState _nState)
+ {
+ OControlWizard::enterState(_nState);
+
+ enableButtons(WizardButtonFlags::PREVIOUS, m_bHadDataSelection ? (LCW_STATE_DATASOURCE_SELECTION < _nState) : LCW_STATE_TABLESELECTION < _nState);
+ enableButtons(WizardButtonFlags::NEXT, getFinalState() != _nState);
+ if (_nState < getFinalState())
+ enableButtons(WizardButtonFlags::FINISH, false);
+
+ if (getFinalState() == _nState)
+ defaultButton(WizardButtonFlags::FINISH);
+ }
+
+
+ bool OListComboWizard::leaveState(WizardState _nState)
+ {
+ if (!OControlWizard::leaveState(_nState))
+ return false;
+
+ if (getFinalState() == _nState)
+ defaultButton(WizardButtonFlags::NEXT);
+
+ return true;
+ }
+
+
+ void OListComboWizard::implApplySettings()
+ {
+ try
+ {
+ // for quoting identifiers, we need the connection meta data
+ Reference< XConnection > xConn = getFormConnection();
+ DBG_ASSERT(xConn.is(), "OListComboWizard::implApplySettings: no connection, unable to quote!");
+ Reference< XDatabaseMetaData > xMetaData;
+ if (xConn.is())
+ xMetaData = xConn->getMetaData();
+
+ // do some quotings
+ if (xMetaData.is())
+ {
+ OUString sQuoteString = xMetaData->getIdentifierQuoteString();
+ if (isListBox()) // only when we have a listbox this should be not empty
+ getSettings().sLinkedListField = quoteName(sQuoteString, getSettings().sLinkedListField);
+
+ OUString sCatalog, sSchema, sName;
+ ::dbtools::qualifiedNameComponents( xMetaData, getSettings().sListContentTable, sCatalog, sSchema, sName, ::dbtools::EComposeRule::InDataManipulation );
+ getSettings().sListContentTable = ::dbtools::composeTableNameForSelect( xConn, sCatalog, sSchema, sName );
+
+ getSettings().sListContentField = quoteName(sQuoteString, getSettings().sListContentField);
+ }
+
+ // ListSourceType: SQL
+ getContext().xObjectModel->setPropertyValue("ListSourceType", makeAny(sal_Int32(ListSourceType_SQL)));
+
+ if (isListBox())
+ {
+ // BoundColumn: 1
+ getContext().xObjectModel->setPropertyValue("BoundColumn", makeAny(sal_Int16(1)));
+
+ // build the statement to set as list source
+ OUString sStatement = "SELECT " +
+ getSettings().sListContentField + ", " + getSettings().sLinkedListField +
+ " FROM " + getSettings().sListContentTable;
+ Sequence< OUString > aListSource { sStatement };
+ getContext().xObjectModel->setPropertyValue("ListSource", makeAny(aListSource));
+ }
+ else
+ {
+ // build the statement to set as list source
+ OUString sStatement = "SELECT DISTINCT " +
+ getSettings().sListContentField +
+ " FROM " + getSettings().sListContentTable;
+ getContext().xObjectModel->setPropertyValue( "ListSource", makeAny(sStatement));
+ }
+
+ // the bound field
+ getContext().xObjectModel->setPropertyValue("DataField", makeAny(getSettings().sLinkedFormField));
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("OListComboWizard::implApplySettings: could not set the property values for the listbox!");
+ }
+ }
+
+
+ bool OListComboWizard::onFinish()
+ {
+ if ( !OControlWizard::onFinish() )
+ return false;
+
+ implApplySettings();
+ return true;
+ }
+
+ Reference< XNameAccess > OLCPage::getTables() const
+ {
+ Reference< XConnection > xConn = getFormConnection();
+ DBG_ASSERT(xConn.is(), "OLCPage::getTables: should have an active connection when reaching this page!");
+
+ Reference< XTablesSupplier > xSuppTables(xConn, UNO_QUERY);
+ Reference< XNameAccess > xTables;
+ if (xSuppTables.is())
+ xTables = xSuppTables->getTables();
+
+ DBG_ASSERT(xTables.is() || !xConn.is(), "OLCPage::getTables: got no tables from the connection!");
+
+ return xTables;
+ }
+
+
+ Sequence< OUString > OLCPage::getTableFields()
+ {
+ Reference< XNameAccess > xTables = getTables();
+ Sequence< OUString > aColumnNames;
+ if (xTables.is())
+ {
+ try
+ {
+ // the list table as XColumnsSupplier
+ Reference< XColumnsSupplier > xSuppCols;
+ xTables->getByName(getSettings().sListContentTable) >>= xSuppCols;
+ DBG_ASSERT(xSuppCols.is(), "OLCPage::getTableFields: no columns supplier!");
+
+ // the columns
+ Reference< XNameAccess > xColumns;
+ if (xSuppCols.is())
+ xColumns = xSuppCols->getColumns();
+
+ // the column names
+ if (xColumns.is())
+ aColumnNames = xColumns->getElementNames();
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "extensions.dbpilots", "OLinkFieldsPage::initializePage: caught an exception while retrieving the columns");
+ }
+ }
+ return aColumnNames;
+ }
+
+ OContentTableSelection::OContentTableSelection(weld::Container* pPage, OListComboWizard* pWizard)
+ : OLCPage(pPage, pWizard, "modules/sabpilot/ui/contenttablepage.ui", "TableSelectionPage")
+ , m_xSelectTable(m_xBuilder->weld_tree_view("table"))
+ {
+ enableFormDatasourceDisplay();
+
+ m_xSelectTable->connect_row_activated(LINK(this, OContentTableSelection, OnTableDoubleClicked));
+ m_xSelectTable->connect_changed(LINK(this, OContentTableSelection, OnTableSelected));
+ }
+
+ OContentTableSelection::~OContentTableSelection()
+ {
+ }
+
+ void OContentTableSelection::Activate()
+ {
+ OLCPage::Activate();
+ m_xSelectTable->grab_focus();
+ }
+
+ bool OContentTableSelection::canAdvance() const
+ {
+ if (!OLCPage::canAdvance())
+ return false;
+
+ return 0 != m_xSelectTable->count_selected_rows();
+ }
+
+ IMPL_LINK_NOARG( OContentTableSelection, OnTableSelected, weld::TreeView&, void )
+ {
+ updateDialogTravelUI();
+ }
+
+ IMPL_LINK( OContentTableSelection, OnTableDoubleClicked, weld::TreeView&, _rListBox, bool )
+ {
+ if (_rListBox.count_selected_rows())
+ getDialog()->travelNext();
+ return true;
+ }
+
+ void OContentTableSelection::initializePage()
+ {
+ OLCPage::initializePage();
+
+ // fill the list with the table name
+ m_xSelectTable->clear();
+ try
+ {
+ Reference< XNameAccess > xTables = getTables();
+ Sequence< OUString > aTableNames;
+ if (xTables.is())
+ aTableNames = xTables->getElementNames();
+ fillListBox(*m_xSelectTable, aTableNames);
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("OContentTableSelection::initializePage: could not retrieve the table names!");
+ }
+
+ m_xSelectTable->select_text(getSettings().sListContentTable);
+ }
+
+
+ bool OContentTableSelection::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!OLCPage::commitPage(_eReason))
+ return false;
+
+ OListComboSettings& rSettings = getSettings();
+ rSettings.sListContentTable = m_xSelectTable->get_selected_text();
+ if (rSettings.sListContentTable.isEmpty() && (::vcl::WizardTypes::eTravelBackward != _eReason))
+ // need to select a table
+ return false;
+
+ return true;
+ }
+
+ OContentFieldSelection::OContentFieldSelection(weld::Container* pPage, OListComboWizard* pWizard)
+ : OLCPage(pPage, pWizard, "modules/sabpilot/ui/contentfieldpage.ui", "FieldSelectionPage")
+ , m_xSelectTableField(m_xBuilder->weld_tree_view("selectfield"))
+ , m_xDisplayedField(m_xBuilder->weld_entry("displayfield"))
+ , m_xInfo(m_xBuilder->weld_label("info"))
+ {
+ m_xInfo->set_label(compmodule::ModuleRes( isListBox() ? RID_STR_FIELDINFO_LISTBOX : RID_STR_FIELDINFO_COMBOBOX));
+ m_xSelectTableField->connect_changed(LINK(this, OContentFieldSelection, OnFieldSelected));
+ m_xSelectTableField->connect_row_activated(LINK(this, OContentFieldSelection, OnTableDoubleClicked));
+ }
+
+ OContentFieldSelection::~OContentFieldSelection()
+ {
+ }
+
+ void OContentFieldSelection::initializePage()
+ {
+ OLCPage::initializePage();
+
+ // fill the list of fields
+ fillListBox(*m_xSelectTableField, getTableFields());
+
+ m_xSelectTableField->select_text(getSettings().sListContentField);
+ m_xDisplayedField->set_text(getSettings().sListContentField);
+ }
+
+ bool OContentFieldSelection::canAdvance() const
+ {
+ if (!OLCPage::canAdvance())
+ return false;
+
+ return 0 != m_xSelectTableField->count_selected_rows();
+ }
+
+ IMPL_LINK_NOARG( OContentFieldSelection, OnTableDoubleClicked, weld::TreeView&, bool )
+ {
+ if (m_xSelectTableField->count_selected_rows())
+ getDialog()->travelNext();
+ return true;
+ }
+
+ IMPL_LINK_NOARG( OContentFieldSelection, OnFieldSelected, weld::TreeView&, void )
+ {
+ updateDialogTravelUI();
+ m_xDisplayedField->set_text(m_xSelectTableField->get_selected_text());
+ }
+
+ bool OContentFieldSelection::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!OLCPage::commitPage(_eReason))
+ return false;
+
+ getSettings().sListContentField = m_xSelectTableField->get_selected_text();
+
+ return true;
+ }
+
+ OLinkFieldsPage::OLinkFieldsPage(weld::Container* pPage, OListComboWizard* pWizard)
+ : OLCPage(pPage, pWizard, "modules/sabpilot/ui/fieldlinkpage.ui", "FieldLinkPage")
+ , m_xValueListField(m_xBuilder->weld_combo_box("valuefield"))
+ , m_xTableField(m_xBuilder->weld_combo_box("listtable"))
+ {
+ m_xValueListField->connect_changed(LINK(this, OLinkFieldsPage, OnSelectionModified));
+ m_xTableField->connect_changed(LINK(this, OLinkFieldsPage, OnSelectionModified));
+ }
+
+ OLinkFieldsPage::~OLinkFieldsPage()
+ {
+ }
+
+ void OLinkFieldsPage::Activate()
+ {
+ OLCPage::Activate();
+ m_xValueListField->grab_focus();
+ }
+
+ void OLinkFieldsPage::initializePage()
+ {
+ OLCPage::initializePage();
+
+ // fill the value list
+ fillListBox(*m_xValueListField, getContext().aFieldNames);
+ // fill the table field list
+ fillListBox(*m_xTableField, getTableFields());
+
+ // the initial selections
+ m_xValueListField->set_entry_text(getSettings().sLinkedFormField);
+ m_xTableField->set_entry_text(getSettings().sLinkedListField);
+
+ implCheckFinish();
+ }
+
+ bool OLinkFieldsPage::canAdvance() const
+ {
+ // we're on the last page here, no travelNext allowed ...
+ return false;
+ }
+
+ void OLinkFieldsPage::implCheckFinish()
+ {
+ bool bInvalidSelection = (-1 == m_xValueListField->find_text(m_xValueListField->get_active_text()));
+ bInvalidSelection |= (-1 == m_xTableField->find_text(m_xTableField->get_active_text()));
+ getDialog()->enableButtons(WizardButtonFlags::FINISH, !bInvalidSelection);
+ }
+
+ IMPL_LINK_NOARG(OLinkFieldsPage, OnSelectionModified, weld::ComboBox&, void)
+ {
+ implCheckFinish();
+ }
+
+ bool OLinkFieldsPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!OLCPage::commitPage(_eReason))
+ return false;
+
+ getSettings().sLinkedFormField = m_xValueListField->get_active_text();
+ getSettings().sLinkedListField = m_xTableField->get_active_text();
+
+ return true;
+ }
+
+ OComboDBFieldPage::OComboDBFieldPage(weld::Container* pPage, OControlWizard* pWizard)
+ : ODBFieldPage(pPage, pWizard)
+ {
+ setDescriptionText(compmodule::ModuleRes(RID_STR_COMBOWIZ_DBFIELD));
+ }
+
+ OUString& OComboDBFieldPage::getDBFieldSetting()
+ {
+ return static_cast<OListComboWizard*>(getDialog())->getSettings().sLinkedFormField;
+ }
+
+ void OComboDBFieldPage::Activate()
+ {
+ ODBFieldPage::Activate();
+ getDialog()->enableButtons(WizardButtonFlags::FINISH, true);
+ }
+
+ bool OComboDBFieldPage::canAdvance() const
+ {
+ // we're on the last page here, no travelNext allowed ...
+ return false;
+ }
+
+} // namespace dbp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/listcombowizard.hxx b/extensions/source/dbpilots/listcombowizard.hxx
new file mode 100644
index 000000000..6fad30110
--- /dev/null
+++ b/extensions/source/dbpilots/listcombowizard.hxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_LISTCOMBOWIZARD_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_LISTCOMBOWIZARD_HXX
+
+#include "controlwizard.hxx"
+#include "commonpagesdbp.hxx"
+
+using vcl::WizardTypes::WizardState;
+using vcl::WizardTypes::CommitPageReason;
+
+namespace dbp
+{
+
+#define LCW_STATE_DATASOURCE_SELECTION 0
+#define LCW_STATE_TABLESELECTION 1
+#define LCW_STATE_FIELDSELECTION 2
+#define LCW_STATE_FIELDLINK 3
+#define LCW_STATE_COMBODBFIELD 4
+
+ struct OListComboSettings : public OControlWizardSettings
+ {
+ OUString sListContentTable;
+ OUString sListContentField;
+ OUString sLinkedFormField;
+ OUString sLinkedListField;
+ };
+
+ class OListComboWizard final : public OControlWizard
+ {
+ OListComboSettings m_aSettings;
+ bool m_bListBox : 1;
+ bool m_bHadDataSelection : 1;
+
+ public:
+ OListComboWizard(
+ weld::Window* pParent,
+ const css::uno::Reference< css::beans::XPropertySet >& _rxObjectModel,
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext
+ );
+
+ OListComboSettings& getSettings() { return m_aSettings; }
+
+ bool isListBox() const { return m_bListBox; }
+
+ private:
+ // OWizardMachine overridables
+ virtual std::unique_ptr<BuilderPage> createPage( WizardState _nState ) override;
+ virtual WizardState determineNextState( WizardState _nCurrentState ) const override;
+ virtual void enterState( WizardState _nState ) override;
+ virtual bool leaveState( WizardState _nState ) override;
+ virtual bool onFinish() override;
+
+ virtual bool approveControl(sal_Int16 _nClassId) override;
+
+ WizardState getFinalState() const { return isListBox() ? LCW_STATE_FIELDLINK : LCW_STATE_COMBODBFIELD; }
+
+ void implApplySettings();
+ };
+
+ class OLCPage : public OControlWizardPage
+ {
+ public:
+ OLCPage(weld::Container* pPage, OListComboWizard* pWizard, const OUString& rUIXMLDescription, const OString& rID)
+ : OControlWizardPage(pPage, pWizard, rUIXMLDescription, rID)
+ {
+ }
+
+ protected:
+ OListComboSettings& getSettings() { return static_cast<OListComboWizard*>(getDialog())->getSettings(); }
+ bool isListBox() { return static_cast<OListComboWizard*>(getDialog())->isListBox(); }
+
+ protected:
+ css::uno::Reference< css::container::XNameAccess > getTables() const;
+ css::uno::Sequence< OUString > getTableFields();
+ };
+
+ class OContentTableSelection final : public OLCPage
+ {
+ std::unique_ptr<weld::TreeView> m_xSelectTable;
+
+ public:
+ explicit OContentTableSelection(weld::Container* pPage, OListComboWizard* pWizard);
+ virtual ~OContentTableSelection() override;
+
+ private:
+ // BuilderPage overridables
+ virtual void Activate() override;
+
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+ virtual bool canAdvance() const override;
+
+ DECL_LINK( OnTableDoubleClicked, weld::TreeView&, bool );
+ DECL_LINK( OnTableSelected, weld::TreeView&, void );
+ };
+
+ class OContentFieldSelection final : public OLCPage
+ {
+ std::unique_ptr<weld::TreeView> m_xSelectTableField;
+ std::unique_ptr<weld::Entry> m_xDisplayedField;
+ std::unique_ptr<weld::Label> m_xInfo;
+
+ public:
+ explicit OContentFieldSelection(weld::Container* pPage, OListComboWizard* pWizard);
+ virtual ~OContentFieldSelection() override;
+
+ private:
+ DECL_LINK( OnFieldSelected, weld::TreeView&, void );
+ DECL_LINK( OnTableDoubleClicked, weld::TreeView&, bool );
+
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+ virtual bool canAdvance() const override;
+ };
+
+ class OLinkFieldsPage final : public OLCPage
+ {
+ std::unique_ptr<weld::ComboBox> m_xValueListField;
+ std::unique_ptr<weld::ComboBox> m_xTableField;
+
+ public:
+ explicit OLinkFieldsPage(weld::Container* pPage, OListComboWizard* pWizard);
+ virtual ~OLinkFieldsPage() override;
+
+ private:
+ // BuilderPage overridables
+ virtual void Activate() override;
+
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+ virtual bool canAdvance() const override;
+
+ void implCheckFinish();
+
+ DECL_LINK(OnSelectionModified, weld::ComboBox&, void);
+ };
+
+ class OComboDBFieldPage : public ODBFieldPage
+ {
+ public:
+ explicit OComboDBFieldPage(weld::Container* pPage, OControlWizard* pWizard);
+
+ protected:
+ // BuilderPage overridables
+ virtual void Activate() override;
+
+ // OWizardPage overridables
+ virtual bool canAdvance() const override;
+
+ // ODBFieldPage overridables
+ virtual OUString& getDBFieldSetting() override;
+ };
+
+
+} // namespace dbp
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_LISTCOMBOWIZARD_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/moduledbp.cxx b/extensions/source/dbpilots/moduledbp.cxx
new file mode 100644
index 000000000..0a8f8fd4d
--- /dev/null
+++ b/extensions/source/dbpilots/moduledbp.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <componentmodule.cxx>
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/optiongrouplayouter.cxx b/extensions/source/dbpilots/optiongrouplayouter.cxx
new file mode 100644
index 000000000..04cd5a847
--- /dev/null
+++ b/extensions/source/dbpilots/optiongrouplayouter.cxx
@@ -0,0 +1,203 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optiongrouplayouter.hxx"
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/drawing/ShapeCollection.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/drawing/XShapeGrouper.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include "groupboxwiz.hxx"
+#include "dbptools.hxx"
+#include <osl/diagnose.h>
+
+
+namespace dbp
+{
+
+
+#define BUTTON_HEIGHT 300
+#define HEIGHT 450
+#define OFFSET 300
+#define MIN_WIDTH 600
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::drawing;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::text;
+ using namespace ::com::sun::star::view;
+
+ OOptionGroupLayouter::OOptionGroupLayouter(const Reference< XComponentContext >& _rxContext)
+ :mxContext(_rxContext)
+ {
+ }
+
+
+ void OOptionGroupLayouter::doLayout(const OControlWizardContext& _rContext, const OOptionGroupSettings& _rSettings)
+ {
+ Reference< XShapes > xPageShapes = _rContext.xDrawPage;
+ if (!xPageShapes.is())
+ {
+ OSL_FAIL("OOptionGroupLayouter::OOptionGroupLayouter: missing the XShapes interface for the page!");
+ return;
+ }
+
+ Reference< XMultiServiceFactory > xDocFactory(_rContext.xDocumentModel, UNO_QUERY);
+ if (!xDocFactory.is())
+ {
+ OSL_FAIL("OOptionGroupLayouter::OOptionGroupLayouter: no document service factory!");
+ return;
+ }
+
+ // no. of buttons to create
+ sal_Int32 nRadioButtons = _rSettings.aLabels.size();
+
+ // the shape of the groupbox
+ css::awt::Size aControlShapeSize = _rContext.xObjectShape->getSize();
+ // maybe need to adjust the size if the control shapes
+ sal_Int32 nMinShapeHeight = BUTTON_HEIGHT*(nRadioButtons+1) + BUTTON_HEIGHT + BUTTON_HEIGHT/4;
+ if (aControlShapeSize.Height < nMinShapeHeight)
+ aControlShapeSize.Height = nMinShapeHeight;
+ if (aControlShapeSize.Width < MIN_WIDTH)
+ aControlShapeSize.Width = MIN_WIDTH;
+ _rContext.xObjectShape->setSize(aControlShapeSize);
+
+ // if we're working on a writer document, we need to anchor the shape
+ implAnchorShape(Reference< XPropertySet >(_rContext.xObjectShape, UNO_QUERY));
+
+ // shape collection (for grouping the shapes)
+ Reference< XShapes > xButtonCollection( ShapeCollection::create(mxContext) );
+ // first member : the shape of the control
+ xButtonCollection->add(_rContext.xObjectShape.get());
+
+ sal_Int32 nTempHeight = (aControlShapeSize.Height - BUTTON_HEIGHT/4) / (nRadioButtons + 1);
+
+ css::awt::Point aShapePosition = _rContext.xObjectShape->getPosition();
+
+ css::awt::Size aButtonSize(aControlShapeSize);
+ aButtonSize.Width = aControlShapeSize.Width - OFFSET;
+ aButtonSize.Height = HEIGHT;
+ css::awt::Point aButtonPosition;
+ aButtonPosition.X = aShapePosition.X + OFFSET;
+
+ OUString sElementsName("RadioGroup");
+ disambiguateName(Reference< XNameAccess >(_rContext.xForm, UNO_QUERY), sElementsName);
+
+ auto aLabelIter = _rSettings.aLabels.cbegin();
+ auto aValueIter = _rSettings.aValues.cbegin();
+ for (sal_Int32 i=0; i<nRadioButtons; ++i, ++aLabelIter, ++aValueIter)
+ {
+ aButtonPosition.Y = aShapePosition.Y + (i+1) * nTempHeight;
+
+ Reference< XPropertySet > xRadioModel(
+ xDocFactory->createInstance("com.sun.star.form.component.RadioButton"),
+ UNO_QUERY);
+
+ // the label
+ xRadioModel->setPropertyValue("Label", makeAny(*aLabelIter));
+ // the value
+ xRadioModel->setPropertyValue("RefValue", makeAny(*aValueIter));
+
+ // default selection
+ if (_rSettings.sDefaultField == *aLabelIter)
+ xRadioModel->setPropertyValue("DefaultState", makeAny(sal_Int16(1)));
+
+ // the connection to the database field
+ if (!_rSettings.sDBField.isEmpty())
+ xRadioModel->setPropertyValue("DataField", makeAny(_rSettings.sDBField));
+
+ // the name for the model
+ xRadioModel->setPropertyValue("Name", makeAny(sElementsName));
+
+ // create a shape for the radio button
+ Reference< XControlShape > xRadioShape(
+ xDocFactory->createInstance("com.sun.star.drawing.ControlShape"),
+ UNO_QUERY);
+ Reference< XPropertySet > xShapeProperties(xRadioShape, UNO_QUERY);
+
+ // if we're working on a writer document, we need to anchor the shape
+ implAnchorShape(xShapeProperties);
+
+ // position it
+ xRadioShape->setSize(aButtonSize);
+ xRadioShape->setPosition(aButtonPosition);
+ // knitting with the model
+ xRadioShape->setControl(Reference< XControlModel >(xRadioModel, UNO_QUERY));
+
+ // the name of the shape
+ // tdf#117282 com.sun.star.drawing.ControlShape *has* no property
+ // of type 'Name'. In older versions it was an error that this did
+ // not throw an UnknownPropertyException. Still, it was never set
+ // at the Shape/SdrObject and was lost.
+ // Thus - just do no tset it. It is/stays part of the FormControl
+ // data, so it will be shown in the FormControl dialogs. It is not
+ // shown/used in SdrObject::Name dialog (e.g. context menu/Name...)
+ // if (xShapeProperties.is())
+ // xShapeProperties->setPropertyValue("Name", makeAny(sElementsName));
+
+ // add to the page
+ xPageShapes->add(xRadioShape.get());
+ // add to the collection (for the later grouping)
+ xButtonCollection->add(xRadioShape.get());
+
+ // set the GroupBox as "LabelControl" for the RadioButton
+ // (_after_ having inserted the model into the page!)
+ xRadioModel->setPropertyValue("LabelControl", makeAny(_rContext.xObjectModel));
+ }
+
+ // group the shapes
+ try
+ {
+ Reference< XShapeGrouper > xGrouper(_rContext.xDrawPage, UNO_QUERY);
+ if (xGrouper.is())
+ {
+ Reference< XShapeGroup > xGroupedOptions = xGrouper->group(xButtonCollection);
+ Reference< XSelectionSupplier > xSelector(_rContext.xDocumentModel->getCurrentController(), UNO_QUERY);
+ if (xSelector.is())
+ xSelector->select(makeAny(xGroupedOptions));
+ }
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL("OOptionGroupLayouter::doLayout: caught an exception while grouping the shapes!");
+ }
+ }
+
+
+ void OOptionGroupLayouter::implAnchorShape(const Reference< XPropertySet >& _rxShapeProps)
+ {
+ static const char s_sAnchorPropertyName[] = "AnchorType";
+ Reference< XPropertySetInfo > xPropertyInfo;
+ if (_rxShapeProps.is())
+ xPropertyInfo = _rxShapeProps->getPropertySetInfo();
+ if (xPropertyInfo.is() && xPropertyInfo->hasPropertyByName(s_sAnchorPropertyName))
+ _rxShapeProps->setPropertyValue(s_sAnchorPropertyName, makeAny(TextContentAnchorType_AT_PAGE));
+ }
+
+
+} // namespace dbp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/optiongrouplayouter.hxx b/extensions/source/dbpilots/optiongrouplayouter.hxx
new file mode 100644
index 000000000..7891f10d9
--- /dev/null
+++ b/extensions/source/dbpilots/optiongrouplayouter.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_OPTIONGROUPLAYOUTER_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_OPTIONGROUPLAYOUTER_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+
+namespace dbp
+{
+
+
+ struct OControlWizardContext;
+ struct OOptionGroupSettings;
+
+ class OOptionGroupLayouter final
+ {
+ css::uno::Reference< css::uno::XComponentContext >
+ mxContext;
+
+ public:
+ explicit OOptionGroupLayouter(
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext
+ );
+
+ void doLayout(
+ const OControlWizardContext& _rContext,
+ const OOptionGroupSettings& _rSettings
+ );
+
+ private:
+ static void implAnchorShape(
+ const css::uno::Reference< css::beans::XPropertySet >& _rxShapeProps
+ );
+ };
+
+
+} // namespace dbp
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_OPTIONGROUPLAYOUTER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/unoautopilot.hxx b/extensions/source/dbpilots/unoautopilot.hxx
new file mode 100644
index 000000000..4b69cd615
--- /dev/null
+++ b/extensions/source/dbpilots/unoautopilot.hxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_UNOAUTOPILOT_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_UNOAUTOPILOT_HXX
+
+#include <svtools/genericunodialog.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <componentmodule.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <vcl/svapp.hxx>
+
+namespace dbp
+{
+ typedef ::svt::OGenericUnoDialog OUnoAutoPilot_Base;
+ template <class TYPE, class SERVICEINFO>
+ class OUnoAutoPilot final
+ :public OUnoAutoPilot_Base
+ ,public ::comphelper::OPropertyArrayUsageHelper< OUnoAutoPilot< TYPE, SERVICEINFO > >
+ {
+ explicit OUnoAutoPilot(const css::uno::Reference< css::uno::XComponentContext >& _rxORB)
+ : OUnoAutoPilot_Base(_rxORB)
+ {
+ }
+
+
+ css::uno::Reference< css::beans::XPropertySet > m_xObjectModel;
+
+ public:
+ // XTypeProvider
+ virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId( ) override
+ {
+ return css::uno::Sequence<sal_Int8>();
+ }
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return getImplementationName_Static();
+ }
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return getSupportedServiceNames_Static();
+ }
+
+ // XServiceInfo - static methods
+ /// @throws css::uno::RuntimeException
+ static css::uno::Sequence< OUString > getSupportedServiceNames_Static()
+ {
+ return SERVICEINFO::getServiceNames();
+ }
+
+ /// @throws css::uno::RuntimeException
+ static OUString getImplementationName_Static()
+ {
+ return SERVICEINFO::getImplementationName();
+ }
+
+ static css::uno::Reference< css::uno::XInterface >
+ SAL_CALL Create(const css::uno::Reference< css::lang::XMultiServiceFactory >& _rxFactory)
+ {
+ return *(new OUnoAutoPilot<TYPE, SERVICEINFO>( comphelper::getComponentContext(_rxFactory) ));
+ }
+
+ // XPropertySet
+ virtual css::uno::Reference< css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override
+ {
+ css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ return xInfo;
+ }
+
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override
+ {
+ return *this->getArrayHelper();
+ }
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override
+ {
+ css::uno::Sequence< css::beans::Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+ }
+
+ private:
+ // OGenericUnoDialog overridables
+ virtual std::unique_ptr<weld::DialogController> createDialog(const css::uno::Reference<css::awt::XWindow>& rParent) override
+ {
+ return std::make_unique<TYPE>(Application::GetFrameWeld(rParent), m_xObjectModel, m_aContext);
+ }
+
+ virtual void implInitialize(const css::uno::Any& _rValue) override
+ {
+ css::beans::PropertyValue aArgument;
+ if (_rValue >>= aArgument)
+ if (aArgument.Name == "ObjectModel")
+ {
+ aArgument.Value >>= m_xObjectModel;
+ return;
+ }
+
+ OUnoAutoPilot_Base::implInitialize(_rValue);
+ }
+ };
+
+} // namespace dbp
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_UNOAUTOPILOT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/wizardcontext.hxx b/extensions/source/dbpilots/wizardcontext.hxx
new file mode 100644
index 000000000..58cda7c20
--- /dev/null
+++ b/extensions/source/dbpilots/wizardcontext.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_WIZARDCONTEXT_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_WIZARDCONTEXT_HXX
+
+#include <sal/config.h>
+
+#include <map>
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdb/XDatabaseContext.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+
+namespace dbp
+{
+
+ struct OControlWizardContext
+ {
+ // the global data source context
+ css::uno::Reference< css::sdb::XDatabaseContext >
+ xDatasourceContext;
+
+ // the control mode
+ css::uno::Reference< css::beans::XPropertySet >
+ xObjectModel;
+ // the form the control model belongs to
+ css::uno::Reference< css::beans::XPropertySet >
+ xForm;
+ // the form as rowset
+ css::uno::Reference< css::sdbc::XRowSet >
+ xRowSet;
+
+ // the model of the document
+ css::uno::Reference< css::frame::XModel >
+ xDocumentModel;
+ // the page where the control mode resides
+ css::uno::Reference< css::drawing::XDrawPage >
+ xDrawPage;
+ // the shape which carries the control
+ css::uno::Reference< css::drawing::XControlShape >
+ xObjectShape;
+
+ // the tables or queries of the data source the form is bound to (if any)
+ css::uno::Reference< css::container::XNameAccess >
+ xObjectContainer;
+ // the column types container of the object the form is bound to (table, query or SQL statement)
+ typedef std::map<OUString, sal_Int32> TNameTypeMap;
+ TNameTypeMap aTypes;
+ // the column names of the object the form is bound to (table, query or SQL statement)
+ css::uno::Sequence< OUString >
+ aFieldNames;
+
+ bool bEmbedded;
+ };
+
+
+} // namespace dbp
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_WIZARDCONTEXT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/wizardservices.cxx b/extensions/source/dbpilots/wizardservices.cxx
new file mode 100644
index 000000000..2f7b91b45
--- /dev/null
+++ b/extensions/source/dbpilots/wizardservices.cxx
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include "dbpservices.hxx"
+#include "wizardservices.hxx"
+#include "unoautopilot.hxx"
+#include "groupboxwiz.hxx"
+#include "listcombowizard.hxx"
+#include "gridwizard.hxx"
+
+// the registration methods
+extern "C" void createRegistryInfo_OGroupBoxWizard()
+{
+ static compmodule::OMultiInstanceAutoRegistration<
+ ::dbp::OUnoAutoPilot< ::dbp::OGroupBoxWizard, ::dbp::OGroupBoxSI >
+ > aAutoRegistration;
+}
+
+extern "C" void createRegistryInfo_OListComboWizard()
+{
+ static compmodule::OMultiInstanceAutoRegistration<
+ ::dbp::OUnoAutoPilot< ::dbp::OListComboWizard, ::dbp::OListComboSI >
+ > aAutoRegistration;
+}
+
+extern "C" void createRegistryInfo_OGridWizard()
+{
+ static compmodule::OMultiInstanceAutoRegistration<
+ ::dbp::OUnoAutoPilot< ::dbp::OGridWizard, ::dbp::OGridSI >
+ > aAutoRegistration;
+}
+
+
+namespace dbp
+{
+
+
+ using namespace ::com::sun::star::uno;
+
+ OUString OGroupBoxSI::getImplementationName()
+ {
+ return "org.openoffice.comp.dbp.OGroupBoxWizard";
+ }
+
+
+ Sequence< OUString > OGroupBoxSI::getServiceNames()
+ {
+ Sequence< OUString > aReturn { "com.sun.star.sdb.GroupBoxAutoPilot" };
+ return aReturn;
+ }
+
+ OUString OListComboSI::getImplementationName()
+ {
+ return "org.openoffice.comp.dbp.OListComboWizard";
+ }
+
+
+ Sequence< OUString > OListComboSI::getServiceNames()
+ {
+ Sequence< OUString > aReturn { "com.sun.star.sdb.ListComboBoxAutoPilot" };
+ return aReturn;
+ }
+
+ OUString OGridSI::getImplementationName()
+ {
+ return "org.openoffice.comp.dbp.OGridWizard";
+ }
+
+
+ Sequence< OUString > OGridSI::getServiceNames()
+ {
+ Sequence< OUString > aReturn { "com.sun.star.sdb.GridControlAutoPilot" };
+ return aReturn;
+ }
+
+
+} // namespace dbp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/dbpilots/wizardservices.hxx b/extensions/source/dbpilots/wizardservices.hxx
new file mode 100644
index 000000000..9ed99154e
--- /dev/null
+++ b/extensions/source/dbpilots/wizardservices.hxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_WIZARDSERVICES_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_WIZARDSERVICES_HXX
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <rtl/ustring.hxx>
+
+
+namespace dbp
+{
+ // service info for the group box wizard
+ struct OGroupBoxSI
+ {
+ public:
+ static OUString getImplementationName();
+ static css::uno::Sequence< OUString >
+ getServiceNames();
+ };
+
+ // service info for the list/combo box wizard
+ struct OListComboSI
+ {
+ public:
+ static OUString getImplementationName();
+ static css::uno::Sequence< OUString >
+ getServiceNames();
+ };
+
+
+ // service info for the grid wizard
+ struct OGridSI
+ {
+ public:
+ static OUString getImplementationName();
+ static css::uno::Sequence< OUString >
+ getServiceNames();
+ };
+
+
+} // namespace dbp
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_DBPILOTS_WIZARDSERVICES_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */