summaryrefslogtreecommitdiffstats
path: root/dbaccess/source/ui/dlg
diff options
context:
space:
mode:
Diffstat (limited to 'dbaccess/source/ui/dlg')
-rw-r--r--dbaccess/source/ui/dlg/CollectionView.cxx316
-rw-r--r--dbaccess/source/ui/dlg/ConnectionHelper.cxx720
-rw-r--r--dbaccess/source/ui/dlg/ConnectionHelper.hxx103
-rw-r--r--dbaccess/source/ui/dlg/ConnectionPage.cxx284
-rw-r--r--dbaccess/source/ui/dlg/ConnectionPage.hxx72
-rw-r--r--dbaccess/source/ui/dlg/ConnectionPageSetup.cxx153
-rw-r--r--dbaccess/source/ui/dlg/ConnectionPageSetup.hxx63
-rw-r--r--dbaccess/source/ui/dlg/DBSetupConnectionPages.cxx786
-rw-r--r--dbaccess/source/ui/dlg/DBSetupConnectionPages.hxx270
-rw-r--r--dbaccess/source/ui/dlg/DbAdminImpl.cxx1074
-rw-r--r--dbaccess/source/ui/dlg/DbAdminImpl.hxx167
-rw-r--r--dbaccess/source/ui/dlg/DriverSettings.hxx78
-rw-r--r--dbaccess/source/ui/dlg/QueryPropertiesDialog.cxx60
-rw-r--r--dbaccess/source/ui/dlg/RelationDlg.cxx215
-rw-r--r--dbaccess/source/ui/dlg/TablesSingleDlg.cxx105
-rw-r--r--dbaccess/source/ui/dlg/TextConnectionHelper.cxx392
-rw-r--r--dbaccess/source/ui/dlg/TextConnectionHelper.hxx89
-rw-r--r--dbaccess/source/ui/dlg/UserAdmin.cxx316
-rw-r--r--dbaccess/source/ui/dlg/UserAdmin.hxx74
-rw-r--r--dbaccess/source/ui/dlg/UserAdminDlg.cxx162
-rw-r--r--dbaccess/source/ui/dlg/admincontrols.cxx201
-rw-r--r--dbaccess/source/ui/dlg/admincontrols.hxx65
-rw-r--r--dbaccess/source/ui/dlg/adminpages.cxx278
-rw-r--r--dbaccess/source/ui/dlg/adminpages.hxx233
-rw-r--r--dbaccess/source/ui/dlg/adodatalinks.cxx141
-rw-r--r--dbaccess/source/ui/dlg/adodatalinks.hxx26
-rw-r--r--dbaccess/source/ui/dlg/adtabdlg.cxx467
-rw-r--r--dbaccess/source/ui/dlg/advancedsettings.cxx472
-rw-r--r--dbaccess/source/ui/dlg/advancedsettings.hxx116
-rw-r--r--dbaccess/source/ui/dlg/dbadmin.cxx433
-rw-r--r--dbaccess/source/ui/dlg/dbfindex.cxx430
-rw-r--r--dbaccess/source/ui/dlg/dbfindex.hxx110
-rw-r--r--dbaccess/source/ui/dlg/dbwiz.cxx336
-rw-r--r--dbaccess/source/ui/dlg/dbwizsetup.cxx994
-rw-r--r--dbaccess/source/ui/dlg/detailpages.cxx717
-rw-r--r--dbaccess/source/ui/dlg/detailpages.hxx253
-rw-r--r--dbaccess/source/ui/dlg/directsql.cxx430
-rw-r--r--dbaccess/source/ui/dlg/dlgattr.cxx60
-rw-r--r--dbaccess/source/ui/dlg/dlgsave.cxx351
-rw-r--r--dbaccess/source/ui/dlg/dlgsize.cxx83
-rw-r--r--dbaccess/source/ui/dlg/dsnItem.hxx48
-rw-r--r--dbaccess/source/ui/dlg/dsselect.cxx133
-rw-r--r--dbaccess/source/ui/dlg/dsselect.hxx61
-rw-r--r--dbaccess/source/ui/dlg/finteraction.cxx59
-rw-r--r--dbaccess/source/ui/dlg/finteraction.hxx54
-rw-r--r--dbaccess/source/ui/dlg/generalpage.cxx700
-rw-r--r--dbaccess/source/ui/dlg/generalpage.hxx189
-rw-r--r--dbaccess/source/ui/dlg/indexdialog.cxx707
-rw-r--r--dbaccess/source/ui/dlg/indexfieldscontrol.cxx447
-rw-r--r--dbaccess/source/ui/dlg/odbcconfig.cxx325
-rw-r--r--dbaccess/source/ui/dlg/odbcconfig.hxx106
-rw-r--r--dbaccess/source/ui/dlg/optionalboolitem.cxx44
-rw-r--r--dbaccess/source/ui/dlg/optionalboolitem.hxx51
-rw-r--r--dbaccess/source/ui/dlg/paramdialog.cxx334
-rw-r--r--dbaccess/source/ui/dlg/queryfilter.cxx748
-rw-r--r--dbaccess/source/ui/dlg/queryorder.cxx218
-rw-r--r--dbaccess/source/ui/dlg/sqlmessage.cxx604
-rw-r--r--dbaccess/source/ui/dlg/tablespage.cxx488
-rw-r--r--dbaccess/source/ui/dlg/tablespage.hxx81
-rw-r--r--dbaccess/source/ui/dlg/textconnectionsettings.cxx69
60 files changed, 17161 insertions, 0 deletions
diff --git a/dbaccess/source/ui/dlg/CollectionView.cxx b/dbaccess/source/ui/dlg/CollectionView.cxx
new file mode 100644
index 000000000..2e02fda50
--- /dev/null
+++ b/dbaccess/source/ui/dlg/CollectionView.cxx
@@ -0,0 +1,316 @@
+/* -*- 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 <CollectionView.hxx>
+#include <tools/diagnose_ex.h>
+#include <core_resource.hxx>
+#include <strings.hrc>
+#include <comphelper/interaction.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <o3tl/safeint.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <UITools.hxx>
+#include <com/sun/star/container/XHierarchicalNameContainer.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <com/sun/star/ucb/IOErrorCode.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/task/InteractionClassification.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <comphelper/processfactory.hxx>
+#include <ucbhelper/commandenvironment.hxx>
+#include <ucbhelper/content.hxx>
+#include <connectivity/dbexception.hxx>
+
+namespace dbaui
+{
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::sdbc;
+using namespace comphelper;
+
+OCollectionView::OCollectionView(weld::Window* pParent,
+ const Reference< XContent>& _xContent,
+ const OUString& _sDefaultName,
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext)
+ : GenericDialogController(pParent, "dbaccess/ui/collectionviewdialog.ui", "CollectionView")
+ , m_xContent(_xContent)
+ , m_xContext(_rxContext)
+ , m_bCreateForm(true)
+ , m_xFTCurrentPath(m_xBuilder->weld_label("currentPathLabel"))
+ , m_xNewFolder(m_xBuilder->weld_button("newFolderButton"))
+ , m_xUp(m_xBuilder->weld_button("upButton"))
+ , m_xView(m_xBuilder->weld_tree_view("viewTreeview"))
+ , m_xName(m_xBuilder->weld_entry("fileNameEntry"))
+ , m_xPB_OK(m_xBuilder->weld_button("ok"))
+{
+ Reference<XInteractionHandler2> xHandler(
+ InteractionHandler::createWithParent(m_xContext, m_xDialog->GetXWindow()));
+ m_xCmdEnv = new ::ucbhelper::CommandEnvironment(xHandler, nullptr);
+
+ OSL_ENSURE(m_xContent.is(),"No valid content!");
+ m_xView->set_size_request(m_xView->get_approximate_digit_width() * 60, m_xView->get_height_rows(8));
+ m_xView->make_sorted();
+ Initialize();
+ initCurrentPath();
+
+ m_xName->set_text(_sDefaultName);
+ m_xName->grab_focus();
+
+ m_xView->connect_row_activated( LINK( this, OCollectionView, Dbl_Click_FileView ) );
+ m_xUp->connect_clicked( LINK( this, OCollectionView, Up_Click ) );
+ m_xNewFolder->connect_clicked( LINK( this, OCollectionView, NewFolder_Click ) );
+ m_xPB_OK->connect_clicked( LINK( this, OCollectionView, Save_Click ) );
+}
+
+OCollectionView::~OCollectionView()
+{
+}
+
+IMPL_LINK_NOARG(OCollectionView, Save_Click, weld::Button&, void)
+{
+ OUString sName = m_xName->get_text();
+ if (sName.isEmpty())
+ return;
+ try
+ {
+ sal_Int32 nIndex = sName.lastIndexOf('/') + 1;
+ if ( nIndex )
+ {
+ if ( nIndex == 1 ) // special handling for root
+ {
+ Reference<XChild> xChild(m_xContent,UNO_QUERY);
+ Reference<XNameAccess> xNameAccess(xChild,UNO_QUERY);
+ while( xNameAccess.is() )
+ {
+ xNameAccess.set(xChild->getParent(),UNO_QUERY);
+ if ( xNameAccess.is() )
+ {
+ m_xContent.set(xNameAccess,UNO_QUERY);
+ xChild.set(m_xContent,UNO_QUERY);
+ }
+ }
+ Initialize();
+ initCurrentPath();
+ }
+ OUString sSubFolder = sName.copy(0,nIndex-1);
+ sName = sName.copy(nIndex);
+ Reference<XHierarchicalNameContainer> xHier(m_xContent,UNO_QUERY);
+ OSL_ENSURE(xHier.is(),"XHierarchicalNameContainer not supported!");
+ if ( !sSubFolder.isEmpty() && xHier.is() )
+ {
+ if ( xHier->hasByHierarchicalName(sSubFolder) )
+ {
+ m_xContent.set(xHier->getByHierarchicalName(sSubFolder),UNO_QUERY);
+ }
+ else // sub folder doesn't exist
+ {
+ Sequence<Any> aValues(comphelper::InitAnyPropertySequence(
+ {
+ {"ResourceName", Any(sSubFolder)},
+ {"ResourceType", Any(OUString("folder"))}
+ }));
+ InteractiveAugmentedIOException aException(OUString(),Reference<XInterface>(),
+ InteractionClassification_ERROR,
+ IOErrorCode_NOT_EXISTING_PATH,aValues);
+
+ Reference<XInteractionHandler2> xHandler(
+ InteractionHandler::createWithParent(m_xContext, m_xDialog->GetXWindow()));
+ rtl::Reference<OInteractionRequest> pRequest = new OInteractionRequest(Any(aException));
+
+ rtl::Reference<OInteractionApprove> pApprove = new OInteractionApprove;
+ pRequest->addContinuation(pApprove);
+ xHandler->handle(pRequest);
+
+ return;
+ }
+ }
+ }
+ Reference<XNameContainer> xNameContainer(m_xContent,UNO_QUERY);
+ if ( xNameContainer.is() )
+ {
+ if ( xNameContainer->hasByName(sName) )
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ DBA_RES(STR_ALREADYEXISTOVERWRITE)));
+ if (xQueryBox->run() != RET_YES)
+ return;
+ }
+ m_xName->set_text(sName);
+ m_xDialog->response(RET_OK);
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+IMPL_LINK_NOARG(OCollectionView, NewFolder_Click, weld::Button&, void)
+{
+ try
+ {
+ Reference<XHierarchicalNameContainer> xNameContainer(m_xContent,UNO_QUERY);
+ if ( dbaui::insertHierarchyElement(m_xDialog.get(),m_xContext,xNameContainer,OUString(),m_bCreateForm) )
+ Initialize();
+ }
+ catch( const SQLException& )
+ {
+ showError(::dbtools::SQLExceptionInfo(::cppu::getCaughtException()), m_xDialog->GetXWindow(), m_xContext);
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+IMPL_LINK_NOARG(OCollectionView, Up_Click, weld::Button&, void)
+{
+ try
+ {
+ Reference<XChild> xChild(m_xContent,UNO_QUERY);
+ if ( xChild.is() )
+ {
+ Reference<XNameAccess> xNameAccess(xChild->getParent(),UNO_QUERY);
+ if ( xNameAccess.is() )
+ {
+ m_xContent.set(xNameAccess,UNO_QUERY);
+ Initialize();
+ initCurrentPath();
+ }
+ else
+ m_xUp->set_sensitive(false);
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+IMPL_LINK_NOARG(OCollectionView, Dbl_Click_FileView, weld::TreeView&, bool)
+{
+ try
+ {
+ Reference<XNameAccess> xNameAccess(m_xContent,UNO_QUERY);
+ if ( xNameAccess.is() )
+ {
+ OUString sSubFolder = m_xView->get_selected_text();
+ if (!sSubFolder.isEmpty())
+ {
+ Reference< XContent> xContent;
+ if ( xNameAccess->hasByName(sSubFolder) )
+ xContent.set(xNameAccess->getByName(sSubFolder),UNO_QUERY);
+ if ( xContent.is() )
+ {
+ m_xContent = xContent;
+ Initialize();
+ initCurrentPath();
+ }
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ return true;
+}
+
+void OCollectionView::initCurrentPath()
+{
+ bool bEnable = false;
+ try
+ {
+ if ( m_xContent.is() )
+ {
+ const OUString sCID = m_xContent->getIdentifier()->getContentIdentifier();
+ static const char s_sFormsCID[] = "private:forms";
+ static const char s_sReportsCID[] = "private:reports";
+ m_bCreateForm = s_sFormsCID == sCID;
+ OUString sPath("/");
+ if ( m_bCreateForm && o3tl::make_unsigned(sCID.getLength()) != strlen(s_sFormsCID))
+ sPath = sCID.copy(strlen(s_sFormsCID));
+ else if ( !m_bCreateForm && o3tl::make_unsigned(sCID.getLength()) != strlen(s_sReportsCID) )
+ sPath = sCID.copy(strlen(s_sReportsCID) - 2);
+
+ m_xFTCurrentPath->set_label(sPath);
+ Reference<XChild> xChild(m_xContent,UNO_QUERY);
+ bEnable = xChild.is() && Reference<XNameAccess>(xChild->getParent(),UNO_QUERY).is();
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ m_xUp->set_sensitive(bEnable);
+}
+
+OUString OCollectionView::getName() const
+{
+ return m_xName->get_text();
+}
+
+#define ROW_TITLE 1
+#define ROW_IS_FOLDER 2
+
+void OCollectionView::Initialize()
+{
+ weld::WaitObject aWaitCursor(m_xDialog.get());
+
+ m_xView->clear();
+
+ try
+ {
+ ::ucbhelper::Content aContent(m_xContent, m_xCmdEnv, comphelper::getProcessComponentContext());
+ Sequence<OUString> aProps { "Title", "IsFolder" };
+ auto xDynResultSet = aContent.createDynamicCursor(aProps, ucbhelper::INCLUDE_FOLDERS_ONLY);
+ if (!xDynResultSet.is())
+ return;
+
+ Reference<XResultSet> xResultSet = xDynResultSet->getStaticResultSet();
+ Reference<XRow> xRow(xResultSet, UNO_QUERY);
+ while (xResultSet->next())
+ {
+ if (!xRow->getBoolean(ROW_IS_FOLDER))
+ continue;
+ m_xView->append_text(xRow->getString(ROW_TITLE));
+ }
+ }
+ catch (const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/ConnectionHelper.cxx b/dbaccess/source/ui/dlg/ConnectionHelper.cxx
new file mode 100644
index 000000000..6642d2895
--- /dev/null
+++ b/dbaccess/source/ui/dlg/ConnectionHelper.cxx
@@ -0,0 +1,720 @@
+/* -*- 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 <core_resource.hxx>
+#include "dsnItem.hxx"
+#include "ConnectionHelper.hxx"
+#include <IItemSetHelper.hxx>
+#include <strings.hrc>
+#include <svl/itemset.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/stritem.hxx>
+#include <dsitems.hxx>
+#include <osl/diagnose.h>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <vcl/stdtext.hxx>
+#include <sqlmessage.hxx>
+#include "dsselect.hxx"
+#include <svl/filenotation.hxx>
+#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/lang/SystemDependent.hpp>
+#include <com/sun/star/mozilla/MozillaBootstrap.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <ucbhelper/commandenvironment.hxx>
+#include <ucbhelper/content.hxx>
+#include "finteraction.hxx"
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+
+#if defined _WIN32
+#include <rtl/process.h>
+#include <vcl/sysdata.hxx>
+#include "adodatalinks.hxx"
+#endif
+
+#include <com/sun/star/mozilla/XMozillaBootstrap.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+
+namespace dbaui
+{
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::ucb;
+ using namespace ::com::sun::star::ui::dialogs;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::mozilla;
+ using namespace ::dbtools;
+ using namespace ::svt;
+
+ OConnectionHelper::OConnectionHelper(weld::Container* pPage, weld::DialogController* pController, const OUString& _rUIXMLDescription, const OString& _rId, const SfxItemSet& _rCoreAttrs)
+ : OGenericAdministrationPage(pPage, pController, _rUIXMLDescription, _rId, _rCoreAttrs)
+ , m_bUserGrabFocus(false)
+ , m_pCollection(nullptr)
+ , m_xFT_Connection(m_xBuilder->weld_label("browseurllabel"))
+ , m_xPB_Connection(m_xBuilder->weld_button("browse"))
+ , m_xPB_CreateDB(m_xBuilder->weld_button("create"))
+ , m_xConnectionURL(new OConnectionURLEdit(m_xBuilder->weld_entry("browseurl"), m_xBuilder->weld_label("browselabel")))
+ {
+ // extract the datasource type collection from the item set
+ const DbuTypeCollectionItem* pCollectionItem = dynamic_cast<const DbuTypeCollectionItem*>( _rCoreAttrs.GetItem(DSID_TYPECOLLECTION) );
+ if (pCollectionItem)
+ m_pCollection = pCollectionItem->getCollection();
+ m_xPB_Connection->connect_clicked(LINK(this, OConnectionHelper, OnBrowseConnections));
+ m_xPB_CreateDB->connect_clicked(LINK(this, OConnectionHelper, OnCreateDatabase));
+ OSL_ENSURE(m_pCollection, "OConnectionHelper::OConnectionHelper : really need a DSN type collection !");
+ m_xConnectionURL->SetTypeCollection(m_pCollection);
+
+ m_xConnectionURL->connect_focus_in(LINK(this, OConnectionHelper, GetFocusHdl));
+ m_xConnectionURL->connect_focus_out(LINK(this, OConnectionHelper, LoseFocusHdl));
+ }
+
+ OConnectionHelper::~OConnectionHelper()
+ {
+ m_xConnectionURL.reset();
+ }
+
+ void OConnectionHelper::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ m_xFT_Connection->show();
+ m_xConnectionURL->show();
+ m_xConnectionURL->ShowPrefix( ::dbaccess::DST_JDBC == m_pCollection->determineType(m_eType) );
+
+ bool bEnableBrowseButton = m_pCollection->supportsBrowsing( m_eType );
+ m_xPB_Connection->set_visible( bEnableBrowseButton );
+
+ bool bEnableCreateButton = m_pCollection->supportsDBCreation( m_eType );
+ m_xPB_CreateDB->set_visible( bEnableCreateButton );
+
+ const SfxStringItem* pUrlItem = _rSet.GetItem<SfxStringItem>(DSID_CONNECTURL);
+
+ // forward the values to the controls
+ if ( bValid )
+ {
+ OUString sUrl = pUrlItem->GetValue();
+ setURL( sUrl );
+
+ checkTestConnection();
+ m_xConnectionURL->save_value();
+ }
+
+ OGenericAdministrationPage::implInitControls(_rSet, _bSaveValue);
+ }
+
+ void OConnectionHelper::implUpdateURLDependentStates() const
+ {
+ OSL_PRECOND( m_pAdminDialog && m_pCollection, "OConnectionHelper::implUpdateURLDependentStates: no admin dialog!" );
+ if ( !m_pAdminDialog || !m_pCollection )
+ return;
+
+ if ( m_pCollection->isFileSystemBased(m_eType) )
+ m_pAdminDialog->enableConfirmSettings( !getURLNoPrefix().isEmpty() );
+ }
+
+ IMPL_LINK_NOARG(OConnectionHelper, OnBrowseConnections, weld::Button&, void)
+ {
+ OSL_ENSURE(m_pAdminDialog,"No Admin dialog set! ->GPF");
+ const ::dbaccess::DATASOURCE_TYPE eType = m_pCollection->determineType(m_eType);
+ switch ( eType )
+ {
+ case ::dbaccess::DST_DBASE:
+ case ::dbaccess::DST_FLAT:
+ {
+ try
+ {
+ Reference< XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(m_xORB, GetFrameWeld());
+
+ bool bDoBrowse = false;
+ OUString sOldPath = getURLNoPrefix();
+ do
+ {
+ if (!sOldPath.isEmpty())
+ xFolderPicker->setDisplayDirectory(sOldPath);
+ if (0 == xFolderPicker->execute())
+ // cancelled by the user
+ return;
+
+ sOldPath = xFolderPicker->getDirectory();
+ switch (checkPathExistence(sOldPath))
+ {
+ case RET_RETRY:
+ bDoBrowse = true;
+ break;
+ case RET_CANCEL:
+ return;
+ default:
+ break;
+ }
+ }
+ while (bDoBrowse);
+
+ OUString sSelectedDirectory = xFolderPicker->getDirectory();
+ INetURLObject aSelectedDirectory( sSelectedDirectory, INetURLObject::EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8 );
+
+ // for UI purpose, we don't want to have the path encoded
+ sSelectedDirectory = aSelectedDirectory.GetMainURL( INetURLObject::DecodeMechanism::WithCharset );
+
+ setURLNoPrefix( sSelectedDirectory );
+ SetRoadmapStateValue(true);
+ callModifiedHdl();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ }
+ break;
+ case ::dbaccess::DST_CALC:
+ {
+ SvtModuleOptions aModule;
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
+ FileDialogFlags::NONE,
+ aModule.GetFactoryEmptyDocumentURL(SvtModuleOptions::EFactory::CALC)
+ ,SfxFilterFlags::IMPORT, SfxFilterFlags::NONE, GetFrameWeld());
+ askForFileName(aFileDlg);
+ }
+ break;
+ case ::dbaccess::DST_WRITER:
+ {
+ SvtModuleOptions aModule;
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
+ FileDialogFlags::NONE,
+ aModule.GetFactoryEmptyDocumentURL(SvtModuleOptions::EFactory::WRITER),
+ SfxFilterFlags::IMPORT, SfxFilterFlags::NONE, GetFrameWeld());
+ askForFileName(aFileDlg);
+ }
+ break;
+ case ::dbaccess::DST_MSACCESS:
+ {
+ OUString sFilterName(DBA_RES (STR_MSACCESS_FILTERNAME));
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
+ FileDialogFlags::NONE, GetFrameWeld());
+ aFileDlg.AddFilter(sFilterName,"*.mdb;*.mde");
+ aFileDlg.SetCurrentFilter(sFilterName);
+ askForFileName(aFileDlg);
+ }
+ break;
+ case ::dbaccess::DST_MSACCESS_2007:
+ {
+ OUString sFilterName2(DBA_RES (STR_MSACCESS_2007_FILTERNAME));
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
+ FileDialogFlags::NONE, GetFrameWeld());
+ aFileDlg.AddFilter(sFilterName2,"*.accdb;*.accde");
+ aFileDlg.SetCurrentFilter(sFilterName2);
+ askForFileName(aFileDlg);
+ }
+ break;
+ case ::dbaccess::DST_MYSQL_ODBC:
+ case ::dbaccess::DST_ODBC:
+ {
+ // collect all ODBC data source names
+ OUString sCurrDatasource = getURLNoPrefix();
+ OUString sDataSource;
+ if ( getSelectedDataSource(sDataSource,sCurrDatasource) && !sDataSource.isEmpty() )
+ {
+ setURLNoPrefix(sDataSource);
+ SetRoadmapStateValue(true);
+ callModifiedHdl();
+ }
+ else
+ return;
+ }
+ break;
+#if defined _WIN32
+ case ::dbaccess::DST_ADO:
+ {
+ OUString sOldDataSource=getURLNoPrefix();
+ OUString sNewDataSource;
+ HWND hWnd = nullptr;
+
+ weld::Window* pDialog = GetFrameWeld();
+ css::uno::Reference<css::awt::XSystemDependentWindowPeer> xSysDepWin(pDialog->GetXWindow(), css::uno::UNO_QUERY);
+ if (xSysDepWin.is())
+ {
+ css::uno::Sequence<sal_Int8> aProcessIdent(16);
+ rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8*>(aProcessIdent.getArray()));
+ css::uno::Any aAny = xSysDepWin->getWindowHandle(aProcessIdent, css::lang::SystemDependent::SYSTEM_WIN32);
+ sal_Int64 tmp(0);
+ aAny >>= tmp;
+ hWnd = reinterpret_cast<HWND>(tmp);
+ }
+
+ sNewDataSource = getAdoDatalink(reinterpret_cast<sal_IntPtr>(hWnd),sOldDataSource);
+ if ( !sNewDataSource.isEmpty() )
+ {
+ setURLNoPrefix(sNewDataSource);
+ SetRoadmapStateValue(true);
+ callModifiedHdl();
+ }
+ }
+ break;
+#endif
+ case ::dbaccess::DST_MOZILLA:
+ case ::dbaccess::DST_THUNDERBIRD:
+ {
+ MozillaProductType profileType = MozillaProductType_Mozilla;
+ if (eType == ::dbaccess::DST_THUNDERBIRD)
+ profileType = MozillaProductType_Thunderbird;
+
+ Reference<XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+ Reference<XMozillaBootstrap> xMozillaBootstrap = MozillaBootstrap::create(xContext);
+
+ // collect all Mozilla Profiles
+ css::uno::Sequence< OUString > list;
+
+ xMozillaBootstrap->getProfileList( profileType, list );
+ const OUString * pArray = list.getConstArray();
+
+ sal_Int32 count = list.getLength();
+
+ std::set<OUString> aProfiles;
+ for (sal_Int32 index=0; index < count; index++)
+ aProfiles.insert(pArray[index]);
+
+ // execute the select dialog
+ ODatasourceSelectDialog aSelector(GetFrameWeld(), aProfiles);
+ OUString sOldProfile=getURLNoPrefix();
+
+ if (!sOldProfile.isEmpty())
+ aSelector.Select(sOldProfile);
+ else
+ aSelector.Select(xMozillaBootstrap->getDefaultProfile(profileType));
+
+ if (RET_OK == aSelector.run())
+ setURLNoPrefix(aSelector.GetSelected());
+ break;
+ }
+ case ::dbaccess::DST_FIREBIRD:
+ {
+ OUString sFilterName(DBA_RES (STR_FIREBIRD_FILTERNAME));
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetFrameWeld());
+ aFileDlg.AddFilter(sFilterName,"*.fdb");
+ aFileDlg.SetCurrentFilter(sFilterName);
+ askForFileName(aFileDlg);
+ break;
+ }
+ default:
+ break;
+ }
+
+ checkTestConnection();
+ }
+
+ IMPL_LINK_NOARG(OConnectionHelper, OnCreateDatabase, weld::Button&, void)
+ {
+ OSL_ENSURE(m_pAdminDialog,"No Admin dialog set! ->GPF");
+ const ::dbaccess::DATASOURCE_TYPE eType = m_pCollection->determineType(m_eType);
+ switch ( eType )
+ {
+ case ::dbaccess::DST_FIREBIRD:
+ {
+ OUString sFilterName(DBA_RES (STR_FIREBIRD_FILTERNAME));
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,
+ FileDialogFlags::NONE, GetFrameWeld());
+ aFileDlg.AddFilter(sFilterName,"*.fdb");
+ aFileDlg.SetCurrentFilter(sFilterName);
+ askForFileName(aFileDlg);
+ break;
+ }
+ default:
+ break;
+ }
+
+ checkTestConnection();
+ }
+
+ bool OConnectionHelper::checkTestConnection()
+ {
+ return true;
+ }
+
+ void OConnectionHelper::impl_setURL( std::u16string_view _rURL, bool _bPrefix )
+ {
+ OUString sURL( comphelper::string::stripEnd(_rURL, '*') );
+ OSL_ENSURE( m_pCollection, "OConnectionHelper::impl_setURL: have no interpreter for the URLs!" );
+
+ if ( m_pCollection && !sURL.isEmpty() )
+ {
+ if ( m_pCollection->isFileSystemBased( m_eType ) )
+ {
+ // get the two parts: prefix and file URL
+ OUString sTypePrefix, sFileURLEncoded;
+ if ( _bPrefix )
+ {
+ sTypePrefix = m_pCollection->getPrefix( m_eType );
+ sFileURLEncoded = m_pCollection->cutPrefix( sURL );
+ }
+ else
+ {
+ sFileURLEncoded = sURL;
+ }
+
+ // substitute any variables
+ sFileURLEncoded = SvtPathOptions().SubstituteVariable( sFileURLEncoded );
+
+ // decode the URL
+ sURL = sTypePrefix;
+ if ( !sFileURLEncoded.isEmpty() )
+ {
+ OFileNotation aFileNotation(sFileURLEncoded);
+ // set this decoded URL as text
+ sURL += aFileNotation.get(OFileNotation::N_SYSTEM);
+ }
+ }
+ }
+
+ if ( _bPrefix )
+ m_xConnectionURL->SetText( sURL );
+ else
+ m_xConnectionURL->SetTextNoPrefix( sURL );
+
+ implUpdateURLDependentStates();
+ }
+
+ OUString OConnectionHelper::impl_getURL() const
+ {
+ // get the pure text
+ OUString sURL = m_xConnectionURL->GetTextNoPrefix();
+
+ OSL_ENSURE( m_pCollection, "OConnectionHelper::impl_getURL: have no interpreter for the URLs!" );
+
+ if ( m_pCollection && !sURL.isEmpty() )
+ {
+ if ( m_pCollection->isFileSystemBased( m_eType ) )
+ {
+ // get the two parts: prefix and file URL
+ OUString sFileURLDecoded = sURL;
+
+ sURL = OUString();
+ if ( !sFileURLDecoded.isEmpty() )
+ {
+ OFileNotation aFileNotation( sFileURLDecoded, OFileNotation::N_SYSTEM );
+ sURL += aFileNotation.get( OFileNotation::N_URL );
+ }
+
+ // encode the URL
+ INetURLObject aFileURL( sFileURLDecoded, INetURLObject::EncodeMechanism::All, RTL_TEXTENCODING_UTF8 );
+ sFileURLDecoded = aFileURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ }
+ }
+ return sURL;
+ }
+
+ void OConnectionHelper::setURL( std::u16string_view _rURL )
+ {
+ impl_setURL( _rURL, true );
+ }
+
+ OUString OConnectionHelper::getURLNoPrefix( ) const
+ {
+ return impl_getURL();
+ }
+
+ void OConnectionHelper::setURLNoPrefix( std::u16string_view _rURL )
+ {
+ impl_setURL( _rURL, false );
+ }
+
+ sal_Int32 OConnectionHelper::checkPathExistence(const OUString& _rURL)
+ {
+ IS_PATH_EXIST e_exists = pathExists(_rURL, false);
+ if (!m_pCollection->supportsDBCreation(m_eType) &&
+ (( e_exists == PATH_NOT_EXIST) || ( e_exists == PATH_NOT_KNOWN)))
+ {
+ OUString sQuery(DBA_RES(STR_ASK_FOR_DIRECTORY_CREATION));
+ OFileNotation aTransformer(_rURL);
+ sQuery = sQuery.replaceFirst("$path$", aTransformer.get(OFileNotation::N_SYSTEM));
+
+ m_bUserGrabFocus = false;
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ sQuery));
+ xQueryBox->set_default_response(RET_YES);
+ sal_Int32 nQueryResult = xQueryBox->run();
+ m_bUserGrabFocus = true;
+
+ switch (nQueryResult)
+ {
+ case RET_YES:
+ {
+ bool bTryCreate = false;
+ do
+ {
+ if ( !createDirectoryDeep(_rURL) )
+ { // could not create the directory
+ sQuery = DBA_RES(STR_COULD_NOT_CREATE_DIRECTORY);
+ sQuery = sQuery.replaceFirst("$name$", aTransformer.get(OFileNotation::N_SYSTEM));
+
+ m_bUserGrabFocus = false;
+
+ std::unique_ptr<weld::MessageDialog> xWhatToDo(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::NONE,
+ sQuery));
+ xWhatToDo->add_button(GetStandardText(StandardButtonType::Retry), RET_RETRY);
+ xWhatToDo->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
+ xWhatToDo->set_default_response(RET_RETRY);
+ nQueryResult = xWhatToDo->run();
+ m_bUserGrabFocus = true;
+
+ if (RET_RETRY == nQueryResult)
+ bTryCreate = true;
+ else
+ {
+ SetRoadmapStateValue(false);
+ callModifiedHdl();
+ return RET_RETRY;
+ }
+ }
+ }
+ while (bTryCreate);
+ }
+ break;
+
+ case RET_NO:
+ callModifiedHdl();
+ return RET_OK;
+
+ default:
+ // cancelled
+ SetRoadmapStateValue(false);
+ callModifiedHdl();
+ return RET_CANCEL;
+ }
+ }
+/* else
+ {
+ // TODO: error msg
+ return RET_CANCEL;
+ } */
+ SetRoadmapStateValue(true);
+ callModifiedHdl();
+ return RET_OK;
+ }
+
+ IS_PATH_EXIST OConnectionHelper::pathExists(const OUString& _rURL, bool bIsFile) const
+ {
+ ::ucbhelper::Content aCheckExistence;
+ IS_PATH_EXIST eExists = PATH_NOT_EXIST;
+ Reference< css::task::XInteractionHandler > xInteractionHandler =
+ task::InteractionHandler::createWithParent(m_xORB, nullptr);
+ rtl::Reference<OFilePickerInteractionHandler> pHandler = new OFilePickerInteractionHandler(xInteractionHandler);
+ xInteractionHandler = pHandler;
+
+ Reference< XCommandEnvironment > xCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );
+ try
+ {
+ aCheckExistence = ::ucbhelper::Content(_rURL, xCmdEnv, comphelper::getProcessComponentContext());
+ const bool bExists = bIsFile? aCheckExistence.isDocument(): aCheckExistence.isFolder();
+ eExists = bExists? PATH_EXIST: PATH_NOT_EXIST;
+ }
+ catch (const Exception&)
+ {
+ eExists = pHandler->isDoesNotExist() ? PATH_NOT_EXIST : (bIsFile ? PATH_NOT_EXIST : PATH_NOT_KNOWN);
+ }
+ return eExists;
+ }
+
+ IMPL_LINK_NOARG(OConnectionHelper, GetFocusHdl, weld::Widget&, void)
+ {
+ if (!m_pCollection->isFileSystemBased(m_eType))
+ return;
+ if (!m_bUserGrabFocus)
+ return;
+ // URL edit field got the focus
+ m_xConnectionURL->SaveValueNoPrefix();
+ }
+
+ IMPL_LINK_NOARG(OConnectionHelper, LoseFocusHdl, weld::Widget&, void)
+ {
+ if (!m_pCollection->isFileSystemBased(m_eType))
+ return;
+ if (!m_bUserGrabFocus)
+ return;
+ // URL edit field lost the focus
+ commitURL();
+ }
+
+ bool OConnectionHelper::createDirectoryDeep(std::u16string_view _rPathURL)
+ {
+ // get a URL object analyzing the URL for us ...
+ INetURLObject aParser;
+ aParser.SetURL(_rPathURL);
+
+ INetProtocol eProtocol = aParser.GetProtocol();
+
+ std::vector< OUString > aToBeCreated; // the to-be-created levels
+
+ // search a level which exists
+ IS_PATH_EXIST eParentExists = PATH_NOT_EXIST;
+ while ( eParentExists == PATH_NOT_EXIST && aParser.getSegmentCount())
+ {
+ aToBeCreated.push_back(aParser.getName()); // remember the local name for creation
+ aParser.removeSegment(); // cut the local name
+ eParentExists = pathExists(aParser.GetMainURL(INetURLObject::DecodeMechanism::NONE), false);
+ }
+
+ if (!aParser.getSegmentCount())
+ return false;
+
+ // create all the missing levels
+ try
+ {
+ // the parent content
+ Reference< XCommandEnvironment > xEmptyEnv;
+ ::ucbhelper::Content aParent(aParser.GetMainURL(INetURLObject::DecodeMechanism::NONE), xEmptyEnv, comphelper::getProcessComponentContext());
+
+ OUString sContentType;
+ if ( INetProtocol::File == eProtocol )
+ {
+ sContentType = "application/vnd.sun.staroffice.fsys-folder";
+ // the file UCP currently does not support the ContentType property
+ }
+ else
+ {
+ Any aContentType = aParent.getPropertyValue("ContentType");
+ aContentType >>= sContentType;
+ }
+
+ // the properties which need to be set on the new content
+ Sequence< OUString > aNewDirectoryProperties { "Title" };
+
+ // loop
+ for ( std::vector< OUString >::const_reverse_iterator aLocalName = aToBeCreated.rbegin();
+ aLocalName != aToBeCreated.rend();
+ ++aLocalName
+ )
+ {
+ // the values to be set
+ Sequence< Any > aNewDirectoryAttributes{ Any(* aLocalName) };
+ if (!aParent.insertNewContent(sContentType, aNewDirectoryProperties, aNewDirectoryAttributes, aParent))
+ return false;
+ }
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ return false;
+ }
+
+ return true;
+ }
+
+ void OConnectionHelper::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFT_Connection.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Button>(m_xPB_Connection.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Button>(m_xPB_CreateDB.get()));
+ }
+
+ void OConnectionHelper::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back( new OSaveValueWidgetWrapper<OConnectionURLEdit>( m_xConnectionURL.get() ) );
+ }
+
+ bool OConnectionHelper::commitURL()
+ {
+ OUString sOldPath = m_xConnectionURL->GetSavedValueNoPrefix();
+ OUString sURL = m_xConnectionURL->GetTextNoPrefix();
+
+ if ( m_pCollection->isFileSystemBased(m_eType) )
+ {
+ if ( ( sURL != sOldPath ) && !sURL.isEmpty() )
+ { // the text changed since entering the control
+
+ // the path may be in system notation...
+ OFileNotation aTransformer(sURL);
+ sURL = aTransformer.get(OFileNotation::N_URL);
+
+ const ::dbaccess::DATASOURCE_TYPE eType = m_pCollection->determineType(m_eType);
+
+ if ( ( ::dbaccess::DST_CALC == eType) || ( ::dbaccess::DST_WRITER == eType) || ( ::dbaccess::DST_MSACCESS == eType) || ( ::dbaccess::DST_MSACCESS_2007 == eType) )
+ {
+ if( pathExists(sURL, true) == PATH_NOT_EXIST )
+ {
+ OUString sFile = DBA_RES( STR_FILE_DOES_NOT_EXIST );
+ sFile = sFile.replaceFirst("$file$", aTransformer.get(OFileNotation::N_SYSTEM));
+ OSQLWarningBox aWarning(GetFrameWeld(), sFile);
+ aWarning.run();
+ setURLNoPrefix(sOldPath);
+ SetRoadmapStateValue(false);
+ callModifiedHdl();
+ return false;
+ }
+ }
+ else
+ {
+ switch (checkPathExistence(sURL))
+ {
+ case RET_RETRY:
+ m_bUserGrabFocus = false;
+ m_xConnectionURL->grab_focus();
+ m_bUserGrabFocus = true;
+ return false;
+
+ case RET_CANCEL:
+ setURLNoPrefix(sOldPath);
+ return false;
+ }
+ }
+ }
+ }
+
+ setURLNoPrefix(sURL);
+ m_xConnectionURL->SaveValueNoPrefix();
+ return true;
+ }
+
+ void OConnectionHelper::askForFileName(::sfx2::FileDialogHelper& _aFileOpen)
+ {
+ OUString sOldPath = getURLNoPrefix();
+ if ( !sOldPath.isEmpty() )
+ _aFileOpen.SetDisplayDirectory(sOldPath);
+ else
+ _aFileOpen.SetDisplayDirectory( SvtPathOptions().GetWorkPath() );
+ if (ERRCODE_NONE == _aFileOpen.Execute())
+ {
+ setURLNoPrefix(_aFileOpen.GetPath());
+ SetRoadmapStateValue(checkTestConnection());
+ callModifiedHdl();
+ }
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/ConnectionHelper.hxx b/dbaccess/source/ui/dlg/ConnectionHelper.hxx
new file mode 100644
index 000000000..b4c00548f
--- /dev/null
+++ b/dbaccess/source/ui/dlg/ConnectionHelper.hxx
@@ -0,0 +1,103 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "adminpages.hxx"
+#include <curledit.hxx>
+#include <sfx2/filedlghelper.hxx>
+
+namespace dbaui
+{
+
+ enum IS_PATH_EXIST
+ {
+ PATH_NOT_EXIST = 0,
+ PATH_EXIST,
+ PATH_NOT_KNOWN
+ };
+
+ class OConnectionHelper : public OGenericAdministrationPage
+ {
+ bool m_bUserGrabFocus;
+
+ public:
+ OConnectionHelper(weld::Container* pPage, weld::DialogController* pController, const OUString& _rUIXMLDescription, const OString& _rId, const SfxItemSet& _rCoreAttrs);
+ virtual ~OConnectionHelper() override;
+
+ OUString m_eType; // the type can't be changed in this class, so we hold it as member.
+ // setting/retrieving the current connection URL
+ // necessary because for some types, the URL must be decoded for display purposes
+ ::dbaccess::ODsnTypeCollection* m_pCollection; /// the DSN type collection instance
+
+ std::unique_ptr<weld::Label> m_xFT_Connection;
+ std::unique_ptr<weld::Button> m_xPB_Connection;
+ std::unique_ptr<weld::Button> m_xPB_CreateDB;
+ std::unique_ptr<OConnectionURLEdit> m_xConnectionURL;
+
+ public:
+
+ // <method>OGenericAdministrationPage::fillControls</method>
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ // <method>OGenericAdministrationPage::fillWindows</method>
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+
+ // setting/retrieving the current connection URL
+ // necessary because for some types, the URL must be decoded for display purposes
+ //String getURL( OConnectionURLEdit* _m_pConnection ) const;
+ //void setURL( const OUString& _rURL, OConnectionURLEdit* _m_pConnection );
+
+ OUString getURLNoPrefix( ) const;
+ void setURLNoPrefix( std::u16string_view _rURL );
+
+ /** checks if the path is existence
+ @param _rURL
+ The URL to check.
+ */
+ sal_Int32 checkPathExistence(const OUString& _rURL);
+
+ IS_PATH_EXIST pathExists(const OUString& _rURL, bool bIsFile) const;
+ bool createDirectoryDeep(std::u16string_view _rPathNormalized);
+ bool commitURL();
+
+ /** opens the FileOpen dialog and asks for a FileName
+ @param _aFileOpen
+ Executes the file open dialog, which must be filled from caller.
+ */
+ void askForFileName(::sfx2::FileDialogHelper& _aFileOpen);
+
+ protected:
+ void setURL( std::u16string_view _rURL );
+ virtual bool checkTestConnection();
+
+ private:
+ DECL_LINK(OnBrowseConnections, weld::Button&, void);
+ DECL_LINK(OnCreateDatabase, weld::Button&, void);
+ DECL_LINK(GetFocusHdl, weld::Widget&, void);
+ DECL_LINK(LoseFocusHdl, weld::Widget&, void);
+ OUString impl_getURL() const;
+ void impl_setURL( std::u16string_view _rURL, bool _bPrefix );
+ void implUpdateURLDependentStates() const;
+ };
+
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/ConnectionPage.cxx b/dbaccess/source/ui/dlg/ConnectionPage.cxx
new file mode 100644
index 000000000..7ff32140e
--- /dev/null
+++ b/dbaccess/source/ui/dlg/ConnectionPage.cxx
@@ -0,0 +1,284 @@
+/* -*- 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 <config_java.h>
+#include "ConnectionPage.hxx"
+#include <core_resource.hxx>
+#include <IItemSetHelper.hxx>
+#include <strings.hrc>
+#include <dsmeta.hxx>
+#if HAVE_FEATURE_JAVA
+#include <jvmaccess/virtualmachine.hxx>
+#endif
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <dsitems.hxx>
+#include <helpids.h>
+#include <sqlmessage.hxx>
+#include <svl/filenotation.hxx>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <connectivity/CommonTools.hxx>
+#include <o3tl/string_view.hxx>
+
+namespace dbaui
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::ucb;
+ using namespace ::com::sun::star::ui::dialogs;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+ using namespace ::dbtools;
+ using namespace ::svt;
+
+ std::unique_ptr<SfxTabPage> OConnectionTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet)
+ {
+ return std::make_unique<OConnectionTabPage>(pPage, pController, *_rAttrSet);
+ }
+
+ // OConnectionTabPage
+ OConnectionTabPage::OConnectionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs)
+ : OConnectionHelper(pPage, pController, "dbaccess/ui/connectionpage.ui", "ConnectionPage", _rCoreAttrs)
+ , m_xFL2(m_xBuilder->weld_label("userlabel"))
+ , m_xUserNameLabel(m_xBuilder->weld_label("userNameLabel"))
+ , m_xUserName(m_xBuilder->weld_entry("userNameEntry"))
+ , m_xPasswordRequired(m_xBuilder->weld_check_button("passCheckbutton"))
+ , m_xFL3(m_xBuilder->weld_label("JDBCLabel"))
+ , m_xJavaDriverLabel(m_xBuilder->weld_label("javaDriverLabel"))
+ , m_xJavaDriver(m_xBuilder->weld_entry("driverEntry"))
+ , m_xTestJavaDriver(m_xBuilder->weld_button("driverButton"))
+ , m_xTestConnection(m_xBuilder->weld_button("connectionButton"))
+ {
+ m_xConnectionURL->connect_changed(LINK(this, OConnectionTabPage, OnEditModified));
+ m_xJavaDriver->connect_changed(LINK(this, OConnectionTabPage, OnEditModified));
+ m_xUserName->connect_changed(LINK(this, OGenericAdministrationPage, OnControlEntryModifyHdl));
+ m_xPasswordRequired->connect_toggled(LINK(this, OGenericAdministrationPage, OnControlModifiedButtonClick));
+
+ m_xTestConnection->connect_clicked(LINK(this,OGenericAdministrationPage,OnTestConnectionButtonClickHdl));
+ m_xTestJavaDriver->connect_clicked(LINK(this,OConnectionTabPage,OnTestJavaClickHdl));
+ }
+
+ OConnectionTabPage::~OConnectionTabPage()
+ {
+ }
+
+ void OConnectionTabPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ m_eType = m_pAdminDialog->getDatasourceType(_rSet);
+ OConnectionHelper::implInitControls( _rSet, _bSaveValue);
+
+ ::dbaccess::DATASOURCE_TYPE eType = m_pCollection->determineType(m_eType);
+ switch( eType )
+ {
+ case ::dbaccess::DST_DBASE:
+ m_xFT_Connection->set_label(DBA_RES(STR_DBASE_PATH_OR_FILE));
+ m_xConnectionURL->set_help_id(HID_DSADMIN_DBASE_PATH);
+ break;
+ case ::dbaccess::DST_FLAT:
+ m_xFT_Connection->set_label(DBA_RES(STR_FLAT_PATH_OR_FILE));
+ m_xConnectionURL->set_help_id(HID_DSADMIN_FLAT_PATH);
+ break;
+ case ::dbaccess::DST_CALC:
+ m_xFT_Connection->set_label(DBA_RES(STR_CALC_PATH_OR_FILE));
+ m_xConnectionURL->set_help_id(HID_DSADMIN_CALC_PATH);
+ break;
+ case ::dbaccess::DST_WRITER:
+ m_xFT_Connection->set_label(DBA_RES(STR_WRITER_PATH_OR_FILE));
+ m_xConnectionURL->set_help_id(HID_DSADMIN_WRITER_PATH);
+ break;
+ case ::dbaccess::DST_ADO:
+ m_xFT_Connection->set_label(DBA_RES(STR_COMMONURL));
+ break;
+ case ::dbaccess::DST_MSACCESS:
+ case ::dbaccess::DST_MSACCESS_2007:
+ m_xFT_Connection->set_label(DBA_RES(STR_MSACCESS_MDB_FILE));
+ m_xConnectionURL->set_help_id(HID_DSADMIN_MSACCESS_MDB_FILE);
+ break;
+ case ::dbaccess::DST_MYSQL_NATIVE:
+ case ::dbaccess::DST_MYSQL_JDBC:
+ m_xFT_Connection->set_label(DBA_RES(STR_MYSQL_DATABASE_NAME));
+ m_xConnectionURL->set_help_id( HID_DSADMIN_MYSQL_DATABASE );
+ break;
+ case ::dbaccess::DST_ORACLE_JDBC:
+ m_xFT_Connection->set_label(DBA_RES(STR_ORACLE_DATABASE_NAME));
+ m_xConnectionURL->set_help_id(HID_DSADMIN_ORACLE_DATABASE);
+ break;
+ case ::dbaccess::DST_MYSQL_ODBC:
+ case ::dbaccess::DST_ODBC:
+ m_xFT_Connection->set_label(DBA_RES(STR_NAME_OF_ODBC_DATASOURCE));
+ m_xConnectionURL->set_help_id( eType == ::dbaccess::DST_MYSQL_ODBC ? OString(HID_DSADMIN_MYSQL_ODBC_DATASOURCE) : OString(HID_DSADMIN_ODBC_DATASOURCE));
+ break;
+ case ::dbaccess::DST_LDAP:
+ m_xFT_Connection->set_label(DBA_RES(STR_HOSTNAME));
+ m_xConnectionURL->set_help_id( HID_DSADMIN_LDAP_HOSTNAME );
+ break;
+ case ::dbaccess::DST_MOZILLA:
+ m_xFT_Connection->set_label(DBA_RES(STR_MOZILLA_PROFILE_NAME));
+ m_xConnectionURL->set_help_id( HID_DSADMIN_MOZILLA_PROFILE_NAME );
+ break;
+ case ::dbaccess::DST_THUNDERBIRD:
+ m_xFT_Connection->set_label(DBA_RES(STR_THUNDERBIRD_PROFILE_NAME));
+ m_xConnectionURL->set_help_id( HID_DSADMIN_THUNDERBIRD_PROFILE_NAME );
+ break;
+ case ::dbaccess::DST_OUTLOOK:
+ case ::dbaccess::DST_OUTLOOKEXP:
+ case ::dbaccess::DST_EVOLUTION:
+ case ::dbaccess::DST_EVOLUTION_GROUPWISE:
+ case ::dbaccess::DST_EVOLUTION_LDAP:
+ case ::dbaccess::DST_KAB:
+ case ::dbaccess::DST_MACAB:
+ m_xFT_Connection->set_label(DBA_RES(STR_NO_ADDITIONAL_SETTINGS));
+ {
+ OUString sText = m_xFT_Connection->get_label();
+ sText = sText.replaceAll("%test",m_xTestConnection->get_label());
+ sText = sText.replaceAll("~","");
+ m_xFT_Connection->set_label(sText);
+ }
+ m_xConnectionURL->hide();
+ break;
+ case ::dbaccess::DST_JDBC:
+ default:
+ m_xFT_Connection->set_label(DBA_RES(STR_COMMONURL));
+ break;
+ }
+
+ AuthenticationMode eAuthMode( DataSourceMetaData::getAuthentication( m_eType ) );
+ bool bShowUserAuthenfication = ( eAuthMode != AuthNone );
+ bool bShowUser = ( eAuthMode == AuthUserPwd );
+
+ m_xPB_Connection->set_help_id(HID_DSADMIN_BROWSECONN);
+ m_xFL2->set_visible( bShowUserAuthenfication );
+ m_xUserNameLabel->set_visible( bShowUser && bShowUserAuthenfication );
+ m_xUserName->set_visible( bShowUser && bShowUserAuthenfication );
+ m_xPasswordRequired->set_visible( bShowUserAuthenfication );
+
+ // collect the items
+ const SfxStringItem* pUidItem = _rSet.GetItem<SfxStringItem>(DSID_USER);
+
+ const SfxStringItem* pJdbcDrvItem = _rSet.GetItem<SfxStringItem>(DSID_JDBCDRIVERCLASS);
+ const SfxStringItem* pUrlItem = _rSet.GetItem<SfxStringItem>(DSID_CONNECTURL);
+ const SfxBoolItem* pAllowEmptyPwd = _rSet.GetItem<SfxBoolItem>(DSID_PASSWORDREQUIRED);
+
+ // forward the values to the controls
+ if ( !bValid )
+ return;
+
+ m_xUserName->set_text(pUidItem->GetValue());
+ m_xPasswordRequired->set_active(pAllowEmptyPwd->GetValue());
+
+ const OUString& sUrl = pUrlItem->GetValue();
+ setURL( sUrl );
+
+ const bool bEnableJDBC = m_pCollection->determineType(m_eType) == ::dbaccess::DST_JDBC;
+ if ( !pJdbcDrvItem->GetValue().getLength() )
+ {
+ OUString sDefaultJdbcDriverName = m_pCollection->getJavaDriverClass(m_eType);
+ if ( !sDefaultJdbcDriverName.isEmpty() )
+ m_xJavaDriver->set_text(sDefaultJdbcDriverName);
+ }
+ else
+ m_xJavaDriver->set_text(pJdbcDrvItem->GetValue());
+
+ m_xJavaDriverLabel->set_visible(bEnableJDBC);
+ m_xJavaDriver->set_visible(bEnableJDBC);
+ m_xTestJavaDriver->set_visible(bEnableJDBC);
+ m_xTestJavaDriver->set_sensitive( !m_xJavaDriver->get_text().trim().isEmpty() );
+ m_xFL3->set_visible(bEnableJDBC);
+
+ checkTestConnection();
+
+ m_xUserName->save_value();
+ m_xConnectionURL->save_value();
+ m_xJavaDriver->save_value();
+ m_xPasswordRequired->save_state();
+ }
+
+ bool OConnectionTabPage::FillItemSet(SfxItemSet* _rSet)
+ {
+ bool bChangedSomething = false;
+
+ if (m_xUserName->get_value_changed_from_saved())
+ {
+ _rSet->Put(SfxStringItem(DSID_USER, m_xUserName->get_text()));
+ _rSet->Put(SfxStringItem(DSID_PASSWORD, OUString()));
+ bChangedSomething = true;
+ }
+
+ fillBool(*_rSet,m_xPasswordRequired.get(),DSID_PASSWORDREQUIRED,false, bChangedSomething);
+
+ if ( m_pCollection->determineType(m_eType) == ::dbaccess::DST_JDBC )
+ {
+ fillString(*_rSet,m_xJavaDriver.get(), DSID_JDBCDRIVERCLASS, bChangedSomething);
+ }
+
+ fillString(*_rSet,m_xConnectionURL.get(), DSID_CONNECTURL, bChangedSomething);
+
+ return bChangedSomething;
+ }
+ IMPL_LINK_NOARG(OConnectionTabPage, OnTestJavaClickHdl, weld::Button&, void)
+ {
+ OSL_ENSURE(m_pAdminDialog,"No Admin dialog set! ->GPF");
+ bool bSuccess = false;
+#if HAVE_FEATURE_JAVA
+ try
+ {
+ if ( !m_xJavaDriver->get_text().trim().isEmpty() )
+ {
+ ::rtl::Reference< jvmaccess::VirtualMachine > xJVM = ::connectivity::getJavaVM( m_pAdminDialog->getORB() );
+ m_xJavaDriver->set_text(m_xJavaDriver->get_text().trim()); // fdo#68341
+ bSuccess = ::connectivity::existsJavaClassByName(xJVM, o3tl::trim(m_xJavaDriver->get_text()));
+ }
+ }
+ catch(Exception&)
+ {
+ }
+#endif
+
+ TranslateId pMessage = bSuccess ? STR_JDBCDRIVER_SUCCESS : STR_JDBCDRIVER_NO_SUCCESS;
+ const MessageType mt = bSuccess ? MessageType::Info : MessageType::Error;
+ OSQLMessageBox aMsg(GetFrameWeld(), DBA_RES(pMessage), OUString(), MessBoxStyle::Ok | MessBoxStyle::DefaultOk, mt);
+ aMsg.run();
+ }
+ bool OConnectionTabPage::checkTestConnection()
+ {
+ OSL_ENSURE(m_pAdminDialog,"No Admin dialog set! ->GPF");
+ bool bEnableTestConnection = !m_xConnectionURL->get_visible() || !m_xConnectionURL->GetTextNoPrefix().isEmpty();
+ if ( m_pCollection->determineType(m_eType) == ::dbaccess::DST_JDBC )
+ bEnableTestConnection = bEnableTestConnection && (!m_xJavaDriver->get_text().trim().isEmpty());
+ m_xTestConnection->set_sensitive(bEnableTestConnection);
+ return true;
+ }
+ IMPL_LINK(OConnectionTabPage, OnEditModified, weld::Entry&, rEdit, void)
+ {
+ if (&rEdit == m_xJavaDriver.get())
+ m_xTestJavaDriver->set_sensitive( !m_xJavaDriver->get_text().trim().isEmpty() );
+
+ checkTestConnection();
+ // tell the listener we were modified
+ callModifiedHdl();
+ }
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/ConnectionPage.hxx b/dbaccess/source/ui/dlg/ConnectionPage.hxx
new file mode 100644
index 000000000..19e769462
--- /dev/null
+++ b/dbaccess/source/ui/dlg/ConnectionPage.hxx
@@ -0,0 +1,72 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "ConnectionHelper.hxx"
+
+namespace dbaui
+{
+
+ // OConnectionTabPage
+
+ /** implements the connection page of the data source properties dialog.
+ */
+ class OConnectionTabPage final : public OConnectionHelper
+ {
+ private:
+ // user authentication
+ std::unique_ptr<weld::Label> m_xFL2;
+ std::unique_ptr<weld::Label> m_xUserNameLabel;
+ std::unique_ptr<weld::Entry> m_xUserName;
+ std::unique_ptr<weld::CheckButton> m_xPasswordRequired;
+
+ // jdbc driver
+ std::unique_ptr<weld::Label> m_xFL3;
+ std::unique_ptr<weld::Label> m_xJavaDriverLabel;
+ std::unique_ptr<weld::Entry> m_xJavaDriver;
+ std::unique_ptr<weld::Button> m_xTestJavaDriver;
+
+ // connection test
+ std::unique_ptr<weld::Button> m_xTestConnection;
+
+ // called when the test connection button was clicked
+ DECL_LINK(OnTestJavaClickHdl, weld::Button&, void);
+ DECL_LINK(OnEditModified, weld::Entry&, void);
+
+ public:
+ OConnectionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs);
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet);
+ virtual ~OConnectionTabPage() override;
+ virtual bool FillItemSet (SfxItemSet* _rCoreAttrs) override;
+
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+
+ /** changes the connection URL.
+ <p>The new URL must be of the type which is currently selected, only the parts which do not
+ affect the type may be changed (compared to the previous URL).</p>
+ */
+ private:
+ /** enables the test connection button, if allowed
+ */
+ virtual bool checkTestConnection() override;
+ };
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/ConnectionPageSetup.cxx b/dbaccess/source/ui/dlg/ConnectionPageSetup.cxx
new file mode 100644
index 000000000..8f57c24f9
--- /dev/null
+++ b/dbaccess/source/ui/dlg/ConnectionPageSetup.cxx
@@ -0,0 +1,153 @@
+/* -*- 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 "ConnectionPageSetup.hxx"
+#include <strings.hrc>
+#include <core_resource.hxx>
+#include <IItemSetHelper.hxx>
+#include <svl/itemset.hxx>
+#include <dsitems.hxx>
+#include <svl/filenotation.hxx>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+
+namespace dbaui
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::ucb;
+ using namespace ::com::sun::star::ui::dialogs;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+ using namespace ::svt;
+
+ std::unique_ptr<OGenericAdministrationPage> OConnectionTabPageSetup::CreateDbaseTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ {
+ return std::make_unique<OConnectionTabPageSetup>( pPage, pController, "dbaccess/ui/dbwizconnectionpage.ui", "ConnectionPage", _rAttrSet, STR_DBASE_HELPTEXT, STR_DBASE_HEADERTEXT, STR_DBASE_PATH_OR_FILE );
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OConnectionTabPageSetup::CreateMSAccessTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ {
+ return std::make_unique<OConnectionTabPageSetup>( pPage, pController, "dbaccess/ui/dbwizconnectionpage.ui", "ConnectionPage", _rAttrSet, STR_MSACCESS_HELPTEXT, STR_MSACCESS_HEADERTEXT, STR_MSACCESS_MDB_FILE );
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OConnectionTabPageSetup::CreateADOTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ {
+ return std::make_unique<OConnectionTabPageSetup>( pPage, pController, "dbaccess/ui/dbwizconnectionpage.ui", "ConnectionPage", _rAttrSet, STR_ADO_HELPTEXT, STR_ADO_HEADERTEXT, STR_COMMONURL );
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OConnectionTabPageSetup::CreateODBCTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ {
+ return std::make_unique<OConnectionTabPageSetup>( pPage, pController, "dbaccess/ui/dbwizconnectionpage.ui", "ConnectionPage", _rAttrSet, STR_ODBC_HELPTEXT, STR_ODBC_HEADERTEXT, STR_NAME_OF_ODBC_DATASOURCE );
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OConnectionTabPageSetup::CreateUserDefinedTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ {
+ return std::make_unique<OConnectionTabPageSetup>(pPage, pController, "dbaccess/ui/dbwizconnectionpage.ui", "ConnectionPage", _rAttrSet, TranslateId(), TranslateId(), STR_COMMONURL);
+ }
+
+ OConnectionTabPageSetup::OConnectionTabPageSetup(weld::Container* pPage, weld::DialogController* pController, const OUString& _rUIXMLDescription, const OString& _rId, const SfxItemSet& _rCoreAttrs, TranslateId pHelpTextResId, TranslateId pHeaderResId, TranslateId pUrlResId)
+ : OConnectionHelper(pPage, pController, _rUIXMLDescription, _rId, _rCoreAttrs)
+ , m_xHelpText(m_xBuilder->weld_label("helptext"))
+ , m_xHeaderText(m_xBuilder->weld_label("header"))
+ {
+
+ if (pHelpTextResId)
+ {
+ OUString sHelpText = DBA_RES(pHelpTextResId);
+ m_xHelpText->set_label(sHelpText);
+ }
+ else
+ m_xHelpText->hide();
+
+ if (pHeaderResId)
+ m_xHeaderText->set_label(DBA_RES(pHeaderResId));
+
+ if (pUrlResId)
+ {
+ OUString sLabelText = DBA_RES(pUrlResId);
+ m_xFT_Connection->set_label(sLabelText);
+ }
+ else
+ m_xFT_Connection->hide();
+
+ m_xConnectionURL->connect_changed(LINK(this, OConnectionTabPageSetup, OnEditModified));
+
+ SetRoadmapStateValue(false);
+ }
+
+ OConnectionTabPageSetup::~OConnectionTabPageSetup()
+ {
+ }
+
+ void OConnectionTabPageSetup::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ m_eType = m_pAdminDialog->getDatasourceType(_rSet);
+ // special handling for oracle, this can only happen
+ // if the user enters the same url as used for Oracle and we are on the JDBC path
+ //! TODO
+ //if ( ::dbaccess::DST_ORACLE_JDBC == m_eType )
+ // m_eType = ::dbaccess::DST_JDBC;
+ if(m_pCollection->determineType(m_eType) == ::dbaccess::DST_POSTGRES){
+ SetRoadmapStateValue(true);
+ }
+
+ OConnectionHelper::implInitControls(_rSet, _bSaveValue);
+
+ //! TODO
+ //if ( m_eType >= ::dbaccess::DST_USERDEFINE1 )
+ //{
+ // OUString sDisplayName = m_pCollection->getTypeDisplayName(m_eType);
+ // FixedText* ppTextControls[] ={&m_aFT_Connection};
+ // for (size_t i = 0; i < sizeof(ppTextControls)/sizeof(ppTextControls[0]); ++i)
+ // {
+ // ppTextControls[i]->SetText(sDisplayName);
+ // }
+ //}
+
+ callModifiedHdl();
+ }
+
+ bool OConnectionTabPageSetup::commitPage( ::vcl::WizardTypes::CommitPageReason /*_eReason*/ )
+ {
+ return commitURL();
+ }
+
+ bool OConnectionTabPageSetup::FillItemSet(SfxItemSet* _rSet)
+ {
+ bool bChangedSomething = false;
+ fillString(*_rSet,m_xConnectionURL.get(), DSID_CONNECTURL, bChangedSomething);
+ return bChangedSomething;
+ }
+
+ bool OConnectionTabPageSetup::checkTestConnection()
+ {
+ if ( m_pCollection->determineType(m_eType) == ::dbaccess::DST_POSTGRES )
+ return true;
+ return !m_xConnectionURL->get_visible() || !m_xConnectionURL->GetTextNoPrefix().isEmpty();
+ }
+
+ IMPL_LINK_NOARG(OConnectionTabPageSetup, OnEditModified, weld::Entry&, void)
+ {
+ SetRoadmapStateValue(checkTestConnection());
+ callModifiedHdl();
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/ConnectionPageSetup.hxx b/dbaccess/source/ui/dlg/ConnectionPageSetup.hxx
new file mode 100644
index 000000000..0039a7160
--- /dev/null
+++ b/dbaccess/source/ui/dlg/ConnectionPageSetup.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 .
+ */
+
+#pragma once
+
+#include "ConnectionHelper.hxx"
+#include "adminpages.hxx"
+#include <unotools/resmgr.hxx>
+
+namespace dbaui
+{
+
+ // OConnectionTabPageSetup
+
+ /** implements the connection page of the data source properties dialog.
+ */
+ class OConnectionTabPageSetup : public OConnectionHelper
+ {
+ std::unique_ptr<weld::Label> m_xHelpText;
+ std::unique_ptr<weld::Label> m_xHeaderText;
+
+ // called when the test connection button was clicked
+ DECL_LINK(OnEditModified, weld::Entry&, void);
+
+ public:
+ OConnectionTabPageSetup(weld::Container* pPage, weld::DialogController* pController, const OUString& _rUIXMLDescription, const OString& _rId, const SfxItemSet& _rCoreAttrs, TranslateId pHelpTextResId, TranslateId pHeaderResId, TranslateId pUrlResId);
+ virtual ~OConnectionTabPageSetup() override;
+
+ static std::unique_ptr<OGenericAdministrationPage> CreateDbaseTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet);
+ static std::unique_ptr<OGenericAdministrationPage> CreateMSAccessTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet);
+ static std::unique_ptr<OGenericAdministrationPage> CreateADOTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet);
+ static std::unique_ptr<OGenericAdministrationPage> CreateODBCTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet);
+ static std::unique_ptr<OGenericAdministrationPage> CreateUserDefinedTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet);
+
+ virtual bool FillItemSet (SfxItemSet* _rCoreAttrs) override;
+
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+
+ protected:
+ virtual bool checkTestConnection() override;
+ };
+
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/DBSetupConnectionPages.cxx b/dbaccess/source/ui/dlg/DBSetupConnectionPages.cxx
new file mode 100644
index 000000000..ffbde972f
--- /dev/null
+++ b/dbaccess/source/ui/dlg/DBSetupConnectionPages.cxx
@@ -0,0 +1,786 @@
+/* -*- 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 <config_java.h>
+
+#include "DBSetupConnectionPages.hxx"
+#include <core_resource.hxx>
+#include <sqlmessage.hxx>
+#include <strings.hrc>
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <dsitems.hxx>
+#include "dsnItem.hxx"
+
+#if HAVE_FEATURE_JAVA
+ #include <jvmaccess/virtualmachine.hxx>
+#endif
+
+#include <connectivity/CommonTools.hxx>
+#include <dbwizsetup.hxx>
+#include "TextConnectionHelper.hxx"
+#include <osl/diagnose.h>
+
+namespace dbaui
+{
+using namespace ::com::sun::star;
+
+ std::unique_ptr<OGenericAdministrationPage> OTextConnectionPageSetup::CreateTextTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ {
+ return std::make_unique<OTextConnectionPageSetup>(pPage, pController, _rAttrSet);
+ }
+
+ // OTextConnectionPageSetup
+ OTextConnectionPageSetup::OTextConnectionPageSetup(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : OConnectionTabPageSetup(pPage, pController, "dbaccess/ui/dbwiztextpage.ui", "DBWizTextPage",
+ rCoreAttrs, STR_TEXT_HELPTEXT, STR_TEXT_HEADERTEXT, STR_TEXT_PATH_OR_FILE)
+ , m_xSubContainer(m_xBuilder->weld_widget("TextPageContainer"))
+ , m_xTextConnectionHelper(new OTextConnectionHelper(m_xSubContainer.get(), TC_EXTENSION | TC_SEPARATORS))
+ {
+ m_xTextConnectionHelper->SetClickHandler(LINK( this, OTextConnectionPageSetup, ImplGetExtensionHdl ) );
+ }
+
+ OTextConnectionPageSetup::~OTextConnectionPageSetup()
+ {
+ m_xTextConnectionHelper.reset();
+ }
+
+ IMPL_LINK_NOARG(OTextConnectionPageSetup, ImplGetExtensionHdl, OTextConnectionHelper*, void)
+ {
+ SetRoadmapStateValue(!m_xTextConnectionHelper->GetExtension().isEmpty() && OConnectionTabPageSetup::checkTestConnection());
+ callModifiedHdl();
+ }
+
+ bool OTextConnectionPageSetup::checkTestConnection()
+ {
+ bool bDoEnable = OConnectionTabPageSetup::checkTestConnection();
+ bDoEnable = !m_xTextConnectionHelper->GetExtension().isEmpty() && bDoEnable;
+ return bDoEnable;
+ }
+
+ void OTextConnectionPageSetup::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ OConnectionTabPageSetup::fillControls(_rControlList);
+ m_xTextConnectionHelper->fillControls(_rControlList);
+ }
+
+ void OTextConnectionPageSetup::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ OConnectionTabPageSetup::fillWindows(_rControlList);
+ m_xTextConnectionHelper->fillWindows(_rControlList);
+ }
+
+ void OTextConnectionPageSetup::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // first check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+ OConnectionTabPageSetup::implInitControls( _rSet, _bSaveValue);
+ m_xTextConnectionHelper->implInitControls(_rSet, bValid);
+ }
+
+ bool OTextConnectionPageSetup::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = OConnectionTabPageSetup::FillItemSet(_rSet);
+ bChangedSomething = m_xTextConnectionHelper->FillItemSet(*_rSet, bChangedSomething);
+ return bChangedSomething;
+ }
+
+ bool OTextConnectionPageSetup::prepareLeave()
+ {
+ return m_xTextConnectionHelper->prepareLeave();
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OLDAPConnectionPageSetup::CreateLDAPTabPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet )
+ {
+ return std::make_unique<OLDAPConnectionPageSetup>(pPage, pController, _rAttrSet);
+ }
+
+ // OLDAPPageSetup
+ OLDAPConnectionPageSetup::OLDAPConnectionPageSetup( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs )
+ : OGenericAdministrationPage(pPage, pController, "dbaccess/ui/ldapconnectionpage.ui", "LDAPConnectionPage", _rCoreAttrs)
+ , m_xFTHelpText(m_xBuilder->weld_label("helpLabel"))
+ , m_xFTHostServer(m_xBuilder->weld_label("hostNameLabel"))
+ , m_xETHostServer(m_xBuilder->weld_entry("hostNameEntry"))
+ , m_xFTBaseDN(m_xBuilder->weld_label("baseDNLabel"))
+ , m_xETBaseDN(m_xBuilder->weld_entry("baseDNEntry"))
+ , m_xFTPortNumber(m_xBuilder->weld_label("portNumLabel"))
+ , m_xNFPortNumber(m_xBuilder->weld_spin_button("portNumEntry"))
+ , m_xFTDefaultPortNumber(m_xBuilder->weld_label("portNumDefLabel"))
+ , m_xCBUseSSL(m_xBuilder->weld_check_button("useSSLCheckbutton"))
+ {
+ m_xETHostServer->connect_changed(LINK(this, OGenericAdministrationPage, OnControlEntryModifyHdl));
+ m_xETBaseDN->connect_changed(LINK(this, OGenericAdministrationPage, OnControlEntryModifyHdl));
+ m_xNFPortNumber->connect_value_changed(LINK(this, OGenericAdministrationPage, OnControlSpinButtonModifyHdl));
+ m_xCBUseSSL->connect_toggled( LINK(this, OGenericAdministrationPage, OnControlModifiedButtonClick) );
+ SetRoadmapStateValue(false);
+ }
+
+ OLDAPConnectionPageSetup::~OLDAPConnectionPageSetup()
+ {
+ }
+
+ bool OLDAPConnectionPageSetup::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = false;
+ fillString(*_rSet,m_xETBaseDN.get(),DSID_CONN_LDAP_BASEDN, bChangedSomething);
+ fillInt32(*_rSet,m_xNFPortNumber.get(),DSID_CONN_LDAP_PORTNUMBER,bChangedSomething);
+
+ if ( m_xETHostServer->get_value_changed_from_saved() )
+ {
+ const DbuTypeCollectionItem* pCollectionItem = dynamic_cast<const DbuTypeCollectionItem*>( _rSet->GetItem(DSID_TYPECOLLECTION) );
+ ::dbaccess::ODsnTypeCollection* pCollection = nullptr;
+ if (pCollectionItem)
+ pCollection = pCollectionItem->getCollection();
+ OSL_ENSURE(pCollection, "OLDAPConnectionPageSetup::FillItemSet : really need a DSN type collection !");
+ if (pCollection)
+ {
+ OUString sUrl = pCollection->getPrefix( "sdbc:address:ldap:") + m_xETHostServer->get_text();
+ _rSet->Put(SfxStringItem(DSID_CONNECTURL, sUrl));
+ bChangedSomething = true;
+ }
+ }
+
+ fillBool(*_rSet,m_xCBUseSSL.get(),DSID_CONN_LDAP_USESSL,false,bChangedSomething);
+ return bChangedSomething;
+ }
+ void OLDAPConnectionPageSetup::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xETHostServer.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xETBaseDN.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::SpinButton>(m_xNFPortNumber.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xCBUseSSL.get()));
+ }
+ void OLDAPConnectionPageSetup::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTHelpText.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTHostServer.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTBaseDN.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTPortNumber.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTDefaultPortNumber.get()));
+ }
+ void OLDAPConnectionPageSetup::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ const SfxStringItem* pBaseDN = _rSet.GetItem<SfxStringItem>(DSID_CONN_LDAP_BASEDN);
+ const SfxInt32Item* pPortNumber = _rSet.GetItem<SfxInt32Item>(DSID_CONN_LDAP_PORTNUMBER);
+
+ if ( bValid )
+ {
+ m_xETBaseDN->set_text(pBaseDN->GetValue());
+ m_xNFPortNumber->set_value(pPortNumber->GetValue());
+ }
+ OGenericAdministrationPage::implInitControls(_rSet, _bSaveValue);
+ callModifiedHdl();
+ }
+
+ void OLDAPConnectionPageSetup::callModifiedHdl(weld::Widget*)
+ {
+ bool bRoadmapState = ((!m_xETHostServer->get_text().isEmpty() ) && ( !m_xETBaseDN->get_text().isEmpty() ) && (!m_xFTPortNumber->get_label().isEmpty() ));
+ SetRoadmapStateValue(bRoadmapState);
+ OGenericAdministrationPage::callModifiedHdl();
+ }
+
+ std::unique_ptr<OMySQLIntroPageSetup> OMySQLIntroPageSetup::CreateMySQLIntroTabPage(weld::Container* pPage, ODbTypeWizDialogSetup* pController, const SfxItemSet& rAttrSet)
+ {
+ return std::make_unique<OMySQLIntroPageSetup>(pPage, pController, rAttrSet);
+ }
+
+ OMySQLIntroPageSetup::OMySQLIntroPageSetup(weld::Container* pPage, ODbTypeWizDialogSetup* pController, const SfxItemSet& _rCoreAttrs)
+ : OGenericAdministrationPage(pPage, pController, "dbaccess/ui/dbwizmysqlintropage.ui", "DBWizMysqlIntroPage", _rCoreAttrs)
+ , m_xODBCDatabase(m_xBuilder->weld_radio_button("odbc"))
+ , m_xJDBCDatabase(m_xBuilder->weld_radio_button("jdbc"))
+ , m_xNATIVEDatabase(m_xBuilder->weld_radio_button("directly"))
+ {
+ m_xODBCDatabase->connect_toggled(LINK(this, OMySQLIntroPageSetup, OnSetupModeSelected));
+ m_xJDBCDatabase->connect_toggled(LINK(this, OMySQLIntroPageSetup, OnSetupModeSelected));
+ m_xNATIVEDatabase->connect_toggled(LINK(this, OMySQLIntroPageSetup, OnSetupModeSelected));
+ pController->SetIntroPage(this);
+ }
+
+ OMySQLIntroPageSetup::~OMySQLIntroPageSetup()
+ {
+ }
+
+ IMPL_LINK_NOARG(OMySQLIntroPageSetup, OnSetupModeSelected, weld::Toggleable&, void)
+ {
+ maClickHdl.Call( this );
+ }
+
+ void OMySQLIntroPageSetup::implInitControls(const SfxItemSet& _rSet, bool /*_bSaveValue*/)
+ {
+ // show the "Connect directly" option only if the driver is installed
+ const DbuTypeCollectionItem* pCollectionItem = dynamic_cast<const DbuTypeCollectionItem*>( _rSet.GetItem(DSID_TYPECOLLECTION) );
+ bool bHasMySQLNative = ( pCollectionItem != nullptr ) && pCollectionItem->getCollection()->hasDriver( "sdbc:mysql:mysqlc:" );
+ if ( bHasMySQLNative )
+ m_xNATIVEDatabase->show();
+
+ // if any of the options is checked, then there's nothing to do
+ if ( m_xODBCDatabase->get_active() || m_xJDBCDatabase->get_active() || m_xNATIVEDatabase->get_active() )
+ return;
+
+ // prefer "native" or "JDBC"
+ if ( bHasMySQLNative )
+ m_xNATIVEDatabase->set_active(true);
+ else
+ m_xJDBCDatabase->set_active(true);
+ }
+
+ void OMySQLIntroPageSetup::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& /*_rControlList*/)
+ {
+ }
+
+ void OMySQLIntroPageSetup::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& /*_rControlList*/)
+ {
+ }
+
+ bool OMySQLIntroPageSetup::FillItemSet(SfxItemSet* /*_rSet*/)
+ {
+ OSL_FAIL("Who called me?! Please ask oj for more information.");
+ return true;
+ }
+
+ OMySQLIntroPageSetup::ConnectionType OMySQLIntroPageSetup::getMySQLMode() const
+ {
+ if (m_xJDBCDatabase->get_active())
+ return VIA_JDBC;
+ else if (m_xNATIVEDatabase->get_active())
+ return VIA_NATIVE;
+ else
+ return VIA_ODBC;
+ }
+
+ // MySQLNativeSetupPage
+ MySQLNativeSetupPage::MySQLNativeSetupPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs )
+ : OGenericAdministrationPage(pPage, pController, "dbaccess/ui/dbwizmysqlnativepage.ui", "DBWizMysqlNativePage", rCoreAttrs)
+ , m_xHelpText(m_xBuilder->weld_label("helptext"))
+ , m_xSettingsContainer(m_xBuilder->weld_container("MySQLSettingsContainer"))
+ , m_xMySQLSettings(new MySQLNativeSettings(m_xSettingsContainer.get(), LINK(this, OGenericAdministrationPage, OnControlModified)))
+ {
+ SetRoadmapStateValue(false);
+ }
+
+ MySQLNativeSetupPage::~MySQLNativeSetupPage()
+ {
+ m_xMySQLSettings.reset();
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> MySQLNativeSetupPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
+ {
+ return std::make_unique<MySQLNativeSetupPage>(pPage, pController, rAttrSet);
+ }
+
+ void MySQLNativeSetupPage::fillControls( std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList )
+ {
+ m_xMySQLSettings->fillControls( _rControlList );
+ }
+
+ void MySQLNativeSetupPage::fillWindows(std::vector<std::unique_ptr<ISaveValueWrapper>>& rControlList)
+ {
+ rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xHelpText.get()));
+ m_xMySQLSettings->fillWindows(rControlList);
+ }
+
+ bool MySQLNativeSetupPage::FillItemSet( SfxItemSet* _rSet )
+ {
+ return m_xMySQLSettings->FillItemSet( _rSet );
+ }
+
+ void MySQLNativeSetupPage::implInitControls( const SfxItemSet& _rSet, bool _bSaveValue )
+ {
+ m_xMySQLSettings->implInitControls( _rSet );
+
+ OGenericAdministrationPage::implInitControls( _rSet, _bSaveValue );
+
+ callModifiedHdl();
+ }
+
+ void MySQLNativeSetupPage::callModifiedHdl(weld::Widget*)
+ {
+ SetRoadmapStateValue( m_xMySQLSettings->canAdvance() );
+
+ OGenericAdministrationPage::callModifiedHdl();
+ }
+
+ // OMySQLJDBCConnectionPageSetup
+ OGeneralSpecialJDBCConnectionPageSetup::OGeneralSpecialJDBCConnectionPageSetup( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs ,sal_uInt16 _nPortId, TranslateId pDefaultPortResId, TranslateId pHelpTextResId, TranslateId pHeaderTextResId, TranslateId pDriverClassId)
+ : OGenericAdministrationPage(pPage, pController, "dbaccess/ui/specialjdbcconnectionpage.ui", "SpecialJDBCConnectionPage", _rCoreAttrs)
+ , m_nPortId(_nPortId)
+ , m_xHeaderText(m_xBuilder->weld_label("header"))
+ , m_xFTHelpText(m_xBuilder->weld_label("helpLabel"))
+ , m_xFTDatabasename(m_xBuilder->weld_label("dbNameLabel"))
+ , m_xETDatabasename(m_xBuilder->weld_entry("dbNameEntry"))
+ , m_xFTHostname(m_xBuilder->weld_label("hostNameLabel"))
+ , m_xETHostname(m_xBuilder->weld_entry("hostNameEntry"))
+ , m_xFTPortNumber(m_xBuilder->weld_label("portNumLabel"))
+ , m_xFTDefaultPortNumber(m_xBuilder->weld_label("portNumDefLabel"))
+ , m_xNFPortNumber(m_xBuilder->weld_spin_button("portNumEntry"))
+ , m_xFTDriverClass(m_xBuilder->weld_label("jdbcDriverLabel"))
+ , m_xETDriverClass(m_xBuilder->weld_entry("jdbcDriverEntry"))
+ , m_xPBTestJavaDriver(m_xBuilder->weld_button("testDriverButton"))
+ {
+ m_xFTDriverClass->set_label(DBA_RES(pDriverClassId));
+
+ m_xFTDefaultPortNumber->set_label(DBA_RES(pDefaultPortResId));
+ OUString sHelpText = DBA_RES(pHelpTextResId);
+ m_xFTHelpText->set_label(sHelpText);
+ //TODO this code snippet is redundant
+ m_xHeaderText->set_label(DBA_RES(pHeaderTextResId));
+
+ m_xETDatabasename->connect_changed(LINK(this, OGenericAdministrationPage, OnControlEntryModifyHdl));
+ m_xETHostname->connect_changed(LINK(this, OGenericAdministrationPage, OnControlEntryModifyHdl));
+ m_xNFPortNumber->connect_value_changed(LINK(this, OGenericAdministrationPage, OnControlSpinButtonModifyHdl));
+
+ m_xETDriverClass->connect_changed(LINK(this, OGenericAdministrationPage, OnControlEntryModifyHdl));
+ m_xPBTestJavaDriver->connect_clicked(LINK(this,OGeneralSpecialJDBCConnectionPageSetup,OnTestJavaClickHdl));
+
+ const SfxStringItem* pUrlItem = _rCoreAttrs.GetItem<SfxStringItem>(DSID_CONNECTURL);
+ const DbuTypeCollectionItem* pTypesItem = _rCoreAttrs.GetItem<DbuTypeCollectionItem>(DSID_TYPECOLLECTION);
+ ::dbaccess::ODsnTypeCollection* pTypeCollection = pTypesItem ? pTypesItem->getCollection() : nullptr;
+ if (pTypeCollection && pUrlItem && pUrlItem->GetValue().getLength() )
+ {
+ m_sDefaultJdbcDriverName = pTypeCollection->getJavaDriverClass(pUrlItem->GetValue());
+ }
+
+ SetRoadmapStateValue(false);
+ }
+
+ OGeneralSpecialJDBCConnectionPageSetup::~OGeneralSpecialJDBCConnectionPageSetup()
+ {
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OGeneralSpecialJDBCConnectionPageSetup::CreateMySQLJDBCTabPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet )
+ {
+ return std::make_unique<OGeneralSpecialJDBCConnectionPageSetup>(pPage, pController,
+ _rAttrSet,
+ DSID_MYSQL_PORTNUMBER ,
+ STR_MYSQL_DEFAULT,
+ STR_MYSQLJDBC_HELPTEXT,
+ STR_MYSQLJDBC_HEADERTEXT,
+ STR_MYSQL_DRIVERCLASSTEXT);
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OGeneralSpecialJDBCConnectionPageSetup::CreateOracleJDBCTabPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet )
+ {
+ return std::make_unique<OGeneralSpecialJDBCConnectionPageSetup>(pPage, pController,
+ _rAttrSet,
+ DSID_ORACLE_PORTNUMBER,
+ STR_ORACLE_DEFAULT,
+ STR_ORACLE_HELPTEXT,
+ STR_ORACLE_HEADERTEXT,
+ STR_ORACLE_DRIVERCLASSTEXT);
+ }
+
+ void OGeneralSpecialJDBCConnectionPageSetup::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xETDatabasename.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xETDriverClass.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xETHostname.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::SpinButton>(m_xNFPortNumber.get()));
+ }
+
+ void OGeneralSpecialJDBCConnectionPageSetup::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTHelpText.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTDatabasename.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTHostname.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTPortNumber.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTDefaultPortNumber.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTDriverClass.get()));
+ }
+
+ bool OGeneralSpecialJDBCConnectionPageSetup::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = false;
+ fillString(*_rSet,m_xETDriverClass.get(),DSID_JDBCDRIVERCLASS,bChangedSomething);
+ fillString(*_rSet,m_xETHostname.get(),DSID_CONN_HOSTNAME,bChangedSomething);
+ fillString(*_rSet,m_xETDatabasename.get(),DSID_DATABASENAME,bChangedSomething);
+ fillInt32(*_rSet,m_xNFPortNumber.get(),m_nPortId,bChangedSomething );
+ return bChangedSomething;
+ }
+
+ void OGeneralSpecialJDBCConnectionPageSetup::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ const SfxStringItem* pDatabaseName = _rSet.GetItem<SfxStringItem>(DSID_DATABASENAME);
+ const SfxStringItem* pDrvItem = _rSet.GetItem<SfxStringItem>(DSID_JDBCDRIVERCLASS);
+ const SfxStringItem* pHostName = _rSet.GetItem<SfxStringItem>(DSID_CONN_HOSTNAME);
+ const SfxInt32Item* pPortNumber = _rSet.GetItem<SfxInt32Item>(m_nPortId);
+
+ if ( bValid )
+ {
+ m_xETDatabasename->set_text(pDatabaseName->GetValue());
+ m_xETDatabasename->save_value();
+
+ m_xETDriverClass->set_text(pDrvItem->GetValue());
+ m_xETDriverClass->save_value();
+
+ m_xETHostname->set_text(pHostName->GetValue());
+ m_xETHostname->save_value();
+
+ m_xNFPortNumber->set_value(pPortNumber->GetValue());
+ m_xNFPortNumber->save_value();
+ }
+ OGenericAdministrationPage::implInitControls(_rSet, _bSaveValue);
+
+ // to get the correct value when saveValue was called by base class
+ if ( m_xETDriverClass->get_text().trim().isEmpty() )
+ {
+ m_xETDriverClass->set_text(m_sDefaultJdbcDriverName);
+ m_xETDriverClass->save_value();
+ }
+ callModifiedHdl();
+
+ bool bRoadmapState = ((!m_xETDatabasename->get_text().isEmpty() ) && (!m_xETHostname->get_text().isEmpty()) && (!m_xNFPortNumber->get_text().isEmpty() ) && ( !m_xETDriverClass->get_text().isEmpty() ));
+ SetRoadmapStateValue(bRoadmapState);
+ }
+
+ IMPL_LINK_NOARG(OGeneralSpecialJDBCConnectionPageSetup, OnTestJavaClickHdl, weld::Button&, void)
+ {
+ OSL_ENSURE(m_pAdminDialog,"No Admin dialog set! ->GPF");
+
+ bool bSuccess = false;
+#if HAVE_FEATURE_JAVA
+ try
+ {
+ if ( !m_xETDriverClass->get_text().trim().isEmpty() )
+ {
+// TODO change jvmaccess
+ ::rtl::Reference< jvmaccess::VirtualMachine > xJVM = ::connectivity::getJavaVM( m_pAdminDialog->getORB() );
+ m_xETDriverClass->set_text(m_xETDriverClass->get_text().trim()); // fdo#68341
+ bSuccess = ::connectivity::existsJavaClassByName(xJVM,m_xETDriverClass->get_text());
+ }
+ }
+ catch(css::uno::Exception&)
+ {
+ }
+#endif
+ TranslateId pMessage = bSuccess ? STR_JDBCDRIVER_SUCCESS : STR_JDBCDRIVER_NO_SUCCESS;
+ const MessageType mt = bSuccess ? MessageType::Info : MessageType::Error;
+ OSQLMessageBox aMsg(GetFrameWeld(), DBA_RES(pMessage), OUString(), MessBoxStyle::Ok | MessBoxStyle::DefaultOk, mt);
+ aMsg.run();
+ }
+
+ void OGeneralSpecialJDBCConnectionPageSetup::callModifiedHdl(weld::Widget* pControl)
+ {
+ if (pControl == m_xETDriverClass.get())
+ m_xPBTestJavaDriver->set_sensitive( !m_xETDriverClass->get_text().trim().isEmpty() );
+ bool bRoadmapState = ((!m_xETDatabasename->get_text().isEmpty() ) && ( !m_xETHostname->get_text().isEmpty() ) && (!m_xNFPortNumber->get_text().isEmpty() ) && ( !m_xETDriverClass->get_text().trim().isEmpty() ));
+ SetRoadmapStateValue(bRoadmapState);
+ OGenericAdministrationPage::callModifiedHdl();
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OJDBCConnectionPageSetup::CreateJDBCTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ {
+ return std::make_unique<OJDBCConnectionPageSetup>(pPage, pController, _rAttrSet);
+ }
+
+ // OMySQLJDBCConnectionPageSetup
+ OJDBCConnectionPageSetup::OJDBCConnectionPageSetup(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : OConnectionTabPageSetup(pPage, pController, "dbaccess/ui/jdbcconnectionpage.ui", "JDBCConnectionPage", rCoreAttrs,
+ STR_JDBC_HELPTEXT, STR_JDBC_HEADERTEXT, STR_COMMONURL)
+ , m_xFTDriverClass(m_xBuilder->weld_label("jdbcLabel"))
+ , m_xETDriverClass(m_xBuilder->weld_entry("jdbcEntry"))
+ , m_xPBTestJavaDriver(m_xBuilder->weld_button("jdbcButton"))
+ {
+ m_xETDriverClass->connect_changed(LINK(this, OJDBCConnectionPageSetup, OnEditModified));
+ m_xPBTestJavaDriver->connect_clicked(LINK(this,OJDBCConnectionPageSetup,OnTestJavaClickHdl));
+ }
+
+ OJDBCConnectionPageSetup::~OJDBCConnectionPageSetup()
+ {
+ }
+
+ void OJDBCConnectionPageSetup::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xETDriverClass.get()));
+ }
+
+ void OJDBCConnectionPageSetup::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTDriverClass.get()));
+ }
+
+ bool OJDBCConnectionPageSetup::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = OConnectionTabPageSetup::FillItemSet(_rSet);
+ fillString(*_rSet,m_xETDriverClass.get(),DSID_JDBCDRIVERCLASS,bChangedSomething);
+ return bChangedSomething;
+ }
+
+ void OJDBCConnectionPageSetup::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ const SfxStringItem* pDrvItem = _rSet.GetItem<SfxStringItem>(DSID_JDBCDRIVERCLASS);
+
+ if ( bValid )
+ {
+ if ( !pDrvItem->GetValue().getLength() )
+ {
+ OUString sDefaultJdbcDriverName = m_pCollection->getJavaDriverClass(m_eType);
+ if ( !sDefaultJdbcDriverName.isEmpty() )
+ {
+ m_xETDriverClass->set_text(sDefaultJdbcDriverName);
+ m_xETDriverClass->save_value();
+ }
+ }
+ else
+ {
+ m_xETDriverClass->set_text(pDrvItem->GetValue());
+ m_xETDriverClass->save_value();
+ }
+ }
+ bool bEnable = pDrvItem->GetValue().getLength() != 0;
+ m_xPBTestJavaDriver->set_sensitive(bEnable);
+ OConnectionTabPageSetup::implInitControls(_rSet, _bSaveValue);
+
+ SetRoadmapStateValue(checkTestConnection());
+ }
+
+ bool OJDBCConnectionPageSetup::checkTestConnection()
+ {
+ OSL_ENSURE(m_pAdminDialog,"No Admin dialog set! ->GPF");
+ bool bEnableTestConnection = !m_xConnectionURL->get_visible() || !m_xConnectionURL->GetTextNoPrefix().isEmpty();
+ bEnableTestConnection = bEnableTestConnection && (!m_xETDriverClass->get_text().isEmpty());
+ return bEnableTestConnection;
+ }
+
+ IMPL_LINK_NOARG(OJDBCConnectionPageSetup, OnTestJavaClickHdl, weld::Button&, void)
+ {
+ OSL_ENSURE(m_pAdminDialog,"No Admin dialog set! ->GPF");
+ bool bSuccess = false;
+#if HAVE_FEATURE_JAVA
+ try
+ {
+ if ( !m_xETDriverClass->get_text().isEmpty() )
+ {
+// TODO change jvmaccess
+ ::rtl::Reference< jvmaccess::VirtualMachine > xJVM = ::connectivity::getJavaVM( m_pAdminDialog->getORB() );
+ m_xETDriverClass->set_text(m_xETDriverClass->get_text().trim()); // fdo#68341
+ bSuccess = xJVM.is() && ::connectivity::existsJavaClassByName(xJVM,m_xETDriverClass->get_text());
+ }
+ }
+ catch(css::uno::Exception&)
+ {
+ }
+#endif
+ TranslateId pMessage = bSuccess ? STR_JDBCDRIVER_SUCCESS : STR_JDBCDRIVER_NO_SUCCESS;
+ const MessageType mt = bSuccess ? MessageType::Info : MessageType::Error;
+ OSQLMessageBox aMsg(GetFrameWeld(), DBA_RES(pMessage), OUString(), MessBoxStyle::Ok | MessBoxStyle::DefaultOk, mt);
+ aMsg.run();
+ }
+
+ IMPL_LINK(OJDBCConnectionPageSetup, OnEditModified, weld::Entry&, rEdit, void)
+ {
+ if (&rEdit == m_xETDriverClass.get())
+ m_xPBTestJavaDriver->set_sensitive(!m_xETDriverClass->get_text().isEmpty());
+ SetRoadmapStateValue(checkTestConnection());
+ // tell the listener we were modified
+ callModifiedHdl();
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OSpreadSheetConnectionPageSetup::CreateDocumentOrSpreadSheetTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ {
+ return std::make_unique<OSpreadSheetConnectionPageSetup>(pPage, pController, _rAttrSet);
+ }
+
+ OSpreadSheetConnectionPageSetup::OSpreadSheetConnectionPageSetup(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : OConnectionTabPageSetup(pPage, pController, "dbaccess/ui/dbwizspreadsheetpage.ui", "DBWizSpreadsheetPage",
+ rCoreAttrs, STR_SPREADSHEET_HELPTEXT, STR_SPREADSHEET_HEADERTEXT, STR_SPREADSHEETPATH)
+ , m_xPasswordrequired(m_xBuilder->weld_check_button("passwordrequired"))
+ {
+ m_xPasswordrequired->connect_toggled(LINK(this, OGenericAdministrationPage, OnControlModifiedButtonClick));
+ }
+
+ OSpreadSheetConnectionPageSetup::~OSpreadSheetConnectionPageSetup()
+ {
+ }
+
+ void OSpreadSheetConnectionPageSetup::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& /*_rControlList*/)
+ {
+ }
+
+ void OSpreadSheetConnectionPageSetup::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ OConnectionTabPageSetup::fillControls(_rControlList);
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xPasswordrequired.get()));
+
+ }
+
+ bool OSpreadSheetConnectionPageSetup::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = OConnectionTabPageSetup::FillItemSet(_rSet);
+ fillBool(*_rSet,m_xPasswordrequired.get(),DSID_PASSWORDREQUIRED,false,bChangedSomething);
+ return bChangedSomething;
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OAuthentificationPageSetup::CreateAuthentificationTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ {
+ return std::make_unique<OAuthentificationPageSetup>(pPage, pController, _rAttrSet);
+ }
+
+ OAuthentificationPageSetup::OAuthentificationPageSetup(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs)
+ : OGenericAdministrationPage(pPage, pController, "dbaccess/ui/authentificationpage.ui", "AuthentificationPage", _rCoreAttrs)
+ , m_xFTHelpText(m_xBuilder->weld_label("helptext"))
+ , m_xFTUserName(m_xBuilder->weld_label("generalUserNameLabel"))
+ , m_xETUserName(m_xBuilder->weld_entry("generalUserNameEntry"))
+ , m_xCBPasswordRequired(m_xBuilder->weld_check_button("passRequiredCheckbutton"))
+ , m_xPBTestConnection(m_xBuilder->weld_button("testConnectionButton"))
+ {
+ m_xETUserName->connect_changed(LINK(this,OGenericAdministrationPage,OnControlEntryModifyHdl));
+ m_xCBPasswordRequired->connect_toggled(LINK(this,OGenericAdministrationPage,OnControlModifiedButtonClick));
+ m_xPBTestConnection->connect_clicked(LINK(this,OGenericAdministrationPage,OnTestConnectionButtonClickHdl));
+ }
+
+ OAuthentificationPageSetup::~OAuthentificationPageSetup()
+ {
+ }
+
+ void OAuthentificationPageSetup::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTHelpText.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTUserName.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Button>(m_xPBTestConnection.get()));
+ }
+
+ void OAuthentificationPageSetup::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xETUserName.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xCBPasswordRequired.get()));
+ }
+
+ void OAuthentificationPageSetup::implInitControls(const SfxItemSet& _rSet, bool /*_bSaveValue*/)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+ const SfxStringItem* pUidItem = _rSet.GetItem<SfxStringItem>(DSID_USER);
+ const SfxBoolItem* pAllowEmptyPwd = _rSet.GetItem<SfxBoolItem>(DSID_PASSWORDREQUIRED);
+
+ m_xETUserName->set_text(pUidItem->GetValue());
+ m_xCBPasswordRequired->set_active(pAllowEmptyPwd->GetValue());
+
+ m_xETUserName->save_value();
+ }
+
+ bool OAuthentificationPageSetup::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = false;
+
+ if (m_xETUserName->get_value_changed_from_saved())
+ {
+ _rSet->Put(SfxStringItem(DSID_USER, m_xETUserName->get_text()));
+ _rSet->Put(SfxStringItem(DSID_PASSWORD, OUString()));
+ bChangedSomething = true;
+ }
+ fillBool(*_rSet, m_xCBPasswordRequired.get(), DSID_PASSWORDREQUIRED, false, bChangedSomething);
+ return bChangedSomething;
+ }
+
+ std::unique_ptr<OGenericAdministrationPage> OFinalDBPageSetup::CreateFinalDBTabPageSetup(weld::Container* pPage, ODbTypeWizDialogSetup* pController, const SfxItemSet& _rAttrSet)
+ {
+ return std::make_unique<OFinalDBPageSetup>(pPage, pController, _rAttrSet);
+ }
+
+ OFinalDBPageSetup::OFinalDBPageSetup(weld::Container* pPage, ODbTypeWizDialogSetup* pController, const SfxItemSet& _rCoreAttrs)
+ : OGenericAdministrationPage(pPage, pController, "dbaccess/ui/finalpagewizard.ui", "PageFinal", _rCoreAttrs)
+ , m_xFTFinalHeader(m_xBuilder->weld_label("headerText"))
+ , m_xFTFinalHelpText(m_xBuilder->weld_label("helpText"))
+ , m_xRBRegisterDataSource(m_xBuilder->weld_radio_button("yesregister"))
+ , m_xRBDontregisterDataSource(m_xBuilder->weld_radio_button("noregister"))
+ , m_xFTAdditionalSettings(m_xBuilder->weld_label("additionalText"))
+ , m_xCBOpenAfterwards(m_xBuilder->weld_check_button("openediting"))
+ , m_xCBStartTableWizard(m_xBuilder->weld_check_button("usewizard"))
+ , m_xFTFinalText(m_xBuilder->weld_label("finishText"))
+ {
+ m_xCBOpenAfterwards->connect_toggled(LINK(this, OFinalDBPageSetup, OnOpenSelected));
+ m_xRBRegisterDataSource->set_active(true);
+ pController->SetFinalPage(this);
+ }
+
+ OFinalDBPageSetup::~OFinalDBPageSetup()
+ {
+ }
+
+ bool OFinalDBPageSetup::IsDatabaseDocumentToBeRegistered() const
+ {
+ return m_xRBRegisterDataSource->get_active() && m_xRBRegisterDataSource->get_sensitive();
+ }
+
+ bool OFinalDBPageSetup::IsDatabaseDocumentToBeOpened() const
+ {
+ return m_xCBOpenAfterwards->get_active() && m_xCBOpenAfterwards->get_sensitive();
+ }
+
+ bool OFinalDBPageSetup::IsTableWizardToBeStarted() const
+ {
+ return m_xCBStartTableWizard->get_active() && m_xCBStartTableWizard->get_sensitive();
+ }
+
+ void OFinalDBPageSetup::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTFinalHeader.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTFinalHelpText.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTAdditionalSettings.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTFinalText.get()));
+ }
+
+ void OFinalDBPageSetup::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xCBOpenAfterwards.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xCBStartTableWizard.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xRBRegisterDataSource.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xRBDontregisterDataSource.get()));
+ }
+
+ void OFinalDBPageSetup::implInitControls(const SfxItemSet& /*_rSet*/, bool /*_bSaveValue*/)
+ {
+ m_xCBOpenAfterwards->set_active(true);
+ }
+
+ void OFinalDBPageSetup::enableTableWizardCheckBox( bool _bSupportsTableCreation)
+ {
+ m_xCBStartTableWizard->set_sensitive(_bSupportsTableCreation);
+ }
+
+ bool OFinalDBPageSetup::FillItemSet( SfxItemSet* /*_rSet*/ )
+ {
+ return true;
+ }
+
+ IMPL_LINK(OFinalDBPageSetup, OnOpenSelected, weld::Toggleable&, rBox, void)
+ {
+ m_xCBStartTableWizard->set_sensitive(rBox.get_sensitive() && rBox.get_active());
+ }
+}
+
+// namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/DBSetupConnectionPages.hxx b/dbaccess/source/ui/dlg/DBSetupConnectionPages.hxx
new file mode 100644
index 000000000..8bc367602
--- /dev/null
+++ b/dbaccess/source/ui/dlg/DBSetupConnectionPages.hxx
@@ -0,0 +1,270 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "ConnectionPageSetup.hxx"
+
+#include "adminpages.hxx"
+#include "admincontrols.hxx"
+#include "TextConnectionHelper.hxx"
+
+namespace dbaui
+{
+ class ODbTypeWizDialogSetup;
+
+ // OSpreadSheetConnectionPageSetup
+ class OSpreadSheetConnectionPageSetup final : public OConnectionTabPageSetup
+ {
+ public:
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+ static std::unique_ptr<OGenericAdministrationPage> CreateDocumentOrSpreadSheetTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet);
+ OSpreadSheetConnectionPageSetup(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs);
+ virtual ~OSpreadSheetConnectionPageSetup() override;
+
+ private:
+ std::unique_ptr<weld::CheckButton> m_xPasswordrequired;
+
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ };
+
+ // OTextConnectionPage
+ class OTextConnectionPageSetup : public OConnectionTabPageSetup
+ {
+ public:
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+ static std::unique_ptr<OGenericAdministrationPage> CreateTextTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet );
+ OTextConnectionPageSetup(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs);
+ virtual ~OTextConnectionPageSetup() override;
+ protected:
+ virtual bool prepareLeave() override;
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ bool checkTestConnection() override;
+ private:
+ DECL_LINK(ImplGetExtensionHdl, OTextConnectionHelper*, void);
+ std::unique_ptr<weld::Widget> m_xSubContainer;
+ std::unique_ptr<OTextConnectionHelper> m_xTextConnectionHelper;
+ };
+
+ // OLDAPConnectionPageSetup
+ class OLDAPConnectionPageSetup : public OGenericAdministrationPage
+ {
+ public:
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+ static std::unique_ptr<OGenericAdministrationPage> CreateLDAPTabPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet );
+ OLDAPConnectionPageSetup( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs );
+ virtual ~OLDAPConnectionPageSetup() override;
+ virtual void callModifiedHdl(weld::Widget* pControl = nullptr) override;
+
+ protected:
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ private:
+ std::unique_ptr<weld::Label> m_xFTHelpText;
+ std::unique_ptr<weld::Label> m_xFTHostServer;
+ std::unique_ptr<weld::Entry> m_xETHostServer;
+ std::unique_ptr<weld::Label> m_xFTBaseDN;
+ std::unique_ptr<weld::Entry> m_xETBaseDN;
+ std::unique_ptr<weld::Label> m_xFTPortNumber;
+ std::unique_ptr<weld::SpinButton> m_xNFPortNumber;
+ std::unique_ptr<weld::Label> m_xFTDefaultPortNumber;
+ std::unique_ptr<weld::CheckButton> m_xCBUseSSL;
+ };
+
+ // MySQLNativeSetupPage
+ class MySQLNativeSetupPage : public OGenericAdministrationPage
+ {
+ private:
+ std::unique_ptr<weld::Label> m_xHelpText;
+ std::unique_ptr<weld::Container> m_xSettingsContainer;
+ std::unique_ptr<MySQLNativeSettings> m_xMySQLSettings;
+
+ public:
+ MySQLNativeSetupPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ virtual ~MySQLNativeSetupPage() override;
+
+ static std::unique_ptr<OGenericAdministrationPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet);
+
+ protected:
+ virtual void fillControls( std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList ) override;
+ virtual void fillWindows( std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList ) override;
+
+ virtual bool FillItemSet( SfxItemSet* _rCoreAttrs ) override;
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+
+ virtual void callModifiedHdl(weld::Widget* pControl = nullptr) override;
+ };
+
+ // OGeneralSpecialJDBCConnectionPageSetup
+ class OGeneralSpecialJDBCConnectionPageSetup final : public OGenericAdministrationPage
+ {
+ public:
+ OGeneralSpecialJDBCConnectionPageSetup(weld::Container* pPage, weld::DialogController* pController
+ , const SfxItemSet& _rCoreAttrs
+ , sal_uInt16 _nPortId
+ , TranslateId pDefaultPortResId
+ , TranslateId pHelpTextResId
+ , TranslateId pHeaderTextResId
+ , TranslateId pDriverClassId );
+ virtual ~OGeneralSpecialJDBCConnectionPageSetup() override;
+ static std::unique_ptr<OGenericAdministrationPage> CreateMySQLJDBCTabPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet );
+ static std::unique_ptr<OGenericAdministrationPage> CreateOracleJDBCTabPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet );
+
+ private:
+ virtual bool FillItemSet( SfxItemSet* _rCoreAttrs ) override;
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void callModifiedHdl(weld::Widget* pControl = nullptr) override;
+
+ DECL_LINK(OnTestJavaClickHdl, weld::Button&, void);
+
+ OUString m_sDefaultJdbcDriverName;
+ sal_uInt16 m_nPortId;
+
+ std::unique_ptr<weld::Label> m_xHeaderText;
+ std::unique_ptr<weld::Label> m_xFTHelpText;
+ std::unique_ptr<weld::Label> m_xFTDatabasename;
+ std::unique_ptr<weld::Entry> m_xETDatabasename;
+ std::unique_ptr<weld::Label> m_xFTHostname;
+ std::unique_ptr<weld::Entry> m_xETHostname;
+ std::unique_ptr<weld::Label> m_xFTPortNumber;
+ std::unique_ptr<weld::Label> m_xFTDefaultPortNumber;
+ std::unique_ptr<weld::SpinButton> m_xNFPortNumber;
+
+ std::unique_ptr<weld::Label> m_xFTDriverClass;
+ std::unique_ptr<weld::Entry> m_xETDriverClass;
+ std::unique_ptr<weld::Button> m_xPBTestJavaDriver;
+ };
+
+ // OJDBCConnectionPageSetup
+ class OJDBCConnectionPageSetup final : public OConnectionTabPageSetup
+ {
+ public:
+ OJDBCConnectionPageSetup(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs);
+ virtual ~OJDBCConnectionPageSetup() override;
+ static std::unique_ptr<OGenericAdministrationPage> CreateJDBCTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet);
+
+ private:
+ virtual bool checkTestConnection() override;
+
+ virtual bool FillItemSet( SfxItemSet* _rCoreAttrs ) override;
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ DECL_LINK(OnTestJavaClickHdl, weld::Button&, void);
+ DECL_LINK(OnEditModified, weld::Entry&, void);
+ std::unique_ptr<weld::Label> m_xFTDriverClass;
+ std::unique_ptr<weld::Entry> m_xETDriverClass;
+ std::unique_ptr<weld::Button> m_xPBTestJavaDriver;
+ };
+
+ // OMySQLIntroPageSetup
+ class OMySQLIntroPageSetup : public OGenericAdministrationPage
+ {
+ public:
+ enum ConnectionType
+ {
+ VIA_ODBC,
+ VIA_JDBC,
+ VIA_NATIVE
+ };
+
+ OMySQLIntroPageSetup(weld::Container* pPage, ODbTypeWizDialogSetup* pController, const SfxItemSet& rCoreAttrs);
+ virtual ~OMySQLIntroPageSetup() override;
+
+ static std::unique_ptr<OMySQLIntroPageSetup> CreateMySQLIntroTabPage(weld::Container* pPage, ODbTypeWizDialogSetup* pController, const SfxItemSet& rAttrSet);
+ ConnectionType getMySQLMode() const;
+ void SetClickHdl( const Link<OMySQLIntroPageSetup *, void>& rLink ) { maClickHdl = rLink; }
+
+ protected:
+ virtual bool FillItemSet(SfxItemSet* _rSet) override;
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ private:
+ std::unique_ptr<weld::RadioButton> m_xODBCDatabase;
+ std::unique_ptr<weld::RadioButton> m_xJDBCDatabase;
+ std::unique_ptr<weld::RadioButton> m_xNATIVEDatabase;
+ Link<OMySQLIntroPageSetup *, void> maClickHdl;
+
+ DECL_LINK(OnSetupModeSelected, weld::Toggleable&, void);
+ };
+
+ // OAuthentificationPageSetup
+ class OAuthentificationPageSetup final : public OGenericAdministrationPage
+ {
+ public:
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+ static std::unique_ptr<OGenericAdministrationPage> CreateAuthentificationTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet);
+ OAuthentificationPageSetup(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs);
+ virtual ~OAuthentificationPageSetup() override;
+
+ private:
+ std::unique_ptr<weld::Label> m_xFTHelpText;
+ std::unique_ptr<weld::Label> m_xFTUserName;
+ std::unique_ptr<weld::Entry> m_xETUserName;
+ std::unique_ptr<weld::CheckButton> m_xCBPasswordRequired;
+ std::unique_ptr<weld::Button> m_xPBTestConnection;
+
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ };
+
+ // OFinalDBPageSetup
+ class OFinalDBPageSetup : public OGenericAdministrationPage
+ {
+ public:
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+ static std::unique_ptr<OGenericAdministrationPage> CreateFinalDBTabPageSetup(weld::Container* pPage, ODbTypeWizDialogSetup* pController, const SfxItemSet& _rAttrSet);
+
+ OFinalDBPageSetup(weld::Container* pPage, ODbTypeWizDialogSetup* pController, const SfxItemSet& _rCoreAttrs);
+ virtual ~OFinalDBPageSetup() override;
+ bool IsDatabaseDocumentToBeRegistered() const;
+ bool IsDatabaseDocumentToBeOpened() const;
+ bool IsTableWizardToBeStarted() const;
+ void enableTableWizardCheckBox( bool _bSupportsTableCreation);
+
+ DECL_LINK(OnOpenSelected, weld::Toggleable&, void);
+ protected:
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ private:
+ std::unique_ptr<weld::Label> m_xFTFinalHeader;
+ std::unique_ptr<weld::Label> m_xFTFinalHelpText;
+ std::unique_ptr<weld::RadioButton> m_xRBRegisterDataSource;
+ std::unique_ptr<weld::RadioButton> m_xRBDontregisterDataSource;
+ std::unique_ptr<weld::Label> m_xFTAdditionalSettings;
+ std::unique_ptr<weld::CheckButton> m_xCBOpenAfterwards;
+ std::unique_ptr<weld::CheckButton> m_xCBStartTableWizard;
+ std::unique_ptr<weld::Label> m_xFTFinalText;
+ };
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/DbAdminImpl.cxx b/dbaccess/source/ui/dlg/DbAdminImpl.cxx
new file mode 100644
index 000000000..ca20930ef
--- /dev/null
+++ b/dbaccess/source/ui/dlg/DbAdminImpl.cxx
@@ -0,0 +1,1074 @@
+/* -*- 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 "DbAdminImpl.hxx"
+#include <dsmeta.hxx>
+
+#include <svl/poolitem.hxx>
+#include <svl/itempool.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/eitem.hxx>
+#include <IItemSetHelper.hxx>
+#include <UITools.hxx>
+#include <core_resource.hxx>
+#include <strings.hrc>
+#include <strings.hxx>
+#include <dsitems.hxx>
+#include "dsnItem.hxx"
+#include "optionalboolitem.hxx"
+#include <stringlistitem.hxx>
+#include <OAuthenticationContinuation.hxx>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdbc/ConnectionPool.hpp>
+#include <com/sun/star/sdbc/XDriver.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/ucb/AuthenticationRequest.hpp>
+
+#include <comphelper/interaction.hxx>
+#include <comphelper/sequence.hxx>
+#include <connectivity/DriversConfig.hxx>
+#include <connectivity/dbexception.hxx>
+#include <osl/file.hxx>
+#include <tools/diagnose_ex.h>
+#include <osl/diagnose.h>
+#include <sal/log.hxx>
+#include <typelib/typedescription.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/weld.hxx>
+
+#include <algorithm>
+#include <iterator>
+#include <functional>
+#include <o3tl/functional.hxx>
+
+namespace dbaui
+{
+using namespace ::dbtools;
+using namespace com::sun::star::uno;
+using namespace com::sun::star;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::task;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::sdb;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::container;
+using namespace com::sun::star::frame;
+
+namespace
+{
+ bool implCheckItemType( SfxItemSet const & _rSet, const sal_uInt16 _nId, const std::function<bool ( const SfxPoolItem* )>& isItemType )
+ {
+ bool bCorrectType = false;
+
+ SfxItemPool* pPool = _rSet.GetPool();
+ OSL_ENSURE( pPool, "implCheckItemType: invalid item pool!" );
+ if ( pPool )
+ {
+ const SfxPoolItem& rDefItem = pPool->GetDefaultItem( _nId );
+ bCorrectType = isItemType(&rDefItem);
+ }
+ return bCorrectType;
+ }
+
+ void lcl_putProperty(const Reference< XPropertySet >& _rxSet, const OUString& _rName, const Any& _rValue)
+ {
+ try
+ {
+ if ( _rxSet.is() )
+ _rxSet->setPropertyValue(_rName, _rValue);
+ }
+ catch(Exception&)
+ {
+ SAL_WARN("dbaccess", "ODbAdminDialog::implTranslateProperty: could not set the property "
+ << _rName);
+ }
+
+ }
+
+ OUString lcl_createHostWithPort(const SfxStringItem* _pHostName,const SfxInt32Item* _pPortNumber)
+ {
+ OUString sNewUrl;
+
+ if ( _pHostName && _pHostName->GetValue().getLength() )
+ sNewUrl = _pHostName->GetValue();
+
+ if ( _pPortNumber )
+ {
+ sNewUrl += ":" + OUString::number(_pPortNumber->GetValue());
+ }
+
+ return sNewUrl;
+ }
+}
+
+ // ODbDataSourceAdministrationHelper
+ODbDataSourceAdministrationHelper::ODbDataSourceAdministrationHelper(const Reference< XComponentContext >& _xORB, weld::Window* pParent, weld::Window* pTopParent, IItemSetHelper* _pItemSetHelper)
+ : m_xContext(_xORB)
+ , m_pParent(pParent)
+ , m_pItemSetHelper(_pItemSetHelper)
+{
+ /// initialize the property translation map
+ // direct properties of a data source
+ m_aDirectPropTranslator.emplace( DSID_CONNECTURL, PROPERTY_URL );
+ m_aDirectPropTranslator.emplace( DSID_NAME, PROPERTY_NAME );
+ m_aDirectPropTranslator.emplace( DSID_USER, PROPERTY_USER );
+ m_aDirectPropTranslator.emplace( DSID_PASSWORD, PROPERTY_PASSWORD );
+ m_aDirectPropTranslator.emplace( DSID_PASSWORDREQUIRED, PROPERTY_ISPASSWORDREQUIRED );
+ m_aDirectPropTranslator.emplace( DSID_TABLEFILTER, PROPERTY_TABLEFILTER );
+ m_aDirectPropTranslator.emplace( DSID_READONLY, PROPERTY_ISREADONLY );
+ m_aDirectPropTranslator.emplace( DSID_SUPPRESSVERSIONCL, PROPERTY_SUPPRESSVERSIONCL );
+
+ // implicit properties, to be found in the direct property "Info"
+ m_aIndirectPropTranslator.emplace( DSID_JDBCDRIVERCLASS, INFO_JDBCDRIVERCLASS );
+ m_aIndirectPropTranslator.emplace( DSID_TEXTFILEEXTENSION, INFO_TEXTFILEEXTENSION );
+ m_aIndirectPropTranslator.emplace( DSID_CHARSET, INFO_CHARSET );
+ m_aIndirectPropTranslator.emplace( DSID_TEXTFILEHEADER, INFO_TEXTFILEHEADER );
+ m_aIndirectPropTranslator.emplace( DSID_FIELDDELIMITER, INFO_FIELDDELIMITER );
+ m_aIndirectPropTranslator.emplace( DSID_TEXTDELIMITER, INFO_TEXTDELIMITER );
+ m_aIndirectPropTranslator.emplace( DSID_DECIMALDELIMITER, INFO_DECIMALDELIMITER );
+ m_aIndirectPropTranslator.emplace( DSID_THOUSANDSDELIMITER, INFO_THOUSANDSDELIMITER );
+ m_aIndirectPropTranslator.emplace( DSID_SHOWDELETEDROWS, INFO_SHOWDELETEDROWS );
+ m_aIndirectPropTranslator.emplace( DSID_ALLOWLONGTABLENAMES, INFO_ALLOWLONGTABLENAMES );
+ m_aIndirectPropTranslator.emplace( DSID_ADDITIONALOPTIONS, INFO_ADDITIONALOPTIONS );
+ m_aIndirectPropTranslator.emplace( DSID_SQL92CHECK, PROPERTY_ENABLESQL92CHECK );
+ m_aIndirectPropTranslator.emplace( DSID_AUTOINCREMENTVALUE, PROPERTY_AUTOINCREMENTCREATION );
+ m_aIndirectPropTranslator.emplace( DSID_AUTORETRIEVEVALUE, INFO_AUTORETRIEVEVALUE );
+ m_aIndirectPropTranslator.emplace( DSID_AUTORETRIEVEENABLED, INFO_AUTORETRIEVEENABLED );
+ m_aIndirectPropTranslator.emplace( DSID_APPEND_TABLE_ALIAS, INFO_APPEND_TABLE_ALIAS );
+ m_aIndirectPropTranslator.emplace( DSID_AS_BEFORE_CORRNAME, INFO_AS_BEFORE_CORRELATION_NAME );
+ m_aIndirectPropTranslator.emplace( DSID_CHECK_REQUIRED_FIELDS, INFO_FORMS_CHECK_REQUIRED_FIELDS );
+ m_aIndirectPropTranslator.emplace( DSID_ESCAPE_DATETIME, INFO_ESCAPE_DATETIME );
+ m_aIndirectPropTranslator.emplace( DSID_PRIMARY_KEY_SUPPORT, OUString("PrimaryKeySupport") );
+ m_aIndirectPropTranslator.emplace( DSID_PARAMETERNAMESUBST, INFO_PARAMETERNAMESUBST );
+ m_aIndirectPropTranslator.emplace( DSID_IGNOREDRIVER_PRIV, INFO_IGNOREDRIVER_PRIV );
+ m_aIndirectPropTranslator.emplace( DSID_BOOLEANCOMPARISON, PROPERTY_BOOLEANCOMPARISONMODE );
+ m_aIndirectPropTranslator.emplace( DSID_ENABLEOUTERJOIN, PROPERTY_ENABLEOUTERJOIN );
+ m_aIndirectPropTranslator.emplace( DSID_CATALOG, PROPERTY_USECATALOGINSELECT );
+ m_aIndirectPropTranslator.emplace( DSID_SCHEMA, PROPERTY_USESCHEMAINSELECT );
+ m_aIndirectPropTranslator.emplace( DSID_INDEXAPPENDIX, OUString("AddIndexAppendix") );
+ m_aIndirectPropTranslator.emplace( DSID_DOSLINEENDS, OUString("PreferDosLikeLineEnds") );
+ m_aIndirectPropTranslator.emplace( DSID_CONN_SOCKET, OUString("LocalSocket") );
+ m_aIndirectPropTranslator.emplace( DSID_NAMED_PIPE, OUString("NamedPipe") );
+ m_aIndirectPropTranslator.emplace( DSID_RESPECTRESULTSETTYPE, OUString("RespectDriverResultSetType") );
+ m_aIndirectPropTranslator.emplace( DSID_MAX_ROW_SCAN, OUString("MaxRowScan") );
+
+ // extra settings for ODBC
+ m_aIndirectPropTranslator.emplace( DSID_USECATALOG, INFO_USECATALOG );
+ // extra settings for an LDAP address book
+ m_aIndirectPropTranslator.emplace( DSID_CONN_LDAP_BASEDN, INFO_CONN_LDAP_BASEDN );
+ m_aIndirectPropTranslator.emplace( DSID_CONN_LDAP_ROWCOUNT, INFO_CONN_LDAP_ROWCOUNT );
+ m_aIndirectPropTranslator.emplace( DSID_CONN_LDAP_USESSL, OUString("UseSSL") );
+ m_aIndirectPropTranslator.emplace( DSID_DOCUMENT_URL, PROPERTY_URL );
+
+ // Oracle
+ m_aIndirectPropTranslator.emplace( DSID_IGNORECURRENCY, OUString("IgnoreCurrency") );
+
+ try
+ {
+ m_xDatabaseContext = DatabaseContext::create(m_xContext);
+ }
+ catch(const Exception&)
+ {
+ ShowServiceNotAvailableError(pTopParent, u"com.sun.star.sdb.DatabaseContext", true);
+ }
+}
+
+bool ODbDataSourceAdministrationHelper::getCurrentSettings(Sequence< PropertyValue >& _rDriverParam)
+{
+ OSL_ENSURE(m_pItemSetHelper->getOutputSet(), "ODbDataSourceAdministrationHelper::getCurrentSettings : not to be called without an example set!");
+ if (!m_pItemSetHelper->getOutputSet())
+ return false;
+
+ std::vector< PropertyValue > aReturn;
+ // collecting this in a vector because it has a push_back, in opposite to sequences
+
+ // user: DSID_USER -> "user"
+ const SfxStringItem* pUser = m_pItemSetHelper->getOutputSet()->GetItem<SfxStringItem>(DSID_USER);
+ if (pUser && pUser->GetValue().getLength())
+ aReturn.emplace_back( "user", 0,
+ Any(pUser->GetValue()), PropertyState_DIRECT_VALUE);
+
+ // check if the connection type requires a password
+ if (hasAuthentication(*m_pItemSetHelper->getOutputSet()))
+ {
+ // password: DSID_PASSWORD -> password
+ const SfxStringItem* pPassword = m_pItemSetHelper->getOutputSet()->GetItem<SfxStringItem>(DSID_PASSWORD);
+ OUString sPassword = pPassword ? pPassword->GetValue() : OUString();
+ const SfxBoolItem* pPasswordRequired = m_pItemSetHelper->getOutputSet()->GetItem<SfxBoolItem>(DSID_PASSWORDREQUIRED);
+ // if the set does not contain a password, but the item set says it requires one, ask the user
+ if ((!pPassword || !pPassword->GetValue().getLength()) && (pPasswordRequired && pPasswordRequired->GetValue()))
+ {
+ const SfxStringItem* pName = m_pItemSetHelper->getOutputSet()->GetItem<SfxStringItem>(DSID_NAME);
+
+ Reference< XModel > xModel( getDataSourceOrModel( m_xDatasource ), UNO_QUERY_THROW );
+ ::comphelper::NamedValueCollection aArgs( xModel->getArgs() );
+ Reference< XInteractionHandler > xHandler( aArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) );
+
+ if ( !xHandler.is() )
+ {
+ // instantiate the default SDB interaction handler
+ xHandler = task::InteractionHandler::createWithParent(m_xContext, m_pParent->GetXWindow());
+ }
+
+ OUString sName = pName ? pName->GetValue() : OUString();
+ OUString sLoginRequest(DBA_RES(STR_ENTER_CONNECTION_PASSWORD));
+ OUString sTemp = sName;
+ sName = ::dbaui::getStrippedDatabaseName(nullptr,sTemp);
+ if ( !sName.isEmpty() )
+ sLoginRequest = sLoginRequest.replaceAll("$name$", sName);
+ else
+ {
+ sLoginRequest = sLoginRequest.replaceAll("\"$name$\"", "");
+ // ensure that in other languages the string will be deleted
+ sLoginRequest = sLoginRequest.replaceAll("$name$", "");
+ }
+
+ // the request
+ AuthenticationRequest aRequest;
+ aRequest.ServerName = sName;
+ aRequest.Diagnostic = sLoginRequest;
+ aRequest.HasRealm = false;
+ // aRequest.Realm
+ aRequest.HasUserName = pUser != nullptr;
+ aRequest.UserName = pUser ? pUser->GetValue() : OUString();
+ aRequest.HasPassword = true;
+ //aRequest.Password
+ aRequest.HasAccount = false;
+ // aRequest.Account
+
+ rtl::Reference<comphelper::OInteractionRequest> pRequest = new comphelper::OInteractionRequest(Any(aRequest));
+
+ // build an interaction request
+ // two continuations (Ok and Cancel)
+ ::rtl::Reference< comphelper::OInteractionAbort > pAbort = new comphelper::OInteractionAbort;
+ ::rtl::Reference< dbaccess::OAuthenticationContinuation > pAuthenticate = new dbaccess::OAuthenticationContinuation;
+ pAuthenticate->setCanChangeUserName( false );
+ pAuthenticate->setRememberPassword( RememberAuthentication_SESSION );
+
+ // some knittings
+ pRequest->addContinuation(pAbort);
+ pRequest->addContinuation(pAuthenticate);
+
+ // handle the request
+ try
+ {
+ SolarMutexGuard aSolarGuard;
+ // release the mutex when calling the handler, it may need to lock the SolarMutex
+ xHandler->handle(pRequest);
+ }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ if (!pAuthenticate->wasSelected())
+ return false;
+
+ sPassword = pAuthenticate->getPassword();
+ if (pAuthenticate->getRememberPassword())
+ m_pItemSetHelper->getWriteOutputSet()->Put(SfxStringItem(DSID_PASSWORD, sPassword));
+ }
+
+ if (!sPassword.isEmpty())
+ aReturn.emplace_back( "password", 0,
+ Any(sPassword), PropertyState_DIRECT_VALUE);
+ }
+
+ if ( !aReturn.empty() )
+ _rDriverParam = comphelper::containerToSequence(aReturn);
+
+ // append all the other stuff (charset etc.)
+ fillDatasourceInfo(*m_pItemSetHelper->getOutputSet(), _rDriverParam);
+
+ return true;
+}
+
+void ODbDataSourceAdministrationHelper::successfullyConnected()
+{
+ OSL_ENSURE(m_pItemSetHelper->getOutputSet(), "ODbDataSourceAdministrationHelper::successfullyConnected: not to be called without an example set!");
+ if (!m_pItemSetHelper->getOutputSet())
+ return;
+
+ if (hasAuthentication(*m_pItemSetHelper->getOutputSet()))
+ {
+ const SfxStringItem* pPassword = m_pItemSetHelper->getOutputSet()->GetItem<SfxStringItem>(DSID_PASSWORD);
+ if (pPassword && (0 != pPassword->GetValue().getLength()))
+ {
+ OUString sPassword = pPassword->GetValue();
+
+ Reference< XPropertySet > xCurrentDatasource = getCurrentDataSource();
+ lcl_putProperty(xCurrentDatasource,m_aDirectPropTranslator[DSID_PASSWORD], Any(sPassword));
+ }
+ }
+}
+
+void ODbDataSourceAdministrationHelper::clearPassword()
+{
+ if (m_pItemSetHelper->getWriteOutputSet())
+ m_pItemSetHelper->getWriteOutputSet()->ClearItem(DSID_PASSWORD);
+}
+
+std::pair< Reference<XConnection>,bool> ODbDataSourceAdministrationHelper::createConnection()
+{
+ std::pair< Reference<XConnection>,bool> aRet;
+ aRet.second = false;
+ Sequence< PropertyValue > aConnectionParams;
+ if ( getCurrentSettings(aConnectionParams) )
+ {
+ // the current DSN
+ // fill the table list with this connection information
+ SQLExceptionInfo aErrorInfo;
+ try
+ {
+ weld::WaitObject aWaitCursor(m_pParent);
+ aRet.first = getDriver()->connect(getConnectionURL(), aConnectionParams);
+ aRet.second = true;
+ }
+ catch (const SQLContext& e) { aErrorInfo = SQLExceptionInfo(e); }
+ catch (const SQLWarning& e) { aErrorInfo = SQLExceptionInfo(e); }
+ catch (const SQLException& e) { aErrorInfo = SQLExceptionInfo(e); }
+
+ showError(aErrorInfo,m_pParent->GetXWindow(),getORB());
+ }
+ if ( aRet.first.is() )
+ successfullyConnected();// notify the admindlg to save the password
+
+ return aRet;
+}
+
+Reference< XDriver > ODbDataSourceAdministrationHelper::getDriver()
+{
+ return getDriver(getConnectionURL());
+}
+
+Reference< XDriver > ODbDataSourceAdministrationHelper::getDriver(const OUString& _sURL)
+{
+ // get the global DriverManager
+ Reference< XConnectionPool > xDriverManager;
+
+ OUString sCurrentActionError = DBA_RES(STR_COULDNOTCREATE_DRIVERMANAGER);
+ sCurrentActionError = sCurrentActionError.replaceFirst("#servicename#", "com.sun.star.sdbc.ConnectionPool");
+
+ try
+ {
+ xDriverManager.set( ConnectionPool::create( getORB() ) );
+ }
+ catch (const Exception&)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ // wrap the exception into an SQLException
+ throw SQLException(sCurrentActionError, getORB(), "S1000", 0, anyEx);
+ }
+
+ Reference< XDriver > xDriver = xDriverManager->getDriverByURL(_sURL);
+ if (!xDriver.is())
+ {
+ sCurrentActionError = DBA_RES(STR_NOREGISTEREDDRIVER);
+ sCurrentActionError = sCurrentActionError.replaceFirst("#connurl#", _sURL);
+ // will be caught and translated into an SQLContext exception
+ throw SQLException(sCurrentActionError, getORB(), "S1000", 0, Any());
+ }
+ return xDriver;
+}
+
+Reference< XPropertySet > const & ODbDataSourceAdministrationHelper::getCurrentDataSource()
+{
+ if ( !m_xDatasource.is() )
+ {
+ Reference<XInterface> xIn(m_aDataSourceOrName,UNO_QUERY);
+ if ( !xIn.is() )
+ {
+ OUString sCurrentDatasource;
+ m_aDataSourceOrName >>= sCurrentDatasource;
+ OSL_ENSURE(!sCurrentDatasource.isEmpty(),"No datasource name given!");
+ try
+ {
+ if ( m_xDatabaseContext.is() )
+ m_xDatasource.set(m_xDatabaseContext->getByName(sCurrentDatasource),UNO_QUERY);
+ xIn = m_xDatasource;
+ }
+ catch(const Exception&)
+ {
+ }
+ }
+ m_xModel.set(getDataSourceOrModel(xIn),UNO_QUERY);
+ if ( m_xModel.is() )
+ m_xDatasource.set(xIn,UNO_QUERY);
+ else
+ {
+ m_xDatasource.set(getDataSourceOrModel(xIn),UNO_QUERY);
+ m_xModel.set(xIn,UNO_QUERY);
+ }
+ }
+
+ OSL_ENSURE(m_xDatasource.is(), "ODbDataSourceAdministrationHelper::getCurrentDataSource: no data source!");
+ return m_xDatasource;
+}
+
+OUString ODbDataSourceAdministrationHelper::getDatasourceType( const SfxItemSet& _rSet )
+{
+ const SfxStringItem* pConnectURL = _rSet.GetItem<SfxStringItem>(DSID_CONNECTURL);
+ OSL_ENSURE( pConnectURL , "ODbDataSourceAdministrationHelper::getDatasourceType: invalid items in the source set!" );
+ const DbuTypeCollectionItem* pTypeCollection = _rSet.GetItem<DbuTypeCollectionItem>(DSID_TYPECOLLECTION);
+ OSL_ENSURE(pTypeCollection, "ODbDataSourceAdministrationHelper::getDatasourceType: invalid items in the source set!");
+ ::dbaccess::ODsnTypeCollection* pCollection = pTypeCollection->getCollection();
+ return pCollection->getType(pConnectURL->GetValue());
+}
+
+bool ODbDataSourceAdministrationHelper::hasAuthentication(const SfxItemSet& _rSet)
+{
+ return DataSourceMetaData::getAuthentication( getDatasourceType( _rSet ) ) != AuthNone;
+}
+
+OUString ODbDataSourceAdministrationHelper::getConnectionURL() const
+{
+ OUString sNewUrl;
+
+ OUString eType = getDatasourceType(*m_pItemSetHelper->getOutputSet());
+
+ const SfxStringItem* pUrlItem = m_pItemSetHelper->getOutputSet()->GetItem<SfxStringItem>(DSID_CONNECTURL);
+ const DbuTypeCollectionItem* pTypeCollection = m_pItemSetHelper->getOutputSet()->GetItem<DbuTypeCollectionItem>(DSID_TYPECOLLECTION);
+
+ OSL_ENSURE(pUrlItem,"Connection URL is NULL. -> GPF!");
+ OSL_ENSURE(pTypeCollection, "ODbDataSourceAdministrationHelper::getDatasourceType: invalid items in the source set!");
+ ::dbaccess::ODsnTypeCollection* pCollection = pTypeCollection->getCollection();
+ OSL_ENSURE(pCollection, "ODbDataSourceAdministrationHelper::getDatasourceType: invalid type collection!");
+
+ switch( pCollection->determineType(eType) )
+ {
+ case ::dbaccess::DST_DBASE:
+ case ::dbaccess::DST_FLAT:
+ case ::dbaccess::DST_CALC:
+ case ::dbaccess::DST_WRITER:
+ break;
+ case ::dbaccess::DST_MSACCESS:
+ case ::dbaccess::DST_MSACCESS_2007:
+ {
+ OUString sFileName = pCollection->cutPrefix(pUrlItem->GetValue());
+ OUString sNewFileName;
+ if ( ::osl::FileBase::getSystemPathFromFileURL( sFileName, sNewFileName ) == ::osl::FileBase::E_None )
+ {
+ sNewUrl += sNewFileName;
+ }
+ }
+ break;
+ case ::dbaccess::DST_MYSQL_NATIVE:
+ case ::dbaccess::DST_MYSQL_JDBC:
+ {
+ const SfxStringItem* pHostName = m_pItemSetHelper->getOutputSet()->GetItem<SfxStringItem>(DSID_CONN_HOSTNAME);
+ const SfxInt32Item* pPortNumber = m_pItemSetHelper->getOutputSet()->GetItem<SfxInt32Item>(DSID_MYSQL_PORTNUMBER);
+ const SfxStringItem* pDatabaseName = m_pItemSetHelper->getOutputSet()->GetItem<SfxStringItem>(DSID_DATABASENAME);
+ sNewUrl = lcl_createHostWithPort(pHostName,pPortNumber);
+ OUString sDatabaseName = pDatabaseName ? pDatabaseName->GetValue() : OUString();
+ if ( !sDatabaseName.getLength() && pUrlItem )
+ sDatabaseName = pCollection->cutPrefix( pUrlItem->GetValue() );
+ // TODO: what's that? Why is the database name transported via the URL Item?
+ // Huh? Anybody there?
+ // OJ: It is needed when the connection properties are changed. There the URL is used for every type.
+
+ if ( !sDatabaseName.isEmpty() )
+ {
+ sNewUrl += "/" + sDatabaseName;
+ }
+ }
+ break;
+ case ::dbaccess::DST_ORACLE_JDBC:
+ {
+ const SfxStringItem* pHostName = m_pItemSetHelper->getOutputSet()->GetItem<SfxStringItem>(DSID_CONN_HOSTNAME);
+ const SfxInt32Item* pPortNumber = m_pItemSetHelper->getOutputSet()->GetItem<SfxInt32Item>(DSID_ORACLE_PORTNUMBER);
+ const SfxStringItem* pDatabaseName = m_pItemSetHelper->getOutputSet()->GetItem<SfxStringItem>(DSID_DATABASENAME);
+ if ( pHostName && pHostName->GetValue().getLength() )
+ {
+ sNewUrl = "@" + lcl_createHostWithPort(pHostName,pPortNumber);
+ OUString sDatabaseName = pDatabaseName ? pDatabaseName->GetValue() : OUString();
+ if ( sDatabaseName.isEmpty() && pUrlItem )
+ sDatabaseName = pCollection->cutPrefix( pUrlItem->GetValue() );
+ if ( !sDatabaseName.isEmpty() )
+ {
+ sNewUrl += ":" + sDatabaseName;
+ }
+ }
+ else
+ { // here someone entered a JDBC url which looks like oracle, so we have to use the url property
+
+ }
+ }
+ break;
+ case ::dbaccess::DST_LDAP:
+ {
+ const SfxInt32Item* pPortNumber = m_pItemSetHelper->getOutputSet()->GetItem<SfxInt32Item>(DSID_CONN_LDAP_PORTNUMBER);
+ sNewUrl = pCollection->cutPrefix(pUrlItem->GetValue()) + lcl_createHostWithPort(nullptr,pPortNumber);
+ }
+ break;
+ case ::dbaccess::DST_JDBC:
+ // run through
+ default:
+ break;
+ }
+ if ( !sNewUrl.isEmpty() )
+ sNewUrl = pCollection->getPrefix(eType) + sNewUrl;
+ else
+ sNewUrl = pUrlItem->GetValue();
+
+ return sNewUrl;
+}
+
+namespace {
+
+struct PropertyValueLess
+{
+ bool operator() (const PropertyValue& x, const PropertyValue& y) const
+ { return x.Name < y.Name; } // construct prevents a MSVC6 warning
+};
+
+}
+
+typedef std::set<PropertyValue, PropertyValueLess> PropertyValueSet;
+
+void ODbDataSourceAdministrationHelper::translateProperties(const Reference< XPropertySet >& _rxSource, SfxItemSet& _rDest)
+{
+ if (_rxSource.is())
+ {
+ for (auto const& elem : m_aDirectPropTranslator)
+ {
+ // get the property value
+ Any aValue;
+ try
+ {
+ aValue = _rxSource->getPropertyValue(elem.second);
+ }
+ catch(Exception&)
+ {
+ SAL_WARN("dbaccess", "ODbDataSourceAdministrationHelper::translateProperties: could not extract the property "
+ << elem.second);
+ }
+ // transfer it into an item
+ implTranslateProperty(_rDest, elem.first, aValue);
+ }
+
+ // get the additional information
+ Sequence< PropertyValue > aAdditionalInfo;
+ try
+ {
+ _rxSource->getPropertyValue(PROPERTY_INFO) >>= aAdditionalInfo;
+ }
+ catch(Exception&) { }
+
+ // collect the names of the additional settings
+ PropertyValueSet aInfos;
+ for (const PropertyValue& rAdditionalInfo : std::as_const(aAdditionalInfo))
+ {
+ if( rAdditionalInfo.Name == "JDBCDRV" )
+ { // compatibility
+ PropertyValue aCompatibility(rAdditionalInfo);
+ aCompatibility.Name = "JavaDriverClass";
+ aInfos.insert(aCompatibility);
+ }
+ else
+ aInfos.insert(rAdditionalInfo);
+ }
+
+ // go through all known translations and check if we have such a setting
+ if ( !aInfos.empty() )
+ {
+ PropertyValue aSearchFor;
+ for (auto const& elem : m_aIndirectPropTranslator)
+ {
+ aSearchFor.Name = elem.second;
+ PropertyValueSet::const_iterator aInfoPos = aInfos.find(aSearchFor);
+ if (aInfos.end() != aInfoPos)
+ // the property is contained in the info sequence
+ // -> transfer it into an item
+ implTranslateProperty(_rDest, elem.first, aInfoPos->Value);
+ }
+ }
+
+ convertUrl(_rDest);
+ }
+
+ try
+ {
+ Reference<XStorable> xStore(getDataSourceOrModel(_rxSource),UNO_QUERY);
+ _rDest.Put(SfxBoolItem(DSID_READONLY, !xStore.is() || xStore->isReadonly() ));
+ }
+ catch(Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("dbaccess", "IsReadOnly throws");
+ }
+}
+
+void ODbDataSourceAdministrationHelper::translateProperties(const SfxItemSet& _rSource, const Reference< XPropertySet >& _rxDest)
+{
+ OSL_ENSURE(_rxDest.is(), "ODbDataSourceAdministrationHelper::translateProperties: invalid property set!");
+ if (!_rxDest.is())
+ return;
+
+ // the property set info
+ Reference< XPropertySetInfo > xInfo;
+ try { xInfo = _rxDest->getPropertySetInfo(); }
+ catch(Exception&) { }
+
+ static const OUStringLiteral sUrlProp(u"URL");
+ // transfer the direct properties
+ for (auto const& elem : m_aDirectPropTranslator)
+ {
+ const SfxPoolItem* pCurrentItem = _rSource.GetItem(static_cast<sal_uInt16>(elem.first));
+ if (pCurrentItem)
+ {
+ sal_Int16 nAttributes = PropertyAttribute::READONLY;
+ if (xInfo.is())
+ {
+ try { nAttributes = xInfo->getPropertyByName(elem.second).Attributes; }
+ catch(Exception&) { }
+ }
+ if ((nAttributes & PropertyAttribute::READONLY) == 0)
+ {
+ if ( sUrlProp == elem.second )
+ {
+ Any aValue(getConnectionURL());
+ // aValue <<= OUString();
+ lcl_putProperty(_rxDest, elem.second,aValue);
+ }
+ else
+ implTranslateProperty(_rxDest, elem.second, pCurrentItem);
+ }
+ }
+ }
+
+ // now for the indirect properties
+
+ Sequence< PropertyValue > aInfo;
+ // the original properties
+ try
+ {
+ _rxDest->getPropertyValue(PROPERTY_INFO) >>= aInfo;
+ }
+ catch(Exception&) { }
+
+ // overwrite and extend them
+ fillDatasourceInfo(_rSource, aInfo);
+ // and propagate the (newly composed) sequence to the set
+ lcl_putProperty(_rxDest,PROPERTY_INFO, Any(aInfo));
+}
+
+void ODbDataSourceAdministrationHelper::fillDatasourceInfo(const SfxItemSet& _rSource, Sequence< css::beans::PropertyValue >& _rInfo)
+{
+ // within the current "Info" sequence, replace the ones we can examine from the item set
+ // (we don't just fill a completely new sequence with our own items, but we preserve any properties unknown to
+ // us)
+
+ // first determine which of all the items are relevant for the data source (depends on the connection url)
+ const OUString eType = getDatasourceType(_rSource);
+ const ::connectivity::DriversConfig aDriverConfig(getORB());
+ const ::comphelper::NamedValueCollection& aProperties = aDriverConfig.getProperties(eType);
+
+ // collect the translated property values for the relevant items
+ PropertyValueSet aRelevantSettings;
+ MapInt2String::const_iterator aTranslation;
+ for (ItemID detailId = DSID_FIRST_ITEM_ID ; detailId <= DSID_LAST_ITEM_ID; ++detailId)
+ {
+ const SfxPoolItem* pCurrent = _rSource.GetItem(static_cast<sal_uInt16>(detailId));
+ aTranslation = m_aIndirectPropTranslator.find(detailId);
+ if ( pCurrent && (m_aIndirectPropTranslator.end() != aTranslation) &&
+ aProperties.has(aTranslation->second) )
+ {
+ if ( aTranslation->second == INFO_CHARSET )
+ {
+ OUString sCharSet;
+ implTranslateProperty(pCurrent) >>= sCharSet;
+ if ( !sCharSet.isEmpty() )
+ aRelevantSettings.insert(PropertyValue(aTranslation->second, 0, Any(sCharSet), PropertyState_DIRECT_VALUE));
+ }
+ else
+ aRelevantSettings.insert(PropertyValue(aTranslation->second, 0, implTranslateProperty(pCurrent), PropertyState_DIRECT_VALUE));
+ }
+ }
+
+ // settings to preserve
+ MapInt2String aPreservedSettings;
+
+ // now aRelevantSettings contains all the property values relevant for the current data source type,
+ // check the original sequence if it already contains any of these values (which have to be overwritten, then)
+ PropertyValue* pInfo = _rInfo.getArray();
+ PropertyValue aSearchFor;
+ sal_Int32 nObsoleteSetting = -1;
+ sal_Int32 nCount = _rInfo.getLength();
+ for (sal_Int32 i = 0; i < nCount; ++i, ++pInfo)
+ {
+ aSearchFor.Name = pInfo->Name;
+ PropertyValueSet::const_iterator aOverwrittenSetting = aRelevantSettings.find(aSearchFor);
+ if (aRelevantSettings.end() != aOverwrittenSetting)
+ { // the setting was present in the original sequence, and it is to be overwritten -> replace it
+ if ( pInfo->Value != aOverwrittenSetting->Value )
+ *pInfo = *aOverwrittenSetting;
+ aRelevantSettings.erase(aOverwrittenSetting);
+ }
+ else if( pInfo->Name == "JDBCDRV" )
+ { // this is a compatibility setting, remove it from the sequence (it's replaced by JavaDriverClass)
+ nObsoleteSetting = i;
+ }
+ else
+ aPreservedSettings[i] = pInfo->Name;
+ }
+ if (-1 != nObsoleteSetting)
+ ::comphelper::removeElementAt(_rInfo, nObsoleteSetting);
+
+ if ( !aPreservedSettings.empty() )
+ { // check if there are settings which
+ // * are known as indirect properties
+ // * but not relevant for the current data source type
+ // These settings have to be removed: If they're not relevant, we have no UI for changing them.
+
+ // for this, we need a string-controlled quick access to m_aIndirectPropTranslator
+ std::set<OUString> aIndirectProps;
+ std::transform(m_aIndirectPropTranslator.begin(),
+ m_aIndirectPropTranslator.end(),
+ std::inserter(aIndirectProps,aIndirectProps.begin()),
+ ::o3tl::select2nd< MapInt2String::value_type >());
+
+ // now check the to-be-preserved props
+ std::vector< sal_Int32 > aRemoveIndexes;
+ sal_Int32 nPositionCorrector = 0;
+ for (auto const& preservedSetting : aPreservedSettings)
+ {
+ if (aIndirectProps.end() != aIndirectProps.find(preservedSetting.second))
+ {
+ aRemoveIndexes.push_back(preservedSetting.first - nPositionCorrector);
+ ++nPositionCorrector;
+ }
+ }
+ // now finally remove all such props
+ for (auto const& removeIndex : aRemoveIndexes)
+ ::comphelper::removeElementAt(_rInfo, removeIndex);
+ }
+
+ Sequence< Any> aTypeSettings;
+ aTypeSettings = aProperties.getOrDefault("TypeInfoSettings",aTypeSettings);
+ // here we have a special entry for types from oracle
+ if ( aTypeSettings.hasElements() )
+ {
+ aRelevantSettings.insert(PropertyValue("TypeInfoSettings", 0, Any(aTypeSettings), PropertyState_DIRECT_VALUE));
+ }
+
+ // check which values are still left ('cause they were not present in the original sequence, but are to be set)
+ if ( aRelevantSettings.empty() )
+ return;
+
+ sal_Int32 nOldLength = _rInfo.getLength();
+ _rInfo.realloc(nOldLength + aRelevantSettings.size());
+ PropertyValue* pAppendValues = _rInfo.getArray() + nOldLength;
+ for (auto const& relevantSetting : aRelevantSettings)
+ {
+ if ( relevantSetting.Name == INFO_CHARSET )
+ {
+ OUString sCharSet;
+ relevantSetting.Value >>= sCharSet;
+ if ( !sCharSet.isEmpty() )
+ *pAppendValues = relevantSetting;
+ }
+ else
+ *pAppendValues = relevantSetting;
+ ++pAppendValues;
+ }
+}
+
+Any ODbDataSourceAdministrationHelper::implTranslateProperty(const SfxPoolItem* _pItem)
+{
+ // translate the SfxPoolItem
+ Any aValue;
+
+ const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>( _pItem );
+ const SfxBoolItem* pBoolItem = dynamic_cast<const SfxBoolItem*>( _pItem );
+ const OptionalBoolItem* pOptBoolItem = dynamic_cast<const OptionalBoolItem*>( _pItem );
+ const SfxInt32Item* pInt32Item = dynamic_cast< const SfxInt32Item* >( _pItem );
+ const OStringListItem* pStringListItem = dynamic_cast<const OStringListItem*>( _pItem );
+
+ if ( pStringItem )
+ {
+ aValue <<= pStringItem->GetValue();
+ }
+ else if ( pBoolItem )
+ {
+ aValue <<= pBoolItem->GetValue();
+ }
+ else if ( pOptBoolItem )
+ {
+ if ( !pOptBoolItem->HasValue() )
+ aValue.clear();
+ else
+ aValue <<= pOptBoolItem->GetValue();
+ }
+ else if ( pInt32Item )
+ {
+ aValue <<= pInt32Item->GetValue();
+ }
+ else if ( pStringListItem )
+ {
+ aValue <<= pStringListItem->getList();
+ }
+ else
+ {
+ OSL_FAIL("ODbDataSourceAdministrationHelper::implTranslateProperty: unsupported item type!");
+ return aValue;
+ }
+
+ return aValue;
+}
+
+void ODbDataSourceAdministrationHelper::implTranslateProperty(const Reference< XPropertySet >& _rxSet, const OUString& _rName, const SfxPoolItem* _pItem)
+{
+ Any aValue = implTranslateProperty(_pItem);
+ lcl_putProperty(_rxSet, _rName,aValue);
+}
+
+OString ODbDataSourceAdministrationHelper::translatePropertyId( sal_Int32 _nId )
+{
+ OUString aString;
+
+ MapInt2String::const_iterator aPos = m_aDirectPropTranslator.find( _nId );
+ if ( m_aDirectPropTranslator.end() != aPos )
+ {
+ aString = aPos->second;
+ }
+ else
+ {
+ MapInt2String::const_iterator indirectPos = m_aIndirectPropTranslator.find( _nId );
+ if ( m_aIndirectPropTranslator.end() != indirectPos )
+ aString = indirectPos->second;
+ }
+
+ OString aReturn( aString.getStr(), aString.getLength(), RTL_TEXTENCODING_ASCII_US );
+ return aReturn;
+}
+template<class T> static bool checkItemType(const SfxPoolItem* pItem){ return dynamic_cast<const T*>(pItem) != nullptr;}
+
+void ODbDataSourceAdministrationHelper::implTranslateProperty( SfxItemSet& _rSet, sal_Int32 _nId, const Any& _rValue )
+{
+ switch ( _rValue.getValueType().getTypeClass() )
+ {
+ case TypeClass_STRING:
+ if ( implCheckItemType( _rSet, _nId, checkItemType<SfxStringItem> ) )
+ {
+ OUString sValue;
+ _rValue >>= sValue;
+ _rSet.Put(SfxStringItem(_nId, sValue));
+ }
+ else {
+ SAL_WARN( "dbaccess", "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value ("
+ << translatePropertyId(_nId) << " should be no string)!");
+ }
+ break;
+
+ case TypeClass_BOOLEAN:
+ if ( implCheckItemType( _rSet, _nId, checkItemType<SfxBoolItem> ) )
+ {
+ bool bVal = false;
+ _rValue >>= bVal;
+ _rSet.Put(SfxBoolItem(_nId, bVal));
+ }
+ else if ( implCheckItemType( _rSet, _nId, checkItemType<OptionalBoolItem> ) )
+ {
+ OptionalBoolItem aItem( _nId );
+ if ( _rValue.hasValue() )
+ {
+ bool bValue = false;
+ _rValue >>= bValue;
+ aItem.SetValue( bValue );
+ }
+ else
+ aItem.ClearValue();
+ _rSet.Put( aItem );
+ }
+ else {
+ SAL_WARN( "dbaccess", "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value ("
+ << translatePropertyId(_nId)
+ << " should be no boolean)!");
+ }
+ break;
+
+ case TypeClass_LONG:
+ if ( implCheckItemType( _rSet, _nId, checkItemType<SfxInt32Item> ) )
+ {
+ sal_Int32 nValue = 0;
+ _rValue >>= nValue;
+ _rSet.Put( SfxInt32Item( _nId, nValue ) );
+ }
+ else {
+ SAL_WARN( "dbaccess", "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value ("
+ << translatePropertyId(_nId)
+ << " should be no int)!");
+ }
+ break;
+
+ case TypeClass_SEQUENCE:
+ if ( implCheckItemType( _rSet, _nId, checkItemType<OStringListItem> ) )
+ {
+ // determine the element type
+ TypeDescription aTD(_rValue.getValueType());
+ typelib_IndirectTypeDescription* pSequenceTD =
+ reinterpret_cast< typelib_IndirectTypeDescription* >(aTD.get());
+ OSL_ENSURE(pSequenceTD && pSequenceTD->pType, "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid sequence type!");
+
+ Type aElementType(pSequenceTD->pType);
+ switch (aElementType.getTypeClass())
+ {
+ case TypeClass_STRING:
+ {
+ Sequence< OUString > aStringList;
+ _rValue >>= aStringList;
+ _rSet.Put(OStringListItem(_nId, aStringList));
+ }
+ break;
+ default:
+ OSL_FAIL("ODbDataSourceAdministrationHelper::implTranslateProperty: unsupported property value type!");
+ }
+ }
+ else {
+ SAL_WARN( "dbaccess", "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value ("
+ << translatePropertyId(_nId)
+ << " should be no string sequence)!");
+ }
+ break;
+
+ case TypeClass_VOID:
+ _rSet.ClearItem(_nId);
+ break;
+
+ default:
+ OSL_FAIL("ODbDataSourceAdministrationHelper::implTranslateProperty: unsupported property value type!");
+ }
+}
+
+OUString ODbDataSourceAdministrationHelper::getDocumentUrl(SfxItemSet const & _rDest)
+{
+ const SfxStringItem* pUrlItem = _rDest.GetItem<SfxStringItem>(DSID_DOCUMENT_URL);
+ OSL_ENSURE(pUrlItem,"Document URL is NULL. -> GPF!");
+ return pUrlItem->GetValue();
+}
+
+void ODbDataSourceAdministrationHelper::convertUrl(SfxItemSet& _rDest)
+{
+ OUString eType = getDatasourceType(_rDest);
+
+ const SfxStringItem* pUrlItem = _rDest.GetItem<SfxStringItem>(DSID_CONNECTURL);
+ const DbuTypeCollectionItem* pTypeCollection = _rDest.GetItem<DbuTypeCollectionItem>(DSID_TYPECOLLECTION);
+
+ OSL_ENSURE(pUrlItem,"Connection URL is NULL. -> GPF!");
+ OSL_ENSURE(pTypeCollection, "ODbAdminDialog::getDatasourceType: invalid items in the source set!");
+ ::dbaccess::ODsnTypeCollection* pCollection = pTypeCollection->getCollection();
+ OSL_ENSURE(pCollection, "ODbAdminDialog::getDatasourceType: invalid type collection!");
+
+ sal_uInt16 nPortNumberId = 0;
+ sal_Int32 nPortNumber = -1;
+ OUString sNewHostName;
+ OUString sUrlPart;
+
+ pCollection->extractHostNamePort(pUrlItem->GetValue(),sUrlPart,sNewHostName,nPortNumber);
+ const ::dbaccess::DATASOURCE_TYPE eTy = pCollection->determineType(eType);
+
+ switch( eTy )
+ {
+ case ::dbaccess::DST_MYSQL_NATIVE:
+ case ::dbaccess::DST_MYSQL_JDBC:
+ nPortNumberId = DSID_MYSQL_PORTNUMBER;
+ break;
+ case ::dbaccess::DST_ORACLE_JDBC:
+ nPortNumberId = DSID_ORACLE_PORTNUMBER;
+ break;
+ case ::dbaccess::DST_LDAP:
+ nPortNumberId = DSID_CONN_LDAP_PORTNUMBER;
+ break;
+ default:
+ break;
+ }
+
+ if ( !sUrlPart.isEmpty() )
+ {
+ if ( eTy == ::dbaccess::DST_MYSQL_NATIVE )
+ {
+ _rDest.Put( SfxStringItem( DSID_DATABASENAME, sUrlPart ) );
+ }
+ else
+ {
+ OUString sNewUrl = pCollection->getPrefix(eType) + sUrlPart;
+ _rDest.Put( SfxStringItem( DSID_CONNECTURL, sNewUrl ) );
+ }
+ }
+
+ if ( !sNewHostName.isEmpty() )
+ _rDest.Put(SfxStringItem(DSID_CONN_HOSTNAME, sNewHostName));
+
+ if ( nPortNumber != -1 && nPortNumberId != 0 )
+ _rDest.Put(SfxInt32Item(nPortNumberId, nPortNumber));
+
+}
+
+bool ODbDataSourceAdministrationHelper::saveChanges(const SfxItemSet& _rSource)
+{
+ // put the remembered settings into the property set
+ Reference<XPropertySet> xDatasource = getCurrentDataSource();
+ if ( !xDatasource.is() )
+ return false;
+
+ translateProperties(_rSource,xDatasource );
+
+ return true;
+}
+
+void ODbDataSourceAdministrationHelper::setDataSourceOrName( const Any& _rDataSourceOrName )
+{
+ OSL_ENSURE( !m_aDataSourceOrName.hasValue(), "ODbDataSourceAdministrationHelper::setDataSourceOrName: already have one!" );
+ // hmm. We could reset m_xDatasource/m_xModel, probably, and continue working
+ m_aDataSourceOrName = _rDataSourceOrName;
+}
+
+// DbuTypeCollectionItem
+DbuTypeCollectionItem::DbuTypeCollectionItem(sal_Int16 _nWhich, ::dbaccess::ODsnTypeCollection* _pCollection)
+ :SfxPoolItem(_nWhich)
+ ,m_pCollection(_pCollection)
+{
+}
+
+DbuTypeCollectionItem::DbuTypeCollectionItem(const DbuTypeCollectionItem& _rSource)
+ :SfxPoolItem(_rSource)
+ ,m_pCollection(_rSource.getCollection())
+{
+}
+
+bool DbuTypeCollectionItem::operator==(const SfxPoolItem& _rItem) const
+{
+ return SfxPoolItem::operator==(_rItem) &&
+ static_cast<const DbuTypeCollectionItem&>( _rItem ).getCollection() == getCollection();
+}
+
+DbuTypeCollectionItem* DbuTypeCollectionItem::Clone(SfxItemPool* /*_pPool*/) const
+{
+ return new DbuTypeCollectionItem(*this);
+}
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/DbAdminImpl.hxx b/dbaccess/source/ui/dlg/DbAdminImpl.hxx
new file mode 100644
index 000000000..22a61ecee
--- /dev/null
+++ b/dbaccess/source/ui/dlg/DbAdminImpl.hxx
@@ -0,0 +1,167 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <map>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sdb/XDatabaseContext.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XDriver.hpp>
+#include <dsntypes.hxx>
+#include <svl/itemset.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <svl/poolitem.hxx>
+#include <vcl/weld.hxx>
+
+namespace dbaui
+{
+ namespace DataSourceInfoConverter
+ {
+ void convert(const css::uno::Reference< css::uno::XComponentContext> & xContext,
+ const ::dbaccess::ODsnTypeCollection* _pCollection,
+ const OUString& _sOldURLPrefix,
+ const OUString& _sNewURLPrefix,
+ const css::uno::Reference< css::beans::XPropertySet >& _xDatasource);
+ };
+ class IItemSetHelper;
+ // ODbDataSourceAdministrationHelper
+ class ODbDataSourceAdministrationHelper final
+ {
+ public:
+ typedef std::map<sal_Int32, OUString> MapInt2String;
+
+ private:
+ css::uno::Reference< css::uno::XComponentContext >
+ m_xContext; /// service factory
+ css::uno::Reference< css::sdb::XDatabaseContext >
+ m_xDatabaseContext; /// database context we're working in
+ css::uno::Reference< css::beans::XPropertySet > m_xDatasource;
+ css::uno::Reference< css::frame::XModel > m_xModel;
+
+ css::uno::Any m_aDataSourceOrName;
+
+ MapInt2String m_aDirectPropTranslator; /// translating property id's into names (direct properties of a data source)
+ MapInt2String m_aIndirectPropTranslator; /// translating property id's into names (indirect properties of a data source)
+ weld::Window* m_pParent;
+ IItemSetHelper* m_pItemSetHelper;
+ public:
+
+ ODbDataSourceAdministrationHelper(const css::uno::Reference< css::uno::XComponentContext >& _xORB,
+ weld::Window* pParent, weld::Window* pTopParent,
+ IItemSetHelper* _pItemSetHelper);
+
+ /** translate the current dialog SfxItems into driver relevant PropertyValues
+ @see successfullyConnected
+ */
+ bool getCurrentSettings(css::uno::Sequence< css::beans::PropertyValue >& _rDriverParams);
+
+ /** to be called if the settings got from getCurrentSettings have been used for successfully connecting
+ @see getCurrentSettings
+ */
+ void successfullyConnected();
+
+ /// clear the password in the current data source's item set
+ void clearPassword();
+
+ const css::uno::Reference< css::uno::XComponentContext >& getORB() const { return m_xContext; }
+
+ /** creates a new connection. The caller is responsible to dispose it !!!!
+ */
+ std::pair< css::uno::Reference< css::sdbc::XConnection >,bool> createConnection();
+
+ /** return the corresponding driver for the selected URL
+ */
+ css::uno::Reference< css::sdbc::XDriver > getDriver();
+ css::uno::Reference< css::sdbc::XDriver > getDriver(const OUString& _sURL);
+
+ /** returns the data source the dialog is currently working with
+ */
+ css::uno::Reference< css::beans::XPropertySet > const & getCurrentDataSource();
+ // returns the Url of a database document
+ static OUString getDocumentUrl(SfxItemSet const & _rDest);
+
+ void setDataSourceOrName( const css::uno::Any& _rDataSourceOrName );
+
+ /** extracts the connection type from the given set<p/>
+ The connection type is determined by the value of the DSN item, analyzed by the TypeCollection item.
+ */
+ static OUString getDatasourceType( const SfxItemSet& _rSet );
+
+ /** returns the connection URL
+ @return
+ The connection URL
+ */
+ OUString getConnectionURL() const;
+
+ /// fill the necessary information from the url line
+ static void convertUrl(SfxItemSet& _rDest);
+
+ const MapInt2String& getIndirectProperties() const { return m_aIndirectPropTranslator; }
+
+ /** translates properties of a UNO data source into SfxItems
+ @param _rxSource
+ The data source
+ @param _rDest
+ The item set to fill.
+ */
+ void translateProperties(
+ const css::uno::Reference< css::beans::XPropertySet >& _rxSource,
+ SfxItemSet& _rDest);
+
+ /** translate SfxItems into properties of a UNO data source
+ @param _rSource
+ The item set to read from.
+ @param _rxDest
+ The data source to fill.
+ */
+ void translateProperties(
+ const SfxItemSet& _rSource,
+ const css::uno::Reference< css::beans::XPropertySet >& _rxDest);
+
+ bool saveChanges(const SfxItemSet& _rSource);
+ private:
+ /** fill a data source info array with the settings from a given item set
+ */
+ void fillDatasourceInfo(const SfxItemSet& _rSource, css::uno::Sequence< css::beans::PropertyValue >& _rInfo);
+
+ /// translate the given value into an SfxPoolItem, put this into the given set under the given id
+ void implTranslateProperty(SfxItemSet& _rSet, sal_Int32 _nId, const css::uno::Any& _rValue);
+
+ /// translate the given SfxPoolItem into an <type scope="com.sun.star.Any">uno</type>
+ static css::uno::Any implTranslateProperty(const SfxPoolItem* _pItem);
+
+ /// translate the given SfxPoolItem into an <type scope="com.sun.star.Any">uno</type>, set it (under the given name) on the given property set
+ static void implTranslateProperty(const css::uno::Reference< css::beans::XPropertySet >& _rxSet, const OUString& _rName, const SfxPoolItem* _pItem);
+
+ /** check if the data source described by the given set needs authentication<p/>
+ The return value depends on the data source type only.
+ */
+ static bool hasAuthentication(const SfxItemSet& _rSet);
+
+ OString translatePropertyId( sal_Int32 _nId );
+ };
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/DriverSettings.hxx b/dbaccess/source/ui/dlg/DriverSettings.hxx
new file mode 100644
index 000000000..72ce3d459
--- /dev/null
+++ b/dbaccess/source/ui/dlg/DriverSettings.hxx
@@ -0,0 +1,78 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+class SfxTabPage;
+namespace dbaui
+{
+ /// a collection class for all details a driver needs
+ class ODriversSettings
+ {
+ public:
+
+ /** Creates the detail page for ado
+ */
+ static std::unique_ptr<SfxTabPage> CreateDbase( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /** Creates the detail page for ado
+ */
+ static std::unique_ptr<SfxTabPage> CreateAdo( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /** Creates the detail page for ODBC
+ */
+ static std::unique_ptr<SfxTabPage> CreateODBC( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /** Creates the detail page for user
+ */
+ static std::unique_ptr<SfxTabPage> CreateUser( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /** Creates the detail page for MySQLODBC
+ */
+ static std::unique_ptr<SfxTabPage> CreateMySQLODBC( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /** Creates the detail page for MySQLJDBC
+ */
+ static std::unique_ptr<SfxTabPage> CreateMySQLJDBC( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /** Creates the detail page for MySQLNATIVE
+ */
+ static std::unique_ptr<SfxTabPage> CreateMySQLNATIVE( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /** Creates the detail page for Oracle JDBC
+ */
+ static std::unique_ptr<SfxTabPage> CreateOracleJDBC( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /** Creates the detail page for LDAP
+ */
+ static std::unique_ptr<SfxTabPage> CreateLDAP( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /// Creates the detail page for Text
+ static std::unique_ptr<SfxTabPage> CreateText( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /// creates the GeneratedValues page
+ static std::unique_ptr<SfxTabPage> CreateGeneratedValuesPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+
+ /// creates the "Special Settings" page of the "Advanced Settings" dialog
+ static std::unique_ptr<SfxTabPage> CreateSpecialSettingsPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet );
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/QueryPropertiesDialog.cxx b/dbaccess/source/ui/dlg/QueryPropertiesDialog.cxx
new file mode 100644
index 000000000..df0d38e4b
--- /dev/null
+++ b/dbaccess/source/ui/dlg/QueryPropertiesDialog.cxx
@@ -0,0 +1,60 @@
+/* -*- 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/.
+ */
+
+#include <QueryPropertiesDialog.hxx>
+#include <strings.hrc>
+#include <core_resource.hxx>
+
+namespace dbaui
+{
+
+QueryPropertiesDialog::QueryPropertiesDialog(
+ weld::Window* pParent, const bool bDistinct, const sal_Int64 nLimit )
+ : GenericDialogController(pParent, "dbaccess/ui/querypropertiesdialog.ui", "QueryPropertiesDialog")
+ , m_xRB_Distinct(m_xBuilder->weld_radio_button("distinct"))
+ , m_xRB_NonDistinct(m_xBuilder->weld_radio_button("nondistinct"))
+ , m_xLB_Limit(m_xBuilder->weld_combo_box("limitbox"))
+{
+ m_xRB_Distinct->set_active(bDistinct);
+ m_xRB_NonDistinct->set_active(!bDistinct);
+
+ m_xLB_Limit->append(OUString::number(-1), DBA_RES(STR_QUERY_LIMIT_ALL)); // ALL_INT and ALL_STRING
+ /// Default values
+ sal_Int64 const aDefLimitAry[] =
+ {
+ 5,
+ 10,
+ 20,
+ 50
+ };
+ for (auto a : aDefLimitAry)
+ m_xLB_Limit->append(OUString::number(a), OUString::number(a));
+ OUString sInitial = OUString::number(nLimit);
+ auto nPos = m_xLB_Limit->find_id(sInitial);
+ if (nPos != -1)
+ m_xLB_Limit->set_active(nPos);
+ else
+ m_xLB_Limit->set_entry_text(OUString::number(nLimit));
+}
+
+sal_Int64 QueryPropertiesDialog::getLimit() const
+{
+ OUString sSelectedId = m_xLB_Limit->get_active_id();
+ if (!sSelectedId.isEmpty())
+ return sSelectedId.toInt64();
+ return m_xLB_Limit->get_active_text().toInt64();
+}
+
+QueryPropertiesDialog::~QueryPropertiesDialog()
+{
+}
+
+} ///dbaui namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/RelationDlg.cxx b/dbaccess/source/ui/dlg/RelationDlg.cxx
new file mode 100644
index 000000000..cc449d9b7
--- /dev/null
+++ b/dbaccess/source/ui/dlg/RelationDlg.cxx
@@ -0,0 +1,215 @@
+/* -*- 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 <RelationDlg.hxx>
+
+#include <com/sun/star/sdbc/KeyRule.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+
+#include <tools/diagnose_ex.h>
+#include <JoinDesignView.hxx>
+#include <JoinController.hxx>
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbtools.hxx>
+#include <RTableConnectionData.hxx>
+#include <RelationControl.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::dbaui;
+using namespace ::dbtools;
+
+ORelationDialog::ORelationDialog( OJoinTableView* pParent,
+ const TTableConnectionData::value_type& pConnectionData,
+ bool bAllowTableSelect )
+ : GenericDialogController(pParent->GetFrameWeld(),
+ "dbaccess/ui/relationdialog.ui", "RelationDialog")
+ , m_pParent(pParent)
+ , m_pOrigConnData(pConnectionData)
+ , m_bTriedOneUpdate(false)
+ , m_xRB_NoCascUpd(m_xBuilder->weld_radio_button("addaction"))
+ , m_xRB_CascUpd(m_xBuilder->weld_radio_button("addcascade"))
+ , m_xRB_CascUpdNull(m_xBuilder->weld_radio_button("addnull"))
+ , m_xRB_CascUpdDefault(m_xBuilder->weld_radio_button("adddefault"))
+ , m_xRB_NoCascDel(m_xBuilder->weld_radio_button("delaction"))
+ , m_xRB_CascDel(m_xBuilder->weld_radio_button("delcascade"))
+ , m_xRB_CascDelNull(m_xBuilder->weld_radio_button("delnull"))
+ , m_xRB_CascDelDefault(m_xBuilder->weld_radio_button("deldefault"))
+ , m_xPB_OK(m_xBuilder->weld_button("ok"))
+{
+ // Copy connection
+ m_pConnData = pConnectionData->NewInstance();
+ m_pConnData->CopyFrom( *pConnectionData );
+
+ Init(m_pConnData);
+ m_xTableControl.reset(new OTableListBoxControl(m_xBuilder.get(), &pParent->GetTabWinMap(), this));
+
+ m_xPB_OK->connect_clicked(LINK(this, ORelationDialog, OKClickHdl));
+
+ m_xTableControl->Init( m_pConnData );
+ if ( bAllowTableSelect )
+ m_xTableControl->fillListBoxes();
+ else
+ m_xTableControl->fillAndDisable(pConnectionData);
+
+ m_xTableControl->lateInit();
+
+ m_xTableControl->NotifyCellChange();
+}
+
+ORelationDialog::~ORelationDialog()
+{
+}
+
+void ORelationDialog::Init(const TTableConnectionData::value_type& _pConnectionData)
+{
+ ORelationTableConnectionData* pConnData = static_cast<ORelationTableConnectionData*>(_pConnectionData.get());
+ // Update Rules
+ switch (pConnData->GetUpdateRules())
+ {
+ case KeyRule::NO_ACTION:
+ case KeyRule::RESTRICT:
+ m_xRB_NoCascUpd->set_active(true);
+ break;
+
+ case KeyRule::CASCADE:
+ m_xRB_CascUpd->set_active(true);
+ break;
+
+ case KeyRule::SET_NULL:
+ m_xRB_CascUpdNull->set_active(true);
+ break;
+ case KeyRule::SET_DEFAULT:
+ m_xRB_CascUpdDefault->set_active(true);
+ break;
+ }
+
+ // Delete Rules
+ switch (pConnData->GetDeleteRules())
+ {
+ case KeyRule::NO_ACTION:
+ case KeyRule::RESTRICT:
+ m_xRB_NoCascDel->set_active(true);
+ break;
+
+ case KeyRule::CASCADE:
+ m_xRB_CascDel->set_active(true);
+ break;
+
+ case KeyRule::SET_NULL:
+ m_xRB_CascDelNull->set_active(true);
+ break;
+ case KeyRule::SET_DEFAULT:
+ m_xRB_CascDelDefault->set_active(true);
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(ORelationDialog, OKClickHdl, weld::Button&, void)
+{
+ // Read out RadioButtons
+ sal_uInt16 nAttrib = 0;
+
+ // Delete Rules
+ if( m_xRB_NoCascDel->get_active() )
+ nAttrib |= KeyRule::NO_ACTION;
+ if( m_xRB_CascDel->get_active() )
+ nAttrib |= KeyRule::CASCADE;
+ if( m_xRB_CascDelNull->get_active() )
+ nAttrib |= KeyRule::SET_NULL;
+ if( m_xRB_CascDelDefault->get_active() )
+ nAttrib |= KeyRule::SET_DEFAULT;
+
+ ORelationTableConnectionData* pConnData = static_cast<ORelationTableConnectionData*>(m_pConnData.get());
+ pConnData->SetDeleteRules( nAttrib );
+
+ // Update Rules
+ nAttrib = 0;
+ if( m_xRB_NoCascUpd->get_active() )
+ nAttrib |= KeyRule::NO_ACTION;
+ if( m_xRB_CascUpd->get_active() )
+ nAttrib |= KeyRule::CASCADE;
+ if( m_xRB_CascUpdNull->get_active() )
+ nAttrib |= KeyRule::SET_NULL;
+ if( m_xRB_CascUpdDefault->get_active() )
+ nAttrib |= KeyRule::SET_DEFAULT;
+ pConnData->SetUpdateRules( nAttrib );
+
+ m_xTableControl->SaveModified();
+
+ //// if the ComboBoxes for the table selection are enabled (constructor with bAllowTableSelect==sal_True),
+ //// then I must also put the table names into the connection
+ //m_pConnData->SetSourceWinName(m_xTableControl->getSourceWinName());
+ //m_pConnData->SetDestWinName(m_xTableControl->getDestWinName());
+
+ // try to create the relation
+ try
+ {
+ ORelationTableConnectionData* pOrigConnData = static_cast<ORelationTableConnectionData*>(m_pOrigConnData.get());
+ if ( *pConnData == *pOrigConnData || pConnData->Update())
+ {
+ m_pOrigConnData->CopyFrom( *m_pConnData );
+ m_xDialog->response(RET_OK);
+ return;
+ }
+ }
+ catch( const SQLException& )
+ {
+ ::dbtools::showError(SQLExceptionInfo(::cppu::getCaughtException()),
+ m_xDialog->GetXWindow(),
+ m_pParent->getDesignView()->getController().getORB());
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ m_bTriedOneUpdate = true;
+ // this means that the original connection may be lost (if m_pConnData was not a newly created but an
+ // existent conn to be modified), which we reflect by returning RET_NO (see ::Execute)
+
+ // try again
+ Init(m_pConnData);
+ m_xTableControl->Init( m_pConnData );
+ m_xTableControl->lateInit();
+}
+
+short ORelationDialog::run()
+{
+ short nResult = GenericDialogController::run();
+ if ((nResult != RET_OK) && m_bTriedOneUpdate)
+ return RET_NO;
+
+ return nResult;
+}
+
+void ORelationDialog::setValid(bool _bValid)
+{
+ m_xPB_OK->set_sensitive(_bValid);
+}
+
+void ORelationDialog::notifyConnectionChange()
+{
+ Init(m_pConnData);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/TablesSingleDlg.cxx b/dbaccess/source/ui/dlg/TablesSingleDlg.cxx
new file mode 100644
index 000000000..bcf039c5e
--- /dev/null
+++ b/dbaccess/source/ui/dlg/TablesSingleDlg.cxx
@@ -0,0 +1,105 @@
+/* -*- 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 <TablesSingleDlg.hxx>
+#include "DbAdminImpl.hxx"
+#include "tablespage.hxx"
+
+namespace dbaui
+{
+using namespace com::sun::star::uno;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+
+ // OTableSubscriptionDialog
+OTableSubscriptionDialog::OTableSubscriptionDialog(weld::Window* pParent
+ ,const SfxItemSet* _pItems
+ ,const Reference< XComponentContext >& _rxORB
+ ,const css::uno::Any& _aDataSourceName)
+ : SfxSingleTabDialogController(pParent, _pItems,
+ "dbaccess/ui/tablesfilterdialog.ui", "TablesFilterDialog")
+ , m_pImpl(new ODbDataSourceAdministrationHelper(_rxORB, m_xDialog.get(), pParent, this))
+ , m_bStopExecution(false)
+{
+ m_pImpl->setDataSourceOrName(_aDataSourceName);
+ Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
+ m_pOutSet.reset(new SfxItemSet( *_pItems ));
+
+ m_pImpl->translateProperties(xDatasource, *m_pOutSet);
+ SetInputSet(m_pOutSet.get());
+
+ auto xTabPage = std::make_unique<OTableSubscriptionPage>(get_content_area(), this, *m_pOutSet);
+ xTabPage->SetServiceFactory(_rxORB);
+ SetTabPage(std::move(xTabPage));
+}
+
+OTableSubscriptionDialog::~OTableSubscriptionDialog()
+{
+}
+
+short OTableSubscriptionDialog::run()
+{
+ short nRet = RET_CANCEL;
+ if ( !m_bStopExecution )
+ {
+ nRet = SfxSingleTabDialogController::run();
+ if ( nRet == RET_OK )
+ {
+ m_pOutSet->Put(*GetOutputItemSet());
+ m_pImpl->saveChanges(*m_pOutSet);
+ }
+ }
+ return nRet;
+}
+
+bool OTableSubscriptionDialog::getCurrentSettings(Sequence< PropertyValue >& _rDriverParams)
+{
+ return m_pImpl->getCurrentSettings(_rDriverParams);
+}
+
+void OTableSubscriptionDialog::successfullyConnected()
+{
+ m_pImpl->successfullyConnected();
+}
+
+void OTableSubscriptionDialog::clearPassword()
+{
+ m_pImpl->clearPassword();
+}
+
+Reference< XPropertySet > const & OTableSubscriptionDialog::getCurrentDataSource()
+{
+ return m_pImpl->getCurrentDataSource();
+}
+
+const SfxItemSet* OTableSubscriptionDialog::getOutputSet() const
+{
+ return m_pOutSet.get();
+}
+
+SfxItemSet* OTableSubscriptionDialog::getWriteOutputSet()
+{
+ return m_pOutSet.get();
+}
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/TextConnectionHelper.cxx b/dbaccess/source/ui/dlg/TextConnectionHelper.cxx
new file mode 100644
index 000000000..15fa887f7
--- /dev/null
+++ b/dbaccess/source/ui/dlg/TextConnectionHelper.cxx
@@ -0,0 +1,392 @@
+/* -*- 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 <core_resource.hxx>
+#include "TextConnectionHelper.hxx"
+#include <strings.hrc>
+#include <strings.hxx>
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <dsitems.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/mnemonic.hxx>
+#include <o3tl/string_view.hxx>
+
+namespace
+{
+
+OUString lcl_getListEntry(const OUString& rStr, sal_Int32& rIdx)
+{
+ const OUString sTkn {rStr.getToken( 0, '\t', rIdx )};
+ if (rIdx>=0)
+ {
+ rIdx = rStr.indexOf('\t', rIdx);
+ if (rIdx>=0 && ++rIdx>=rStr.getLength())
+ rIdx = -1;
+ }
+ return sTkn;
+}
+
+}
+
+namespace dbaui
+{
+
+ OTextConnectionHelper::OTextConnectionHelper(weld::Widget* pParent, const short _nAvailableSections)
+ : m_aFieldSeparatorList (DBA_RES(STR_AUTOFIELDSEPARATORLIST))
+ , m_aTextSeparatorList (STR_AUTOTEXTSEPARATORLIST)
+ , m_aTextNone (DBA_RES(STR_AUTOTEXT_FIELD_SEP_NONE))
+ , m_nAvailableSections( _nAvailableSections )
+ , m_xBuilder(Application::CreateBuilder(pParent, "dbaccess/ui/textpage.ui"))
+ , m_xContainer(m_xBuilder->weld_widget("TextPage"))
+ , m_xExtensionHeader(m_xBuilder->weld_widget("extensionframe"))
+ , m_xAccessTextFiles(m_xBuilder->weld_radio_button("textfile"))
+ , m_xAccessCSVFiles(m_xBuilder->weld_radio_button("csvfile"))
+ , m_xAccessOtherFiles(m_xBuilder->weld_radio_button("custom"))
+ , m_xOwnExtension(m_xBuilder->weld_entry("extension"))
+ , m_xExtensionExample(m_xBuilder->weld_label("example"))
+ , m_xFormatHeader(m_xBuilder->weld_widget("formatframe"))
+ , m_xFieldSeparatorLabel(m_xBuilder->weld_label("fieldlabel"))
+ , m_xFieldSeparator(m_xBuilder->weld_combo_box("fieldseparator"))
+ , m_xTextSeparatorLabel(m_xBuilder->weld_label("textlabel"))
+ , m_xTextSeparator(m_xBuilder->weld_combo_box("textseparator"))
+ , m_xDecimalSeparatorLabel(m_xBuilder->weld_label("decimallabel"))
+ , m_xDecimalSeparator(m_xBuilder->weld_combo_box("decimalseparator"))
+ , m_xThousandsSeparatorLabel(m_xBuilder->weld_label("thousandslabel"))
+ , m_xThousandsSeparator(m_xBuilder->weld_combo_box("thousandsseparator"))
+ , m_xRowHeader(m_xBuilder->weld_check_button("containsheaders"))
+ , m_xCharSetHeader(m_xBuilder->weld_widget("charsetframe"))
+ , m_xCharSetLabel(m_xBuilder->weld_label("charsetlabel"))
+ , m_xCharSet(new CharSetListBox(m_xBuilder->weld_combo_box("charset")))
+ {
+ for(sal_Int32 nIdx {0}; nIdx>=0;)
+ m_xFieldSeparator->append_text( lcl_getListEntry(m_aFieldSeparatorList, nIdx) );
+
+ for(sal_Int32 nIdx {0}; nIdx>=0;)
+ m_xTextSeparator->append_text( lcl_getListEntry(m_aTextSeparatorList, nIdx) );
+ m_xTextSeparator->append_text(m_aTextNone);
+
+ m_xOwnExtension->connect_changed(LINK(this, OTextConnectionHelper, OnEditModified));
+ m_xAccessTextFiles->connect_toggled(LINK(this, OTextConnectionHelper, OnSetExtensionHdl));
+ m_xAccessCSVFiles->connect_toggled(LINK(this, OTextConnectionHelper, OnSetExtensionHdl));
+ m_xAccessOtherFiles->connect_toggled(LINK(this, OTextConnectionHelper, OnSetExtensionHdl));
+ m_xAccessCSVFiles->set_active(true);
+
+ struct SectionDescriptor
+ {
+ short nFlag;
+ weld::Widget* pFrame;
+ } aSections[] = {
+ { TC_EXTENSION, m_xExtensionHeader.get() },
+ { TC_SEPARATORS, m_xFormatHeader.get() },
+ { TC_HEADER, m_xRowHeader.get() },
+ { TC_CHARSET, m_xCharSetHeader.get() },
+ { 0, nullptr }
+ };
+
+ for ( size_t section=0; section < SAL_N_ELEMENTS( aSections ) - 1; ++section )
+ {
+ if ( ( m_nAvailableSections & aSections[section].nFlag ) != 0 )
+ {
+ // the section is visible, no need to do anything here
+ continue;
+ }
+
+ // hide all elements from this section
+ aSections[section].pFrame->hide();
+ }
+
+ m_xContainer->show();
+ }
+
+ IMPL_LINK_NOARG(OTextConnectionHelper, OnEditModified, weld::Entry&, void)
+ {
+ m_aGetExtensionHandler.Call(this);
+ }
+
+ IMPL_LINK_NOARG(OTextConnectionHelper, OnSetExtensionHdl, weld::Toggleable&, void)
+ {
+ bool bDoEnable = m_xAccessOtherFiles->get_active();
+ m_xOwnExtension->set_sensitive(bDoEnable);
+ m_xExtensionExample->set_sensitive(bDoEnable);
+ m_aGetExtensionHandler.Call(this);
+ }
+
+ void OTextConnectionHelper::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xFieldSeparator.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xTextSeparator.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xDecimalSeparator.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xThousandsSeparator.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xRowHeader.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xCharSet->get_widget()));
+ }
+
+ void OTextConnectionHelper::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFieldSeparatorLabel.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xTextSeparatorLabel.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xDecimalSeparatorLabel.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xThousandsSeparatorLabel.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Widget>(m_xCharSetHeader.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xCharSetLabel.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::ComboBox>(m_xCharSet->get_widget()));
+ }
+
+ void OTextConnectionHelper::implInitControls(const SfxItemSet& _rSet, bool _bValid)
+ {
+ if ( !_bValid )
+ return;
+
+ const SfxStringItem* pDelItem = _rSet.GetItem<SfxStringItem>(DSID_FIELDDELIMITER);
+ const SfxStringItem* pStrItem = _rSet.GetItem<SfxStringItem>(DSID_TEXTDELIMITER);
+ const SfxStringItem* pDecdelItem = _rSet.GetItem<SfxStringItem>(DSID_DECIMALDELIMITER);
+ const SfxStringItem* pThodelItem = _rSet.GetItem<SfxStringItem>(DSID_THOUSANDSDELIMITER);
+ const SfxStringItem* pExtensionItem = _rSet.GetItem<SfxStringItem>(DSID_TEXTFILEEXTENSION);
+ const SfxStringItem* pCharsetItem = _rSet.GetItem<SfxStringItem>(DSID_CHARSET);
+
+ if ( ( m_nAvailableSections & TC_EXTENSION ) != 0 )
+ {
+ m_aOldExtension = pExtensionItem->GetValue();
+ SetExtension( m_aOldExtension );
+ }
+
+ if ( ( m_nAvailableSections & TC_HEADER ) != 0 )
+ {
+ const SfxBoolItem* pHdrItem = _rSet.GetItem<SfxBoolItem>(DSID_TEXTFILEHEADER);
+ m_xRowHeader->set_active(pHdrItem->GetValue());
+ }
+
+ if ( ( m_nAvailableSections & TC_SEPARATORS ) != 0 )
+ {
+ SetSeparator(*m_xFieldSeparator, m_aFieldSeparatorList, pDelItem->GetValue());
+ SetSeparator(*m_xTextSeparator, m_aTextSeparatorList, pStrItem->GetValue());
+ m_xDecimalSeparator->set_entry_text( pDecdelItem->GetValue() );
+ m_xThousandsSeparator->set_entry_text( pThodelItem->GetValue() );
+ }
+
+ if ( ( m_nAvailableSections & TC_CHARSET ) != 0 )
+ {
+ m_xCharSet->SelectEntryByIanaName( pCharsetItem->GetValue() );
+ }
+ }
+
+ bool OTextConnectionHelper::prepareLeave()
+ {
+ OUString sExtension = GetExtension();
+ OUString aErrorText;
+ weld::Widget* pErrorWin = nullptr;
+ OUString aDelText(m_xFieldSeparator->get_active_text());
+ if(aDelText.isEmpty())
+ { // No FieldSeparator
+ aErrorText = DBA_RES(STR_AUTODELIMITER_MISSING);
+ aErrorText = aErrorText.replaceFirst("#1",m_xFieldSeparatorLabel->get_label());
+ pErrorWin = m_xFieldSeparator.get();
+ }
+ else if (m_xDecimalSeparator->get_active_text().isEmpty())
+ { // No DecimalSeparator
+ aErrorText = DBA_RES(STR_AUTODELIMITER_MISSING);
+ aErrorText = aErrorText.replaceFirst("#1",m_xDecimalSeparatorLabel->get_label());
+ pErrorWin = m_xDecimalSeparator.get();
+ }
+ else if (m_xTextSeparator->get_active_text() == m_xFieldSeparator->get_active_text())
+ { // Field and TextSeparator must not be the same
+ aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
+ aErrorText = aErrorText.replaceFirst("#1",m_xTextSeparatorLabel->get_label());
+ aErrorText = aErrorText.replaceFirst("#2",m_xFieldSeparatorLabel->get_label());
+ pErrorWin = m_xTextSeparator.get();
+ }
+ else if (m_xDecimalSeparator->get_active_text() == m_xThousandsSeparator->get_active_text())
+ { // Thousands and DecimalSeparator must not be the same
+ aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
+ aErrorText = aErrorText.replaceFirst("#1",m_xDecimalSeparatorLabel->get_label());
+ aErrorText = aErrorText.replaceFirst("#2",m_xThousandsSeparatorLabel->get_label());
+ pErrorWin = m_xDecimalSeparator.get();
+ }
+ else if (m_xFieldSeparator->get_active_text() == m_xThousandsSeparator->get_active_text())
+ { // Thousands and FieldSeparator must not be the same
+ aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
+ aErrorText = aErrorText.replaceFirst("#1",m_xFieldSeparatorLabel->get_label());
+ aErrorText = aErrorText.replaceFirst("#2",m_xThousandsSeparatorLabel->get_label());
+ pErrorWin = m_xFieldSeparator.get();
+ }
+ else if (m_xFieldSeparator->get_active_text() == m_xDecimalSeparator->get_active_text())
+ { // Tenner and FieldSeparator must not be the same
+ aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
+ aErrorText = aErrorText.replaceFirst("#1",m_xFieldSeparatorLabel->get_label());
+ aErrorText = aErrorText.replaceFirst("#2",m_xDecimalSeparatorLabel->get_label());
+ pErrorWin = m_xFieldSeparator.get();
+ }
+ else if (m_xTextSeparator->get_active_text() == m_xThousandsSeparator->get_active_text())
+ { // Thousands and TextSeparator must not be the same
+ aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
+ aErrorText = aErrorText.replaceFirst("#1",m_xTextSeparatorLabel->get_label());
+ aErrorText = aErrorText.replaceFirst("#2",m_xThousandsSeparatorLabel->get_label());
+ pErrorWin = m_xTextSeparator.get();
+ }
+ else if (m_xTextSeparator->get_active_text() == m_xDecimalSeparator->get_active_text())
+ { // Tenner and TextSeparator must not be the same
+ aErrorText = DBA_RES(STR_AUTODELIMITER_MUST_DIFFER);
+ aErrorText = aErrorText.replaceFirst("#1",m_xTextSeparatorLabel->get_label());
+ aErrorText = aErrorText.replaceFirst("#2",m_xDecimalSeparatorLabel->get_label());
+ pErrorWin = m_xTextSeparator.get();
+ }
+ else if ((sExtension.indexOf('*') != -1) || (sExtension.indexOf('?') != -1))
+ {
+ aErrorText = DBA_RES(STR_AUTONO_WILDCARDS);
+ aErrorText = aErrorText.replaceFirst("#1",sExtension);
+ pErrorWin = m_xOwnExtension.get();
+ }
+ else
+ return true;
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xContainer.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ MnemonicGenerator::EraseAllMnemonicChars(aErrorText)));
+ xBox->run();
+ pErrorWin->grab_focus();
+ return false;
+ }
+
+ bool OTextConnectionHelper::FillItemSet( SfxItemSet& rSet, const bool _bChangedSomething )
+ {
+ bool bChangedSomething = _bChangedSomething;
+
+ if ( ( m_nAvailableSections & TC_EXTENSION ) != 0 )
+ {
+ OUString sExtension = GetExtension();
+ if( m_aOldExtension != sExtension )
+ {
+ rSet.Put( SfxStringItem( DSID_TEXTFILEEXTENSION, sExtension ) );
+ bChangedSomething = true;
+ }
+ }
+
+ if ( ( m_nAvailableSections & TC_HEADER ) != 0 )
+ {
+ if (m_xRowHeader->get_state_changed_from_saved())
+ {
+ rSet.Put(SfxBoolItem(DSID_TEXTFILEHEADER, m_xRowHeader->get_active()));
+ bChangedSomething = true;
+ }
+ }
+
+ if ( ( m_nAvailableSections & TC_SEPARATORS ) != 0 )
+ {
+ if (m_xFieldSeparator->get_value_changed_from_saved())
+ {
+ rSet.Put( SfxStringItem(DSID_FIELDDELIMITER, GetSeparator( *m_xFieldSeparator, m_aFieldSeparatorList) ) );
+ bChangedSomething = true;
+ }
+ if (m_xTextSeparator->get_value_changed_from_saved())
+ {
+ rSet.Put( SfxStringItem(DSID_TEXTDELIMITER, GetSeparator( *m_xTextSeparator, m_aTextSeparatorList) ) );
+ bChangedSomething = true;
+ }
+
+ if (m_xDecimalSeparator->get_value_changed_from_saved())
+ {
+ rSet.Put( SfxStringItem(DSID_DECIMALDELIMITER, m_xDecimalSeparator->get_active_text().copy(0, 1) ) );
+ bChangedSomething = true;
+ }
+ if (m_xThousandsSeparator->get_value_changed_from_saved())
+ {
+ rSet.Put( SfxStringItem(DSID_THOUSANDSDELIMITER, m_xThousandsSeparator->get_active_text().copy(0,1) ) );
+ bChangedSomething = true;
+ }
+ }
+
+ if ( ( m_nAvailableSections & TC_CHARSET ) != 0 )
+ {
+ if ( m_xCharSet->StoreSelectedCharSet( rSet, DSID_CHARSET ) )
+ bChangedSomething = true;
+ }
+
+ return bChangedSomething;
+ }
+
+ void OTextConnectionHelper::SetExtension(const OUString& _rVal)
+ {
+ if (_rVal == "txt")
+ m_xAccessTextFiles->set_active(true);
+ else if (_rVal == "csv")
+ m_xAccessCSVFiles->set_active(true);
+ else
+ {
+ m_xAccessOtherFiles->set_active(true);
+ m_xExtensionExample->set_label(_rVal);
+ }
+ }
+
+ OUString OTextConnectionHelper::GetExtension() const
+ {
+ OUString sExtension;
+ if (m_xAccessTextFiles->get_active())
+ sExtension = "txt";
+ else if (m_xAccessCSVFiles->get_active())
+ sExtension = "csv";
+ else
+ {
+ sExtension = m_xOwnExtension->get_text();
+ if ( sExtension.startsWith("*.") )
+ sExtension = sExtension.copy(2);
+ }
+ return sExtension;
+ }
+
+ OUString OTextConnectionHelper::GetSeparator(const weld::ComboBox& rBox, std::u16string_view rList)
+ {
+ sal_Unicode const nTok = '\t';
+ int nPos(rBox.find_text(rBox.get_active_text()));
+
+ if (nPos == -1)
+ return rBox.get_active_text();
+
+ if ( m_xTextSeparator.get() != &rBox || nPos != (rBox.get_count()-1) )
+ return OUString(
+ static_cast< sal_Unicode >( o3tl::toInt32(o3tl::getToken(rList, (nPos*2)+1, nTok )) ));
+ // somewhat strange ... translates for instance an "32" into " "
+ return OUString();
+ }
+
+ void OTextConnectionHelper::SetSeparator( weld::ComboBox& rBox, std::u16string_view rList, const OUString& rVal )
+ {
+ if (rVal.getLength()==1)
+ {
+ const sal_Unicode nVal {rVal[0]};
+ for(sal_Int32 nIdx {0}; nIdx>=0;)
+ {
+ sal_Int32 nPrevIdx {nIdx};
+ if (static_cast<sal_Unicode>(o3tl::toInt32(o3tl::getToken(rList, 1, '\t', nIdx))) == nVal)
+ {
+ rBox.set_entry_text(OUString(o3tl::getToken(rList,0, '\t', nPrevIdx)));
+ return;
+ }
+ }
+ rBox.set_entry_text( rVal );
+ }
+ else if ( m_xTextSeparator.get() == &rBox && rVal.isEmpty() )
+ rBox.set_entry_text(m_aTextNone);
+ else
+ rBox.set_entry_text(rVal.copy(0, 1));
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/TextConnectionHelper.hxx b/dbaccess/source/ui/dlg/TextConnectionHelper.hxx
new file mode 100644
index 000000000..6755a4223
--- /dev/null
+++ b/dbaccess/source/ui/dlg/TextConnectionHelper.hxx
@@ -0,0 +1,89 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "adminpages.hxx"
+#include <charsetlistbox.hxx>
+#include <rtl/ustring.hxx>
+
+namespace dbaui
+
+{
+
+ #define TC_EXTENSION (short(0x01)) // a section specifying the extension of the files to connect to
+ #define TC_SEPARATORS (short(0x02)) // a section specifying the various separators
+ #define TC_HEADER (short(0x04)) // a section containing the "Text contains header" check box only
+ #define TC_CHARSET (short(0x08)) // not yet implemented
+
+ class OTextConnectionHelper final
+ {
+ public:
+ OTextConnectionHelper(weld::Widget* pParent , const short _nAvailableSections);
+
+ private:
+ OUString m_aFieldSeparatorList;
+ OUString m_aTextSeparatorList;
+ OUString m_aTextNone;
+ OUString m_aOldExtension;
+ Link<OTextConnectionHelper*, void> m_aGetExtensionHandler; /// to be called if a new type is selected
+
+ short m_nAvailableSections;
+
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Widget> m_xContainer;
+ std::unique_ptr<weld::Widget> m_xExtensionHeader;
+ std::unique_ptr<weld::RadioButton> m_xAccessTextFiles;
+ std::unique_ptr<weld::RadioButton> m_xAccessCSVFiles;
+ std::unique_ptr<weld::RadioButton> m_xAccessOtherFiles;
+ std::unique_ptr<weld::Entry> m_xOwnExtension;
+ std::unique_ptr<weld::Label> m_xExtensionExample;
+ std::unique_ptr<weld::Widget> m_xFormatHeader;
+ std::unique_ptr<weld::Label> m_xFieldSeparatorLabel;
+ std::unique_ptr<weld::ComboBox> m_xFieldSeparator;
+ std::unique_ptr<weld::Label> m_xTextSeparatorLabel;
+ std::unique_ptr<weld::ComboBox> m_xTextSeparator;
+ std::unique_ptr<weld::Label> m_xDecimalSeparatorLabel;
+ std::unique_ptr<weld::ComboBox> m_xDecimalSeparator;
+ std::unique_ptr<weld::Label> m_xThousandsSeparatorLabel;
+ std::unique_ptr<weld::ComboBox> m_xThousandsSeparator;
+ std::unique_ptr<weld::CheckButton> m_xRowHeader;
+ std::unique_ptr<weld::Widget> m_xCharSetHeader;
+ std::unique_ptr<weld::Label> m_xCharSetLabel;
+ std::unique_ptr<CharSetListBox> m_xCharSet;
+
+ DECL_LINK(OnSetExtensionHdl, weld::Toggleable&, void);
+ DECL_LINK(OnEditModified, weld::Entry&, void);
+
+ OUString GetSeparator(const weld::ComboBox& rBox, std::u16string_view rList);
+ void SetSeparator(weld::ComboBox& rBox, std::u16string_view rList, const OUString& rVal);
+ void SetExtension(const OUString& _rVal);
+
+ public:
+ void implInitControls(const SfxItemSet& _rSet, bool _bValid);
+ void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList);
+ void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList);
+ void SetClickHandler(const Link<OTextConnectionHelper*, void>& _rHandler) { m_aGetExtensionHandler = _rHandler; }
+ OUString GetExtension() const;
+ bool FillItemSet( SfxItemSet& rSet, const bool bChangedSomething );
+ bool prepareLeave();
+ };
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/UserAdmin.cxx b/dbaccess/source/ui/dlg/UserAdmin.cxx
new file mode 100644
index 000000000..b601c4939
--- /dev/null
+++ b/dbaccess/source/ui/dlg/UserAdmin.cxx
@@ -0,0 +1,316 @@
+/* -*- 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 "UserAdmin.hxx"
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include <com/sun/star/sdbc/XDriver.hpp>
+#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
+#include <com/sun/star/sdbcx/XUsersSupplier.hpp>
+#include <com/sun/star/sdbcx/XDrop.hpp>
+#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdbcx/XUser.hpp>
+#include <com/sun/star/sdbcx/XAppend.hpp>
+#include <IItemSetHelper.hxx>
+#include <strings.hrc>
+#include <strings.hxx>
+#include <core_resource.hxx>
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbtools.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/passwd.hxx>
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::task;
+using namespace dbaui;
+using namespace comphelper;
+
+namespace {
+
+class OPasswordDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Frame> m_xUser;
+ std::unique_ptr<weld::Entry> m_xEDOldPassword;
+ std::unique_ptr<weld::Entry> m_xEDPassword;
+ std::unique_ptr<weld::Entry> m_xEDPasswordRepeat;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+ DECL_LINK(ModifiedHdl, weld::Entry&, void);
+
+public:
+ OPasswordDialog(weld::Window* pParent, std::u16string_view rUserName);
+
+ OUString GetOldPassword() const { return m_xEDOldPassword->get_text(); }
+ OUString GetNewPassword() const { return m_xEDPassword->get_text(); }
+};
+
+}
+
+OPasswordDialog::OPasswordDialog(weld::Window* _pParent, std::u16string_view rUserName)
+ : GenericDialogController(_pParent, "dbaccess/ui/password.ui", "PasswordDialog")
+ , m_xUser(m_xBuilder->weld_frame("userframe"))
+ , m_xEDOldPassword(m_xBuilder->weld_entry("oldpassword"))
+ , m_xEDPassword(m_xBuilder->weld_entry("newpassword"))
+ , m_xEDPasswordRepeat(m_xBuilder->weld_entry("confirmpassword"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+{
+ OUString sUser = m_xUser->get_label();
+ sUser = sUser.replaceFirst("$name$: $", rUserName);
+ m_xUser->set_label(sUser);
+ m_xOKBtn->set_sensitive(false);
+
+ m_xOKBtn->connect_clicked( LINK( this, OPasswordDialog, OKHdl_Impl ) );
+ m_xEDOldPassword->connect_changed( LINK( this, OPasswordDialog, ModifiedHdl ) );
+}
+
+IMPL_LINK_NOARG(OPasswordDialog, OKHdl_Impl, weld::Button&, void)
+{
+ if (m_xEDPassword->get_text() == m_xEDPasswordRepeat->get_text())
+ m_xDialog->response(RET_OK);
+ else
+ {
+ OUString aErrorMsg( DBA_RES( STR_ERROR_PASSWORDS_NOT_IDENTICAL));
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ aErrorMsg));
+ xErrorBox->run();
+ m_xEDPassword->set_text(OUString());
+ m_xEDPasswordRepeat->set_text(OUString());
+ m_xEDPassword->grab_focus();
+ }
+}
+
+IMPL_LINK(OPasswordDialog, ModifiedHdl, weld::Entry&, rEdit, void)
+{
+ m_xOKBtn->set_sensitive(!rEdit.get_text().isEmpty());
+}
+
+// OUserAdmin
+OUserAdmin::OUserAdmin(weld::Container* pPage, weld::DialogController* pController,const SfxItemSet& _rAttrSet)
+ : OGenericAdministrationPage(pPage, pController, "dbaccess/ui/useradminpage.ui", "UserAdminPage", _rAttrSet)
+ , m_xUSER(m_xBuilder->weld_combo_box("user"))
+ , m_xNEWUSER(m_xBuilder->weld_button("add"))
+ , m_xCHANGEPWD(m_xBuilder->weld_button("changepass"))
+ , m_xDELETEUSER(m_xBuilder->weld_button("delete"))
+ , m_xTable(m_xBuilder->weld_container("table"))
+ , m_xTableCtrlParent(m_xTable->CreateChildFrame())
+ , m_xTableCtrl(VclPtr<OTableGrantControl>::Create(m_xTableCtrlParent))
+{
+ m_xTableCtrl->Show();
+
+ m_xUSER->connect_changed(LINK(this, OUserAdmin, ListDblClickHdl));
+ m_xNEWUSER->connect_clicked(LINK(this, OUserAdmin, UserHdl));
+ m_xCHANGEPWD->connect_clicked(LINK(this, OUserAdmin, UserHdl));
+ m_xDELETEUSER->connect_clicked(LINK(this, OUserAdmin, UserHdl));
+}
+
+OUserAdmin::~OUserAdmin()
+{
+ m_xConnection = nullptr;
+ m_xTableCtrl.disposeAndClear();
+ m_xTableCtrlParent->dispose();
+ m_xTableCtrlParent.clear();
+}
+
+void OUserAdmin::FillUserNames()
+{
+ if(m_xConnection.is())
+ {
+ m_xUSER->clear();
+
+ Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData();
+
+ if ( xMetaData.is() )
+ {
+ m_UserName = xMetaData->getUserName();
+
+ // first we need the users
+ if ( m_xUsers.is() )
+ {
+ m_xUSER->clear();
+
+ m_aUserNames = m_xUsers->getElementNames();
+ const OUString* pBegin = m_aUserNames.getConstArray();
+ const OUString* pEnd = pBegin + m_aUserNames.getLength();
+ for(;pBegin != pEnd;++pBegin)
+ m_xUSER->append_text(*pBegin);
+
+ m_xUSER->set_active(0);
+ if(m_xUsers->hasByName(m_UserName))
+ {
+ Reference<XAuthorizable> xAuth;
+ m_xUsers->getByName(m_UserName) >>= xAuth;
+ m_xTableCtrl->setGrantUser(xAuth);
+ }
+
+ m_xTableCtrl->setUserName(GetUser());
+ m_xTableCtrl->Init();
+ }
+ }
+ }
+
+ Reference<XAppend> xAppend(m_xUsers,UNO_QUERY);
+ m_xNEWUSER->set_sensitive(xAppend.is());
+ Reference<XDrop> xDrop(m_xUsers,UNO_QUERY);
+ m_xDELETEUSER->set_sensitive(xDrop.is());
+
+ m_xCHANGEPWD->set_sensitive(m_xUsers.is());
+ m_xTableCtrl->Enable(m_xUsers.is());
+}
+
+std::unique_ptr<SfxTabPage> OUserAdmin::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet )
+{
+ return std::make_unique<OUserAdmin>( pPage, pController, *_rAttrSet );
+}
+
+IMPL_LINK(OUserAdmin, UserHdl, weld::Button&, rButton, void)
+{
+ try
+ {
+ if (&rButton == m_xNEWUSER.get())
+ {
+ SfxPasswordDialog aPwdDlg(GetFrameWeld());
+ aPwdDlg.ShowExtras(SfxShowExtras::ALL);
+ if (aPwdDlg.run())
+ {
+ Reference<XDataDescriptorFactory> xUserFactory(m_xUsers,UNO_QUERY);
+ Reference<XPropertySet> xNewUser = xUserFactory->createDataDescriptor();
+ if(xNewUser.is())
+ {
+ xNewUser->setPropertyValue(PROPERTY_NAME,Any(aPwdDlg.GetUser()));
+ xNewUser->setPropertyValue(PROPERTY_PASSWORD,Any(aPwdDlg.GetPassword()));
+ Reference<XAppend> xAppend(m_xUsers,UNO_QUERY);
+ if(xAppend.is())
+ xAppend->appendByDescriptor(xNewUser);
+ }
+ }
+ }
+ else if (&rButton == m_xCHANGEPWD.get())
+ {
+ OUString sName = GetUser();
+
+ if(m_xUsers->hasByName(sName))
+ {
+ Reference<XUser> xUser;
+ m_xUsers->getByName(sName) >>= xUser;
+ if(xUser.is())
+ {
+ OPasswordDialog aDlg(GetFrameWeld(), sName);
+ if (aDlg.run() == RET_OK)
+ {
+ OUString sNewPassword,sOldPassword;
+ sNewPassword = aDlg.GetNewPassword();
+ sOldPassword = aDlg.GetOldPassword();
+
+ if(!sNewPassword.isEmpty())
+ xUser->changePassword(sOldPassword,sNewPassword);
+ }
+ }
+ }
+ }
+ else
+ {// delete user
+ if(m_xUsers.is() && m_xUsers->hasByName(GetUser()))
+ {
+ Reference<XDrop> xDrop(m_xUsers,UNO_QUERY);
+ if(xDrop.is())
+ {
+ std::unique_ptr<weld::MessageDialog> xQry(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ DBA_RES(STR_QUERY_USERADMIN_DELETE_USER)));
+ if (xQry->run() == RET_YES)
+ xDrop->dropByName(GetUser());
+ }
+ }
+ }
+ FillUserNames();
+ }
+ catch(const SQLException& e)
+ {
+ ::dbtools::showError(::dbtools::SQLExceptionInfo(e), GetDialogController()->getDialog()->GetXWindow(), m_xORB);
+ }
+ catch(Exception& )
+ {
+ }
+}
+
+IMPL_LINK_NOARG(OUserAdmin, ListDblClickHdl, weld::ComboBox&, void)
+{
+ m_xTableCtrl->setUserName(GetUser());
+ m_xTableCtrl->UpdateTables();
+ m_xTableCtrl->DeactivateCell();
+ m_xTableCtrl->ActivateCell(m_xTableCtrl->GetCurRow(),m_xTableCtrl->GetCurColumnId());
+}
+
+OUString OUserAdmin::GetUser() const
+{
+ return m_xUSER->get_active_text();
+}
+
+void OUserAdmin::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& /*_rControlList*/)
+{
+}
+
+void OUserAdmin::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& /*_rControlList*/)
+{
+}
+
+void OUserAdmin::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+{
+ m_xTableCtrl->setComponentContext(m_xORB);
+ try
+ {
+ if ( !m_xConnection.is() && m_pAdminDialog )
+ {
+ m_xConnection = m_pAdminDialog->createConnection().first;
+ Reference< XTablesSupplier > xTablesSup(m_xConnection,UNO_QUERY);
+ Reference<XUsersSupplier> xUsersSup(xTablesSup,UNO_QUERY);
+ if ( !xUsersSup.is() )
+ {
+ Reference< XDataDefinitionSupplier > xDriver(m_pAdminDialog->getDriver(),UNO_QUERY);
+ if ( xDriver.is() )
+ {
+ xUsersSup.set(xDriver->getDataDefinitionByConnection(m_xConnection),UNO_QUERY);
+ xTablesSup.set(xUsersSup,UNO_QUERY);
+ }
+ }
+ if ( xUsersSup.is() )
+ {
+ m_xTableCtrl->setTablesSupplier(xTablesSup);
+ m_xUsers = xUsersSup->getUsers();
+ }
+ }
+ FillUserNames();
+ }
+ catch(const SQLException& e)
+ {
+ ::dbtools::showError(::dbtools::SQLExceptionInfo(e), GetDialogController()->getDialog()->GetXWindow(), m_xORB);
+ }
+
+ OGenericAdministrationPage::implInitControls(_rSet, _bSaveValue);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/UserAdmin.hxx b/dbaccess/source/ui/dlg/UserAdmin.hxx
new file mode 100644
index 000000000..e9c2a13e7
--- /dev/null
+++ b/dbaccess/source/ui/dlg/UserAdmin.hxx
@@ -0,0 +1,74 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <TableGrantCtrl.hxx>
+#include "adminpages.hxx"
+
+namespace com::sun::star {
+ namespace sdbc {
+ class XConnection;
+ }
+}
+
+namespace dbaui
+{
+
+class OUserAdmin final : public OGenericAdministrationPage
+{
+ std::unique_ptr<weld::ComboBox> m_xUSER;
+ std::unique_ptr<weld::Button> m_xNEWUSER;
+ std::unique_ptr<weld::Button> m_xCHANGEPWD;
+ std::unique_ptr<weld::Button> m_xDELETEUSER;
+ std::unique_ptr<weld::Container> m_xTable;
+ css::uno::Reference<css::awt::XWindow> m_xTableCtrlParent;
+ VclPtr<OTableGrantControl> m_xTableCtrl; // show the grant rights of one user
+
+ css::uno::Reference< css::sdbc::XConnection> m_xConnection;
+ css::uno::Reference< css::container::XNameAccess > m_xUsers;
+ css::uno::Sequence< OUString> m_aUserNames;
+
+ OUString m_UserName;
+
+ // methods
+ DECL_LINK(ListDblClickHdl, weld::ComboBox&, void);
+ DECL_LINK(UserHdl, weld::Button&, void);
+
+ void FillUserNames();
+
+public:
+ OUserAdmin(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs);
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+ virtual ~OUserAdmin() override;
+
+ OUString GetUser() const;
+
+ // subclasses must override this, but it isn't pure virtual
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+
+ // <method>OGenericAdministrationPage::fillControls</method>
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ // <method>OGenericAdministrationPage::fillWindows</method>
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/UserAdminDlg.cxx b/dbaccess/source/ui/dlg/UserAdminDlg.cxx
new file mode 100644
index 000000000..ec44c3399
--- /dev/null
+++ b/dbaccess/source/ui/dlg/UserAdminDlg.cxx
@@ -0,0 +1,162 @@
+/* -*- 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 <core_resource.hxx>
+#include "adminpages.hxx"
+#include "DbAdminImpl.hxx"
+#include <strings.hrc>
+#include "UserAdmin.hxx"
+#include <UserAdminDlg.hxx>
+
+#include <com/sun/star/sdbc/SQLException.hpp>
+
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbmetadata.hxx>
+#include <connectivity/dbtools.hxx>
+#include <comphelper/types.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <tools/diagnose_ex.h>
+
+namespace dbaui
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+
+ // OUserAdminDlg
+ OUserAdminDlg::OUserAdminDlg(weld::Window* pParent,
+ SfxItemSet* pItems,
+ const Reference< XComponentContext >& rxORB,
+ const css::uno::Any& rDataSourceName,
+ const Reference< XConnection >& xConnection)
+ : SfxTabDialogController(pParent, "dbaccess/ui/useradmindialog.ui", "UserAdminDialog", pItems)
+ , m_pParent(pParent)
+ , m_pItemSet(pItems)
+ , m_xConnection(xConnection)
+ , m_bOwnConnection(!xConnection.is())
+ {
+ m_pImpl.reset(new ODbDataSourceAdministrationHelper(rxORB, m_xDialog.get(), pParent, this));
+ m_pImpl->setDataSourceOrName(rDataSourceName);
+ Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
+ m_pImpl->translateProperties(xDatasource, *pItems);
+ SetInputSet(pItems);
+ // propagate this set as our new input set and reset the example set
+ m_xExampleSet.reset(new SfxItemSet(*GetInputSetImpl()));
+
+ AddTabPage("settings", OUserAdmin::Create, nullptr);
+
+ // remove the reset button - it's meaning is much too ambiguous in this dialog
+ RemoveResetButton();
+ }
+
+ OUserAdminDlg::~OUserAdminDlg()
+ {
+ if ( m_bOwnConnection )
+ {
+ try
+ {
+ ::comphelper::disposeComponent(m_xConnection);
+ }
+ catch(const Exception&)
+ {
+ }
+ }
+
+ SetInputSet(nullptr);
+ }
+
+ short OUserAdminDlg::run()
+ {
+ try
+ {
+ ::dbtools::DatabaseMetaData aMetaData( createConnection().first );
+ if ( !aMetaData.supportsUserAdministration( getORB() ) )
+ {
+ OUString sError(DBA_RES(STR_USERADMIN_NOT_AVAILABLE));
+ throw SQLException(sError, nullptr, "S1000", 0, Any());
+ }
+ }
+ catch(const SQLException&)
+ {
+ ::dbtools::showError(::dbtools::SQLExceptionInfo(::cppu::getCaughtException()), m_pParent->GetXWindow(), getORB());
+ return RET_CANCEL;
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ short nRet = SfxTabDialogController::run();
+ if ( nRet == RET_OK )
+ m_pImpl->saveChanges(*GetOutputItemSet());
+ return nRet;
+ }
+ void OUserAdminDlg::PageCreated(const OString& rId, SfxTabPage& _rPage)
+ {
+ // register ourself as modified listener
+ static_cast<OGenericAdministrationPage&>(_rPage).SetServiceFactory( m_pImpl->getORB() );
+ static_cast<OGenericAdministrationPage&>(_rPage).SetAdminDialog(this,this);
+ SfxTabDialogController::PageCreated(rId, _rPage);
+ }
+ const SfxItemSet* OUserAdminDlg::getOutputSet() const
+ {
+ return m_pItemSet;
+ }
+ SfxItemSet* OUserAdminDlg::getWriteOutputSet()
+ {
+ return m_pItemSet;
+ }
+ std::pair< Reference<XConnection>,bool> OUserAdminDlg::createConnection()
+ {
+ if ( !m_xConnection.is() )
+ {
+ m_xConnection = m_pImpl->createConnection().first;
+ m_bOwnConnection = m_xConnection.is();
+ }
+ return std::pair< Reference<XConnection>,bool> (m_xConnection,false);
+ }
+ Reference< XComponentContext > OUserAdminDlg::getORB() const
+ {
+ return m_pImpl->getORB();
+ }
+ Reference< XDriver > OUserAdminDlg::getDriver()
+ {
+ return m_pImpl->getDriver();
+ }
+ OUString OUserAdminDlg::getDatasourceType(const SfxItemSet& _rSet) const
+ {
+ return dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(_rSet);
+ }
+ void OUserAdminDlg::clearPassword()
+ {
+ m_pImpl->clearPassword();
+ }
+ void OUserAdminDlg::setTitle(const OUString& _sTitle)
+ {
+ m_xDialog->set_title(_sTitle);
+ }
+ void OUserAdminDlg::enableConfirmSettings( bool ) {}
+ void OUserAdminDlg::saveDatasource()
+ {
+ PrepareLeaveCurrentPage();
+ }
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/admincontrols.cxx b/dbaccess/source/ui/dlg/admincontrols.cxx
new file mode 100644
index 000000000..de515f9e3
--- /dev/null
+++ b/dbaccess/source/ui/dlg/admincontrols.cxx
@@ -0,0 +1,201 @@
+/* -*- 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 "admincontrols.hxx"
+#include <dsitems.hxx>
+
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <vcl/svapp.hxx>
+
+namespace dbaui
+{
+
+ // MySQLNativeSettings
+ MySQLNativeSettings::MySQLNativeSettings(weld::Widget* pParent, const Link<weld::Widget*,void>& rControlModificationLink)
+ : m_xBuilder(Application::CreateBuilder(pParent, "dbaccess/ui/mysqlnativesettings.ui"))
+ , m_xContainer(m_xBuilder->weld_widget("MysqlNativeSettings"))
+ , m_xDatabaseNameLabel(m_xBuilder->weld_label("dbnamelabel"))
+ , m_xDatabaseName(m_xBuilder->weld_entry("dbname"))
+ , m_xHostPortRadio(m_xBuilder->weld_radio_button("hostport"))
+ , m_xSocketRadio(m_xBuilder->weld_radio_button("socketlabel"))
+ , m_xNamedPipeRadio(m_xBuilder->weld_radio_button("namedpipelabel"))
+ , m_xHostNameLabel(m_xBuilder->weld_label("serverlabel"))
+ , m_xHostName(m_xBuilder->weld_entry("server"))
+ , m_xPortLabel(m_xBuilder->weld_label("portlabel"))
+ , m_xPort(m_xBuilder->weld_spin_button("port"))
+ , m_xDefaultPort(m_xBuilder->weld_label("defaultport"))
+ , m_xSocket(m_xBuilder->weld_entry("socket"))
+ , m_xNamedPipe(m_xBuilder->weld_entry("namedpipe"))
+ , m_aControlModificationLink(rControlModificationLink)
+ {
+ m_xDatabaseName->connect_changed( LINK(this, MySQLNativeSettings, EditModifyHdl) );
+ m_xHostName->connect_changed( LINK(this, MySQLNativeSettings, EditModifyHdl) );
+ m_xPort->connect_value_changed( LINK(this, MySQLNativeSettings, SpinModifyHdl) );
+ m_xSocket->connect_changed( LINK(this, MySQLNativeSettings, EditModifyHdl) );
+ m_xNamedPipe->connect_changed( LINK(this, MySQLNativeSettings, EditModifyHdl) );
+ m_xSocketRadio->connect_toggled( LINK(this, MySQLNativeSettings, RadioToggleHdl) );
+ m_xNamedPipeRadio->connect_toggled( LINK(this, MySQLNativeSettings, RadioToggleHdl) );
+ m_xHostPortRadio->connect_toggled( LINK(this, MySQLNativeSettings, RadioToggleHdl) );
+
+ // sockets are available on Unix systems only, named pipes only on Windows
+#ifdef UNX
+ m_xNamedPipeRadio->hide();
+ m_xNamedPipe->hide();
+#else
+ m_xSocketRadio->hide();
+ m_xSocket->hide();
+#endif
+ m_xContainer->show();
+ }
+
+ IMPL_LINK(MySQLNativeSettings, RadioToggleHdl, weld::Toggleable&, rRadioButton, void)
+ {
+ m_aControlModificationLink.Call(&rRadioButton);
+
+ const bool bHostPortRadio = m_xHostPortRadio->get_active();
+ m_xHostNameLabel->set_sensitive(bHostPortRadio);
+ m_xHostName->set_sensitive(bHostPortRadio);
+ m_xPortLabel->set_sensitive(bHostPortRadio);
+ m_xPort->set_sensitive(bHostPortRadio);
+ m_xDefaultPort->set_sensitive(bHostPortRadio);
+
+ m_xSocket->set_sensitive(m_xSocketRadio->get_active());
+ m_xNamedPipe->set_sensitive(m_xNamedPipeRadio->get_active());
+ }
+
+ IMPL_LINK(MySQLNativeSettings, EditModifyHdl, weld::Entry&, rEdit, void)
+ {
+ m_aControlModificationLink.Call(&rEdit);
+ }
+
+ IMPL_LINK(MySQLNativeSettings, SpinModifyHdl, weld::SpinButton&, rEdit, void)
+ {
+ m_aControlModificationLink.Call(&rEdit);
+ }
+
+ void MySQLNativeSettings::fillControls( std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList )
+ {
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xDatabaseName.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xHostName.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xPort.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xSocket.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xNamedPipe.get()));
+ }
+
+ void MySQLNativeSettings::fillWindows( std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList )
+ {
+ _rControlList.emplace_back( new ODisableWidgetWrapper<weld::Label>( m_xDatabaseNameLabel.get() ) );
+ _rControlList.emplace_back( new ODisableWidgetWrapper<weld::Label>( m_xHostNameLabel.get() ) );
+ _rControlList.emplace_back( new ODisableWidgetWrapper<weld::Label>( m_xPortLabel.get() ) );
+ _rControlList.emplace_back( new ODisableWidgetWrapper<weld::Label>( m_xDefaultPort.get() ) );
+ _rControlList.emplace_back( new ODisableWidgetWrapper<weld::RadioButton>( m_xSocketRadio.get() ) );
+ _rControlList.emplace_back( new ODisableWidgetWrapper<weld::RadioButton>( m_xNamedPipeRadio.get() ) );
+ }
+
+ bool MySQLNativeSettings::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = false;
+
+ OGenericAdministrationPage::fillString( *_rSet, m_xHostName.get(), DSID_CONN_HOSTNAME, bChangedSomething );
+ OGenericAdministrationPage::fillString( *_rSet, m_xDatabaseName.get(), DSID_DATABASENAME, bChangedSomething );
+ OGenericAdministrationPage::fillInt32 ( *_rSet, m_xPort.get(), DSID_MYSQL_PORTNUMBER, bChangedSomething );
+#ifdef UNX
+ OGenericAdministrationPage::fillString( *_rSet, m_xSocket.get(), DSID_CONN_SOCKET, bChangedSomething );
+#else
+ OGenericAdministrationPage::fillString( *_rSet, m_xNamedPipe.get(), DSID_NAMED_PIPE, bChangedSomething );
+#endif
+
+ return bChangedSomething;
+ }
+
+ void MySQLNativeSettings::implInitControls(const SfxItemSet& _rSet )
+ {
+ const SfxBoolItem* pInvalid = _rSet.GetItem<SfxBoolItem>(DSID_INVALID_SELECTION);
+ bool bValid = !pInvalid || !pInvalid->GetValue();
+ if ( !bValid )
+ return;
+
+ const SfxStringItem* pDatabaseName = _rSet.GetItem<SfxStringItem>(DSID_DATABASENAME);
+ const SfxStringItem* pHostName = _rSet.GetItem<SfxStringItem>(DSID_CONN_HOSTNAME);
+ const SfxInt32Item* pPortNumber = _rSet.GetItem<SfxInt32Item>(DSID_MYSQL_PORTNUMBER);
+ const SfxStringItem* pSocket = _rSet.GetItem<SfxStringItem>(DSID_CONN_SOCKET);
+ const SfxStringItem* pNamedPipe = _rSet.GetItem<SfxStringItem>(DSID_NAMED_PIPE);
+
+ m_xDatabaseName->set_text( pDatabaseName->GetValue() );
+ m_xDatabaseName->save_value();
+
+ m_xHostName->set_text( pHostName->GetValue() );
+ m_xHostName->save_value();
+
+ m_xPort->set_value( pPortNumber->GetValue() );
+ m_xPort->save_value();
+
+ m_xSocket->set_text( pSocket->GetValue() );
+ m_xSocket->save_value();
+
+ m_xNamedPipe->set_text( pNamedPipe->GetValue() );
+ m_xNamedPipe->save_value();
+
+ // if a socket (on Unix) or a pipe name (on Windows) is given, this is preferred over
+ // the port
+#ifdef UNX
+ weld::RadioButton& rSocketPipeRadio = *m_xSocketRadio;
+ const SfxStringItem* pSocketPipeItem = pSocket;
+#else
+ weld::RadioButton& rSocketPipeRadio = *m_xNamedPipeRadio;
+ const SfxStringItem* pSocketPipeItem = pNamedPipe;
+#endif
+ const OUString& rSocketPipe( pSocketPipeItem->GetValue() );
+ if (!rSocketPipe.isEmpty())
+ rSocketPipeRadio.set_active(true);
+ else
+ m_xHostPortRadio->set_active(true);
+ }
+
+ bool MySQLNativeSettings::canAdvance() const
+ {
+ if (m_xDatabaseName->get_text().isEmpty())
+ return false;
+
+ if ( m_xHostPortRadio->get_active()
+ && ( ( m_xHostName->get_text().isEmpty() )
+ || ( m_xPort->get_text().isEmpty() )
+ )
+ )
+ return false;
+
+#ifdef UNX
+ if ( ( m_xSocketRadio->get_active() )
+ && ( m_xSocket->get_text().isEmpty() )
+ )
+#else
+ if ( ( m_xNamedPipeRadio->get_active() )
+ && ( m_xNamedPipe->get_text().isEmpty() )
+ )
+#endif
+ return false;
+
+ return true;
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/admincontrols.hxx b/dbaccess/source/ui/dlg/admincontrols.hxx
new file mode 100644
index 000000000..7bd1e5edf
--- /dev/null
+++ b/dbaccess/source/ui/dlg/admincontrols.hxx
@@ -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 .
+ */
+
+#pragma once
+
+#include "adminpages.hxx"
+
+#include <vcl/weld.hxx>
+
+namespace dbaui
+{
+
+ // MySQLNativeSettings
+ class MySQLNativeSettings
+ {
+ private:
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Widget> m_xContainer;
+ std::unique_ptr<weld::Label> m_xDatabaseNameLabel;
+ std::unique_ptr<weld::Entry> m_xDatabaseName;
+ std::unique_ptr<weld::RadioButton> m_xHostPortRadio;
+ std::unique_ptr<weld::RadioButton> m_xSocketRadio;
+ std::unique_ptr<weld::RadioButton> m_xNamedPipeRadio;
+ std::unique_ptr<weld::Label> m_xHostNameLabel;
+ std::unique_ptr<weld::Entry> m_xHostName;
+ std::unique_ptr<weld::Label> m_xPortLabel;
+ std::unique_ptr<weld::SpinButton> m_xPort;
+ std::unique_ptr<weld::Label> m_xDefaultPort;
+ std::unique_ptr<weld::Entry> m_xSocket;
+ std::unique_ptr<weld::Entry> m_xNamedPipe;
+ Link<weld::Widget*,void> m_aControlModificationLink;
+ DECL_LINK(RadioToggleHdl, weld::Toggleable&, void);
+ DECL_LINK(SpinModifyHdl, weld::SpinButton&, void);
+ DECL_LINK(EditModifyHdl, weld::Entry&, void);
+
+ public:
+ MySQLNativeSettings(weld::Widget* pParent, const Link<weld::Widget*,void>& rControlModificationLink);
+ void fillControls( std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList );
+ void fillWindows( std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList );
+
+ bool FillItemSet( SfxItemSet* rCoreAttrs );
+ void implInitControls( const SfxItemSet& _rSet );
+
+ bool canAdvance() const;
+ };
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/adminpages.cxx b/dbaccess/source/ui/dlg/adminpages.cxx
new file mode 100644
index 000000000..5f0eedbb0
--- /dev/null
+++ b/dbaccess/source/ui/dlg/adminpages.cxx
@@ -0,0 +1,278 @@
+/* -*- 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 "adminpages.hxx"
+#include <core_resource.hxx>
+#include <dbu_dlg.hxx>
+#include <IItemSetHelper.hxx>
+#include <strings.hrc>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <dsitems.hxx>
+#include "dsselect.hxx"
+#include "odbcconfig.hxx"
+#include "optionalboolitem.hxx"
+#include <sqlmessage.hxx>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <comphelper/types.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+namespace dbaui
+{
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::lang;
+ using namespace ::dbtools;
+
+ ISaveValueWrapper::~ISaveValueWrapper()
+ {
+ }
+
+ OGenericAdministrationPage::OGenericAdministrationPage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rId, const SfxItemSet& rAttrSet)
+ : SfxTabPage(pPage, pController, rUIXMLDescription, rId, &rAttrSet)
+ , m_abEnableRoadmap(false)
+ , m_pAdminDialog(nullptr)
+ , m_pItemSetHelper(nullptr)
+ {
+ SetExchangeSupport();
+
+ m_xContainer->set_size_request(m_xContainer->get_approximate_digit_width() * WIZARD_PAGE_X,
+ m_xContainer->get_text_height() * WIZARD_PAGE_Y);
+ }
+
+ DeactivateRC OGenericAdministrationPage::DeactivatePage(SfxItemSet* _pSet)
+ {
+ if (_pSet)
+ {
+ if (!prepareLeave())
+ return DeactivateRC::KeepPage;
+ FillItemSet(_pSet);
+ }
+
+ return DeactivateRC::LeavePage;
+ }
+
+ void OGenericAdministrationPage::Reset(const SfxItemSet* _rCoreAttrs)
+ {
+ implInitControls(*_rCoreAttrs, false);
+ }
+
+ void OGenericAdministrationPage::Activate()
+ {
+ BuilderPage::Activate();
+ OSL_ENSURE(m_pItemSetHelper,"NO ItemSetHelper set!");
+ if ( m_pItemSetHelper )
+ ActivatePage(*m_pItemSetHelper->getOutputSet());
+ }
+
+ void OGenericAdministrationPage::ActivatePage(const SfxItemSet& _rSet)
+ {
+ implInitControls(_rSet, true);
+ }
+
+ void OGenericAdministrationPage::getFlags(const SfxItemSet& _rSet, bool& _rValid, bool& _rReadonly)
+ {
+ const SfxBoolItem* pInvalid = _rSet.GetItem<SfxBoolItem>(DSID_INVALID_SELECTION);
+ _rValid = !pInvalid || !pInvalid->GetValue();
+ const SfxBoolItem* pReadonly = _rSet.GetItem<SfxBoolItem>(DSID_READONLY);
+ _rReadonly = !_rValid || (pReadonly && pReadonly->GetValue());
+ }
+
+ IMPL_LINK(OGenericAdministrationPage, OnControlModified, weld::Widget*, pCtrl, void)
+ {
+ callModifiedHdl(pCtrl);
+ }
+
+ IMPL_LINK(OGenericAdministrationPage, OnControlModifiedButtonClick, weld::Toggleable&, rCtrl, void)
+ {
+ callModifiedHdl(&rCtrl);
+ }
+
+ IMPL_LINK(OGenericAdministrationPage, OnControlEntryModifyHdl, weld::Entry&, rCtrl, void)
+ {
+ callModifiedHdl(&rCtrl);
+ }
+
+ IMPL_LINK(OGenericAdministrationPage, OnControlSpinButtonModifyHdl, weld::SpinButton&, rCtrl, void)
+ {
+ callModifiedHdl(&rCtrl);
+ }
+
+ bool OGenericAdministrationPage::getSelectedDataSource(OUString& _sReturn, OUString const & _sCurr)
+ {
+ // collect all ODBC data source names
+ std::set<OUString> aOdbcDatasources;
+ OOdbcEnumeration aEnumeration;
+ if (!aEnumeration.isLoaded())
+ {
+ // show an error message
+ OUString sError(DBA_RES(STR_COULD_NOT_LOAD_ODBC_LIB));
+ sError = sError.replaceFirst("#lib#", aEnumeration.getLibraryName());
+ std::unique_ptr<weld::MessageDialog> xDialog(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ sError));
+ xDialog->run();
+ return false;
+ }
+ else
+ {
+ aEnumeration.getDatasourceNames(aOdbcDatasources);
+ // execute the select dialog
+ ODatasourceSelectDialog aSelector(GetFrameWeld(), aOdbcDatasources);
+ if (!_sCurr.isEmpty())
+ aSelector.Select(_sCurr);
+ if (RET_OK == aSelector.run())
+ _sReturn = aSelector.GetSelected();
+ }
+ return true;
+ }
+
+ void OGenericAdministrationPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ std::vector< std::unique_ptr<ISaveValueWrapper> > aControlList;
+ if ( _bSaveValue )
+ {
+ fillControls(aControlList);
+ for( const auto& pValueWrapper : aControlList )
+ {
+ pValueWrapper->SaveValue();
+ }
+ }
+
+ if ( bReadonly )
+ {
+ fillWindows(aControlList);
+ for( const auto& pValueWrapper : aControlList )
+ {
+ pValueWrapper->Disable();
+ }
+ }
+ }
+
+ void OGenericAdministrationPage::initializePage()
+ {
+ OSL_ENSURE(m_pItemSetHelper,"NO ItemSetHelper set!");
+ if ( m_pItemSetHelper )
+ Reset(m_pItemSetHelper->getOutputSet());
+ }
+ bool OGenericAdministrationPage::commitPage( ::vcl::WizardTypes::CommitPageReason )
+ {
+ return true;
+ }
+ bool OGenericAdministrationPage::canAdvance() const
+ {
+ return true;
+ }
+ void OGenericAdministrationPage::fillBool( SfxItemSet& _rSet, const weld::CheckButton* pCheckBox, sal_uInt16 _nID, bool bOptionalBool, bool& _bChangedSomething, bool _bRevertValue )
+ {
+ if (!(pCheckBox && pCheckBox->get_state_changed_from_saved()))
+ return;
+
+ bool bValue = pCheckBox->get_active();
+ if ( _bRevertValue )
+ bValue = !bValue;
+
+ if (bOptionalBool)
+ {
+ OptionalBoolItem aValue( _nID );
+ if ( pCheckBox->get_state() != TRISTATE_INDET )
+ aValue.SetValue( bValue );
+ _rSet.Put( aValue );
+ }
+ else
+ _rSet.Put( SfxBoolItem( _nID, bValue ) );
+
+ _bChangedSomething = true;
+ }
+ void OGenericAdministrationPage::fillInt32(SfxItemSet& _rSet, const weld::SpinButton* pEdit, sal_uInt16 _nID, bool& _bChangedSomething)
+ {
+ if (pEdit && pEdit->get_value_changed_from_saved())
+ {
+ _rSet.Put(SfxInt32Item(_nID, pEdit->get_value()));
+ _bChangedSomething = true;
+ }
+ }
+ void OGenericAdministrationPage::fillString(SfxItemSet& _rSet, const weld::Entry* pEdit, sal_uInt16 _nID, bool& _bChangedSomething)
+ {
+ if (pEdit && pEdit->get_value_changed_from_saved())
+ {
+ _rSet.Put(SfxStringItem(_nID, pEdit->get_text().trim()));
+ _bChangedSomething = true;
+ }
+ }
+ void OGenericAdministrationPage::fillString(SfxItemSet& _rSet, const dbaui::OConnectionURLEdit* pEdit, sal_uInt16 _nID, bool& _bChangedSomething)
+ {
+ if (pEdit && pEdit->get_value_changed_from_saved())
+ {
+ _rSet.Put(SfxStringItem(_nID, pEdit->GetText().trim()));
+ _bChangedSomething = true;
+ }
+ }
+
+ IMPL_LINK_NOARG(OGenericAdministrationPage, OnTestConnectionButtonClickHdl, weld::Button&, void)
+ {
+ OSL_ENSURE(m_pAdminDialog,"No Admin dialog set! ->GPF");
+ bool bSuccess = false;
+ if ( !m_pAdminDialog )
+ return;
+
+ m_pAdminDialog->saveDatasource();
+ OGenericAdministrationPage::implInitControls(*m_pItemSetHelper->getOutputSet(), true);
+ bool bShowMessage = true;
+ try
+ {
+ std::pair< Reference<XConnection>,bool> aConnectionPair = m_pAdminDialog->createConnection();
+ bShowMessage = aConnectionPair.second;
+ bSuccess = aConnectionPair.first.is();
+ ::comphelper::disposeComponent(aConnectionPair.first);
+ }
+ catch(Exception&)
+ {
+ }
+ if ( bShowMessage )
+ {
+ MessageType eImage = MessageType::Info;
+ OUString aMessage,sTitle;
+ sTitle = DBA_RES(STR_CONNECTION_TEST);
+ if ( bSuccess )
+ {
+ aMessage = DBA_RES(STR_CONNECTION_SUCCESS);
+ }
+ else
+ {
+ eImage = MessageType::Error;
+ aMessage = DBA_RES(STR_CONNECTION_NO_SUCCESS);
+ }
+ OSQLMessageBox aMsg(GetFrameWeld(), sTitle, aMessage, MessBoxStyle::Ok, eImage);
+ aMsg.run();
+ }
+ if ( !bSuccess )
+ m_pAdminDialog->clearPassword();
+ }
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/adminpages.hxx b/dbaccess/source/ui/dlg/adminpages.hxx
new file mode 100644
index 000000000..de8265751
--- /dev/null
+++ b/dbaccess/source/ui/dlg/adminpages.hxx
@@ -0,0 +1,233 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/wizardmachine.hxx>
+#include <curledit.hxx>
+
+namespace dbaui
+{
+ /// helper class to wrap the savevalue and disable call
+ class SAL_NO_VTABLE ISaveValueWrapper
+ {
+ public:
+ virtual ~ISaveValueWrapper() = 0;
+ virtual void SaveValue() = 0;
+ virtual void Disable() = 0;
+ };
+
+ template < class T > class OSaveValueWidgetWrapper : public ISaveValueWrapper
+ {
+ T* m_pSaveValue;
+ public:
+ explicit OSaveValueWidgetWrapper(T* _pSaveValue) : m_pSaveValue(_pSaveValue)
+ { OSL_ENSURE(m_pSaveValue,"Illegal argument!"); }
+
+ virtual void SaveValue() override { m_pSaveValue->save_value(); }
+ virtual void Disable() override { m_pSaveValue->set_sensitive(false); }
+ };
+
+ template <> class OSaveValueWidgetWrapper<weld::Toggleable> : public ISaveValueWrapper
+ {
+ weld::Toggleable* m_pSaveValue;
+ public:
+ explicit OSaveValueWidgetWrapper(weld::Toggleable* _pSaveValue) : m_pSaveValue(_pSaveValue)
+ { OSL_ENSURE(m_pSaveValue,"Illegal argument!"); }
+
+ virtual void SaveValue() override { m_pSaveValue->save_state(); }
+ virtual void Disable() override { m_pSaveValue->set_sensitive(false); }
+ };
+
+ template <> class OSaveValueWidgetWrapper<dbaui::OConnectionURLEdit> : public ISaveValueWrapper
+ {
+ dbaui::OConnectionURLEdit* m_pSaveValue;
+ public:
+ explicit OSaveValueWidgetWrapper(dbaui::OConnectionURLEdit* _pSaveValue) : m_pSaveValue(_pSaveValue)
+ { OSL_ENSURE(m_pSaveValue,"Illegal argument!"); }
+
+ virtual void SaveValue() override { m_pSaveValue->save_value(); }
+ virtual void Disable() override { m_pSaveValue->set_sensitive(false); }
+ };
+
+ template <class T> class ODisableWidgetWrapper : public ISaveValueWrapper
+ {
+ T* m_pSaveValue;
+ public:
+ explicit ODisableWidgetWrapper(T* _pSaveValue) : m_pSaveValue(_pSaveValue)
+ { OSL_ENSURE(m_pSaveValue,"Illegal argument!"); }
+
+ virtual void SaveValue() override {}
+ virtual void Disable() override { m_pSaveValue->set_sensitive(false); }
+ };
+
+ // OGenericAdministrationPage
+ class IDatabaseSettingsDialog;
+ class IItemSetHelper;
+ class OGenericAdministrationPage :public SfxTabPage
+ ,public ::vcl::IWizardPageController
+ {
+ private:
+ Link<OGenericAdministrationPage const *, void> m_aModifiedHandler; /// to be called if something on the page has been modified
+ bool m_abEnableRoadmap;
+ protected:
+ IDatabaseSettingsDialog* m_pAdminDialog;
+ IItemSetHelper* m_pItemSetHelper;
+
+ css::uno::Reference< css::uno::XComponentContext >
+ m_xORB;
+ public:
+ OGenericAdministrationPage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rId, const SfxItemSet& rAttrSet);
+ /// set a handler which gets called every time something on the page has been modified
+ void SetModifiedHandler(const Link<OGenericAdministrationPage const *, void>& _rHandler) { m_aModifiedHandler = _rHandler; }
+
+ /** Sets the ParentDialog
+ @param _pAdminDialog
+ the ParentDialog
+ @param _pItemSetHelper
+ the itemset helper
+ */
+ void SetAdminDialog(IDatabaseSettingsDialog* _pDialog,IItemSetHelper* _pItemSetHelper)
+ {
+ OSL_ENSURE(_pDialog && _pItemSetHelper,"Values are NULL!");
+ m_pAdminDialog = _pDialog;
+ m_pItemSetHelper = _pItemSetHelper;
+ }
+
+ /** Sets the ServiceFactory
+ @param _rxORB
+ The service factory.
+ */
+ void SetServiceFactory(const css::uno::Reference< css::uno::XComponentContext >& rxORB)
+ {
+ m_xORB = rxORB;
+ }
+
+ /** opens a dialog filled with all data sources available for this type and
+ returns the selected on.
+ @param _eType
+ The type for which the data source dialog should be opened.
+ @param _sReturn
+ <OUT/> contains the selected name.
+ @return
+ <FALSE/> if an error occurred, otherwise <TRUE/>
+ */
+ bool getSelectedDataSource(OUString& _sReturn, OUString const & _sCurr);
+
+ // svt::IWizardPageController
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+ virtual bool canAdvance() const override;
+
+ void SetRoadmapStateValue( bool _bDoEnable ) { m_abEnableRoadmap = _bDoEnable; }
+ bool GetRoadmapStateValue() const { return m_abEnableRoadmap; }
+
+ protected:
+ /// default implementation: call FillItemSet, call prepareLeave,
+ virtual DeactivateRC DeactivatePage(SfxItemSet* pSet) override;
+ /// default implementation: call implInitControls with the given item set and _bSaveValue = sal_False
+ virtual void Reset(const SfxItemSet* _rCoreAttrs) override;
+ /// default implementation: call implInitControls with the given item set and _bSaveValue = sal_True
+ virtual void ActivatePage(const SfxItemSet& _rSet) override;
+
+ // BuilderPage overridables
+ virtual void Activate() override;
+
+ protected:
+ virtual void callModifiedHdl(weld::Widget* /*pControl*/ = nullptr) { m_aModifiedHandler.Call(this); }
+
+ /// called from within DeactivatePage. The page is allowed to be deactivated if this method returns sal_True
+ virtual bool prepareLeave() { return true; }
+
+ /** called from within Reset and ActivatePage, use to initialize the controls with the items from the given set
+ @param _bSaveValue if set to sal_True, the implementation should call SaveValue on all relevant controls
+ */
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue);
+
+ /// analyze the invalid and the readonly flag which may be present in the set
+ static void getFlags(const SfxItemSet& _rSet, bool& _rValid, bool& _rReadonly);
+
+ /** will be called inside <method>implInitControls</method> to save the value if necessary
+ @param _rControlList
+ The list must be filled with the controls.
+ It is not allowed to clear the list before pushing data into it.
+ */
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) = 0;
+
+ /** will be called inside <method>implInitControls</method> to disable if necessary
+ @param _rControlList
+ The list must be filled with the controls.
+ It is not allowed to clear the list before pushing data into it.
+ */
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) = 0;
+
+ public:
+ /** fills the Boolean value into the item set when the value changed.
+ @param _rSet
+ The item set where to put the new value into.
+ @param _pCheckBox
+ The check box which is checked.
+ @param _nID
+ The id in the itemset to set with the new value.
+ @param _bChangedSomething
+ <TRUE/> if something changed otherwise <FALSE/>
+ @param _bRevertValue
+ set to <TRUE/> if the display value should be reverted before putting it into the set
+ */
+ static void fillBool(SfxItemSet& _rSet, const weld::CheckButton* pCheckBox, sal_uInt16 _nID, bool bOptionalBool, bool& _bChangedSomething, bool _bRevertValue = false);
+
+ /** fills the int value into the item set when the value changed.
+ @param _rSet
+ The item set where to put the new value into.
+ @param _pEdit
+ The check box which is checked.
+ @param _nID
+ The id in the itemset to set with the new value.
+ @param _bChangedSomething
+ <TRUE/> if something changed otherwise <FALSE/>
+ */
+ static void fillInt32(SfxItemSet& _rSet,const weld::SpinButton* pEdit,sal_uInt16 _nID, bool& _bChangedSomething);
+
+ /** fills the String value into the item set when the value changed.
+ @param _rSet
+ The item set where to put the new value into.
+ @param _pEdit
+ The check box which is checked.
+ @param _nID
+ The id in the itemset to set with the new value.
+ @param _bChangedSomething
+ <TRUE/> if something changed otherwise <FALSE/>
+ */
+ static void fillString(SfxItemSet& _rSet,const weld::Entry* pEdit,sal_uInt16 _nID, bool& _bChangedSomething);
+ static void fillString(SfxItemSet& _rSet,const dbaui::OConnectionURLEdit* pEdit,sal_uInt16 _nID, bool& _bChangedSomething);
+
+ protected:
+ /** This link be used for controls where the tabpage does not need to take any special action when the control
+ is modified. The implementation just calls callModifiedHdl.
+ */
+ DECL_LINK(OnControlModified, weld::Widget*, void);
+ DECL_LINK(OnControlEntryModifyHdl, weld::Entry&, void);
+ DECL_LINK(OnControlSpinButtonModifyHdl, weld::SpinButton&, void);
+ DECL_LINK(OnControlModifiedButtonClick, weld::Toggleable&, void);
+ DECL_LINK(OnTestConnectionButtonClickHdl, weld::Button&, void);
+ };
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/adodatalinks.cxx b/dbaccess/source/ui/dlg/adodatalinks.cxx
new file mode 100644
index 000000000..82af63688
--- /dev/null
+++ b/dbaccess/source/ui/dlg/adodatalinks.cxx
@@ -0,0 +1,141 @@
+/* -*- 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 .
+ */
+
+
+#if defined(_WIN32)
+// LO/windows.h conflict
+#undef WB_LEFT
+#undef WB_RIGHT
+#include <msdasc.h>
+
+#include <comphelper/scopeguard.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
+#include <systools/win32/comtools.hxx>
+#include <systools/win32/oleauto.hxx>
+
+#include <initguid.h>
+#include <adoid.h>
+#include <adoint.h>
+
+#include "adodatalinks.hxx"
+
+namespace {
+
+OUString PromptNew(sal_IntPtr hWnd)
+{
+ try
+ {
+ // Initialize COM
+ sal::systools::CoInitializeGuard aGuard(COINIT_APARTMENTTHREADED);
+
+ // Instantiate DataLinks object.
+ sal::systools::COMReference<IDataSourceLocator> dlPrompt;
+ dlPrompt.CoCreateInstance(CLSID_DataLinks, //clsid -- Data Links UI
+ nullptr, //pUnkOuter
+ CLSCTX_INPROC_SERVER); //dwClsContext
+
+ sal::systools::ThrowIfFailed(dlPrompt->put_hWnd(hWnd), "put_hWnd failed");
+
+ // Prompt for connection information.
+ sal::systools::COMReference<IDispatch> piDispatch;
+ sal::systools::ThrowIfFailed(dlPrompt->PromptNew(&piDispatch), "PromptNew failed");
+ sal::systools::COMReference<ADOConnection> piTmpConnection(piDispatch,
+ sal::systools::COM_QUERY_THROW);
+
+ sal::systools::BStr _result;
+ sal::systools::ThrowIfFailed(piTmpConnection->get_ConnectionString(&_result),
+ "get_ConnectionString failed");
+
+ return OUString(_result);
+ }
+ catch (const sal::systools::ComError&)
+ {
+ return OUString();
+ }
+}
+
+OUString PromptEdit(sal_IntPtr hWnd, OUString const & connstr)
+{
+ try
+ {
+ // Initialize COM
+ sal::systools::CoInitializeGuard aGuard(COINIT_APARTMENTTHREADED);
+
+ sal::systools::COMReference<ADOConnection> piTmpConnection;
+ piTmpConnection.CoCreateInstance(CLSID_CADOConnection, nullptr, CLSCTX_INPROC_SERVER);
+
+ sal::systools::ThrowIfFailed(
+ piTmpConnection->put_ConnectionString(sal::systools::BStr(connstr)),
+ "put_ConnectionString failed");
+
+ // Instantiate DataLinks object.
+ sal::systools::COMReference<IDataSourceLocator> dlPrompt;
+ dlPrompt.CoCreateInstance(CLSID_DataLinks, //clsid -- Data Links UI
+ nullptr, //pUnkOuter
+ CLSCTX_INPROC_SERVER); //dwClsContext
+
+ sal::systools::ThrowIfFailed(dlPrompt->put_hWnd(hWnd), "put_hWnd failed");
+
+ try
+ {
+ // Prompt for connection information.
+ IDispatch* piDispatch = piTmpConnection.get();
+ VARIANT_BOOL pbSuccess;
+ sal::systools::ThrowIfFailed(dlPrompt->PromptEdit(&piDispatch, &pbSuccess),
+ "PromptEdit failed");
+ if (!pbSuccess) //if user press cancel then sal_False == pbSuccess
+ return connstr;
+ }
+ catch (const sal::systools::ComError&)
+ {
+ // Prompt for new connection information.
+ sal::systools::COMReference<IDispatch> piDispatch;
+ sal::systools::ThrowIfFailed(dlPrompt->PromptNew(&piDispatch), "PromptNew failed");
+ piTmpConnection.set(piDispatch, sal::systools::COM_QUERY_THROW);
+ }
+
+ sal::systools::BStr _result;
+ sal::systools::ThrowIfFailed(piTmpConnection->get_ConnectionString(&_result),
+ "get_ConnectionString failed");
+
+ return OUString(_result);
+ }
+ catch (const sal::systools::ComError&)
+ {
+ return connstr;
+ }
+}
+
+}
+
+OUString getAdoDatalink(sal_IntPtr hWnd,OUString const & oldLink)
+{
+ OUString dataLink;
+ if (!oldLink.isEmpty())
+ {
+ dataLink=PromptEdit(hWnd,oldLink);
+ }
+ else
+ dataLink=PromptNew(hWnd);
+ return dataLink;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/adodatalinks.hxx b/dbaccess/source/ui/dlg/adodatalinks.hxx
new file mode 100644
index 000000000..6b753f62e
--- /dev/null
+++ b/dbaccess/source/ui/dlg/adodatalinks.hxx
@@ -0,0 +1,26 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+OUString getAdoDatalink(sal_IntPtr hWnd, OUString const& oldLink);
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/adtabdlg.cxx b/dbaccess/source/ui/dlg/adtabdlg.cxx
new file mode 100644
index 000000000..809b483cd
--- /dev/null
+++ b/dbaccess/source/ui/dlg/adtabdlg.cxx
@@ -0,0 +1,467 @@
+/* -*- 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 <adtabdlg.hxx>
+#include <tools/diagnose_ex.h>
+#include <core_resource.hxx>
+#include <strings.hrc>
+#include <connectivity/dbtools.hxx>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/sdb/application/DatabaseObject.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <imageprovider.hxx>
+#include <comphelper/containermultiplexer.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <algorithm>
+
+// slot ids
+using namespace dbaui;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+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 dbtools;
+
+TableObjectListFacade::~TableObjectListFacade()
+{
+}
+
+namespace {
+
+class TableListFacade : public ::cppu::BaseMutex
+ , public TableObjectListFacade
+ , public ::comphelper::OContainerListener
+{
+ OTableTreeListBox& m_rTableList;
+ Reference< XConnection > m_xConnection;
+ ::rtl::Reference< comphelper::OContainerListenerAdapter>
+ m_pContainerListener;
+ bool m_bAllowViews;
+
+public:
+ TableListFacade(OTableTreeListBox& _rTableList, const Reference< XConnection >& _rxConnection)
+ : ::comphelper::OContainerListener(m_aMutex)
+ ,m_rTableList( _rTableList )
+ ,m_xConnection( _rxConnection )
+ ,m_bAllowViews(true)
+ {
+ }
+ virtual ~TableListFacade() override;
+
+private:
+ virtual void updateTableObjectList( bool _bAllowViews ) override;
+ virtual OUString getSelectedName( OUString& _out_rAliasName ) const override;
+ virtual bool isLeafSelected() const override;
+ // OContainerListener
+ virtual void _elementInserted( const css::container::ContainerEvent& _rEvent ) override;
+ virtual void _elementRemoved( const css::container::ContainerEvent& _rEvent ) override;
+ virtual void _elementReplaced( const css::container::ContainerEvent& _rEvent ) override;
+};
+
+}
+
+TableListFacade::~TableListFacade()
+{
+ if ( m_pContainerListener.is() )
+ m_pContainerListener->dispose();
+}
+
+OUString TableListFacade::getSelectedName( OUString& _out_rAliasName ) const
+{
+ weld::TreeView& rTableList = m_rTableList.GetWidget();
+ std::unique_ptr<weld::TreeIter> xEntry(rTableList.make_iterator());
+
+ if (!rTableList.get_selected(xEntry.get()))
+ return OUString();
+
+ OUString aCatalog, aSchema, aTableName;
+ std::unique_ptr<weld::TreeIter> xSchema(rTableList.make_iterator(xEntry.get()));
+ if (rTableList.iter_parent(*xSchema))
+ {
+ auto xAll = m_rTableList.getAllObjectsEntry();
+ if (!xAll || !xSchema->equal(*xAll))
+ {
+ std::unique_ptr<weld::TreeIter> xCatalog(rTableList.make_iterator(xSchema.get()));
+ if (rTableList.iter_parent(*xCatalog))
+ {
+ if (!xAll || !xCatalog->equal(*xAll))
+ aCatalog = rTableList.get_text(*xCatalog, 0);
+ }
+ aSchema = rTableList.get_text(*xSchema, 0);
+ }
+ }
+ aTableName = rTableList.get_text(*xEntry, 0);
+
+ OUString aComposedName;
+ try
+ {
+ Reference< XDatabaseMetaData > xMeta( m_xConnection->getMetaData(), UNO_SET_THROW );
+ if ( aCatalog.isEmpty()
+ && !aSchema.isEmpty()
+ && xMeta->supportsCatalogsInDataManipulation()
+ && !xMeta->supportsSchemasInDataManipulation() )
+ {
+ aCatalog = aSchema;
+ aSchema.clear();
+ }
+
+ aComposedName = ::dbtools::composeTableName(
+ xMeta, aCatalog, aSchema, aTableName, false, ::dbtools::EComposeRule::InDataManipulation );
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ _out_rAliasName = aTableName;
+ return aComposedName;
+}
+
+void TableListFacade::_elementInserted( const container::ContainerEvent& /*_rEvent*/ )
+{
+ updateTableObjectList(m_bAllowViews);
+}
+
+void TableListFacade::_elementRemoved( const container::ContainerEvent& /*_rEvent*/ )
+{
+ updateTableObjectList(m_bAllowViews);
+}
+
+void TableListFacade::_elementReplaced( const container::ContainerEvent& /*_rEvent*/ )
+{
+}
+
+void TableListFacade::updateTableObjectList( bool _bAllowViews )
+{
+ m_bAllowViews = _bAllowViews;
+ weld::TreeView& rTableList = m_rTableList.GetWidget();
+ rTableList.clear();
+ try
+ {
+ Reference< XTablesSupplier > xTableSupp( m_xConnection, UNO_QUERY_THROW );
+
+ Reference< XViewsSupplier > xViewSupp;
+ Reference< XNameAccess > xTables, xViews;
+ Sequence< OUString > sTables, sViews;
+
+ xTables = xTableSupp->getTables();
+ if ( xTables.is() )
+ {
+ if ( !m_pContainerListener.is() )
+ {
+ Reference< XContainer> xContainer(xTables,uno::UNO_QUERY);
+ if ( xContainer.is() )
+ m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
+ }
+ sTables = xTables->getElementNames();
+ }
+
+ xViewSupp.set( xTableSupp, UNO_QUERY );
+ if ( xViewSupp.is() )
+ {
+ xViews = xViewSupp->getViews();
+ if ( xViews.is() )
+ sViews = xViews->getElementNames();
+ }
+
+ // if no views are allowed remove the views also out the table name filter
+ if ( !_bAllowViews )
+ {
+ const OUString* pTableBegin = sTables.getConstArray();
+ const OUString* pTableEnd = pTableBegin + sTables.getLength();
+ std::vector< OUString > aTables(pTableBegin,pTableEnd);
+
+ const OUString* pViewBegin = sViews.getConstArray();
+ const OUString* pViewEnd = pViewBegin + sViews.getLength();
+ ::comphelper::UStringMixEqual aEqualFunctor;
+ for(;pViewBegin != pViewEnd;++pViewBegin)
+ aTables.erase(std::remove_if(aTables.begin(),aTables.end(),
+ [&aEqualFunctor, pViewBegin](const OUString& lhs)
+ { return aEqualFunctor(lhs, *pViewBegin); } )
+ , aTables.end());
+ sTables = Sequence< OUString>(aTables.data(), aTables.size());
+ sViews = Sequence< OUString>();
+ }
+
+ m_rTableList.UpdateTableList( m_xConnection, sTables, sViews );
+
+ std::unique_ptr<weld::TreeIter> xEntry(rTableList.make_iterator());
+ bool bEntry = rTableList.get_iter_first(*xEntry);
+ while (bEntry && rTableList.iter_has_child(*xEntry))
+ {
+ rTableList.expand_row(*xEntry);
+ bEntry = rTableList.iter_next(*xEntry);
+ }
+ if (bEntry)
+ rTableList.select(*xEntry);
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+bool TableListFacade::isLeafSelected() const
+{
+ weld::TreeView& rTableList = m_rTableList.GetWidget();
+ std::unique_ptr<weld::TreeIter> xEntry(rTableList.make_iterator());
+ const bool bEntry = rTableList.get_selected(xEntry.get());
+ return bEntry && !rTableList.iter_has_child(*xEntry);
+}
+
+namespace {
+
+class QueryListFacade : public ::cppu::BaseMutex
+ , public TableObjectListFacade
+ , public ::comphelper::OContainerListener
+{
+ weld::TreeView& m_rQueryList;
+ Reference< XConnection > m_xConnection;
+ ::rtl::Reference< comphelper::OContainerListenerAdapter>
+ m_pContainerListener;
+
+public:
+ QueryListFacade( weld::TreeView& _rQueryList, const Reference< XConnection >& _rxConnection )
+ : ::comphelper::OContainerListener(m_aMutex)
+ ,m_rQueryList( _rQueryList )
+ ,m_xConnection( _rxConnection )
+ {
+ }
+ virtual ~QueryListFacade() override;
+
+private:
+ virtual void updateTableObjectList( bool _bAllowViews ) override;
+ virtual OUString getSelectedName( OUString& _out_rAliasName ) const override;
+ virtual bool isLeafSelected() const override;
+ // OContainerListener
+ virtual void _elementInserted( const css::container::ContainerEvent& _rEvent ) override;
+ virtual void _elementRemoved( const css::container::ContainerEvent& _rEvent ) override;
+ virtual void _elementReplaced( const css::container::ContainerEvent& _rEvent ) override;
+};
+
+}
+
+QueryListFacade::~QueryListFacade()
+{
+ if ( m_pContainerListener.is() )
+ m_pContainerListener->dispose();
+}
+
+void QueryListFacade::_elementInserted( const container::ContainerEvent& _rEvent )
+{
+ OUString sName;
+ if ( _rEvent.Accessor >>= sName )
+ {
+ OUString aQueryImage(ImageProvider::getDefaultImageResourceID(css::sdb::application::DatabaseObject::QUERY));
+ m_rQueryList.append("", sName, aQueryImage);
+ }
+}
+
+void QueryListFacade::_elementRemoved( const container::ContainerEvent& /*_rEvent*/ )
+{
+ updateTableObjectList(true);
+}
+
+void QueryListFacade::_elementReplaced( const container::ContainerEvent& /*_rEvent*/ )
+{
+}
+
+void QueryListFacade::updateTableObjectList( bool /*_bAllowViews*/ )
+{
+ m_rQueryList.clear();
+ try
+ {
+ OUString aQueryImage(ImageProvider::getDefaultImageResourceID(css::sdb::application::DatabaseObject::QUERY));
+
+ Reference< XQueriesSupplier > xSuppQueries( m_xConnection, UNO_QUERY_THROW );
+ Reference< XNameAccess > xQueries( xSuppQueries->getQueries(), UNO_SET_THROW );
+ if ( !m_pContainerListener.is() )
+ {
+ Reference< XContainer> xContainer(xQueries,UNO_QUERY_THROW);
+ m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
+ }
+ const Sequence< OUString > aQueryNames = xQueries->getElementNames();
+
+ for ( auto const & name : aQueryNames )
+ m_rQueryList.append("", name, aQueryImage);
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+OUString QueryListFacade::getSelectedName( OUString& _out_rAliasName ) const
+{
+ OUString sSelected;
+ std::unique_ptr<weld::TreeIter> xEntry(m_rQueryList.make_iterator());
+ const bool bEntry = m_rQueryList.get_selected(xEntry.get());
+ if (bEntry)
+ sSelected = _out_rAliasName = m_rQueryList.get_text(*xEntry, 0);
+ return sSelected;
+}
+
+bool QueryListFacade::isLeafSelected() const
+{
+ std::unique_ptr<weld::TreeIter> xEntry(m_rQueryList.make_iterator());
+ const bool bEntry = m_rQueryList.get_selected(xEntry.get());
+ return bEntry && !m_rQueryList.iter_has_child(*xEntry);
+
+}
+
+OAddTableDlg::OAddTableDlg(weld::Window* pParent, IAddTableDialogContext& _rContext)
+ : GenericDialogController(pParent, "dbaccess/ui/tablesjoindialog.ui", "TablesJoinDialog")
+ , m_rContext(_rContext)
+ , m_xCaseTables(m_xBuilder->weld_radio_button("tables"))
+ , m_xCaseQueries(m_xBuilder->weld_radio_button("queries"))
+ // false means: do not show any buttons
+ , m_xTableList(new OTableTreeListBox(m_xBuilder->weld_tree_view("tablelist"), false))
+ , m_xQueryList(m_xBuilder->weld_tree_view("querylist"))
+ , m_xAddButton(m_xBuilder->weld_button("add"))
+ , m_xCloseButton(m_xBuilder->weld_button("close"))
+{
+ weld::TreeView& rTableList = m_xTableList->GetWidget();
+ Size aSize(rTableList.get_approximate_digit_width() * 23,
+ rTableList.get_height_rows(15));
+ rTableList.set_size_request(aSize.Width(), aSize.Height());
+ m_xQueryList->set_size_request(aSize.Width(), aSize.Height());
+
+ m_xCaseTables->connect_toggled(LINK(this, OAddTableDlg, OnTypeSelected));
+ m_xAddButton->connect_clicked( LINK( this, OAddTableDlg, AddClickHdl ) );
+ m_xCloseButton->connect_clicked( LINK( this, OAddTableDlg, CloseClickHdl ) );
+ rTableList.connect_row_activated( LINK( this, OAddTableDlg, TableListDoubleClickHdl ) );
+ rTableList.connect_changed( LINK( this, OAddTableDlg, TableListSelectHdl ) );
+ m_xQueryList->connect_row_activated( LINK( this, OAddTableDlg, TableListDoubleClickHdl ) );
+ m_xQueryList->connect_changed( LINK( this, OAddTableDlg, TableListSelectHdl ) );
+
+ rTableList.set_selection_mode(SelectionMode::Single);
+ m_xTableList->SuppressEmptyFolders();
+
+ m_xQueryList->set_selection_mode(SelectionMode::Single);
+
+ if ( !m_rContext.allowQueries() )
+ {
+ m_xCaseTables->hide();
+ m_xCaseQueries->hide();
+ }
+
+ m_xDialog->set_title(getDialogTitleForContext(m_rContext));
+}
+
+OAddTableDlg::~OAddTableDlg()
+{
+}
+
+void OAddTableDlg::impl_switchTo( ObjectList _eList )
+{
+ switch ( _eList )
+ {
+ case Tables:
+ m_xTableList->GetWidget().show(); m_xCaseTables->set_active(true);
+ m_xQueryList->hide(); m_xCaseQueries->set_active(false);
+ m_xCurrentList.reset( new TableListFacade( *m_xTableList, m_rContext.getConnection() ) );
+ m_xTableList->GetWidget().grab_focus();
+ break;
+
+ case Queries:
+ m_xTableList->GetWidget().hide(); m_xCaseTables->set_active(false);
+ m_xQueryList->show(); m_xCaseQueries->set_active(true);
+ m_xCurrentList.reset( new QueryListFacade( *m_xQueryList, m_rContext.getConnection() ) );
+ m_xQueryList->grab_focus();
+ break;
+ }
+ m_xCurrentList->updateTableObjectList( m_rContext.allowViews() );
+}
+
+void OAddTableDlg::Update()
+{
+ if (!m_xCurrentList)
+ impl_switchTo( Tables );
+ else
+ m_xCurrentList->updateTableObjectList( m_rContext.allowViews() );
+}
+
+IMPL_LINK_NOARG( OAddTableDlg, AddClickHdl, weld::Button&, void )
+{
+ TableListDoubleClickHdl(m_xTableList->GetWidget());
+}
+
+IMPL_LINK_NOARG(OAddTableDlg, TableListDoubleClickHdl, weld::TreeView&, bool)
+{
+ if ( impl_isAddAllowed() )
+ {
+ if ( m_xCurrentList->isLeafSelected() )
+ {
+ OUString sSelectedName, sAliasName;
+ sSelectedName = m_xCurrentList->getSelectedName( sAliasName );
+
+ m_rContext.addTableWindow( sSelectedName, sAliasName );
+ }
+ if ( !impl_isAddAllowed() )
+ m_xDialog->response(RET_CLOSE);
+ }
+ return true;
+}
+
+IMPL_LINK_NOARG( OAddTableDlg, TableListSelectHdl, weld::TreeView&, void )
+{
+ m_xAddButton->set_sensitive( m_xCurrentList->isLeafSelected() );
+}
+
+IMPL_LINK_NOARG( OAddTableDlg, CloseClickHdl, weld::Button&, void )
+{
+ m_xDialog->response(RET_CLOSE);
+}
+
+IMPL_LINK_NOARG(OAddTableDlg, OnTypeSelected, weld::Toggleable&, void)
+{
+ if ( m_xCaseTables->get_active() )
+ impl_switchTo( Tables );
+ else
+ impl_switchTo( Queries );
+}
+
+void OAddTableDlg::OnClose()
+{
+ m_rContext.onWindowClosing();
+}
+
+bool OAddTableDlg::impl_isAddAllowed()
+{
+ return m_rContext.allowAddition();
+}
+
+OUString OAddTableDlg::getDialogTitleForContext( IAddTableDialogContext const & _rContext )
+{
+ OUString sTitle;
+
+ if ( _rContext.allowQueries() )
+ sTitle = DBA_RES( STR_ADD_TABLE_OR_QUERY );
+ else
+ sTitle = DBA_RES( STR_ADD_TABLES );
+
+ return sTitle;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/advancedsettings.cxx b/dbaccess/source/ui/dlg/advancedsettings.cxx
new file mode 100644
index 000000000..40964305a
--- /dev/null
+++ b/dbaccess/source/ui/dlg/advancedsettings.cxx
@@ -0,0 +1,472 @@
+/* -*- 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 <memory>
+
+#include "advancedsettings.hxx"
+#include <advancedsettingsdlg.hxx>
+#include <dsitems.hxx>
+#include "DbAdminImpl.hxx"
+#include "DriverSettings.hxx"
+#include "optionalboolitem.hxx"
+
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/stritem.hxx>
+
+namespace dbaui
+{
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::XComponentContext;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::sdbc::XConnection;
+ using ::com::sun::star::sdbc::XDriver;
+
+ // SpecialSettingsPage
+ struct BooleanSettingDesc
+ {
+ std::unique_ptr<weld::CheckButton>& xControl; // the dialog's control which displays this setting
+ OString sControlId; // the widget name of the control in the .ui
+ sal_uInt16 nItemId; // the ID of the item (in an SfxItemSet) which corresponds to this setting
+ bool bInvertedDisplay; // true if and only if the checkbox is checked when the item is sal_False, and vice versa
+ bool bOptionalBool; // type is OptionalBool
+ };
+
+ // SpecialSettingsPage
+ SpecialSettingsPage::SpecialSettingsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs, const DataSourceMetaData& _rDSMeta)
+ : OGenericAdministrationPage(pPage, pController, "dbaccess/ui/specialsettingspage.ui", "SpecialSettingsPage", _rCoreAttrs)
+ , m_aBooleanSettings {
+ { m_xIsSQL92Check, "usesql92", DSID_SQL92CHECK, false, false },
+ { m_xAppendTableAlias, "append", DSID_APPEND_TABLE_ALIAS, false, false },
+ { m_xAsBeforeCorrelationName, "useas", DSID_AS_BEFORE_CORRNAME, false, false },
+ { m_xEnableOuterJoin, "useoj", DSID_ENABLEOUTERJOIN, false, false },
+ { m_xIgnoreDriverPrivileges, "ignoreprivs", DSID_IGNOREDRIVER_PRIV, false, false },
+ { m_xParameterSubstitution, "replaceparams", DSID_PARAMETERNAMESUBST, false, false },
+ { m_xSuppressVersionColumn, "displayver", DSID_SUPPRESSVERSIONCL, true, false },
+ { m_xCatalog, "usecatalogname", DSID_CATALOG, false, false },
+ { m_xSchema, "useschemaname", DSID_SCHEMA, false, false },
+ { m_xIndexAppendix, "createindex", DSID_INDEXAPPENDIX, false, false },
+ { m_xDosLineEnds, "eol", DSID_DOSLINEENDS, false, false },
+ { m_xCheckRequiredFields, "inputchecks", DSID_CHECK_REQUIRED_FIELDS, false, false },
+ { m_xIgnoreCurrency, "ignorecurrency", DSID_IGNORECURRENCY, false, false },
+ { m_xEscapeDateTime, "useodbcliterals", DSID_ESCAPE_DATETIME, false, false },
+ { m_xPrimaryKeySupport, "primarykeys", DSID_PRIMARY_KEY_SUPPORT, false, false },
+ { m_xRespectDriverResultSetType, "resulttype", DSID_RESPECTRESULTSETTYPE, false, false } }
+ , m_bHasBooleanComparisonMode( _rDSMeta.getFeatureSet().has( DSID_BOOLEANCOMPARISON ) )
+ , m_bHasMaxRowScan( _rDSMeta.getFeatureSet().has( DSID_MAX_ROW_SCAN ) )
+ {
+ const FeatureSet& rFeatures( _rDSMeta.getFeatureSet() );
+ // create all the check boxes for the boolean settings
+ for (auto & booleanSetting : m_aBooleanSettings)
+ {
+ sal_uInt16 nItemId = booleanSetting.nItemId;
+ if ( rFeatures.has( nItemId ) )
+ {
+ // check whether this must be a tristate check box
+ const SfxPoolItem& rItem = _rCoreAttrs.Get(nItemId);
+ booleanSetting.bOptionalBool = dynamic_cast<const OptionalBoolItem*>(&rItem) != nullptr;
+ booleanSetting.xControl = m_xBuilder->weld_check_button(booleanSetting.sControlId);
+ if (booleanSetting.bOptionalBool)
+ booleanSetting.xControl->connect_toggled(LINK(this, SpecialSettingsPage, OnTriStateToggleHdl));
+ else
+ booleanSetting.xControl->connect_toggled(LINK(this, SpecialSettingsPage, OnToggleHdl));
+ booleanSetting.xControl->show();
+ }
+ }
+
+ // create the controls for the boolean comparison mode
+ if ( m_bHasBooleanComparisonMode )
+ {
+ m_xBooleanComparisonModeLabel = m_xBuilder->weld_label("comparisonft");
+ m_xBooleanComparisonMode = m_xBuilder->weld_combo_box("comparison");
+ m_xBooleanComparisonMode->connect_changed(LINK(this, SpecialSettingsPage, BooleanComparisonSelectHdl));
+ m_xBooleanComparisonModeLabel->show();
+ m_xBooleanComparisonMode->show();
+ }
+ // create the controls for the max row scan
+ if ( m_bHasMaxRowScan )
+ {
+ m_xMaxRowScanLabel = m_xBuilder->weld_label("rowsft");
+ m_xMaxRowScan = m_xBuilder->weld_spin_button("rows");
+ m_xMaxRowScan->connect_value_changed(LINK(this, OGenericAdministrationPage, OnControlSpinButtonModifyHdl));
+ m_xMaxRowScanLabel->show();
+ m_xMaxRowScan->show();
+ }
+ }
+
+ IMPL_LINK(SpecialSettingsPage, OnTriStateToggleHdl, weld::Toggleable&, rToggle, void)
+ {
+ auto eOldState = m_aTriStates[&rToggle];
+ switch (eOldState)
+ {
+ case TRISTATE_INDET:
+ rToggle.set_state(TRISTATE_FALSE);
+ break;
+ case TRISTATE_TRUE:
+ rToggle.set_state(TRISTATE_INDET);
+ break;
+ case TRISTATE_FALSE:
+ rToggle.set_state(TRISTATE_TRUE);
+ break;
+ }
+ m_aTriStates[&rToggle] = rToggle.get_state();
+ OnToggleHdl(rToggle);
+ }
+
+ IMPL_LINK(SpecialSettingsPage, OnToggleHdl, weld::Toggleable&, rBtn, void)
+ {
+ if (&rBtn == m_xAppendTableAlias.get() && m_xAsBeforeCorrelationName)
+ {
+ // make m_xAsBeforeCorrelationName depend on m_xAppendTableAlias
+ m_xAsBeforeCorrelationName->set_sensitive(m_xAppendTableAlias->get_active());
+ }
+ OnControlModifiedButtonClick(rBtn);
+ }
+
+ IMPL_LINK(SpecialSettingsPage, BooleanComparisonSelectHdl, weld::ComboBox&, rControl, void)
+ {
+ callModifiedHdl(&rControl);
+ }
+
+ SpecialSettingsPage::~SpecialSettingsPage()
+ {
+ }
+
+ void SpecialSettingsPage::fillWindows( std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList )
+ {
+ if ( m_bHasBooleanComparisonMode )
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xBooleanComparisonModeLabel.get()));
+ }
+ if ( m_bHasMaxRowScan )
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xMaxRowScanLabel.get()));
+ }
+ }
+
+ void SpecialSettingsPage::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ for (auto const& booleanSetting : m_aBooleanSettings)
+ {
+ if (booleanSetting.xControl)
+ {
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(booleanSetting.xControl.get()));
+ }
+ }
+
+ if ( m_bHasBooleanComparisonMode )
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xBooleanComparisonMode.get()));
+ if ( m_bHasMaxRowScan )
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::SpinButton>(m_xMaxRowScan.get()));
+ }
+
+ void SpecialSettingsPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags( _rSet, bValid, bReadonly );
+
+ if ( !bValid )
+ {
+ OGenericAdministrationPage::implInitControls(_rSet, _bSaveValue);
+ return;
+ }
+
+ m_aTriStates.clear();
+
+ // the boolean items
+ for (auto const& booleanSetting : m_aBooleanSettings)
+ {
+ if (!booleanSetting.xControl)
+ continue;
+
+ bool bTriState = false;
+
+ std::optional<bool> aValue;
+
+ const SfxPoolItem* pItem = _rSet.GetItem<SfxPoolItem>(booleanSetting.nItemId);
+ if (const SfxBoolItem *pBoolItem = dynamic_cast<const SfxBoolItem*>( pItem) )
+ {
+ aValue = pBoolItem->GetValue();
+ }
+ else if (const OptionalBoolItem *pOptionalItem = dynamic_cast<const OptionalBoolItem*>( pItem) )
+ {
+ aValue = pOptionalItem->GetFullValue();
+ bTriState = true;
+ }
+ else
+ OSL_FAIL( "SpecialSettingsPage::implInitControls: unknown boolean item type!" );
+
+ if ( !aValue )
+ {
+ booleanSetting.xControl->set_state(TRISTATE_INDET);
+ }
+ else
+ {
+ bool bValue = *aValue;
+ if ( booleanSetting.bInvertedDisplay )
+ bValue = !bValue;
+ booleanSetting.xControl->set_active(bValue);
+ }
+ if (bTriState)
+ m_aTriStates[booleanSetting.xControl.get()] = booleanSetting.xControl->get_state();
+ }
+
+ if (m_xAppendTableAlias && m_xAsBeforeCorrelationName)
+ {
+ // make m_xAsBeforeCorrelationName depend on m_xAppendTableAlias
+ m_xAsBeforeCorrelationName->set_sensitive(m_xAppendTableAlias->get_active());
+ }
+
+ // the non-boolean items
+ if ( m_bHasBooleanComparisonMode )
+ {
+ const SfxInt32Item* pBooleanComparison = _rSet.GetItem<SfxInt32Item>(DSID_BOOLEANCOMPARISON);
+ m_xBooleanComparisonMode->set_active(static_cast<sal_uInt16>(pBooleanComparison->GetValue()));
+ }
+
+ if ( m_bHasMaxRowScan )
+ {
+ const SfxInt32Item* pMaxRowScan = _rSet.GetItem<SfxInt32Item>(DSID_MAX_ROW_SCAN);
+ m_xMaxRowScan->set_value(pMaxRowScan->GetValue());
+ }
+
+ OGenericAdministrationPage::implInitControls(_rSet, _bSaveValue);
+ }
+
+ bool SpecialSettingsPage::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = false;
+
+ // the boolean items
+ for (auto const& booleanSetting : m_aBooleanSettings)
+ {
+ if (!booleanSetting.xControl)
+ continue;
+ fillBool(*_rSet, booleanSetting.xControl.get(), booleanSetting.nItemId, booleanSetting.bOptionalBool, bChangedSomething, booleanSetting.bInvertedDisplay);
+ }
+
+ // the non-boolean items
+ if ( m_bHasBooleanComparisonMode )
+ {
+ if (m_xBooleanComparisonMode->get_value_changed_from_saved())
+ {
+ _rSet->Put(SfxInt32Item(DSID_BOOLEANCOMPARISON, m_xBooleanComparisonMode->get_active()));
+ bChangedSomething = true;
+ }
+ }
+ if ( m_bHasMaxRowScan )
+ {
+ fillInt32(*_rSet,m_xMaxRowScan.get(),DSID_MAX_ROW_SCAN,bChangedSomething);
+ }
+ return bChangedSomething;
+ }
+
+ // GeneratedValuesPage
+ GeneratedValuesPage::GeneratedValuesPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs)
+ : OGenericAdministrationPage(pPage, pController, "dbaccess/ui/generatedvaluespage.ui", "GeneratedValuesPage", _rCoreAttrs)
+ , m_xAutoRetrievingEnabled(m_xBuilder->weld_check_button("autoretrieve"))
+ , m_xGrid(m_xBuilder->weld_widget("grid"))
+ , m_xAutoIncrementLabel(m_xBuilder->weld_label("statementft"))
+ , m_xAutoIncrement(m_xBuilder->weld_entry("statement"))
+ , m_xAutoRetrievingLabel(m_xBuilder->weld_label("queryft"))
+ , m_xAutoRetrieving(m_xBuilder->weld_entry("query"))
+ {
+ m_xAutoRetrievingEnabled->connect_toggled(LINK(this, GeneratedValuesPage, OnAutoToggleHdl));
+ m_xAutoIncrement->connect_changed(LINK(this, OGenericAdministrationPage, OnControlEntryModifyHdl));
+ m_xAutoRetrieving->connect_changed(LINK(this, OGenericAdministrationPage, OnControlEntryModifyHdl));
+ }
+
+ IMPL_LINK(GeneratedValuesPage, OnAutoToggleHdl, weld::Toggleable&, rBtn, void)
+ {
+ m_xGrid->set_sensitive(rBtn.get_active());
+ OnControlModifiedButtonClick(rBtn);
+ }
+
+ GeneratedValuesPage::~GeneratedValuesPage()
+ {
+ }
+
+ void GeneratedValuesPage::fillWindows( std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList )
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Widget>(m_xContainer.get()));
+ }
+
+ void GeneratedValuesPage::fillControls( std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList )
+ {
+ _rControlList.emplace_back( new OSaveValueWidgetWrapper<weld::Toggleable>( m_xAutoRetrievingEnabled.get() ) );
+ _rControlList.emplace_back( new OSaveValueWidgetWrapper<weld::Entry>( m_xAutoIncrement.get() ) );
+ _rControlList.emplace_back( new OSaveValueWidgetWrapper<weld::Entry>( m_xAutoRetrieving.get() ) );
+ }
+
+ void GeneratedValuesPage::implInitControls( const SfxItemSet& _rSet, bool _bSaveValue )
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ // collect the items
+ const SfxStringItem* pAutoIncrementItem = _rSet.GetItem<SfxStringItem>(DSID_AUTOINCREMENTVALUE);
+ const SfxStringItem* pAutoRetrieveValueItem = _rSet.GetItem<SfxStringItem>(DSID_AUTORETRIEVEVALUE);
+ const SfxBoolItem* pAutoRetrieveEnabledItem = _rSet.GetItem<SfxBoolItem>(DSID_AUTORETRIEVEENABLED);
+
+ // forward the values to the controls
+ if (bValid)
+ {
+ bool bEnabled = pAutoRetrieveEnabledItem->GetValue();
+ m_xAutoRetrievingEnabled->set_active(bEnabled);
+
+ m_xAutoIncrement->set_text(pAutoIncrementItem->GetValue());
+ m_xAutoIncrement->save_value();
+ m_xAutoRetrieving->set_text(pAutoRetrieveValueItem->GetValue());
+ m_xAutoRetrieving->save_value();
+ }
+ OGenericAdministrationPage::implInitControls( _rSet, _bSaveValue );
+ }
+
+ bool GeneratedValuesPage::FillItemSet(SfxItemSet* _rSet)
+ {
+ bool bChangedSomething = false;
+
+ fillString( *_rSet, m_xAutoIncrement.get(), DSID_AUTOINCREMENTVALUE, bChangedSomething );
+ fillBool( *_rSet, m_xAutoRetrievingEnabled.get(), DSID_AUTORETRIEVEENABLED, false, bChangedSomething );
+ fillString( *_rSet, m_xAutoRetrieving.get(), DSID_AUTORETRIEVEVALUE, bChangedSomething );
+
+ return bChangedSomething;
+ }
+
+ // AdvancedSettingsDialog
+ AdvancedSettingsDialog::AdvancedSettingsDialog(weld::Window* pParent, SfxItemSet* _pItems,
+ const Reference< XComponentContext >& _rxContext, const Any& _aDataSourceName )
+ : SfxTabDialogController(pParent, "dbaccess/ui/advancedsettingsdialog.ui", "AdvancedSettingsDialog", _pItems)
+ {
+ m_pImpl.reset(new ODbDataSourceAdministrationHelper(_rxContext, m_xDialog.get(), pParent, this));
+ m_pImpl->setDataSourceOrName(_aDataSourceName);
+ Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
+ m_pImpl->translateProperties(xDatasource, *_pItems);
+ SetInputSet(_pItems);
+ // propagate this set as our new input set and reset the example set
+ m_xExampleSet.reset(new SfxItemSet(*GetInputSetImpl()));
+
+ const OUString eType = dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(*_pItems);
+
+ DataSourceMetaData aMeta( eType );
+ const FeatureSet& rFeatures( aMeta.getFeatureSet() );
+
+ // auto-generated values?
+ if (rFeatures.supportsGeneratedValues())
+ AddTabPage("generated", ODriversSettings::CreateGeneratedValuesPage, nullptr);
+ else
+ RemoveTabPage("generated");
+
+ // any "special settings"?
+ if (rFeatures.supportsAnySpecialSetting())
+ AddTabPage("special", ODriversSettings::CreateSpecialSettingsPage, nullptr);
+ else
+ RemoveTabPage("special");
+
+ // remove the reset button - it's meaning is much too ambiguous in this dialog
+ RemoveResetButton();
+ }
+
+ AdvancedSettingsDialog::~AdvancedSettingsDialog()
+ {
+ SetInputSet(nullptr);
+ }
+
+ bool AdvancedSettingsDialog::doesHaveAnyAdvancedSettings( const OUString& _sURL )
+ {
+ DataSourceMetaData aMeta( _sURL );
+ const FeatureSet& rFeatures( aMeta.getFeatureSet() );
+ return rFeatures.supportsGeneratedValues() || rFeatures.supportsAnySpecialSetting();
+ }
+
+ short AdvancedSettingsDialog::Ok()
+ {
+ short nRet = SfxTabDialogController::Ok();
+ if ( nRet == RET_OK )
+ {
+ m_xExampleSet->Put(*GetOutputItemSet());
+ m_pImpl->saveChanges(*m_xExampleSet);
+ }
+ return nRet;
+ }
+
+ void AdvancedSettingsDialog::PageCreated(const OString& rId, SfxTabPage& _rPage)
+ {
+ // register ourself as modified listener
+ static_cast<OGenericAdministrationPage&>(_rPage).SetServiceFactory( getORB() );
+ static_cast<OGenericAdministrationPage&>(_rPage).SetAdminDialog(this,this);
+ SfxTabDialogController::PageCreated(rId, _rPage);
+ }
+
+ const SfxItemSet* AdvancedSettingsDialog::getOutputSet() const
+ {
+ return m_xExampleSet.get();
+ }
+
+ SfxItemSet* AdvancedSettingsDialog::getWriteOutputSet()
+ {
+ return m_xExampleSet.get();
+ }
+
+ std::pair< Reference< XConnection >, bool > AdvancedSettingsDialog::createConnection()
+ {
+ return m_pImpl->createConnection();
+ }
+
+ Reference< XComponentContext > AdvancedSettingsDialog::getORB() const
+ {
+ return m_pImpl->getORB();
+ }
+
+ Reference< XDriver > AdvancedSettingsDialog::getDriver()
+ {
+ return m_pImpl->getDriver();
+ }
+
+ OUString AdvancedSettingsDialog::getDatasourceType(const SfxItemSet& _rSet) const
+ {
+ return dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(_rSet);
+ }
+
+ void AdvancedSettingsDialog::clearPassword()
+ {
+ m_pImpl->clearPassword();
+ }
+
+ void AdvancedSettingsDialog::setTitle(const OUString& _sTitle)
+ {
+ m_xDialog->set_title(_sTitle);
+ }
+
+ void AdvancedSettingsDialog::enableConfirmSettings( bool ) {}
+
+ void AdvancedSettingsDialog::saveDatasource()
+ {
+ PrepareLeaveCurrentPage();
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/advancedsettings.hxx b/dbaccess/source/ui/dlg/advancedsettings.hxx
new file mode 100644
index 000000000..38f100612
--- /dev/null
+++ b/dbaccess/source/ui/dlg/advancedsettings.hxx
@@ -0,0 +1,116 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "adminpages.hxx"
+#include <dsmeta.hxx>
+#include <vector>
+
+namespace dbaui
+{
+ struct BooleanSettingDesc;
+
+ // SpecialSettingsPage
+ // implements the "Special Settings" page of the advanced database settings
+ class SpecialSettingsPage final : public OGenericAdministrationPage
+ {
+ std::unique_ptr<weld::CheckButton> m_xIsSQL92Check;
+ std::unique_ptr<weld::CheckButton> m_xAppendTableAlias;
+ std::unique_ptr<weld::CheckButton> m_xAsBeforeCorrelationName;
+ std::unique_ptr<weld::CheckButton> m_xEnableOuterJoin;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreDriverPrivileges;
+ std::unique_ptr<weld::CheckButton> m_xParameterSubstitution;
+ std::unique_ptr<weld::CheckButton> m_xSuppressVersionColumn;
+ std::unique_ptr<weld::CheckButton> m_xCatalog;
+ std::unique_ptr<weld::CheckButton> m_xSchema;
+ std::unique_ptr<weld::CheckButton> m_xIndexAppendix;
+ std::unique_ptr<weld::CheckButton> m_xDosLineEnds;
+ std::unique_ptr<weld::CheckButton> m_xCheckRequiredFields;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreCurrency;
+ std::unique_ptr<weld::CheckButton> m_xEscapeDateTime;
+ std::unique_ptr<weld::CheckButton> m_xPrimaryKeySupport;
+ std::unique_ptr<weld::CheckButton> m_xRespectDriverResultSetType;
+
+ std::unique_ptr<weld::Label> m_xBooleanComparisonModeLabel;
+ std::unique_ptr<weld::ComboBox> m_xBooleanComparisonMode;
+
+ std::unique_ptr<weld::Label> m_xMaxRowScanLabel;
+ std::unique_ptr<weld::SpinButton> m_xMaxRowScan;
+
+ std::map<weld::Toggleable*, TriState> m_aTriStates;
+
+ std::vector< BooleanSettingDesc > m_aBooleanSettings;
+
+ bool m_bHasBooleanComparisonMode;
+ bool m_bHasMaxRowScan;
+
+ public:
+ DECL_LINK(OnToggleHdl, weld::Toggleable&, void);
+ DECL_LINK(OnTriStateToggleHdl, weld::Toggleable&, void);
+
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+
+ SpecialSettingsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs, const DataSourceMetaData& _rDSMeta);
+ virtual ~SpecialSettingsPage() override;
+
+ private:
+ // OGenericAdministrationPage overridables
+ virtual void implInitControls (const SfxItemSet& _rSet, bool _bSaveValue ) override;
+
+ // <method>OGenericAdministrationPage::fillControls</method>
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ // <method>OGenericAdministrationPage::fillWindows</method>
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ DECL_LINK(BooleanComparisonSelectHdl, weld::ComboBox&, void);
+ };
+
+ // GeneratedValuesPage
+ class GeneratedValuesPage final : public OGenericAdministrationPage
+ {
+ std::unique_ptr<weld::CheckButton> m_xAutoRetrievingEnabled;
+ std::unique_ptr<weld::Widget> m_xGrid;
+ std::unique_ptr<weld::Label> m_xAutoIncrementLabel;
+ std::unique_ptr<weld::Entry> m_xAutoIncrement;
+ std::unique_ptr<weld::Label> m_xAutoRetrievingLabel;
+ std::unique_ptr<weld::Entry> m_xAutoRetrieving;
+
+ public:
+ virtual bool FillItemSet (SfxItemSet* _rCoreAttrs) override;
+
+ GeneratedValuesPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs);
+ virtual ~GeneratedValuesPage() override;
+
+ private:
+ DECL_LINK(OnAutoToggleHdl, weld::Toggleable&, void);
+
+ // subclasses must override this, but it isn't pure virtual
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+
+ // <method>OGenericAdministrationPage::fillControls</method>
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ // <method>OGenericAdministrationPage::fillWindows</method>
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dbadmin.cxx b/dbaccess/source/ui/dlg/dbadmin.cxx
new file mode 100644
index 000000000..c6ca46f75
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dbadmin.cxx
@@ -0,0 +1,433 @@
+/* -*- 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 "ConnectionPage.hxx"
+#include "DbAdminImpl.hxx"
+#include "DriverSettings.hxx"
+#include "adminpages.hxx"
+#include <dbadmin.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <core_resource.hxx>
+#include <strings.hrc>
+#include <dsitems.hxx>
+#include "dsnItem.hxx"
+#include "optionalboolitem.hxx"
+#include <stringlistitem.hxx>
+
+#include <unotools/confignode.hxx>
+
+namespace dbaui
+{
+using namespace com::sun::star::uno;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::util;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+
+// ODbAdminDialog
+ODbAdminDialog::ODbAdminDialog(weld::Window* pParent,
+ SfxItemSet const * _pItems,
+ const Reference< XComponentContext >& _rxContext)
+ : SfxTabDialogController(pParent, "dbaccess/ui/admindialog.ui", "AdminDialog", _pItems)
+ , m_sMainPageID("advanced")
+{
+ m_pImpl.reset(new ODbDataSourceAdministrationHelper(_rxContext, m_xDialog.get(), pParent, this));
+
+ // add the initial tab page
+ AddTabPage(m_sMainPageID, OConnectionTabPage::Create, nullptr);
+
+ // remove the reset button - it's meaning is much too ambiguous in this dialog
+ RemoveResetButton();
+}
+
+ODbAdminDialog::~ODbAdminDialog()
+{
+ SetInputSet(nullptr);
+}
+
+short ODbAdminDialog::Ok()
+{
+ SfxTabDialogController::Ok();
+ return ( AR_LEAVE_MODIFIED == implApplyChanges() ) ? RET_OK : RET_CANCEL;
+ // TODO : AR_ERROR is not handled correctly, we always close the dialog here
+}
+
+void ODbAdminDialog::PageCreated(const OString& rId, SfxTabPage& _rPage)
+{
+ // register ourself as modified listener
+ static_cast<OGenericAdministrationPage&>(_rPage).SetServiceFactory( getORB() );
+ static_cast<OGenericAdministrationPage&>(_rPage).SetAdminDialog(this,this);
+
+ SfxTabDialogController::PageCreated(rId, _rPage);
+}
+
+void ODbAdminDialog::addDetailPage(const OString& rPageId, TranslateId pTextId, CreateTabPage pCreateFunc)
+{
+ AddTabPage(rPageId, DBA_RES(pTextId), pCreateFunc);
+}
+
+void ODbAdminDialog::impl_selectDataSource(const css::uno::Any& _aDataSourceName)
+{
+ m_pImpl->setDataSourceOrName(_aDataSourceName);
+ Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
+ impl_resetPages( xDatasource );
+
+ const DbuTypeCollectionItem* pCollectionItem = dynamic_cast<const DbuTypeCollectionItem*>(getOutputSet()->GetItem(DSID_TYPECOLLECTION));
+ assert(pCollectionItem && "must exist");
+ ::dbaccess::ODsnTypeCollection* pCollection = pCollectionItem->getCollection();
+ ::dbaccess::DATASOURCE_TYPE eType = pCollection->determineType(getDatasourceType(*getOutputSet()));
+
+ // and insert the new ones
+ switch ( eType )
+ {
+ case ::dbaccess::DST_DBASE:
+ addDetailPage("dbase", STR_PAGETITLE_ADVANCED, ODriversSettings::CreateDbase);
+ break;
+
+ case ::dbaccess::DST_ADO:
+ addDetailPage("ado", STR_PAGETITLE_ADVANCED, ODriversSettings::CreateAdo);
+ break;
+
+ case ::dbaccess::DST_FLAT:
+ addDetailPage("text", STR_PAGETITLE_ADVANCED, ODriversSettings::CreateText);
+ break;
+
+ case ::dbaccess::DST_ODBC:
+ addDetailPage("odbc", STR_PAGETITLE_ADVANCED, ODriversSettings::CreateODBC);
+ break;
+
+ case ::dbaccess::DST_MYSQL_ODBC:
+ addDetailPage("mysqlodbc", STR_PAGETITLE_ADVANCED, ODriversSettings::CreateMySQLODBC);
+ break;
+
+ case ::dbaccess::DST_MYSQL_JDBC:
+ addDetailPage("mysqljdbc", STR_PAGETITLE_ADVANCED, ODriversSettings::CreateMySQLJDBC);
+ break;
+
+ case ::dbaccess::DST_ORACLE_JDBC:
+ addDetailPage("oraclejdbc", STR_PAGETITLE_ADVANCED, ODriversSettings::CreateOracleJDBC);
+ break;
+
+ case ::dbaccess::DST_LDAP:
+ addDetailPage("ldap",STR_PAGETITLE_ADVANCED,ODriversSettings::CreateLDAP);
+ break;
+ case ::dbaccess::DST_USERDEFINE1: /// first user defined driver
+ case ::dbaccess::DST_USERDEFINE2:
+ case ::dbaccess::DST_USERDEFINE3:
+ case ::dbaccess::DST_USERDEFINE4:
+ case ::dbaccess::DST_USERDEFINE5:
+ case ::dbaccess::DST_USERDEFINE6:
+ case ::dbaccess::DST_USERDEFINE7:
+ case ::dbaccess::DST_USERDEFINE8:
+ case ::dbaccess::DST_USERDEFINE9:
+ case ::dbaccess::DST_USERDEFINE10:
+ {
+ OUString aTitle(DBA_RES(STR_PAGETITLE_ADVANCED));
+ AddTabPage("user" + OString::number(eType - dbaccess::DST_USERDEFINE1 + 1), aTitle, ODriversSettings::CreateUser);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void ODbAdminDialog::impl_resetPages(const Reference< XPropertySet >& _rxDatasource)
+{
+ // the selection is valid if and only if we have a datasource now
+ GetInputSetImpl()->Put(SfxBoolItem(DSID_INVALID_SELECTION, !_rxDatasource.is()));
+ // (sal_False tells the tab pages to disable and reset all their controls, which is different
+ // from "just set them to readonly")
+
+ // reset the pages
+
+ // prevent flicker
+ m_xDialog->freeze();
+
+ // remove all items which relate to indirect properties from the input set
+ // (without this, the following may happen: select an arbitrary data source where some indirect properties
+ // are set. Select another data source of the same type, where the indirect props are not set (yet). Then,
+ // the indirect property values of the first ds are shown in the second ds ...)
+ const ODbDataSourceAdministrationHelper::MapInt2String& rMap = m_pImpl->getIndirectProperties();
+ for (auto const& elem : rMap)
+ GetInputSetImpl()->ClearItem( static_cast<sal_uInt16>(elem.first) );
+
+ // extract all relevant data from the property set of the data source
+ m_pImpl->translateProperties(_rxDatasource, *GetInputSetImpl());
+
+ // reset the example set
+ m_xExampleSet.reset(new SfxItemSet(*GetInputSetImpl()));
+
+ // special case: MySQL Native does not have the generic "advanced" page
+
+ const DbuTypeCollectionItem* pCollectionItem = dynamic_cast<const DbuTypeCollectionItem*>(getOutputSet()->GetItem(DSID_TYPECOLLECTION));
+ assert(pCollectionItem && "must exist");
+ ::dbaccess::ODsnTypeCollection* pCollection = pCollectionItem->getCollection();
+ if ( pCollection->determineType(getDatasourceType( *m_xExampleSet )) == ::dbaccess::DST_MYSQL_NATIVE )
+ {
+ OString sMySqlNative("mysqlnative");
+ AddTabPage(sMySqlNative, DBA_RES(STR_PAGETITLE_CONNECTION), ODriversSettings::CreateMySQLNATIVE);
+ RemoveTabPage("advanced");
+ m_sMainPageID = sMySqlNative;
+ }
+
+ SetCurPageId(m_sMainPageID);
+ SfxTabPage* pConnectionPage = GetTabPage(m_sMainPageID);
+ if ( pConnectionPage )
+ pConnectionPage->Reset(GetInputSetImpl());
+ // if this is NULL, the page has not been created yet, which means we're called before the
+ // dialog was displayed (probably from inside the ctor)
+
+ m_xDialog->thaw();
+}
+
+void ODbAdminDialog::setTitle(const OUString& rTitle)
+{
+ m_xDialog->set_title(rTitle);
+}
+
+void ODbAdminDialog::enableConfirmSettings( bool ) {}
+
+void ODbAdminDialog::saveDatasource()
+{
+ PrepareLeaveCurrentPage();
+}
+
+ODbAdminDialog::ApplyResult ODbAdminDialog::implApplyChanges()
+{
+ if (!PrepareLeaveCurrentPage())
+ { // the page did not allow us to leave
+ return AR_KEEP;
+ }
+
+ if ( !m_pImpl->saveChanges(*m_xExampleSet) )
+ return AR_KEEP;
+
+ return AR_LEAVE_MODIFIED;
+}
+
+void ODbAdminDialog::selectDataSource(const css::uno::Any& _aDataSourceName)
+{
+ impl_selectDataSource(_aDataSourceName);
+}
+
+const SfxItemSet* ODbAdminDialog::getOutputSet() const
+{
+ return GetExampleSet();
+}
+
+SfxItemSet* ODbAdminDialog::getWriteOutputSet()
+{
+ return m_xExampleSet.get();
+}
+
+std::pair< Reference<XConnection>,bool> ODbAdminDialog::createConnection()
+{
+ return m_pImpl->createConnection();
+}
+
+Reference< XComponentContext > ODbAdminDialog::getORB() const
+{
+ return m_pImpl->getORB();
+}
+
+Reference< XDriver > ODbAdminDialog::getDriver()
+{
+ return m_pImpl->getDriver();
+}
+
+OUString ODbAdminDialog::getDatasourceType(const SfxItemSet& _rSet) const
+{
+ return dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(_rSet);
+}
+
+void ODbAdminDialog::clearPassword()
+{
+ m_pImpl->clearPassword();
+}
+
+void ODbAdminDialog::createItemSet(std::unique_ptr<SfxItemSet>& _rpSet, rtl::Reference<SfxItemPool>& _rpPool, std::vector<SfxPoolItem*>*& _rpDefaults, ::dbaccess::ODsnTypeCollection* _pTypeCollection)
+{
+ // just to be sure...
+ _rpSet = nullptr;
+ _rpPool = nullptr;
+ _rpDefaults = nullptr;
+
+ const OUString sFilterAll( "%" );
+ // create and initialize the defaults
+ _rpDefaults = new std::vector<SfxPoolItem*>(DSID_LAST_ITEM_ID - DSID_FIRST_ITEM_ID + 1);
+ SfxPoolItem** pCounter = _rpDefaults->data(); // want to modify this without affecting the out param _rppDefaults
+ *pCounter++ = new SfxStringItem(DSID_NAME, OUString());
+ *pCounter++ = new SfxStringItem(DSID_ORIGINALNAME, OUString());
+ *pCounter++ = new SfxStringItem(DSID_CONNECTURL, OUString());
+ *pCounter++ = new OStringListItem(DSID_TABLEFILTER, Sequence< OUString >(&sFilterAll, 1));
+ *pCounter++ = new DbuTypeCollectionItem(DSID_TYPECOLLECTION, _pTypeCollection);
+ *pCounter++ = new SfxBoolItem(DSID_INVALID_SELECTION, false);
+ *pCounter++ = new SfxBoolItem(DSID_READONLY, false);
+ *pCounter++ = new SfxStringItem(DSID_USER, OUString());
+ *pCounter++ = new SfxStringItem(DSID_PASSWORD, OUString());
+ *pCounter++ = new SfxStringItem(DSID_ADDITIONALOPTIONS, OUString());
+ *pCounter++ = new SfxStringItem(DSID_CHARSET, OUString());
+ *pCounter++ = new SfxBoolItem(DSID_PASSWORDREQUIRED, false);
+ *pCounter++ = new SfxBoolItem(DSID_SHOWDELETEDROWS, false);
+ *pCounter++ = new SfxBoolItem(DSID_ALLOWLONGTABLENAMES, false);
+ *pCounter++ = new SfxStringItem(DSID_JDBCDRIVERCLASS, OUString());
+ *pCounter++ = new SfxStringItem(DSID_FIELDDELIMITER, OUString(','));
+ *pCounter++ = new SfxStringItem(DSID_TEXTDELIMITER, OUString('"'));
+ *pCounter++ = new SfxStringItem(DSID_DECIMALDELIMITER, OUString('.'));
+ *pCounter++ = new SfxStringItem(DSID_THOUSANDSDELIMITER, OUString());
+ *pCounter++ = new SfxStringItem(DSID_TEXTFILEEXTENSION, "txt");
+ *pCounter++ = new SfxBoolItem(DSID_TEXTFILEHEADER, true);
+ *pCounter++ = new SfxBoolItem(DSID_PARAMETERNAMESUBST, false);
+ *pCounter++ = new SfxInt32Item(DSID_CONN_PORTNUMBER, 8100);
+ *pCounter++ = new SfxBoolItem(DSID_SUPPRESSVERSIONCL, false);
+ *pCounter++ = new SfxBoolItem(DSID_CONN_SHUTSERVICE, false);
+ *pCounter++ = new SfxInt32Item(DSID_CONN_DATAINC, 20);
+ *pCounter++ = new SfxInt32Item(DSID_CONN_CACHESIZE, 20);
+ *pCounter++ = new SfxStringItem(DSID_CONN_CTRLUSER, OUString());
+ *pCounter++ = new SfxStringItem(DSID_CONN_CTRLPWD, OUString());
+ *pCounter++ = new SfxBoolItem(DSID_USECATALOG, false);
+ *pCounter++ = new SfxStringItem(DSID_CONN_HOSTNAME, OUString());
+ *pCounter++ = new SfxStringItem(DSID_CONN_LDAP_BASEDN, OUString());
+ *pCounter++ = new SfxInt32Item(DSID_CONN_LDAP_PORTNUMBER, 389);
+ *pCounter++ = new SfxInt32Item(DSID_CONN_LDAP_ROWCOUNT, 100);
+ *pCounter++ = new SfxBoolItem(DSID_SQL92CHECK, false);
+ *pCounter++ = new SfxStringItem(DSID_AUTOINCREMENTVALUE, OUString());
+ *pCounter++ = new SfxStringItem(DSID_AUTORETRIEVEVALUE, OUString());
+ *pCounter++ = new SfxBoolItem(DSID_AUTORETRIEVEENABLED, false);
+ *pCounter++ = new SfxBoolItem(DSID_APPEND_TABLE_ALIAS, false);
+ *pCounter++ = new SfxInt32Item(DSID_MYSQL_PORTNUMBER, 3306);
+ *pCounter++ = new SfxBoolItem(DSID_IGNOREDRIVER_PRIV, true);
+ *pCounter++ = new SfxInt32Item(DSID_BOOLEANCOMPARISON, 0);
+ *pCounter++ = new SfxInt32Item(DSID_ORACLE_PORTNUMBER, 1521);
+ *pCounter++ = new SfxBoolItem(DSID_ENABLEOUTERJOIN, true);
+ *pCounter++ = new SfxBoolItem(DSID_CATALOG, true);
+ *pCounter++ = new SfxBoolItem(DSID_SCHEMA, true);
+ *pCounter++ = new SfxBoolItem(DSID_INDEXAPPENDIX, true);
+ *pCounter++ = new SfxBoolItem(DSID_CONN_LDAP_USESSL, false);
+ *pCounter++ = new SfxStringItem(DSID_DOCUMENT_URL, OUString());
+ *pCounter++ = new SfxBoolItem(DSID_DOSLINEENDS, false);
+ *pCounter++ = new SfxStringItem(DSID_DATABASENAME, OUString());
+ *pCounter++ = new SfxBoolItem(DSID_AS_BEFORE_CORRNAME, false);
+ *pCounter++ = new SfxBoolItem(DSID_CHECK_REQUIRED_FIELDS, true);
+ *pCounter++ = new SfxBoolItem(DSID_IGNORECURRENCY, false);
+ *pCounter++ = new SfxStringItem(DSID_CONN_SOCKET, OUString());
+ *pCounter++ = new SfxBoolItem(DSID_ESCAPE_DATETIME, true);
+ *pCounter++ = new SfxStringItem(DSID_NAMED_PIPE, OUString());
+ *pCounter++ = new OptionalBoolItem( DSID_PRIMARY_KEY_SUPPORT );
+ *pCounter++ = new SfxInt32Item(DSID_MAX_ROW_SCAN, 100);
+ *pCounter++ = new SfxBoolItem( DSID_RESPECTRESULTSETTYPE,false );
+
+ // create the pool
+ static SfxItemInfo const aItemInfos[DSID_LAST_ITEM_ID - DSID_FIRST_ITEM_ID + 1] =
+ {
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ {0,false},
+ };
+
+ OSL_ENSURE(SAL_N_ELEMENTS(aItemInfos) == DSID_LAST_ITEM_ID,"Invalid Ids!");
+ _rpPool = new SfxItemPool("DSAItemPool", DSID_FIRST_ITEM_ID, DSID_LAST_ITEM_ID,
+ aItemInfos, _rpDefaults);
+ _rpPool->FreezeIdRanges();
+
+ // and, finally, the set
+ _rpSet.reset(new SfxItemSet(*_rpPool));
+}
+
+void ODbAdminDialog::destroyItemSet(std::unique_ptr<SfxItemSet>& _rpSet, rtl::Reference<SfxItemPool>& _rpPool, std::vector<SfxPoolItem*>*& _rpDefaults)
+{
+ // _first_ delete the set (referring the pool)
+ _rpSet.reset();
+
+ // delete the pool
+ if (_rpPool)
+ {
+ _rpPool->ReleaseDefaults(true);
+ // the "true" means delete the items, too
+ _rpPool = nullptr;
+ }
+
+ // reset the defaults ptr
+ _rpDefaults = nullptr;
+ // no need to explicitly delete the defaults, this has been done by the ReleaseDefaults
+}
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dbfindex.cxx b/dbaccess/source/ui/dlg/dbfindex.cxx
new file mode 100644
index 000000000..89f74ab72
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dbfindex.cxx
@@ -0,0 +1,430 @@
+/* -*- 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 "dbfindex.hxx"
+#include <comphelper/processfactory.hxx>
+#include <osl/file.hxx>
+#include <osl/thread.hxx>
+#include <tools/config.hxx>
+#include <osl/diagnose.h>
+#include <unotools/localfilehelper.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/pathoptions.hxx>
+#include <ucbhelper/content.hxx>
+#include <svl/filenotation.hxx>
+#include <rtl/strbuf.hxx>
+
+namespace dbaui
+{
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::svt;
+
+constexpr OStringLiteral aGroupIdent("dBase III");
+
+
+ODbaseIndexDialog::ODbaseIndexDialog(weld::Window * pParent, const OUString& aDataSrcName)
+ : GenericDialogController(pParent, "dbaccess/ui/dbaseindexdialog.ui", "DBaseIndexDialog")
+ , m_aDSN(aDataSrcName)
+ , m_xPB_OK(m_xBuilder->weld_button("ok"))
+ , m_xCB_Tables(m_xBuilder->weld_combo_box("table"))
+ , m_xIndexes(m_xBuilder->weld_widget("frame"))
+ , m_xLB_TableIndexes(m_xBuilder->weld_tree_view("tableindex"))
+ , m_xLB_FreeIndexes(m_xBuilder->weld_tree_view("freeindex"))
+ , m_xAdd(m_xBuilder->weld_button("add"))
+ , m_xRemove(m_xBuilder->weld_button("remove"))
+ , m_xAddAll(m_xBuilder->weld_button("addall"))
+ , m_xRemoveAll(m_xBuilder->weld_button("removeall"))
+{
+ int nWidth = m_xLB_TableIndexes->get_approximate_digit_width() * 18;
+ int nHeight = m_xLB_TableIndexes->get_height_rows(10);
+ m_xLB_TableIndexes->set_size_request(nWidth, nHeight);
+ m_xLB_FreeIndexes->set_size_request(nWidth, nHeight);
+
+ m_xCB_Tables->connect_changed( LINK(this, ODbaseIndexDialog, TableSelectHdl) );
+ m_xAdd->connect_clicked( LINK(this, ODbaseIndexDialog, AddClickHdl) );
+ m_xRemove->connect_clicked( LINK(this, ODbaseIndexDialog, RemoveClickHdl) );
+ m_xAddAll->connect_clicked( LINK(this, ODbaseIndexDialog, AddAllClickHdl) );
+ m_xRemoveAll->connect_clicked( LINK(this, ODbaseIndexDialog, RemoveAllClickHdl) );
+ m_xPB_OK->connect_clicked( LINK(this, ODbaseIndexDialog, OKClickHdl) );
+
+ m_xLB_FreeIndexes->connect_changed( LINK(this, ODbaseIndexDialog, OnListEntrySelected) );
+ m_xLB_TableIndexes->connect_changed( LINK(this, ODbaseIndexDialog, OnListEntrySelected) );
+
+ Init();
+ SetCtrls();
+}
+
+ODbaseIndexDialog::~ODbaseIndexDialog()
+{
+}
+
+void ODbaseIndexDialog::checkButtons()
+{
+ m_xAdd->set_sensitive(0 != m_xLB_FreeIndexes->count_selected_rows());
+ m_xAddAll->set_sensitive(0 != m_xLB_FreeIndexes->n_children());
+
+ m_xRemove->set_sensitive(0 != m_xLB_TableIndexes->count_selected_rows());
+ m_xRemoveAll->set_sensitive(0 != m_xLB_TableIndexes->n_children());
+}
+
+OTableIndex ODbaseIndexDialog::implRemoveIndex(const OUString& _rName, TableIndexList& _rList, weld::TreeView& _rDisplay, bool _bMustExist)
+{
+ OTableIndex aReturn;
+
+ TableIndexList::iterator aSearch = std::find_if(_rList.begin(), _rList.end(),
+ [&_rName](const OTableIndex& rIndex) { return rIndex.GetIndexFileName() == _rName; });
+ if (aSearch != _rList.end())
+ {
+ sal_Int32 nPos = static_cast<sal_Int32>(std::distance(_rList.begin(), aSearch));
+
+ aReturn = *aSearch;
+
+ _rList.erase(aSearch);
+ _rDisplay.remove_text(_rName);
+
+ // adjust selection if necessary
+ if (static_cast<sal_uInt32>(nPos) == _rList.size())
+ _rDisplay.select(static_cast<sal_uInt16>(nPos)-1);
+ else
+ _rDisplay.select(static_cast<sal_uInt16>(nPos));
+ }
+ OSL_ENSURE(!_bMustExist || !aReturn.GetIndexFileName().isEmpty(), "ODbaseIndexDialog::implRemoveIndex : did not find the index!");
+ return aReturn;
+}
+
+void ODbaseIndexDialog::implInsertIndex(const OTableIndex& _rIndex, TableIndexList& _rList, weld::TreeView& _rDisplay)
+{
+ _rList.push_front(_rIndex);
+ _rDisplay.append_text(_rIndex.GetIndexFileName());
+ _rDisplay.select(0);
+}
+
+OTableIndex ODbaseIndexDialog::RemoveTableIndex( std::u16string_view _rTableName, const OUString& _rIndexName )
+{
+ OTableIndex aReturn;
+
+ // does the table exist ?
+ TableInfoList::iterator aTablePos = std::find_if(m_aTableInfoList.begin(), m_aTableInfoList.end(),
+ [&] (const OTableInfo& arg) { return arg.aTableName == _rTableName; });
+
+ if (aTablePos == m_aTableInfoList.end())
+ return aReturn;
+
+ return implRemoveIndex(_rIndexName, aTablePos->aIndexList, *m_xLB_TableIndexes, true/*_bMustExist*/);
+}
+
+void ODbaseIndexDialog::InsertTableIndex( std::u16string_view _rTableName, const OTableIndex& _rIndex)
+{
+ TableInfoList::iterator aTablePos = std::find_if(m_aTableInfoList.begin(), m_aTableInfoList.end(),
+ [&] (const OTableInfo& arg) { return arg.aTableName == _rTableName; });
+
+ if (aTablePos == m_aTableInfoList.end())
+ return;
+
+ implInsertIndex(_rIndex, aTablePos->aIndexList, *m_xLB_TableIndexes);
+}
+
+IMPL_LINK_NOARG(ODbaseIndexDialog, OKClickHdl, weld::Button&, void)
+{
+ // let all tables write their INF file
+
+ for (auto const& tableInfo : m_aTableInfoList)
+ tableInfo.WriteInfFile(m_aDSN);
+
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(ODbaseIndexDialog, AddClickHdl, weld::Button&, void)
+{
+ OUString aSelection = m_xLB_FreeIndexes->get_selected_text();
+ OUString aTableName = m_xCB_Tables->get_active_text();
+ OTableIndex aIndex = RemoveFreeIndex( aSelection, true );
+ InsertTableIndex( aTableName, aIndex );
+
+ checkButtons();
+}
+
+IMPL_LINK_NOARG(ODbaseIndexDialog, RemoveClickHdl, weld::Button&, void)
+{
+ OUString aSelection = m_xLB_TableIndexes->get_selected_text();
+ OUString aTableName = m_xCB_Tables->get_active_text();
+ OTableIndex aIndex = RemoveTableIndex( aTableName, aSelection );
+ InsertFreeIndex( aIndex );
+
+ checkButtons();
+}
+
+IMPL_LINK_NOARG(ODbaseIndexDialog, AddAllClickHdl, weld::Button&, void)
+{
+ const sal_Int32 nCnt = m_xLB_FreeIndexes->n_children();
+ OUString aTableName = m_xCB_Tables->get_active_text();
+
+ for (sal_Int32 nPos = 0; nPos < nCnt; ++nPos)
+ InsertTableIndex(aTableName, RemoveFreeIndex(m_xLB_FreeIndexes->get_text(0), true));
+
+ checkButtons();
+}
+
+IMPL_LINK_NOARG(ODbaseIndexDialog, RemoveAllClickHdl, weld::Button&, void)
+{
+ const sal_Int32 nCnt = m_xLB_TableIndexes->n_children();
+ OUString aTableName = m_xCB_Tables->get_active_text();
+
+ for (sal_Int32 nPos = 0; nPos < nCnt; ++nPos)
+ InsertFreeIndex(RemoveTableIndex(aTableName, m_xLB_TableIndexes->get_text(0)));
+
+ checkButtons();
+}
+
+IMPL_LINK_NOARG(ODbaseIndexDialog, OnListEntrySelected, weld::TreeView&, void)
+{
+ checkButtons();
+}
+
+IMPL_LINK(ODbaseIndexDialog, TableSelectHdl, weld::ComboBox&, rComboBox, void)
+{
+ // search the table
+ TableInfoList::iterator aTablePos = std::find_if(m_aTableInfoList.begin(), m_aTableInfoList.end(),
+ [&] (const OTableInfo& arg) { return arg.aTableName == rComboBox.get_active_text() ; });
+
+ if (aTablePos == m_aTableInfoList.end())
+ return;
+
+ // fill the listbox for the indexes
+ m_xLB_TableIndexes->clear();
+ for (auto const& index : aTablePos->aIndexList)
+ m_xLB_TableIndexes->append_text(index.GetIndexFileName());
+
+ if (!aTablePos->aIndexList.empty())
+ m_xLB_TableIndexes->select(0);
+
+ checkButtons();
+}
+
+void ODbaseIndexDialog::Init()
+{
+ m_xPB_OK->set_sensitive(false);
+ m_xIndexes->set_sensitive(false);
+
+ // All indices are first added to a list of free indices.
+ // Afterwards, check the index of each table in the Inf-file.
+ // These indices are removed from the list of free indices and
+ // entered in the indexlist of the table.
+
+ // if the string does not contain a path, cut the string
+ INetURLObject aURL;
+ aURL.SetSmartProtocol(INetProtocol::File);
+ {
+ SvtPathOptions aPathOptions;
+ m_aDSN = aPathOptions.SubstituteVariable(m_aDSN);
+ }
+ aURL.SetSmartURL(m_aDSN);
+
+ // String aFileName = aURL.PathToFileName();
+ m_aDSN = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+ ::ucbhelper::Content aFile;
+ bool bFolder=true;
+ try
+ {
+ aFile = ::ucbhelper::Content(m_aDSN,Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext());
+ bFolder = aFile.isFolder();
+ }
+ catch(Exception&)
+ {
+ return;
+ }
+
+ // first assume for all indexes they're free
+
+ OUString const aIndexExt("ndx");
+ OUString const aTableExt("dbf");
+
+ std::vector< OUString > aUsedIndexes;
+
+ aURL.SetSmartProtocol(INetProtocol::File);
+ const Sequence<OUString> aFolderUrls = ::utl::LocalFileHelper::GetFolderContents(m_aDSN, bFolder);
+ for(const OUString& rURL : aFolderUrls)
+ {
+ OUString aName;
+ osl::FileBase::getSystemPathFromFileURL(rURL,aName);
+ aURL.SetSmartURL(aName);
+ OUString aExt = aURL.getExtension();
+ if (aExt == aIndexExt)
+ {
+ m_aFreeIndexList.emplace_back(aURL.getName() );
+ }
+ else if (aExt == aTableExt)
+ {
+ m_aTableInfoList.emplace_back(aURL.getName() );
+ OTableInfo& rTabInfo = m_aTableInfoList.back();
+
+ // open the INF file
+ aURL.setExtension(u"inf");
+ OFileNotation aTransformer(aURL.GetURLNoPass(), OFileNotation::N_URL);
+ Config aInfFile( aTransformer.get(OFileNotation::N_SYSTEM) );
+ aInfFile.SetGroup( aGroupIdent );
+
+ // fill the indexes list
+ OString aNDX;
+ sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
+ OString aKeyName;
+ OUString aEntry;
+
+ for( sal_uInt16 nKey = 0; nKey < nKeyCnt; nKey++ )
+ {
+ // does the key point to an index file ?
+ aKeyName = aInfFile.GetKeyName( nKey );
+ aNDX = aKeyName.copy(0,3);
+
+ // yes -> add to the tables index list
+ if (aNDX == "NDX")
+ {
+ aEntry = OStringToOUString(aInfFile.ReadKey(aKeyName), osl_getThreadTextEncoding());
+ rTabInfo.aIndexList.emplace_back( aEntry );
+
+ // and remove it from the free index list
+ aUsedIndexes.push_back(aEntry);
+ // do this later below. We may not have encountered the index file, yet, thus we may not
+ // know the index as being free, yet
+ }
+ }
+ }
+ }
+
+ for (auto const& usedIndex : aUsedIndexes)
+ RemoveFreeIndex( usedIndex, false );
+
+ if (!m_aTableInfoList.empty())
+ {
+ m_xPB_OK->set_sensitive(true);
+ m_xIndexes->set_sensitive(true);
+ }
+
+ checkButtons();
+}
+
+void ODbaseIndexDialog::SetCtrls()
+{
+ // ComboBox tables
+ for (auto const& tableInfo : m_aTableInfoList)
+ m_xCB_Tables->append_text(tableInfo.aTableName);
+
+ // put the first dataset into Edit
+ if (!m_aTableInfoList.empty())
+ {
+ const OTableInfo& rTabInfo = m_aTableInfoList.front();
+ m_xCB_Tables->set_entry_text(rTabInfo.aTableName);
+
+ // build ListBox of the table indices
+ for (auto const& index : rTabInfo.aIndexList)
+ m_xLB_TableIndexes->append_text(index.GetIndexFileName());
+
+ if (!rTabInfo.aIndexList.empty())
+ m_xLB_TableIndexes->select(0);
+ }
+
+ // ListBox of the free indices
+ for (auto const& freeIndex : m_aFreeIndexList)
+ m_xLB_FreeIndexes->append_text(freeIndex.GetIndexFileName());
+
+ if (!m_aFreeIndexList.empty())
+ m_xLB_FreeIndexes->select(0);
+
+ TableSelectHdl(*m_xCB_Tables);
+ checkButtons();
+}
+
+void OTableInfo::WriteInfFile( const OUString& rDSN ) const
+{
+ // open INF file
+ INetURLObject aURL;
+ aURL.SetSmartProtocol(INetProtocol::File);
+ OUString aDsn = rDSN;
+ {
+ SvtPathOptions aPathOptions;
+ aDsn = aPathOptions.SubstituteVariable(aDsn);
+ }
+ aURL.SetSmartURL(aDsn);
+ aURL.Append(aTableName);
+ aURL.setExtension(u"inf");
+
+ OFileNotation aTransformer(aURL.GetURLNoPass(), OFileNotation::N_URL);
+ Config aInfFile( aTransformer.get(OFileNotation::N_SYSTEM) );
+ aInfFile.SetGroup( aGroupIdent );
+
+ // first, delete all table indices
+ OString aNDX;
+ sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
+ sal_uInt16 nKey = 0;
+
+ while( nKey < nKeyCnt )
+ {
+ // Does the key point to an index file?...
+ OString aKeyName = aInfFile.GetKeyName( nKey );
+ aNDX = aKeyName.copy(0,3);
+
+ //...if yes, delete index file, nKey is at subsequent key
+ if (aNDX == "NDX")
+ {
+ aInfFile.DeleteKey(aKeyName);
+ nKeyCnt--;
+ }
+ else
+ nKey++;
+
+ }
+
+ // now add all saved indices
+ sal_uInt16 nPos = 0;
+ for (auto const& index : aIndexList)
+ {
+ OStringBuffer aKeyName("NDX");
+ if( nPos > 0 ) // first index contains no number
+ aKeyName.append(static_cast<sal_Int32>(nPos));
+ aInfFile.WriteKey(
+ aKeyName.makeStringAndClear(),
+ OUStringToOString(index.GetIndexFileName(),
+ osl_getThreadTextEncoding()));
+ ++nPos;
+ }
+
+ aInfFile.Flush();
+
+ // if only [dbase] is left in INF-file, delete file
+ if(nPos)
+ return;
+
+ try
+ {
+ ::ucbhelper::Content aContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>(), comphelper::getProcessComponentContext());
+ aContent.executeCommand( "delete", Any( true ) );
+ }
+ catch (const Exception& )
+ {
+ // simply silent this. The strange algorithm here does a lot of
+ // things even if no files at all were created or accessed, so it's
+ // possible that the file we're trying to delete does not even
+ // exist, and this is a valid condition.
+ }
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dbfindex.hxx b/dbaccess/source/ui/dlg/dbfindex.hxx
new file mode 100644
index 000000000..53b75640e
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dbfindex.hxx
@@ -0,0 +1,110 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <deque>
+
+namespace dbaui
+{
+
+// OTableIndex
+/// represents a single dbf index
+class OTableIndex
+{
+private:
+ OUString aIndexFileName;
+
+public:
+ OTableIndex() { }
+ explicit OTableIndex( const OUString& rFileName ) : aIndexFileName( rFileName ) { }
+
+ const OUString& GetIndexFileName() const { return aIndexFileName; }
+};
+
+typedef std::deque< OTableIndex > TableIndexList;
+
+// OTableInfo
+class ODbaseIndexDialog;
+/** holds the INF file of a table
+*/
+class OTableInfo
+{
+ friend class ODbaseIndexDialog;
+private:
+ OUString aTableName;
+ TableIndexList aIndexList;
+
+public:
+ explicit OTableInfo( const OUString& rName ) : aTableName(rName) { }
+
+ void WriteInfFile( const OUString& rDSN ) const;
+};
+
+typedef std::deque< OTableInfo > TableInfoList;
+
+// IndexDialog
+class ODbaseIndexDialog : public weld::GenericDialogController
+{
+protected:
+ OUString m_aDSN;
+ TableInfoList m_aTableInfoList;
+ TableIndexList m_aFreeIndexList;
+
+ std::unique_ptr<weld::Button> m_xPB_OK;
+ std::unique_ptr<weld::ComboBox> m_xCB_Tables;
+ std::unique_ptr<weld::Widget> m_xIndexes;
+ std::unique_ptr<weld::TreeView> m_xLB_TableIndexes;
+ std::unique_ptr<weld::TreeView> m_xLB_FreeIndexes;
+
+ std::unique_ptr<weld::Button> m_xAdd;
+ std::unique_ptr<weld::Button> m_xRemove;
+ std::unique_ptr<weld::Button> m_xAddAll;
+ std::unique_ptr<weld::Button> m_xRemoveAll;
+
+ DECL_LINK( TableSelectHdl, weld::ComboBox&, void );
+ DECL_LINK( AddClickHdl, weld::Button&, void );
+ DECL_LINK( RemoveClickHdl, weld::Button&, void );
+ DECL_LINK( AddAllClickHdl, weld::Button&, void );
+ DECL_LINK( RemoveAllClickHdl, weld::Button&, void );
+ DECL_LINK( OKClickHdl, weld::Button&, void );
+ DECL_LINK( OnListEntrySelected, weld::TreeView&, void );
+
+ void Init();
+ void SetCtrls();
+
+ static OTableIndex implRemoveIndex(const OUString& _rName, TableIndexList& _rList, weld::TreeView& _rDisplay, bool _bMustExist);
+ static void implInsertIndex(const OTableIndex& _rIndex, TableIndexList& _rList, weld::TreeView& _rDisplay);
+
+ OTableIndex RemoveFreeIndex( const OUString& _rName, bool _bMustExist ) { return implRemoveIndex(_rName, m_aFreeIndexList, *m_xLB_FreeIndexes, _bMustExist); }
+ void InsertFreeIndex( const OTableIndex& _rIndex ) { implInsertIndex(_rIndex, m_aFreeIndexList, *m_xLB_FreeIndexes); }
+ OTableIndex RemoveTableIndex( std::u16string_view _rTableName, const OUString& _rIndexName );
+ void InsertTableIndex( std::u16string_view _rTableName, const OTableIndex& _rIndex );
+
+ void checkButtons();
+
+public:
+ ODbaseIndexDialog(weld::Window * pParent, const OUString& rDataSrcName);
+ virtual ~ODbaseIndexDialog() override;
+};
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dbwiz.cxx b/dbaccess/source/ui/dlg/dbwiz.cxx
new file mode 100644
index 000000000..fa0653502
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dbwiz.cxx
@@ -0,0 +1,336 @@
+/* -*- 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 <core_resource.hxx>
+#include <dbwiz.hxx>
+#include <strings.hrc>
+#include <strings.hxx>
+#include <dsitems.hxx>
+#include "dsnItem.hxx"
+#include "adminpages.hxx"
+#include "generalpage.hxx"
+#include <unotools/confignode.hxx>
+#include "ConnectionPage.hxx"
+#include "DriverSettings.hxx"
+#include "DbAdminImpl.hxx"
+#include <helpids.h>
+
+namespace dbaui
+{
+using namespace com::sun::star::uno;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::util;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+
+#define START_PAGE 0
+#define CONNECTION_PAGE 1
+#define ADDITIONAL_PAGE_DBASE 2
+#define ADDITIONAL_PAGE_FLAT 3
+#define ADDITIONAL_PAGE_LDAP 4
+//5 was ADDITIONAL_PAGE_ADABAS
+#define ADDITIONAL_PAGE_MYSQL_JDBC 6
+#define ADDITIONAL_PAGE_MYSQL_ODBC 7
+#define ADDITIONAL_PAGE_ORACLE_JDBC 8
+#define ADDITIONAL_PAGE_ADO 9
+#define ADDITIONAL_PAGE_ODBC 10
+#define ADDITIONAL_USERDEFINED 11
+#define ADDITIONAL_PAGE_MYSQL_NATIVE 12
+
+// ODbTypeWizDialog
+ODbTypeWizDialog::ODbTypeWizDialog(weld::Window* _pParent, SfxItemSet const * _pItems,
+ const Reference< XComponentContext >& _rxORB, const css::uno::Any& _aDataSourceName)
+ : WizardMachine(_pParent, WizardButtonFlags::NEXT | WizardButtonFlags::PREVIOUS | WizardButtonFlags::FINISH | WizardButtonFlags::CANCEL | WizardButtonFlags::HELP )
+{
+ m_pImpl.reset(new ODbDataSourceAdministrationHelper(_rxORB, m_xAssistant.get(), _pParent, this));
+ m_pImpl->setDataSourceOrName(_aDataSourceName);
+ Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
+ m_pOutSet.reset(new SfxItemSet( *_pItems->GetPool(), _pItems->GetRanges() ));
+
+ m_pImpl->translateProperties(xDatasource, *m_pOutSet);
+ m_eType = dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(*m_pOutSet);
+
+ defaultButton(WizardButtonFlags::NEXT);
+ enableButtons(WizardButtonFlags::FINISH, false);
+ enableAutomaticNextButtonState();
+
+ m_xPrevPage->set_help_id(HID_DBWIZ_PREVIOUS);
+ m_xNextPage->set_help_id(HID_DBWIZ_NEXT);
+ m_xCancel->set_help_id(HID_DBWIZ_CANCEL);
+ m_xFinish->set_help_id(HID_DBWIZ_FINISH);
+ // no local resources needed anymore
+
+ const DbuTypeCollectionItem* pCollectionItem = dynamic_cast<const DbuTypeCollectionItem*>(_pItems->GetItem(DSID_TYPECOLLECTION));
+ assert(pCollectionItem && "must exist");
+ m_pCollection = pCollectionItem->getCollection();
+
+ ActivatePage();
+ setTitleBase(DBA_RES(STR_DATABASE_TYPE_CHANGE));
+
+ m_xAssistant->set_current_page(0);
+}
+
+ODbTypeWizDialog::~ODbTypeWizDialog()
+{
+}
+
+IMPL_LINK(ODbTypeWizDialog, OnTypeSelected, OGeneralPage&, _rTabPage, void)
+{
+ m_eType = _rTabPage.GetSelectedType();
+ const bool bURLRequired = m_pCollection->isConnectionUrlRequired(m_eType);
+ enableButtons(WizardButtonFlags::NEXT,bURLRequired);
+ enableButtons(WizardButtonFlags::FINISH,!bURLRequired);
+}
+
+WizardState ODbTypeWizDialog::determineNextState( WizardState _nCurrentState ) const
+{
+ WizardState nNextState = WZS_INVALID_STATE;
+ switch(_nCurrentState)
+ {
+ case START_PAGE:
+ switch(m_pCollection->determineType(m_eType))
+ {
+ case ::dbaccess::DST_MOZILLA:
+ case ::dbaccess::DST_OUTLOOK:
+ case ::dbaccess::DST_OUTLOOKEXP:
+ case ::dbaccess::DST_EVOLUTION:
+ case ::dbaccess::DST_EVOLUTION_GROUPWISE:
+ case ::dbaccess::DST_EVOLUTION_LDAP:
+ case ::dbaccess::DST_KAB:
+ case ::dbaccess::DST_MACAB:
+ nNextState = WZS_INVALID_STATE;
+ break;
+ case ::dbaccess::DST_MYSQL_NATIVE:
+ nNextState = ADDITIONAL_PAGE_MYSQL_NATIVE;
+ break;
+ default:
+ nNextState = CONNECTION_PAGE;
+ break;
+ }
+ break;
+ case CONNECTION_PAGE:
+ switch(m_pCollection->determineType(m_eType))
+ {
+ case ::dbaccess::DST_MOZILLA:
+ case ::dbaccess::DST_THUNDERBIRD:
+ case ::dbaccess::DST_OUTLOOK:
+ case ::dbaccess::DST_OUTLOOKEXP:
+ case ::dbaccess::DST_EVOLUTION:
+ case ::dbaccess::DST_EVOLUTION_GROUPWISE:
+ case ::dbaccess::DST_EVOLUTION_LDAP:
+ case ::dbaccess::DST_KAB:
+ case ::dbaccess::DST_MACAB:
+ case ::dbaccess::DST_MSACCESS:
+ case ::dbaccess::DST_MSACCESS_2007:
+ case ::dbaccess::DST_JDBC:
+ case ::dbaccess::DST_CALC:
+ case ::dbaccess::DST_WRITER:
+ nNextState = WZS_INVALID_STATE;
+ break;
+ case ::dbaccess::DST_DBASE:
+ nNextState = ADDITIONAL_PAGE_DBASE;
+ break;
+ case ::dbaccess::DST_FLAT:
+ nNextState = ADDITIONAL_PAGE_FLAT;
+ break;
+ case ::dbaccess::DST_LDAP:
+ nNextState = ADDITIONAL_PAGE_LDAP;
+ break;
+ case ::dbaccess::DST_MYSQL_JDBC:
+ nNextState = ADDITIONAL_PAGE_MYSQL_JDBC;
+ break;
+ case ::dbaccess::DST_MYSQL_ODBC:
+ nNextState = ADDITIONAL_PAGE_MYSQL_ODBC;
+ break;
+ case ::dbaccess::DST_ORACLE_JDBC:
+ nNextState = ADDITIONAL_PAGE_ORACLE_JDBC;
+ break;
+ case ::dbaccess::DST_ADO:
+ nNextState = ADDITIONAL_PAGE_ADO;
+ break;
+ case ::dbaccess::DST_ODBC:
+ nNextState = ADDITIONAL_PAGE_ODBC;
+ break;
+ default:
+ nNextState = WZS_INVALID_STATE;
+ break;
+ }
+ break;
+ }
+
+ return nNextState;
+}
+
+const SfxItemSet* ODbTypeWizDialog::getOutputSet() const
+{
+ return m_pOutSet.get();
+}
+
+SfxItemSet* ODbTypeWizDialog::getWriteOutputSet()
+{
+ return m_pOutSet.get();
+}
+
+std::pair< Reference<XConnection>,bool> ODbTypeWizDialog::createConnection()
+{
+ return m_pImpl->createConnection();
+}
+
+Reference< XComponentContext > ODbTypeWizDialog::getORB() const
+{
+ return m_pImpl->getORB();
+}
+
+Reference< XDriver > ODbTypeWizDialog::getDriver()
+{
+ return m_pImpl->getDriver();
+}
+
+OUString ODbTypeWizDialog::getDatasourceType(const SfxItemSet& _rSet) const
+{
+ return dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(_rSet);
+}
+
+void ODbTypeWizDialog::clearPassword()
+{
+ m_pImpl->clearPassword();
+}
+
+std::unique_ptr<BuilderPage> ODbTypeWizDialog::createPage(WizardState _nState)
+{
+ TranslateId pStringId = STR_PAGETITLE_ADVANCED;
+ std::unique_ptr<BuilderPage> xPage;
+
+ OString sIdent(OString::number(_nState));
+ weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
+
+ switch(_nState)
+ {
+ case START_PAGE: // start state
+ {
+ xPage = std::make_unique<OGeneralPageDialog>(pPageContainer, this, *m_pOutSet);
+ OGeneralPage* pGeneralPage = static_cast<OGeneralPage*>(xPage.get());
+ pGeneralPage->SetTypeSelectHandler( LINK( this, ODbTypeWizDialog, OnTypeSelected));
+ pStringId = STR_PAGETITLE_GENERAL;
+ }
+ break;
+ case CONNECTION_PAGE:
+ xPage = OConnectionTabPage::Create(pPageContainer, this, m_pOutSet.get());
+ pStringId = STR_PAGETITLE_CONNECTION;
+ break;
+
+ case ADDITIONAL_PAGE_DBASE:
+ xPage = ODriversSettings::CreateDbase(pPageContainer, this, m_pOutSet.get());
+ break;
+ case ADDITIONAL_PAGE_FLAT:
+ xPage = ODriversSettings::CreateText(pPageContainer, this, m_pOutSet.get());
+ break;
+ case ADDITIONAL_PAGE_LDAP:
+ xPage = ODriversSettings::CreateLDAP(pPageContainer, this, m_pOutSet.get());
+ break;
+ case ADDITIONAL_PAGE_MYSQL_JDBC:
+ xPage = ODriversSettings::CreateMySQLJDBC(pPageContainer, this, m_pOutSet.get());
+ break;
+ case ADDITIONAL_PAGE_MYSQL_NATIVE:
+ xPage = ODriversSettings::CreateMySQLNATIVE(pPageContainer, this, m_pOutSet.get());
+ break;
+ case ADDITIONAL_PAGE_MYSQL_ODBC:
+ xPage = ODriversSettings::CreateMySQLODBC(pPageContainer, this, m_pOutSet.get());
+ break;
+ case ADDITIONAL_PAGE_ORACLE_JDBC:
+ xPage = ODriversSettings::CreateOracleJDBC(pPageContainer, this, m_pOutSet.get());
+ break;
+ case ADDITIONAL_PAGE_ADO:
+ xPage = ODriversSettings::CreateAdo(pPageContainer, this, m_pOutSet.get());
+ break;
+ case ADDITIONAL_PAGE_ODBC:
+ xPage = ODriversSettings::CreateODBC(pPageContainer, this, m_pOutSet.get());
+ break;
+ case ADDITIONAL_USERDEFINED:
+ xPage = ODriversSettings::CreateUser(pPageContainer, this, m_pOutSet.get());
+ break;
+ default:
+ OSL_FAIL("Wrong state!");
+ break;
+ }
+
+ // register ourself as modified listener
+ if ( xPage )
+ {
+ static_cast<OGenericAdministrationPage*>(xPage.get())->SetServiceFactory( m_pImpl->getORB() );
+ static_cast<OGenericAdministrationPage*>(xPage.get())->SetAdminDialog(this,this);
+ m_xAssistant->set_page_title(sIdent, DBA_RES(pStringId));
+ defaultButton( _nState == START_PAGE ? WizardButtonFlags::NEXT : WizardButtonFlags::FINISH );
+ enableButtons( WizardButtonFlags::FINISH, _nState != START_PAGE);
+ }
+ return xPage;
+}
+
+bool ODbTypeWizDialog::leaveState(WizardState _nState)
+{
+ SfxTabPage* pPage = static_cast<SfxTabPage*>(WizardMachine::GetPage(_nState));
+ if ( pPage )
+ pPage->FillItemSet(m_pOutSet.get());
+ return true;
+}
+
+void ODbTypeWizDialog::setTitle(const OUString& _sTitle)
+{
+ m_xAssistant->set_title(_sTitle);
+}
+
+void ODbTypeWizDialog::enableConfirmSettings( bool _bEnable )
+{
+ enableButtons( WizardButtonFlags::FINISH, _bEnable );
+ // TODO:
+ // this is hacky. At the moment, this method is used in only one case.
+ // As soon as it is to be used more wide-spread, we should find a proper concept
+ // for enabling both the Next and Finish buttons, depending on the current page state.
+ // Plus, the concept must also care for the case where those pages are embedded into
+ // a normal tab dialog.
+}
+
+void ODbTypeWizDialog::saveDatasource()
+{
+ SfxTabPage* pPage = static_cast<SfxTabPage*>(WizardMachine::GetPage(getCurrentState()));
+ if ( pPage )
+ pPage->FillItemSet(m_pOutSet.get());
+
+ OUString sOldURL;
+ if ( m_pImpl->getCurrentDataSource().is() )
+ m_pImpl->getCurrentDataSource()->getPropertyValue(PROPERTY_URL) >>= sOldURL;
+ DataSourceInfoConverter::convert( getORB(), m_pCollection,sOldURL,m_eType,m_pImpl->getCurrentDataSource());
+}
+
+vcl::IWizardPageController* ODbTypeWizDialog::getPageController(BuilderPage* pCurrentPage) const
+{
+ OGenericAdministrationPage* pPage = static_cast<OGenericAdministrationPage*>(pCurrentPage);
+ return pPage;
+}
+
+bool ODbTypeWizDialog::onFinish()
+{
+ saveDatasource();
+ return m_pImpl->saveChanges(*m_pOutSet) && WizardMachine::onFinish();
+}
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dbwizsetup.cxx b/dbaccess/source/ui/dlg/dbwizsetup.cxx
new file mode 100644
index 000000000..f687740dd
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dbwizsetup.cxx
@@ -0,0 +1,994 @@
+/* -*- 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 <core_resource.hxx>
+#include <dbwizsetup.hxx>
+#include <dsmeta.hxx>
+#include "DBSetupConnectionPages.hxx"
+#include <strings.hrc>
+#include <strings.hxx>
+#include <dsitems.hxx>
+#include "dsnItem.hxx"
+
+#include <unotools/pathoptions.hxx>
+#include <svl/stritem.hxx>
+#include "adminpages.hxx"
+#include <sfx2/docfilt.hxx>
+#include <unotools/ucbhelper.hxx>
+#include "generalpage.hxx"
+#include <unotools/confignode.hxx>
+#include "DbAdminImpl.hxx"
+#include <helpids.h>
+#include "ConnectionPageSetup.hxx"
+#include <UITools.hxx>
+#include <dbaccess/AsynchronousLink.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/frame/TerminationVetoException.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <com/sun/star/ucb/InteractiveIOException.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/frame/XTerminateListener.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/ucb/IOErrorCode.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/task/XInteractionHandler2.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+#include <comphelper/interaction.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <tools/diagnose_ex.h>
+#include <osl/diagnose.h>
+#include <connectivity/DriversConfig.hxx>
+
+namespace dbaui
+{
+using namespace dbtools;
+using namespace vcl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::sdbcx;
+using namespace com::sun::star::task;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::io;
+using namespace com::sun::star::util;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::ucb;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::document;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+using vcl::RoadmapWizardTypes::WizardPath;
+
+// ODbTypeWizDialogSetup
+ODbTypeWizDialogSetup::ODbTypeWizDialogSetup(weld::Window* _pParent
+ ,SfxItemSet const * _pItems
+ ,const Reference< XComponentContext >& _rxORB
+ ,const css::uno::Any& _aDataSourceName
+ )
+ : vcl::RoadmapWizardMachine( _pParent )
+
+ , m_bIsConnectable( false)
+ , m_sRM_IntroText( DBA_RES( STR_PAGETITLE_INTROPAGE ) )
+ , m_sRM_dBaseText( DBA_RES( STR_PAGETITLE_DBASE ) )
+ , m_sRM_TextText( DBA_RES( STR_PAGETITLE_TEXT ) )
+ , m_sRM_MSAccessText( DBA_RES( STR_PAGETITLE_MSACCESS ) )
+ , m_sRM_LDAPText( DBA_RES( STR_PAGETITLE_LDAP ) )
+ , m_sRM_ADOText( DBA_RES( STR_PAGETITLE_ADO ) )
+ , m_sRM_JDBCText( DBA_RES( STR_PAGETITLE_JDBC ) )
+ , m_sRM_MySQLNativePageTitle( DBA_RES( STR_PAGETITLE_MYSQL_NATIVE ) )
+ , m_sRM_OracleText( DBA_RES( STR_PAGETITLE_ORACLE ) )
+ , m_sRM_MySQLText( DBA_RES( STR_PAGETITLE_MYSQL ) )
+ , m_sRM_ODBCText( DBA_RES( STR_PAGETITLE_ODBC ) )
+ , m_sRM_DocumentOrSpreadSheetText( DBA_RES( STR_PAGETITLE_DOCUMENT_OR_SPREADSHEET ) )
+ , m_sRM_AuthentificationText( DBA_RES( STR_PAGETITLE_AUTHENTIFICATION ) )
+ , m_sRM_FinalText( DBA_RES( STR_PAGETITLE_FINAL ) )
+ , m_sWorkPath( SvtPathOptions().GetWorkPath() )
+ , m_pGeneralPage( nullptr )
+ , m_pMySQLIntroPage( nullptr )
+ , m_pFinalPage( nullptr )
+{
+ // no local resources needed anymore
+ // extract the datasource type collection from the item set
+ const DbuTypeCollectionItem* pCollectionItem = dynamic_cast<const DbuTypeCollectionItem*>(_pItems->GetItem(DSID_TYPECOLLECTION));
+ assert(pCollectionItem && "must exist");
+ m_pCollection = pCollectionItem->getCollection();
+
+ assert(m_pCollection && "ODbTypeWizDialogSetup::ODbTypeWizDialogSetup : really need a DSN type collection !");
+
+ m_pImpl.reset(new ODbDataSourceAdministrationHelper(_rxORB, m_xAssistant.get(), _pParent, this));
+ m_pImpl->setDataSourceOrName(_aDataSourceName);
+ Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
+ m_pOutSet.reset( new SfxItemSet( *_pItems->GetPool(), _pItems->GetRanges() ) );
+
+ m_pImpl->translateProperties(xDatasource, *m_pOutSet);
+
+ defaultButton(WizardButtonFlags::NEXT);
+ enableButtons(WizardButtonFlags::FINISH, true);
+ enableAutomaticNextButtonState();
+
+ ::dbaccess::ODsnTypeCollection::TypeIterator aIter = m_pCollection->begin();
+ ::dbaccess::ODsnTypeCollection::TypeIterator aEnd = m_pCollection->end();
+ for(PathId i = 1;aIter != aEnd;++aIter,++i)
+ {
+ const OUString& sURLPrefix = aIter.getURLPrefix();
+ WizardPath aPath;
+ aPath.push_back(PAGE_DBSETUPWIZARD_INTRO);
+ m_pCollection->fillPageIds(sURLPrefix,aPath);
+ aPath.push_back(PAGE_DBSETUPWIZARD_AUTHENTIFICATION);
+ aPath.push_back(PAGE_DBSETUPWIZARD_FINAL);
+
+ declareAuthDepPath(sURLPrefix,i,aPath);
+ }
+
+ WizardPath aPath;
+ aPath.push_back(PAGE_DBSETUPWIZARD_INTRO);
+ declarePath( static_cast<PathId>(m_pCollection->size()+1), aPath);
+
+ m_xPrevPage->set_help_id(HID_DBWIZ_PREVIOUS);
+ m_xNextPage->set_help_id(HID_DBWIZ_NEXT);
+ m_xCancel->set_help_id(HID_DBWIZ_CANCEL);
+ m_xFinish->set_help_id(HID_DBWIZ_FINISH);
+ ActivatePage();
+ setTitleBase(DBA_RES(STR_DBWIZARDTITLE));
+ m_xAssistant->set_current_page(0);
+}
+
+void ODbTypeWizDialogSetup::declareAuthDepPath( const OUString& _sURL, PathId _nPathId, const WizardPath& _rPaths)
+{
+ bool bHasAuthentication = DataSourceMetaData::getAuthentication( _sURL ) != AuthNone;
+
+ // collect the elements of the path
+ WizardPath aPath;
+
+ for (auto const& path : _rPaths)
+ {
+ if ( bHasAuthentication || ( path != PAGE_DBSETUPWIZARD_AUTHENTIFICATION ) )
+ aPath.push_back(path);
+ }
+
+ // call base method
+ ::vcl::RoadmapWizardMachine::declarePath( _nPathId, aPath );
+}
+
+OUString ODbTypeWizDialogSetup::getStateDisplayName(WizardState _nState) const
+{
+ OUString sRoadmapItem;
+ switch( _nState )
+ {
+ case PAGE_DBSETUPWIZARD_INTRO:
+ sRoadmapItem = m_sRM_IntroText;
+ break;
+
+ case PAGE_DBSETUPWIZARD_DBASE:
+ sRoadmapItem = m_sRM_dBaseText;
+ break;
+ case PAGE_DBSETUPWIZARD_ADO:
+ sRoadmapItem = m_sRM_ADOText;
+ break;
+ case PAGE_DBSETUPWIZARD_TEXT:
+ sRoadmapItem = m_sRM_TextText;
+ break;
+ case PAGE_DBSETUPWIZARD_MSACCESS:
+ sRoadmapItem = m_sRM_MSAccessText;
+ break;
+ case PAGE_DBSETUPWIZARD_LDAP:
+ sRoadmapItem = m_sRM_LDAPText;
+ break;
+ case PAGE_DBSETUPWIZARD_JDBC:
+ sRoadmapItem = m_sRM_JDBCText;
+ break;
+ case PAGE_DBSETUPWIZARD_ORACLE:
+ sRoadmapItem = m_sRM_OracleText;
+ break;
+ case PAGE_DBSETUPWIZARD_MYSQL_INTRO:
+ sRoadmapItem = m_sRM_MySQLText;
+ break;
+ case PAGE_DBSETUPWIZARD_MYSQL_JDBC:
+ sRoadmapItem = m_sRM_JDBCText;
+ break;
+ case PAGE_DBSETUPWIZARD_MYSQL_NATIVE:
+ sRoadmapItem = m_sRM_MySQLNativePageTitle;
+ break;
+ case PAGE_DBSETUPWIZARD_MYSQL_ODBC:
+ sRoadmapItem = m_sRM_ODBCText;
+ break;
+ case PAGE_DBSETUPWIZARD_ODBC:
+ sRoadmapItem = m_sRM_ODBCText;
+ break;
+ case PAGE_DBSETUPWIZARD_DOCUMENT_OR_SPREADSHEET:
+ sRoadmapItem = m_sRM_DocumentOrSpreadSheetText;
+ break;
+ case PAGE_DBSETUPWIZARD_AUTHENTIFICATION:
+ sRoadmapItem = m_sRM_AuthentificationText;
+ break;
+ case PAGE_DBSETUPWIZARD_USERDEFINED:
+ sRoadmapItem = DBA_RES(STR_PAGETITLE_CONNECTION);
+ break;
+ case PAGE_DBSETUPWIZARD_FINAL:
+ sRoadmapItem = m_sRM_FinalText;
+ break;
+ default:
+ break;
+ }
+ return sRoadmapItem;
+}
+
+ODbTypeWizDialogSetup::~ODbTypeWizDialogSetup()
+{
+}
+
+IMPL_LINK_NOARG(ODbTypeWizDialogSetup, OnTypeSelected, OGeneralPage&, void)
+{
+ activateDatabasePath();
+}
+
+static void lcl_removeUnused(const ::comphelper::NamedValueCollection& _aOld,const ::comphelper::NamedValueCollection& _aNew,::comphelper::NamedValueCollection& _rDSInfo)
+{
+ _rDSInfo.merge(_aNew,true);
+ uno::Sequence< beans::NamedValue > aOldValues = _aOld.getNamedValues();
+ const beans::NamedValue* pIter = aOldValues.getConstArray();
+ const beans::NamedValue* pEnd = pIter + aOldValues.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ if ( !_aNew.has(pIter->Name) )
+ {
+ _rDSInfo.remove(pIter->Name);
+ }
+ }
+}
+
+void DataSourceInfoConverter::convert(const Reference<XComponentContext> & xContext, const ::dbaccess::ODsnTypeCollection* _pCollection,const OUString& _sOldURLPrefix,const OUString& _sNewURLPrefix,const css::uno::Reference< css::beans::XPropertySet >& _xDatasource)
+{
+ if ( _pCollection->getPrefix(_sOldURLPrefix) == _pCollection->getPrefix(_sNewURLPrefix) )
+ return ;
+ uno::Sequence< beans::PropertyValue> aInfo;
+ _xDatasource->getPropertyValue(PROPERTY_INFO) >>= aInfo;
+ ::comphelper::NamedValueCollection aDS(aInfo);
+
+ ::connectivity::DriversConfig aDriverConfig(xContext);
+
+ const ::comphelper::NamedValueCollection& aOldProperties = aDriverConfig.getProperties(_sOldURLPrefix);
+ const ::comphelper::NamedValueCollection& aNewProperties = aDriverConfig.getProperties(_sNewURLPrefix);
+ lcl_removeUnused(aOldProperties,aNewProperties,aDS);
+
+ aDS >>= aInfo;
+ _xDatasource->setPropertyValue(PROPERTY_INFO,uno::Any(aInfo));
+}
+
+void ODbTypeWizDialogSetup::activateDatabasePath()
+{
+ switch ( m_pGeneralPage->GetDatabaseCreationMode() )
+ {
+ case OGeneralPageWizard::eCreateNew:
+ {
+ sal_Int32 nCreateNewDBIndex = m_pCollection->getIndexOf( m_pGeneralPage->GetSelectedType() );
+ if ( nCreateNewDBIndex == -1 )
+ nCreateNewDBIndex = m_pCollection->getIndexOf( u"sdbc:dbase:" );
+ OSL_ENSURE( nCreateNewDBIndex != -1, "ODbTypeWizDialogSetup::activateDatabasePath: the GeneralPage should have prevented this!" );
+ activatePath( static_cast< PathId >( nCreateNewDBIndex + 1 ), true );
+
+ enableState(PAGE_DBSETUPWIZARD_FINAL );
+ enableButtons( WizardButtonFlags::FINISH, true);
+ }
+ break;
+ case OGeneralPageWizard::eConnectExternal:
+ {
+ OUString sOld = m_sURL;
+ m_sURL = m_pGeneralPage->GetSelectedType();
+ DataSourceInfoConverter::convert(getORB(), m_pCollection,sOld,m_sURL,m_pImpl->getCurrentDataSource());
+ ::dbaccess::DATASOURCE_TYPE eType = VerifyDataSourceType(m_pCollection->determineType(m_sURL));
+ if (eType == ::dbaccess::DST_UNKNOWN)
+ m_pCollection->determineType(m_sOldURL);
+
+ activatePath( static_cast<PathId>(m_pCollection->getIndexOf(m_sURL) + 1), true);
+ updateTypeDependentStates();
+ }
+ break;
+ case OGeneralPageWizard::eOpenExisting:
+ {
+ activatePath( static_cast<PathId>(m_pCollection->size() + 1), true );
+ enableButtons( WizardButtonFlags::FINISH, !m_pGeneralPage->GetSelectedDocumentURL().isEmpty() );
+ }
+ break;
+ default:
+ OSL_FAIL( "ODbTypeWizDialogSetup::activateDatabasePath: unknown creation mode!" );
+ }
+
+ enableButtons( WizardButtonFlags::NEXT, m_pGeneralPage->GetDatabaseCreationMode() != OGeneralPageWizard::eOpenExisting );
+ // TODO: this should go into the base class. Point is, we activate a path whose *last*
+ // step is also the current one. The base class should automatically disable
+ // the Next button in such a case. However, not for this patch ...
+}
+
+void ODbTypeWizDialogSetup::updateTypeDependentStates()
+{
+ bool bDoEnable = false;
+ bool bIsConnectionRequired = m_pCollection->isConnectionUrlRequired(m_sURL);
+ if (!bIsConnectionRequired)
+ {
+ bDoEnable = true;
+ }
+ else if ( m_sURL == m_sOldURL )
+ {
+ bDoEnable = m_bIsConnectable;
+ }
+ enableState(PAGE_DBSETUPWIZARD_AUTHENTIFICATION, bDoEnable);
+ enableState(PAGE_DBSETUPWIZARD_FINAL, bDoEnable );
+ enableButtons( WizardButtonFlags::FINISH, bDoEnable);
+}
+
+void ODbTypeWizDialogSetup::resetPages(const Reference< XPropertySet >& _rxDatasource)
+{
+ // remove all items which relate to indirect properties from the input set
+ // (without this, the following may happen: select an arbitrary data source where some indirect properties
+ // are set. Select another data source of the same type, where the indirect props are not set (yet). Then,
+ // the indirect property values of the first ds are shown in the second ds ...)
+ const ODbDataSourceAdministrationHelper::MapInt2String& rMap = m_pImpl->getIndirectProperties();
+ for (auto const& elem : rMap)
+ getWriteOutputSet()->ClearItem( static_cast<sal_uInt16>(elem.first) );
+
+ // extract all relevant data from the property set of the data source
+ m_pImpl->translateProperties(_rxDatasource, *getWriteOutputSet());
+}
+
+const SfxItemSet* ODbTypeWizDialogSetup::getOutputSet() const
+{
+ return m_pOutSet.get();
+}
+
+SfxItemSet* ODbTypeWizDialogSetup::getWriteOutputSet()
+{
+ return m_pOutSet.get();
+}
+
+std::pair< Reference<XConnection>,bool> ODbTypeWizDialogSetup::createConnection()
+{
+ return m_pImpl->createConnection();
+}
+
+Reference< XComponentContext > ODbTypeWizDialogSetup::getORB() const
+{
+ return m_pImpl->getORB();
+}
+
+Reference< XDriver > ODbTypeWizDialogSetup::getDriver()
+{
+ return m_pImpl->getDriver();
+}
+
+::dbaccess::DATASOURCE_TYPE ODbTypeWizDialogSetup::VerifyDataSourceType(const ::dbaccess::DATASOURCE_TYPE DatabaseType) const
+{
+ ::dbaccess::DATASOURCE_TYPE LocDatabaseType = DatabaseType;
+ if ((LocDatabaseType == ::dbaccess::DST_MYSQL_JDBC) || (LocDatabaseType == ::dbaccess::DST_MYSQL_ODBC) || (LocDatabaseType == ::dbaccess::DST_MYSQL_NATIVE))
+ {
+ if (m_pMySQLIntroPage != nullptr)
+ {
+ switch( m_pMySQLIntroPage->getMySQLMode() )
+ {
+ case OMySQLIntroPageSetup::VIA_JDBC:
+ return ::dbaccess::DST_MYSQL_JDBC;
+ case OMySQLIntroPageSetup::VIA_NATIVE:
+ return ::dbaccess::DST_MYSQL_NATIVE;
+ case OMySQLIntroPageSetup::VIA_ODBC:
+ return ::dbaccess::DST_MYSQL_ODBC;
+ }
+ }
+ }
+ return LocDatabaseType;
+}
+
+OUString ODbTypeWizDialogSetup::getDatasourceType(const SfxItemSet& _rSet) const
+{
+ OUString sRet = dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(_rSet);
+ if (m_pMySQLIntroPage && m_pMySQLIntroPage->IsVisible())
+ {
+ switch( m_pMySQLIntroPage->getMySQLMode() )
+ {
+ case OMySQLIntroPageSetup::VIA_JDBC:
+ sRet = "sdbc:mysql:jdbc:";
+ break;
+ case OMySQLIntroPageSetup::VIA_NATIVE:
+ sRet = "sdbc:mysql:mysqlc:";
+ break;
+ case OMySQLIntroPageSetup::VIA_ODBC:
+ sRet = "sdbc:mysql:odbc:";
+ break;
+ }
+ }
+ return sRet;
+}
+
+void ODbTypeWizDialogSetup::clearPassword()
+{
+ m_pImpl->clearPassword();
+}
+
+void ODbTypeWizDialogSetup::SetIntroPage(OMySQLIntroPageSetup* pPage)
+{
+ m_pMySQLIntroPage = pPage;
+ m_pMySQLIntroPage->SetClickHdl(LINK( this, ODbTypeWizDialogSetup, ImplClickHdl ) );
+}
+
+void ODbTypeWizDialogSetup::SetGeneralPage(OGeneralPageWizard* pPage)
+{
+ m_pGeneralPage = pPage;
+ m_pGeneralPage->SetTypeSelectHandler(LINK(this, ODbTypeWizDialogSetup, OnTypeSelected));
+ m_pGeneralPage->SetCreationModeHandler(LINK( this, ODbTypeWizDialogSetup, OnChangeCreationMode ) );
+ m_pGeneralPage->SetDocumentSelectionHandler(LINK( this, ODbTypeWizDialogSetup, OnRecentDocumentSelected ) );
+ m_pGeneralPage->SetChooseDocumentHandler(LINK( this, ODbTypeWizDialogSetup, OnSingleDocumentChosen ) );
+}
+
+void ODbTypeWizDialogSetup::SetFinalPage(OFinalDBPageSetup* pPage)
+{
+ m_pFinalPage = pPage;
+}
+
+std::unique_ptr<BuilderPage> ODbTypeWizDialogSetup::createPage(WizardState _nState)
+{
+ std::unique_ptr<OGenericAdministrationPage> xPage;
+
+ OString sIdent(OString::number(_nState));
+ weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
+
+ switch(_nState)
+ {
+ case PAGE_DBSETUPWIZARD_INTRO:
+ xPage = std::make_unique<OGeneralPageWizard>(pPageContainer,this,*m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_DBASE:
+ xPage = OConnectionTabPageSetup::CreateDbaseTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_ADO:
+ xPage = OConnectionTabPageSetup::CreateADOTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_TEXT:
+ xPage = OTextConnectionPageSetup::CreateTextTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_ODBC:
+ xPage = OConnectionTabPageSetup::CreateODBCTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_JDBC:
+ xPage = OJDBCConnectionPageSetup::CreateJDBCTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_MYSQL_ODBC:
+ m_pOutSet->Put(SfxStringItem(DSID_CONNECTURL, m_pCollection->getPrefix("sdbc:mysql:odbc:")));
+ xPage = OConnectionTabPageSetup::CreateODBCTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_MYSQL_JDBC:
+ m_pOutSet->Put(SfxStringItem(DSID_CONNECTURL, m_pCollection->getPrefix("sdbc:mysql:jdbc:")));
+ xPage = OGeneralSpecialJDBCConnectionPageSetup::CreateMySQLJDBCTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+ case PAGE_DBSETUPWIZARD_MYSQL_NATIVE:
+ m_pOutSet->Put(SfxStringItem(DSID_CONNECTURL, m_pCollection->getPrefix("sdbc:mysql:mysqlc:")));
+ xPage = MySQLNativeSetupPage::Create(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_ORACLE:
+ xPage = OGeneralSpecialJDBCConnectionPageSetup::CreateOracleJDBCTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_LDAP:
+ xPage = OLDAPConnectionPageSetup::CreateLDAPTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_DOCUMENT_OR_SPREADSHEET:
+ xPage = OSpreadSheetConnectionPageSetup::CreateDocumentOrSpreadSheetTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_MSACCESS:
+ xPage = OConnectionTabPageSetup::CreateMSAccessTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+ case PAGE_DBSETUPWIZARD_MYSQL_INTRO:
+ xPage = OMySQLIntroPageSetup::CreateMySQLIntroTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_AUTHENTIFICATION:
+ xPage = OAuthentificationPageSetup::CreateAuthentificationTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_USERDEFINED:
+ xPage = OConnectionTabPageSetup::CreateUserDefinedTabPage(pPageContainer, this, *m_pOutSet);
+ break;
+
+ case PAGE_DBSETUPWIZARD_FINAL:
+ xPage = OFinalDBPageSetup::CreateFinalDBTabPageSetup(pPageContainer, this, *m_pOutSet);
+ break;
+ }
+
+ if ( xPage )
+ {
+ if ((_nState != PAGE_DBSETUPWIZARD_INTRO) && (_nState != PAGE_DBSETUPWIZARD_AUTHENTIFICATION))
+ {
+ xPage->SetModifiedHandler(LINK( this, ODbTypeWizDialogSetup, ImplModifiedHdl ) );
+ }
+
+ xPage->SetServiceFactory( m_pImpl->getORB() );
+ xPage->SetAdminDialog(this, this);
+
+ defaultButton( _nState == PAGE_DBSETUPWIZARD_FINAL ? WizardButtonFlags::FINISH : WizardButtonFlags::NEXT );
+ enableButtons( WizardButtonFlags::FINISH, _nState == PAGE_DBSETUPWIZARD_FINAL );
+ enableButtons( WizardButtonFlags::NEXT, _nState != PAGE_DBSETUPWIZARD_FINAL );
+
+ m_xAssistant->set_page_title(sIdent, getStateDisplayName(_nState));
+ }
+ return xPage;
+}
+
+IMPL_LINK(ODbTypeWizDialogSetup, ImplModifiedHdl, OGenericAdministrationPage const *, _pConnectionPageSetup, void)
+{
+ m_bIsConnectable = _pConnectionPageSetup->GetRoadmapStateValue( );
+ enableState(PAGE_DBSETUPWIZARD_FINAL, m_bIsConnectable);
+ enableState(PAGE_DBSETUPWIZARD_AUTHENTIFICATION, m_bIsConnectable);
+ if (getCurrentState() == PAGE_DBSETUPWIZARD_FINAL)
+ enableButtons( WizardButtonFlags::FINISH, true);
+ else
+ enableButtons( WizardButtonFlags::FINISH, m_bIsConnectable);
+ enableButtons( WizardButtonFlags::NEXT, m_bIsConnectable && (getCurrentState() != PAGE_DBSETUPWIZARD_FINAL));
+}
+
+IMPL_LINK(ODbTypeWizDialogSetup, ImplClickHdl, OMySQLIntroPageSetup*, _pMySQLIntroPageSetup, void)
+{
+ OUString sURLPrefix;
+ switch( _pMySQLIntroPageSetup->getMySQLMode() )
+ {
+ case OMySQLIntroPageSetup::VIA_ODBC:
+ sURLPrefix = "sdbc:mysql:odbc:";
+ break;
+ case OMySQLIntroPageSetup::VIA_JDBC:
+ sURLPrefix = "sdbc:mysql:jdbc:";
+ break;
+ case OMySQLIntroPageSetup::VIA_NATIVE:
+ sURLPrefix = "sdbc:mysql:mysqlc:";
+ break;
+ }
+ activatePath( static_cast<PathId>(m_pCollection->getIndexOf(sURLPrefix) + 1), true);
+}
+
+IMPL_LINK_NOARG(ODbTypeWizDialogSetup, OnChangeCreationMode, OGeneralPageWizard&, void)
+{
+ activateDatabasePath();
+}
+
+IMPL_LINK_NOARG(ODbTypeWizDialogSetup, OnRecentDocumentSelected, OGeneralPageWizard&, void)
+{
+ enableButtons( WizardButtonFlags::FINISH, !m_pGeneralPage->GetSelectedDocumentURL().isEmpty() );
+}
+
+IMPL_LINK_NOARG(ODbTypeWizDialogSetup, OnSingleDocumentChosen, OGeneralPageWizard&, void)
+{
+ if (prepareLeaveCurrentState(WizardTypes::eFinish))
+ onFinish();
+}
+
+void ODbTypeWizDialogSetup::enterState(WizardState _nState)
+{
+ m_sURL = dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(*m_pOutSet);
+ RoadmapWizardMachine::enterState(_nState);
+ switch(_nState)
+ {
+ case PAGE_DBSETUPWIZARD_INTRO:
+ m_sOldURL = m_sURL;
+ break;
+ case PAGE_DBSETUPWIZARD_FINAL:
+ enableButtons( WizardButtonFlags::FINISH, true);
+ if ( m_pFinalPage )
+ m_pFinalPage->enableTableWizardCheckBox(m_pCollection->supportsTableCreation(m_sURL));
+ break;
+ }
+}
+
+void ODbTypeWizDialogSetup::saveDatasource()
+{
+ SfxTabPage* pPage = static_cast<SfxTabPage*>(GetPage(getCurrentState()));
+ if ( pPage )
+ pPage->FillItemSet(m_pOutSet.get());
+}
+
+bool ODbTypeWizDialogSetup::leaveState(WizardState _nState)
+{
+ if (_nState == PAGE_DBSETUPWIZARD_MYSQL_INTRO)
+ return true;
+ if ( _nState == PAGE_DBSETUPWIZARD_INTRO && m_sURL != m_sOldURL )
+ {
+ resetPages(m_pImpl->getCurrentDataSource());
+ }
+ SfxTabPage* pPage = static_cast<SfxTabPage*>(GetPage(_nState));
+ return pPage && pPage->DeactivatePage(m_pOutSet.get()) != DeactivateRC::KeepPage;
+}
+
+void ODbTypeWizDialogSetup::setTitle(const OUString& _sTitle)
+{
+ m_xAssistant->set_title(_sTitle);
+}
+
+void ODbTypeWizDialogSetup::enableConfirmSettings( bool /*_bEnable*/ )
+{
+}
+
+namespace
+{
+ bool lcl_handle( const Reference< XInteractionHandler2 >& _rxHandler, const Any& _rRequest )
+ {
+ rtl::Reference<OInteractionRequest> pRequest = new OInteractionRequest( _rRequest );
+ rtl::Reference<OInteractionAbort> pAbort = new OInteractionAbort;
+ pRequest->addContinuation( pAbort );
+
+ return _rxHandler->handleInteractionRequest( pRequest );
+ }
+}
+
+bool ODbTypeWizDialogSetup::SaveDatabaseDocument()
+{
+ Reference< XInteractionHandler2 > xHandler( InteractionHandler::createWithParent(getORB(), nullptr) );
+ try
+ {
+ if (callSaveAsDialog())
+ {
+ m_pImpl->saveChanges(*m_pOutSet);
+ Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
+ Reference< XModel > xModel( getDataSourceOrModel( xDatasource ), UNO_QUERY_THROW );
+ Reference< XStorable > xStore( xModel, UNO_QUERY_THROW );
+
+ if ( m_pGeneralPage->GetDatabaseCreationMode() == OGeneralPageWizard::eCreateNew )
+ CreateDatabase();
+
+ ::comphelper::NamedValueCollection aArgs( xModel->getArgs() );
+ aArgs.put( "Overwrite", true );
+ aArgs.put( "InteractionHandler", xHandler );
+ aArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
+ aArgs.put( "IgnoreFirebirdMigration", true );
+
+ OUString sPath = ODbDataSourceAdministrationHelper::getDocumentUrl( *m_pOutSet );
+ xStore->storeAsURL( sPath, aArgs.getPropertyValues() );
+
+ if ( !m_pFinalPage || m_pFinalPage->IsDatabaseDocumentToBeRegistered() )
+ RegisterDataSourceByLocation( sPath );
+
+ return true;
+ }
+ }
+ catch ( const Exception& e )
+ {
+ Any aError = ::cppu::getCaughtException();
+ if ( xHandler.is() )
+ {
+ if ( !lcl_handle( xHandler, aError ) )
+ {
+ InteractiveIOException aRequest;
+ aRequest.Classification = InteractionClassification_ERROR;
+ if ( aError.isExtractableTo( ::cppu::UnoType< IOException >::get() ) )
+ // assume saving the document failed
+ aRequest.Code = IOErrorCode_CANT_WRITE;
+ else
+ aRequest.Code = IOErrorCode_GENERAL;
+ aRequest.Message = e.Message;
+ aRequest.Context = e.Context;
+ lcl_handle( xHandler, Any( aRequest ) );
+ }
+ }
+ }
+ return false;
+}
+
+ bool ODbTypeWizDialogSetup::IsDatabaseDocumentToBeOpened() const
+ {
+ if ( m_pGeneralPage->GetDatabaseCreationMode() == OGeneralPageWizard::eOpenExisting )
+ return true;
+
+ if ( m_pFinalPage != nullptr )
+ return m_pFinalPage->IsDatabaseDocumentToBeOpened();
+
+ return true;
+ }
+
+ bool ODbTypeWizDialogSetup::IsTableWizardToBeStarted() const
+ {
+ if ( m_pGeneralPage->GetDatabaseCreationMode() == OGeneralPageWizard::eOpenExisting )
+ return false;
+
+ if ( m_pFinalPage != nullptr )
+ return m_pFinalPage->IsTableWizardToBeStarted();
+
+ return false;
+ }
+
+ void ODbTypeWizDialogSetup::CreateDatabase()
+ {
+ OUString sUrl;
+ const OUString eType = m_pGeneralPage->GetSelectedType();
+ if ( dbaccess::ODsnTypeCollection::isEmbeddedDatabase(eType) )
+ {
+ sUrl = eType;
+ Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
+ OSL_ENSURE(xDatasource.is(),"DataSource is null!");
+ if ( xDatasource.is() )
+ xDatasource->setPropertyValue( PROPERTY_INFO, Any( m_pCollection->getDefaultDBSettings( eType ) ) );
+ m_pImpl->translateProperties(xDatasource,*m_pOutSet);
+ }
+ else if ( m_pCollection->isFileSystemBased(eType) )
+ {
+ Reference< XSimpleFileAccess3 > xSimpleFileAccess(ucb::SimpleFileAccess::create(getORB()));
+ INetURLObject aDBPathURL(m_sWorkPath);
+ aDBPathURL.Append(m_aDocURL.getBase());
+ createUniqueFolderName(&aDBPathURL);
+ sUrl = aDBPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE);
+ xSimpleFileAccess->createFolder(sUrl);
+ sUrl = eType + sUrl;
+ }
+ m_pOutSet->Put(SfxStringItem(DSID_CONNECTURL, sUrl));
+ m_pImpl->saveChanges(*m_pOutSet);
+ }
+
+ void ODbTypeWizDialogSetup::RegisterDataSourceByLocation(std::u16string_view _sPath)
+ {
+ Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
+ Reference< XDatabaseContext > xDatabaseContext( DatabaseContext::create(getORB()) );
+ INetURLObject aURL( _sPath );
+ OUString sFilename = aURL.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset );
+ OUString sDatabaseName = ::dbtools::createUniqueName(xDatabaseContext, sFilename, false);
+ xDatabaseContext->registerObject(sDatabaseName, xDatasource);
+ }
+
+ bool ODbTypeWizDialogSetup::callSaveAsDialog()
+ {
+ bool bRet = false;
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,
+ FileDialogFlags::NONE, m_xAssistant.get());
+ aFileDlg.SetContext(sfx2::FileDialogHelper::BaseSaveAs);
+ std::shared_ptr<const SfxFilter> pFilter = getStandardDatabaseFilter();
+ if ( pFilter )
+ {
+ OUString sDefaultName = DBA_RES( STR_DATABASEDEFAULTNAME );
+ OUString sExtension = pFilter->GetDefaultExtension();
+ sDefaultName += sExtension.replaceAt( 0, 1, u"" );
+ INetURLObject aWorkURL( m_sWorkPath );
+ aWorkURL.Append( sDefaultName );
+ sDefaultName = createUniqueFileName( aWorkURL );
+ aFileDlg.SetFileName( sDefaultName );
+
+ aFileDlg.AddFilter(pFilter->GetUIName(),pFilter->GetDefaultExtension());
+ aFileDlg.SetCurrentFilter(pFilter->GetUIName());
+ }
+ if ( aFileDlg.Execute() == ERRCODE_NONE )
+ {
+ m_aDocURL = INetURLObject(aFileDlg.GetPath());
+
+ if( m_aDocURL.GetProtocol() != INetProtocol::NotValid )
+ {
+ OUString sFileName = m_aDocURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ if ( ::utl::UCBContentHelper::IsDocument(sFileName) )
+ ::utl::UCBContentHelper::Kill(sFileName);
+ m_pOutSet->Put(SfxStringItem(DSID_DOCUMENT_URL, sFileName));
+ bRet = true;
+ }
+ }
+ return bRet;
+ }
+
+ void ODbTypeWizDialogSetup::createUniqueFolderName(INetURLObject* pURL)
+ {
+ Reference< XSimpleFileAccess3 > xSimpleFileAccess(ucb::SimpleFileAccess::create(getORB()));
+ OUString sLastSegmentName = pURL->getName();
+ bool bFolderExists = true;
+ sal_Int32 i = 1;
+ while (bFolderExists)
+ {
+ bFolderExists = xSimpleFileAccess->isFolder(pURL->GetMainURL( INetURLObject::DecodeMechanism::NONE ));
+ if (bFolderExists)
+ {
+ i++;
+ pURL->setName(OUStringConcatenation(sLastSegmentName + OUString::number(i)));
+ }
+ }
+ }
+
+ OUString ODbTypeWizDialogSetup::createUniqueFileName(const INetURLObject& _rURL)
+ {
+ Reference< XSimpleFileAccess3 > xSimpleFileAccess(ucb::SimpleFileAccess::create(getORB()));
+ OUString BaseName = _rURL.getBase();
+
+ bool bElementExists = true;
+
+ INetURLObject aExistenceCheck( _rURL );
+ for ( sal_Int32 i = 1; bElementExists; )
+ {
+ bElementExists = xSimpleFileAccess->exists( aExistenceCheck.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ if ( bElementExists )
+ {
+ aExistenceCheck.setBase( OUStringConcatenation(BaseName + OUString::number( i ) ));
+ ++i;
+ }
+ }
+ return aExistenceCheck.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset );
+ }
+
+ vcl::IWizardPageController* ODbTypeWizDialogSetup::getPageController(BuilderPage* pCurrentPage) const
+ {
+ OGenericAdministrationPage* pPage = static_cast<OGenericAdministrationPage*>(pCurrentPage);
+ return pPage;
+ }
+
+ namespace
+ {
+ typedef ::cppu::WeakImplHelper< XTerminateListener
+ > AsyncLoader_Base;
+ class AsyncLoader : public AsyncLoader_Base
+ {
+ private:
+ Reference< XComponentLoader > m_xFrameLoader;
+ Reference< XDesktop2 > m_xDesktop;
+ Reference< XInteractionHandler2 > m_xInteractionHandler;
+ OUString m_sURL;
+ OAsynchronousLink m_aAsyncCaller;
+
+ public:
+ AsyncLoader( const Reference< XComponentContext >& _rxORB, const OUString& _rURL );
+
+ void doLoadAsync();
+
+ // XTerminateListener
+ virtual void SAL_CALL queryTermination( const css::lang::EventObject& Event ) override;
+ virtual void SAL_CALL notifyTermination( const css::lang::EventObject& Event ) override;
+ // XEventListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
+
+ private:
+ DECL_LINK( OnOpenDocument, void*, void );
+ };
+
+ AsyncLoader::AsyncLoader( const Reference< XComponentContext >& _rxORB, const OUString& _rURL )
+ :m_sURL( _rURL )
+ ,m_aAsyncCaller( LINK( this, AsyncLoader, OnOpenDocument ) )
+ {
+ try
+ {
+ m_xDesktop.set( Desktop::create(_rxORB) );
+ m_xFrameLoader.set( m_xDesktop, UNO_QUERY_THROW );
+ m_xInteractionHandler = InteractionHandler::createWithParent(_rxORB, nullptr);
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ }
+
+ void AsyncLoader::doLoadAsync()
+ {
+ OSL_ENSURE( !m_aAsyncCaller.IsRunning(), "AsyncLoader:doLoadAsync: already running!" );
+
+ acquire();
+ try
+ {
+ if ( m_xDesktop.is() )
+ m_xDesktop->addTerminateListener( this );
+ }
+ catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION("dbaccess"); }
+
+ m_aAsyncCaller.Call();
+ }
+
+ IMPL_LINK_NOARG( AsyncLoader, OnOpenDocument, void*, void )
+ {
+ try
+ {
+ if ( m_xFrameLoader.is() )
+ {
+ ::comphelper::NamedValueCollection aLoadArgs;
+ aLoadArgs.put( "InteractionHandler", m_xInteractionHandler );
+ aLoadArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
+
+ Sequence< PropertyValue > aLoadArgPV;
+ aLoadArgs >>= aLoadArgPV;
+
+ m_xFrameLoader->loadComponentFromURL( m_sURL,
+ "_default",
+ FrameSearchFlag::ALL,
+ aLoadArgPV
+ );
+ }
+ }
+ catch( const Exception& )
+ {
+ // do not assert.
+ // Such an exception happens for instance of the to-be-loaded document does not exist anymore.
+ }
+
+ try
+ {
+ if ( m_xDesktop.is() )
+ m_xDesktop->removeTerminateListener( this );
+ }
+ catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION("dbaccess"); }
+
+ release();
+ }
+
+ void SAL_CALL AsyncLoader::queryTermination( const css::lang::EventObject& /*Event*/ )
+ {
+ throw TerminationVetoException();
+ }
+
+ void SAL_CALL AsyncLoader::notifyTermination( const css::lang::EventObject& /*Event*/ )
+ {
+ }
+ void SAL_CALL AsyncLoader::disposing( const css::lang::EventObject& /*Source*/ )
+ {
+ }
+ }
+
+ bool ODbTypeWizDialogSetup::onFinish()
+ {
+ if ( m_pGeneralPage->GetDatabaseCreationMode() == OGeneralPageWizard::eOpenExisting )
+ {
+ // we're not going to re-use the XModel we have - since the document the user
+ // wants us to load could be a non-database document. Instead, we asynchronously
+ // open the selected document. Thus, the wizard's return value is RET_CANCEL,
+ // which means to not continue loading the database document
+ if ( !WizardMachine::Finish() )
+ return false;
+
+ try
+ {
+ rtl::Reference<AsyncLoader> pAsyncLoader = new AsyncLoader( getORB(), m_pGeneralPage->GetSelectedDocumentURL() );
+ pAsyncLoader->doLoadAsync();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ return true;
+ }
+
+ if (getCurrentState() != PAGE_DBSETUPWIZARD_FINAL)
+ {
+ skipUntil(PAGE_DBSETUPWIZARD_FINAL);
+ }
+ if (getCurrentState() == PAGE_DBSETUPWIZARD_FINAL)
+ return SaveDatabaseDocument() && WizardMachine::onFinish();
+ else
+ {
+ enableButtons( WizardButtonFlags::FINISH, false );
+ return false;
+ }
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/detailpages.cxx b/dbaccess/source/ui/dlg/detailpages.cxx
new file mode 100644
index 000000000..8a06d7de1
--- /dev/null
+++ b/dbaccess/source/ui/dlg/detailpages.cxx
@@ -0,0 +1,717 @@
+/* -*- 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 <config_java.h>
+#include <core_resource.hxx>
+#include "detailpages.hxx"
+#include <sqlmessage.hxx>
+#include <dsmeta.hxx>
+#include "advancedsettings.hxx"
+#include "DbAdminImpl.hxx"
+#include <dsitems.hxx>
+#include "dbfindex.hxx"
+#include "dsnItem.hxx"
+
+#include <IItemSetHelper.hxx>
+#include <strings.hrc>
+
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#if HAVE_FEATURE_JAVA
+#include <jvmaccess/virtualmachine.hxx>
+#endif
+#include <connectivity/CommonTools.hxx>
+#include "DriverSettings.hxx"
+
+namespace dbaui
+{
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+ using namespace ::dbtools;
+
+ OCommonBehaviourTabPage::OCommonBehaviourTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const OUString& rUIXMLDescription, const OString& rId, const SfxItemSet& rCoreAttrs,
+ OCommonBehaviourTabPageFlags nControlFlags)
+ : OGenericAdministrationPage(pPage, pController, rUIXMLDescription, rId, rCoreAttrs)
+ , m_nControlFlags(nControlFlags)
+ {
+ if (m_nControlFlags & OCommonBehaviourTabPageFlags::UseOptions)
+ {
+ m_xOptionsLabel = m_xBuilder->weld_label("optionslabel");
+ m_xOptionsLabel->show();
+ m_xOptions = m_xBuilder->weld_entry("options");
+ m_xOptions->show();
+ m_xOptions->connect_changed(LINK(this,OGenericAdministrationPage,OnControlEntryModifyHdl));
+ }
+
+ if (m_nControlFlags & OCommonBehaviourTabPageFlags::UseCharset)
+ {
+ m_xDataConvertLabel = m_xBuilder->weld_label("charsetheader");
+ m_xDataConvertLabel->show();
+ m_xCharsetLabel = m_xBuilder->weld_label("charsetlabel");
+ m_xCharsetLabel->show();
+ m_xCharset.reset(new CharSetListBox(m_xBuilder->weld_combo_box("charset")));
+ m_xCharset->show();
+ m_xCharset->connect_changed(LINK(this, OCommonBehaviourTabPage, CharsetSelectHdl));
+ }
+ }
+
+ IMPL_LINK_NOARG(OCommonBehaviourTabPage, CharsetSelectHdl, weld::ComboBox&, void)
+ {
+ callModifiedHdl();
+ }
+
+ OCommonBehaviourTabPage::~OCommonBehaviourTabPage()
+ {
+ m_xCharset.reset();
+ }
+
+ void OCommonBehaviourTabPage::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ if (m_nControlFlags & OCommonBehaviourTabPageFlags::UseOptions)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xOptionsLabel.get()));
+ }
+
+ if (m_nControlFlags & OCommonBehaviourTabPageFlags::UseCharset)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xCharsetLabel.get()));
+ }
+ }
+
+ void OCommonBehaviourTabPage::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ if (m_nControlFlags & OCommonBehaviourTabPageFlags::UseOptions)
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xOptions.get()));
+
+ if (m_nControlFlags & OCommonBehaviourTabPageFlags::UseCharset)
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xCharset->get_widget()));
+ }
+
+ void OCommonBehaviourTabPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ // collect the items
+ const SfxStringItem* pOptionsItem = _rSet.GetItem<SfxStringItem>(DSID_ADDITIONALOPTIONS);
+ const SfxStringItem* pCharsetItem = _rSet.GetItem<SfxStringItem>(DSID_CHARSET);
+
+ // forward the values to the controls
+ if (bValid)
+ {
+ if (m_nControlFlags & OCommonBehaviourTabPageFlags::UseOptions)
+ {
+ m_xOptions->set_text(pOptionsItem->GetValue());
+ m_xOptions->save_value();
+ }
+
+ if (m_nControlFlags & OCommonBehaviourTabPageFlags::UseCharset)
+ {
+ m_xCharset->SelectEntryByIanaName( pCharsetItem->GetValue() );
+ }
+ }
+ OGenericAdministrationPage::implInitControls(_rSet, _bSaveValue);
+ }
+
+ bool OCommonBehaviourTabPage::FillItemSet(SfxItemSet* _rSet)
+ {
+ bool bChangedSomething = false;
+
+ if (m_nControlFlags & OCommonBehaviourTabPageFlags::UseOptions)
+ {
+ fillString(*_rSet,m_xOptions.get(),DSID_ADDITIONALOPTIONS,bChangedSomething);
+ }
+
+ if (m_nControlFlags & OCommonBehaviourTabPageFlags::UseCharset)
+ {
+ if ( m_xCharset->StoreSelectedCharSet( *_rSet, DSID_CHARSET ) )
+ bChangedSomething = true;
+ }
+
+ return bChangedSomething;
+ }
+
+ // ODbaseDetailsPage
+ ODbaseDetailsPage::ODbaseDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs)
+ : OCommonBehaviourTabPage(pPage, pController, "dbaccess/ui/dbasepage.ui", "DbasePage",
+ _rCoreAttrs, OCommonBehaviourTabPageFlags::UseCharset)
+ , m_xShowDeleted(m_xBuilder->weld_check_button("showDelRowsCheckbutton"))
+ , m_xFT_Message(m_xBuilder->weld_label("specMessageLabel"))
+ , m_xIndexes(m_xBuilder->weld_button("indiciesButton"))
+ {
+ m_xIndexes->connect_clicked(LINK(this, ODbaseDetailsPage, OnButtonClicked));
+ m_xShowDeleted->connect_toggled(LINK(this, ODbaseDetailsPage, OnButtonToggled));
+ }
+
+ ODbaseDetailsPage::~ODbaseDetailsPage()
+ {
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateDbase(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet)
+ {
+ return std::make_unique<ODbaseDetailsPage>(pPage, pController, *_rAttrSet);
+ }
+
+ void ODbaseDetailsPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ // get the DSN string (needed for the index dialog)
+ const SfxStringItem* pUrlItem = _rSet.GetItem<SfxStringItem>(DSID_CONNECTURL);
+ const DbuTypeCollectionItem* pTypesItem = _rSet.GetItem<DbuTypeCollectionItem>(DSID_TYPECOLLECTION);
+ ::dbaccess::ODsnTypeCollection* pTypeCollection = pTypesItem ? pTypesItem->getCollection() : nullptr;
+ if (pTypeCollection && pUrlItem && pUrlItem->GetValue().getLength())
+ m_sDsn = pTypeCollection->cutPrefix(pUrlItem->GetValue());
+
+ // get the other relevant items
+ const SfxBoolItem* pDeletedItem = _rSet.GetItem<SfxBoolItem>(DSID_SHOWDELETEDROWS);
+
+ if ( bValid )
+ {
+ m_xShowDeleted->set_active(pDeletedItem->GetValue());
+ m_xFT_Message->set_visible(m_xShowDeleted->get_active());
+ }
+
+ OCommonBehaviourTabPage::implInitControls(_rSet, _bSaveValue);
+ }
+
+ bool ODbaseDetailsPage::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = OCommonBehaviourTabPage::FillItemSet(_rSet);
+
+ fillBool(*_rSet, m_xShowDeleted.get(), DSID_SHOWDELETEDROWS, false, bChangedSomething);
+ return bChangedSomething;
+ }
+
+ IMPL_LINK_NOARG(ODbaseDetailsPage, OnButtonClicked, weld::Button&, void)
+ {
+ ODbaseIndexDialog aIndexDialog(GetFrameWeld(), m_sDsn);
+ aIndexDialog.run();
+ }
+
+ IMPL_LINK_NOARG(ODbaseDetailsPage, OnButtonToggled, weld::Toggleable&, void)
+ {
+ m_xFT_Message->set_visible(m_xShowDeleted->get_active());
+ // it was the checkbox -> we count as modified from now on
+ callModifiedHdl();
+ }
+
+
+ // OAdoDetailsPage
+ OAdoDetailsPage::OAdoDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : OCommonBehaviourTabPage(pPage, pController, "dbaccess/ui/autocharsetpage.ui", "AutoCharset",
+ rCoreAttrs, OCommonBehaviourTabPageFlags::UseCharset )
+ {
+
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateAdo(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+ {
+ return std::make_unique<OAdoDetailsPage>(pPage, pController, *rAttrSet);
+ }
+
+ // OOdbcDetailsPage
+ OOdbcDetailsPage::OOdbcDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : OCommonBehaviourTabPage(pPage, pController, "dbaccess/ui/odbcpage.ui", "ODBC", rCoreAttrs,
+ OCommonBehaviourTabPageFlags::UseCharset | OCommonBehaviourTabPageFlags::UseOptions)
+ , m_xUseCatalog(m_xBuilder->weld_check_button("useCatalogCheckbutton"))
+ {
+ m_xUseCatalog->connect_toggled(LINK(this, OGenericAdministrationPage, OnControlModifiedButtonClick));
+ }
+
+ OOdbcDetailsPage::~OOdbcDetailsPage()
+ {
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateODBC(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pAttrSet)
+ {
+ return std::make_unique<OOdbcDetailsPage>(pPage, pController, *pAttrSet);
+ }
+
+ bool OOdbcDetailsPage::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = OCommonBehaviourTabPage::FillItemSet(_rSet);
+ fillBool(*_rSet,m_xUseCatalog.get(),DSID_USECATALOG,false,bChangedSomething);
+ return bChangedSomething;
+ }
+ void OOdbcDetailsPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ const SfxBoolItem* pUseCatalogItem = _rSet.GetItem<SfxBoolItem>(DSID_USECATALOG);
+
+ if ( bValid )
+ m_xUseCatalog->set_active(pUseCatalogItem->GetValue());
+
+ OCommonBehaviourTabPage::implInitControls(_rSet, _bSaveValue);
+ }
+ // OOdbcDetailsPage
+ OUserDriverDetailsPage::OUserDriverDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : OCommonBehaviourTabPage(pPage, pController, "dbaccess/ui/userdetailspage.ui", "UserDetailsPage",
+ rCoreAttrs, OCommonBehaviourTabPageFlags::UseCharset | OCommonBehaviourTabPageFlags::UseOptions)
+ , m_xFTHostname(m_xBuilder->weld_label("hostnameft"))
+ , m_xEDHostname(m_xBuilder->weld_entry("hostname"))
+ , m_xPortNumber(m_xBuilder->weld_label("portnumberft"))
+ , m_xNFPortNumber(m_xBuilder->weld_spin_button("portnumber"))
+ , m_xUseCatalog(m_xBuilder->weld_check_button("usecatalog"))
+ {
+ m_xUseCatalog->connect_toggled(LINK(this, OGenericAdministrationPage, OnControlModifiedButtonClick));
+ }
+
+ OUserDriverDetailsPage::~OUserDriverDetailsPage()
+ {
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateUser(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pAttrSet)
+ {
+ return std::make_unique<OUserDriverDetailsPage>(pPage, pController, *pAttrSet);
+ }
+
+ bool OUserDriverDetailsPage::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = OCommonBehaviourTabPage::FillItemSet(_rSet);
+
+ fillInt32(*_rSet,m_xNFPortNumber.get(),DSID_CONN_PORTNUMBER,bChangedSomething);
+ fillString(*_rSet,m_xEDHostname.get(),DSID_CONN_HOSTNAME,bChangedSomething);
+ fillBool(*_rSet,m_xUseCatalog.get(),DSID_USECATALOG,false,bChangedSomething);
+
+ return bChangedSomething;
+ }
+ void OUserDriverDetailsPage::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ OCommonBehaviourTabPage::fillControls(_rControlList);
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xEDHostname.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xUseCatalog.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::SpinButton>(m_xNFPortNumber.get()));
+ }
+ void OUserDriverDetailsPage::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ OCommonBehaviourTabPage::fillWindows(_rControlList);
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xFTHostname.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xPortNumber.get()));
+ }
+ void OUserDriverDetailsPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ const SfxBoolItem* pUseCatalogItem = _rSet.GetItem<SfxBoolItem>(DSID_USECATALOG);
+ const SfxStringItem* pHostName = _rSet.GetItem<SfxStringItem>(DSID_CONN_HOSTNAME);
+ const SfxInt32Item* pPortNumber = _rSet.GetItem<SfxInt32Item>(DSID_CONN_PORTNUMBER);
+
+ if ( bValid )
+ {
+ m_xEDHostname->set_text(pHostName->GetValue());
+ m_xEDHostname->save_value();
+
+ m_xNFPortNumber->set_value(pPortNumber->GetValue());
+ m_xNFPortNumber->save_value();
+
+ m_xUseCatalog->set_active(pUseCatalogItem->GetValue());
+ }
+
+ OCommonBehaviourTabPage::implInitControls(_rSet, _bSaveValue);
+ }
+ // OMySQLODBCDetailsPage
+ OMySQLODBCDetailsPage::OMySQLODBCDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : OCommonBehaviourTabPage(pPage, pController, "dbaccess/ui/autocharsetpage.ui", "AutoCharset",
+ rCoreAttrs, OCommonBehaviourTabPageFlags::UseCharset )
+ {
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateMySQLODBC(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pAttrSet)
+ {
+ return std::make_unique<OMySQLODBCDetailsPage>(pPage, pController, *pAttrSet);
+ }
+
+ // OMySQLJDBCDetailsPage
+ OGeneralSpecialJDBCDetailsPage::OGeneralSpecialJDBCDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs ,sal_uInt16 _nPortId, bool bShowSocket)
+ : OCommonBehaviourTabPage(pPage, pController, "dbaccess/ui/generalspecialjdbcdetailspage.ui", "GeneralSpecialJDBCDetails",
+ rCoreAttrs, OCommonBehaviourTabPageFlags::UseCharset)
+ , m_nPortId(_nPortId)
+ , m_bUseClass(true)
+ , m_xEDHostname(m_xBuilder->weld_entry("hostNameEntry"))
+ , m_xNFPortNumber(m_xBuilder->weld_spin_button("portNumberSpinbutton"))
+ , m_xFTSocket(m_xBuilder->weld_label("socketLabel"))
+ , m_xEDSocket(m_xBuilder->weld_entry("socketEntry"))
+ , m_xFTDriverClass(m_xBuilder->weld_label("driverClassLabel"))
+ , m_xEDDriverClass(m_xBuilder->weld_entry("jdbcDriverClassEntry"))
+ , m_xTestJavaDriver(m_xBuilder->weld_button("testDriverClassButton"))
+ {
+ const SfxStringItem* pUrlItem = rCoreAttrs.GetItem<SfxStringItem>(DSID_CONNECTURL);
+ const DbuTypeCollectionItem* pTypesItem = rCoreAttrs.GetItem<DbuTypeCollectionItem>(DSID_TYPECOLLECTION);
+ ::dbaccess::ODsnTypeCollection* pTypeCollection = pTypesItem ? pTypesItem->getCollection() : nullptr;
+ if (pTypeCollection && pUrlItem && pUrlItem->GetValue().getLength() )
+ {
+ m_sDefaultJdbcDriverName = pTypeCollection->getJavaDriverClass(pUrlItem->GetValue());
+ }
+ if ( m_sDefaultJdbcDriverName.getLength() )
+ {
+ m_xEDDriverClass->connect_changed(LINK(this,OGenericAdministrationPage,OnControlEntryModifyHdl));
+ m_xTestJavaDriver->connect_clicked(LINK(this,OGeneralSpecialJDBCDetailsPage,OnTestJavaClickHdl));
+ }
+ else
+ {
+ m_bUseClass = false;
+ m_xFTDriverClass->hide();
+ m_xEDDriverClass->hide();
+ m_xTestJavaDriver->hide();
+ }
+
+ m_xFTSocket->set_visible(bShowSocket && !m_bUseClass);
+ m_xEDSocket->set_visible(bShowSocket && !m_bUseClass);
+
+ m_xEDHostname->connect_changed(LINK(this,OGenericAdministrationPage,OnControlEntryModifyHdl));
+ m_xNFPortNumber->connect_value_changed(LINK(this,OGenericAdministrationPage,OnControlSpinButtonModifyHdl));
+ m_xEDSocket->connect_changed(LINK(this,OGenericAdministrationPage,OnControlEntryModifyHdl));
+ }
+
+ OGeneralSpecialJDBCDetailsPage::~OGeneralSpecialJDBCDetailsPage()
+ {
+ }
+
+ bool OGeneralSpecialJDBCDetailsPage::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = OCommonBehaviourTabPage::FillItemSet(_rSet);
+ if ( m_bUseClass )
+ fillString(*_rSet,m_xEDDriverClass.get(),DSID_JDBCDRIVERCLASS,bChangedSomething);
+ fillString(*_rSet,m_xEDHostname.get(),DSID_CONN_HOSTNAME,bChangedSomething);
+ fillString(*_rSet,m_xEDSocket.get(),DSID_CONN_SOCKET,bChangedSomething);
+ fillInt32(*_rSet,m_xNFPortNumber.get(),m_nPortId,bChangedSomething );
+
+ return bChangedSomething;
+ }
+ void OGeneralSpecialJDBCDetailsPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ const SfxStringItem* pDrvItem = _rSet.GetItem<SfxStringItem>(DSID_JDBCDRIVERCLASS);
+ const SfxStringItem* pHostName = _rSet.GetItem<SfxStringItem>(DSID_CONN_HOSTNAME);
+ const SfxInt32Item* pPortNumber = _rSet.GetItem<SfxInt32Item>(m_nPortId);
+ const SfxStringItem* pSocket = _rSet.GetItem<SfxStringItem>(DSID_CONN_SOCKET);
+
+ if ( bValid )
+ {
+ if ( m_bUseClass )
+ {
+ m_xEDDriverClass->set_text(pDrvItem->GetValue());
+ m_xEDDriverClass->save_value();
+ }
+
+ m_xEDHostname->set_text(pHostName->GetValue());
+ m_xEDHostname->save_value();
+
+ m_xNFPortNumber->set_value(pPortNumber->GetValue());
+ m_xNFPortNumber->save_value();
+
+ m_xEDSocket->set_text(pSocket->GetValue());
+ m_xEDSocket->save_value();
+ }
+
+ OCommonBehaviourTabPage::implInitControls(_rSet, _bSaveValue);
+
+ // to get the correct value when saveValue was called by base class
+ if ( m_bUseClass && m_xEDDriverClass->get_text().trim().isEmpty() )
+ {
+ m_xEDDriverClass->set_text(m_sDefaultJdbcDriverName);
+ m_xEDDriverClass->save_value();
+ }
+ }
+ IMPL_LINK_NOARG(OGeneralSpecialJDBCDetailsPage, OnTestJavaClickHdl, weld::Button&, void)
+ {
+ OSL_ENSURE(m_pAdminDialog,"No Admin dialog set! ->GPF");
+ OSL_ENSURE(m_bUseClass,"Who called me?");
+
+ bool bSuccess = false;
+#if HAVE_FEATURE_JAVA
+ try
+ {
+ if (!m_xEDDriverClass->get_text().trim().isEmpty())
+ {
+// TODO change jvmaccess
+ ::rtl::Reference< jvmaccess::VirtualMachine > xJVM = ::connectivity::getJavaVM( m_pAdminDialog->getORB() );
+ m_xEDDriverClass->set_text(m_xEDDriverClass->get_text().trim()); // fdo#68341
+ bSuccess = ::connectivity::existsJavaClassByName(xJVM,m_xEDDriverClass->get_text());
+ }
+ }
+ catch(Exception&)
+ {
+ }
+#endif
+ TranslateId pMessage = bSuccess ? STR_JDBCDRIVER_SUCCESS : STR_JDBCDRIVER_NO_SUCCESS;
+ const MessageType mt = bSuccess ? MessageType::Info : MessageType::Error;
+ OSQLMessageBox aMsg(GetFrameWeld(), DBA_RES(pMessage), OUString(), MessBoxStyle::Ok | MessBoxStyle::DefaultOk, mt);
+ aMsg.run();
+ }
+
+ void OGeneralSpecialJDBCDetailsPage::callModifiedHdl(weld::Widget* pControl)
+ {
+ if (m_bUseClass && pControl == m_xEDDriverClass.get())
+ m_xTestJavaDriver->set_sensitive(!m_xEDDriverClass->get_text().trim().isEmpty());
+
+ // tell the listener we were modified
+ OGenericAdministrationPage::callModifiedHdl();
+ }
+
+ // MySQLNativePage
+ MySQLNativePage::MySQLNativePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : OCommonBehaviourTabPage(pPage, pController, "dbaccess/ui/mysqlnativepage.ui", "MysqlNativePage", rCoreAttrs, OCommonBehaviourTabPageFlags::UseCharset)
+ , m_xMySQLSettingsContainer(m_xBuilder->weld_widget("MySQLSettingsContainer"))
+ , m_xMySQLSettings(new MySQLNativeSettings(m_xMySQLSettingsContainer.get(), LINK(this,OGenericAdministrationPage,OnControlModified)))
+ , m_xSeparator1(m_xBuilder->weld_label("connectionheader"))
+ , m_xSeparator2(m_xBuilder->weld_label("userheader"))
+ , m_xUserNameLabel(m_xBuilder->weld_label("usernamelabel"))
+ , m_xUserName(m_xBuilder->weld_entry("username"))
+ , m_xPasswordRequired(m_xBuilder->weld_check_button("passwordrequired"))
+ {
+ m_xUserName->connect_changed(LINK(this,OGenericAdministrationPage,OnControlEntryModifyHdl));
+ }
+
+ MySQLNativePage::~MySQLNativePage()
+ {
+ m_xMySQLSettings.reset();
+ }
+
+ void MySQLNativePage::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ OCommonBehaviourTabPage::fillControls( _rControlList );
+ m_xMySQLSettings->fillControls( _rControlList );
+
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Entry>(m_xUserName.get()));
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::Toggleable>(m_xPasswordRequired.get()));
+ }
+
+ void MySQLNativePage::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ OCommonBehaviourTabPage::fillWindows( _rControlList );
+ m_xMySQLSettings->fillWindows( _rControlList);
+
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xSeparator1.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xSeparator2.get()));
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xUserNameLabel.get()));
+ }
+
+ bool MySQLNativePage::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = OCommonBehaviourTabPage::FillItemSet( _rSet );
+
+ bChangedSomething |= m_xMySQLSettings->FillItemSet( _rSet );
+
+ if (m_xUserName->get_value_changed_from_saved())
+ {
+ _rSet->Put( SfxStringItem( DSID_USER, m_xUserName->get_text() ) );
+ _rSet->Put( SfxStringItem( DSID_PASSWORD, OUString()));
+ bChangedSomething = true;
+ }
+ fillBool(*_rSet,m_xPasswordRequired.get(),DSID_PASSWORDREQUIRED,false,bChangedSomething);
+
+ return bChangedSomething;
+ }
+ void MySQLNativePage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ m_xMySQLSettings->implInitControls( _rSet );
+
+ const SfxStringItem* pUidItem = _rSet.GetItem<SfxStringItem>(DSID_USER);
+ const SfxBoolItem* pAllowEmptyPwd = _rSet.GetItem<SfxBoolItem>(DSID_PASSWORDREQUIRED);
+
+ if ( bValid )
+ {
+ m_xUserName->set_text(pUidItem->GetValue());
+ m_xUserName->save_value();
+ m_xPasswordRequired->set_active(pAllowEmptyPwd->GetValue());
+ }
+
+ OCommonBehaviourTabPage::implInitControls(_rSet, _bSaveValue);
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateMySQLJDBC( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet )
+ {
+ return std::make_unique<OGeneralSpecialJDBCDetailsPage>(pPage, pController, *_rAttrSet,DSID_MYSQL_PORTNUMBER);
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateMySQLNATIVE(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pAttrSet)
+ {
+ return std::make_unique<MySQLNativePage>(pPage, pController, *pAttrSet);
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateOracleJDBC(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet)
+ {
+ return std::make_unique<OGeneralSpecialJDBCDetailsPage>(pPage, pController, *_rAttrSet,DSID_ORACLE_PORTNUMBER, false);
+ }
+
+ // OLDAPDetailsPage
+ OLDAPDetailsPage::OLDAPDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : OCommonBehaviourTabPage(pPage, pController, "dbaccess/ui/ldappage.ui", "LDAP",
+ rCoreAttrs, OCommonBehaviourTabPageFlags::NONE)
+ , m_xETBaseDN(m_xBuilder->weld_entry("baseDNEntry"))
+ , m_xCBUseSSL(m_xBuilder->weld_check_button("useSSLCheckbutton"))
+ , m_xNFPortNumber(m_xBuilder->weld_spin_button("portNumberSpinbutton"))
+ , m_xNFRowCount(m_xBuilder->weld_spin_button("LDAPRowCountspinbutton"))
+ {
+ m_xETBaseDN->connect_changed(LINK(this,OGenericAdministrationPage,OnControlEntryModifyHdl));
+ m_xNFPortNumber->connect_value_changed(LINK(this,OGenericAdministrationPage,OnControlSpinButtonModifyHdl));
+ m_xNFRowCount->connect_value_changed(LINK(this,OGenericAdministrationPage,OnControlSpinButtonModifyHdl));
+
+ m_iNormalPort = 389;
+ m_iSSLPort = 636;
+ m_xCBUseSSL->connect_toggled(LINK(this, OLDAPDetailsPage, OnCheckBoxClick));
+ }
+
+ OLDAPDetailsPage::~OLDAPDetailsPage()
+ {
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateLDAP(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet)
+ {
+ return std::make_unique<OLDAPDetailsPage>(pPage, pController, *_rAttrSet);
+ }
+
+ bool OLDAPDetailsPage::FillItemSet( SfxItemSet* _rSet )
+ {
+ bool bChangedSomething = OCommonBehaviourTabPage::FillItemSet(_rSet);
+
+ fillString(*_rSet,m_xETBaseDN.get(),DSID_CONN_LDAP_BASEDN,bChangedSomething);
+ fillInt32(*_rSet,m_xNFPortNumber.get(),DSID_CONN_LDAP_PORTNUMBER,bChangedSomething);
+ fillInt32(*_rSet,m_xNFRowCount.get(),DSID_CONN_LDAP_ROWCOUNT,bChangedSomething);
+ fillBool(*_rSet,m_xCBUseSSL.get(),DSID_CONN_LDAP_USESSL,false,bChangedSomething);
+ return bChangedSomething;
+ }
+
+ IMPL_LINK(OLDAPDetailsPage, OnCheckBoxClick, weld::Toggleable&, rCheckBox, void)
+ {
+ OnControlModifiedButtonClick(rCheckBox);
+ callModifiedHdl();
+ if (m_xCBUseSSL->get_active())
+ {
+ m_iNormalPort = m_xNFPortNumber->get_value();
+ m_xNFPortNumber->set_value(m_iSSLPort);
+ }
+ else
+ {
+ m_iSSLPort = m_xNFPortNumber->get_value();
+ m_xNFPortNumber->set_value(m_iNormalPort);
+ }
+ }
+
+ void OLDAPDetailsPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ const SfxStringItem* pBaseDN = _rSet.GetItem<SfxStringItem>(DSID_CONN_LDAP_BASEDN);
+ const SfxBoolItem* pUseSSL = _rSet.GetItem<SfxBoolItem>(DSID_CONN_LDAP_USESSL);
+ const SfxInt32Item* pPortNumber = _rSet.GetItem<SfxInt32Item>(DSID_CONN_LDAP_PORTNUMBER);
+ const SfxInt32Item* pRowCount = _rSet.GetItem<SfxInt32Item>(DSID_CONN_LDAP_ROWCOUNT);
+
+ if ( bValid )
+ {
+ m_xETBaseDN->set_text(pBaseDN->GetValue());
+ m_xNFPortNumber->set_value(pPortNumber->GetValue());
+ m_xNFRowCount->set_value(pRowCount->GetValue());
+ m_xCBUseSSL->set_active(pUseSSL->GetValue());
+ }
+
+ OCommonBehaviourTabPage::implInitControls(_rSet, _bSaveValue);
+ }
+
+ // OTextDetailsPage
+ OTextDetailsPage::OTextDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : OCommonBehaviourTabPage(pPage, pController, "dbaccess/ui/emptypage.ui", "EmptyPage", rCoreAttrs, OCommonBehaviourTabPageFlags::NONE)
+ , m_xTextConnectionHelper(new OTextConnectionHelper(m_xContainer.get(), TC_EXTENSION | TC_HEADER | TC_SEPARATORS | TC_CHARSET))
+ {
+ }
+
+ OTextDetailsPage::~OTextDetailsPage()
+ {
+ m_xTextConnectionHelper.reset();
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateText(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pAttrSet)
+ {
+ return std::make_unique<OTextDetailsPage>(pPage, pController, *pAttrSet);
+ }
+
+ void OTextDetailsPage::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ OCommonBehaviourTabPage::fillControls(_rControlList);
+ m_xTextConnectionHelper->fillControls(_rControlList);
+
+ }
+ void OTextDetailsPage::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ OCommonBehaviourTabPage::fillWindows(_rControlList);
+ m_xTextConnectionHelper->fillWindows(_rControlList);
+
+ }
+ void OTextDetailsPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // first check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ m_xTextConnectionHelper->implInitControls(_rSet, bValid);
+ OCommonBehaviourTabPage::implInitControls(_rSet, _bSaveValue);
+ }
+
+ bool OTextDetailsPage::FillItemSet( SfxItemSet* rSet )
+ {
+ bool bChangedSomething = OCommonBehaviourTabPage::FillItemSet(rSet);
+ bChangedSomething = m_xTextConnectionHelper->FillItemSet(*rSet, bChangedSomething);
+ return bChangedSomething;
+ }
+
+ bool OTextDetailsPage::prepareLeave()
+ {
+ return m_xTextConnectionHelper->prepareLeave();
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateGeneratedValuesPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet)
+ {
+ return std::make_unique<GeneratedValuesPage>(pPage, pController, *_rAttrSet);
+ }
+
+ std::unique_ptr<SfxTabPage> ODriversSettings::CreateSpecialSettingsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet)
+ {
+ OUString eType = ODbDataSourceAdministrationHelper::getDatasourceType( *_rAttrSet );
+ DataSourceMetaData aMetaData( eType );
+ return std::make_unique<SpecialSettingsPage>(pPage, pController, *_rAttrSet, aMetaData);
+ }
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/detailpages.hxx b/dbaccess/source/ui/dlg/detailpages.hxx
new file mode 100644
index 000000000..2952f42e6
--- /dev/null
+++ b/dbaccess/source/ui/dlg/detailpages.hxx
@@ -0,0 +1,253 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "adminpages.hxx"
+#include <charsetlistbox.hxx>
+#include "TextConnectionHelper.hxx"
+#include "admincontrols.hxx"
+
+#include <o3tl/typed_flags_set.hxx>
+
+enum class OCommonBehaviourTabPageFlags {
+ NONE = 0x0000,
+ UseCharset = 0x0002,
+ UseOptions = 0x0004,
+};
+namespace o3tl {
+ template<> struct typed_flags<OCommonBehaviourTabPageFlags> : is_typed_flags<OCommonBehaviourTabPageFlags, 0x0006> {};
+}
+
+namespace dbaui
+{
+ /** eases the implementation of tab pages handling user/password and/or character
+ set and/or generic options input
+ <BR>
+ The controls to be used have to be defined within the resource, as usual, but
+ this class does all the handling necessary.
+ */
+ class OCommonBehaviourTabPage : public OGenericAdministrationPage
+ {
+ OCommonBehaviourTabPageFlags m_nControlFlags;
+
+ std::unique_ptr<weld::Label> m_xOptionsLabel;
+ std::unique_ptr<weld::Entry> m_xOptions;
+
+ std::unique_ptr<weld::Label> m_xDataConvertLabel;
+ std::unique_ptr<weld::Label> m_xCharsetLabel;
+ std::unique_ptr<CharSetListBox> m_xCharset;
+
+ std::unique_ptr<weld::CheckButton> m_xAutoRetrievingEnabled;
+ std::unique_ptr<weld::Label> m_xAutoIncrementLabel;
+ std::unique_ptr<weld::Entry> m_xAutoIncrement;
+ std::unique_ptr<weld::Label> m_xAutoRetrievingLabel;
+ std::unique_ptr<weld::Entry> m_xAutoRetrieving;
+
+ public:
+ virtual bool FillItemSet (SfxItemSet* _rCoreAttrs) override;
+
+ OCommonBehaviourTabPage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rId, const SfxItemSet& _rCoreAttrs, OCommonBehaviourTabPageFlags nControlFlags);
+ protected:
+
+ virtual ~OCommonBehaviourTabPage() override;
+
+ // subclasses must override this, but it isn't pure virtual
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+
+ // <method>OGenericAdministrationPage::fillControls</method>
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ // <method>OGenericAdministrationPage::fillWindows</method>
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ private:
+ DECL_LINK(CharsetSelectHdl, weld::ComboBox&, void);
+ };
+
+
+ // ODbaseDetailsPage
+ class ODbaseDetailsPage : public OCommonBehaviourTabPage
+ {
+ public:
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+
+ ODbaseDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs);
+ virtual ~ODbaseDetailsPage() override;
+ private:
+ OUString m_sDsn;
+
+ std::unique_ptr<weld::CheckButton> m_xShowDeleted;
+ std::unique_ptr<weld::Label> m_xFT_Message;
+ std::unique_ptr<weld::Button> m_xIndexes;
+
+ protected:
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+
+ private:
+ DECL_LINK(OnButtonClicked, weld::Button&, void);
+ DECL_LINK(OnButtonToggled, weld::Toggleable&, void);
+ };
+
+ // OAdoDetailsPage
+ class OAdoDetailsPage : public OCommonBehaviourTabPage
+ {
+ public:
+ OAdoDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ };
+
+ // OOdbcDetailsPage
+ class OOdbcDetailsPage : public OCommonBehaviourTabPage
+ {
+ public:
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+
+ OOdbcDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ virtual ~OOdbcDetailsPage() override;
+ protected:
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ private:
+ std::unique_ptr<weld::CheckButton> m_xUseCatalog;
+ };
+
+ // OUserDriverDetailsPage
+ class OUserDriverDetailsPage : public OCommonBehaviourTabPage
+ {
+ public:
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+
+ OUserDriverDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rCoreAttrs);
+ virtual ~OUserDriverDetailsPage() override;
+ protected:
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ private:
+ std::unique_ptr<weld::Label> m_xFTHostname;
+ std::unique_ptr<weld::Entry> m_xEDHostname;
+ std::unique_ptr<weld::Label> m_xPortNumber;
+ std::unique_ptr<weld::SpinButton> m_xNFPortNumber;
+ std::unique_ptr<weld::CheckButton> m_xUseCatalog;
+ };
+
+ // OMySQLODBCDetailsPage
+ class OMySQLODBCDetailsPage : public OCommonBehaviourTabPage
+ {
+ public:
+ OMySQLODBCDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ };
+
+ // OGeneralSpecialJDBCDetailsPage
+ class OGeneralSpecialJDBCDetailsPage final : public OCommonBehaviourTabPage
+ {
+ public:
+ OGeneralSpecialJDBCDetailsPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& _rCoreAttrs,
+ sal_uInt16 _nPortId,
+ bool bShowSocket = true);
+ virtual ~OGeneralSpecialJDBCDetailsPage() override;
+
+ private:
+
+ virtual bool FillItemSet( SfxItemSet* _rCoreAttrs ) override;
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void callModifiedHdl(weld::Widget* pControl = nullptr) override;
+
+ DECL_LINK(OnTestJavaClickHdl, weld::Button&, void);
+
+ OUString m_sDefaultJdbcDriverName;
+ sal_uInt16 m_nPortId;
+ bool m_bUseClass;
+
+ std::unique_ptr<weld::Entry> m_xEDHostname;
+ std::unique_ptr<weld::SpinButton> m_xNFPortNumber;
+ std::unique_ptr<weld::Label> m_xFTSocket;
+ std::unique_ptr<weld::Entry> m_xEDSocket;
+ std::unique_ptr<weld::Label> m_xFTDriverClass;
+ std::unique_ptr<weld::Entry> m_xEDDriverClass;
+ std::unique_ptr<weld::Button> m_xTestJavaDriver;
+ };
+
+ // MySQLNativePage
+ class MySQLNativePage : public OCommonBehaviourTabPage
+ {
+ public:
+ MySQLNativePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ virtual ~MySQLNativePage() override;
+
+ private:
+ std::unique_ptr<weld::Widget> m_xMySQLSettingsContainer;
+ std::unique_ptr<MySQLNativeSettings> m_xMySQLSettings;
+ std::unique_ptr<weld::Label> m_xSeparator1;
+ std::unique_ptr<weld::Label> m_xSeparator2;
+ std::unique_ptr<weld::Label> m_xUserNameLabel;
+ std::unique_ptr<weld::Entry> m_xUserName;
+ std::unique_ptr<weld::CheckButton> m_xPasswordRequired;
+
+ protected:
+ virtual bool FillItemSet( SfxItemSet* _rCoreAttrs ) override;
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ };
+
+ // OOdbcDetailsPage
+ class OLDAPDetailsPage : public OCommonBehaviourTabPage
+ {
+ public:
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+
+ OLDAPDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ virtual ~OLDAPDetailsPage() override;
+ protected:
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ private:
+ sal_Int32 m_iSSLPort;
+ sal_Int32 m_iNormalPort;
+
+ std::unique_ptr<weld::Entry> m_xETBaseDN;
+ std::unique_ptr<weld::CheckButton> m_xCBUseSSL;
+ std::unique_ptr<weld::SpinButton> m_xNFPortNumber;
+ std::unique_ptr<weld::SpinButton> m_xNFRowCount;
+
+ DECL_LINK(OnCheckBoxClick, weld::Toggleable&, void);
+ };
+
+ // OTextDetailsPage
+ class OTextDetailsPage : public OCommonBehaviourTabPage
+ {
+ public:
+ virtual bool FillItemSet ( SfxItemSet* _rCoreAttrs ) override;
+
+ OTextDetailsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ virtual ~OTextDetailsPage() override;
+
+ protected:
+ virtual bool prepareLeave() override;
+
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ private:
+ std::unique_ptr<OTextConnectionHelper> m_xTextConnectionHelper;
+ };
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/directsql.cxx b/dbaccess/source/ui/dlg/directsql.cxx
new file mode 100644
index 000000000..ba5d9d3be
--- /dev/null
+++ b/dbaccess/source/ui/dlg/directsql.cxx
@@ -0,0 +1,430 @@
+/* -*- 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 <core_resource.hxx>
+#include <directsql.hxx>
+#include <sqledit.hxx>
+#include <strings.hxx>
+#include <strings.hrc>
+#include <comphelper/types.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdbc/XMultipleResults.hpp>
+
+namespace dbaui
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::lang;
+
+ constexpr sal_Int32 g_nHistoryLimit = 20;
+
+ // DirectSQLDialog
+ DirectSQLDialog::DirectSQLDialog(weld::Window* _pParent, const Reference< XConnection >& _rxConn)
+ : GenericDialogController(_pParent, "dbaccess/ui/directsqldialog.ui", "DirectSQLDialog")
+ , m_xExecute(m_xBuilder->weld_button("execute"))
+ , m_xSQLHistory(m_xBuilder->weld_combo_box("sqlhistory"))
+ , m_xStatus(m_xBuilder->weld_text_view("status"))
+ , m_xDirectSQL(m_xBuilder->weld_check_button("directsql"))
+ , m_xShowOutput(m_xBuilder->weld_check_button("showoutput"))
+ , m_xOutput(m_xBuilder->weld_text_view("output"))
+ , m_xClose(m_xBuilder->weld_button("close"))
+ , m_xSQL(new SQLEditView(m_xBuilder->weld_scrolled_window("scrolledwindow", true)))
+ , m_xSQLEd(new weld::CustomWeld(*m_xBuilder, "sql", *m_xSQL))
+ , m_nStatusCount(1)
+ , m_xConnection(_rxConn)
+ , m_pClosingEvent(nullptr)
+ {
+ int nWidth = m_xStatus->get_approximate_digit_width() * 60;
+ int nHeight = m_xStatus->get_height_rows(7);
+
+ m_xSQLEd->set_size_request(nWidth, nHeight);
+ m_xStatus->set_size_request(-1, nHeight);
+ m_xOutput->set_size_request(-1, nHeight);
+
+ m_xSQL->GrabFocus();
+
+ m_xExecute->connect_clicked(LINK(this, DirectSQLDialog, OnExecute));
+ m_xClose->connect_clicked(LINK(this, DirectSQLDialog, OnCloseClick));
+ m_xSQLHistory->connect_changed(LINK(this, DirectSQLDialog, OnListEntrySelected));
+
+ // add a dispose listener to the connection
+ Reference< XComponent > xConnComp(m_xConnection, UNO_QUERY);
+ OSL_ENSURE(xConnComp.is(), "DirectSQLDialog::DirectSQLDialog: invalid connection!");
+ if (xConnComp.is())
+ startComponentListening(xConnComp);
+
+ m_xSQL->SetModifyHdl(LINK(this, DirectSQLDialog, OnStatementModified));
+ OnStatementModified(nullptr);
+ }
+
+ DirectSQLDialog::~DirectSQLDialog()
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ if (m_pClosingEvent)
+ Application::RemoveUserEvent(m_pClosingEvent);
+ stopAllComponentListening();
+ }
+
+ void DirectSQLDialog::_disposing( const EventObject& _rSource )
+ {
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ assert(!m_pClosingEvent);
+
+ OSL_ENSURE(Reference< XConnection >(_rSource.Source, UNO_QUERY).get() == m_xConnection.get(),
+ "DirectSQLDialog::_disposing: where does this come from?");
+
+ {
+ OUString sMessage(DBA_RES(STR_DIRECTSQL_CONNECTIONLOST));
+ std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ sMessage));
+ xError->run();
+ }
+
+ m_pClosingEvent = Application::PostUserEvent(LINK(this, DirectSQLDialog, OnClose));
+ }
+
+ sal_Int32 DirectSQLDialog::getHistorySize() const
+ {
+ #ifdef DBG_UTIL
+ {
+ const char* pError = impl_CheckInvariants();
+ if (pError)
+ SAL_WARN("dbaccess.ui", "DirectSQLDialog::getHistorySize: " << pError);
+ }
+ #endif
+ return m_aStatementHistory.size();
+ }
+
+ void DirectSQLDialog::implEnsureHistoryLimit()
+ {
+ #ifdef DBG_UTIL
+ {
+ const char* pError = impl_CheckInvariants();
+ if (pError)
+ SAL_WARN("dbaccess.ui", "DirectSQLDialog::implEnsureHistoryLimit: " << pError);
+ }
+ #endif
+
+ if (getHistorySize() <= g_nHistoryLimit)
+ // nothing to do
+ return;
+
+ sal_Int32 nRemoveEntries = getHistorySize() - g_nHistoryLimit;
+ while (nRemoveEntries--)
+ {
+ m_aStatementHistory.pop_front();
+ m_aNormalizedHistory.pop_front();
+ m_xSQLHistory->remove(0);
+ }
+ }
+
+ void DirectSQLDialog::implAddToStatementHistory(const OUString& _rStatement)
+ {
+ #ifdef DBG_UTIL
+ {
+ const char* pError = impl_CheckInvariants();
+ if (pError)
+ SAL_WARN("dbaccess.ui", "DirectSQLDialog::implAddToStatementHistor: " << pError);
+ }
+ #endif
+
+ // add the statement to the history
+ m_aStatementHistory.push_back(_rStatement);
+
+ // normalize the statement, and remember the normalized form, too
+ OUString sNormalized = _rStatement.replaceAll("\n", " ");
+ m_aNormalizedHistory.push_back(sNormalized);
+
+ // add the normalized version to the list box
+ m_xSQLHistory->append_text(sNormalized);
+
+ // ensure that we don't exceed the history limit
+ implEnsureHistoryLimit();
+ }
+
+#ifdef DBG_UTIL
+ const char* DirectSQLDialog::impl_CheckInvariants() const
+ {
+ if (m_aStatementHistory.size() != m_aNormalizedHistory.size())
+ return "statement history is inconsistent!";
+
+ if (!m_xSQLHistory)
+ return "invalid listbox!";
+
+ if (m_aStatementHistory.size() != static_cast<size_t>(m_xSQLHistory->get_count()))
+ return "invalid listbox entry count!";
+
+ if (!m_xConnection.is())
+ return "have no connection!";
+
+ return nullptr;
+ }
+#endif
+
+ void DirectSQLDialog::implExecuteStatement(const OUString& _rStatement)
+ {
+ #ifdef DBG_UTIL
+ {
+ const char* pError = impl_CheckInvariants();
+ if (pError)
+ SAL_WARN("dbaccess.ui", "DirectSQLDialog::implExecuteStatement: " << pError);
+ }
+ #endif
+
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ OUString sStatus;
+
+ // clear the output box
+ m_xOutput->set_text(OUString());
+ try
+ {
+ // create a statement
+ Reference< XStatement > xStatement = m_xConnection->createStatement();
+
+ if (m_xDirectSQL->get_active())
+ {
+ Reference< com::sun::star::beans::XPropertySet > xStatementProps(xStatement, UNO_QUERY_THROW);
+ try
+ {
+ xStatementProps->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, Any(false));
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ }
+
+ Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
+ css::uno::Reference< css::sdbc::XMultipleResults > xMR ( xStatement, UNO_QUERY );
+
+ if (xMeta.is() && xMeta->supportsMultipleResultSets() && xMR.is())
+ {
+ bool hasRS = xStatement->execute(_rStatement);
+ if(hasRS)
+ {
+ css::uno::Reference< css::sdbc::XResultSet > xRS (xMR->getResultSet());
+ if (m_xShowOutput->get_active())
+ display(xRS);
+ }
+ else
+ addOutputText(
+ OUStringConcatenation(OUString::number(xMR->getUpdateCount()) + " rows updated\n"));
+ for (;;)
+ {
+ hasRS = xMR->getMoreResults();
+ if (!hasRS && xMR->getUpdateCount() == -1)
+ break;
+ if(hasRS)
+ {
+ css::uno::Reference< css::sdbc::XResultSet > xRS (xMR->getResultSet());
+ if (m_xShowOutput->get_active())
+ display(xRS);
+ }
+ }
+ }
+ else
+ {
+ const OUString upperStatement = _rStatement.toAsciiUpperCase();
+ if (upperStatement.startsWith("UPDATE"))
+ {
+ sal_Int32 resultCount = xStatement->executeUpdate(_rStatement);
+ addOutputText(OUStringConcatenation(OUString::number(resultCount) + " rows updated\n"));
+ }
+ else if (upperStatement.startsWith("INSERT"))
+ {
+ sal_Int32 resultCount = xStatement->executeUpdate(_rStatement);
+ addOutputText(OUStringConcatenation(OUString::number(resultCount) + " rows inserted\n"));
+ }
+ else if (upperStatement.startsWith("DELETE"))
+ {
+ sal_Int32 resultCount = xStatement->executeUpdate(_rStatement);
+ addOutputText(OUStringConcatenation(OUString::number(resultCount) + " rows deleted\n"));
+ }
+ else if (upperStatement.startsWith("CREATE"))
+ {
+ xStatement->executeUpdate(_rStatement);
+ addOutputText(u"Command executed\n");
+ }
+ else if (upperStatement.startsWith("SELECT") || m_xShowOutput->get_active())
+ {
+ css::uno::Reference< css::sdbc::XResultSet > xRS = xStatement->executeQuery(_rStatement);
+ if (m_xShowOutput->get_active())
+ display(xRS);
+ }
+ else
+ {
+ sal_Int32 resultCount = xStatement->executeUpdate(_rStatement);
+ addOutputText(OUStringConcatenation(OUString::number(resultCount) + " rows updated\n"));
+ }
+ }
+ // successful
+ sStatus = DBA_RES(STR_COMMAND_EXECUTED_SUCCESSFULLY);
+
+ // dispose the statement
+ ::comphelper::disposeComponent(xStatement);
+ }
+ catch(const SQLException& e)
+ {
+ sStatus = e.Message;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ // add the status text
+ addStatusText(sStatus);
+ }
+
+ void DirectSQLDialog::display(const css::uno::Reference< css::sdbc::XResultSet >& xRS)
+ {
+ // get a handle for the rows
+ css::uno::Reference< css::sdbc::XRow > xRow( xRS, css::uno::UNO_QUERY );
+ // work through each of the rows
+ while (xRS->next())
+ {
+ // initialise the output line for each row
+ OUStringBuffer out;
+ // work along the columns until that are none left
+ try
+ {
+ int i = 1;
+ for (;;)
+ {
+ // be dumb, treat everything as a string
+ out.append(xRow->getString(i) + ",");
+ i++;
+ }
+ }
+ // trap for when we fall off the end of the row
+ catch (const SQLException&)
+ {
+ }
+ // report the output
+ addOutputText(out);
+ }
+ }
+
+ void DirectSQLDialog::addStatusText(std::u16string_view _rMessage)
+ {
+ OUString sAppendMessage = OUString::number(m_nStatusCount++) + ": " + _rMessage + "\n\n";
+
+ OUString sCompleteMessage = m_xStatus->get_text() + sAppendMessage;
+ m_xStatus->set_text(sCompleteMessage);
+
+ m_xStatus->select_region(sCompleteMessage.getLength(), sCompleteMessage.getLength());
+ }
+
+ void DirectSQLDialog::addOutputText(std::u16string_view _rMessage)
+ {
+ OUString sAppendMessage = OUString::Concat(_rMessage) + "\n";
+
+ OUString sCompleteMessage = m_xOutput->get_text() + sAppendMessage;
+ m_xOutput->set_text(sCompleteMessage);
+ }
+
+ void DirectSQLDialog::executeCurrent()
+ {
+ #ifdef DBG_UTIL
+ {
+ const char* pError = impl_CheckInvariants();
+ if (pError)
+ SAL_WARN("dbaccess.ui", "DirectSQLDialog::executeCurrent: " << pError);
+ }
+ #endif
+
+ OUString sStatement = m_xSQL->GetText();
+
+ // execute
+ implExecuteStatement(sStatement);
+
+ // add the statement to the history
+ implAddToStatementHistory(sStatement);
+
+ m_xSQL->GrabFocus();
+ }
+
+ void DirectSQLDialog::switchToHistory(sal_Int32 _nHistoryPos)
+ {
+ #ifdef DBG_UTIL
+ {
+ const char* pError = impl_CheckInvariants();
+ if (pError)
+ SAL_WARN("dbaccess.ui", "DirectSQLDialog::switchToHistory: " << pError);
+ }
+ #endif
+
+ if ((_nHistoryPos >= 0) && (_nHistoryPos < getHistorySize()))
+ {
+ // set the text in the statement editor
+ OUString sStatement = m_aStatementHistory[_nHistoryPos];
+ m_xSQL->SetTextAndUpdate(sStatement);
+ OnStatementModified(nullptr);
+
+ m_xSQL->GrabFocus();
+ }
+ else
+ OSL_FAIL("DirectSQLDialog::switchToHistory: invalid position!");
+ }
+
+ IMPL_LINK_NOARG( DirectSQLDialog, OnStatementModified, LinkParamNone*, void )
+ {
+ m_xExecute->set_sensitive(!m_xSQL->GetText().isEmpty());
+ }
+
+ IMPL_LINK_NOARG( DirectSQLDialog, OnCloseClick, weld::Button&, void )
+ {
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK_NOARG( DirectSQLDialog, OnClose, void*, void )
+ {
+ assert(m_pClosingEvent);
+ Application::RemoveUserEvent(m_pClosingEvent);
+ m_pClosingEvent = nullptr;
+
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK_NOARG( DirectSQLDialog, OnExecute, weld::Button&, void )
+ {
+ executeCurrent();
+ }
+
+ IMPL_LINK_NOARG( DirectSQLDialog, OnListEntrySelected, weld::ComboBox&, void )
+ {
+ const sal_Int32 nSelected = m_xSQLHistory->get_active();
+ if (nSelected != -1)
+ switchToHistory(nSelected);
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dlgattr.cxx b/dbaccess/source/ui/dlg/dlgattr.cxx
new file mode 100644
index 000000000..1df2acc20
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dlgattr.cxx
@@ -0,0 +1,60 @@
+/* -*- 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 <dlgattr.hxx>
+
+#include <sfx2/tabdlg.hxx>
+
+#include <svx/numinf.hxx>
+
+#include <svx/dialogs.hrc>
+#include <svl/itemset.hxx>
+#include <svx/svxids.hrc>
+
+using namespace dbaui;
+
+
+SbaSbAttrDlg::SbaSbAttrDlg(weld::Widget* pParent, const SfxItemSet* pCellAttrs,
+ SvNumberFormatter* pFormatter, bool bHasFormat)
+ : SfxTabDialogController(pParent, "dbaccess/ui/fielddialog.ui", "FieldDialog", pCellAttrs)
+{
+ pNumberInfoItem.reset( new SvxNumberInfoItem( pFormatter, SID_ATTR_NUMBERFORMAT_INFO ) );
+
+ if (bHasFormat)
+ AddTabPage("format", RID_SVXPAGE_NUMBERFORMAT);
+ else
+ RemoveTabPage("format");
+ AddTabPage("alignment", RID_SVXPAGE_ALIGNMENT);
+}
+
+SbaSbAttrDlg::~SbaSbAttrDlg()
+{
+}
+
+void SbaSbAttrDlg::PageCreated(const OString& rPageId, SfxTabPage& rTabPage)
+{
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ if (rPageId == "format")
+ {
+ aSet.Put (SvxNumberInfoItem( pNumberInfoItem->GetNumberFormatter(), SID_ATTR_NUMBERFORMAT_INFO));
+ rTabPage.PageCreated(aSet);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dlgsave.cxx b/dbaccess/source/ui/dlg/dlgsave.cxx
new file mode 100644
index 000000000..ce5d16881
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dlgsave.cxx
@@ -0,0 +1,351 @@
+/* -*- 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 <dlgsave.hxx>
+#include <core_resource.hxx>
+#include <strings.hrc>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <connectivity/dbtools.hxx>
+#include <UITools.hxx>
+#include <SqlNameEdit.hxx>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include <objectnamecheck.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace dbaui;
+using namespace dbtools;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+namespace dbaui
+{
+
+class OSaveAsDlgImpl
+{
+public:
+ OUString m_aQryLabel;
+ OUString m_sTblLabel;
+ OUString m_aName;
+ const IObjectNameCheck& m_rObjectNameCheck;
+ css::uno::Reference< css::sdbc::XDatabaseMetaData> m_xMetaData;
+ sal_Int32 m_nType;
+ SADFlags m_nFlags;
+
+ OSQLNameChecker m_aChecker;
+
+ std::unique_ptr<weld::Label> m_xDescription;
+ std::unique_ptr<weld::Label> m_xCatalogLbl;
+ std::unique_ptr<weld::ComboBox> m_xCatalog;
+ std::unique_ptr<weld::Label> m_xSchemaLbl;
+ std::unique_ptr<weld::ComboBox> m_xSchema;
+ std::unique_ptr<weld::Label> m_xLabel;
+ std::unique_ptr<weld::Entry> m_xTitle;
+ std::unique_ptr<weld::Button> m_xPB_OK;
+
+ DECL_LINK(TextFilterHdl, OUString&, bool);
+
+ OSaveAsDlgImpl( weld::Builder* pParent, sal_Int32 _rType,
+ const css::uno::Reference< css::sdbc::XConnection>& _xConnection,
+ const OUString& rDefault,
+ const IObjectNameCheck& _rObjectNameCheck,
+ SADFlags _nFlags);
+ OSaveAsDlgImpl( weld::Builder* pParent,
+ const OUString& rDefault,
+ const IObjectNameCheck& _rObjectNameCheck,
+ SADFlags _nFlags);
+};
+
+} // dbaui
+
+IMPL_LINK(OSaveAsDlgImpl, TextFilterHdl, OUString&, rTest, bool)
+{
+ OUString sCorrected;
+ if (m_aChecker.checkString(rTest, sCorrected))
+ rTest = sCorrected;
+ return true;
+}
+
+OSaveAsDlgImpl::OSaveAsDlgImpl(weld::Builder* pBuilder,
+ sal_Int32 _rType,
+ const Reference< XConnection>& _xConnection,
+ const OUString& rDefault,
+ const IObjectNameCheck& _rObjectNameCheck,
+ SADFlags _nFlags)
+ : m_aQryLabel(DBA_RES(STR_QRY_LABEL))
+ , m_sTblLabel(DBA_RES(STR_TBL_LABEL))
+ , m_aName(rDefault)
+ , m_rObjectNameCheck( _rObjectNameCheck )
+ , m_nType(_rType)
+ , m_nFlags(_nFlags)
+ , m_aChecker(OUString())
+ , m_xDescription(pBuilder->weld_label("descriptionft"))
+ , m_xCatalogLbl(pBuilder->weld_label("catalogft"))
+ , m_xCatalog(pBuilder->weld_combo_box("catalog"))
+ , m_xSchemaLbl(pBuilder->weld_label("schemaft"))
+ , m_xSchema(pBuilder->weld_combo_box("schema"))
+ , m_xLabel(pBuilder->weld_label("titleft"))
+ , m_xTitle(pBuilder->weld_entry("title"))
+ , m_xPB_OK(pBuilder->weld_button("ok"))
+{
+ if ( _xConnection.is() )
+ m_xMetaData = _xConnection->getMetaData();
+
+ if (m_xMetaData.is())
+ {
+ OUString sExtraNameChars(m_xMetaData->getExtraNameCharacters());
+ m_aChecker.setAllowedChars(sExtraNameChars);
+ }
+
+ m_xTitle->connect_insert_text(LINK(this, OSaveAsDlgImpl, TextFilterHdl));
+ m_xSchema->connect_entry_insert_text(LINK(this, OSaveAsDlgImpl, TextFilterHdl));
+ m_xCatalog->connect_entry_insert_text(LINK(this, OSaveAsDlgImpl, TextFilterHdl));
+}
+
+OSaveAsDlgImpl::OSaveAsDlgImpl(weld::Builder* pBuilder,
+ const OUString& rDefault,
+ const IObjectNameCheck& _rObjectNameCheck,
+ SADFlags _nFlags)
+ : m_aQryLabel(DBA_RES(STR_QRY_LABEL))
+ , m_sTblLabel(DBA_RES(STR_TBL_LABEL))
+ , m_aName(rDefault)
+ , m_rObjectNameCheck( _rObjectNameCheck )
+ , m_nType(CommandType::COMMAND)
+ , m_nFlags(_nFlags)
+ , m_aChecker(OUString())
+ , m_xDescription(pBuilder->weld_label("descriptionft"))
+ , m_xCatalogLbl(pBuilder->weld_label("catalogft"))
+ , m_xCatalog(pBuilder->weld_combo_box("catalog"))
+ , m_xSchemaLbl(pBuilder->weld_label("schemaft"))
+ , m_xSchema(pBuilder->weld_combo_box("schema"))
+ , m_xLabel(pBuilder->weld_label("titleft"))
+ , m_xTitle(pBuilder->weld_entry("title"))
+ , m_xPB_OK(pBuilder->weld_button("ok"))
+{
+ m_xTitle->connect_insert_text(LINK(this, OSaveAsDlgImpl, TextFilterHdl));
+ m_xSchema->connect_entry_insert_text(LINK(this, OSaveAsDlgImpl, TextFilterHdl));
+ m_xCatalog->connect_entry_insert_text(LINK(this, OSaveAsDlgImpl, TextFilterHdl));
+}
+
+using namespace ::com::sun::star::lang;
+
+namespace
+{
+typedef Reference< XResultSet > (SAL_CALL XDatabaseMetaData::*FGetMetaStrings)();
+
+void lcl_fillComboList( weld::ComboBox& _rList, const Reference< XConnection >& _rxConnection,
+ FGetMetaStrings GetAll, const OUString& _rCurrent )
+{
+ try {
+ Reference< XDatabaseMetaData > xMetaData( _rxConnection->getMetaData(), UNO_SET_THROW );
+
+ Reference< XResultSet > xRes = (xMetaData.get()->*GetAll)();
+ Reference< XRow > xRow( xRes, UNO_QUERY_THROW );
+ OUString sValue;
+ while ( xRes->next() ) {
+ sValue = xRow->getString( 1 );
+ if ( !xRow->wasNull() )
+ _rList.append_text( sValue );
+ }
+
+ int nPos = _rList.find_text( _rCurrent );
+ if (nPos != -1)
+ _rList.set_active( nPos );
+ else
+ _rList.set_active( 0 );
+ } catch( const Exception& ) {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+}
+
+OSaveAsDlg::OSaveAsDlg( weld::Window * pParent,
+ sal_Int32 _rType,
+ const Reference< XComponentContext >& _rxContext,
+ const Reference< XConnection>& _xConnection,
+ const OUString& rDefault,
+ const IObjectNameCheck& _rObjectNameCheck,
+ SADFlags _nFlags)
+ : GenericDialogController(pParent, "dbaccess/ui/savedialog.ui", "SaveDialog")
+ , m_xContext( _rxContext )
+{
+ m_pImpl.reset( new OSaveAsDlgImpl(m_xBuilder.get(),_rType,_xConnection,rDefault,_rObjectNameCheck,_nFlags) );
+
+ switch (_rType) {
+ case CommandType::QUERY:
+ implInitOnlyTitle(m_pImpl->m_aQryLabel);
+ break;
+
+ case CommandType::TABLE:
+ OSL_ENSURE( m_pImpl->m_xMetaData.is(), "OSaveAsDlg::OSaveAsDlg: no meta data for entering table names: this will crash!" );
+ {
+ m_pImpl->m_xLabel->set_label(m_pImpl->m_sTblLabel);
+ if(m_pImpl->m_xMetaData.is() && !m_pImpl->m_xMetaData->supportsCatalogsInTableDefinitions()) {
+ m_pImpl->m_xCatalogLbl->hide();
+ m_pImpl->m_xCatalog->hide();
+ } else {
+ // now fill the catalogs
+ lcl_fillComboList( *m_pImpl->m_xCatalog, _xConnection,
+ &XDatabaseMetaData::getCatalogs, _xConnection->getCatalog() );
+ }
+
+ if ( !m_pImpl->m_xMetaData->supportsSchemasInTableDefinitions()) {
+ m_pImpl->m_xSchemaLbl->hide();
+ m_pImpl->m_xSchema->hide();
+ } else {
+ lcl_fillComboList( *m_pImpl->m_xSchema, _xConnection,
+ &XDatabaseMetaData::getSchemas, m_pImpl->m_xMetaData->getUserName() );
+ }
+
+ OSL_ENSURE(m_pImpl->m_xMetaData.is(),"The metadata can not be null!");
+ if(m_pImpl->m_aName.indexOf('.') != -1) {
+ OUString sCatalog,sSchema,sTable;
+ ::dbtools::qualifiedNameComponents(m_pImpl->m_xMetaData,
+ m_pImpl->m_aName,
+ sCatalog,
+ sSchema,
+ sTable,
+ ::dbtools::EComposeRule::InDataManipulation);
+
+ int nPos = m_pImpl->m_xCatalog->find_text(sCatalog);
+ if (nPos != -1)
+ m_pImpl->m_xCatalog->set_active(nPos);
+
+ if ( !sSchema.isEmpty() ) {
+ nPos = m_pImpl->m_xSchema->find_text(sSchema);
+ if (nPos != -1)
+ m_pImpl->m_xSchema->set_active(nPos);
+ }
+ m_pImpl->m_xTitle->set_text(sTable);
+ } else
+ m_pImpl->m_xTitle->set_text(m_pImpl->m_aName);
+ m_pImpl->m_xTitle->select_region(0, -1);
+
+ sal_Int32 nLength = m_pImpl->m_xMetaData.is() ? m_pImpl->m_xMetaData->getMaxTableNameLength() : 0;
+ if (nLength)
+ {
+ m_pImpl->m_xTitle->set_max_length(nLength);
+ m_pImpl->m_xSchema->set_entry_max_length(nLength);
+ m_pImpl->m_xCatalog->set_entry_max_length(nLength);
+ }
+
+ bool bCheck = _xConnection.is() && isSQL92CheckEnabled(_xConnection);
+ m_pImpl->m_aChecker.setCheck(bCheck); // enable non valid sql chars as well
+ }
+ break;
+
+ default:
+ OSL_FAIL( "OSaveAsDlg::OSaveAsDlg: Type not supported yet!" );
+ }
+
+ implInit();
+}
+
+OSaveAsDlg::OSaveAsDlg(weld::Window * pParent,
+ const Reference< XComponentContext >& _rxContext,
+ const OUString& rDefault,
+ const OUString& _sLabel,
+ const IObjectNameCheck& _rObjectNameCheck,
+ SADFlags _nFlags)
+ : GenericDialogController(pParent, "dbaccess/ui/savedialog.ui", "SaveDialog")
+ , m_xContext( _rxContext )
+{
+ m_pImpl.reset( new OSaveAsDlgImpl(m_xBuilder.get(),rDefault,_rObjectNameCheck,_nFlags) );
+ implInitOnlyTitle(_sLabel);
+ implInit();
+}
+
+OSaveAsDlg::~OSaveAsDlg()
+{
+}
+
+IMPL_LINK_NOARG(OSaveAsDlg, ButtonClickHdl, weld::Button&, void)
+{
+ m_pImpl->m_aName = m_pImpl->m_xTitle->get_text();
+
+ OUString sNameToCheck( m_pImpl->m_aName );
+
+ if ( m_pImpl->m_nType == CommandType::TABLE ) {
+ sNameToCheck = ::dbtools::composeTableName(
+ m_pImpl->m_xMetaData,
+ getCatalog(),
+ getSchema(),
+ sNameToCheck,
+ false, // no quoting
+ ::dbtools::EComposeRule::InDataManipulation
+ );
+ }
+
+ SQLExceptionInfo aNameError;
+ if ( m_pImpl->m_rObjectNameCheck.isNameValid( sNameToCheck, aNameError ) )
+ m_xDialog->response(RET_OK);
+
+ showError(aNameError, m_xDialog->GetXWindow(), m_xContext);
+ m_pImpl->m_xTitle->grab_focus();
+}
+
+IMPL_LINK_NOARG(OSaveAsDlg, EditModifyHdl, weld::Entry&, void)
+{
+ m_pImpl->m_xPB_OK->set_sensitive(!m_pImpl->m_xTitle->get_text().isEmpty());
+}
+
+void OSaveAsDlg::implInitOnlyTitle(const OUString& _rLabel)
+{
+ m_pImpl->m_xLabel->set_label(_rLabel);
+ m_pImpl->m_xCatalogLbl->hide();
+ m_pImpl->m_xCatalog->hide();
+ m_pImpl->m_xSchemaLbl->hide();
+ m_pImpl->m_xSchema->hide();
+
+ m_pImpl->m_xTitle->set_text(m_pImpl->m_aName);
+ m_pImpl->m_aChecker.setCheck(false); // enable non valid sql chars as well
+}
+
+void OSaveAsDlg::implInit()
+{
+ if ( !( m_pImpl->m_nFlags & SADFlags::AdditionalDescription ) ) {
+ // hide the description window
+ m_pImpl->m_xDescription->hide();
+ }
+
+ if ( SADFlags::TitlePasteAs == ( m_pImpl->m_nFlags & SADFlags::TitlePasteAs ) )
+ m_xDialog->set_title( DBA_RES( STR_TITLE_PASTE_AS ) );
+ else if ( SADFlags::TitleRename == ( m_pImpl->m_nFlags & SADFlags::TitleRename ) )
+ m_xDialog->set_title( DBA_RES( STR_TITLE_RENAME ) );
+
+ m_pImpl->m_xPB_OK->connect_clicked(LINK(this,OSaveAsDlg,ButtonClickHdl));
+ m_pImpl->m_xTitle->connect_changed(LINK(this,OSaveAsDlg,EditModifyHdl));
+ m_pImpl->m_xTitle->grab_focus();
+}
+
+const OUString& OSaveAsDlg::getName() const
+{
+ return m_pImpl->m_aName;
+}
+OUString OSaveAsDlg::getCatalog() const
+{
+ return m_pImpl->m_xCatalog->get_visible() ? m_pImpl->m_xCatalog->get_active_text() : OUString();
+}
+OUString OSaveAsDlg::getSchema() const
+{
+ return m_pImpl->m_xSchema->get_visible() ? m_pImpl->m_xSchema->get_active_text() : OUString();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dlgsize.cxx b/dbaccess/source/ui/dlg/dlgsize.cxx
new file mode 100644
index 000000000..544d9577f
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dlgsize.cxx
@@ -0,0 +1,83 @@
+/* -*- 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 <dlgsize.hxx>
+
+namespace dbaui
+{
+
+#define DEF_ROW_HEIGHT 45
+#define DEF_COL_WIDTH 227
+
+DlgSize::DlgSize(weld::Window* pParent, sal_Int32 nVal, bool bRow, sal_Int32 _nAlternativeStandard )
+ : GenericDialogController(pParent, bRow ? OUString("dbaccess/ui/rowheightdialog.ui") : OUString("dbaccess/ui/colwidthdialog.ui"),
+ bRow ? OString("RowHeightDialog") : OString("ColWidthDialog"))
+ , m_nPrevValue(nVal)
+ , m_xMF_VALUE(m_xBuilder->weld_metric_spin_button("value", FieldUnit::CM))
+ , m_xCB_STANDARD(m_xBuilder->weld_check_button("automatic"))
+{
+ sal_Int32 nStandard(bRow ? DEF_ROW_HEIGHT : DEF_COL_WIDTH);
+ if ( _nAlternativeStandard > 0 )
+ nStandard = _nAlternativeStandard;
+ m_xCB_STANDARD->connect_toggled(LINK(this,DlgSize,CbClickHdl));
+
+ bool bDefault = -1 == nVal;
+ m_xCB_STANDARD->set_active(bDefault);
+ if (bDefault)
+ {
+ SetValue(nStandard);
+ m_nPrevValue = nStandard;
+ }
+ CbClickHdl(*m_xCB_STANDARD);
+}
+
+DlgSize::~DlgSize()
+{
+}
+
+void DlgSize::SetValue( sal_Int32 nVal )
+{
+ m_xMF_VALUE->set_value(nVal, FieldUnit::CM );
+}
+
+sal_Int32 DlgSize::GetValue() const
+{
+ if (m_xCB_STANDARD->get_active())
+ return -1;
+ return static_cast<sal_Int32>(m_xMF_VALUE->get_value( FieldUnit::CM ));
+}
+
+IMPL_LINK_NOARG(DlgSize, CbClickHdl, weld::Toggleable&, void)
+{
+ m_xMF_VALUE->set_sensitive(!m_xCB_STANDARD->get_active());
+ if (m_xCB_STANDARD->get_active())
+ {
+ // don't use getValue as this will use m_xCB_STANDARD->to determine if we're standard
+ m_nPrevValue = static_cast<sal_Int32>(m_xMF_VALUE->get_value(FieldUnit::CM));
+ m_xMF_VALUE->set_text("");
+ }
+ else
+ {
+ SetValue(m_nPrevValue);
+ }
+}
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dsnItem.hxx b/dbaccess/source/ui/dlg/dsnItem.hxx
new file mode 100644
index 000000000..4ae414881
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dsnItem.hxx
@@ -0,0 +1,48 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <svl/poolitem.hxx>
+
+namespace dbaccess
+{
+ class ODsnTypeCollection;
+}
+namespace dbaui
+{
+ // DbuTypeCollectionItem
+ /** allows an ODsnTypeCollection to be transported in an SfxItemSet
+ */
+ class DbuTypeCollectionItem : public SfxPoolItem
+ {
+ ::dbaccess::ODsnTypeCollection* m_pCollection;
+
+ public:
+ DbuTypeCollectionItem(sal_Int16 nWhich, ::dbaccess::ODsnTypeCollection* _pCollection);
+ DbuTypeCollectionItem(const DbuTypeCollectionItem& _rSource);
+
+ virtual bool operator==(const SfxPoolItem& _rItem) const override;
+ virtual DbuTypeCollectionItem* Clone(SfxItemPool* _pPool = nullptr) const override;
+
+ ::dbaccess::ODsnTypeCollection* getCollection() const { return m_pCollection; }
+ };
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dsselect.cxx b/dbaccess/source/ui/dlg/dsselect.cxx
new file mode 100644
index 000000000..4c0b9a836
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dsselect.cxx
@@ -0,0 +1,133 @@
+/* -*- 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 "dsselect.hxx"
+
+#include <com/sun/star/sdbcx/XCreateCatalog.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+
+namespace dbaui
+{
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::ui::dialogs;
+
+ODatasourceSelectDialog::ODatasourceSelectDialog(weld::Window* _pParent, const std::set<OUString>& _rDatasources)
+ : GenericDialogController(_pParent, "dbaccess/ui/choosedatasourcedialog.ui", "ChooseDataSourceDialog")
+ , m_xDatasource(m_xBuilder->weld_tree_view("treeview"))
+ , m_xOk(m_xBuilder->weld_button("ok"))
+ , m_xCancel(m_xBuilder->weld_button("cancel"))
+ , m_xManageDatasources(m_xBuilder->weld_button("organize"))
+{
+ m_xDatasource->set_size_request(-1, m_xDatasource->get_height_rows(6));
+
+ fillListBox(_rDatasources);
+#ifdef HAVE_ODBC_ADMINISTRATION
+ // allow ODBC datasource management
+ m_xManageDatasources->show();
+ m_xManageDatasources->set_sensitive(true);
+ m_xManageDatasources->connect_clicked(LINK(this,ODatasourceSelectDialog,ManageClickHdl));
+#endif
+ m_xDatasource->connect_row_activated(LINK(this,ODatasourceSelectDialog,ListDblClickHdl));
+}
+
+ODatasourceSelectDialog::~ODatasourceSelectDialog()
+{
+}
+
+IMPL_LINK(ODatasourceSelectDialog, ListDblClickHdl, weld::TreeView&, rListBox, bool)
+{
+ if (rListBox.n_children())
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+short ODatasourceSelectDialog::run()
+{
+ short nRet = GenericDialogController::run();
+#ifdef HAVE_ODBC_ADMINISTRATION
+ if (m_xODBCManagement.get())
+ m_xODBCManagement->disableCallback();
+#endif
+ return nRet;
+}
+
+#ifdef HAVE_ODBC_ADMINISTRATION
+IMPL_LINK_NOARG(ODatasourceSelectDialog, ManageClickHdl, weld::Button&, void)
+{
+ if ( !m_xODBCManagement.get() )
+ m_xODBCManagement.reset( new OOdbcManagement( LINK( this, ODatasourceSelectDialog, ManageProcessFinished ) ) );
+
+ if ( !m_xODBCManagement->manageDataSources_async() )
+ {
+ // TODO: error message
+ m_xDatasource->grab_focus();
+ m_xManageDatasources->set_sensitive(false);
+ return;
+ }
+
+ m_xDatasource->set_sensitive(false);
+ m_xOk->set_sensitive(false);
+ m_xCancel->set_sensitive(false);
+ m_xManageDatasources->set_sensitive(false);
+
+ SAL_WARN_IF( !m_xODBCManagement->isRunning(), "dbaccess.ui", "ODatasourceSelectDialog::ManageClickHdl: success, but not running - you were *fast*!" );
+}
+
+IMPL_LINK_NOARG( ODatasourceSelectDialog, ManageProcessFinished, void*, void )
+{
+ m_xODBCManagement->receivedCallback();
+
+ std::set<OUString> aOdbcDatasources;
+ OOdbcEnumeration aEnumeration;
+ aEnumeration.getDatasourceNames( aOdbcDatasources );
+ fillListBox( aOdbcDatasources );
+
+ m_xDatasource->set_sensitive(true);
+ m_xOk->set_sensitive(true);
+ m_xCancel->set_sensitive(true);
+ m_xManageDatasources->set_sensitive(true);
+}
+
+#endif
+void ODatasourceSelectDialog::fillListBox(const std::set<OUString>& _rDatasources)
+{
+ OUString sSelected;
+ if (m_xDatasource->n_children())
+ sSelected = m_xDatasource->get_selected_text();
+ m_xDatasource->clear();
+ // fill the list
+ for (auto const& datasource : _rDatasources)
+ {
+ m_xDatasource->append_text(datasource);
+ }
+
+ if (m_xDatasource->n_children())
+ {
+ if (!sSelected.isEmpty())
+ m_xDatasource->select_text(sSelected);
+ else // select the first entry
+ m_xDatasource->select(0);
+ }
+}
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/dsselect.hxx b/dbaccess/source/ui/dlg/dsselect.hxx
new file mode 100644
index 000000000..87cdef17c
--- /dev/null
+++ b/dbaccess/source/ui/dlg/dsselect.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 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+#include <vcl/weld.hxx>
+
+#include <memory>
+#include <set>
+
+class SfxItemSet;
+namespace dbaui
+{
+// ODatasourceSelector
+class ODatasourceSelectDialog final : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::TreeView> m_xDatasource;
+ std::unique_ptr<weld::Button> m_xOk;
+ std::unique_ptr<weld::Button> m_xCancel;
+ std::unique_ptr<weld::Button> m_xManageDatasources;
+#ifdef HAVE_ODBC_ADMINISTRATION
+ std::unique_ptr<OOdbcManagement> m_xODBCManagement;
+#endif
+
+public:
+ ODatasourceSelectDialog(weld::Window* pParent, const std::set<OUString>& rDatasources);
+ virtual ~ODatasourceSelectDialog() override;
+ OUString GetSelected() const { return m_xDatasource->get_selected_text(); }
+ void Select(const OUString& _rEntry) { m_xDatasource->select_text(_rEntry); }
+
+ virtual short run() override;
+
+private:
+ DECL_LINK(ListDblClickHdl, weld::TreeView&, bool);
+#ifdef HAVE_ODBC_ADMINISTRATION
+ DECL_LINK(ManageClickHdl, weld::Button&, void);
+ DECL_LINK(ManageProcessFinished, void*, void);
+#endif
+ void fillListBox(const std::set<OUString>& _rDatasources);
+};
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/finteraction.cxx b/dbaccess/source/ui/dlg/finteraction.cxx
new file mode 100644
index 000000000..611119a0c
--- /dev/null
+++ b/dbaccess/source/ui/dlg/finteraction.cxx
@@ -0,0 +1,59 @@
+/* -*- 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 "finteraction.hxx"
+#include <com/sun/star/ucb/InteractiveIOException.hpp>
+
+namespace dbaui
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::task;
+ using namespace ::com::sun::star::ucb;
+
+ // OFilePickerInteractionHandler
+ OFilePickerInteractionHandler::OFilePickerInteractionHandler( const Reference< XInteractionHandler >& _rxMaster )
+ :m_xMaster( _rxMaster )
+ ,m_bDoesNotExist(false)
+ {
+ assert(m_xMaster.is());
+ }
+
+ OFilePickerInteractionHandler::~OFilePickerInteractionHandler( )
+ {
+ }
+
+ void SAL_CALL OFilePickerInteractionHandler::handle( const Reference< XInteractionRequest >& _rxRequest )
+ {
+ InteractiveIOException aIoException;
+ if ( _rxRequest->getRequest() >>= aIoException )
+ {
+ if ( IOErrorCode_NOT_EXISTING == aIoException.Code )
+ {
+ m_bDoesNotExist = true;
+ return;
+ }
+ }
+
+ if ( m_xMaster.is() )
+ m_xMaster->handle( _rxRequest );
+ }
+
+} // namespace svt
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/finteraction.hxx b/dbaccess/source/ui/dlg/finteraction.hxx
new file mode 100644
index 000000000..a487392a5
--- /dev/null
+++ b/dbaccess/source/ui/dlg/finteraction.hxx
@@ -0,0 +1,54 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+
+namespace dbaui
+{
+
+ // OFilePickerInteractionHandler
+ typedef ::cppu::WeakImplHelper< css::task::XInteractionHandler
+ > OFilePickerInteractionHandler_Base;
+
+ /** an InteractionHandler implementation which extends another handler with some customizability
+ */
+ class OFilePickerInteractionHandler final : public OFilePickerInteractionHandler_Base
+ {
+ css::uno::Reference< css::task::XInteractionHandler >
+ m_xMaster; // our master handler
+ bool m_bDoesNotExist;
+
+ public:
+ explicit OFilePickerInteractionHandler( const css::uno::Reference< css::task::XInteractionHandler >& _rxMaster );
+
+ bool isDoesNotExist() const { return m_bDoesNotExist; }
+
+ private:
+ // XInteractionHandler
+ virtual void SAL_CALL handle( const css::uno::Reference< css::task::XInteractionRequest >& _rxRequest ) override;
+
+ virtual ~OFilePickerInteractionHandler() override;
+ };
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/generalpage.cxx b/dbaccess/source/ui/dlg/generalpage.cxx
new file mode 100644
index 000000000..f7017187b
--- /dev/null
+++ b/dbaccess/source/ui/dlg/generalpage.cxx
@@ -0,0 +1,700 @@
+/* -*- 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 <config_features.h>
+#include <core_resource.hxx>
+#include "dsnItem.hxx"
+#include "generalpage.hxx"
+#include <connectivity/dbexception.hxx>
+#include <strings.hrc>
+#include <dsitems.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/docfilt.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svl/stritem.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <UITools.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/confignode.hxx>
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+#include <sal/log.hxx>
+#include <dbwizsetup.hxx>
+
+namespace dbaui
+{
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::container;
+
+ // OGeneralPage
+ OGeneralPage::OGeneralPage(weld::Container* pPage, weld::DialogController* pController, const OUString& _rUIXMLDescription, const SfxItemSet& _rItems)
+ : OGenericAdministrationPage(pPage, pController, _rUIXMLDescription, "PageGeneral", _rItems)
+ , m_xSpecialMessage(m_xBuilder->weld_label("specialMessage"))
+ , m_eLastMessage(smNone)
+ , m_bInitTypeList(true)
+ , m_xDatasourceType(m_xBuilder->weld_combo_box("datasourceType"))
+ , m_pCollection(nullptr)
+ {
+ // extract the datasource type collection from the item set
+ const DbuTypeCollectionItem* pCollectionItem = dynamic_cast<const DbuTypeCollectionItem*>( _rItems.GetItem(DSID_TYPECOLLECTION) );
+ if (pCollectionItem)
+ m_pCollection = pCollectionItem->getCollection();
+ SAL_WARN_IF(!m_pCollection, "dbaccess.ui.generalpage", "OGeneralPage::OGeneralPage : really need a DSN type collection !");
+
+ // do some knittings
+ m_xDatasourceType->connect_changed(LINK(this, OGeneralPage, OnDatasourceTypeSelected));
+ }
+
+ OGeneralPage::~OGeneralPage()
+ {
+ }
+
+ namespace
+ {
+ struct DisplayedType
+ {
+ OUString eType;
+ OUString sDisplayName;
+
+ DisplayedType( const OUString& _eType, const OUString& _rDisplayName ) : eType( _eType ), sDisplayName( _rDisplayName ) { }
+ };
+ typedef std::vector< DisplayedType > DisplayedTypes;
+
+ struct DisplayedTypeLess
+ {
+ bool operator() ( const DisplayedType& _rLHS, const DisplayedType& _rRHS )
+ {
+ return _rLHS.eType < _rRHS.eType;
+ }
+ };
+ }
+
+ void OGeneralPage::initializeTypeList()
+ {
+ if ( !m_bInitTypeList )
+ return;
+
+ m_bInitTypeList = false;
+ m_xDatasourceType->clear();
+
+ if ( !m_pCollection )
+ return;
+
+ DisplayedTypes aDisplayedTypes;
+
+ ::dbaccess::ODsnTypeCollection::TypeIterator aEnd = m_pCollection->end();
+ for ( ::dbaccess::ODsnTypeCollection::TypeIterator aTypeLoop = m_pCollection->begin();
+ aTypeLoop != aEnd;
+ ++aTypeLoop
+ )
+ {
+ const OUString& sURLPrefix = aTypeLoop.getURLPrefix();
+ if ( !sURLPrefix.isEmpty() )
+ {
+ // skip mysql connection variations. It is handled in another window.
+ if(sURLPrefix.startsWith("sdbc:mysql:") && !sURLPrefix.startsWith("sdbc:mysql:jdbc:"))
+ continue;
+
+ OUString sDisplayName = aTypeLoop.getDisplayName();
+ if (m_xDatasourceType->find_text(sDisplayName) == -1 &&
+ approveDatasourceType(sURLPrefix, sDisplayName))
+ {
+ aDisplayedTypes.emplace_back( sURLPrefix, sDisplayName );
+ }
+ }
+ }
+ std::sort( aDisplayedTypes.begin(), aDisplayedTypes.end(), DisplayedTypeLess() );
+ for ( const auto& rDisplayedType : aDisplayedTypes )
+ insertDatasourceTypeEntryData( rDisplayedType.eType, rDisplayedType.sDisplayName );
+ }
+
+ void OGeneralPageWizard::initializeEmbeddedDBList()
+ {
+ if ( !m_bInitEmbeddedDBList )
+ return;
+
+ m_bInitEmbeddedDBList = false;
+ m_xEmbeddedDBType->clear();
+
+ if ( !m_pCollection )
+ return;
+
+ DisplayedTypes aDisplayedTypes;
+
+ ::dbaccess::ODsnTypeCollection::TypeIterator aEnd = m_pCollection->end();
+ for ( ::dbaccess::ODsnTypeCollection::TypeIterator aTypeLoop = m_pCollection->begin();
+ aTypeLoop != aEnd;
+ ++aTypeLoop
+ )
+ {
+ const OUString& sURLPrefix = aTypeLoop.getURLPrefix();
+ if ( !sURLPrefix.isEmpty() )
+ {
+ OUString sDisplayName = aTypeLoop.getDisplayName();
+ if (m_xEmbeddedDBType->find_text(sDisplayName) == -1 &&
+ dbaccess::ODsnTypeCollection::isEmbeddedDatabase(sURLPrefix))
+ {
+#if !HAVE_FEATURE_MACOSX_SANDBOX
+ if( !officecfg::Office::Common::Misc::ExperimentalMode::get()
+ && sURLPrefix.startsWith("sdbc:embedded:firebird") )
+ continue;
+#endif
+ aDisplayedTypes.emplace_back( sURLPrefix, sDisplayName );
+ m_bIsDisplayedTypesEmpty = false;
+ }
+ }
+ }
+ std::sort( aDisplayedTypes.begin(), aDisplayedTypes.end(), DisplayedTypeLess() );
+ for (auto const& displayedType : aDisplayedTypes)
+ insertEmbeddedDBTypeEntryData( displayedType.eType, displayedType.sDisplayName );
+ }
+
+ void OGeneralPage::setParentTitle(const OUString&)
+ {
+ }
+
+ void OGeneralPage::switchMessage(std::u16string_view _sURLPrefix)
+ {
+ SPECIAL_MESSAGE eMessage = smNone;
+ if ( _sURLPrefix.empty()/*_eType == m_eNotSupportedKnownType*/ )
+ {
+ eMessage = smUnsupportedType;
+ }
+
+ if ( eMessage != m_eLastMessage )
+ {
+ TranslateId pResId;
+ if ( smUnsupportedType == eMessage )
+ pResId = STR_UNSUPPORTED_DATASOURCE_TYPE;
+ OUString sMessage;
+ if ( pResId )
+ sMessage = DBA_RES(pResId);
+
+ m_xSpecialMessage->set_label( sMessage );
+ m_eLastMessage = eMessage;
+ }
+ }
+
+ void OGeneralPage::onTypeSelected(const OUString& _sURLPrefix)
+ {
+ // the new URL text as indicated by the selection history
+ implSetCurrentType( _sURLPrefix );
+
+ switchMessage(_sURLPrefix);
+
+ m_aTypeSelectHandler.Call(*this);
+ }
+
+ void OGeneralPage::implInitControls( const SfxItemSet& _rSet, bool _bSaveValue )
+ {
+ initializeTypeList();
+
+ m_xDatasourceType->set_active_text(getDatasourceName(_rSet));
+
+ // notify our listener that our type selection has changed (if so)
+ // FIXME: how to detect that it did not changed? (fdo#62937)
+ setParentTitle( m_eCurrentSelection );
+ onTypeSelected( m_eCurrentSelection );
+
+ // a special message for the current page state
+ switchMessage( m_eCurrentSelection );
+
+ OGenericAdministrationPage::implInitControls( _rSet, _bSaveValue );
+ }
+
+ OUString OGeneralPageWizard::getEmbeddedDBName( const SfxItemSet& _rSet )
+ {
+ // first check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags( _rSet, bValid, bReadonly );
+
+ // if the selection is invalid, disable everything
+
+ implSetCurrentType( OUString() );
+
+ // compare the DSN prefix with the registered ones
+ OUString sDisplayName;
+
+ if (m_pCollection && bValid)
+ {
+ implSetCurrentType( dbaccess::ODsnTypeCollection::getEmbeddedDatabase() );
+ sDisplayName = m_pCollection->getTypeDisplayName( m_eCurrentSelection );
+ onTypeSelected(m_eCurrentSelection);
+ }
+
+ // select the correct datasource type
+ if ( dbaccess::ODsnTypeCollection::isEmbeddedDatabase( m_eCurrentSelection )
+ && m_xEmbeddedDBType->find_text(sDisplayName) == -1 )
+ { // this indicates it's really a type which is known in general, but not supported on the current platform
+ // show a message saying so
+ // eSpecialMessage = smUnsupportedType;
+ insertEmbeddedDBTypeEntryData( m_eCurrentSelection, sDisplayName );
+ }
+
+ return sDisplayName;
+ }
+
+ OUString OGeneralPage::getDatasourceName( const SfxItemSet& _rSet )
+ {
+ // first check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags( _rSet, bValid, bReadonly );
+
+ // if the selection is invalid, disable everything
+ OUString sConnectURL;
+ if ( bValid )
+ {
+ // collect some items and some values
+ const SfxStringItem* pUrlItem = _rSet.GetItem<SfxStringItem>(DSID_CONNECTURL);
+ assert( pUrlItem );
+ sConnectURL = pUrlItem->GetValue();
+ }
+
+ implSetCurrentType( OUString() );
+
+ // compare the DSN prefix with the registered ones
+ OUString sDisplayName;
+
+ if (m_pCollection && bValid)
+ {
+ implSetCurrentType( m_pCollection->getPrefix( sConnectURL ) );
+ sDisplayName = m_pCollection->getTypeDisplayName( m_eCurrentSelection );
+ }
+
+ // select the correct datasource type
+ if ( approveDatasourceType( m_eCurrentSelection, sDisplayName )
+ && m_xDatasourceType->find_text(sDisplayName) == -1 )
+ { // this indicates it's really a type which is known in general, but not supported on the current platform
+ // show a message saying so
+ // eSpecialMessage = smUnsupportedType;
+ insertDatasourceTypeEntryData( m_eCurrentSelection, sDisplayName );
+ }
+
+ return sDisplayName;
+ }
+
+ // For the databaseWizard we only have one entry for the MySQL Database,
+ // because we have a separate tabpage to retrieve the respective datasource type
+ // ( ::dbaccess::DST_MYSQL_ODBC || ::dbaccess::DST_MYSQL_JDBC). Therefore we use ::dbaccess::DST_MYSQL_JDBC as a temporary
+ // representative for all MySQl databases)
+ // Also, embedded databases (embedded HSQL, at the moment), are not to appear in the list of
+ // databases to connect to.
+ bool OGeneralPage::approveDatasourceType( std::u16string_view _sURLPrefix, OUString& _inout_rDisplayName )
+ {
+ return approveDatasourceType( m_pCollection->determineType(_sURLPrefix), _inout_rDisplayName );
+ }
+
+ bool OGeneralPage::approveDatasourceType( ::dbaccess::DATASOURCE_TYPE eType, OUString& _inout_rDisplayName )
+ {
+ if ( eType == ::dbaccess::DST_MYSQL_NATIVE_DIRECT )
+ {
+ // do not display the Connector/OOo driver itself, it is always wrapped via the MySQL-Driver, if
+ // this driver is installed
+ if ( m_pCollection->hasDriver( "sdbc:mysql:mysqlc:" ) )
+ _inout_rDisplayName.clear();
+ }
+
+ if ( eType == ::dbaccess::DST_EMBEDDED_HSQLDB
+ || eType == ::dbaccess::DST_EMBEDDED_FIREBIRD )
+ _inout_rDisplayName.clear();
+
+ return _inout_rDisplayName.getLength() > 0;
+ }
+
+ void OGeneralPage::insertDatasourceTypeEntryData(const OUString& _sType, const OUString& sDisplayName)
+ {
+ // insert a (temporary) entry
+ m_xDatasourceType->append_text(sDisplayName);
+ m_aURLPrefixes.push_back(_sType);
+ }
+
+ void OGeneralPageWizard::insertEmbeddedDBTypeEntryData(const OUString& _sType, const OUString& sDisplayName)
+ {
+ // insert a (temporary) entry
+ m_xEmbeddedDBType->append_text(sDisplayName);
+ m_aEmbeddedURLPrefixes.push_back(_sType);
+ }
+
+ void OGeneralPage::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Label>(m_xSpecialMessage.get()));
+ }
+
+ void OGeneralPage::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new OSaveValueWidgetWrapper<weld::ComboBox>(m_xDatasourceType.get()));
+ }
+
+ void OGeneralPage::implSetCurrentType( const OUString& _eType )
+ {
+ if ( _eType == m_eCurrentSelection )
+ return;
+
+ m_eCurrentSelection = _eType;
+ }
+
+ void OGeneralPage::Reset(const SfxItemSet* _rCoreAttrs)
+ {
+ // reset all locale data
+ implSetCurrentType( OUString() );
+ // this ensures that our type selection link will be called, even if the new one is the same as the
+ // current one
+ OGenericAdministrationPage::Reset(_rCoreAttrs);
+ }
+
+ IMPL_LINK( OGeneralPageWizard, OnEmbeddedDBTypeSelected, weld::ComboBox&, _rBox, void )
+ {
+ // get the type from the entry data
+ const sal_Int32 nSelected = _rBox.get_active();
+ if (o3tl::make_unsigned(nSelected) >= m_aEmbeddedURLPrefixes.size() )
+ {
+ SAL_WARN("dbaccess.ui.generalpage", "Got out-of-range value '" << nSelected << "' from the DatasourceType selection ListBox's GetSelectedEntryPos(): no corresponding URL prefix");
+ return;
+ }
+ const OUString sURLPrefix = m_aEmbeddedURLPrefixes[ nSelected ];
+
+ setParentTitle( sURLPrefix );
+ // let the impl method do all the stuff
+ onTypeSelected( sURLPrefix );
+ // tell the listener we were modified
+ callModifiedHdl();
+ }
+
+ IMPL_LINK( OGeneralPage, OnDatasourceTypeSelected, weld::ComboBox&, _rBox, void )
+ {
+ // get the type from the entry data
+ const sal_Int32 nSelected = _rBox.get_active();
+ if (nSelected == -1)
+ return;
+ if (o3tl::make_unsigned(nSelected) >= m_aURLPrefixes.size() )
+ {
+ SAL_WARN("dbaccess.ui.generalpage", "Got out-of-range value '" << nSelected << "' from the DatasourceType selection ListBox's GetSelectedEntryPos(): no corresponding URL prefix");
+ return;
+ }
+ const OUString sURLPrefix = m_aURLPrefixes[ nSelected ];
+
+ setParentTitle( sURLPrefix );
+ // let the impl method do all the stuff
+ onTypeSelected( sURLPrefix );
+ // tell the listener we were modified
+ callModifiedHdl();
+ }
+
+ // OGeneralPageDialog
+ OGeneralPageDialog::OGeneralPageDialog(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rItems)
+ : OGeneralPage(pPage, pController, "dbaccess/ui/generalpagedialog.ui", _rItems)
+ {
+ }
+
+ void OGeneralPageDialog::setParentTitle( const OUString& _sURLPrefix )
+ {
+ const OUString sName = m_pCollection->getTypeDisplayName( _sURLPrefix );
+ if ( m_pAdminDialog )
+ {
+ OUString sMessage = DBA_RES(STR_PARENTTITLE_GENERAL);
+ m_pAdminDialog->setTitle( sMessage.replaceAll( "#", sName ) );
+ }
+ }
+
+ void OGeneralPageDialog::implInitControls( const SfxItemSet& _rSet, bool _bSaveValue )
+ {
+ OGeneralPage::implInitControls( _rSet, _bSaveValue );
+
+ // first check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly );
+
+ m_xDatasourceType->set_sensitive( bValid );
+ }
+
+ bool OGeneralPageDialog::FillItemSet( SfxItemSet* _rCoreAttrs )
+ {
+ bool bChangedSomething = false;
+
+ const sal_Int32 nEntry = m_xDatasourceType->get_active();
+ OUString sURLPrefix = m_aURLPrefixes[ nEntry ];
+
+ if (m_xDatasourceType->get_value_changed_from_saved())
+ {
+ _rCoreAttrs->Put( SfxStringItem( DSID_CONNECTURL, sURLPrefix ) );
+ bChangedSomething = true;
+ }
+
+ return bChangedSomething;
+ }
+
+ // OGeneralPageWizard
+ OGeneralPageWizard::OGeneralPageWizard(weld::Container* pPage, ODbTypeWizDialogSetup* pController, const SfxItemSet& _rItems)
+ : OGeneralPage( pPage, pController, "dbaccess/ui/generalpagewizard.ui", _rItems )
+ , m_xRB_CreateDatabase(m_xBuilder->weld_radio_button("createDatabase"))
+ , m_xRB_OpenExistingDatabase(m_xBuilder->weld_radio_button("openExistingDatabase"))
+ , m_xRB_ConnectDatabase(m_xBuilder->weld_radio_button("connectDatabase"))
+ , m_xFT_EmbeddedDBLabel(m_xBuilder->weld_label("embeddeddbLabel"))
+ , m_xEmbeddedDBType(m_xBuilder->weld_combo_box("embeddeddbList"))
+ , m_xFT_DocListLabel(m_xBuilder->weld_label("docListLabel"))
+ , m_xFT_HelpText(m_xBuilder->weld_label("helpText"))
+ , m_xLB_DocumentList(new OpenDocumentListBox(m_xBuilder->weld_combo_box("documentList"), "com.sun.star.sdb.OfficeDatabaseDocument"))
+ , m_xPB_OpenDatabase(new OpenDocumentButton(m_xBuilder->weld_button("openDatabase"), "com.sun.star.sdb.OfficeDatabaseDocument"))
+ , m_xFT_NoEmbeddedDBLabel(m_xBuilder->weld_label("noembeddeddbLabel"))
+ , m_eOriginalCreationMode(eCreateNew)
+ , m_bInitEmbeddedDBList(true)
+ , m_bIsDisplayedTypesEmpty(true)
+ {
+ // If no driver for embedded DBs is installed, and no dBase driver, then hide the "Create new database" option
+ sal_Int32 nCreateNewDBIndex = m_pCollection->getIndexOf( dbaccess::ODsnTypeCollection::getEmbeddedDatabase() );
+ if ( nCreateNewDBIndex == -1 )
+ nCreateNewDBIndex = m_pCollection->getIndexOf( u"sdbc:dbase:" );
+ bool bHideCreateNew = ( nCreateNewDBIndex == -1 );
+
+ // also, if our application policies tell us to hide the option, do it
+ ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithComponentContext(
+ ::comphelper::getProcessComponentContext(),
+ "/org.openoffice.Office.DataAccess/Policies/Features/Base"
+ ) );
+ bool bAllowCreateLocalDatabase( true );
+ OSL_VERIFY( aConfig.getNodeValue( "CreateLocalDatabase" ) >>= bAllowCreateLocalDatabase );
+ if ( !bAllowCreateLocalDatabase )
+ bHideCreateNew = true;
+
+ if ( bHideCreateNew )
+ {
+ m_xRB_CreateDatabase->hide();
+ m_xRB_ConnectDatabase->set_active(true);
+ }
+ else
+ m_xRB_CreateDatabase->set_active(true);
+
+ // do some knittings
+ m_xEmbeddedDBType->connect_changed(LINK(this, OGeneralPageWizard, OnEmbeddedDBTypeSelected));
+ m_xRB_CreateDatabase->connect_toggled( LINK( this, OGeneralPageWizard, OnSetupModeSelected ) );
+ m_xRB_ConnectDatabase->connect_toggled( LINK( this, OGeneralPageWizard, OnSetupModeSelected ) );
+ m_xRB_OpenExistingDatabase->connect_toggled( LINK( this, OGeneralPageWizard, OnSetupModeSelected ) );
+ m_xLB_DocumentList->connect_changed( LINK( this, OGeneralPageWizard, OnDocumentSelected ) );
+ m_xPB_OpenDatabase->connect_clicked( LINK( this, OGeneralPageWizard, OnOpenDocument ) );
+ m_xFT_NoEmbeddedDBLabel->hide();
+
+ pController->SetGeneralPage(this);
+ }
+
+ OGeneralPageWizard::~OGeneralPageWizard()
+ {
+ }
+
+ OGeneralPageWizard::CreationMode OGeneralPageWizard::GetDatabaseCreationMode() const
+ {
+ if ( m_xRB_CreateDatabase->get_active() )
+ return eCreateNew;
+ if ( m_xRB_ConnectDatabase->get_active() )
+ return eConnectExternal;
+ return eOpenExisting;
+ }
+
+ void OGeneralPageWizard::implInitControls( const SfxItemSet& _rSet, bool _bSaveValue )
+ {
+ OGeneralPage::implInitControls( _rSet, _bSaveValue );
+
+ initializeEmbeddedDBList();
+ m_xEmbeddedDBType->set_active_text(getEmbeddedDBName(_rSet));
+
+ if(m_bIsDisplayedTypesEmpty)
+ {
+ m_xRB_CreateDatabase->set_sensitive(false);
+ m_xFT_EmbeddedDBLabel->hide();
+ m_xEmbeddedDBType->hide();
+ m_xFT_NoEmbeddedDBLabel->show();
+ m_xRB_OpenExistingDatabase->set_active(true);
+ }
+
+ // first check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags( _rSet, bValid, bReadonly );
+
+ SetPageTitle(OUString());
+
+ if ( !bValid || bReadonly )
+ {
+ m_xFT_EmbeddedDBLabel->set_sensitive( false );
+ m_xDatasourceType->set_sensitive( false );
+ m_xPB_OpenDatabase->set_sensitive( false );
+ m_xFT_DocListLabel->set_sensitive( false );
+ m_xLB_DocumentList->set_sensitive( false );
+ }
+
+ if (m_xLB_DocumentList->get_count())
+ m_xLB_DocumentList->set_active(0);
+
+ m_eOriginalCreationMode = GetDatabaseCreationMode();
+
+ SetupModeSelected();
+ }
+
+ OUString OGeneralPageWizard::getDatasourceName(const SfxItemSet& _rSet)
+ {
+ // Sets the default selected database on startup.
+ if (m_xRB_CreateDatabase->get_active() )
+ {
+ return m_pCollection->getTypeDisplayName( u"sdbc:firebird:" );
+ }
+
+ return OGeneralPage::getDatasourceName( _rSet );
+ }
+
+ bool OGeneralPageWizard::approveDatasourceType( ::dbaccess::DATASOURCE_TYPE eType, OUString& _inout_rDisplayName )
+ {
+ switch ( eType )
+ {
+ case ::dbaccess::DST_MYSQL_JDBC:
+ case ::dbaccess::DST_MYSQL_ODBC:
+ case ::dbaccess::DST_MYSQL_NATIVE:
+ _inout_rDisplayName = "MySQL/MariaDB";
+ break;
+ default:
+ break;
+ }
+
+ return OGeneralPage::approveDatasourceType( eType, _inout_rDisplayName );
+ }
+
+ bool OGeneralPageWizard::FillItemSet(SfxItemSet* _rCoreAttrs)
+ {
+ bool bChangedSomething = false;
+
+ bool bCommitTypeSelection = true;
+
+ if ( m_xRB_CreateDatabase->get_active() )
+ {
+ _rCoreAttrs->Put( SfxStringItem( DSID_CONNECTURL, "sdbc:dbase:" ) );
+ bChangedSomething = true;
+ bCommitTypeSelection = false;
+ }
+ else if ( m_xRB_OpenExistingDatabase->get_active() )
+ {
+ if ( m_xRB_OpenExistingDatabase->get_state_changed_from_saved() )
+ bChangedSomething = true;
+
+ // TODO
+ bCommitTypeSelection = false;
+ }
+
+ if ( bCommitTypeSelection )
+ {
+ const sal_Int32 nEntry = m_xDatasourceType->get_active();
+ OUString sURLPrefix = m_aURLPrefixes[nEntry];
+
+ if ( m_xDatasourceType->get_value_changed_from_saved()
+ || ( GetDatabaseCreationMode() != m_eOriginalCreationMode )
+ )
+ {
+ _rCoreAttrs->Put( SfxStringItem( DSID_CONNECTURL,sURLPrefix ) );
+ bChangedSomething = true;
+ }
+ else
+ implSetCurrentType( sURLPrefix );
+ }
+ return bChangedSomething;
+ }
+
+ OUString OGeneralPageWizard::GetSelectedDocumentURL() const
+ {
+ if ( !m_aBrowsedDocumentURL.isEmpty() )
+ return m_aBrowsedDocumentURL;
+ else
+ return m_xLB_DocumentList->GetSelectedDocumentURL();
+ }
+
+ void OGeneralPageWizard::EnableControls()
+ {
+ bool bValid, bReadonly;
+ getFlags( GetItemSet(), bValid, bReadonly );
+ if ( bValid && !bReadonly )
+ {
+ m_xEmbeddedDBType->set_sensitive(m_xRB_CreateDatabase->get_active());
+ m_xFT_EmbeddedDBLabel->set_sensitive(m_xRB_CreateDatabase->get_active());
+ m_xDatasourceType->set_sensitive(m_xRB_ConnectDatabase->get_active());
+ m_xPB_OpenDatabase->set_sensitive(m_xRB_OpenExistingDatabase->get_active());
+ m_xFT_DocListLabel->set_sensitive(m_xRB_OpenExistingDatabase->get_active());
+ m_xLB_DocumentList->set_sensitive(m_xRB_OpenExistingDatabase->get_active());
+ }
+ }
+
+ void OGeneralPageWizard::SetupModeSelected()
+ {
+ m_aCreationModeHandler.Call( *this );
+
+ if (m_xRB_CreateDatabase->get_active())
+ OnEmbeddedDBTypeSelected(*m_xEmbeddedDBType);
+ else
+ OnDatasourceTypeSelected(*m_xDatasourceType);
+
+ EnableControls();
+ }
+
+ IMPL_LINK(OGeneralPageWizard, OnSetupModeSelected, weld::Toggleable&, rButton, void)
+ {
+ if (!rButton.get_active())
+ return;
+ SetupModeSelected();
+ }
+
+ IMPL_LINK_NOARG( OGeneralPageWizard, OnDocumentSelected, weld::ComboBox&, void )
+ {
+ m_aDocumentSelectionHandler.Call( *this );
+ }
+
+ IMPL_LINK_NOARG( OGeneralPageWizard, OnOpenDocument, weld::Button&, void )
+ {
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
+ FileDialogFlags::NONE, "sdatabase", SfxFilterFlags::NONE, SfxFilterFlags::NONE, GetFrameWeld());
+ aFileDlg.SetContext(sfx2::FileDialogHelper::BaseDataSource);
+ std::shared_ptr<const SfxFilter> pFilter = getStandardDatabaseFilter();
+ if ( pFilter )
+ {
+ aFileDlg.SetCurrentFilter(pFilter->GetUIName());
+ }
+ if ( aFileDlg.Execute() != ERRCODE_NONE )
+ return;
+
+ OUString sPath = aFileDlg.GetPath();
+ // check for aFileDlg.GetCurrentFilter used to be here but current fpicker filter
+ // can be set to anything, see tdf#125267 how this breaks if other value
+ // than 'ODF Database' is selected. Let's therefore check only if wildcard matches
+ if ( !pFilter->GetWildcard().Matches(sPath) )
+ {
+ OUString sMessage(DBA_RES(STR_ERR_USE_CONNECT_TO));
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ sMessage));
+ xInfoBox->run();
+ m_xRB_ConnectDatabase->set_active(true);
+ OnSetupModeSelected( *m_xRB_ConnectDatabase );
+ return;
+ }
+ m_aBrowsedDocumentURL = sPath;
+ m_aChooseDocumentHandler.Call( *this );
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/generalpage.hxx b/dbaccess/source/ui/dlg/generalpage.hxx
new file mode 100644
index 000000000..1abda980e
--- /dev/null
+++ b/dbaccess/source/ui/dlg/generalpage.hxx
@@ -0,0 +1,189 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "adminpages.hxx"
+#include <opendoccontrols.hxx>
+
+namespace dbaui
+{
+ class ODbTypeWizDialogSetup;
+
+ // OGeneralPage
+ class OGeneralPage : public OGenericAdministrationPage
+ {
+ protected:
+ OGeneralPage(weld::Container* pPage, weld::DialogController* pController, const OUString& _rUIXMLDescription, const SfxItemSet& _rItems);
+
+ OUString m_eCurrentSelection; /// currently selected type
+
+ private:
+ std::unique_ptr<weld::Label> m_xSpecialMessage;
+
+ enum SPECIAL_MESSAGE
+ {
+ smNone,
+ smUnsupportedType
+ };
+ SPECIAL_MESSAGE m_eLastMessage;
+
+ Link<OGeneralPage&,void> m_aTypeSelectHandler; /// to be called if a new type is selected
+ bool m_bInitTypeList : 1;
+ bool approveDatasourceType( std::u16string_view _sURLPrefix, OUString& _inout_rDisplayName );
+ void insertDatasourceTypeEntryData( const OUString& _sType, const OUString& sDisplayName );
+
+ protected:
+ std::unique_ptr<weld::ComboBox> m_xDatasourceType;
+
+ ::dbaccess::ODsnTypeCollection*
+ m_pCollection; /// the DSN type collection instance
+
+ std::vector< OUString>
+ m_aURLPrefixes;
+
+ public:
+ virtual ~OGeneralPage() override;
+
+ /// set a handler which gets called every time the user selects a new type
+ void SetTypeSelectHandler( const Link<OGeneralPage&,void>& _rHandler ) { m_aTypeSelectHandler = _rHandler; }
+
+ /// get the currently selected datasource type
+ const OUString& GetSelectedType() const { return m_eCurrentSelection; }
+
+ protected:
+ // SfxTabPage overridables
+ virtual void Reset( const SfxItemSet* _rCoreAttrs ) override;
+
+ virtual void implInitControls( const SfxItemSet& _rSet, bool _bSaveValue ) override;
+ virtual OUString getDatasourceName( const SfxItemSet& _rSet );
+ virtual bool approveDatasourceType( ::dbaccess::DATASOURCE_TYPE eType, OUString& _inout_rDisplayName );
+
+ // <method>OGenericAdministrationPage::fillControls</method>
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ // <method>OGenericAdministrationPage::fillWindows</method>
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ void onTypeSelected(const OUString& _sURLPrefix);
+
+ /**
+ * Initializes the listbox, which contains entries each representing a
+ * connection to an existing database.
+ */
+ void initializeTypeList();
+
+ void implSetCurrentType( const OUString& _eType );
+
+ void switchMessage(std::u16string_view _sURLPrefix);
+
+ /// sets the title of the parent dialog
+ virtual void setParentTitle( const OUString& _sURLPrefix );
+
+ DECL_LINK(OnDatasourceTypeSelected, weld::ComboBox&, void);
+ };
+
+ // OGeneralPageDialog
+ class OGeneralPageDialog : public OGeneralPage
+ {
+ public:
+ OGeneralPageDialog(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rItems);
+
+ protected:
+ virtual bool FillItemSet( SfxItemSet* _rCoreAttrs ) override;
+
+ virtual void implInitControls( const SfxItemSet& _rSet, bool _bSaveValue ) override;
+ virtual void setParentTitle( const OUString& _sURLPrefix ) override;
+ };
+
+ // OGeneralPageWizard
+ class OGeneralPageWizard final : public OGeneralPage
+ {
+ public:
+ OGeneralPageWizard( weld::Container* pPage, ODbTypeWizDialogSetup* pController, const SfxItemSet& _rItems );
+ virtual ~OGeneralPageWizard() override;
+
+ enum CreationMode
+ {
+ eCreateNew,
+ eConnectExternal,
+ eOpenExisting
+ };
+
+ private:
+ // dialog controls
+ std::unique_ptr<weld::RadioButton> m_xRB_CreateDatabase;
+ std::unique_ptr<weld::RadioButton> m_xRB_OpenExistingDatabase;
+ std::unique_ptr<weld::RadioButton> m_xRB_ConnectDatabase;
+
+ std::unique_ptr<weld::Label> m_xFT_EmbeddedDBLabel;
+ std::unique_ptr<weld::ComboBox> m_xEmbeddedDBType;
+
+ std::unique_ptr<weld::Label> m_xFT_DocListLabel;
+ std::unique_ptr<weld::Label> m_xFT_HelpText;
+ std::unique_ptr<OpenDocumentListBox> m_xLB_DocumentList;
+ std::unique_ptr<OpenDocumentButton> m_xPB_OpenDatabase;
+
+ std::unique_ptr<weld::Label> m_xFT_NoEmbeddedDBLabel;
+
+ // state
+ OUString m_aBrowsedDocumentURL;
+ CreationMode m_eOriginalCreationMode;
+
+ Link<OGeneralPageWizard&,void> m_aCreationModeHandler; /// to be called if a new type is selected
+ Link<OGeneralPageWizard&,void> m_aDocumentSelectionHandler; /// to be called when a document in the RecentDoc list is selected
+ Link<OGeneralPageWizard&,void> m_aChooseDocumentHandler; /// to be called when a recent document has been definitely chosen
+
+ bool m_bInitEmbeddedDBList : 1;
+ bool m_bIsDisplayedTypesEmpty : 1;
+ void insertEmbeddedDBTypeEntryData( const OUString& _sType, const OUString& sDisplayName );
+
+ void EnableControls();
+
+ public:
+ void SetCreationModeHandler( const Link<OGeneralPageWizard&,void>& _rHandler ) { m_aCreationModeHandler = _rHandler; }
+ CreationMode GetDatabaseCreationMode() const;
+
+ void SetDocumentSelectionHandler( const Link<OGeneralPageWizard&,void>& _rHandler) { m_aDocumentSelectionHandler = _rHandler; }
+ void SetChooseDocumentHandler( const Link<OGeneralPageWizard&,void>& _rHandler) { m_aChooseDocumentHandler = _rHandler; }
+ OUString GetSelectedDocumentURL() const;
+
+ private:
+ virtual bool FillItemSet( SfxItemSet* _rCoreAttrs ) override;
+
+ virtual void implInitControls( const SfxItemSet& _rSet, bool _bSaveValue ) override;
+ virtual OUString getDatasourceName( const SfxItemSet& _rSet ) override;
+ virtual bool approveDatasourceType( ::dbaccess::DATASOURCE_TYPE eType, OUString& _inout_rDisplayName ) override;
+
+ std::vector< OUString>
+ m_aEmbeddedURLPrefixes;
+
+ OUString getEmbeddedDBName( const SfxItemSet& _rSet );
+ void initializeEmbeddedDBList();
+
+ void SetupModeSelected();
+
+ DECL_LINK( OnEmbeddedDBTypeSelected, weld::ComboBox&, void );
+ DECL_LINK( OnSetupModeSelected, weld::Toggleable&, void );
+ DECL_LINK( OnDocumentSelected, weld::ComboBox&, void );
+ DECL_LINK( OnOpenDocument, weld::Button&, void );
+ };
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/indexdialog.cxx b/dbaccess/source/ui/dlg/indexdialog.cxx
new file mode 100644
index 000000000..4c9312848
--- /dev/null
+++ b/dbaccess/source/ui/dlg/indexdialog.cxx
@@ -0,0 +1,707 @@
+/* -*- 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 <set>
+
+#include <core_resource.hxx>
+#include <indexdialog.hxx>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <indexfieldscontrol.hxx>
+#include <indexcollection.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <connectivity/dbtools.hxx>
+#include <osl/diagnose.h>
+
+namespace dbaui
+{
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::lang;
+ using namespace ::dbtools;
+
+ // helper
+ static bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS)
+ {
+ return (_rLHS.sFieldName == _rRHS.sFieldName)
+ && (_rLHS.bSortAscending == _rRHS.bSortAscending);
+ }
+
+ static bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS)
+ {
+ return std::equal(_rLHS.begin(), _rLHS.end(), _rRHS.begin(), _rRHS.end());
+ }
+
+ static bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS)
+ {
+ return !(_rLHS == _rRHS);
+ }
+
+ // DbaIndexDialog
+ DbaIndexDialog::DbaIndexDialog(weld::Window* pParent, const Sequence< OUString >& _rFieldNames,
+ const Reference< XNameAccess >& _rxIndexes,
+ const Reference< XConnection >& _rxConnection,
+ const Reference< XComponentContext >& _rxContext)
+ : GenericDialogController(pParent, "dbaccess/ui/indexdesigndialog.ui", "IndexDesignDialog")
+ , m_xConnection(_rxConnection)
+ , m_bEditingActive(false)
+ , m_bEditAgain(false)
+ , m_bNoHandlerCall(false)
+ , m_xContext(_rxContext)
+ , m_xActions(m_xBuilder->weld_toolbar("ACTIONS"))
+ , m_xIndexList(m_xBuilder->weld_tree_view("INDEX_LIST"))
+ , m_xIndexDetails(m_xBuilder->weld_label("INDEX_DETAILS"))
+ , m_xDescriptionLabel(m_xBuilder->weld_label("DESC_LABEL"))
+ , m_xDescription(m_xBuilder->weld_label("DESCRIPTION"))
+ , m_xUnique(m_xBuilder->weld_check_button("UNIQUE"))
+ , m_xFieldsLabel(m_xBuilder->weld_label("FIELDS_LABEL"))
+ , m_xClose(m_xBuilder->weld_button("close"))
+ , m_xTable(m_xBuilder->weld_container("FIELDS"))
+ , m_xTableCtrlParent(m_xTable->CreateChildFrame())
+ , m_xFields(VclPtr<IndexFieldsControl>::Create(m_xTableCtrlParent))
+ {
+ m_xIndexList->set_size_request(m_xIndexList->get_approximate_digit_width() * 17,
+ m_xIndexList->get_height_rows(12));
+
+ int nWidth = m_xIndexList->get_approximate_digit_width() * 60;
+ int nHeight = m_xIndexList->get_height_rows(8);
+ m_xTable->set_size_request(nWidth, nHeight);
+
+ m_xActions->connect_clicked(LINK(this, DbaIndexDialog, OnIndexAction));
+
+ m_xIndexList->connect_changed(LINK(this, DbaIndexDialog, OnIndexSelected));
+ m_xIndexList->connect_editing(LINK(this, DbaIndexDialog, OnEntryEditing),
+ LINK(this, DbaIndexDialog, OnEntryEdited));
+
+ m_xFields->SetSizePixel(Size(nWidth, 100));
+ m_xFields->Init(_rFieldNames, ::dbtools::getBooleanDataSourceSetting( m_xConnection, "AddIndexAppendix" ));
+ m_xFields->Show();
+
+ m_xIndexes.reset(new OIndexCollection());
+ try
+ {
+ m_xIndexes->attach(_rxIndexes);
+ }
+ catch(SQLException& e)
+ {
+ ::dbtools::showError(SQLExceptionInfo(e), pParent->GetXWindow(), _rxContext);
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL("DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!");
+ }
+
+ fillIndexList();
+
+ m_xUnique->connect_toggled(LINK(this, DbaIndexDialog, OnModifiedClick));
+ m_xFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified));
+
+ m_xClose->connect_clicked(LINK(this, DbaIndexDialog, OnCloseDialog));
+
+ // if all of the indexes have an empty description, we're not interested in displaying it
+ bool bFound = false;
+ for (auto const& check : *m_xIndexes)
+ {
+ if (!check.sDescription.isEmpty())
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if (!bFound)
+ {
+ // hide the controls which are necessary for the description
+ m_xDescription->hide();
+ m_xDescriptionLabel->hide();
+ }
+ }
+
+ void DbaIndexDialog::updateToolbox()
+ {
+ m_xActions->set_item_sensitive("ID_INDEX_NEW", !m_bEditingActive);
+
+ int nSelected = m_xIndexList->get_selected_index();
+ bool bSelectedAnything = nSelected != -1;
+ if (bSelectedAnything)
+ {
+ // is the current entry modified?
+ Indexes::const_iterator aSelectedPos = m_xIndexes->begin() + m_xIndexList->get_id(nSelected).toUInt32();
+ m_xActions->set_item_sensitive("ID_INDEX_SAVE", aSelectedPos->isModified() || aSelectedPos->isNew());
+ m_xActions->set_item_sensitive("ID_INDEX_RESET", aSelectedPos->isModified() || aSelectedPos->isNew());
+ bSelectedAnything = !aSelectedPos->bPrimaryKey;
+ }
+ else
+ {
+ m_xActions->set_item_sensitive("ID_INDEX_SAVE", false);
+ m_xActions->set_item_sensitive("ID_INDEX_RESET", false);
+ }
+ m_xActions->set_item_sensitive("ID_INDEX_DROP", bSelectedAnything);
+ m_xActions->set_item_sensitive("ID_INDEX_RENAME", bSelectedAnything);
+ }
+
+ void DbaIndexDialog::fillIndexList()
+ {
+ OUString aPKeyIcon(BMP_PKEYICON);
+ // fill the list with the index names
+ m_xIndexList->clear();
+ sal_uInt32 nPos = 0;
+ for (auto const& indexLoop : *m_xIndexes)
+ {
+ m_xIndexList->append(OUString::number(nPos), indexLoop.sName);
+ if (indexLoop.bPrimaryKey)
+ m_xIndexList->set_image(nPos, aPKeyIcon);
+ ++nPos;
+ }
+
+ if (nPos)
+ m_xIndexList->select(0);
+
+ IndexSelected();
+ }
+
+ DbaIndexDialog::~DbaIndexDialog( )
+ {
+ m_xIndexes.reset();
+ m_xFields.disposeAndClear();
+ m_xTableCtrlParent->dispose();
+ m_xTableCtrlParent.clear();
+ }
+
+ bool DbaIndexDialog::implCommit(const weld::TreeIter* pEntry)
+ {
+ assert(pEntry && "DbaIndexDialog::implCommit: invalid entry!");
+
+ Indexes::iterator aCommitPos = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();
+
+ // if it's not a new index, remove it
+ // (we can't modify indexes, only drop'n'insert)
+ if (!aCommitPos->isNew())
+ if (!implDropIndex(pEntry, false))
+ return false;
+
+ // create the new index
+ SQLExceptionInfo aExceptionInfo;
+ try
+ {
+ m_xIndexes->commitNewIndex(aCommitPos);
+ }
+ catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
+ catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
+ catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
+
+ // reflect the new selection in the toolbox
+ updateToolbox();
+
+ if (aExceptionInfo.isValid())
+ showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
+ else
+ {
+ m_xUnique->save_state();
+ m_xFields->SaveValue();
+ }
+
+ return !aExceptionInfo.isValid();
+ }
+
+ void DbaIndexDialog::OnNewIndex()
+ {
+ // commit the current entry, if necessary
+ if (!implCommitPreviouslySelected())
+ return;
+
+ // get a new unique name for the new index
+ OUString sNewIndexName;
+ const OUString sNewIndexNameBase(DBA_RES(STR_LOGICAL_INDEX_NAME));
+ sal_Int32 i;
+
+ for ( i = 1; i < 0x7FFFFFFF; ++i )
+ {
+ sNewIndexName = sNewIndexNameBase + OUString::number(i);
+ if (m_xIndexes->end() == m_xIndexes->find(sNewIndexName))
+ break;
+ }
+ if (i == 0x7FFFFFFF)
+ {
+ OSL_FAIL("DbaIndexDialog::OnNewIndex: no free index name found!");
+ // can't do anything ... of course we try another base, but this could end with the same result ...
+ return;
+ }
+
+ std::unique_ptr<weld::TreeIter> xNewEntry(m_xIndexList->make_iterator());
+ m_xIndexList->insert(nullptr, -1, &sNewIndexName, nullptr, nullptr, nullptr, false, xNewEntry.get());
+ m_xIndexes->insert(sNewIndexName);
+
+ // update the user data on the entries in the list box:
+ // they're iterators of the index collection, and thus they have changed when removing the index
+ m_xIndexList->all_foreach([this](weld::TreeIter& rEntry){
+ Indexes::const_iterator aAfterInsertPos = m_xIndexes->find(m_xIndexList->get_text(rEntry));
+ OSL_ENSURE(aAfterInsertPos != m_xIndexes->end(), "DbaIndexDialog::OnNewIndex: problems with one of the entries!");
+ m_xIndexList->set_id(rEntry, OUString::number(aAfterInsertPos - m_xIndexes->begin()));
+ return false;
+ });
+
+ // select the entry and start in-place editing
+ m_bNoHandlerCall = true;
+ m_xIndexList->select(*xNewEntry);
+ m_bNoHandlerCall = false;
+ IndexSelected();
+ m_xIndexList->grab_focus();
+ m_xIndexList->start_editing(*xNewEntry);
+ updateToolbox();
+ }
+
+ void DbaIndexDialog::OnDropIndex(bool _bConfirm)
+ {
+ std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
+ // the selected index
+ if (!m_xIndexList->get_selected(xSelected.get()))
+ return;
+
+ // let the user confirm the drop
+ if (_bConfirm)
+ {
+ OUString sConfirm(DBA_RES(STR_CONFIRM_DROP_INDEX));
+ sConfirm = sConfirm.replaceFirst("$name$", m_xIndexList->get_text(*xSelected));
+ std::unique_ptr<weld::MessageDialog> xConfirm(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ sConfirm));
+ if (RET_YES != xConfirm->run())
+ return;
+ }
+
+ // do the drop
+ implDropIndex(xSelected.get(), true);
+
+ // reflect the new selection in the toolbox
+ updateToolbox();
+ }
+
+ bool DbaIndexDialog::implDropIndex(const weld::TreeIter* pEntry, bool _bRemoveFromCollection)
+ {
+ // do the drop
+ Indexes::iterator aDropPos = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();
+ OSL_ENSURE(aDropPos != m_xIndexes->end(), "DbaIndexDialog::OnDropIndex: did not find the index in my collection!");
+
+ SQLExceptionInfo aExceptionInfo;
+ bool bSuccess = false;
+ try
+ {
+ if (_bRemoveFromCollection)
+ bSuccess = m_xIndexes->drop(aDropPos);
+ else
+ bSuccess = m_xIndexes->dropNoRemove(aDropPos);
+ }
+ catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
+ catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
+ catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
+
+ if (aExceptionInfo.isValid())
+ showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
+ else if (bSuccess && _bRemoveFromCollection)
+ {
+ m_bNoHandlerCall = true;
+
+ // if the entry to remove is the selected on...
+ if (m_xPreviousSelection && m_xPreviousSelection->equal(*pEntry))
+ m_xPreviousSelection.reset();
+ m_xIndexList->remove(*pEntry);
+
+ m_bNoHandlerCall = false;
+
+ // update the user data on the entries in the list box:
+ // they're iterators of the index collection, and thus they have changed when removing the index
+ m_xIndexList->all_foreach([this](weld::TreeIter& rEntry){
+ Indexes::const_iterator aAfterDropPos = m_xIndexes->find(m_xIndexList->get_text(rEntry));
+ OSL_ENSURE(aAfterDropPos != m_xIndexes->end(), "DbaIndexDialog::OnDropIndex: problems with one of the remaining entries!");
+ m_xIndexList->set_id(rEntry, OUString::number(aAfterDropPos - m_xIndexes->begin()));
+ return false;
+ });
+
+ // the Remove automatically selected another entry (if possible), but we disabled the calling of the handler
+ // to prevent that we missed something... call the handler directly
+ IndexSelected();
+ }
+
+ return !aExceptionInfo.isValid();
+ }
+
+ void DbaIndexDialog::OnRenameIndex()
+ {
+ // the selected iterator
+ std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
+ if (!m_xIndexList->get_selected(xSelected.get()))
+ return;
+
+ // save the changes made 'til here
+ // Upon leaving the edit mode, the control will be re-initialized with the
+ // settings from the current entry
+ implSaveModified(false);
+
+ m_xIndexList->grab_focus();
+ m_xIndexList->start_editing(*xSelected);
+ updateToolbox();
+ }
+
+ void DbaIndexDialog::OnSaveIndex()
+ {
+ // the selected index
+ implCommitPreviouslySelected();
+ updateToolbox();
+ }
+
+ void DbaIndexDialog::OnResetIndex()
+ {
+ // the selected index
+ std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
+ // the selected index
+ if (!m_xIndexList->get_selected(xSelected.get()))
+ xSelected.reset();
+ OSL_ENSURE(xSelected, "DbaIndexDialog::OnResetIndex: invalid call!");
+ if (!xSelected)
+ return;
+
+ Indexes::iterator aResetPos = m_xIndexes->begin() + m_xIndexList->get_id(*xSelected).toUInt32();
+
+ if (aResetPos->isNew())
+ {
+ OnDropIndex(false);
+ return;
+ }
+
+ SQLExceptionInfo aExceptionInfo;
+ try
+ {
+ m_xIndexes->resetIndex(aResetPos);
+ }
+ catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
+ catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
+ catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
+
+ if (aExceptionInfo.isValid())
+ showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
+ else
+ m_xIndexList->set_text(*xSelected, aResetPos->sName);
+
+ updateControls(xSelected.get());
+ updateToolbox();
+ }
+
+ IMPL_LINK(DbaIndexDialog, OnIndexAction, const OString&, rClicked, void)
+ {
+ if (rClicked == "ID_INDEX_NEW")
+ OnNewIndex();
+ else if (rClicked == "ID_INDEX_DROP")
+ OnDropIndex();
+ else if (rClicked == "ID_INDEX_RENAME")
+ OnRenameIndex();
+ else if (rClicked == "ID_INDEX_SAVE")
+ OnSaveIndex();
+ else if (rClicked == "ID_INDEX_RESET")
+ OnResetIndex();
+ }
+
+ IMPL_LINK_NOARG(DbaIndexDialog, OnCloseDialog, weld::Button&, void)
+ {
+ if (m_bEditingActive)
+ {
+ OSL_ENSURE(!m_bEditAgain, "DbaIndexDialog::OnCloseDialog: somebody was faster than hell!");
+ // this means somebody entered a new name, which was invalid, which cause us to posted us an event,
+ // and before the event arrived the user clicked onto "close". VERY fast, this user...
+ m_xIndexList->end_editing();
+ if (m_bEditAgain)
+ // could not commit the new name (started a new - asynchronous - edit trial)
+ return;
+ }
+
+ // the currently selected entry
+ std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
+ // the selected index
+ if (!m_xIndexList->get_selected(xSelected.get()))
+ xSelected.reset();
+
+ OSL_ENSURE(xSelected && m_xPreviousSelection && xSelected->equal(*m_xPreviousSelection), "DbaIndexDialog::OnCloseDialog: inconsistence!");
+
+ sal_Int32 nResponse = RET_NO;
+ if (xSelected)
+ {
+ // the descriptor
+ Indexes::const_iterator aSelected = m_xIndexes->begin() + m_xIndexList->get_id(*xSelected).toUInt32();
+ if (aSelected->isModified() || aSelected->isNew())
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), "dbaccess/ui/saveindexdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("SaveIndexDialog"));
+ nResponse = xQuery->run();
+ }
+ }
+
+ switch (nResponse)
+ {
+ case RET_YES:
+ if (!implCommitPreviouslySelected())
+ return;
+ break;
+ case RET_NO:
+ break;
+ default:
+ return;
+ }
+
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK(DbaIndexDialog, OnEditIndexAgain, void*, p, void)
+ {
+ weld::TreeIter* pEntry = static_cast<weld::TreeIter*>(p);
+ m_bEditAgain = false;
+ m_xIndexList->grab_focus();
+ m_xIndexList->start_editing(*pEntry);
+ delete pEntry;
+ }
+
+ IMPL_LINK_NOARG(DbaIndexDialog, OnEntryEditing, const weld::TreeIter&, bool)
+ {
+ m_bEditingActive = true;
+ return true;
+ }
+
+ IMPL_LINK(DbaIndexDialog, OnEntryEdited, const IterString&, rIterString, bool)
+ {
+ m_bEditingActive = false;
+
+ const weld::TreeIter& rEntry = rIterString.first;
+ OUString sNewName = rIterString.second;
+
+ Indexes::iterator aPosition = m_xIndexes->begin() + m_xIndexList->get_id(rEntry).toUInt32();
+
+ OSL_ENSURE(aPosition >= m_xIndexes->begin() && aPosition < m_xIndexes->end(),
+ "DbaIndexDialog::OnEntryEdited: invalid entry!");
+
+ Indexes::const_iterator aSameName = m_xIndexes->find(sNewName);
+ if (aSameName != aPosition && m_xIndexes->end() != aSameName)
+ {
+ OUString sError(DBA_RES(STR_INDEX_NAME_ALREADY_USED));
+ sError = sError.replaceFirst("$name$", sNewName);
+ std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ sError));
+ xError->run();
+
+ updateToolbox();
+ m_bEditAgain = true;
+ std::unique_ptr<weld::TreeIter> xEntry(m_xIndexList->make_iterator(&rEntry));
+ Application::PostUserEvent(LINK(this, DbaIndexDialog, OnEditIndexAgain), xEntry.release());
+ return false;
+ }
+
+ aPosition->sName = sNewName;
+
+ // rename can be done by a drop/insert combination only
+ if (aPosition->isNew())
+ {
+ updateToolbox();
+ // no commitment needed here...
+ return true;
+ }
+
+ if (aPosition->sName != aPosition->getOriginalName())
+ {
+ aPosition->setModified(true);
+ updateToolbox();
+ }
+
+ return true;
+ }
+
+ bool DbaIndexDialog::implSaveModified(bool _bPlausibility)
+ {
+ if (!m_xPreviousSelection)
+ return true;
+
+ // try to commit the previously selected index
+ if (m_xFields->IsModified() && !m_xFields->SaveModified())
+ return false;
+
+ Indexes::iterator aPreviouslySelected = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();
+
+ // the unique flag
+ aPreviouslySelected->bUnique = m_xUnique->get_active();
+ if (m_xUnique->get_state_changed_from_saved())
+ aPreviouslySelected->setModified(true);
+
+ // the fields
+ m_xFields->commitTo(aPreviouslySelected->aFields);
+ if (m_xFields->GetSavedValue() != aPreviouslySelected->aFields)
+ aPreviouslySelected->setModified(true);
+
+ // plausibility checks
+ if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected))
+ return false;
+
+ return true;
+ }
+
+ bool DbaIndexDialog::implCheckPlausibility(const Indexes::const_iterator& _rPos)
+ {
+ // need at least one field
+ if (_rPos->aFields.empty())
+ {
+ std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ DBA_RES(STR_NEED_INDEX_FIELDS)));
+ xError->run();
+ m_xFields->GrabFocus();
+ return false;
+ }
+
+ // no double fields
+ std::set< OUString > aExistentFields;
+ for (auto const& fieldCheck : _rPos->aFields)
+ {
+ if (aExistentFields.end() != aExistentFields.find(fieldCheck.sFieldName))
+ {
+ // a column is specified twice ... won't work anyway, so prevent this here and now
+ OUString sMessage(DBA_RES(STR_INDEXDESIGN_DOUBLE_COLUMN_NAME));
+ sMessage = sMessage.replaceFirst("$name$", fieldCheck.sFieldName);
+ std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ sMessage));
+ xError->run();
+ m_xFields->GrabFocus();
+ return false;
+ }
+ aExistentFields.insert(fieldCheck.sFieldName);
+ }
+
+ return true;
+ }
+
+ bool DbaIndexDialog::implCommitPreviouslySelected()
+ {
+ if (m_xPreviousSelection)
+ {
+ Indexes::const_iterator aPreviouslySelected = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();
+
+ if (!implSaveModified())
+ return false;
+
+ // commit the index (if necessary)
+ if (aPreviouslySelected->isModified() && !implCommit(m_xPreviousSelection.get()))
+ return false;
+ }
+
+ return true;
+ }
+
+ IMPL_LINK_NOARG(DbaIndexDialog, OnModifiedClick, weld::Toggleable&, void)
+ {
+ OnModified(*m_xFields);
+ }
+
+ IMPL_LINK_NOARG( DbaIndexDialog, OnModified, IndexFieldsControl&, void )
+ {
+ assert(m_xPreviousSelection && "DbaIndexDialog, OnModified: invalid call!");
+ Indexes::iterator aPosition = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();
+
+ aPosition->setModified(true);
+ updateToolbox();
+ }
+
+ void DbaIndexDialog::updateControls(const weld::TreeIter* pEntry)
+ {
+ if (pEntry)
+ {
+ // the descriptor of the selected index
+ Indexes::const_iterator aSelectedIndex = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();
+
+ // fill the controls
+ m_xUnique->set_active(aSelectedIndex->bUnique);
+ m_xUnique->set_sensitive(!aSelectedIndex->bPrimaryKey);
+ m_xUnique->save_state();
+
+ m_xFields->initializeFrom(std::vector(aSelectedIndex->aFields));
+ m_xFields->Enable(!aSelectedIndex->bPrimaryKey);
+ m_xFields->SaveValue();
+
+ m_xDescription->set_label(aSelectedIndex->sDescription);
+ m_xDescription->set_sensitive(!aSelectedIndex->bPrimaryKey);
+
+ m_xDescriptionLabel->set_sensitive(!aSelectedIndex->bPrimaryKey);
+ }
+ else
+ {
+ m_xUnique->set_active(false);
+ m_xFields->initializeFrom(IndexFields());
+ m_xDescription->set_label(OUString());
+ }
+ }
+
+ void DbaIndexDialog::IndexSelected()
+ {
+ if (m_bEditingActive)
+ m_xIndexList->end_editing();
+
+ std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
+ if (!m_xIndexList->get_selected(xSelected.get()))
+ xSelected.reset();
+
+ // commit the old data
+ if (m_xPreviousSelection && (!xSelected || !m_xPreviousSelection->equal(*xSelected)))
+ {
+ // (this call may happen in case somebody ended an in-place edit with 'return', so we need to check this before committing)
+ if (!implCommitPreviouslySelected())
+ {
+ m_bNoHandlerCall = true;
+ m_xIndexList->select(*m_xPreviousSelection);
+ m_bNoHandlerCall = false;
+ return;
+ }
+ }
+
+ // disable/enable the detail controls
+ m_xIndexDetails->set_sensitive(xSelected != nullptr);
+ m_xUnique->set_sensitive(xSelected != nullptr);
+ m_xDescriptionLabel->set_sensitive(xSelected != nullptr);
+ m_xFieldsLabel->set_sensitive(xSelected != nullptr);
+ m_xFields->Enable(xSelected != nullptr);
+
+ updateControls(xSelected.get());
+ if (xSelected)
+ m_xIndexList->grab_focus();
+
+ m_xPreviousSelection = std::move(xSelected);
+
+ updateToolbox();
+ }
+
+ IMPL_LINK_NOARG(DbaIndexDialog, OnIndexSelected, weld::TreeView&, void)
+ {
+ if (m_bNoHandlerCall)
+ return;
+ IndexSelected();
+ }
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/indexfieldscontrol.cxx b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx
new file mode 100644
index 000000000..35b0e3f02
--- /dev/null
+++ b/dbaccess/source/ui/dlg/indexfieldscontrol.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 <core_resource.hxx>
+#include <indexfieldscontrol.hxx>
+#include <strings.hrc>
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+#include <helpids.h>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+namespace dbaui
+{
+
+constexpr auto BROWSER_STANDARD_FLAGS = BrowserMode::COLUMNSELECTION | BrowserMode::HLINES | BrowserMode::VLINES |
+ BrowserMode::HIDECURSOR | BrowserMode::HIDESELECT | BrowserMode::AUTO_HSCROLL | BrowserMode::AUTO_VSCROLL;
+
+#define COLUMN_ID_FIELDNAME 1
+#define COLUMN_ID_ORDER 2
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::svt;
+
+ // DbaMouseDownListBoxController
+ class DbaMouseDownListBoxController : public ListBoxCellController
+ {
+ protected:
+ Link<DbaMouseDownListBoxController&,void> m_aAdditionalModifyHdl;
+
+ public:
+ explicit DbaMouseDownListBoxController(ListBoxControl* _pParent)
+ :ListBoxCellController(_pParent)
+ {
+ }
+
+ void SetAdditionalModifyHdl(const Link<DbaMouseDownListBoxController&,void>& _rHdl);
+
+ protected:
+ virtual void callModifyHdl() override;
+ };
+
+ void DbaMouseDownListBoxController::SetAdditionalModifyHdl(const Link<DbaMouseDownListBoxController&,void>& _rHdl)
+ {
+ m_aAdditionalModifyHdl = _rHdl;
+ }
+
+ void DbaMouseDownListBoxController::callModifyHdl()
+ {
+ m_aAdditionalModifyHdl.Call(*this);
+ ListBoxCellController::callModifyHdl();
+ }
+
+ // IndexFieldsControl
+ IndexFieldsControl::IndexFieldsControl(const css::uno::Reference<css::awt::XWindow> &rParent)
+ : EditBrowseBox(VCLUnoHelper::GetWindow(rParent), EditBrowseBoxFlags::SMART_TAB_TRAVEL | EditBrowseBoxFlags::ACTIVATE_ON_BUTTONDOWN, WB_TABSTOP | WB_BORDER, BROWSER_STANDARD_FLAGS)
+ , m_aSeekRow(m_aFields.end())
+ , m_pSortingCell(nullptr)
+ , m_pFieldNameCell(nullptr)
+ , m_bAddIndexAppendix(false)
+ {
+ }
+
+ IndexFieldsControl::~IndexFieldsControl()
+ {
+ disposeOnce();
+ }
+
+ void IndexFieldsControl::dispose()
+ {
+ m_pSortingCell.disposeAndClear();
+ m_pFieldNameCell.disposeAndClear();
+ ::svt::EditBrowseBox::dispose();
+ }
+
+ bool IndexFieldsControl::SeekRow(sal_Int32 nRow)
+ {
+ if (!EditBrowseBox::SeekRow(nRow))
+ return false;
+
+ if (nRow < 0)
+ {
+ m_aSeekRow = m_aFields.end();
+ }
+ else
+ {
+ m_aSeekRow = m_aFields.begin() + nRow;
+ OSL_ENSURE(m_aSeekRow <= m_aFields.end(), "IndexFieldsControl::SeekRow: invalid row!");
+ }
+
+ return true;
+ }
+
+ void IndexFieldsControl::PaintCell( OutputDevice& _rDev, const tools::Rectangle& _rRect, sal_uInt16 _nColumnId ) const
+ {
+ Point aPos(_rRect.TopLeft());
+ aPos.AdjustX(1 );
+
+ OUString aText = GetRowCellText(m_aSeekRow,_nColumnId);
+ Size TxtSize(GetDataWindow().GetTextWidth(aText), GetDataWindow().GetTextHeight());
+
+ // clipping
+ if (aPos.X() < _rRect.Right() || aPos.X() + TxtSize.Width() > _rRect.Right() ||
+ aPos.Y() < _rRect.Top() || aPos.Y() + TxtSize.Height() > _rRect.Bottom())
+ _rDev.SetClipRegion(vcl::Region(_rRect));
+
+ // allow for a disabled control ...
+ bool bEnabled = IsEnabled();
+ Color aOriginalColor = _rDev.GetTextColor();
+ if (!bEnabled)
+ _rDev.SetTextColor(GetSettings().GetStyleSettings().GetDisableColor());
+
+ // draw the text
+ _rDev.DrawText(aPos, aText);
+
+ // reset the color (if necessary)
+ if (!bEnabled)
+ _rDev.SetTextColor(aOriginalColor);
+
+ if (_rDev.IsClipRegion())
+ _rDev.SetClipRegion();
+ }
+
+ void IndexFieldsControl::initializeFrom(IndexFields&& _rFields)
+ {
+ // copy the field descriptions
+ m_aFields = std::move(_rFields);
+ m_aSeekRow = m_aFields.end();
+
+ SetUpdateMode(false);
+ // remove all rows
+ RowRemoved(1, GetRowCount());
+ // insert rows for the fields
+ RowInserted(GetRowCount(), m_aFields.size(), false);
+ // insert an additional row for a new field for that index
+ RowInserted(GetRowCount(), 1, false);
+ SetUpdateMode(true);
+
+ GoToRowColumnId(0, COLUMN_ID_FIELDNAME);
+ }
+
+ void IndexFieldsControl::commitTo(IndexFields& _rFields)
+ {
+ // do not just copy the array, we may have empty field names (which should not be copied)
+ _rFields.resize(m_aFields.size());
+ IndexFields::iterator aDest = std::copy_if(m_aFields.begin(), m_aFields.end(), _rFields.begin(),
+ [](const OIndexField& source) { return !source.sFieldName.isEmpty(); });
+
+ _rFields.resize(aDest - _rFields.begin());
+ }
+
+ sal_uInt32 IndexFieldsControl::GetTotalCellWidth(sal_Int32 _nRow, sal_uInt16 _nColId)
+ {
+ if (COLUMN_ID_ORDER == _nColId)
+ {
+ sal_Int32 nWidthAsc = GetTextWidth(m_sAscendingText) + GetSettings().GetStyleSettings().GetScrollBarSize();
+ sal_Int32 nWidthDesc = GetTextWidth(m_sDescendingText) + GetSettings().GetStyleSettings().GetScrollBarSize();
+ // maximum plus some additional space
+ return std::max(nWidthAsc, nWidthDesc) + GetTextWidth(OUString('0')) * 2;
+ }
+ return EditBrowseBox::GetTotalCellWidth(_nRow, _nColId);
+ }
+
+ void IndexFieldsControl::Init(const Sequence< OUString >& _rAvailableFields, bool _bAddIndexAppendix)
+ {
+ m_bAddIndexAppendix = _bAddIndexAppendix;
+
+ RemoveColumns();
+
+ // for the width: both columns together should be somewhat smaller than the whole window (without the scrollbar)
+ sal_Int32 nFieldNameWidth = GetSizePixel().Width();
+
+ if ( m_bAddIndexAppendix )
+ {
+ m_sAscendingText = DBA_RES(STR_ORDER_ASCENDING);
+ m_sDescendingText = DBA_RES(STR_ORDER_DESCENDING);
+
+ // the "sort order" column
+ OUString sColumnName = DBA_RES(STR_TAB_INDEX_SORTORDER);
+ // the width of the order column is the maximum widths of the texts used
+ // (the title of the column)
+ sal_Int32 nSortOrderColumnWidth = GetTextWidth(sColumnName);
+ // ("ascending" + scrollbar width)
+ sal_Int32 nOther = GetTextWidth(m_sAscendingText) + GetSettings().GetStyleSettings().GetScrollBarSize();
+ nSortOrderColumnWidth = std::max(nSortOrderColumnWidth, nOther);
+ // ("descending" + scrollbar width)
+ nOther = GetTextWidth(m_sDescendingText) + GetSettings().GetStyleSettings().GetScrollBarSize();
+ nSortOrderColumnWidth = std::max(nSortOrderColumnWidth, nOther);
+ // (plus some additional space)
+ nSortOrderColumnWidth += GetTextWidth(OUString('0')) * 2;
+ InsertDataColumn(COLUMN_ID_ORDER, sColumnName, nSortOrderColumnWidth, HeaderBarItemBits::STDSTYLE, 1);
+
+ m_pSortingCell = VclPtr<ListBoxControl>::Create(&GetDataWindow());
+ weld::ComboBox& rSortingListBox = m_pSortingCell->get_widget();
+ rSortingListBox.append_text(m_sAscendingText);
+ rSortingListBox.append_text(m_sDescendingText);
+ rSortingListBox.set_help_id(HID_DLGINDEX_INDEXDETAILS_SORTORDER);
+
+ nFieldNameWidth -= nSortOrderColumnWidth;
+ }
+ StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
+ nFieldNameWidth -= aSystemStyle.GetScrollBarSize();
+ nFieldNameWidth -= 8;
+ // the "field name" column
+ OUString sColumnName = DBA_RES(STR_TAB_INDEX_FIELD);
+ InsertDataColumn(COLUMN_ID_FIELDNAME, sColumnName, nFieldNameWidth, HeaderBarItemBits::STDSTYLE, 0);
+
+ // create the cell controllers
+ // for the field name cell
+ m_pFieldNameCell = VclPtr<ListBoxControl>::Create(&GetDataWindow());
+ weld::ComboBox& rNameListBox = m_pFieldNameCell->get_widget();
+ rNameListBox.append_text(OUString());
+ rNameListBox.set_help_id(HID_DLGINDEX_INDEXDETAILS_FIELD);
+ const OUString* pFields = _rAvailableFields.getConstArray();
+ const OUString* pFieldsEnd = pFields + _rAvailableFields.getLength();
+ for (;pFields < pFieldsEnd; ++pFields)
+ rNameListBox.append_text(*pFields);
+ }
+
+ CellController* IndexFieldsControl::GetController(sal_Int32 _nRow, sal_uInt16 _nColumnId)
+ {
+ if (!IsEnabled())
+ return nullptr;
+
+ IndexFields::const_iterator aRow;
+ bool bNewField = !implGetFieldDesc(_nRow, aRow);
+
+ DbaMouseDownListBoxController* pReturn = nullptr;
+ switch (_nColumnId)
+ {
+ case COLUMN_ID_ORDER:
+ if (!bNewField && m_pSortingCell && !aRow->sFieldName.isEmpty())
+ pReturn = new DbaMouseDownListBoxController(m_pSortingCell);
+ break;
+
+ case COLUMN_ID_FIELDNAME:
+ pReturn = new DbaMouseDownListBoxController(m_pFieldNameCell);
+ break;
+
+ default:
+ OSL_FAIL("IndexFieldsControl::GetController: invalid column id!");
+ }
+
+ if (pReturn)
+ pReturn->SetAdditionalModifyHdl(LINK(this, IndexFieldsControl, OnListEntrySelected));
+
+ return pReturn;
+ }
+
+ bool IndexFieldsControl::implGetFieldDesc(sal_Int32 _nRow, IndexFields::const_iterator& _rPos)
+ {
+ _rPos = m_aFields.end();
+ if ((_nRow < 0) || (o3tl::make_unsigned(_nRow) >= m_aFields.size()))
+ return false;
+ _rPos = m_aFields.begin() + _nRow;
+ return true;
+ }
+
+ bool IndexFieldsControl::SaveModified()
+ {
+ if (!IsModified())
+ return true;
+
+ switch (GetCurColumnId())
+ {
+ case COLUMN_ID_FIELDNAME:
+ {
+ weld::ComboBox& rNameListBox = m_pFieldNameCell->get_widget();
+ OUString sFieldSelected = rNameListBox.get_active_text();
+ bool bEmptySelected = sFieldSelected.isEmpty();
+ if (isNewField())
+ {
+ if (!bEmptySelected)
+ {
+ // add a new field to the collection
+ OIndexField aNewField;
+ aNewField.sFieldName = sFieldSelected;
+ m_aFields.push_back(aNewField);
+ RowInserted(GetRowCount());
+ }
+ }
+ else
+ {
+ sal_Int32 nRow = GetCurRow();
+ OSL_ENSURE(nRow < static_cast<sal_Int32>(m_aFields.size()), "IndexFieldsControl::SaveModified: invalid current row!");
+ if (nRow >= 0) // may be -1 in case the control was empty
+ {
+ // remove the field from the selection
+ IndexFields::iterator aPos = m_aFields.begin() + nRow;
+
+ if (bEmptySelected)
+ {
+ aPos->sFieldName.clear();
+
+ // invalidate the row to force repaint
+ Invalidate(GetRowRectPixel(nRow));
+ return true;
+ }
+
+ if (sFieldSelected == aPos->sFieldName)
+ // nothing changed
+ return true;
+
+ aPos->sFieldName = sFieldSelected;
+ }
+ }
+
+ Invalidate(GetRowRectPixel(GetCurRow()));
+ }
+ break;
+ case COLUMN_ID_ORDER:
+ {
+ OSL_ENSURE(!isNewField(), "IndexFieldsControl::SaveModified: why the hell ...!!!");
+ // selected entry
+ weld::ComboBox& rSortingListBox = m_pSortingCell->get_widget();
+ sal_Int32 nPos = rSortingListBox.get_active();
+ OSL_ENSURE(nPos != -1, "IndexFieldsControl::SaveModified: how did you get this selection??");
+ // adjust the sort flag in the index field description
+ OIndexField& rCurrentField = m_aFields[GetCurRow()];
+ rCurrentField.bSortAscending = (0 == nPos);
+
+ }
+ break;
+ default:
+ OSL_FAIL("IndexFieldsControl::SaveModified: invalid column id!");
+ }
+ return true;
+ }
+
+ void IndexFieldsControl::InitController(CellControllerRef& /*_rController*/, sal_Int32 _nRow, sal_uInt16 _nColumnId)
+ {
+ IndexFields::const_iterator aFieldDescription;
+ bool bNewField = !implGetFieldDesc(_nRow, aFieldDescription);
+
+ switch (_nColumnId)
+ {
+ case COLUMN_ID_FIELDNAME:
+ {
+ weld::ComboBox& rNameListBox = m_pFieldNameCell->get_widget();
+ rNameListBox.set_active_text(bNewField ? OUString() : aFieldDescription->sFieldName);
+ rNameListBox.save_value();
+ break;
+ }
+
+ case COLUMN_ID_ORDER:
+ {
+ weld::ComboBox& rSortingListBox = m_pSortingCell->get_widget();
+ rSortingListBox.set_active_text(aFieldDescription->bSortAscending ? m_sAscendingText : m_sDescendingText);
+ rSortingListBox.save_value();
+ break;
+ }
+
+ default:
+ OSL_FAIL("IndexFieldsControl::InitController: invalid column id!");
+ }
+ }
+
+ IMPL_LINK( IndexFieldsControl, OnListEntrySelected, DbaMouseDownListBoxController&, rController, void )
+ {
+ weld::ComboBox& rListBox = rController.GetListBox();
+ if (!rListBox.get_popup_shown())
+ m_aModifyHdl.Call(*this);
+
+ if (&rListBox != &m_pFieldNameCell->get_widget())
+ return;
+
+// a field has been selected
+ if (GetCurRow() >= GetRowCount() - 2)
+ { // and we're in one of the last two rows
+ OUString sSelectedEntry = rListBox.get_active_text();
+ sal_Int32 nCurrentRow = GetCurRow();
+ sal_Int32 rowCount = GetRowCount();
+
+ OSL_ENSURE((static_cast<sal_Int32>(m_aFields.size() + 1)) == rowCount, "IndexFieldsControl::OnListEntrySelected: inconsistence!");
+
+ if (!sSelectedEntry.isEmpty() && (nCurrentRow == rowCount - 1) /*&& (!m_nMaxColumnsInIndex || rowCount < m_nMaxColumnsInIndex )*/ )
+ { // in the last row, a non-empty string has been selected
+ // -> insert a new row
+ m_aFields.emplace_back();
+ RowInserted(GetRowCount());
+ Invalidate(GetRowRectPixel(nCurrentRow));
+ }
+ else if (sSelectedEntry.isEmpty() && (nCurrentRow == rowCount - 2))
+ { // in the (last-1)th row, an empty entry has been selected
+ // -> remove the last row
+ m_aFields.pop_back();
+ RowRemoved(GetRowCount() - 1);
+ Invalidate(GetRowRectPixel(nCurrentRow));
+ }
+ }
+
+ SaveModified();
+ }
+ OUString IndexFieldsControl::GetCellText(sal_Int32 _nRow,sal_uInt16 nColId) const
+ {
+ IndexFields::const_iterator aRow = m_aFields.end();
+ if ( _nRow >= 0 )
+ {
+ aRow = m_aFields.begin() + _nRow;
+ OSL_ENSURE(aRow <= m_aFields.end(), "IndexFieldsControl::SeekRow: invalid row!");
+ }
+ return GetRowCellText(aRow,nColId);
+ }
+ OUString IndexFieldsControl::GetRowCellText(const IndexFields::const_iterator& _rRow,sal_uInt16 nColId) const
+ {
+ if (_rRow < m_aFields.end())
+ {
+ switch (nColId)
+ {
+ case COLUMN_ID_FIELDNAME:
+ return _rRow->sFieldName;
+ case COLUMN_ID_ORDER:
+ if (_rRow->sFieldName.isEmpty())
+ return OUString();
+ else
+ return _rRow->bSortAscending ? m_sAscendingText : m_sDescendingText;
+ default:
+ OSL_FAIL("IndexFieldsControl::GetCurrentRowCellText: invalid column id!");
+ }
+ }
+ return OUString();
+ }
+ bool IndexFieldsControl::IsTabAllowed(bool /*bForward*/) const
+ {
+ return false;
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/odbcconfig.cxx b/dbaccess/source/ui/dlg/odbcconfig.cxx
new file mode 100644
index 000000000..b2f3a45ff
--- /dev/null
+++ b/dbaccess/source/ui/dlg/odbcconfig.cxx
@@ -0,0 +1,325 @@
+/* -*- 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 <config_folders.h>
+#include "odbcconfig.hxx"
+
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/diagnose.h>
+#include <osl/process.h>
+#include <osl/thread.hxx>
+#include <vcl/svapp.hxx>
+
+#ifdef HAVE_ODBC_SUPPORT
+
+#if defined(_WIN32)
+#define ODBC_LIBRARY "ODBC32.DLL"
+#endif
+#ifdef UNX
+#ifdef MACOSX
+#define ODBC_LIBRARY "libiodbc.dylib"
+#else
+#define ODBC_LIBRARY_PLAIN "libodbc.so"
+#define ODBC_LIBRARY_1 "libodbc.so.1"
+#define ODBC_LIBRARY "libodbc.so.2"
+#endif
+#endif
+
+#include <connectivity/odbc.hxx>
+
+#else
+
+#define ODBC_LIBRARY ""
+
+#endif // HAVE_ODBC_SUPPORT
+
+namespace dbaui
+{
+
+#ifdef HAVE_ODBC_SUPPORT
+typedef SQLRETURN (SQL_API* TSQLManageDataSource) (SQLHWND hwndParent);
+typedef SQLRETURN (SQL_API* TSQLAllocHandle) (SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE* OutputHandlePtr);
+typedef SQLRETURN (SQL_API* TSQLFreeHandle) (SQLSMALLINT HandleType, SQLHANDLE Handle);
+typedef SQLRETURN (SQL_API* TSQLSetEnvAttr) (SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
+typedef SQLRETURN (SQL_API* TSQLDataSources) (SQLHENV EnvironmentHandle, SQLUSMALLINT Direction, SQLCHAR* ServerName,
+ SQLSMALLINT BufferLength1, SQLSMALLINT* NameLength1Ptr, SQLCHAR* Description, SQLSMALLINT BufferLength2, SQLSMALLINT* NameLength2Ptr);
+
+#endif
+
+// OOdbcLibWrapper
+
+bool OOdbcEnumeration::load(const char* _pLibPath)
+{
+ m_sLibPath = OUString::createFromAscii(_pLibPath);
+#if defined(HAVE_ODBC_SUPPORT) && !defined(DISABLE_DYNLOADING)
+ // load the module
+ m_pOdbcLib = osl_loadModule(m_sLibPath.pData, SAL_LOADMODULE_NOW);
+ return (nullptr != m_pOdbcLib);
+#else
+ return sal_False;
+#endif
+}
+
+void OOdbcEnumeration::unload()
+{
+#if defined(HAVE_ODBC_SUPPORT) && !defined(DISABLE_DYNLOADING)
+ if (isLoaded())
+ {
+ osl_unloadModule(m_pOdbcLib);
+ m_pOdbcLib = nullptr;
+ }
+#endif
+}
+
+oslGenericFunction OOdbcEnumeration::loadSymbol(const char* _pFunctionName)
+{
+ return osl_getFunctionSymbol(m_pOdbcLib, OUString::createFromAscii(_pFunctionName).pData);
+}
+
+
+struct OdbcTypesImpl
+{
+#ifdef HAVE_ODBC_SUPPORT
+ SQLHANDLE hEnvironment;
+ OdbcTypesImpl() : hEnvironment(nullptr) { }
+#else
+ void* pDummy;
+#endif
+};
+
+OOdbcEnumeration::OOdbcEnumeration()
+ :m_pOdbcLib(nullptr)
+#ifdef HAVE_ODBC_SUPPORT
+ ,m_pAllocHandle(nullptr)
+ ,m_pFreeHandle(nullptr)
+ ,m_pSetEnvAttr(nullptr)
+ ,m_pDataSources(nullptr)
+ ,m_pImpl(new OdbcTypesImpl)
+#endif
+{
+ bool bLoaded = load(ODBC_LIBRARY);
+#ifdef ODBC_LIBRARY_1
+ if ( !bLoaded )
+ bLoaded = load(ODBC_LIBRARY_1);
+#endif
+#ifdef ODBC_LIBRARY_PLAIN
+ if ( !bLoaded )
+ bLoaded = load(ODBC_LIBRARY_PLAIN);
+#endif
+
+ if ( !bLoaded )
+ return;
+
+#ifdef HAVE_ODBC_SUPPORT
+ // load the generic functions
+ m_pAllocHandle = loadSymbol("SQLAllocHandle");
+ m_pFreeHandle = loadSymbol("SQLFreeHandle");
+ m_pSetEnvAttr = loadSymbol("SQLSetEnvAttr");
+ m_pDataSources = loadSymbol("SQLDataSources");
+
+ // all or nothing
+ if (!m_pAllocHandle || !m_pSetEnvAttr || !m_pDataSources || !m_pFreeHandle)
+ {
+ unload();
+ m_pAllocHandle = m_pFreeHandle = m_pSetEnvAttr = m_pDataSources = nullptr;
+ }
+#endif
+}
+
+OOdbcEnumeration::~OOdbcEnumeration()
+{
+ freeEnv();
+ unload();
+}
+
+// OOdbcEnumeration
+bool OOdbcEnumeration::allocEnv()
+{
+ OSL_ENSURE(isLoaded(), "OOdbcEnumeration::allocEnv: not loaded!");
+ if (!isLoaded())
+ return false;
+
+#ifdef HAVE_ODBC_SUPPORT
+ if (m_pImpl->hEnvironment)
+ // nothing to do
+ return true;
+ SQLRETURN nResult = (*reinterpret_cast<TSQLAllocHandle>(m_pAllocHandle))(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_pImpl->hEnvironment);
+ if (SQL_SUCCESS != nResult)
+ // can't do anything without environment
+ return false;
+
+ (*reinterpret_cast<TSQLSetEnvAttr>(m_pSetEnvAttr))(m_pImpl->hEnvironment, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>(SQL_OV_ODBC3),SQL_IS_INTEGER);
+ return true;
+#else
+ return sal_False;
+#endif
+}
+
+void OOdbcEnumeration::freeEnv()
+{
+#ifdef HAVE_ODBC_SUPPORT
+ if (m_pImpl->hEnvironment)
+ (*reinterpret_cast<TSQLFreeHandle>(m_pFreeHandle))(SQL_HANDLE_ENV, m_pImpl->hEnvironment);
+ m_pImpl->hEnvironment = nullptr;
+#endif
+}
+
+void OOdbcEnumeration::getDatasourceNames(std::set<OUString>& _rNames)
+{
+ OSL_ENSURE(isLoaded(), "OOdbcEnumeration::getDatasourceNames: not loaded!");
+ if (!isLoaded())
+ return;
+
+ if (!allocEnv())
+ {
+ OSL_FAIL("OOdbcEnumeration::getDatasourceNames: could not allocate an ODBC environment!");
+ return;
+ }
+
+#ifdef HAVE_ODBC_SUPPORT
+ // now that we have an environment collect the data source names
+ UCHAR szDSN[SQL_MAX_DSN_LENGTH+1];
+ SWORD pcbDSN;
+ UCHAR szDescription[1024+1];
+ SWORD pcbDescription;
+ SQLRETURN nResult = SQL_SUCCESS;
+ rtl_TextEncoding nTextEncoding = osl_getThreadTextEncoding();
+
+ for ( nResult = (*reinterpret_cast<TSQLDataSources>(m_pDataSources))(m_pImpl->hEnvironment, SQL_FETCH_FIRST, szDSN,
+ sizeof(szDSN), &pcbDSN, szDescription, sizeof(szDescription)-1, &pcbDescription);
+ ;
+ nResult = (*reinterpret_cast<TSQLDataSources>(m_pDataSources))(m_pImpl->hEnvironment, SQL_FETCH_NEXT, szDSN,
+ sizeof(szDSN), &pcbDSN, szDescription, sizeof(szDescription)-1, &pcbDescription)
+ )
+ {
+ if (nResult != SQL_SUCCESS)
+ // no further error handling
+ break;
+ else
+ {
+ OUString aCurrentDsn(reinterpret_cast<const char*>(szDSN),pcbDSN, nTextEncoding);
+ _rNames.insert(aCurrentDsn);
+ }
+ }
+#else
+ (void) _rNames;
+#endif
+}
+
+#ifdef HAVE_ODBC_ADMINISTRATION
+
+// ProcessTerminationWait
+class ProcessTerminationWait : public ::osl::Thread
+{
+ oslProcess m_hProcessHandle;
+ Link<void*,void> m_aFinishHdl;
+ ImplSVEvent* m_nEventId;
+
+public:
+ ProcessTerminationWait( oslProcess _hProcessHandle, const Link<void*,void>& _rFinishHdl )
+ : m_hProcessHandle( _hProcessHandle )
+ , m_aFinishHdl( _rFinishHdl )
+ , m_nEventId(nullptr)
+ {
+ }
+
+ void disableCallback()
+ {
+ // if finished event not posted yet, disable by turning it to a no-op Link
+ m_aFinishHdl = Link<void*, void>();
+ if (m_nEventId)
+ {
+ // already posted, remove it
+ Application::RemoveUserEvent(m_nEventId);
+ m_nEventId = nullptr;
+ }
+ }
+
+ void receivedCallback()
+ {
+ m_nEventId = nullptr;
+ }
+
+protected:
+ virtual void SAL_CALL run() override
+ {
+ osl_setThreadName("dbaui::ProcessTerminationWait");
+
+ osl_joinProcess( m_hProcessHandle );
+ osl_freeProcessHandle( m_hProcessHandle );
+ m_nEventId = Application::PostUserEvent( m_aFinishHdl );
+ }
+};
+
+// OOdbcManagement
+OOdbcManagement::OOdbcManagement(const Link<void*,void>& rAsyncFinishCallback)
+ : m_aAsyncFinishCallback(rAsyncFinishCallback)
+{
+}
+
+OOdbcManagement::~OOdbcManagement()
+{
+ // wait for our thread to be finished
+ if ( m_pProcessWait )
+ m_pProcessWait->join();
+}
+
+bool OOdbcManagement::manageDataSources_async()
+{
+ OSL_PRECOND( !isRunning(), "OOdbcManagement::manageDataSources_async: still running from the previous call!" );
+ if ( isRunning() )
+ return false;
+
+ // this is done in an external process, due to #i78733#
+ // (and note this whole functionality is supported on Windows only, ATM)
+ OUString sExecutableName( "$BRAND_BASE_DIR/" LIBO_LIBEXEC_FOLDER "/odbcconfig.exe" );
+ ::rtl::Bootstrap::expandMacros( sExecutableName ); //TODO: detect failure
+ oslProcess hProcessHandle(nullptr);
+ oslProcessError eError = osl_executeProcess( sExecutableName.pData, nullptr, 0, 0, nullptr, nullptr, nullptr, 0, &hProcessHandle );
+ if ( eError != osl_Process_E_None )
+ return false;
+
+ m_pProcessWait.reset( new ProcessTerminationWait( hProcessHandle, m_aAsyncFinishCallback ) );
+ m_pProcessWait->create();
+ return true;
+}
+
+void OOdbcManagement::disableCallback()
+{
+ if (m_pProcessWait)
+ m_pProcessWait->disableCallback();
+}
+
+void OOdbcManagement::receivedCallback()
+{
+ if (m_pProcessWait)
+ m_pProcessWait->receivedCallback();
+}
+
+bool OOdbcManagement::isRunning() const
+{
+ return ( m_pProcessWait && m_pProcessWait->isRunning() );
+}
+
+#endif // HAVE_ODBC_ADMINISTRATION
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/odbcconfig.hxx b/dbaccess/source/ui/dlg/odbcconfig.hxx
new file mode 100644
index 000000000..16177ad8a
--- /dev/null
+++ b/dbaccess/source/ui/dlg/odbcconfig.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 .
+ */
+
+#pragma once
+
+#if defined(_WIN32) || (defined (UNX) && !defined(ANDROID) && !defined(IOS))
+#define HAVE_ODBC_SUPPORT
+#endif
+
+#if defined(_WIN32) && defined(HAVE_ODBC_SUPPORT)
+#define HAVE_ODBC_ADMINISTRATION
+#endif
+
+#include <rtl/ustring.hxx>
+#include <tools/link.hxx>
+#include <osl/module.h>
+
+#include <memory>
+#include <set>
+
+namespace dbaui
+{
+
+// OOdbcEnumeration
+struct OdbcTypesImpl;
+class OOdbcEnumeration final
+{
+ oslModule m_pOdbcLib; // the library handle
+ OUString m_sLibPath; // the path to the library
+
+#ifdef HAVE_ODBC_SUPPORT
+ // entry points for ODBC administration
+ oslGenericFunction m_pAllocHandle;
+ oslGenericFunction m_pFreeHandle;
+ oslGenericFunction m_pSetEnvAttr;
+ oslGenericFunction m_pDataSources;
+
+#endif
+ std::unique_ptr<OdbcTypesImpl> m_pImpl;
+ // needed because we can't have a member of type SQLHANDLE: this would require us to include the respective
+ // ODBC file, which would lead to a lot of conflicts with other includes
+
+public:
+ OOdbcEnumeration();
+ ~OOdbcEnumeration();
+
+#ifdef HAVE_ODBC_SUPPORT
+ bool isLoaded() const { return nullptr != m_pOdbcLib; }
+#else
+ bool isLoaded() const { return false; }
+#endif
+ const OUString& getLibraryName() const { return m_sLibPath; }
+
+ void getDatasourceNames(std::set<OUString>& _rNames);
+
+private:
+ oslGenericFunction loadSymbol(const char* _pFunctionName);
+
+ /// load the lib
+ bool load(const char* _pLibPath);
+ /// unload the lib
+ void unload();
+ /// ensure that an ODBC environment is allocated
+ bool allocEnv();
+ /// free any allocated ODBC environment
+ void freeEnv();
+};
+
+// OOdbcManagement
+#ifdef HAVE_ODBC_ADMINISTRATION
+class ProcessTerminationWait;
+class OOdbcManagement
+{
+ std::unique_ptr< ProcessTerminationWait > m_pProcessWait;
+ Link<void*,void> m_aAsyncFinishCallback;
+
+public:
+ explicit OOdbcManagement( const Link<void*,void>& _rAsyncFinishCallback );
+ ~OOdbcManagement();
+
+ bool manageDataSources_async();
+ bool isRunning() const;
+ void disableCallback();
+ void receivedCallback();
+};
+#endif
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/optionalboolitem.cxx b/dbaccess/source/ui/dlg/optionalboolitem.cxx
new file mode 100644
index 000000000..30d176391
--- /dev/null
+++ b/dbaccess/source/ui/dlg/optionalboolitem.cxx
@@ -0,0 +1,44 @@
+/* -*- 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 "optionalboolitem.hxx"
+
+namespace dbaui
+{
+
+ // OptionalBoolItem
+ OptionalBoolItem::OptionalBoolItem( sal_uInt16 _nWhich )
+ :SfxPoolItem( _nWhich )
+ {
+ }
+
+ bool OptionalBoolItem::operator==( const SfxPoolItem& _rItem ) const
+ {
+ return SfxPoolItem::operator==(_rItem) &&
+ static_cast<const OptionalBoolItem&>( _rItem ).m_aValue == m_aValue;
+ }
+
+ OptionalBoolItem* OptionalBoolItem::Clone( SfxItemPool* /*_pPool*/ ) const
+ {
+ return new OptionalBoolItem( *this );
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/optionalboolitem.hxx b/dbaccess/source/ui/dlg/optionalboolitem.hxx
new file mode 100644
index 000000000..c500dfa2a
--- /dev/null
+++ b/dbaccess/source/ui/dlg/optionalboolitem.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <svl/poolitem.hxx>
+
+#include <optional>
+
+namespace dbaui
+{
+
+ // OptionalBoolItem
+ class OptionalBoolItem : public SfxPoolItem
+ {
+ ::std::optional< bool > m_aValue;
+
+ public:
+ explicit OptionalBoolItem( sal_uInt16 nWhich );
+
+ virtual bool operator==( const SfxPoolItem& _rItem ) const override;
+ virtual OptionalBoolItem* Clone( SfxItemPool* _pPool = nullptr ) const override;
+
+ bool HasValue() const { return !!m_aValue; }
+ void ClearValue() { m_aValue.reset(); }
+ bool GetValue() const { return *m_aValue; }
+ void SetValue(bool _bValue) { m_aValue = _bValue; }
+
+ const ::std::optional< bool >&
+ GetFullValue() const { return m_aValue; }
+ };
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/paramdialog.cxx b/dbaccess/source/ui/dlg/paramdialog.cxx
new file mode 100644
index 000000000..de3347682
--- /dev/null
+++ b/dbaccess/source/ui/dlg/paramdialog.cxx
@@ -0,0 +1,334 @@
+/* -*- 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 <core_resource.hxx>
+#include <paramdialog.hxx>
+#include <strings.hrc>
+#include <strings.hxx>
+#include <com/sun/star/util/NumberFormatter.hpp>
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <vcl/weld.hxx>
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
+
+namespace dbaui
+{
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::util;
+ using namespace ::connectivity;
+
+ // OParameterDialog
+
+
+ OParameterDialog::OParameterDialog(
+ weld::Window* pParent, const Reference< XIndexAccess > & rParamContainer,
+ const Reference< XConnection > & _rxConnection, const Reference< XComponentContext >& rxContext)
+ : GenericDialogController(pParent, "dbaccess/ui/parametersdialog.ui", "Parameters")
+ , m_nCurrentlySelected(-1)
+ , m_xConnection(_rxConnection)
+ , m_aPredicateInput( rxContext, _rxConnection, getParseContext() )
+ , m_aResetVisitFlag("dbaccess OParameterDialog m_aResetVisitFlag")
+ , m_xAllParams(m_xBuilder->weld_tree_view("allParamTreeview"))
+ , m_xParam(m_xBuilder->weld_entry("paramEntry"))
+ , m_xTravelNext(m_xBuilder->weld_button("next"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xCancelBtn(m_xBuilder->weld_button("cancel"))
+ {
+ m_xAllParams->set_size_request(-1, m_xAllParams->get_height_rows(10));
+
+ if (rxContext.is())
+ m_xFormatter.set( NumberFormatter::create( rxContext ), UNO_QUERY_THROW);
+ else {
+ OSL_FAIL("OParameterDialog::OParameterDialog: need a service factory!");
+ }
+
+ Reference< XNumberFormatsSupplier > xNumberFormats = ::dbtools::getNumberFormats(m_xConnection, true);
+ if (!xNumberFormats.is())
+ ::comphelper::disposeComponent(m_xFormatter);
+ else
+ m_xFormatter->attachNumberFormatsSupplier(xNumberFormats);
+ try
+ {
+ OSL_ENSURE(rParamContainer->getCount(), "OParameterDialog::OParameterDialog : can't handle empty containers !");
+
+ m_aFinalValues.realloc(rParamContainer->getCount());
+ PropertyValue* pValues = m_aFinalValues.getArray();
+
+ for (sal_Int32 i = 0, nCount = rParamContainer->getCount(); i<nCount; ++i, ++pValues)
+ {
+ Reference< XPropertySet > xParamAsSet;
+ rParamContainer->getByIndex(i) >>= xParamAsSet;
+ OSL_ENSURE(xParamAsSet.is(),"Parameter is null!");
+ if(!xParamAsSet.is())
+ continue;
+ pValues->Name = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
+ m_xAllParams->append_text(pValues->Name);
+
+ m_aVisitedParams.push_back(VisitFlags::NONE);
+ // not visited, not dirty
+ }
+
+ m_xParams = rParamContainer;
+ }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ Construct();
+
+ m_aResetVisitFlag.SetInvokeHandler(LINK(this, OParameterDialog, OnVisitedTimeout));
+ }
+
+ OParameterDialog::~OParameterDialog()
+ {
+ if (m_aResetVisitFlag.IsActive())
+ m_aResetVisitFlag.Stop();
+ }
+
+ void OParameterDialog::Construct()
+ {
+ m_xAllParams->connect_changed(LINK(this, OParameterDialog, OnEntryListBoxSelected));
+ m_xParam->connect_focus_out(LINK(this, OParameterDialog, OnValueLoseFocusHdl));
+ m_xParam->connect_changed(LINK(this, OParameterDialog, OnValueModified));
+ m_xTravelNext->connect_clicked(LINK(this, OParameterDialog, OnButtonClicked));
+ m_xOKBtn->connect_clicked(LINK(this, OParameterDialog, OnButtonClicked));
+ m_xCancelBtn->connect_clicked(LINK(this, OParameterDialog, OnButtonClicked));
+
+ if (m_xAllParams->n_children())
+ {
+ m_xAllParams->select(0);
+ OnEntrySelected();
+
+ if (m_xAllParams->n_children() == 1)
+ m_xTravelNext->set_sensitive(false);
+
+ if (m_xAllParams->n_children() > 1)
+ m_xDialog->change_default_widget(m_xOKBtn.get(), m_xTravelNext.get());
+ }
+
+ m_xParam->grab_focus();
+ }
+
+ IMPL_LINK_NOARG(OParameterDialog, OnValueLoseFocusHdl, weld::Widget&, void)
+ {
+ CheckValueForError();
+ }
+
+ bool OParameterDialog::CheckValueForError()
+ {
+ if (m_nCurrentlySelected != -1)
+ {
+ if ( !( m_aVisitedParams[ m_nCurrentlySelected ] & VisitFlags::Dirty ) )
+ // nothing to do, the value isn't dirty
+ return false;
+ }
+
+ bool bRet = false;
+
+ Reference< XPropertySet > xParamAsSet;
+ m_xParams->getByIndex(m_nCurrentlySelected) >>= xParamAsSet;
+ if (xParamAsSet.is())
+ {
+ if (m_xConnection.is() && m_xFormatter.is())
+ {
+ OUString sParamValue(m_xParam->get_text());
+ bool bValid = m_aPredicateInput.normalizePredicateString( sParamValue, xParamAsSet );
+ m_xParam->set_text(sParamValue);
+ m_xParam->set_message_type(bValid ? weld::EntryMessageType::Normal : weld::EntryMessageType::Error);
+ OUString sToolTip;
+ if ( bValid )
+ {
+ // with this the value isn't dirty anymore
+ if (m_nCurrentlySelected != -1)
+ m_aVisitedParams[m_nCurrentlySelected] &= ~VisitFlags::Dirty;
+ }
+ else
+ {
+ OUString sName;
+ try
+ {
+ sName = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
+ }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ OUString sMessage(DBA_RES(STR_COULD_NOT_CONVERT_PARAM));
+ sToolTip = sMessage.replaceAll( "$name$", sName );
+ m_xParam->grab_focus();
+ bRet = true;
+ }
+ m_xParam->set_tooltip_text(sToolTip);
+ m_xOKBtn->set_sensitive(bValid);
+ }
+ }
+
+ return bRet;
+ }
+
+ IMPL_LINK(OParameterDialog, OnButtonClicked, weld::Button&, rButton, void)
+ {
+ if (m_xCancelBtn.get() == &rButton)
+ {
+ // no interpreting of the given values anymore...
+ m_xParam->connect_focus_out(Link<weld::Widget&, void>()); // no direct call from the control anymore ...
+ m_xDialog->response(RET_CANCEL);
+ }
+ else if (m_xOKBtn.get() == &rButton)
+ {
+ // transfer the current values into the Any
+ if (OnEntrySelected())
+ { // there was an error interpreting the current text
+ return;
+ }
+
+ if (m_xParams.is())
+ {
+ // write the parameters
+ try
+ {
+ PropertyValue* pValues = m_aFinalValues.getArray();
+ for (sal_Int32 i = 0, nCount = m_xParams->getCount(); i<nCount; ++i, ++pValues)
+ {
+ Reference< XPropertySet > xParamAsSet;
+ m_xParams->getByIndex(i) >>= xParamAsSet;
+
+ OUString sValue;
+ pValues->Value >>= sValue;
+ pValues->Value = m_aPredicateInput.getPredicateValue( sValue, xParamAsSet );
+ }
+ }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ }
+ m_xDialog->response(RET_OK);
+ }
+ else if (m_xTravelNext.get() == &rButton)
+ {
+ if (sal_Int32 nCount = m_xAllParams->n_children())
+ {
+ sal_Int32 nCurrent = m_xAllParams->get_selected_index();
+ OSL_ENSURE(static_cast<size_t>(nCount) == m_aVisitedParams.size(), "OParameterDialog::OnButtonClicked : inconsistent lists !");
+
+ // search the next entry in list we haven't visited yet
+ sal_Int32 nNext = (nCurrent + 1) % nCount;
+ while ((nNext != nCurrent) && ( m_aVisitedParams[nNext] & VisitFlags::Visited ))
+ nNext = (nNext + 1) % nCount;
+
+ if ( m_aVisitedParams[nNext] & VisitFlags::Visited )
+ // there is no such "not visited yet" entry -> simply take the next one
+ nNext = (nCurrent + 1) % nCount;
+
+ m_xAllParams->select(nNext);
+ OnEntrySelected();
+ }
+ }
+ }
+
+ IMPL_LINK_NOARG(OParameterDialog, OnEntryListBoxSelected, weld::TreeView&, void)
+ {
+ OnEntrySelected();
+ }
+
+ bool OParameterDialog::OnEntrySelected()
+ {
+ if (m_aResetVisitFlag.IsActive())
+ {
+ LINK(this, OParameterDialog, OnVisitedTimeout).Call(&m_aResetVisitFlag);
+ m_aResetVisitFlag.Stop();
+ }
+ // save the old values
+ if (m_nCurrentlySelected != -1)
+ {
+ // do the transformation of the current text
+ if (CheckValueForError())
+ { // there was an error interpreting the text
+ m_xAllParams->select(m_nCurrentlySelected);
+ return true;
+ }
+
+ m_aFinalValues.getArray()[m_nCurrentlySelected].Value <<= m_xParam->get_text();
+ }
+
+ // initialize the controls with the new values
+ sal_Int32 nSelected = m_xAllParams->get_selected_index();
+ OSL_ENSURE(nSelected != -1, "OParameterDialog::OnEntrySelected : no current entry !");
+
+ m_xParam->set_text(::comphelper::getString(m_aFinalValues[nSelected].Value));
+ m_nCurrentlySelected = nSelected;
+
+ // with this the value isn't dirty
+ OSL_ENSURE(o3tl::make_unsigned(m_nCurrentlySelected) < m_aVisitedParams.size(), "OParameterDialog::OnEntrySelected : invalid current entry !");
+ m_aVisitedParams[m_nCurrentlySelected] &= ~VisitFlags::Dirty;
+
+ m_aResetVisitFlag.SetTimeout(1000);
+ m_aResetVisitFlag.Start();
+
+ return false;
+ }
+
+ IMPL_LINK_NOARG(OParameterDialog, OnVisitedTimeout, Timer*, void)
+ {
+ OSL_ENSURE(m_nCurrentlySelected != -1, "OParameterDialog::OnVisitedTimeout : invalid call !");
+
+ // mark the currently selected entry as visited
+ OSL_ENSURE(o3tl::make_unsigned(m_nCurrentlySelected) < m_aVisitedParams.size(), "OParameterDialog::OnVisitedTimeout : invalid entry !");
+ m_aVisitedParams[m_nCurrentlySelected] |= VisitFlags::Visited;
+
+ // was it the last "not visited yet" entry ?
+ bool bVisited = false;
+ for (auto const& visitedParam : m_aVisitedParams)
+ {
+ if (!(visitedParam & VisitFlags::Visited))
+ {
+ bVisited = true;
+ break;
+ }
+ }
+
+ if (!bVisited)
+ {
+ // yes, there isn't another one -> change the "default button"
+ m_xDialog->change_default_widget(m_xTravelNext.get(), m_xOKBtn.get());
+ }
+ }
+
+ IMPL_LINK(OParameterDialog, OnValueModified, weld::Entry&, rEdit, void)
+ {
+ // mark the currently selected entry as dirty
+ OSL_ENSURE(o3tl::make_unsigned(m_nCurrentlySelected) < m_aVisitedParams.size(), "OParameterDialog::OnValueModified : invalid entry !");
+ m_aVisitedParams[m_nCurrentlySelected] |= VisitFlags::Dirty;
+ rEdit.set_message_type(weld::EntryMessageType::Normal);
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/queryfilter.cxx b/dbaccess/source/ui/dlg/queryfilter.cxx
new file mode 100644
index 000000000..2735acee5
--- /dev/null
+++ b/dbaccess/source/ui/dlg/queryfilter.cxx
@@ -0,0 +1,748 @@
+/* -*- 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 <queryfilter.hxx>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/sdbc/ColumnSearch.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdb/SQLFilterOperator.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <comphelper/string.hxx>
+#include <tools/diagnose_ex.h>
+#include <osl/diagnose.h>
+#include <connectivity/dbtools.hxx>
+#include <strings.hxx>
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+
+using namespace dbaui;
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+
+static void Replace_OS_PlaceHolder(OUString& aString)
+{
+ aString = aString.replaceAll( "*", "%" );
+ aString = aString.replaceAll( "?", "_" );
+}
+
+static void Replace_SQL_PlaceHolder(OUString& aString)
+{
+ aString = aString.replaceAll( "%", "*" );
+ aString = aString.replaceAll( "_", "?" );
+}
+
+DlgFilterCrit::DlgFilterCrit(weld::Window * pParent,
+ const Reference< XComponentContext >& rxContext,
+ const Reference< XConnection>& _rxConnection,
+ const Reference< XSingleSelectQueryComposer >& _rxComposer,
+ const Reference< XNameAccess>& _rxCols)
+ : GenericDialogController(pParent, "dbaccess/ui/queryfilterdialog.ui", "QueryFilterDialog")
+ , m_xQueryComposer(_rxComposer)
+ , m_xColumns( _rxCols )
+ , m_xConnection( _rxConnection )
+ , m_xMetaData( _rxConnection->getMetaData() )
+ , m_aPredicateInput( rxContext, _rxConnection, getParseContext() )
+ , m_xLB_WHEREFIELD1(m_xBuilder->weld_combo_box("field1"))
+ , m_xLB_WHERECOMP1(m_xBuilder->weld_combo_box("cond1"))
+ , m_xET_WHEREVALUE1(m_xBuilder->weld_entry("value1"))
+ , m_xLB_WHERECOND2(m_xBuilder->weld_combo_box("op2"))
+ , m_xLB_WHEREFIELD2(m_xBuilder->weld_combo_box("field2"))
+ , m_xLB_WHERECOMP2(m_xBuilder->weld_combo_box("cond2"))
+ , m_xET_WHEREVALUE2(m_xBuilder->weld_entry("value2"))
+ , m_xLB_WHERECOND3(m_xBuilder->weld_combo_box("op3"))
+ , m_xLB_WHEREFIELD3(m_xBuilder->weld_combo_box("field3"))
+ , m_xLB_WHERECOMP3(m_xBuilder->weld_combo_box("cond3"))
+ , m_xET_WHEREVALUE3(m_xBuilder->weld_entry("value3"))
+{
+ //set all condition preferred width to max width
+ //if all entries exist
+ Size aSize(m_xLB_WHERECOMP1->get_preferred_size());
+ m_xLB_WHERECOMP1->set_size_request(aSize.Width(), -1);
+ m_xLB_WHERECOMP2->set_size_request(aSize.Width(), -1);
+ m_xLB_WHERECOMP3->set_size_request(aSize.Width(), -1);
+ const sal_Int32 nEntryCount = m_xLB_WHERECOMP1->get_count();
+ m_aSTR_COMPARE_OPERATORS.resize(nEntryCount);
+ for (sal_Int32 i = 0; i < nEntryCount; ++i)
+ {
+ m_aSTR_COMPARE_OPERATORS[i] = m_xLB_WHERECOMP1->get_text(i);
+ }
+ m_xLB_WHERECOMP1->clear();
+
+ // ... also write it into the remaining fields
+ Sequence< OUString> aNames = m_xColumns->getElementNames();
+ const OUString* pIter = aNames.getConstArray();
+ const OUString* pEnd = pIter + aNames.getLength();
+ Reference<XPropertySet> xColumn;
+ for(;pIter != pEnd;++pIter)
+ {
+ try
+ {
+ xColumn.set( m_xColumns->getByName( *pIter ), UNO_QUERY_THROW );
+
+ sal_Int32 nDataType( 0 );
+ OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_TYPE ) >>= nDataType );
+ sal_Int32 eColumnSearch = ::dbtools::getSearchColumnFlag( m_xConnection, nDataType );
+ if ( eColumnSearch == ColumnSearch::NONE )
+ continue;
+
+ bool bIsSearchable( true );
+ OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_ISSEARCHABLE ) >>= bIsSearchable );
+ if ( !bIsSearchable )
+ continue;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ m_xLB_WHEREFIELD1->append_text( *pIter );
+ m_xLB_WHEREFIELD2->append_text( *pIter );
+ m_xLB_WHEREFIELD3->append_text( *pIter );
+ }
+
+ Reference<XNameAccess> xSelectColumns = Reference<XColumnsSupplier>(m_xQueryComposer,UNO_QUERY_THROW)->getColumns();
+ aNames = xSelectColumns->getElementNames();
+ pIter = aNames.getConstArray();
+ pEnd = pIter + aNames.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ // don't insert a column name twice
+ if ( !m_xColumns->hasByName(*pIter) )
+ {
+ xColumn.set(xSelectColumns->getByName(*pIter),UNO_QUERY);
+ OSL_ENSURE(xColumn.is(),"DlgFilterCrit::DlgFilterCrit: Column is null!");
+ sal_Int32 nDataType(0);
+ xColumn->getPropertyValue(PROPERTY_TYPE) >>= nDataType;
+ sal_Int32 eColumnSearch = dbtools::getSearchColumnFlag(m_xConnection,nDataType);
+ // TODO
+ // !pColumn->IsFunction()
+ if(eColumnSearch != ColumnSearch::NONE)
+ {
+ m_xLB_WHEREFIELD1->append_text( *pIter );
+ m_xLB_WHEREFIELD2->append_text( *pIter );
+ m_xLB_WHEREFIELD3->append_text( *pIter );
+ }
+ }
+ }
+ // initialize the listboxes with noEntry
+ m_xLB_WHEREFIELD1->set_active(0);
+ m_xLB_WHEREFIELD2->set_active(0);
+ m_xLB_WHEREFIELD3->set_active(0);
+
+ // insert the criteria into the dialog
+ Sequence<Sequence<PropertyValue > > aValues = m_xQueryComposer->getStructuredFilter();
+ int i(0);
+ fillLines(i, aValues);
+ aValues = m_xQueryComposer->getStructuredHavingClause();
+ fillLines(i, aValues);
+
+ EnableLines();
+
+ m_xLB_WHEREFIELD1->connect_changed(LINK(this,DlgFilterCrit,ListSelectHdl));
+ m_xLB_WHEREFIELD2->connect_changed(LINK(this,DlgFilterCrit,ListSelectHdl));
+ m_xLB_WHEREFIELD3->connect_changed(LINK(this,DlgFilterCrit,ListSelectHdl));
+
+ m_xLB_WHERECOMP1->connect_changed(LINK(this,DlgFilterCrit,ListSelectCompHdl));
+ m_xLB_WHERECOMP2->connect_changed(LINK(this,DlgFilterCrit,ListSelectCompHdl));
+ m_xLB_WHERECOMP3->connect_changed(LINK(this,DlgFilterCrit,ListSelectCompHdl));
+
+ m_xET_WHEREVALUE1->connect_focus_out( LINK( this, DlgFilterCrit, PredicateLoseFocus ) );
+ m_xET_WHEREVALUE2->connect_focus_out( LINK( this, DlgFilterCrit, PredicateLoseFocus ) );
+ m_xET_WHEREVALUE3->connect_focus_out( LINK( this, DlgFilterCrit, PredicateLoseFocus ) );
+
+ if (m_xET_WHEREVALUE1->get_sensitive())
+ m_xET_WHEREVALUE1->grab_focus();
+}
+
+DlgFilterCrit::~DlgFilterCrit()
+{
+}
+
+sal_Int32 DlgFilterCrit::GetOSQLPredicateType( std::u16string_view _rSelectedPredicate ) const
+{
+ sal_Int32 nPredicateIndex = -1;
+ for ( size_t i=0; i < m_aSTR_COMPARE_OPERATORS.size(); ++i)
+ if ( m_aSTR_COMPARE_OPERATORS[i] == _rSelectedPredicate )
+ {
+ nPredicateIndex = i;
+ break;
+ }
+
+ sal_Int32 nPredicateType = SQLFilterOperator::NOT_SQLNULL;
+ switch ( nPredicateIndex )
+ {
+ case 0:
+ nPredicateType = SQLFilterOperator::EQUAL;
+ break;
+ case 1:
+ nPredicateType = SQLFilterOperator::NOT_EQUAL;
+ break;
+ case 2:
+ nPredicateType = SQLFilterOperator::LESS;
+ break;
+ case 3:
+ nPredicateType = SQLFilterOperator::LESS_EQUAL;
+ break;
+ case 4:
+ nPredicateType = SQLFilterOperator::GREATER;
+ break;
+ case 5:
+ nPredicateType = SQLFilterOperator::GREATER_EQUAL;
+ break;
+ case 6:
+ nPredicateType = SQLFilterOperator::LIKE;
+ break;
+ case 7:
+ nPredicateType = SQLFilterOperator::NOT_LIKE;
+ break;
+ case 8:
+ nPredicateType = SQLFilterOperator::SQLNULL;
+ break;
+ case 9:
+ nPredicateType = SQLFilterOperator::NOT_SQLNULL;
+ break;
+ default:
+ OSL_FAIL( "DlgFilterCrit::GetOSQLPredicateType: unknown predicate string!" );
+ break;
+ }
+
+ return nPredicateType;
+}
+
+sal_Int32 DlgFilterCrit::GetSelectionPos(sal_Int32 eType, const weld::ComboBox& rListBox)
+{
+ sal_Int32 nPos;
+ switch(eType)
+ {
+ case SQLFilterOperator::EQUAL:
+ nPos = 0;
+ break;
+ case SQLFilterOperator::NOT_EQUAL:
+ nPos = 1;
+ break;
+ case SQLFilterOperator::LESS:
+ nPos = 2;
+ break;
+ case SQLFilterOperator::LESS_EQUAL:
+ nPos = 3;
+ break;
+ case SQLFilterOperator::GREATER:
+ nPos = 4;
+ break;
+ case SQLFilterOperator::GREATER_EQUAL:
+ nPos = 5;
+ break;
+ case SQLFilterOperator::NOT_LIKE:
+ nPos = rListBox.get_count() > 2 ? rListBox.get_count()-3 : 0;
+ break;
+ case SQLFilterOperator::LIKE:
+ nPos = rListBox.get_count() > 2 ? rListBox.get_count()-4 : 1;
+ break;
+ case SQLFilterOperator::SQLNULL:
+ nPos = rListBox.get_count()-2;
+ break;
+ case SQLFilterOperator::NOT_SQLNULL:
+ nPos = rListBox.get_count()-1;
+ break;
+ default:
+ // TODO What value should this be?
+ nPos = 0;
+ break;
+ }
+ return nPos;
+}
+
+bool DlgFilterCrit::getCondition(const weld::ComboBox& _rField,const weld::ComboBox& _rComp,const weld::Entry& _rValue,PropertyValue& _rFilter) const
+{
+ bool bHaving = false;
+ try
+ {
+ _rFilter.Name = _rField.get_active_text();
+ Reference< XPropertySet > xColumn = getQueryColumn(_rFilter.Name);
+ if ( xColumn.is() )
+ {
+ bool bFunction = false;
+ OUString sTableName;
+ Reference< XPropertySetInfo > xInfo = xColumn->getPropertySetInfo();
+ if ( xInfo->hasPropertyByName(PROPERTY_REALNAME) )
+ {
+ if ( xInfo->hasPropertyByName(PROPERTY_TABLENAME) )
+ {
+ xColumn->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName;
+ if ( !sTableName.isEmpty() )
+ {
+ // properly quote all parts of the table name, so
+ // e.g. <schema>.<table> becomes "<schema>"."<table>"
+ OUString aCatlog,aSchema,aTable;
+ ::dbtools::qualifiedNameComponents( m_xMetaData, sTableName, aCatlog, aSchema, aTable, ::dbtools::EComposeRule::InDataManipulation );
+ sTableName = ::dbtools::composeTableName( m_xMetaData, aCatlog, aSchema, aTable, true, ::dbtools::EComposeRule::InDataManipulation );
+ }
+ }
+ xColumn->getPropertyValue(PROPERTY_REALNAME) >>= _rFilter.Name;
+ static constexpr OUStringLiteral sAgg = u"AggregateFunction";
+ if ( xInfo->hasPropertyByName(sAgg) )
+ xColumn->getPropertyValue(sAgg) >>= bHaving;
+ static constexpr OUStringLiteral sFunction = u"Function";
+ if ( xInfo->hasPropertyByName(sFunction) )
+ xColumn->getPropertyValue(sFunction) >>= bFunction;
+ }
+ if ( !bFunction )
+ {
+ const OUString aQuote = m_xMetaData.is() ? m_xMetaData->getIdentifierQuoteString() : OUString();
+ _rFilter.Name = ::dbtools::quoteName(aQuote,_rFilter.Name);
+ if ( !sTableName.isEmpty() )
+ {
+ sTableName += "." + _rFilter.Name;
+ _rFilter.Name = sTableName;
+ }
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+
+ _rFilter.Handle = GetOSQLPredicateType( _rComp.get_active_text() );
+ if ( SQLFilterOperator::SQLNULL != _rFilter.Handle && _rFilter.Handle != SQLFilterOperator::NOT_SQLNULL )
+ {
+ OUString sPredicateValue;
+ m_aPredicateInput.getPredicateValue( _rValue.get_text(), getMatchingColumn( _rValue ) ) >>= sPredicateValue;
+ if ( _rFilter.Handle == SQLFilterOperator::LIKE ||
+ _rFilter.Handle == SQLFilterOperator::NOT_LIKE )
+ ::Replace_OS_PlaceHolder( sPredicateValue );
+ _rFilter.Value <<= sPredicateValue;
+ }
+ return bHaving;
+}
+
+Reference< XPropertySet > DlgFilterCrit::getColumn( const OUString& _rFieldName ) const
+{
+ Reference< XPropertySet > xColumn;
+ try
+ {
+ if ( m_xColumns.is() && m_xColumns->hasByName( _rFieldName ) )
+ m_xColumns->getByName( _rFieldName ) >>= xColumn;
+
+ Reference< XNameAccess> xColumns = Reference< XColumnsSupplier >(m_xQueryComposer,UNO_QUERY_THROW)->getColumns();
+ if ( xColumns.is() && !xColumn.is() )
+ {
+ Sequence< OUString> aSeq = xColumns->getElementNames();
+ const OUString* pIter = aSeq.getConstArray();
+ const OUString* pEnd = pIter + aSeq.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ Reference<XPropertySet> xProp(xColumns->getByName(*pIter),UNO_QUERY);
+ if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME) )
+ {
+ OUString sRealName;
+ xProp->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
+ if ( sRealName == _rFieldName )
+ {
+ if ( m_xColumns.is() && m_xColumns->hasByName( *pIter ) )
+ m_xColumns->getByName( *pIter ) >>= xColumn;
+ break;
+ }
+ }
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ return xColumn;
+}
+
+Reference< XPropertySet > DlgFilterCrit::getQueryColumn( const OUString& _rFieldName ) const
+{
+ Reference< XPropertySet > xColumn;
+ try
+ {
+ Reference< XNameAccess> xColumns = Reference< XColumnsSupplier >(m_xQueryComposer,UNO_QUERY_THROW)->getColumns();
+ if ( xColumns.is() && xColumns->hasByName( _rFieldName ) )
+ xColumns->getByName( _rFieldName ) >>= xColumn;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ return xColumn;
+}
+
+Reference< XPropertySet > DlgFilterCrit::getMatchingColumn( const weld::Entry& _rValueInput ) const
+{
+ // the name
+ OUString sField;
+ if ( &_rValueInput == m_xET_WHEREVALUE1.get() )
+ {
+ sField = m_xLB_WHEREFIELD1->get_active_text();
+ }
+ else if ( &_rValueInput == m_xET_WHEREVALUE2.get() )
+ {
+ sField = m_xLB_WHEREFIELD2->get_active_text();
+ }
+ else if ( &_rValueInput == m_xET_WHEREVALUE3.get() )
+ {
+ sField = m_xLB_WHEREFIELD3->get_active_text();
+ }
+ else {
+ OSL_FAIL( "DlgFilterCrit::getMatchingColumn: invalid event source!" );
+ }
+
+ // the field itself
+ return getColumn( sField );
+}
+
+IMPL_LINK( DlgFilterCrit, PredicateLoseFocus, weld::Widget&, rControl, void )
+{
+ weld::Entry& rField = dynamic_cast<weld::Entry&>(rControl);
+ // retrieve the field affected
+ Reference< XPropertySet> xColumn(getMatchingColumn(rField));
+ // and normalize its content
+ if ( xColumn.is() )
+ {
+ OUString sText(rField.get_text());
+ m_aPredicateInput.normalizePredicateString(sText, xColumn);
+ rField.set_text(sText);
+ }
+}
+
+void DlgFilterCrit::SetLine( int nIdx, const PropertyValue& _rItem, bool _bOr )
+{
+ OUString aStr;
+ _rItem.Value >>= aStr;
+ if ( _rItem.Handle == SQLFilterOperator::LIKE ||
+ _rItem.Handle == SQLFilterOperator::NOT_LIKE )
+ ::Replace_SQL_PlaceHolder(aStr);
+ aStr = comphelper::string::stripEnd(aStr, ' ');
+
+ Reference< XPropertySet > xColumn = getColumn( _rItem.Name );
+
+ // to make sure that we only set first three
+ weld::ComboBox* pColumnListControl = nullptr;
+ weld::ComboBox* pPredicateListControl = nullptr;
+ weld::Entry* pPredicateValueControl = nullptr;
+ switch( nIdx )
+ {
+ case 0:
+ pColumnListControl = m_xLB_WHEREFIELD1.get();
+ pPredicateListControl = m_xLB_WHERECOMP1.get();
+ pPredicateValueControl = m_xET_WHEREVALUE1.get();
+ break;
+ case 1:
+ m_xLB_WHERECOND2->set_active( _bOr ? 1 : 0 );
+
+ pColumnListControl = m_xLB_WHEREFIELD2.get();
+ pPredicateListControl = m_xLB_WHERECOMP2.get();
+ pPredicateValueControl = m_xET_WHEREVALUE2.get();
+ break;
+ case 2:
+ m_xLB_WHERECOND3->set_active( _bOr ? 1 : 0 );
+
+ pColumnListControl = m_xLB_WHEREFIELD3.get();
+ pPredicateListControl = m_xLB_WHERECOMP3.get();
+ pPredicateValueControl = m_xET_WHEREVALUE3.get();
+ break;
+ }
+
+ if ( !(pColumnListControl && pPredicateListControl && pPredicateValueControl) )
+ return;
+
+ OUString sName;
+ if ( xColumn.is() )
+ xColumn->getPropertyValue(PROPERTY_NAME) >>= sName;
+ else
+ sName = _rItem.Name;
+ // select the appropriate field name
+ SelectField( *pColumnListControl, sName );
+ ListSelectHdl( *pColumnListControl );
+
+ // select the appropriate condition
+ pPredicateListControl->set_active( GetSelectionPos( _rItem.Handle, *pPredicateListControl ) );
+
+ // initially normalize this value
+ OUString aString( aStr );
+ m_aPredicateInput.normalizePredicateString( aString, xColumn );
+ pPredicateValueControl->set_text( aString );
+}
+
+void DlgFilterCrit::SelectField(weld::ComboBox& rBox, std::u16string_view rField)
+{
+ const sal_Int32 nCnt = rBox.get_count();
+
+ for( sal_Int32 i=0 ; i<nCnt ; i++ )
+ {
+ if (rBox.get_text(i) == rField)
+ {
+ rBox.set_active(i);
+ return;
+ }
+ }
+
+ rBox.set_active(0);
+}
+
+void DlgFilterCrit::EnableLines()
+{
+ // enabling/disabling of whole lines
+ if( m_xLB_WHEREFIELD1->get_active() == 0 )
+ {
+ m_xLB_WHEREFIELD2->set_sensitive(false);
+ m_xLB_WHERECOND2->set_sensitive(false);
+ m_xLB_WHERECOMP2->set_sensitive(false);
+ m_xET_WHEREVALUE2->set_sensitive(false);
+
+ m_xLB_WHEREFIELD3->set_sensitive(false);
+ m_xLB_WHERECOND3->set_sensitive(false);
+ m_xLB_WHERECOMP3->set_sensitive(false);
+ m_xET_WHEREVALUE3->set_sensitive(false);
+ }
+ else
+ {
+ m_xLB_WHEREFIELD2->set_sensitive(true);
+ m_xLB_WHERECOND2->set_sensitive(true);
+ m_xLB_WHERECOMP2->set_sensitive(true);
+ m_xET_WHEREVALUE2->set_sensitive(true);
+
+ m_xLB_WHEREFIELD3->set_sensitive(true);
+ m_xLB_WHERECOND3->set_sensitive(true);
+ m_xLB_WHERECOMP3->set_sensitive(true);
+ m_xET_WHEREVALUE3->set_sensitive(true);
+ }
+
+ if( m_xLB_WHEREFIELD2->get_active() == 0 )
+ {
+ m_xLB_WHEREFIELD3->set_sensitive(false);
+ m_xLB_WHERECOND3->set_sensitive(false);
+ m_xLB_WHERECOMP3->set_sensitive(false);
+ m_xET_WHEREVALUE3->set_sensitive(false);
+ }
+ else
+ {
+ m_xLB_WHEREFIELD3->set_sensitive(true);
+ m_xLB_WHERECOND3->set_sensitive(true);
+ m_xLB_WHERECOMP3->set_sensitive(true);
+ m_xET_WHEREVALUE3->set_sensitive(true);
+ }
+
+ // comparison field equal to NOENTRY
+ if( m_xLB_WHEREFIELD1->get_active() == 0 )
+ {
+ m_xLB_WHERECOMP1->set_sensitive(false);
+ m_xET_WHEREVALUE1->set_sensitive(false);
+ }
+ else
+ {
+ m_xLB_WHEREFIELD1->set_sensitive(true);
+ m_xLB_WHERECOMP1->set_sensitive(true);
+ m_xET_WHEREVALUE1->set_sensitive(true);
+ }
+
+ if( m_xLB_WHEREFIELD2->get_active() == 0 )
+ {
+ m_xLB_WHERECOND2->set_sensitive(false);
+ m_xLB_WHERECOMP2->set_sensitive(false);
+ m_xET_WHEREVALUE2->set_sensitive(false);
+ }
+ else
+ {
+ m_xLB_WHERECOND2->set_sensitive(true);
+ m_xLB_WHEREFIELD2->set_sensitive(true);
+ m_xLB_WHERECOMP2->set_sensitive(true);
+ m_xET_WHEREVALUE2->set_sensitive(true);
+ }
+
+ if( m_xLB_WHEREFIELD3->get_active() == 0 )
+ {
+ m_xLB_WHERECOND3->set_sensitive(false);
+ m_xLB_WHERECOMP3->set_sensitive(false);
+ m_xET_WHEREVALUE3->set_sensitive(false);
+ }
+ else
+ {
+ m_xLB_WHERECOND3->set_sensitive(true);
+ m_xLB_WHERECOND3->set_sensitive(true);
+ m_xLB_WHEREFIELD3->set_sensitive(true);
+ m_xLB_WHERECOMP3->set_sensitive(true);
+ m_xET_WHEREVALUE3->set_sensitive(true);
+ }
+
+ // comparison operator equal to ISNULL or ISNOTNULL
+ if(m_xLB_WHERECOMP1->get_count() > 2 &&
+ ((m_xLB_WHERECOMP1->get_active() == m_xLB_WHERECOMP1->get_count()-1) ||
+ (m_xLB_WHERECOMP1->get_active() == m_xLB_WHERECOMP1->get_count()-2)) )
+ m_xET_WHEREVALUE1->set_sensitive(false);
+
+ if(m_xLB_WHERECOMP2->get_count() > 2 &&
+ ((m_xLB_WHERECOMP2->get_active() == m_xLB_WHERECOMP2->get_count()-1) ||
+ (m_xLB_WHERECOMP2->get_active() == m_xLB_WHERECOMP2->get_count()-2)) )
+ m_xET_WHEREVALUE2->set_sensitive(false);
+
+ if(m_xLB_WHERECOMP3->get_count() > 2 &&
+ ((m_xLB_WHERECOMP3->get_active() == m_xLB_WHERECOMP3->get_count()-1) ||
+ (m_xLB_WHERECOMP3->get_active() == m_xLB_WHERECOMP3->get_count()-2)) )
+ m_xET_WHEREVALUE3->set_sensitive(false);
+}
+
+IMPL_LINK( DlgFilterCrit, ListSelectHdl, weld::ComboBox&, rListBox, void )
+{
+ OUString aName;
+ weld::ComboBox* pComp;
+ if(&rListBox == m_xLB_WHEREFIELD1.get())
+ {
+ aName = m_xLB_WHEREFIELD1->get_active_text();
+ pComp = m_xLB_WHERECOMP1.get();
+ }
+ else if(&rListBox == m_xLB_WHEREFIELD2.get())
+ {
+ aName = m_xLB_WHEREFIELD2->get_active_text();
+ pComp = m_xLB_WHERECOMP2.get();
+ }
+ else
+ {
+ aName = m_xLB_WHEREFIELD3->get_active_text();
+ pComp = m_xLB_WHERECOMP3.get();
+ }
+
+ pComp->clear();
+
+ Reference<XPropertySet> xColumn = getColumn(aName);
+ if ( xColumn.is() )
+ {
+ sal_Int32 nDataType = 0;
+ xColumn->getPropertyValue(PROPERTY_TYPE) >>= nDataType;
+ sal_Int32 eColumnSearch = dbtools::getSearchColumnFlag(m_xConnection,nDataType);
+
+ if(eColumnSearch == ColumnSearch::FULL)
+ {
+ for(size_t i=0;i < m_aSTR_COMPARE_OPERATORS.size(); i++)
+ pComp->append_text(m_aSTR_COMPARE_OPERATORS[i]);
+ }
+ else if(eColumnSearch == ColumnSearch::CHAR)
+ {
+ for(sal_Int32 i=6; i<10; i++)
+ pComp->append_text(m_aSTR_COMPARE_OPERATORS[i]);
+ }
+ else if(eColumnSearch == ColumnSearch::BASIC)
+ {
+ size_t i;
+ for( i = 0; i < 6; i++ )
+ pComp->append_text(m_aSTR_COMPARE_OPERATORS[i]);
+ for(i=8; i < m_aSTR_COMPARE_OPERATORS.size(); ++i)
+ pComp->append_text(m_aSTR_COMPARE_OPERATORS[i]);
+ }
+ else
+ {
+ OSL_FAIL("DlgFilterCrit::ListSelectHdl: This column should not exist at all.");
+ }
+ }
+ pComp->set_active(0);
+
+ EnableLines();
+}
+
+IMPL_LINK_NOARG(DlgFilterCrit, ListSelectCompHdl, weld::ComboBox&, void)
+{
+ EnableLines();
+}
+
+void DlgFilterCrit::BuildWherePart()
+{
+ Sequence<Sequence<PropertyValue> > aFilter(1),aHaving(1);
+
+ if( m_xLB_WHEREFIELD1->get_active() != 0 )
+ {
+ PropertyValue aValue;
+ if ( getCondition(*m_xLB_WHEREFIELD1,*m_xLB_WHERECOMP1,*m_xET_WHEREVALUE1,aValue) )
+ {
+ aHaving = { { aValue } };
+ }
+ else
+ {
+ aFilter = { { aValue} };
+ }
+ }
+
+ if( m_xLB_WHEREFIELD2->get_active() != 0 )
+ {
+ PropertyValue aValue;
+ Sequence<Sequence<PropertyValue> >& _rValues = aFilter;
+ if ( getCondition(*m_xLB_WHEREFIELD2,*m_xLB_WHERECOMP2,*m_xET_WHEREVALUE2,aValue) )
+ _rValues = aHaving;
+ if ( m_xLB_WHERECOND2->get_active() )
+ _rValues.realloc( _rValues.getLength() + 1);
+ sal_Int32 nPos = _rValues.getLength() - 1;
+ sal_Int32 nAndPos = _rValues[nPos].getLength();
+ auto pValues = _rValues.getArray();
+ pValues[nPos].realloc( _rValues[nPos].getLength() + 1);
+ pValues[nPos].getArray()[nAndPos] = aValue;
+ }
+
+ if( m_xLB_WHEREFIELD3->get_active() != 0 )
+ {
+ PropertyValue aValue;
+ Sequence<Sequence<PropertyValue> >& _rValues = aFilter;
+ if ( getCondition(*m_xLB_WHEREFIELD3,*m_xLB_WHERECOMP3,*m_xET_WHEREVALUE3,aValue) )
+ _rValues = aHaving;
+ if (m_xLB_WHERECOND3->get_active())
+ _rValues.realloc( _rValues.getLength() + 1);
+ sal_Int32 nPos = _rValues.getLength() - 1;
+ sal_Int32 nAndPos = _rValues[nPos].getLength();
+ auto pValues = _rValues.getArray();
+ pValues[nPos].realloc( _rValues[nPos].getLength() + 1);
+ pValues[nPos].getArray()[nAndPos] = aValue;
+ }
+ try
+ {
+ m_xQueryComposer->setStructuredFilter(aFilter);
+ m_xQueryComposer->setStructuredHavingClause(aHaving);
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void DlgFilterCrit::fillLines(int &i, const Sequence< Sequence< PropertyValue > >& _aValues)
+{
+ const Sequence<PropertyValue >* pOrIter = _aValues.getConstArray();
+ const Sequence<PropertyValue >* pOrEnd = pOrIter + _aValues.getLength();
+ bool bOr(i != 0); // WHERE clause and HAVING clause are always ANDed, nor ORed
+ for(; pOrIter != pOrEnd; ++pOrIter)
+ {
+ const PropertyValue* pAndIter = pOrIter->getConstArray();
+ const PropertyValue* pAndEnd = pAndIter + pOrIter->getLength();
+ for(;pAndIter != pAndEnd; ++pAndIter)
+ {
+ SetLine( i++,*pAndIter,bOr);
+ bOr = false;
+ }
+ bOr=true;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/queryorder.cxx b/dbaccess/source/ui/dlg/queryorder.cxx
new file mode 100644
index 000000000..40b25cdd3
--- /dev/null
+++ b/dbaccess/source/ui/dlg/queryorder.cxx
@@ -0,0 +1,218 @@
+/* -*- 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 <strings.hrc>
+#include <strings.hxx>
+#include <core_resource.hxx>
+#include <queryorder.hxx>
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#include <com/sun/star/sdbc/ColumnSearch.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <connectivity/dbtools.hxx>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <tools/diagnose_ex.h>
+
+using namespace dbaui;
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+
+
+DlgOrderCrit::DlgOrderCrit(weld::Window * pParent,
+ const Reference< XConnection>& _rxConnection,
+ const Reference< XSingleSelectQueryComposer >& _rxComposer,
+ const Reference< XNameAccess>& _rxCols)
+ : GenericDialogController(pParent, "dbaccess/ui/sortdialog.ui", "SortDialog")
+ , m_xQueryComposer(_rxComposer)
+ , m_xColumns(_rxCols)
+ , m_xConnection(_rxConnection)
+ , m_xLB_ORDERFIELD1(m_xBuilder->weld_combo_box("field1"))
+ , m_xLB_ORDERVALUE1(m_xBuilder->weld_combo_box("value1"))
+ , m_xLB_ORDERFIELD2(m_xBuilder->weld_combo_box("field2"))
+ , m_xLB_ORDERVALUE2(m_xBuilder->weld_combo_box("value2"))
+ , m_xLB_ORDERFIELD3(m_xBuilder->weld_combo_box("field3"))
+ , m_xLB_ORDERVALUE3(m_xBuilder->weld_combo_box("value3"))
+{
+ m_aColumnList[0] = m_xLB_ORDERFIELD1.get();
+ m_aColumnList[1] = m_xLB_ORDERFIELD2.get();
+ m_aColumnList[2] = m_xLB_ORDERFIELD3.get();
+
+ m_aValueList[0] = m_xLB_ORDERVALUE1.get();
+ m_aValueList[1] = m_xLB_ORDERVALUE2.get();
+ m_aValueList[2] = m_xLB_ORDERVALUE3.get();
+
+ OUString aSTR_NOENTRY(DBA_RES(STR_VALUE_NONE));
+ for (auto j : m_aColumnList)
+ {
+ j->append_text(aSTR_NOENTRY);
+ }
+
+ for (int j=0; j < DOG_ROWS; ++j)
+ {
+ m_aColumnList[j]->set_active(0);
+ m_aValueList[j]->set_active(0);
+ }
+ try
+ {
+ // ... also the remaining fields
+ Sequence< OUString> aNames = m_xColumns->getElementNames();
+ const OUString* pIter = aNames.getConstArray();
+ const OUString* pEnd = pIter + aNames.getLength();
+ Reference<XPropertySet> xColumn;
+ for(;pIter != pEnd;++pIter)
+ {
+ xColumn.set(m_xColumns->getByName(*pIter),UNO_QUERY);
+ OSL_ENSURE(xColumn.is(),"Column is null!");
+ if ( xColumn.is() )
+ {
+ sal_Int32 nDataType = 0;
+ xColumn->getPropertyValue(PROPERTY_TYPE) >>= nDataType;
+ sal_Int32 eColumnSearch = dbtools::getSearchColumnFlag(m_xConnection,nDataType);
+ if(eColumnSearch != ColumnSearch::NONE)
+ {
+ for (auto j : m_aColumnList)
+ {
+ j->append_text(*pIter);
+ }
+ }
+ }
+ }
+
+ m_sOrgOrder = m_xQueryComposer->getOrder();
+ impl_initializeOrderList_nothrow();
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ EnableLines();
+
+ m_xLB_ORDERFIELD1->connect_changed(LINK(this,DlgOrderCrit,FieldListSelectHdl));
+ m_xLB_ORDERFIELD2->connect_changed(LINK(this,DlgOrderCrit,FieldListSelectHdl));
+}
+
+DlgOrderCrit::~DlgOrderCrit()
+{
+}
+
+IMPL_LINK_NOARG( DlgOrderCrit, FieldListSelectHdl, weld::ComboBox&, void )
+{
+ EnableLines();
+}
+
+void DlgOrderCrit::impl_initializeOrderList_nothrow()
+{
+ try
+ {
+ static const OUStringLiteral sNameProperty = u"Name";
+ static const OUStringLiteral sAscendingProperty = u"IsAscending";
+
+ Reference< XIndexAccess > xOrderColumns( m_xQueryComposer->getOrderColumns(), UNO_SET_THROW );
+ sal_Int32 nColumns = xOrderColumns->getCount();
+ if ( nColumns > DOG_ROWS )
+ nColumns = DOG_ROWS;
+
+ for ( sal_Int32 i = 0; i < nColumns; ++i )
+ {
+ Reference< XPropertySet > xColumn( xOrderColumns->getByIndex( i ), UNO_QUERY_THROW );
+
+ OUString sColumnName;
+ bool bIsAscending( true );
+
+ xColumn->getPropertyValue( sNameProperty ) >>= sColumnName;
+ xColumn->getPropertyValue( sAscendingProperty ) >>= bIsAscending;
+
+ m_aColumnList[i]->set_active_text(sColumnName);
+ m_aValueList[i]->set_active(bIsAscending ? 0 : 1);
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void DlgOrderCrit::EnableLines()
+{
+
+ if ( m_xLB_ORDERFIELD1->get_active() == 0 )
+ {
+ m_xLB_ORDERFIELD2->set_sensitive(false);
+ m_xLB_ORDERVALUE2->set_sensitive(false);
+
+ m_xLB_ORDERFIELD2->set_active( 0 );
+ m_xLB_ORDERVALUE2->set_active( 0 );
+ }
+ else
+ {
+ m_xLB_ORDERFIELD2->set_sensitive(true);
+ m_xLB_ORDERVALUE2->set_sensitive(true);
+ }
+
+ if ( m_xLB_ORDERFIELD2->get_active() == 0 )
+ {
+ m_xLB_ORDERFIELD3->set_sensitive(false);
+ m_xLB_ORDERVALUE3->set_sensitive(false);
+
+ m_xLB_ORDERFIELD3->set_active( 0 );
+ m_xLB_ORDERVALUE3->set_active( 0 );
+ }
+ else
+ {
+ m_xLB_ORDERFIELD3->set_sensitive(true);
+ m_xLB_ORDERVALUE3->set_sensitive(true);
+ }
+}
+
+OUString DlgOrderCrit::GetOrderList( ) const
+{
+ Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData();
+ OUString sQuote = xMetaData.is() ? xMetaData->getIdentifierQuoteString() : OUString();
+
+ OUStringBuffer sOrder;
+ for( sal_uInt16 i=0 ; i<DOG_ROWS; i++ )
+ {
+ if (m_aColumnList[i]->get_active() != 0)
+ {
+ if(!sOrder.isEmpty())
+ sOrder.append(",");
+
+ OUString sName = m_aColumnList[i]->get_active_text();
+ sOrder.append(::dbtools::quoteName(sQuote,sName));
+ if (m_aValueList[i]->get_active())
+ sOrder.append(" DESC ");
+ else
+ sOrder.append(" ASC ");
+ }
+ }
+ return sOrder.makeStringAndClear();
+}
+
+void DlgOrderCrit::BuildOrderPart()
+{
+ m_xQueryComposer->setOrder(GetOrderList());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/sqlmessage.cxx b/dbaccess/source/ui/dlg/sqlmessage.cxx
new file mode 100644
index 000000000..eacc59083
--- /dev/null
+++ b/dbaccess/source/ui/dlg/sqlmessage.cxx
@@ -0,0 +1,604 @@
+/* -*- 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 <core_resource.hxx>
+#include <sqlmessage.hxx>
+#include <strings.hrc>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <vcl/stdtext.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <osl/diagnose.h>
+#include <connectivity/dbexception.hxx>
+#include <connectivity/sqlerror.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <tools/urlobj.hxx>
+
+#define RET_MORE RET_RETRY + 1
+
+using namespace dbtools;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::sdb;
+using namespace com::sun::star::sdbc;
+
+namespace dbaui
+{
+
+namespace
+{
+ class ImageProvider
+ {
+ private:
+ OUString m_defaultImageID;
+
+ public:
+ explicit ImageProvider(const OUString& defaultImageID)
+ : m_defaultImageID(defaultImageID)
+ {
+ }
+
+ const OUString& getImage() const
+ {
+ return m_defaultImageID;
+ }
+ };
+
+ class LabelProvider
+ {
+ private:
+ OUString m_label;
+ public:
+ explicit LabelProvider(TranslateId labelResourceID)
+ : m_label(DBA_RES(labelResourceID))
+ {
+ }
+
+ const OUString& getLabel() const
+ {
+ return m_label;
+ }
+ };
+
+ class ProviderFactory
+ {
+ private:
+ mutable std::shared_ptr< ImageProvider > m_pErrorImage;
+ mutable std::shared_ptr< ImageProvider > m_pWarningsImage;
+ mutable std::shared_ptr< ImageProvider > m_pInfoImage;
+ mutable std::shared_ptr< LabelProvider > m_pErrorLabel;
+ mutable std::shared_ptr< LabelProvider > m_pWarningsLabel;
+ mutable std::shared_ptr< LabelProvider > m_pInfoLabel;
+
+ public:
+ ProviderFactory()
+ {
+ }
+
+ std::shared_ptr< ImageProvider > const & getImageProvider( SQLExceptionInfo::TYPE _eType ) const
+ {
+ std::shared_ptr< ImageProvider >* ppProvider( &m_pErrorImage );
+ OUString sNormalImageID("dialog-error");
+
+ switch ( _eType )
+ {
+ case SQLExceptionInfo::TYPE::SQLWarning:
+ ppProvider = &m_pWarningsImage;
+ sNormalImageID = "dialog-warning";
+ break;
+
+ case SQLExceptionInfo::TYPE::SQLContext:
+ ppProvider = &m_pInfoImage;
+ sNormalImageID = "dialog-information";
+ break;
+
+ default:
+ break;
+ }
+
+ if ( !ppProvider->get() )
+ (*ppProvider) = std::make_shared<ImageProvider>(sNormalImageID);
+ return *ppProvider;
+ }
+
+ std::shared_ptr< LabelProvider > const & getLabelProvider( SQLExceptionInfo::TYPE _eType, bool _bSubLabel ) const
+ {
+ std::shared_ptr< LabelProvider >* ppProvider( &m_pErrorLabel );
+ TranslateId pLabelID( STR_EXCEPTION_ERROR );
+
+ switch ( _eType )
+ {
+ case SQLExceptionInfo::TYPE::SQLWarning:
+ ppProvider = &m_pWarningsLabel;
+ pLabelID = STR_EXCEPTION_WARNING;
+ break;
+
+ case SQLExceptionInfo::TYPE::SQLContext:
+ ppProvider = &m_pInfoLabel;
+ pLabelID = _bSubLabel ? STR_EXCEPTION_DETAILS : STR_EXCEPTION_INFO;
+ break;
+ default:
+ break;
+ }
+
+ if ( !ppProvider->get() )
+ (*ppProvider) = std::make_shared<LabelProvider>( pLabelID );
+ return *ppProvider;
+ }
+
+ };
+
+ /// a stripped version of the SQLException, packed for displaying
+ struct ExceptionDisplayInfo
+ {
+ SQLExceptionInfo::TYPE eType;
+
+ std::shared_ptr< ImageProvider > pImageProvider;
+ std::shared_ptr< LabelProvider > pLabelProvider;
+
+ bool bSubEntry;
+
+ OUString sMessage;
+ OUString sSQLState;
+ OUString sErrorCode;
+
+ ExceptionDisplayInfo() : eType( SQLExceptionInfo::TYPE::Undefined ), bSubEntry( false ) { }
+ explicit ExceptionDisplayInfo( SQLExceptionInfo::TYPE _eType ) : eType( _eType ), bSubEntry( false ) { }
+ };
+
+ bool lcl_hasDetails( const ExceptionDisplayInfo& _displayInfo )
+ {
+ return ( !_displayInfo.sErrorCode.isEmpty() )
+ || ( !_displayInfo.sSQLState.isEmpty()
+ && _displayInfo.sSQLState != "S1000"
+ );
+ }
+
+ typedef std::vector< ExceptionDisplayInfo > ExceptionDisplayChain;
+
+ /// strips the [OOoBase] vendor identifier from the given error message, if applicable
+ OUString lcl_stripOOoBaseVendor( const OUString& _rErrorMessage )
+ {
+ OUString sErrorMessage( _rErrorMessage );
+
+ const OUString sVendorIdentifier( ::connectivity::SQLError::getMessagePrefix() );
+ if ( sErrorMessage.startsWith( sVendorIdentifier ) )
+ {
+ // characters to strip
+ sal_Int32 nStripLen( sVendorIdentifier.getLength() );
+ // usually, there should be a whitespace between the vendor and the real message
+ while ( ( sErrorMessage.getLength() > nStripLen )
+ && ( sErrorMessage[nStripLen] == ' ' )
+ )
+ ++nStripLen;
+ sErrorMessage = sErrorMessage.copy( nStripLen );
+ }
+
+ return sErrorMessage;
+ }
+
+ void lcl_buildExceptionChain( const SQLExceptionInfo& _rErrorInfo, const ProviderFactory& _rFactory, ExceptionDisplayChain& _out_rChain )
+ {
+ ExceptionDisplayChain().swap(_out_rChain);
+
+ SQLExceptionIteratorHelper iter( _rErrorInfo );
+ while ( iter.hasMoreElements() )
+ {
+ // current chain element
+ SQLExceptionInfo aCurrentElement;
+ iter.next( aCurrentElement );
+
+ const SQLException* pCurrentError = aCurrentElement;
+ OSL_ENSURE( pCurrentError, "lcl_buildExceptionChain: iterator failure!" );
+ // hasMoreElements should not have returned <TRUE/> in this case
+
+ ExceptionDisplayInfo aDisplayInfo( aCurrentElement.getType() );
+
+ aDisplayInfo.sMessage = pCurrentError->Message.trim();
+ aDisplayInfo.sSQLState = pCurrentError->SQLState;
+ if ( pCurrentError->ErrorCode )
+ aDisplayInfo.sErrorCode = OUString::number( pCurrentError->ErrorCode );
+
+ if ( aDisplayInfo.sMessage.isEmpty()
+ && !lcl_hasDetails( aDisplayInfo )
+ )
+ {
+ OSL_FAIL( "lcl_buildExceptionChain: useless exception: no state, no error code, no message!" );
+ continue;
+ }
+
+ aDisplayInfo.pImageProvider = _rFactory.getImageProvider( aCurrentElement.getType() );
+ aDisplayInfo.pLabelProvider = _rFactory.getLabelProvider( aCurrentElement.getType(), false );
+
+ _out_rChain.push_back( aDisplayInfo );
+
+ if ( aCurrentElement.getType() == SQLExceptionInfo::TYPE::SQLContext )
+ {
+ const SQLContext* pContext = aCurrentElement;
+ if ( !pContext->Details.isEmpty() )
+ {
+ ExceptionDisplayInfo aSubInfo( aCurrentElement.getType() );
+
+ aSubInfo.sMessage = pContext->Details;
+ aSubInfo.pImageProvider = _rFactory.getImageProvider( aCurrentElement.getType() );
+ aSubInfo.pLabelProvider = _rFactory.getLabelProvider( aCurrentElement.getType(), true );
+ aSubInfo.bSubEntry = true;
+
+ _out_rChain.push_back( aSubInfo );
+ }
+ }
+ }
+ }
+
+ void lcl_insertExceptionEntry(weld::TreeView& rList, size_t nElementPos, const ExceptionDisplayInfo& rEntry)
+ {
+ rList.append(OUString::number(nElementPos), rEntry.pLabelProvider->getLabel(), rEntry.pImageProvider->getImage());
+ }
+}
+
+namespace {
+
+class OExceptionChainDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::TreeView> m_xExceptionList;
+ std::unique_ptr<weld::TextView> m_xExceptionText;
+
+ OUString m_sStatusLabel;
+ OUString m_sErrorCodeLabel;
+
+ ExceptionDisplayChain m_aExceptions;
+
+public:
+ OExceptionChainDialog(weld::Window* pParent, ExceptionDisplayChain&& rExceptions);
+
+protected:
+ DECL_LINK(OnExceptionSelected, weld::TreeView&, void);
+};
+
+}
+
+OExceptionChainDialog::OExceptionChainDialog(weld::Window* pParent, ExceptionDisplayChain&& rExceptions)
+ : GenericDialogController(pParent, "dbaccess/ui/sqlexception.ui", "SQLExceptionDialog")
+ , m_xExceptionList(m_xBuilder->weld_tree_view("list"))
+ , m_xExceptionText(m_xBuilder->weld_text_view("description"))
+ , m_aExceptions(std::move(rExceptions))
+{
+ int nListWidth = m_xExceptionText->get_approximate_digit_width() * 28;
+ int nTextWidth = m_xExceptionText->get_approximate_digit_width() * 42;
+ int nHeight = m_xExceptionList->get_height_rows(6);
+ m_xExceptionList->set_size_request(nListWidth, nHeight);
+ m_xExceptionText->set_size_request(nTextWidth, nHeight);
+
+ m_sStatusLabel = DBA_RES( STR_EXCEPTION_STATUS );
+ m_sErrorCodeLabel = DBA_RES( STR_EXCEPTION_ERRORCODE );
+
+ m_xExceptionList->connect_changed(LINK(this, OExceptionChainDialog, OnExceptionSelected));
+
+ bool bHave22018 = false;
+ size_t elementPos = 0;
+
+ for (auto const& elem : m_aExceptions)
+ {
+ lcl_insertExceptionEntry(*m_xExceptionList, elementPos, elem);
+ bHave22018 = elem.sSQLState == "22018";
+ ++elementPos;
+ }
+
+ // if the error has the code 22018, then add an additional explanation
+ // #i24021#
+ if ( bHave22018 )
+ {
+ ProviderFactory aProviderFactory;
+
+ ExceptionDisplayInfo aInfo22018;
+ aInfo22018.sMessage = DBA_RES( STR_EXPLAN_STRINGCONVERSION_ERROR );
+ aInfo22018.pLabelProvider = aProviderFactory.getLabelProvider( SQLExceptionInfo::TYPE::SQLContext, false );
+ aInfo22018.pImageProvider = aProviderFactory.getImageProvider( SQLExceptionInfo::TYPE::SQLContext );
+ m_aExceptions.push_back( aInfo22018 );
+
+ lcl_insertExceptionEntry(*m_xExceptionList, m_aExceptions.size() - 1, aInfo22018);
+ }
+
+ if (m_xExceptionList->n_children())
+ {
+ m_xExceptionList->select(0);
+ OnExceptionSelected(*m_xExceptionList);
+ }
+}
+
+IMPL_LINK_NOARG(OExceptionChainDialog, OnExceptionSelected, weld::TreeView&, void)
+{
+ OUString sText;
+
+ OUString sId(m_xExceptionList->get_selected_id());
+ if (!sId.isEmpty())
+ {
+ const ExceptionDisplayInfo& aExceptionInfo(m_aExceptions[sId.toUInt32()]);
+
+ if ( !aExceptionInfo.sSQLState.isEmpty() )
+ {
+ sText += m_sStatusLabel + ": " + aExceptionInfo.sSQLState + "\n";
+ }
+
+ if ( !aExceptionInfo.sErrorCode.isEmpty() )
+ {
+ sText += m_sErrorCodeLabel + ": " + aExceptionInfo.sErrorCode + "\n";
+ }
+
+ if ( !sText.isEmpty() )
+ sText += "\n";
+
+ sText += aExceptionInfo.sMessage;
+ }
+
+ m_xExceptionText->set_text(sText);
+}
+
+// SQLMessageBox_Impl
+struct SQLMessageBox_Impl
+{
+ ExceptionDisplayChain aDisplayInfo;
+
+ explicit SQLMessageBox_Impl( const SQLExceptionInfo& _rExceptionInfo )
+ {
+ // transform the exception chain to a form more suitable for displaying it here
+ ProviderFactory aProviderFactory;
+ lcl_buildExceptionChain( _rExceptionInfo, aProviderFactory, aDisplayInfo );
+ }
+};
+
+namespace
+{
+ void lcl_addButton(weld::MessageDialog* pDialog, StandardButtonType eType, bool bDefault)
+ {
+ sal_uInt16 nButtonID = 0;
+ switch (eType)
+ {
+ case StandardButtonType::Yes:
+ nButtonID = RET_YES;
+ pDialog->add_button(GetStandardText(StandardButtonType::Yes), nButtonID);
+ break;
+ case StandardButtonType::No:
+ nButtonID = RET_NO;
+ pDialog->add_button(GetStandardText(StandardButtonType::No), nButtonID);
+ break;
+ case StandardButtonType::OK:
+ nButtonID = RET_OK;
+ pDialog->add_button(GetStandardText(StandardButtonType::OK), nButtonID);
+ break;
+ case StandardButtonType::Cancel:
+ nButtonID = RET_CANCEL;
+ pDialog->add_button(GetStandardText(StandardButtonType::Cancel), nButtonID);
+ break;
+ case StandardButtonType::Retry:
+ nButtonID = RET_RETRY;
+ pDialog->add_button(GetStandardText(StandardButtonType::Retry), nButtonID);
+ break;
+ case StandardButtonType::Help:
+ nButtonID = RET_HELP;
+ pDialog->add_button(GetStandardText(StandardButtonType::Help), nButtonID);
+ break;
+ default:
+ OSL_FAIL( "lcl_addButton: invalid button id!" );
+ break;
+ }
+ if (bDefault)
+ pDialog->set_default_response(nButtonID);
+ }
+}
+
+void OSQLMessageBox::impl_fillMessages()
+{
+ OSL_PRECOND( !m_pImpl->aDisplayInfo.empty(), "OSQLMessageBox::impl_fillMessages: nothing to display at all?" );
+
+ if ( m_pImpl->aDisplayInfo.empty() )
+ return;
+ const ExceptionDisplayInfo* pSecondInfo = nullptr;
+
+ const ExceptionDisplayInfo& rFirstInfo = *m_pImpl->aDisplayInfo.begin();
+ if ( m_pImpl->aDisplayInfo.size() > 1 )
+ pSecondInfo = &m_pImpl->aDisplayInfo[1];
+ OUString sPrimary, sSecondary;
+ sPrimary = rFirstInfo.sMessage;
+ // one or two texts to display?
+ if ( pSecondInfo )
+ {
+ // we show two elements in the main dialog if and only if one of
+ // - the first element in the chain is an SQLContext, and the second
+ // element denotes its sub entry
+ // - the first and the second element are both independent (i.e. the second
+ // is no sub entry), and none of them is a context.
+ bool bFirstElementIsContext = ( rFirstInfo.eType == SQLExceptionInfo::TYPE::SQLContext );
+ bool bSecondElementIsContext = ( pSecondInfo->eType == SQLExceptionInfo::TYPE::SQLContext );
+
+ if ( bFirstElementIsContext && pSecondInfo->bSubEntry )
+ sSecondary = pSecondInfo->sMessage;
+ if ( !bFirstElementIsContext && !bSecondElementIsContext )
+ sSecondary = pSecondInfo->sMessage;
+ }
+
+ // primary text
+ m_xDialog->set_primary_text(lcl_stripOOoBaseVendor(sPrimary));
+
+ // secondary text (if applicable)
+ m_xDialog->set_secondary_text(lcl_stripOOoBaseVendor(sSecondary));
+}
+
+void OSQLMessageBox::impl_createStandardButtons( MessBoxStyle _nStyle )
+{
+ if ( _nStyle & MessBoxStyle::YesNoCancel )
+ {
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Yes, bool(_nStyle & MessBoxStyle::DefaultYes));
+ lcl_addButton(m_xDialog.get(), StandardButtonType::No, bool(_nStyle & MessBoxStyle::DefaultNo));
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Cancel, bool(_nStyle & MessBoxStyle::DefaultCancel));
+ }
+ else if ( _nStyle & MessBoxStyle::OkCancel )
+ {
+ lcl_addButton(m_xDialog.get(), StandardButtonType::OK, bool(_nStyle & MessBoxStyle::DefaultOk));
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Cancel, bool(_nStyle & MessBoxStyle::DefaultCancel));
+ }
+ else if ( _nStyle & MessBoxStyle::YesNo )
+ {
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Yes, bool(_nStyle & MessBoxStyle::DefaultYes));
+ lcl_addButton(m_xDialog.get(), StandardButtonType::No, bool(_nStyle & MessBoxStyle::DefaultNo));
+ }
+ else if ( _nStyle & MessBoxStyle::RetryCancel )
+ {
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Retry, bool(_nStyle & MessBoxStyle::DefaultRetry));
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Cancel, bool(_nStyle & MessBoxStyle::DefaultCancel));
+ }
+ else if ( _nStyle & MessBoxStyle::Ok )
+ {
+ lcl_addButton(m_xDialog.get(), StandardButtonType::OK, true);
+ }
+
+ if ( m_sHelpURL.isEmpty() )
+ return;
+
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Help, false);
+
+ OUString aTmp;
+ INetURLObject aHID( m_sHelpURL );
+ if ( aHID.GetProtocol() == INetProtocol::Hid )
+ aTmp = aHID.GetURLPath();
+ else
+ aTmp = m_sHelpURL;
+
+ m_xDialog->set_help_id(OUStringToOString(aTmp, RTL_TEXTENCODING_UTF8));
+}
+
+void OSQLMessageBox::impl_addDetailsButton()
+{
+ size_t nFirstPageVisible = m_xDialog->get_secondary_text().isEmpty() ? 1 : 2;
+
+ bool bMoreDetailsAvailable = m_pImpl->aDisplayInfo.size() > nFirstPageVisible;
+ if ( !bMoreDetailsAvailable )
+ {
+ // even if the text fits into what we can display, we might need to details button
+ // if there is more non-trivial information in the errors than the mere messages
+ for (auto const& error : m_pImpl->aDisplayInfo)
+ {
+ if ( lcl_hasDetails(error) )
+ {
+ bMoreDetailsAvailable = true;
+ break;
+ }
+ }
+ }
+
+ if ( bMoreDetailsAvailable )
+ {
+ m_xDialog->add_button(GetStandardText(StandardButtonType::More), RET_MORE);
+ m_xMoreButton.reset(m_xDialog->weld_widget_for_response(RET_MORE));
+ m_xMoreButton->connect_clicked(LINK(this, OSQLMessageBox, ButtonClickHdl));
+ }
+}
+
+void OSQLMessageBox::Construct(weld::Window* pParent, MessBoxStyle _nStyle, MessageType _eImage)
+{
+ // init the image
+ MessageType eType( _eImage );
+ if ( eType == AUTO )
+ {
+ switch ( m_pImpl->aDisplayInfo[0].eType )
+ {
+ case SQLExceptionInfo::TYPE::SQLException: eType = Error; break;
+ case SQLExceptionInfo::TYPE::SQLWarning: eType = Warning; break;
+ case SQLExceptionInfo::TYPE::SQLContext: eType = Info; break;
+ default: OSL_FAIL( "OSQLMessageBox::Construct: invalid type!" );
+ }
+ }
+ VclMessageType eMessageType;
+ switch (eType)
+ {
+ default:
+ OSL_FAIL( "OSQLMessageBox::impl_initImage: unsupported image type!" );
+ [[fallthrough]];
+ case Info:
+ eMessageType = VclMessageType::Info;
+ break;
+ case Warning:
+ eMessageType = VclMessageType::Warning;
+ break;
+ case Error:
+ eMessageType = VclMessageType::Error;
+ break;
+ case Query:
+ eMessageType = VclMessageType::Question;
+ break;
+ }
+
+ m_xDialog.reset(Application::CreateMessageDialog(pParent, eMessageType, VclButtonsType::NONE, ""));
+ m_xDialog->set_title(utl::ConfigManager::getProductName() + " Base");
+
+ impl_fillMessages();
+
+ // create buttons
+ impl_createStandardButtons( _nStyle );
+ impl_addDetailsButton();
+}
+
+OSQLMessageBox::OSQLMessageBox(weld::Window* pParent, const SQLExceptionInfo& rException, MessBoxStyle nStyle, const OUString& rHelpURL)
+ : m_pImpl(new SQLMessageBox_Impl(rException))
+ , m_sHelpURL(rHelpURL)
+{
+ Construct(pParent, nStyle, AUTO);
+}
+
+OSQLMessageBox::OSQLMessageBox(weld::Window* pParent, const OUString& rTitle, const OUString& rMessage, MessBoxStyle nStyle, MessageType eType, const ::dbtools::SQLExceptionInfo* pAdditionalErrorInfo )
+{
+ SQLContext aError;
+ aError.Message = rTitle;
+ aError.Details = rMessage;
+ if (pAdditionalErrorInfo)
+ aError.NextException = pAdditionalErrorInfo->get();
+
+ m_pImpl.reset(new SQLMessageBox_Impl(SQLExceptionInfo(aError)));
+
+ Construct(pParent, nStyle, eType);
+}
+
+OSQLMessageBox::~OSQLMessageBox()
+{
+}
+
+IMPL_LINK_NOARG(OSQLMessageBox, ButtonClickHdl, weld::Button&, void)
+{
+ OExceptionChainDialog aDlg(m_xDialog.get(), std::vector(m_pImpl->aDisplayInfo));
+ aDlg.run();
+}
+
+// OSQLWarningBox
+OSQLWarningBox::OSQLWarningBox(weld::Window* pParent, const OUString& rMessage, MessBoxStyle nStyle,
+ const ::dbtools::SQLExceptionInfo* pAdditionalErrorInfo )
+ : OSQLMessageBox(pParent, DBA_RES(STR_EXCEPTION_WARNING), rMessage, nStyle, MessageType::Warning, pAdditionalErrorInfo)
+{
+}
+
+// OSQLErrorBox
+OSQLErrorBox::OSQLErrorBox(weld::Window* pParent, const OUString& rMessage)
+ : OSQLMessageBox(pParent, DBA_RES(STR_EXCEPTION_ERROR), rMessage, MessBoxStyle::Ok | MessBoxStyle::DefaultOk,
+ MessageType::Error, nullptr)
+{
+}
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/tablespage.cxx b/dbaccess/source/ui/dlg/tablespage.cxx
new file mode 100644
index 000000000..6094f84e7
--- /dev/null
+++ b/dbaccess/source/ui/dlg/tablespage.cxx
@@ -0,0 +1,488 @@
+/* -*- 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 "tablespage.hxx"
+#include <dsitems.hxx>
+#include <datasourceconnector.hxx>
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/dbexception.hxx>
+#include <stringlistitem.hxx>
+#include <svl/stritem.hxx>
+#include <strings.hxx>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <sqlmessage.hxx>
+#include <UITools.hxx>
+#include <osl/diagnose.h>
+#include <TablesSingleDlg.hxx>
+#include <tools/diagnose_ex.h>
+#include <cppuhelper/exc_hlp.hxx>
+
+namespace dbaui
+{
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::util;
+ using namespace ::dbtools;
+ using namespace ::comphelper;
+
+ // OTableSubscriptionPage
+ OTableSubscriptionPage::OTableSubscriptionPage(weld::Container* pPage, OTableSubscriptionDialog* pTablesDlg, const SfxItemSet& _rCoreAttrs)
+ : OGenericAdministrationPage(pPage, pTablesDlg, "dbaccess/ui/tablesfilterpage.ui", "TablesFilterPage", _rCoreAttrs)
+ , m_bCatalogAtStart(true)
+ , m_pTablesDlg(pTablesDlg)
+ , m_xTables(m_xBuilder->weld_widget("TablesFilterPage"))
+ , m_xTablesList(new OTableTreeListBox(m_xBuilder->weld_tree_view("treeview"), true))
+ {
+ m_xTablesList->init();
+
+ weld::TreeView& rWidget = m_xTablesList->GetWidget();
+
+ rWidget.set_size_request(rWidget.get_approximate_digit_width() * 48,
+ rWidget.get_height_rows(12));
+
+ // initialize the TabListBox
+ rWidget.set_selection_mode(SelectionMode::Multiple);
+
+ rWidget.connect_toggled(LINK(this, OTableSubscriptionPage, OnTreeEntryChecked));
+ }
+
+ OTableSubscriptionPage::~OTableSubscriptionPage()
+ {
+ // just to make sure that our connection will be removed
+ try
+ {
+ ::comphelper::disposeComponent(m_xCurrentConnection);
+ }
+ catch (RuntimeException&) { }
+ }
+
+ void OTableSubscriptionPage::implCheckTables(const Sequence< OUString >& _rTables)
+ {
+ // the meta data for the current connection, used for splitting up table names
+ Reference< XDatabaseMetaData > xMeta;
+ try
+ {
+ if (m_xCurrentConnection.is())
+ xMeta = m_xCurrentConnection->getMetaData();
+ }
+ catch(SQLException&)
+ {
+ OSL_FAIL("OTableSubscriptionPage::implCheckTables : could not retrieve the current connection's meta data!");
+ }
+
+ // uncheck all
+ CheckAll(false);
+
+ // check the ones which are in the list
+ OUString sCatalog, sSchema, sName;
+
+ std::unique_ptr<weld::TreeIter> xRootEntry(m_xTablesList->getAllObjectsEntry());
+
+ for (const OUString& rIncludeTable : _rTables)
+ {
+ if (xMeta.is())
+ qualifiedNameComponents(xMeta, rIncludeTable, sCatalog, sSchema, sName,::dbtools::EComposeRule::InDataManipulation);
+ else
+ sName = rIncludeTable;
+
+ bool bAllTables = (1 == sName.getLength()) && ('%' == sName[0]);
+ bool bAllSchemas = (1 == sSchema.getLength()) && ('%' == sSchema[0]);
+
+ // the catalog entry
+ std::unique_ptr<weld::TreeIter> xCatalog(m_xTablesList->GetEntryPosByName(sCatalog, xRootEntry.get()));
+ if (!(xCatalog || sCatalog.isEmpty()))
+ // the table (resp. its catalog) referred in this filter entry does not exist anymore
+ continue;
+
+ if (bAllSchemas && xCatalog)
+ {
+ m_xTablesList->checkWildcard(*xCatalog);
+ continue;
+ }
+
+ // the schema entry
+ std::unique_ptr<weld::TreeIter> xSchema = m_xTablesList->GetEntryPosByName(sSchema, (xCatalog ? xCatalog.get() : xRootEntry.get()));
+ if (!(xSchema || sSchema.isEmpty()))
+ // the table (resp. its schema) referred in this filter entry does not exist anymore
+ continue;
+
+ if (bAllTables && xSchema)
+ {
+ m_xTablesList->checkWildcard(*xSchema);
+ continue;
+ }
+
+ std::unique_ptr<weld::TreeIter> xEntry(m_xTablesList->GetEntryPosByName(sName, xSchema ? xSchema.get() : (xCatalog ? xCatalog.get() : xRootEntry.get())));
+ if (xEntry)
+ m_xTablesList->GetWidget().set_toggle(*xEntry, TRISTATE_TRUE);
+ }
+ m_xTablesList->CheckButtons();
+ }
+
+ void OTableSubscriptionPage::implCompleteTablesCheck( const css::uno::Sequence< OUString >& _rTableFilter )
+ {
+ if (!_rTableFilter.hasElements())
+ { // no tables visible
+ CheckAll(false);
+ }
+ else
+ {
+ if ((1 == _rTableFilter.getLength()) && _rTableFilter[0] == "%")
+ { // all tables visible
+ CheckAll();
+ }
+ else
+ implCheckTables( _rTableFilter );
+ }
+ }
+
+ void OTableSubscriptionPage::implInitControls(const SfxItemSet& _rSet, bool _bSaveValue)
+ {
+ // check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
+ bool bValid, bReadonly;
+ getFlags(_rSet, bValid, bReadonly);
+
+ // get the name of the data source we're working for
+ const SfxStringItem* pNameItem = _rSet.GetItem<SfxStringItem>(DSID_NAME);
+ OSL_ENSURE(pNameItem, "OTableSubscriptionPage::implInitControls: missing the name attribute!");
+ OUString sDSName = pNameItem->GetValue();
+
+ if (bValid && !sDSName.isEmpty() && !m_xCurrentConnection.is() )
+ { // get the current table list from the connection for the current settings
+
+ // the PropertyValues for the current dialog settings
+ Sequence< PropertyValue > aConnectionParams;
+ OSL_ENSURE(m_pTablesDlg, "OTableSubscriptionPage::implInitControls: need a parent dialog doing the translation!");
+ if ( m_pTablesDlg )
+ {
+ if (!m_pTablesDlg->getCurrentSettings(aConnectionParams))
+ {
+ m_xTablesList->GetWidget().clear();
+ m_pTablesDlg->endExecution();
+ return;
+ }
+ }
+
+ // fill the table list with this connection information
+ SQLExceptionInfo aErrorInfo;
+
+ try
+ {
+ weld::WaitObject aWaitCursor(GetFrameWeld());
+
+ Reference<XPropertySet> xProp = m_pTablesDlg->getCurrentDataSource();
+ OSL_ENSURE(xProp.is(),"No data source set!");
+ if ( xProp.is() )
+ {
+ Any aTableFilter = xProp->getPropertyValue(PROPERTY_TABLEFILTER);
+ Any aTableTypeFilter = xProp->getPropertyValue(PROPERTY_TABLETYPEFILTER);
+
+ Reference<XModifiable> xModi(getDataSourceOrModel(xProp),UNO_QUERY);
+ bool bModified = ( xModi.is() && xModi->isModified() );
+
+ Sequence< OUString > aNewTableFilter { "%" };
+ xProp->setPropertyValue(PROPERTY_TABLEFILTER,Any(aNewTableFilter));
+
+ xProp->setPropertyValue( PROPERTY_TABLETYPEFILTER, Any( Sequence< OUString >() ) );
+ Reference< css::lang::XEventListener> xEvt;
+ aErrorInfo = ::dbaui::createConnection(xProp, m_xORB, xEvt, m_xCurrentConnection);
+
+ xProp->setPropertyValue(PROPERTY_TABLEFILTER,aTableFilter);
+ xProp->setPropertyValue(PROPERTY_TABLETYPEFILTER,aTableTypeFilter);
+
+ if ( xModi.is() && !bModified )
+ xModi->setModified(false);
+
+ }
+
+ if ( m_xCurrentConnection.is() )
+ {
+ m_xTablesList->UpdateTableList( m_xCurrentConnection );
+ if (m_pTablesDlg)
+ m_pTablesDlg->successfullyConnected();
+ }
+ }
+ catch (const SQLException&)
+ {
+ aErrorInfo = ::cppu::getCaughtException();
+ }
+
+ if (aErrorInfo.isValid())
+ {
+ // establishing the connection failed. Show an error window and exit.
+ OSQLMessageBox aMessageBox(GetFrameWeld(), aErrorInfo);
+ aMessageBox.run();
+ m_xTables->set_sensitive(false);
+ m_xTablesList->GetWidget().clear();
+
+ if ( m_pTablesDlg )
+ {
+ m_pTablesDlg->clearPassword();
+ m_pTablesDlg->endExecution();
+ }
+ }
+ else
+ {
+ // in addition, we need some infos about the connection used
+ m_sCatalogSeparator = "."; // (default)
+ m_bCatalogAtStart = true; // (default)
+ try
+ {
+ Reference< XDatabaseMetaData > xMeta;
+ if (m_xCurrentConnection.is())
+ xMeta = m_xCurrentConnection->getMetaData();
+ if (xMeta.is() && xMeta->supportsCatalogsInDataManipulation())
+ {
+ m_sCatalogSeparator = xMeta->getCatalogSeparator();
+ m_bCatalogAtStart = xMeta->isCatalogAtStart();
+ }
+ }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ }
+ }
+
+ // get the current table filter
+ const OStringListItem* pTableFilter = _rSet.GetItem<OStringListItem>(DSID_TABLEFILTER);
+ Sequence< OUString > aTableFilter;
+ if (pTableFilter)
+ aTableFilter = pTableFilter->getList();
+
+ implCompleteTablesCheck( aTableFilter );
+
+ // expand the first entry by default
+ std::unique_ptr<weld::TreeIter> xExpand = m_xTablesList->getAllObjectsEntry();
+ while (xExpand)
+ {
+ m_xTablesList->GetWidget().expand_row(*xExpand);
+ if (!m_xTablesList->GetWidget().iter_children(*xExpand))
+ break;
+ std::unique_ptr<weld::TreeIter> xSibling(m_xTablesList->GetWidget().make_iterator(xExpand.get()));
+ if (m_xTablesList->GetWidget().iter_next_sibling(*xSibling))
+ xExpand.reset();
+ }
+
+ // update the toolbox according the current selection and check state
+ OGenericAdministrationPage::implInitControls(_rSet, _bSaveValue);
+ }
+
+ void OTableSubscriptionPage::CheckAll( bool _bCheck )
+ {
+ std::unique_ptr<weld::TreeIter> xEntry(m_xTablesList->GetWidget().make_iterator());
+ if (m_xTablesList->GetWidget().get_iter_first(*xEntry))
+ {
+ do
+ {
+ m_xTablesList->GetWidget().set_toggle(*xEntry, _bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ }
+ while (m_xTablesList->GetWidget().iter_next(*xEntry));
+ }
+
+ if (_bCheck)
+ {
+ auto xRoot = m_xTablesList->getAllObjectsEntry();
+ if (xRoot)
+ m_xTablesList->checkWildcard(*xRoot);
+ }
+ }
+
+ DeactivateRC OTableSubscriptionPage::DeactivatePage(SfxItemSet* _pSet)
+ {
+ DeactivateRC nResult = OGenericAdministrationPage::DeactivatePage(_pSet);
+
+ // dispose the connection, we don't need it anymore, so we're not wasting resources
+ try
+ {
+ ::comphelper::disposeComponent(m_xCurrentConnection);
+ }
+ catch (RuntimeException&) { }
+
+ return nResult;
+ }
+
+ IMPL_LINK(OTableSubscriptionPage, OnTreeEntryChecked, const weld::TreeView::iter_col&, rRowCol, void)
+ {
+ m_xTablesList->checkedButton_noBroadcast(rRowCol.first);
+ callModifiedHdl();
+ }
+
+ Sequence< OUString > OTableSubscriptionPage::collectDetailedSelection() const
+ {
+ Sequence< OUString > aTableFilter;
+ constexpr OUStringLiteral sWildcard = u"%";
+
+ std::unique_ptr<weld::TreeIter> xAllObjectsEntry(m_xTablesList->getAllObjectsEntry());
+ if (!xAllObjectsEntry)
+ return aTableFilter;
+ std::unique_ptr<weld::TreeIter> xEntry(m_xTablesList->GetWidget().make_iterator(xAllObjectsEntry.get()));
+ if (!m_xTablesList->GetWidget().iter_next(*xEntry))
+ xEntry.reset();
+ while (xEntry)
+ {
+ bool bCatalogWildcard = false;
+ bool bSchemaWildcard = false;
+ std::unique_ptr<weld::TreeIter> xSchema;
+ std::unique_ptr<weld::TreeIter> xCatalog;
+
+ if (m_xTablesList->GetWidget().get_toggle(*xEntry) == TRISTATE_TRUE && !m_xTablesList->GetWidget().iter_has_child(*xEntry))
+ { // checked and a leaf, which means it's no catalog, no schema, but a real table
+ OUStringBuffer sComposedName;
+ OUString sCatalog;
+ if (m_xTablesList->GetWidget().get_iter_depth(*xEntry))
+ {
+ xSchema = m_xTablesList->GetWidget().make_iterator(xEntry.get());
+ m_xTablesList->GetWidget().iter_parent(*xSchema);
+ if (xAllObjectsEntry->equal(*xSchema))
+ {
+ // do not want to have the root entry
+ xSchema.reset();
+ }
+
+ if (xSchema)
+ { // it's a real schema entry, not the "all objects" root
+ if (m_xTablesList->GetWidget().get_iter_depth(*xSchema))
+ {
+ xCatalog = m_xTablesList->GetWidget().make_iterator(xSchema.get());
+ m_xTablesList->GetWidget().iter_parent(*xCatalog);
+ if (xAllObjectsEntry->equal(*xCatalog))
+ {
+ // do not want to have the root entry
+ xCatalog.reset();
+ }
+
+ if (xCatalog)
+ { // it's a real catalog entry, not the "all objects" root
+ bCatalogWildcard = m_xTablesList->isWildcardChecked(*xCatalog);
+ if (m_bCatalogAtStart)
+ {
+ sComposedName.append(m_xTablesList->GetWidget().get_text(*xCatalog) + m_sCatalogSeparator);
+ if (bCatalogWildcard)
+ sComposedName.append(sWildcard);
+ }
+ else
+ {
+ if (bCatalogWildcard)
+ sCatalog = sWildcard;
+ else
+ sCatalog.clear();
+ sCatalog += m_sCatalogSeparator + m_xTablesList->GetWidget().get_text(*xCatalog) ;
+ }
+ }
+ }
+ bSchemaWildcard = m_xTablesList->isWildcardChecked(*xSchema);
+ sComposedName.append(m_xTablesList->GetWidget().get_text(*xSchema) + ".");
+ }
+
+ if (bSchemaWildcard)
+ sComposedName.append(sWildcard);
+ }
+ if (!bSchemaWildcard && !bCatalogWildcard)
+ sComposedName.append(m_xTablesList->GetWidget().get_text(*xEntry));
+
+ if (!m_bCatalogAtStart && !bCatalogWildcard)
+ sComposedName.append(sCatalog);
+
+ // need some space
+ sal_Int32 nOldLen = aTableFilter.getLength();
+ aTableFilter.realloc(nOldLen + 1);
+ // add the new name
+ aTableFilter.getArray()[nOldLen] = sComposedName.makeStringAndClear();
+ }
+
+ if (bCatalogWildcard)
+ xEntry = implNextSibling(xCatalog.get());
+ else if (bSchemaWildcard)
+ xEntry = implNextSibling(xSchema.get());
+ else
+ {
+ if (!m_xTablesList->GetWidget().iter_next(*xEntry))
+ xEntry.reset();
+ }
+ }
+
+ return aTableFilter;
+ }
+
+ std::unique_ptr<weld::TreeIter> OTableSubscriptionPage::implNextSibling(const weld::TreeIter* pEntry) const
+ {
+ std::unique_ptr<weld::TreeIter> xReturn;
+ if (pEntry)
+ {
+ xReturn = m_xTablesList->GetWidget().make_iterator(pEntry);
+ if (!m_xTablesList->GetWidget().iter_next_sibling(*xReturn))
+ {
+ std::unique_ptr<weld::TreeIter> xParent = m_xTablesList->GetWidget().make_iterator(pEntry);
+ if (m_xTablesList->GetWidget().iter_parent(*xParent))
+ xReturn = implNextSibling(xParent.get());
+ else
+ xReturn.reset();
+ }
+ }
+ return xReturn;
+ }
+
+ bool OTableSubscriptionPage::FillItemSet( SfxItemSet* _rCoreAttrs )
+ {
+ bool bValid, bReadonly;
+ getFlags(*_rCoreAttrs, bValid, bReadonly);
+
+ if (!bValid || bReadonly)
+ // don't store anything if the data we're working with is invalid or readonly
+ return true;
+
+ // create the output string which contains all the table names
+ if ( m_xCurrentConnection.is() )
+ { // collect the table filter data only if we have a connection - else no tables are displayed at all
+ Sequence< OUString > aTableFilter;
+ auto xRoot = m_xTablesList->getAllObjectsEntry();
+ if (xRoot && m_xTablesList->isWildcardChecked(*xRoot))
+ {
+ aTableFilter = { "%" };
+ }
+ else
+ {
+ aTableFilter = collectDetailedSelection();
+ }
+ _rCoreAttrs->Put( OStringListItem(DSID_TABLEFILTER, aTableFilter) );
+ }
+
+ return true;
+ }
+
+ void OTableSubscriptionPage::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& /*_rControlList*/)
+ {
+ }
+
+ void OTableSubscriptionPage::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
+ {
+ _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Widget>(m_xTables.get()));
+ }
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/tablespage.hxx b/dbaccess/source/ui/dlg/tablespage.hxx
new file mode 100644
index 000000000..483518b2a
--- /dev/null
+++ b/dbaccess/source/ui/dlg/tablespage.hxx
@@ -0,0 +1,81 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "adminpages.hxx"
+#include <tabletree.hxx>
+#include <com/sun/star/sdbc/XConnection.hpp>
+
+namespace dbaui
+{
+
+ // OTableSubscriptionPage
+ class OTableSubscriptionDialog;
+ class OTableSubscriptionPage final
+ :public OGenericAdministrationPage
+ {
+ private:
+ OUString m_sCatalogSeparator;
+ bool m_bCatalogAtStart : 1;
+
+ css::uno::Reference< css::sdbc::XConnection >
+ m_xCurrentConnection; /// valid as long as the page is active
+ OTableSubscriptionDialog* m_pTablesDlg;
+
+ std::unique_ptr<weld::Widget> m_xTables;
+ std::unique_ptr<OTableTreeListBox> m_xTablesList;
+
+ public:
+ virtual bool FillItemSet(SfxItemSet* _rCoreAttrs) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet* _pSet) override;
+
+ OTableSubscriptionPage(weld::Container* pPage, OTableSubscriptionDialog* pController, const SfxItemSet& _rCoreAttrs);
+ virtual ~OTableSubscriptionPage() override;
+
+ private:
+ virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+ virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override;
+
+ DECL_LINK(OnTreeEntryChecked, const weld::TreeView::iter_col&, void);
+
+ /** check the tables in <member>m_aTablesList</member> according to <arg>_rTables</arg>
+ */
+ void implCheckTables(const css::uno::Sequence< OUString >& _rTables);
+
+ /// returns the next sibling, if not available, the next sibling of the parent, a.s.o.
+ std::unique_ptr<weld::TreeIter> implNextSibling(const weld::TreeIter* pEntry) const;
+
+ /** return the current selection in <member>m_aTablesList</member>
+ */
+ css::uno::Sequence< OUString > collectDetailedSelection() const;
+
+ /// (un)check all entries
+ void CheckAll( bool bCheck = true );
+
+ virtual void implInitControls(const SfxItemSet& _rSet, bool _bSaveValue) override;
+
+ // checks the tables according to the filter given
+ // in opposite to implCheckTables, this method handles the case of an empty sequence, too ...
+ void implCompleteTablesCheck( const css::uno::Sequence< OUString >& _rTableFilter );
+ };
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/dlg/textconnectionsettings.cxx b/dbaccess/source/ui/dlg/textconnectionsettings.cxx
new file mode 100644
index 000000000..5076b3d32
--- /dev/null
+++ b/dbaccess/source/ui/dlg/textconnectionsettings.cxx
@@ -0,0 +1,69 @@
+/* -*- 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 <textconnectionsettings.hxx>
+#include "TextConnectionHelper.hxx"
+#include <dsitems.hxx>
+#include <stringconstants.hxx>
+
+namespace dbaui
+{
+ // TextConnectionSettingsDialog
+ TextConnectionSettingsDialog::TextConnectionSettingsDialog(weld::Window* pParent, SfxItemSet& rItems)
+ : GenericDialogController(pParent, "dbaccess/ui/textconnectionsettings.ui", "TextConnectionSettingsDialog")
+ , m_rItems(rItems)
+ , m_xContainer(m_xBuilder->weld_widget("TextPageContainer"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+ , m_xTextConnectionHelper(new OTextConnectionHelper(m_xContainer.get(), TC_HEADER | TC_SEPARATORS | TC_CHARSET))
+ {
+ m_xOK->connect_clicked(LINK(this, TextConnectionSettingsDialog, OnOK));
+ }
+
+ TextConnectionSettingsDialog::~TextConnectionSettingsDialog()
+ {
+ }
+
+ void TextConnectionSettingsDialog::bindItemStorages( SfxItemSet& _rSet, PropertyValues& _rValues )
+ {
+ _rValues[ PROPERTY_ID_HEADER_LINE ] = std::make_shared<SetItemPropertyStorage>( _rSet, DSID_TEXTFILEHEADER );
+ _rValues[ PROPERTY_ID_FIELD_DELIMITER ] = std::make_shared<SetItemPropertyStorage>( _rSet, DSID_FIELDDELIMITER );
+ _rValues[ PROPERTY_ID_STRING_DELIMITER ] = std::make_shared<SetItemPropertyStorage>( _rSet, DSID_TEXTDELIMITER );
+ _rValues[ PROPERTY_ID_DECIMAL_DELIMITER ] = std::make_shared<SetItemPropertyStorage>( _rSet, DSID_DECIMALDELIMITER );
+ _rValues[ PROPERTY_ID_THOUSAND_DELIMITER ] = std::make_shared<SetItemPropertyStorage>( _rSet, DSID_THOUSANDSDELIMITER );
+ _rValues[ PROPERTY_ID_ENCODING ] = std::make_shared<SetItemPropertyStorage>( _rSet, DSID_CHARSET );
+ }
+
+ short TextConnectionSettingsDialog::run()
+ {
+ m_xTextConnectionHelper->implInitControls(m_rItems, true);
+ return GenericDialogController::run();
+ }
+
+ IMPL_LINK_NOARG(TextConnectionSettingsDialog, OnOK, weld::Button&, void)
+ {
+ if (m_xTextConnectionHelper->prepareLeave())
+ {
+ m_xTextConnectionHelper->FillItemSet( m_rItems, false/*bUnused*/ );
+ m_xDialog->response(RET_OK);
+ }
+ }
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */