summaryrefslogtreecommitdiffstats
path: root/extensions/source/abpilot
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /extensions/source/abpilot
parentInitial commit. (diff)
downloadlibreoffice-cb75148ebd0135178ff46f89a30139c44f8d2040.tar.xz
libreoffice-cb75148ebd0135178ff46f89a30139c44f8d2040.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--extensions/source/abpilot/abp.component26
-rw-r--r--extensions/source/abpilot/abpfinalpage.cxx227
-rw-r--r--extensions/source/abpilot/abpfinalpage.hxx74
-rw-r--r--extensions/source/abpilot/abptypes.hxx40
-rw-r--r--extensions/source/abpilot/abspage.cxx74
-rw-r--r--extensions/source/abpilot/abspage.hxx56
-rw-r--r--extensions/source/abpilot/abspilot.cxx449
-rw-r--r--extensions/source/abpilot/abspilot.hxx119
-rw-r--r--extensions/source/abpilot/addresssettings.hxx56
-rw-r--r--extensions/source/abpilot/admininvokationimpl.cxx116
-rw-r--r--extensions/source/abpilot/admininvokationimpl.hxx50
-rw-r--r--extensions/source/abpilot/admininvokationpage.cxx90
-rw-r--r--extensions/source/abpilot/admininvokationpage.hxx52
-rw-r--r--extensions/source/abpilot/datasourcehandling.cxx620
-rw-r--r--extensions/source/abpilot/datasourcehandling.hxx181
-rw-r--r--extensions/source/abpilot/fieldmappingimpl.cxx317
-rw-r--r--extensions/source/abpilot/fieldmappingimpl.hxx111
-rw-r--r--extensions/source/abpilot/fieldmappingpage.cxx77
-rw-r--r--extensions/source/abpilot/fieldmappingpage.hxx46
-rw-r--r--extensions/source/abpilot/moduleabp.cxx22
-rw-r--r--extensions/source/abpilot/tableselectionpage.cxx101
-rw-r--r--extensions/source/abpilot/tableselectionpage.hxx50
-rw-r--r--extensions/source/abpilot/typeselectionpage.cxx224
-rw-r--r--extensions/source/abpilot/typeselectionpage.hxx81
-rw-r--r--extensions/source/abpilot/unodialogabp.cxx156
-rw-r--r--extensions/source/abpilot/unodialogabp.hxx78
26 files changed, 3493 insertions, 0 deletions
diff --git a/extensions/source/abpilot/abp.component b/extensions/source/abpilot/abp.component
new file mode 100644
index 000000000..91b9638c4
--- /dev/null
+++ b/extensions/source/abpilot/abp.component
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+
+<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="org.openoffice.comp.abp.OAddressBookSourcePilot"
+ constructor="org_openoffice_comp_abp_OAddressBookSourcePilot">
+ <service name="com.sun.star.ui.dialogs.AddressBookSourcePilot"/>
+ </implementation>
+</component>
diff --git a/extensions/source/abpilot/abpfinalpage.cxx b/extensions/source/abpilot/abpfinalpage.cxx
new file mode 100644
index 000000000..045a66d3f
--- /dev/null
+++ b/extensions/source/abpilot/abpfinalpage.cxx
@@ -0,0 +1,227 @@
+/* -*- 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 "abpfinalpage.hxx"
+#include "addresssettings.hxx"
+#include "abspilot.hxx"
+#include <osl/diagnose.h>
+#include <tools/urlobj.hxx>
+#include <svtools/inettbc.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/filenotation.hxx>
+#include <sfx2/docfilt.hxx>
+#include <o3tl/string_view.hxx>
+
+namespace abp
+{
+
+ using namespace ::svt;
+ using namespace ::utl;
+
+ static std::shared_ptr<const SfxFilter> lcl_getBaseFilter()
+ {
+ std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetFilterByName("StarOffice XML (Base)");
+ OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
+ return pFilter;
+ }
+
+ FinalPage::FinalPage(weld::Container* pPage, OAddressBookSourcePilot* pWizard)
+ : AddressBookSourcePage(pPage, pWizard, "modules/sabpilot/ui/datasourcepage.ui",
+ "DataSourcePage")
+ , m_xLocation(new SvtURLBox(m_xBuilder->weld_combo_box("location")))
+ , m_xBrowse(m_xBuilder->weld_button("browse"))
+ , m_xRegisterName(m_xBuilder->weld_check_button("available"))
+ , m_xEmbed(m_xBuilder->weld_check_button("embed"))
+ , m_xNameLabel(m_xBuilder->weld_label("nameft"))
+ , m_xLocationLabel(m_xBuilder->weld_label("locationft"))
+ , m_xName(m_xBuilder->weld_entry("name"))
+ , m_xDuplicateNameError(m_xBuilder->weld_label("warning"))
+ {
+ m_xLocation->SetSmartProtocol(INetProtocol::File);
+ m_xLocation->DisableHistory();
+
+ m_xLocationController.reset( new svx::DatabaseLocationInputController(pWizard->getORB(),
+ *m_xLocation, *m_xBrowse, *pWizard->getDialog()) );
+
+ m_xName->connect_changed( LINK(this, FinalPage, OnEntryNameModified) );
+ m_xLocation->connect_changed( LINK(this, FinalPage, OnComboNameModified) );
+ m_xRegisterName->connect_toggled( LINK( this, FinalPage, OnRegister ) );
+ m_xRegisterName->set_active(true);
+ m_xEmbed->connect_toggled( LINK( this, FinalPage, OnEmbed ) );
+ m_xEmbed->set_active(true);
+ }
+
+ FinalPage::~FinalPage()
+ {
+ m_xLocationController.reset();
+ }
+
+ bool FinalPage::isValidName() const
+ {
+ OUString sCurrentName(m_xName->get_text());
+
+ if (sCurrentName.isEmpty())
+ // the name must not be empty
+ return false;
+
+ if ( m_aInvalidDataSourceNames.find( sCurrentName ) != m_aInvalidDataSourceNames.end() )
+ // there already is a data source with this name
+ return false;
+
+ return true;
+ }
+
+ void FinalPage::setFields()
+ {
+ AddressSettings& rSettings = getSettings();
+
+ INetURLObject aURL( rSettings.sDataSourceName );
+ if( aURL.GetProtocol() == INetProtocol::NotValid )
+ {
+ OUString sPath = SvtPathOptions().GetWorkPath();
+ sPath += "/" + rSettings.sDataSourceName;
+
+ std::shared_ptr<const SfxFilter> pFilter = lcl_getBaseFilter();
+ if ( pFilter )
+ {
+ OUString sExt = pFilter->GetDefaultExtension();
+ sPath += o3tl::getToken(sExt,1,'*');
+ }
+
+ aURL.SetURL(sPath);
+ }
+ OSL_ENSURE( aURL.GetProtocol() != INetProtocol::NotValid ,"No valid file name!");
+ rSettings.sDataSourceName = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ m_xLocationController->setURL( rSettings.sDataSourceName );
+ OUString sName = aURL.getName( );
+ sal_Int32 nPos = sName.indexOf(aURL.GetFileExtension());
+ if ( nPos != -1 )
+ {
+ sName = sName.replaceAt(nPos-1, 4, u"");
+ }
+ m_xName->set_text(sName);
+
+ OnRegister(*m_xRegisterName);
+ }
+
+
+ void FinalPage::initializePage()
+ {
+ AddressBookSourcePage::initializePage();
+
+ setFields();
+ }
+
+ bool FinalPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!AddressBookSourcePage::commitPage(_eReason))
+ return false;
+
+ if ( ( ::vcl::WizardTypes::eTravelBackward != _eReason )
+ && ( !m_xLocationController->prepareCommit() )
+ )
+ return false;
+
+ AddressSettings& rSettings = getSettings();
+ rSettings.sDataSourceName = m_xLocationController->getURL();
+ rSettings.bRegisterDataSource = m_xRegisterName->get_active();
+ if ( rSettings.bRegisterDataSource )
+ rSettings.sRegisteredDataSourceName = m_xName->get_text();
+ rSettings.bEmbedDataSource = m_xEmbed->get_active();
+
+ return true;
+ }
+
+ void FinalPage::Activate()
+ {
+ AddressBookSourcePage::Activate();
+
+ // get the names of all data sources
+ ODataSourceContext aContext( getORB() );
+ aContext.getDataSourceNames( m_aInvalidDataSourceNames );
+
+ // give the name edit the focus
+ m_xLocation->grab_focus();
+
+ // default the finish button
+ getDialog()->defaultButton( WizardButtonFlags::FINISH );
+
+ OnEmbed(*m_xEmbed);
+ }
+
+ void FinalPage::Deactivate()
+ {
+ AddressBookSourcePage::Deactivate();
+
+ // default the "next" button, again
+ getDialog()->defaultButton( WizardButtonFlags::NEXT );
+ // disable the finish button
+ getDialog()->enableButtons( WizardButtonFlags::FINISH, false );
+ }
+
+
+ bool FinalPage::canAdvance() const
+ {
+ return false;
+ }
+
+ void FinalPage::implCheckName()
+ {
+ bool bValidName = isValidName();
+ bool bEmptyName = m_xName->get_text().isEmpty();
+ bool bEmptyLocation = m_xLocation->get_active_text().isEmpty();
+
+ // enable or disable the finish button
+ getDialog()->enableButtons( WizardButtonFlags::FINISH, !bEmptyLocation && (!m_xRegisterName->get_active() || bValidName) );
+
+ // show the error message for an invalid name
+ m_xDuplicateNameError->set_visible(!bValidName && !bEmptyName);
+ }
+
+ IMPL_LINK_NOARG( FinalPage, OnEntryNameModified, weld::Entry&, void )
+ {
+ implCheckName();
+ }
+
+ IMPL_LINK_NOARG( FinalPage, OnComboNameModified, weld::ComboBox&, void )
+ {
+ implCheckName();
+ }
+
+ IMPL_LINK_NOARG(FinalPage, OnRegister, weld::Toggleable&, void)
+ {
+ bool bEnable = m_xRegisterName->get_active();
+ m_xNameLabel->set_sensitive(bEnable);
+ m_xName->set_sensitive(bEnable);
+ implCheckName();
+ }
+
+ IMPL_LINK_NOARG(FinalPage, OnEmbed, weld::Toggleable&, void)
+ {
+ bool bEmbed = m_xEmbed->get_active();
+ m_xLocationLabel->set_sensitive(!bEmbed);
+ m_xLocation->set_sensitive(!bEmbed);
+ m_xBrowse->set_sensitive(!bEmbed);
+ }
+
+} // namespace abp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/abpfinalpage.hxx b/extensions/source/abpilot/abpfinalpage.hxx
new file mode 100644
index 000000000..6c6c5d69d
--- /dev/null
+++ b/extensions/source/abpilot/abpfinalpage.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 "abspage.hxx"
+#include "abptypes.hxx"
+
+#include <svx/databaselocationinput.hxx>
+#include <vcl/vclptr.hxx>
+
+namespace abp
+{
+
+ class FinalPage final : public AddressBookSourcePage
+ {
+ std::unique_ptr<SvtURLBox> m_xLocation;
+ std::unique_ptr<weld::Button> m_xBrowse;
+ std::unique_ptr<weld::CheckButton> m_xRegisterName;
+ std::unique_ptr<weld::CheckButton> m_xEmbed;
+ std::unique_ptr<weld::Label> m_xNameLabel;
+ std::unique_ptr<weld::Label> m_xLocationLabel;
+ std::unique_ptr<weld::Entry> m_xName;
+ std::unique_ptr<weld::Label> m_xDuplicateNameError;
+
+ std::unique_ptr<svx::DatabaseLocationInputController>
+ m_xLocationController;
+
+ StringBag m_aInvalidDataSourceNames;
+
+ public:
+ explicit FinalPage(weld::Container* pPage, OAddressBookSourcePilot* pController);
+ virtual ~FinalPage() override;
+
+ private:
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+
+ // BuilderPage overridables
+ virtual void Activate() override;
+ virtual void Deactivate() override;
+
+ // OImportPage overridables
+ virtual bool canAdvance() const override;
+
+ DECL_LINK(OnEntryNameModified, weld::Entry&, void);
+ DECL_LINK(OnComboNameModified, weld::ComboBox&, void);
+ DECL_LINK(OnRegister, weld::Toggleable&, void);
+ DECL_LINK(OnEmbed, weld::Toggleable&, void);
+
+ bool isValidName() const;
+ void implCheckName();
+ void setFields();
+ };
+
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/abptypes.hxx b/extensions/source/abpilot/abptypes.hxx
new file mode 100644
index 000000000..0339253ff
--- /dev/null
+++ b/extensions/source/abpilot/abptypes.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <map>
+#include <set>
+
+#include <rtl/ustring.hxx>
+
+
+namespace abp
+{
+
+
+ typedef std::set<OUString> StringBag;
+
+ typedef std::map<OUString, OUString> MapString2String;
+
+
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/abspage.cxx b/extensions/source/abpilot/abspage.cxx
new file mode 100644
index 000000000..ee36cee27
--- /dev/null
+++ b/extensions/source/abpilot/abspage.cxx
@@ -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 .
+ */
+
+#include "abspage.hxx"
+#include "abspilot.hxx"
+
+namespace abp
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+
+ AddressBookSourcePage::AddressBookSourcePage(weld::Container* pPage, OAddressBookSourcePilot* pDialog, const OUString& rUIXMLDescription, const OString& rID)
+ : AddressBookSourcePage_Base(pPage, pDialog, rUIXMLDescription, rID)
+ , m_pDialog(pDialog)
+ {
+ }
+
+ void AddressBookSourcePage::Activate()
+ {
+ AddressBookSourcePage_Base::Activate();
+ m_pDialog->updateTravelUI();
+ }
+
+ void AddressBookSourcePage::Deactivate()
+ {
+ AddressBookSourcePage_Base::Deactivate();
+ m_pDialog->enableButtons(WizardButtonFlags::NEXT, true);
+ }
+
+ OAddressBookSourcePilot* AddressBookSourcePage::getDialog()
+ {
+ return m_pDialog;
+ }
+
+ const OAddressBookSourcePilot* AddressBookSourcePage::getDialog() const
+ {
+ return m_pDialog;
+ }
+
+ AddressSettings& AddressBookSourcePage::getSettings()
+ {
+ return m_pDialog->getSettings();
+ }
+
+ const AddressSettings& AddressBookSourcePage::getSettings() const
+ {
+ return m_pDialog->getSettings();
+ }
+
+ const Reference< XComponentContext > & AddressBookSourcePage::getORB() const
+ {
+ return m_pDialog->getORB();
+ }
+
+} // namespace abp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/abspage.hxx b/extensions/source/abpilot/abspage.hxx
new file mode 100644
index 000000000..4d78533ad
--- /dev/null
+++ b/extensions/source/abpilot/abspage.hxx
@@ -0,0 +1,56 @@
+/* -*- 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/wizardmachine.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <strings.hrc>
+#include <componentmodule.hxx>
+
+namespace abp
+{
+ class OAddressBookSourcePilot;
+ struct AddressSettings;
+
+ typedef ::vcl::OWizardPage AddressBookSourcePage_Base;
+ /// the base class for all tab pages in the address book source wizard
+ class AddressBookSourcePage : public AddressBookSourcePage_Base
+ {
+ OAddressBookSourcePilot* m_pDialog;
+
+ protected:
+ AddressBookSourcePage(weld::Container* pPage, OAddressBookSourcePilot* pController, const OUString& rUIXMLDescription, const OString& rID);
+
+ protected:
+ // helper
+ OAddressBookSourcePilot* getDialog();
+ const OAddressBookSourcePilot* getDialog() const;
+ const css::uno::Reference< css::uno::XComponentContext > &
+ getORB() const;
+ AddressSettings& getSettings();
+ const AddressSettings& getSettings() const;
+
+ // BuilderPage overridables
+ virtual void Activate() override;
+ virtual void Deactivate() override;
+ };
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/abspilot.cxx b/extensions/source/abpilot/abspilot.cxx
new file mode 100644
index 000000000..0a5cba073
--- /dev/null
+++ b/extensions/source/abpilot/abspilot.cxx
@@ -0,0 +1,449 @@
+/* -*- 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 "abspilot.hxx"
+#include <helpids.h>
+#include <strings.hrc>
+#include <componentmodule.hxx>
+#include <tools/debug.hxx>
+#include "typeselectionpage.hxx"
+#include "admininvokationpage.hxx"
+#include "tableselectionpage.hxx"
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <osl/diagnose.h>
+#include "abpfinalpage.hxx"
+#include "fieldmappingpage.hxx"
+#include "fieldmappingimpl.hxx"
+
+using vcl::RoadmapWizardTypes::PathId;
+
+namespace abp
+{
+
+
+#define STATE_SELECT_ABTYPE 0
+#define STATE_INVOKE_ADMIN_DIALOG 1
+#define STATE_TABLE_SELECTION 2
+#define STATE_MANUAL_FIELD_MAPPING 3
+#define STATE_FINAL_CONFIRM 4
+
+#define PATH_COMPLETE 1
+#define PATH_NO_SETTINGS 2
+#define PATH_NO_FIELDS 3
+#define PATH_NO_SETTINGS_NO_FIELDS 4
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+
+ OAddressBookSourcePilot::OAddressBookSourcePilot(weld::Window* _pParent, const Reference< XComponentContext >& _rxORB)
+ :OAddressBookSourcePilot_Base( _pParent )
+ ,m_xORB(_rxORB)
+ ,m_aNewDataSource(_rxORB)
+ ,m_eNewDataSourceType( AST_INVALID )
+ {
+ declarePath( PATH_COMPLETE,
+ {STATE_SELECT_ABTYPE,
+ STATE_INVOKE_ADMIN_DIALOG,
+ STATE_TABLE_SELECTION,
+ STATE_MANUAL_FIELD_MAPPING,
+ STATE_FINAL_CONFIRM}
+ );
+ declarePath( PATH_NO_SETTINGS,
+ {STATE_SELECT_ABTYPE,
+ STATE_TABLE_SELECTION,
+ STATE_MANUAL_FIELD_MAPPING,
+ STATE_FINAL_CONFIRM}
+ );
+ declarePath( PATH_NO_FIELDS,
+ {STATE_SELECT_ABTYPE,
+ STATE_INVOKE_ADMIN_DIALOG,
+ STATE_TABLE_SELECTION,
+ STATE_FINAL_CONFIRM}
+ );
+ declarePath( PATH_NO_SETTINGS_NO_FIELDS,
+ {STATE_SELECT_ABTYPE,
+ STATE_TABLE_SELECTION,
+ STATE_FINAL_CONFIRM}
+ );
+
+ m_xPrevPage->set_help_id(HID_ABSPILOT_PREVIOUS);
+ m_xNextPage->set_help_id(HID_ABSPILOT_NEXT);
+ m_xCancel->set_help_id(HID_ABSPILOT_CANCEL);
+ m_xFinish->set_help_id(HID_ABSPILOT_FINISH);
+ m_xHelp->set_help_id(UID_ABSPILOT_HELP);
+
+ // some initial settings
+#ifdef UNX
+#ifdef MACOSX
+ m_aSettings.eType = AST_MACAB;
+#else
+// FIXME: if KDE use KAB instead
+ m_aSettings.eType = AST_EVOLUTION;
+#endif
+#else
+ m_aSettings.eType = AST_OTHER;
+#endif
+ m_aSettings.sDataSourceName = compmodule::ModuleRes(RID_STR_DEFAULT_NAME);
+ m_aSettings.bRegisterDataSource = false;
+ m_aSettings.bEmbedDataSource = false;
+ m_aSettings.bIgnoreNoTable = false;
+
+ defaultButton(WizardButtonFlags::NEXT);
+ enableButtons(WizardButtonFlags::FINISH, false);
+ ActivatePage();
+ m_xAssistant->set_current_page(0);
+
+ typeSelectionChanged( m_aSettings.eType );
+
+ OUString sDialogTitle = compmodule::ModuleRes(RID_STR_ABSOURCEDIALOGTITLE);
+ setTitleBase(sDialogTitle);
+ m_xAssistant->set_help_id(HID_ABSPILOT);
+ }
+
+ OUString OAddressBookSourcePilot::getStateDisplayName( WizardState _nState ) const
+ {
+ TranslateId pResId;
+ switch ( _nState )
+ {
+ case STATE_SELECT_ABTYPE: pResId = RID_STR_SELECT_ABTYPE; break;
+ case STATE_INVOKE_ADMIN_DIALOG: pResId = RID_STR_INVOKE_ADMIN_DIALOG; break;
+ case STATE_TABLE_SELECTION: pResId = RID_STR_TABLE_SELECTION; break;
+ case STATE_MANUAL_FIELD_MAPPING: pResId = RID_STR_MANUAL_FIELD_MAPPING; break;
+ case STATE_FINAL_CONFIRM: pResId = RID_STR_FINAL_CONFIRM; break;
+ }
+ DBG_ASSERT( pResId, "OAddressBookSourcePilot::getStateDisplayName: don't know this state!" );
+
+ OUString sDisplayName;
+ if (pResId)
+ {
+ sDisplayName = compmodule::ModuleRes(pResId);
+ }
+
+ return sDisplayName;
+ }
+
+ void OAddressBookSourcePilot::implCommitAll()
+ {
+ // in real, the data source already exists in the data source context
+ // Thus, if the user changed the name, we have to rename the data source
+ if ( m_aSettings.sDataSourceName != m_aNewDataSource.getName() )
+ m_aNewDataSource.rename( m_aSettings.sDataSourceName );
+
+ // 1. the data source
+ m_aNewDataSource.store(m_aSettings);
+
+ // 2. check if we need to register the data source
+ if ( m_aSettings.bRegisterDataSource )
+ m_aNewDataSource.registerDataSource(m_aSettings.sRegisteredDataSourceName);
+
+ // 3. write the data source / table names into the configuration
+ addressconfig::writeTemplateAddressSource( getORB(), m_aSettings.bRegisterDataSource ? m_aSettings.sRegisteredDataSourceName : m_aSettings.sDataSourceName, m_aSettings.sSelectedTable );
+
+ // 4. write the field mapping
+ fieldmapping::writeTemplateAddressFieldMapping( getORB(), std::map(m_aSettings.aFieldMapping) );
+ }
+
+ void OAddressBookSourcePilot::implCleanup()
+ {
+ if ( m_aNewDataSource.isValid() )
+ m_aNewDataSource.remove();
+ }
+
+ short OAddressBookSourcePilot::run()
+ {
+ short nRet = OAddressBookSourcePilot_Base::run();
+
+ implCleanup();
+
+ return nRet;
+ }
+
+ bool OAddressBookSourcePilot::onFinish()
+ {
+ if ( !OAddressBookSourcePilot_Base::onFinish() )
+ return false;
+
+ implCommitAll();
+
+ addressconfig::markPilotSuccess( getORB() );
+
+ return true;
+ }
+
+ void OAddressBookSourcePilot::enterState( WizardState _nState )
+ {
+ switch ( _nState )
+ {
+ case STATE_SELECT_ABTYPE:
+ impl_updateRoadmap( static_cast< TypeSelectionPage* >( GetPage( STATE_SELECT_ABTYPE ) )->getSelectedType() );
+ break;
+
+ case STATE_FINAL_CONFIRM:
+ if ( !needManualFieldMapping( ) )
+ implDoAutoFieldMapping();
+ break;
+
+ case STATE_TABLE_SELECTION:
+ implDefaultTableName();
+ break;
+ }
+
+ OAddressBookSourcePilot_Base::enterState(_nState);
+ }
+
+
+ bool OAddressBookSourcePilot::prepareLeaveCurrentState( CommitPageReason _eReason )
+ {
+ if ( !OAddressBookSourcePilot_Base::prepareLeaveCurrentState( _eReason ) )
+ return false;
+
+ if ( _eReason == vcl::WizardTypes::eTravelBackward )
+ return true;
+
+ bool bAllow = true;
+
+ switch ( getCurrentState() )
+ {
+ case STATE_SELECT_ABTYPE:
+ implCreateDataSource();
+ if ( needAdminInvokationPage() )
+ break;
+ [[fallthrough]];
+
+ case STATE_INVOKE_ADMIN_DIALOG:
+ if ( !connectToDataSource( false ) )
+ {
+ // connecting did not succeed -> do not allow proceeding
+ bAllow = false;
+ break;
+ }
+
+
+ // now that we connected to the data source, check whether we need the "table selection" page
+ const StringBag& aTables = m_aNewDataSource.getTableNames();
+
+ if ( aTables.empty() )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xAssistant.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ compmodule::ModuleRes(getSettings().eType == AST_EVOLUTION_GROUPWISE ? RID_STR_QRY_NO_EVO_GW : RID_STR_QRY_NOTABLES)));
+
+ if (RET_YES != xBox->run())
+ {
+ // cannot ask the user, or the user chose to use this data source, though there are no tables
+ bAllow = false;
+ break;
+ }
+
+ m_aSettings.bIgnoreNoTable = true;
+ }
+
+ if ( aTables.size() == 1 )
+ // remember the one and only table we have
+ m_aSettings.sSelectedTable = *aTables.begin();
+
+ break;
+ }
+
+ impl_updateRoadmap( m_aSettings.eType );
+ return bAllow;
+ }
+
+ void OAddressBookSourcePilot::implDefaultTableName()
+ {
+ const StringBag& rTableNames = getDataSource().getTableNames();
+ if ( rTableNames.end() != rTableNames.find( getSettings().sSelectedTable ) )
+ // already a valid table selected
+ return;
+
+ const char* pGuess = nullptr;
+ switch ( getSettings().eType )
+ {
+ case AST_THUNDERBIRD : pGuess = "Personal Address book"; break;
+ case AST_EVOLUTION :
+ case AST_EVOLUTION_GROUPWISE:
+ case AST_EVOLUTION_LDAP : pGuess = "Personal"; break;
+ default:
+ OSL_FAIL( "OAddressBookSourcePilot::implDefaultTableName: unhandled case!" );
+ return;
+ }
+ const OUString sGuess = OUString::createFromAscii( pGuess );
+ if ( rTableNames.end() != rTableNames.find( sGuess ) )
+ getSettings().sSelectedTable = sGuess;
+ }
+
+ void OAddressBookSourcePilot::implDoAutoFieldMapping()
+ {
+ DBG_ASSERT( !needManualFieldMapping( ), "OAddressBookSourcePilot::implDoAutoFieldMapping: invalid call!" );
+
+ fieldmapping::defaultMapping( getORB(), m_aSettings.aFieldMapping );
+ }
+
+ void OAddressBookSourcePilot::implCreateDataSource()
+ {
+ if (m_aNewDataSource.isValid())
+ { // we already have a data source object
+ if ( m_aSettings.eType == m_eNewDataSourceType )
+ // and it already has the correct type
+ return;
+
+ // it has a wrong type -> remove it
+ m_aNewDataSource.remove();
+ }
+
+ ODataSourceContext aContext( getORB() );
+ aContext.disambiguate( m_aSettings.sDataSourceName );
+
+ switch (m_aSettings.eType)
+ {
+ case AST_THUNDERBIRD:
+ m_aNewDataSource = aContext.createNewThunderbird( m_aSettings.sDataSourceName );
+ break;
+
+ case AST_EVOLUTION:
+ m_aNewDataSource = aContext.createNewEvolution( m_aSettings.sDataSourceName );
+ break;
+
+ case AST_EVOLUTION_GROUPWISE:
+ m_aNewDataSource = aContext.createNewEvolutionGroupwise( m_aSettings.sDataSourceName );
+ break;
+
+ case AST_EVOLUTION_LDAP:
+ m_aNewDataSource = aContext.createNewEvolutionLdap( m_aSettings.sDataSourceName );
+ break;
+
+ case AST_KAB:
+ m_aNewDataSource = aContext.createNewKab( m_aSettings.sDataSourceName );
+ break;
+
+ case AST_MACAB:
+ m_aNewDataSource = aContext.createNewMacab( m_aSettings.sDataSourceName );
+ break;
+
+ case AST_OTHER:
+ m_aNewDataSource = aContext.createNewOther( m_aSettings.sDataSourceName );
+ break;
+
+ case AST_INVALID:
+ OSL_FAIL( "OAddressBookSourcePilot::implCreateDataSource: illegal data source type!" );
+ break;
+ }
+ m_eNewDataSourceType = m_aSettings.eType;
+ }
+
+ bool OAddressBookSourcePilot::connectToDataSource( bool _bForceReConnect )
+ {
+ DBG_ASSERT( m_aNewDataSource.isValid(), "OAddressBookSourcePilot::implConnect: invalid current data source!" );
+
+ weld::WaitObject aWaitCursor(m_xAssistant.get());
+ if ( _bForceReConnect && m_aNewDataSource.isConnected( ) )
+ m_aNewDataSource.disconnect( );
+
+ return m_aNewDataSource.connect(m_xAssistant.get());
+ }
+
+ std::unique_ptr<BuilderPage> OAddressBookSourcePilot::createPage(WizardState _nState)
+ {
+ OString sIdent(OString::number(_nState));
+ weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
+
+ std::unique_ptr<vcl::OWizardPage> xRet;
+
+ switch (_nState)
+ {
+ case STATE_SELECT_ABTYPE:
+ xRet = std::make_unique<TypeSelectionPage>(pPageContainer, this);
+ break;
+ case STATE_INVOKE_ADMIN_DIALOG:
+ xRet = std::make_unique<AdminDialogInvokationPage>(pPageContainer, this);
+ break;
+ case STATE_TABLE_SELECTION:
+ xRet = std::make_unique<TableSelectionPage>(pPageContainer, this);
+ break;
+ case STATE_MANUAL_FIELD_MAPPING:
+ xRet = std::make_unique<FieldMappingPage>(pPageContainer, this);
+ break;
+ case STATE_FINAL_CONFIRM:
+ xRet = std::make_unique<FinalPage>(pPageContainer, this);
+ break;
+ default:
+ assert(false && "OAddressBookSourcePilot::createPage: invalid state!");
+ break;
+ }
+
+ m_xAssistant->set_page_title(sIdent, getStateDisplayName(_nState));
+
+ return xRet;
+ }
+
+ void OAddressBookSourcePilot::impl_updateRoadmap( AddressSourceType _eType )
+ {
+ bool bSettingsPage = needAdminInvokationPage( _eType );
+ bool bTablesPage = needTableSelection( _eType );
+ bool bFieldsPage = needManualFieldMapping( _eType );
+
+ bool bConnected = m_aNewDataSource.isConnected();
+ bool bCanSkipTables =
+ ( m_aNewDataSource.hasTable( m_aSettings.sSelectedTable )
+ || m_aSettings.bIgnoreNoTable
+ );
+
+ enableState( STATE_INVOKE_ADMIN_DIALOG, bSettingsPage );
+
+ enableState( STATE_TABLE_SELECTION,
+ bTablesPage && ( bConnected ? !bCanSkipTables : !bSettingsPage )
+ // if we do not need a settings page, we connect upon "Next" on the first page
+ );
+
+ enableState( STATE_MANUAL_FIELD_MAPPING,
+ bFieldsPage && bConnected && m_aNewDataSource.hasTable( m_aSettings.sSelectedTable )
+ );
+
+ enableState( STATE_FINAL_CONFIRM,
+ bConnected && bCanSkipTables
+ );
+ }
+
+ void OAddressBookSourcePilot::typeSelectionChanged( AddressSourceType _eType )
+ {
+ PathId nCurrentPathID( PATH_COMPLETE );
+ bool bSettingsPage = needAdminInvokationPage( _eType );
+ bool bFieldsPage = needManualFieldMapping( _eType );
+ if ( !bSettingsPage )
+ if ( !bFieldsPage )
+ nCurrentPathID = PATH_NO_SETTINGS_NO_FIELDS;
+ else
+ nCurrentPathID = PATH_NO_SETTINGS;
+ else
+ if ( !bFieldsPage )
+ nCurrentPathID = PATH_NO_FIELDS;
+ else
+ nCurrentPathID = PATH_COMPLETE;
+ activatePath( nCurrentPathID, true );
+
+ m_aNewDataSource.disconnect();
+ m_aSettings.bIgnoreNoTable = false;
+ impl_updateRoadmap( _eType );
+ }
+
+} // namespace abp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/abspilot.hxx b/extensions/source/abpilot/abspilot.hxx
new file mode 100644
index 000000000..45c965d2b
--- /dev/null
+++ b/extensions/source/abpilot/abspilot.hxx
@@ -0,0 +1,119 @@
+/* -*- 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/roadmapwizard.hxx>
+#include "addresssettings.hxx"
+#include "datasourcehandling.hxx"
+
+using vcl::WizardTypes::WizardState;
+using vcl::WizardTypes::CommitPageReason;
+
+namespace abp
+{
+ typedef ::vcl::RoadmapWizardMachine OAddressBookSourcePilot_Base;
+ class OAddressBookSourcePilot final : public OAddressBookSourcePilot_Base
+ {
+ css::uno::Reference< css::uno::XComponentContext >
+ m_xORB;
+ AddressSettings m_aSettings;
+
+ ODataSource m_aNewDataSource;
+ AddressSourceType m_eNewDataSourceType;
+
+ public:
+ /// ctor
+ OAddressBookSourcePilot(
+ weld::Window* _pParent,
+ const css::uno::Reference< css::uno::XComponentContext >& _rxORB);
+
+ virtual short run() override;
+
+ /// get the service factory which was used to create the dialog
+ const css::uno::Reference< css::uno::XComponentContext >&
+ getORB() const { return m_xORB; }
+ AddressSettings& getSettings() { return m_aSettings; }
+ const AddressSettings& getSettings() const { return m_aSettings; }
+
+ const ODataSource& getDataSource() const { return m_aNewDataSource; }
+
+ bool connectToDataSource( bool _bForceReConnect );
+
+ void travelNext( ) { OAddressBookSourcePilot_Base::travelNext(); }
+
+ /// to be called when the selected type changed
+ void typeSelectionChanged( AddressSourceType _eType );
+
+ private:
+ // OWizardMachine overridables
+ virtual std::unique_ptr<BuilderPage> createPage( WizardState _nState ) override;
+ virtual void enterState( WizardState _nState ) override;
+ virtual bool prepareLeaveCurrentState( CommitPageReason _eReason ) override;
+ virtual bool onFinish() override;
+
+ // RoadmapWizard
+ virtual OUString getStateDisplayName( WizardState _nState ) const override;
+
+ /** creates a new data source of the type indicated by m_aSettings
+ <p>If another data source has been created before, this one is deleted.</p>
+ */
+ void implCreateDataSource();
+
+ /// does an automatic field mapping (possible for all types except AST_OTHER)
+ void implDoAutoFieldMapping();
+
+ /// guesses a default for the table name, if no valid table is selected
+ void implDefaultTableName();
+
+ static bool needAdminInvokationPage( AddressSourceType _eType )
+ {
+ return ( AST_OTHER == _eType );
+ }
+ /// check if with the current settings, we would need to invoke he administration dialog for more details about the data source
+ bool needAdminInvokationPage() const
+ {
+ return needAdminInvokationPage( m_aSettings.eType );
+ }
+
+ static bool needManualFieldMapping( AddressSourceType _eType )
+ {
+ return ( AST_OTHER == _eType ) || ( AST_KAB == _eType ) ||
+ ( AST_EVOLUTION == _eType ) || ( AST_EVOLUTION_GROUPWISE == _eType ) ||
+ ( AST_EVOLUTION_LDAP == _eType );
+ }
+ /// checks if we need a manual (user-guided) field mapping
+ bool needManualFieldMapping() const
+ {
+ return needManualFieldMapping( m_aSettings.eType );
+ }
+
+ /// determines whether the given address book type does provide one table only
+ static bool needTableSelection( AddressSourceType _eType )
+ {
+ return ( AST_KAB != _eType );
+ }
+
+ void implCleanup();
+ void implCommitAll();
+
+ void impl_updateRoadmap( AddressSourceType _eType );
+ };
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/addresssettings.hxx b/extensions/source/abpilot/addresssettings.hxx
new file mode 100644
index 000000000..542a2fe67
--- /dev/null
+++ b/extensions/source/abpilot/addresssettings.hxx
@@ -0,0 +1,56 @@
+/* -*- 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 "abptypes.hxx"
+
+
+namespace abp
+{
+
+ enum AddressSourceType
+ {
+ AST_THUNDERBIRD,
+ AST_EVOLUTION,
+ AST_EVOLUTION_GROUPWISE,
+ AST_EVOLUTION_LDAP,
+ AST_KAB,
+ AST_MACAB,
+ AST_OTHER,
+
+ AST_INVALID
+ };
+
+ struct AddressSettings
+ {
+ AddressSourceType eType;
+ OUString sDataSourceName;
+ OUString sRegisteredDataSourceName;
+ OUString sSelectedTable;
+ bool bIgnoreNoTable;
+ MapString2String aFieldMapping;
+ bool bRegisterDataSource;
+ bool bEmbedDataSource;
+ };
+
+
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/admininvokationimpl.cxx b/extensions/source/abpilot/admininvokationimpl.cxx
new file mode 100644
index 000000000..c8ec00b68
--- /dev/null
+++ b/extensions/source/abpilot/admininvokationimpl.cxx
@@ -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 .
+ */
+
+#include "admininvokationimpl.hxx"
+#include <tools/diagnose_ex.h>
+#include <tools/debug.hxx>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/sdbc/DriverManager.hpp>
+#include <comphelper/propertysequence.hxx>
+#include <strings.hrc>
+#include <componentmodule.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/weld.hxx>
+
+namespace abp
+{
+
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::ui::dialogs;
+ using namespace ::com::sun::star::sdbc;
+
+ OAdminDialogInvokation::OAdminDialogInvokation(const Reference< XComponentContext >& _rxContext,
+ const css::uno::Reference< css::beans::XPropertySet >& _rxDataSource,
+ weld::Window* _pMessageParent)
+ :m_xContext(_rxContext)
+ ,m_xDataSource(_rxDataSource)
+ ,m_pMessageParent(_pMessageParent)
+ {
+ DBG_ASSERT(m_xContext.is(), "OAdminDialogInvokation::OAdminDialogInvokation: invalid service factory!");
+ DBG_ASSERT(m_xDataSource.is(), "OAdminDialogInvokation::OAdminDialogInvokation: invalid preferred name!");
+ assert(m_pMessageParent && "OAdminDialogInvokation::OAdminDialogInvokation: invalid message parent!");
+ }
+
+
+ bool OAdminDialogInvokation::invokeAdministration()
+ {
+ if (!m_xContext.is())
+ return false;
+
+ try
+ {
+ // the service name of the administration dialog
+ static const char16_t s_sAdministrationServiceName[] = u"com.sun.star.sdb.DatasourceAdministrationDialog";
+ static constexpr OUStringLiteral s_sDataSourceTypeChangeDialog = u"com.sun.star.sdb.DataSourceTypeChangeDialog";
+
+ // the parameters for the call
+ Sequence<Any> aArguments(comphelper::InitAnyPropertySequence(
+ {
+ {"ParentWindow", Any(m_pMessageParent->GetXWindow())},
+ {"Title", Any(compmodule::ModuleRes(RID_STR_ADMINDIALOGTITLE))},
+ {"InitialSelection", Any(m_xDataSource)}, // the name of the new data source
+ }));
+
+
+ // create the dialog
+ Reference< XExecutableDialog > xDialog;
+ {
+ // creating the dialog service is potentially expensive (if all the libraries invoked need to be loaded)
+ // so we display a wait cursor
+ weld::WaitObject aWaitCursor(m_pMessageParent);
+ Reference<XInterface> x = m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(s_sDataSourceTypeChangeDialog, aArguments, m_xContext);
+ xDialog.set( x, UNO_QUERY );
+
+ // just for a smoother UI: What the dialog does upon execution, is (amongst other things) creating
+ // the DriverManager service
+ // If this context has never been accessed before, this may be expensive (it includes loading of
+ // at least one library).
+ // As this wizard is intended to run on the first office start, it is very likely that the
+ // context needs to be freshly created
+ // Thus, we access the context here (within the WaitCursor), which means the user sees a waitcursor
+ // while his/her office blocks a few seconds...
+ DriverManager::create( m_xContext );
+ }
+
+ if (xDialog.is())
+ { // execute it
+ if (xDialog->execute())
+ return true;
+ }
+ else
+ ShowServiceNotAvailableError(m_pMessageParent, s_sAdministrationServiceName, true);
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.abpilot",
+ "caught an exception while executing the dialog!");
+ }
+ return false;
+ }
+
+
+} // namespace abp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/admininvokationimpl.hxx b/extensions/source/abpilot/admininvokationimpl.hxx
new file mode 100644
index 000000000..2003809c8
--- /dev/null
+++ b/extensions/source/abpilot/admininvokationimpl.hxx
@@ -0,0 +1,50 @@
+/* -*- 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 <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+namespace weld { class Window; }
+
+namespace abp
+{
+ /** outsourced from AdminDialogInvokationPage, 'cause this class here, in opposite to
+ the page, needs exception handling to be enabled.
+ */
+ class OAdminDialogInvokation
+ {
+ private:
+ css::uno::Reference< css::uno::XComponentContext >
+ m_xContext;
+ css::uno::Reference< css::beans::XPropertySet > m_xDataSource;
+ weld::Window* m_pMessageParent;
+
+ public:
+ OAdminDialogInvokation(
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
+ const css::uno::Reference< css::beans::XPropertySet >& _rDataSource,
+ weld::Window* _pMessageParent
+ );
+
+ bool invokeAdministration();
+ };
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/admininvokationpage.cxx b/extensions/source/abpilot/admininvokationpage.cxx
new file mode 100644
index 000000000..2f51d8639
--- /dev/null
+++ b/extensions/source/abpilot/admininvokationpage.cxx
@@ -0,0 +1,90 @@
+/* -*- 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 "admininvokationpage.hxx"
+#include "abspilot.hxx"
+#include "admininvokationimpl.hxx"
+
+namespace abp
+{
+ AdminDialogInvokationPage::AdminDialogInvokationPage(weld::Container* pPage, OAddressBookSourcePilot* pController)
+ : AddressBookSourcePage(pPage, pController, "modules/sabpilot/ui/invokeadminpage.ui", "InvokeAdminPage")
+ , m_xInvokeAdminDialog(m_xBuilder->weld_button("settings"))
+ , m_xErrorMessage(m_xBuilder->weld_label("warning"))
+ {
+ m_xInvokeAdminDialog->connect_clicked(LINK(this, AdminDialogInvokationPage, OnInvokeAdminDialog));
+ }
+
+ AdminDialogInvokationPage::~AdminDialogInvokationPage()
+ {
+ }
+
+ void AdminDialogInvokationPage::Activate()
+ {
+ AddressBookSourcePage::Activate();
+ m_xInvokeAdminDialog->grab_focus();
+ }
+
+ void AdminDialogInvokationPage::implUpdateErrorMessage()
+ {
+ const bool bIsConnected = getDialog()->getDataSource().isConnected();
+ m_xErrorMessage->set_visible( !bIsConnected );
+ }
+
+ void AdminDialogInvokationPage::initializePage()
+ {
+ AddressBookSourcePage::initializePage();
+ m_xErrorMessage->hide();
+ // if we're entering this page, we assume we had no connection trial with this data source
+ }
+
+ void AdminDialogInvokationPage::implTryConnect()
+ {
+ getDialog()->connectToDataSource( true );
+
+ // show our error message if and only if we could not connect
+ implUpdateErrorMessage();
+
+ // the status of the next button may have changed
+ updateDialogTravelUI();
+
+ // automatically go to the next page (if successfully connected)
+ if ( canAdvance() )
+ getDialog()->travelNext();
+ }
+
+ bool AdminDialogInvokationPage::canAdvance() const
+ {
+ return AddressBookSourcePage::canAdvance() && getDialog()->getDataSource().isConnected();
+ }
+
+ // davido: Do we need it?
+ IMPL_LINK_NOARG(AdminDialogInvokationPage, OnInvokeAdminDialog, weld::Button&, void)
+ {
+ OAdminDialogInvokation aInvokation(getORB(), getDialog()->getDataSource().getDataSource(), getDialog()->getDialog());
+ if ( aInvokation.invokeAdministration() )
+ {
+ // try to connect to this data source
+ implTryConnect();
+ }
+ }
+
+} // namespace abp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/admininvokationpage.hxx b/extensions/source/abpilot/admininvokationpage.hxx
new file mode 100644
index 000000000..3d4f676e2
--- /dev/null
+++ b/extensions/source/abpilot/admininvokationpage.hxx
@@ -0,0 +1,52 @@
+/* -*- 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 "abspage.hxx"
+
+
+namespace abp
+{
+ class AdminDialogInvokationPage final : public AddressBookSourcePage
+ {
+ std::unique_ptr<weld::Button> m_xInvokeAdminDialog;
+ std::unique_ptr<weld::Label> m_xErrorMessage;
+
+ public:
+ explicit AdminDialogInvokationPage(weld::Container* pPage, OAddressBookSourcePilot* pDialog);
+ virtual ~AdminDialogInvokationPage() override;
+ private:
+ // BuilderPage overridables
+ virtual void Activate() override;
+
+ // OWizard overridables
+ virtual void initializePage() override;
+
+ // OImportPage overridables
+ virtual bool canAdvance() const override;
+
+ DECL_LINK( OnInvokeAdminDialog, weld::Button&, void );
+
+ void implTryConnect();
+ void implUpdateErrorMessage();
+ };
+
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/datasourcehandling.cxx b/extensions/source/abpilot/datasourcehandling.cxx
new file mode 100644
index 000000000..a411c2536
--- /dev/null
+++ b/extensions/source/abpilot/datasourcehandling.cxx
@@ -0,0 +1,620 @@
+/* -*- 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 "abptypes.hxx"
+#include <componentmodule.hxx>
+#include "datasourcehandling.hxx"
+#include "addresssettings.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+#include <com/sun/star/sdb/XDatabaseRegistrations.hpp>
+#include <com/sun/star/sdb/XDocumentDataSource.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/uri/UriReferenceFactory.hpp>
+#include <com/sun/star/uri/VndSunStarPkgUrlReferenceFactory.hpp>
+
+#include <comphelper/interaction.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/sharedunocomponent.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <comphelper/propertysequence.hxx>
+
+namespace
+{
+
+/// Returns the URL of this object shell.
+OUString lcl_getOwnURL(SfxObjectShell const * pObjectShell)
+{
+ OUString aRet;
+
+ if (!pObjectShell)
+ return aRet;
+
+ const INetURLObject& rURLObject = pObjectShell->GetMedium()->GetURLObject();
+ aRet = rURLObject.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+ return aRet;
+}
+
+}
+
+namespace abp
+{
+
+
+ using namespace ::utl;
+ using namespace ::comphelper;
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::task;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::frame;
+
+ static Reference< XDatabaseContext > lcl_getDataSourceContext( const Reference< XComponentContext >& _rxContext )
+ {
+ Reference<XDatabaseContext> xContext = DatabaseContext::create(_rxContext);
+ return xContext;
+ }
+
+
+ /// creates a new data source and inserts it into the context
+ static void lcl_implCreateAndInsert(
+ const Reference< XComponentContext >& _rxContext, const OUString& _rName,
+ Reference< XPropertySet >& /* [out] */ _rxNewDataSource )
+ {
+
+ // get the data source context
+ Reference< XDatabaseContext > xContext = lcl_getDataSourceContext( _rxContext );
+
+ DBG_ASSERT( !xContext->hasByName( _rName ), "lcl_implCreateAndInsert: name already used!" );
+
+
+ // create a new data source
+ Reference< XPropertySet > xNewDataSource;
+ if (xContext.is())
+ xNewDataSource.set( xContext->createInstance(), UNO_QUERY );
+ DBG_ASSERT( xNewDataSource.is(), "lcl_implCreateAndInsert: could not create a new data source!" );
+
+
+ // insert the data source into the context
+ DBG_ASSERT( xContext.is(), "lcl_implCreateAndInsert: missing an interface on the context (XNamingService)!" );
+ if (xContext.is())
+ {
+ // xDynamicContext->registerObject( _rName, xNewDataSource );
+ _rxNewDataSource = xNewDataSource;
+ }
+ }
+
+
+ /// creates and inserts a data source, and sets its URL property to the string given
+ static ODataSource lcl_implCreateAndSetURL(
+ const Reference< XComponentContext >& _rxORB, const OUString& _rName,
+ const char* _pInitialAsciiURL )
+ {
+ ODataSource aReturn( _rxORB );
+ try
+ {
+ // create the new data source
+ Reference< XPropertySet > xNewDataSource;
+ lcl_implCreateAndInsert( _rxORB, _rName, xNewDataSource );
+
+
+ // set the URL property
+ if (xNewDataSource.is())
+ {
+ xNewDataSource->setPropertyValue(
+ "URL",
+ Any( OUString::createFromAscii( _pInitialAsciiURL ) )
+ );
+ }
+
+ aReturn.setDataSource( xNewDataSource, _rName );
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.abpilot",
+ "caught an exception while creating the data source!");
+ }
+
+ return aReturn;
+ }
+
+ static void lcl_registerDataSource(
+ const Reference< XComponentContext >& _rxORB, const OUString& _sName,
+ const OUString& _sURL )
+ {
+ OSL_ENSURE( !_sName.isEmpty(), "lcl_registerDataSource: invalid name!" );
+ OSL_ENSURE( !_sURL.isEmpty(), "lcl_registerDataSource: invalid URL!" );
+ try
+ {
+ Reference< XDatabaseContext > xRegistrations( DatabaseContext::create(_rxORB) );
+ if ( xRegistrations->hasRegisteredDatabase( _sName ) )
+ xRegistrations->changeDatabaseLocation( _sName, _sURL );
+ else
+ xRegistrations->registerDatabaseLocation( _sName, _sURL );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("extensions.abpilot");
+ }
+ }
+
+ struct ODataSourceContextImpl
+ {
+ Reference< XComponentContext > xORB;
+ Reference< XNameAccess > xContext; /// the UNO data source context
+ StringBag aDataSourceNames; /// for quicker name checks (without the UNO overhead)
+
+ explicit ODataSourceContextImpl(const Reference< XComponentContext >& _rxORB)
+ : xORB(_rxORB)
+ {
+ }
+ ODataSourceContextImpl(const ODataSourceContextImpl&) = delete;
+ ODataSourceContextImpl& operator=(const ODataSourceContextImpl&) = delete;
+ };
+
+ ODataSourceContext::ODataSourceContext(const Reference< XComponentContext >& _rxORB)
+ :m_pImpl( new ODataSourceContextImpl( _rxORB ) )
+ {
+ try
+ {
+ // create the UNO context
+ m_pImpl->xContext.set( lcl_getDataSourceContext( _rxORB ), UNO_QUERY_THROW );
+
+ // collect the data source names
+ Sequence< OUString > aDSNames = m_pImpl->xContext->getElementNames();
+ const OUString* pDSNames = aDSNames.getConstArray();
+ const OUString* pDSNamesEnd = pDSNames + aDSNames.getLength();
+
+ for ( ;pDSNames != pDSNamesEnd; ++pDSNames )
+ m_pImpl->aDataSourceNames.insert( *pDSNames );
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "extensions.abpilot", "ODataSourceContext::ODataSourceContext" );
+ }
+ }
+ ODataSourceContext::~ODataSourceContext()
+ {
+ }
+
+
+ void ODataSourceContext::disambiguate(OUString& _rDataSourceName)
+ {
+ OUString sCheck( _rDataSourceName );
+ StringBag::const_iterator aPos = m_pImpl->aDataSourceNames.find( sCheck );
+
+ sal_Int32 nPostfix = 1;
+ while ( ( m_pImpl->aDataSourceNames.end() != aPos ) && ( nPostfix < 65535 ) )
+ { // there already is a data source with this name
+ sCheck = _rDataSourceName + OUString::number( nPostfix++ );
+
+ aPos = m_pImpl->aDataSourceNames.find( sCheck );
+ }
+
+ _rDataSourceName = sCheck;
+ }
+
+
+ void ODataSourceContext::getDataSourceNames( StringBag& _rNames ) const
+ {
+ _rNames = m_pImpl->aDataSourceNames;
+ }
+
+ ODataSource ODataSourceContext::createNewThunderbird( const OUString& _rName )
+ {
+ return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:thunderbird" );
+ }
+
+
+ ODataSource ODataSourceContext::createNewEvolutionLdap( const OUString& _rName)
+ {
+ return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:evolution:ldap" );
+ }
+
+ ODataSource ODataSourceContext::createNewEvolutionGroupwise( const OUString& _rName)
+ {
+ return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:evolution:groupwise" );
+ }
+
+ ODataSource ODataSourceContext::createNewEvolution( const OUString& _rName)
+ {
+ return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:evolution:local" );
+ }
+
+
+ ODataSource ODataSourceContext::createNewKab( const OUString& _rName)
+ {
+ return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:kab" );
+ }
+
+
+ ODataSource ODataSourceContext::createNewMacab( const OUString& _rName)
+ {
+ return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:macab" );
+ }
+
+
+ // tdf117101: Spreadsheet by default
+ ODataSource ODataSourceContext::createNewOther( const OUString& _rName)
+ {
+ return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:calc:" );
+ }
+
+ struct ODataSourceImpl
+ {
+ public:
+ Reference< XComponentContext > xORB; /// the service factory
+ Reference< XPropertySet > xDataSource; /// the UNO data source
+ ::utl::SharedUNOComponent< XConnection >
+ xConnection;
+ StringBag aTables; // the cached table names
+ OUString sName;
+
+ explicit ODataSourceImpl(const Reference< XComponentContext >& _rxORB)
+ : xORB(_rxORB)
+ {
+ }
+ };
+
+
+ ODataSource::ODataSource( const ODataSource& _rSource )
+ {
+ *this = _rSource;
+ }
+
+ ODataSource& ODataSource::operator=( const ODataSource& _rSource )
+ {
+ if( this != &_rSource )
+ {
+ m_pImpl.reset( new ODataSourceImpl( *_rSource.m_pImpl ) );
+ }
+ return *this;
+ }
+
+ ODataSource& ODataSource::operator=(ODataSource&& _rSource) noexcept
+ {
+ m_pImpl = std::move(_rSource.m_pImpl);
+ return *this;
+ }
+
+ ODataSource::ODataSource( const Reference< XComponentContext >& _rxORB )
+ :m_pImpl(new ODataSourceImpl(_rxORB))
+ {
+ }
+
+ ODataSource::~ODataSource( )
+ {
+ }
+
+ void ODataSource::store(const AddressSettings& rSettings)
+ {
+ if (!isValid())
+ // nothing to do
+ return;
+ try
+ {
+ Reference< XDocumentDataSource > xDocAccess( m_pImpl->xDataSource, UNO_QUERY );
+ Reference< XStorable > xStorable;
+ if ( xDocAccess.is() )
+ xStorable.set(xDocAccess->getDatabaseDocument(), css::uno::UNO_QUERY);
+ OSL_ENSURE( xStorable.is(),"DataSource is no XStorable!" );
+ if ( xStorable.is() )
+ {
+ SfxViewFrame* pFrame = SfxViewFrame::Current();
+ SfxObjectShell* pObjectShell = pFrame ? pFrame->GetObjectShell() : nullptr;
+ OUString aOwnURL = lcl_getOwnURL(pObjectShell); // empty if pObjectShell is nullptr
+ if (aOwnURL.isEmpty() || !rSettings.bEmbedDataSource)
+ {
+ // Cannot or should not embed.
+ xStorable->storeAsURL(m_pImpl->sName,Sequence<PropertyValue>());
+ }
+ else
+ {
+ // Embed.
+ OUString aStreamRelPath = "EmbeddedDatabase";
+ auto xContext(comphelper::getProcessComponentContext());
+ auto xUri = css::uri::UriReferenceFactory::create(xContext)->parse(aOwnURL);
+ assert(xUri.is());
+ xUri = css::uri::VndSunStarPkgUrlReferenceFactory::create(xContext)->createVndSunStarPkgUrlReference(xUri);
+ assert(xUri.is());
+ OUString const sTmpName = xUri->getUriReference() + "/" + aStreamRelPath;
+ assert(pObjectShell);
+ uno::Reference<embed::XStorage> xStorage = pObjectShell->GetStorage();
+ uno::Sequence<beans::PropertyValue> aSequence = comphelper::InitPropertySequence(
+ {
+ {"TargetStorage", uno::Any(xStorage)},
+ {"StreamRelPath", uno::Any(aStreamRelPath)},
+ {"BaseURI", uno::Any(aOwnURL)}
+ });
+ xStorable->storeAsURL(sTmpName, aSequence);
+ m_pImpl->sName = sTmpName;
+
+ // Refer to the sub-storage name in the document settings, so
+ // we can load it again next time the file is imported.
+ uno::Reference<lang::XMultiServiceFactory> xFactory(pObjectShell->GetModel(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPropertySet(xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
+ xPropertySet->setPropertyValue("EmbeddedDatabaseName", uno::Any(aStreamRelPath));
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.abpilot",
+ "caught an exception while creating the data source!");
+ }
+ }
+
+ void ODataSource::registerDataSource( const OUString& _sRegisteredDataSourceName)
+ {
+ if (!isValid())
+ // nothing to do
+ return;
+
+ try
+ {
+ // invalidate ourself
+ lcl_registerDataSource(m_pImpl->xORB,_sRegisteredDataSourceName,m_pImpl->sName);
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.abpilot",
+ "caught an exception while creating the data source!");
+ }
+ }
+
+
+ void ODataSource::setDataSource( const Reference< XPropertySet >& _rxDS,const OUString& _sName )
+ {
+ if (m_pImpl->xDataSource.get() == _rxDS.get())
+ // nothing to do
+ return;
+
+ if ( isConnected() )
+ disconnect();
+
+ m_pImpl->sName = _sName;
+ m_pImpl->xDataSource = _rxDS;
+ }
+
+
+ void ODataSource::remove()
+ {
+ if (!isValid())
+ // nothing to do
+ return;
+
+ try
+ {
+ // invalidate ourself
+ m_pImpl->xDataSource.clear();
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.abpilot",
+ "caught an exception while creating the data source!");
+ }
+ }
+
+
+ bool ODataSource::rename( const OUString& _rName )
+ {
+ if (!isValid())
+ // nothing to do
+ return false;
+
+ m_pImpl->sName = _rName;
+ return true;
+ }
+
+
+ OUString ODataSource::getName() const
+ {
+ if ( !isValid() )
+ return OUString();
+ return m_pImpl->sName;
+ }
+
+
+ bool ODataSource::hasTable( const OUString& _rTableName ) const
+ {
+ if ( !isConnected() )
+ return false;
+
+ const StringBag& aTables( getTableNames() );
+ return aTables.find( _rTableName ) != aTables.end();
+ }
+
+
+ const StringBag& ODataSource::getTableNames() const
+ {
+ m_pImpl->aTables.clear();
+ if ( !isConnected() )
+ {
+ OSL_FAIL( "ODataSource::getTableNames: not connected!" );
+ }
+ else
+ {
+ try
+ {
+ // get the tables container from the connection
+ Reference< XTablesSupplier > xSuppTables( m_pImpl->xConnection.getTyped(), UNO_QUERY );
+ Reference< XNameAccess > xTables;
+ if ( xSuppTables.is( ) )
+ xTables = xSuppTables->getTables();
+ DBG_ASSERT( xTables.is(), "ODataSource::getTableNames: could not retrieve the tables container!" );
+
+ // get the names
+ Sequence< OUString > aTableNames;
+ if ( xTables.is( ) )
+ aTableNames = xTables->getElementNames( );
+
+ // copy the names
+ const OUString* pTableNames = aTableNames.getConstArray();
+ const OUString* pTableNamesEnd = pTableNames + aTableNames.getLength();
+ for (;pTableNames < pTableNamesEnd; ++pTableNames)
+ m_pImpl->aTables.insert( *pTableNames );
+ }
+ catch(const Exception&)
+ {
+ }
+ }
+
+ // now the table cache is up-to-date
+ return m_pImpl->aTables;
+ }
+
+
+ bool ODataSource::connect(weld::Window* _pMessageParent)
+ {
+ if ( isConnected( ) )
+ // nothing to do
+ return true;
+
+
+ // create the interaction handler (needed for authentication and error handling)
+ Reference< XInteractionHandler > xInteractions;
+ try
+ {
+ xInteractions = InteractionHandler::createWithParent(m_pImpl->xORB, nullptr);
+ }
+ catch(const Exception&)
+ {
+ }
+
+
+ // failure to create the interaction handler is a serious issue ...
+ if (!xInteractions.is())
+ {
+ if ( _pMessageParent )
+ ShowServiceNotAvailableError( _pMessageParent, u"com.sun.star.task.InteractionHandler", true );
+ return false;
+ }
+
+
+ // open the connection
+ Any aError;
+ Reference< XConnection > xConnection;
+ try
+ {
+ Reference< XCompletedConnection > xComplConn( m_pImpl->xDataSource, UNO_QUERY );
+ DBG_ASSERT( xComplConn.is(), "ODataSource::connect: missing the XCompletedConnection interface on the data source!" );
+ if ( xComplConn.is() )
+ xConnection = xComplConn->connectWithCompletion( xInteractions );
+ }
+ catch( const SQLContext& e ) { aError <<= e; }
+ catch( const SQLWarning& e ) { aError <<= e; }
+ catch( const SQLException& e ) { aError <<= e; }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("extensions.abpilot", "");
+ }
+
+
+ // handle errors
+ if ( aError.hasValue() && _pMessageParent )
+ {
+ try
+ {
+ SQLException aException;
+ aError >>= aException;
+ if ( aException.Message.isEmpty() )
+ {
+ // prepend some context info
+ SQLContext aDetailedError;
+ aDetailedError.Message = compmodule::ModuleRes(RID_STR_NOCONNECTION);
+ aDetailedError.Details = compmodule::ModuleRes(RID_STR_PLEASECHECKSETTINGS);
+ aDetailedError.NextException = aError;
+ // handle (aka display) the new context info
+ xInteractions->handle( new OInteractionRequest( Any( aDetailedError ) ) );
+ }
+ else
+ {
+ // handle (aka display) the original error
+ xInteractions->handle( new OInteractionRequest( Any( aException ) ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("extensions.abpilot",
+ "caught an exception while trying to display the error!");
+ }
+ }
+
+ if ( !xConnection.is() )
+ return false;
+
+
+ // success
+ m_pImpl->xConnection.reset( xConnection );
+ m_pImpl->aTables.clear();
+
+ return true;
+ }
+
+
+ void ODataSource::disconnect( )
+ {
+ m_pImpl->xConnection.clear();
+ m_pImpl->aTables.clear();
+ }
+
+
+ bool ODataSource::isConnected( ) const
+ {
+ return m_pImpl->xConnection.is();
+ }
+
+
+ bool ODataSource::isValid() const
+ {
+ return m_pImpl && m_pImpl->xDataSource.is();
+ }
+
+ Reference< XPropertySet > ODataSource::getDataSource() const
+ {
+ return m_pImpl ? m_pImpl->xDataSource : Reference< XPropertySet >();
+ }
+
+
+} // namespace abp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/datasourcehandling.hxx b/extensions/source/abpilot/datasourcehandling.hxx
new file mode 100644
index 000000000..485c3c15b
--- /dev/null
+++ b/extensions/source/abpilot/datasourcehandling.hxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <memory>
+
+#include "abptypes.hxx"
+
+
+namespace com::sun::star {
+ namespace beans {
+ class XPropertySet;
+ }
+}
+
+namespace weld { class Window; }
+
+
+namespace abp
+{
+
+ struct ODataSourceContextImpl;
+ class ODataSource;
+ /// a non-UNO wrapper for the data source context
+ class ODataSourceContext
+ {
+ private:
+ std::unique_ptr<ODataSourceContextImpl> m_pImpl;
+
+ public:
+ explicit ODataSourceContext(
+ const css::uno::Reference< css::uno::XComponentContext >& _rxORB
+ );
+ ~ODataSourceContext();
+
+ /// retrieves the names of all data sources
+ void getDataSourceNames( StringBag& _rNames ) const;
+
+ /// disambiguates the given name by appending successive numbers
+ void disambiguate(OUString& _rDataSourceName);
+
+ /// creates a new Thunderbird data source
+ ODataSource createNewThunderbird( const OUString& _rName );
+
+ /// creates a new Evolution local data source
+ ODataSource createNewEvolution( const OUString& _rName );
+
+ /// creates a new Evolution LDAP data source
+ ODataSource createNewEvolutionLdap( const OUString& _rName );
+
+ /// creates a new Evolution GROUPWISE data source
+ ODataSource createNewEvolutionGroupwise( const OUString& _rName );
+
+ /// creates a new KDE address book data source
+ ODataSource createNewKab( const OUString& _rName );
+
+ /// creates a new macOS address book data source
+ ODataSource createNewMacab( const OUString& _rName );
+
+ /// creates a new Other data source; tdf117101: Spreadsheet by default
+ ODataSource createNewOther( const OUString& _rName );
+ };
+
+ struct ODataSourceImpl;
+ struct AddressSettings;
+ /** a non-UNO wrapper for a data source
+ <p>This class allows to access data sources without the need to compile the respective file with
+ exception handling enabled (hopefully :).</p>
+ <p>In addition to wrapping a UNO data source, an instance of this class can handle at most
+ one valid connection, as obtained from the data source.</p>
+ */
+ class ODataSource
+ {
+ private:
+ std::unique_ptr<ODataSourceImpl> m_pImpl;
+
+ public:
+
+ // - ctor/dtor/assignment
+
+ /// constructs an object which is initially invalid
+ explicit ODataSource(
+ const css::uno::Reference< css::uno::XComponentContext >& _rxORB
+ );
+
+ /// copy ctor
+ ODataSource( const ODataSource& _rSource );
+
+ /// dtor
+ ~ODataSource( );
+
+ /// copy assignment
+ ODataSource& operator=( const ODataSource& _rSource );
+
+ /// move assignment
+ ODataSource& operator=(ODataSource&& _rSource) noexcept;
+
+ /// checks whether or not the object represents a valid data source
+ bool isValid() const;
+
+
+ /// removes the data source represented by the object from the data source context
+ void remove();
+ // TODO: put this into the context class
+
+ /// returns the name of the data source
+ OUString
+ getName() const;
+
+ /// renames the data source
+ bool rename( const OUString& _rName );
+ // TODO: put this into the context class
+
+
+ // - connection handling
+
+ /** connects to the data source represented by this object
+ @param _pMessageParent
+ the window to use as parent for any error messages. If this is <NULL/>, no messages are displayed
+ at all.
+ @see isConnected
+ */
+ bool connect(weld::Window* _pMessageParent);
+
+ /// returns <TRUE/> if the object has a valid connection, obtained from its data source
+ bool isConnected( ) const;
+
+ /// disconnects from the data source (i.e. disposes the UNO connection hold internally)
+ void disconnect( );
+
+ /// stores the database file
+ void store(const AddressSettings& rSettings);
+
+ /// register the data source under the given name in the configuration
+ void registerDataSource( const OUString& _sRegisteredDataSourceName );
+
+
+ /** retrieves the tables names from the connection
+ <p>to be called when <method>isConnected</method> returns <TRUE/> only</p>
+ */
+ const StringBag& getTableNames() const;
+
+ /** determines whether a given table exists
+ */
+ bool hasTable( const OUString& _rTableName ) const;
+
+ /// return the intern data source object
+ css::uno::Reference< css::beans::XPropertySet > getDataSource() const;
+
+
+ /** set a new data source.
+ <p>Available to selected clients only</p>
+ */
+ void setDataSource(
+ const css::uno::Reference< css::beans::XPropertySet >& _rxDS
+ ,const OUString& _sName
+ );
+ };
+
+
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/fieldmappingimpl.cxx b/extensions/source/abpilot/fieldmappingimpl.cxx
new file mode 100644
index 000000000..145732bdf
--- /dev/null
+++ b/extensions/source/abpilot/fieldmappingimpl.cxx
@@ -0,0 +1,317 @@
+/* -*- 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 "fieldmappingimpl.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/AddressBookSourceDialog.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/weld.hxx>
+#include <com/sun/star/util/AliasProgrammaticPair.hpp>
+#include <strings.hrc>
+#include <componentmodule.hxx>
+#include <unotools/confignode.hxx>
+#include <sal/macros.h>
+#include <sal/log.hxx>
+
+
+namespace abp
+{
+
+
+ using namespace ::utl;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::ui;
+ using namespace ::com::sun::star::ui::dialogs;
+
+
+ const char16_t sDriverSettingsNodeName[] = u"/org.openoffice.Office.DataAccess/DriverSettings/com.sun.star.comp.sdbc.MozabDriver";
+ constexpr OUStringLiteral sAddressBookNodeName = u"/org.openoffice.Office.DataAccess/AddressBook";
+
+ namespace fieldmapping
+ {
+ bool invokeDialog( const Reference< XComponentContext >& _rxORB, class weld::Window* _pParent,
+ const Reference< XPropertySet >& _rxDataSource, AddressSettings& _rSettings )
+ {
+ _rSettings.aFieldMapping.clear();
+
+ DBG_ASSERT( _rxORB.is(), "fieldmapping::invokeDialog: invalid service factory!" );
+ DBG_ASSERT( _rxDataSource.is(), "fieldmapping::invokeDialog: invalid data source!" );
+ if ( !_rxORB.is() || !_rxDataSource.is() )
+ return false;
+
+ try
+ {
+
+ // create an instance of the dialog service
+ Reference< XWindow > xDialogParent = _pParent->GetXWindow();
+ OUString sTitle(compmodule::ModuleRes(RID_STR_FIELDDIALOGTITLE));
+ Reference< XExecutableDialog > xDialog = AddressBookSourceDialog::createWithDataSource(_rxORB,
+ // the parent window
+ xDialogParent,
+ _rxDataSource,
+ _rSettings.bRegisterDataSource ? _rSettings.sRegisteredDataSourceName : _rSettings.sDataSourceName,
+ // the table to use
+ _rSettings.sSelectedTable,
+ sTitle);
+
+ // execute the dialog
+ if ( xDialog->execute() )
+ {
+ // retrieve the field mapping as set by he user
+ Reference< XPropertySet > xDialogProps( xDialog, UNO_QUERY );
+
+ Sequence< AliasProgrammaticPair > aMapping;
+ bool bSuccess =
+ xDialogProps->getPropertyValue("FieldMapping") >>= aMapping;
+ DBG_ASSERT( bSuccess, "fieldmapping::invokeDialog: invalid property type for FieldMapping!" );
+
+ // and copy it into the map
+ const AliasProgrammaticPair* pMapping = aMapping.getConstArray();
+ const AliasProgrammaticPair* pMappingEnd = pMapping + aMapping.getLength();
+ for (;pMapping != pMappingEnd; ++pMapping)
+ _rSettings.aFieldMapping[ pMapping->ProgrammaticName ] = pMapping->Alias;
+
+ return true;
+ }
+
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.abpilot",
+ "caught an exception while executing the dialog!");
+ }
+ return false;
+ }
+
+
+ void defaultMapping( const Reference< XComponentContext >& _rxContext, MapString2String& _rFieldAssignment )
+ {
+ _rFieldAssignment.clear();
+
+ try
+ {
+ // what we have:
+ // a) For the address data source, we need a mapping from programmatic names (1) to real column names
+ // b) The SDBC driver has a fixed set of columns, which, when returned, are named according to
+ // some configuration entries. E.g., the driver displays the field which it knows contains
+ // the first name as "First Name" - the latter string is stored in the config.
+ // For this, the driver uses programmatic names, too, but they differ from the programmatic names the
+ // template documents have.
+ // So what we need first is a mapping from programmatic names (1) to programmatic names (2)
+ const char* pMappingProgrammatics[] =
+ {
+ "FirstName", "FirstName",
+ "LastName", "LastName",
+ "Street", "HomeAddress",
+ "Zip", "HomeZipCode",
+ "City", "HomeCity",
+ "State", "HomeState",
+ "Country", "HomeCountry",
+ "PhonePriv", "HomePhone",
+ "PhoneComp", "WorkPhone",
+ "PhoneCell", "CellularNumber",
+ "Pager", "PagerNumber",
+ "Fax", "FaxNumber",
+ "EMail", "PrimaryEmail",
+ "URL", "WebPage1",
+ "Note", "Notes",
+ "Altfield1", "Custom1",
+ "Altfield2", "Custom2",
+ "Altfield3", "Custom3",
+ "Altfield4", "Custom4",
+ "Title", "JobTitle",
+ "Company", "Company",
+ "Department", "Department"
+ };
+ // (this list is not complete: both lists of programmatic names are larger in real,
+ // but this list above is the intersection)
+
+
+ // access the configuration information which the driver uses for determining its column names
+ OUString sDriverAliasesNodeName(
+ OUString::Concat(sDriverSettingsNodeName)
+ + "/ColumnAliases");
+
+ // create a config node for this
+ OConfigurationTreeRoot aDriverFieldAliasing = OConfigurationTreeRoot::createWithComponentContext(
+ _rxContext, sDriverAliasesNodeName, -1, OConfigurationTreeRoot::CM_READONLY);
+
+ // loop through all programmatic pairs
+ DBG_ASSERT( 0 == SAL_N_ELEMENTS( pMappingProgrammatics ) % 2,
+ "fieldmapping::defaultMapping: invalid programmatic map!" );
+ // number of pairs
+ sal_Int32 const nIntersectedProgrammatics = SAL_N_ELEMENTS( pMappingProgrammatics ) / 2;
+
+ const char** pProgrammatic = pMappingProgrammatics;
+ OUString sAddressProgrammatic;
+ OUString sDriverProgrammatic;
+ OUString sDriverUI;
+ for ( sal_Int32 i=0;
+ i < nIntersectedProgrammatics;
+ ++i
+ )
+ {
+ sAddressProgrammatic = OUString::createFromAscii( *pProgrammatic++ );
+ sDriverProgrammatic = OUString::createFromAscii( *pProgrammatic++ );
+
+ if ( aDriverFieldAliasing.hasByName( sDriverProgrammatic ) )
+ {
+ aDriverFieldAliasing.getNodeValue( sDriverProgrammatic ) >>= sDriverUI;
+ if ( 0 == sDriverUI.getLength() )
+ {
+ OSL_FAIL( "fieldmapping::defaultMapping: invalid driver UI column name!");
+ }
+ else
+ _rFieldAssignment[ sAddressProgrammatic ] = sDriverUI;
+ }
+ else
+ {
+ OSL_FAIL( "fieldmapping::defaultMapping: invalid driver programmatic name!" );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("extensions.abpilot",
+ "code is assumed to throw no exceptions!");
+ // the config nodes we're using herein should not do this...
+ }
+ }
+
+
+ void writeTemplateAddressFieldMapping( const Reference< XComponentContext >& _rxContext, MapString2String&& aFieldAssignment )
+ {
+ // access the configuration information which the driver uses for determining its column names
+
+ // create a config node for this
+ OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithComponentContext(
+ _rxContext, sAddressBookNodeName);
+
+ OConfigurationNode aFields = aAddressBookSettings.openNode( OUString( "Fields" ) );
+
+ // loop through all existent fields
+ Sequence< OUString > aExistentFields = aFields.getNodeNames();
+ const OUString* pExistentFields = aExistentFields.getConstArray();
+ const OUString* pExistentFieldsEnd = pExistentFields + aExistentFields.getLength();
+
+ static const OUStringLiteral sProgrammaticNodeName( u"ProgrammaticFieldName" );
+ static const OUStringLiteral sAssignedNodeName( u"AssignedFieldName" );
+
+ for ( ; pExistentFields != pExistentFieldsEnd; ++pExistentFields )
+ {
+ SAL_WARN_IF(
+ ((aFields.openNode(*pExistentFields)
+ .getNodeValue(sProgrammaticNodeName).get<OUString>())
+ != *pExistentFields),
+ "extensions.abpilot",
+ "fieldmapping::writeTemplateAddressFieldMapping: inconsistent config data!");
+ // there should be a redundancy in the config data... if this asserts, there isn't anymore!
+
+ // do we have a new alias for the programmatic?
+ MapString2String::iterator aPos = aFieldAssignment.find( *pExistentFields );
+ if ( aFieldAssignment.end() != aPos )
+ { // yes
+ // -> set a new value
+ OConfigurationNode aExistentField = aFields.openNode( *pExistentFields );
+ aExistentField.setNodeValue( sAssignedNodeName, Any( aPos->second ) );
+ // and remove the mapping entry
+ aFieldAssignment.erase( *pExistentFields );
+ }
+ else
+ { // no
+ // -> remove it
+ aFields.removeNode( *pExistentFields );
+ }
+ }
+
+ // now everything remaining in aFieldAssignment marks a mapping entry which was not present
+ // in the config before
+ for (auto const& elem : aFieldAssignment)
+ {
+ DBG_ASSERT( !aFields.hasByName( elem.first ),
+ "fieldmapping::writeTemplateAddressFieldMapping: inconsistence!" );
+ // in case the config node for the fields already has the node named <aNewMapping->first>,
+ // the entry should have been removed from aNewMapping (in the above loop)
+ OConfigurationNode aNewField = aFields.createNode( elem.first );
+ aNewField.setNodeValue( sProgrammaticNodeName, Any( elem.first ) );
+ aNewField.setNodeValue( sAssignedNodeName, Any( elem.second ) );
+ }
+
+ // commit the changes done
+ aAddressBookSettings.commit();
+ }
+
+
+ } // namespace fieldmapping
+
+
+ namespace addressconfig
+ {
+
+
+ void writeTemplateAddressSource( const Reference< XComponentContext >& _rxContext,
+ const OUString& _rDataSourceName, const OUString& _rTableName )
+ {
+ // access the configuration information which the driver uses for determining its column names
+
+ // create a config node for this
+ OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithComponentContext(
+ _rxContext, sAddressBookNodeName);
+
+ aAddressBookSettings.setNodeValue( OUString( "DataSourceName" ), Any( _rDataSourceName ) );
+ aAddressBookSettings.setNodeValue( OUString( "Command" ), Any( _rTableName ) );
+ aAddressBookSettings.setNodeValue( OUString( "CommandType" ), Any( sal_Int16(CommandType::TABLE) ) );
+
+ // commit the changes done
+ aAddressBookSettings.commit();
+ }
+
+
+ void markPilotSuccess( const Reference< XComponentContext >& _rxContext )
+ {
+ // access the configuration information which the driver uses for determining its column names
+
+ // create a config node for this
+ OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithComponentContext(
+ _rxContext, sAddressBookNodeName);
+
+ // set the flag
+ aAddressBookSettings.setNodeValue( OUString( "AutoPilotCompleted" ), Any( true ) );
+
+ // commit the changes done
+ aAddressBookSettings.commit();
+ }
+
+
+ } // namespace addressconfig
+
+
+} // namespace abp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/fieldmappingimpl.hxx b/extensions/source/abpilot/fieldmappingimpl.hxx
new file mode 100644
index 000000000..e4a2dd1c9
--- /dev/null
+++ b/extensions/source/abpilot/fieldmappingimpl.hxx
@@ -0,0 +1,111 @@
+/* -*- 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 "abptypes.hxx"
+#include <com/sun/star/uno/Reference.hxx>
+#include "addresssettings.hxx"
+
+namespace com::sun::star {
+ namespace lang {
+ class XMultiServiceFactory;
+ }
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace beans {
+ class XPropertySet;
+ }
+}
+namespace weld { class Window; }
+
+namespace abp
+{
+
+
+ namespace fieldmapping
+ {
+
+
+ /** invokes the field mapping dialog
+ @param _rxORB
+ service factory to use for creating UNO services
+ @param _pParent
+ window to use as parent for the dialog and error messages
+ @param _rSettings
+ current settings. Upon return, the field mapping member of this
+ structure will be filled with the settings the user did in the
+ field mapping dialog.
+ */
+ bool invokeDialog(
+ const css::uno::Reference< css::uno::XComponentContext >& _rxORB,
+ class weld::Window* _pParent,
+ const css::uno::Reference< css::beans::XPropertySet >& _rxDataSource,
+ AddressSettings& _rSettings
+ );
+
+
+ /** creates a default field mapping for usage with the address book SDBC driver
+ <p>The column names as used by the SDBC driver for address books is stored in the configuration,
+ and this function creates a mapping which uses this configuration information.</p>
+ */
+ void defaultMapping(
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
+ MapString2String& /* [out] */ _rFieldAssignment
+ );
+
+
+ /** writes a field mapping for the template document address source
+ */
+ void writeTemplateAddressFieldMapping(
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
+ MapString2String&& _rFieldAssignment
+ );
+
+
+ } // namespace fieldmapping
+
+
+ namespace addressconfig
+ {
+
+
+ /** writes the data source / table name given into the configuration, to where the template documents
+ expect it.
+ */
+ void writeTemplateAddressSource(
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
+ const OUString& _rDataSourceName,
+ const OUString& _rTableName
+ );
+
+ /** writes the configuration entry which states the pilot has been completed successfully
+ */
+ void markPilotSuccess(
+ const css::uno::Reference< css::uno::XComponentContext >& _rxContext
+ );
+
+
+ } // namespace addressconfig
+
+
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/fieldmappingpage.cxx b/extensions/source/abpilot/fieldmappingpage.cxx
new file mode 100644
index 000000000..1652723fd
--- /dev/null
+++ b/extensions/source/abpilot/fieldmappingpage.cxx
@@ -0,0 +1,77 @@
+/* -*- 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 "fieldmappingpage.hxx"
+#include "fieldmappingimpl.hxx"
+#include "addresssettings.hxx"
+#include "abspilot.hxx"
+
+
+namespace abp
+{
+ FieldMappingPage::FieldMappingPage(weld::Container* pPage, OAddressBookSourcePilot* pController)
+ : AddressBookSourcePage(pPage, pController, "modules/sabpilot/ui/fieldassignpage.ui", "FieldAssignPage")
+ , m_xInvokeDialog(m_xBuilder->weld_button("assign"))
+ , m_xHint(m_xBuilder->weld_label("hint"))
+ {
+ m_xInvokeDialog->connect_clicked(LINK(this, FieldMappingPage, OnInvokeDialog));
+ }
+
+ FieldMappingPage::~FieldMappingPage()
+ {
+ }
+
+ void FieldMappingPage::Activate()
+ {
+ AddressBookSourcePage::Activate();
+ m_xInvokeDialog->grab_focus();
+ }
+
+ void FieldMappingPage::initializePage()
+ {
+ AddressBookSourcePage::initializePage();
+ implUpdateHint();
+ }
+
+ void FieldMappingPage::implUpdateHint()
+ {
+ const AddressSettings& rSettings = getSettings();
+ OUString sHint;
+ if ( rSettings.aFieldMapping.empty() )
+ sHint = compmodule::ModuleRes(RID_STR_NOFIELDSASSIGNED);
+ m_xHint->set_label(sHint);
+ }
+
+ IMPL_LINK_NOARG( FieldMappingPage, OnInvokeDialog, weld::Button&, void )
+ {
+ AddressSettings& rSettings = getSettings();
+
+ // invoke the dialog doing the mapping
+ if ( fieldmapping::invokeDialog( getORB(), getDialog()->getDialog(), getDialog()->getDataSource().getDataSource(), rSettings ) )
+ {
+ if ( !rSettings.aFieldMapping.empty() )
+ getDialog()->travelNext();
+ else
+ implUpdateHint();
+ }
+ }
+
+} // namespace abp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/fieldmappingpage.hxx b/extensions/source/abpilot/fieldmappingpage.hxx
new file mode 100644
index 000000000..e3ef93794
--- /dev/null
+++ b/extensions/source/abpilot/fieldmappingpage.hxx
@@ -0,0 +1,46 @@
+/* -*- 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 "abspage.hxx"
+#include <vcl/weld.hxx>
+
+namespace abp
+{
+ class FieldMappingPage final : public AddressBookSourcePage
+ {
+ std::unique_ptr<weld::Button> m_xInvokeDialog;
+ std::unique_ptr<weld::Label> m_xHint;
+ public:
+ explicit FieldMappingPage(weld::Container* pPage, OAddressBookSourcePilot* pController);
+ virtual ~FieldMappingPage() override;
+ private:
+ // OWizardPage overridables
+ virtual void initializePage() override;
+
+ // BuilderPage overridables
+ virtual void Activate() override;
+
+ DECL_LINK(OnInvokeDialog, weld::Button&, void);
+
+ void implUpdateHint();
+ };
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/moduleabp.cxx b/extensions/source/abpilot/moduleabp.cxx
new file mode 100644
index 000000000..0a8f8fd4d
--- /dev/null
+++ b/extensions/source/abpilot/moduleabp.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <componentmodule.cxx>
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/tableselectionpage.cxx b/extensions/source/abpilot/tableselectionpage.cxx
new file mode 100644
index 000000000..abf8e5829
--- /dev/null
+++ b/extensions/source/abpilot/tableselectionpage.cxx
@@ -0,0 +1,101 @@
+/* -*- 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 "tableselectionpage.hxx"
+#include "abptypes.hxx"
+#include "addresssettings.hxx"
+#include "abspilot.hxx"
+#include <tools/debug.hxx>
+
+
+namespace abp
+{
+
+ TableSelectionPage::TableSelectionPage(weld::Container* pPage, OAddressBookSourcePilot* pController)
+ : AddressBookSourcePage(pPage, pController, "modules/sabpilot/ui/selecttablepage.ui", "SelectTablePage")
+ , m_xTableList(m_xBuilder->weld_tree_view("table"))
+ {
+ m_xTableList->connect_changed( LINK( this, TableSelectionPage, OnTableSelected ) );
+ m_xTableList->connect_row_activated( LINK( this, TableSelectionPage, OnTableDoubleClicked ) );
+ }
+
+ TableSelectionPage::~TableSelectionPage()
+ {
+ }
+
+ void TableSelectionPage::Activate()
+ {
+ AddressBookSourcePage::Activate();
+
+ m_xTableList->grab_focus();
+ }
+
+ void TableSelectionPage::initializePage()
+ {
+ AddressBookSourcePage::initializePage();
+
+ const AddressSettings& rSettings = getSettings();
+
+ m_xTableList->clear();
+
+ // get the table names
+ const StringBag& aTableNames = getDialog()->getDataSource().getTableNames();
+ DBG_ASSERT( aTableNames.size() > 1, "TableSelectionPage::initializePage: to be called for more than one table only!");
+ // this page should never bother the user if there is 1 or less tables.
+
+ // fill the list
+ for (auto const& tableName : aTableNames)
+ m_xTableList->append_text(tableName);
+
+ // initially select the proper table
+ m_xTableList->select_text(rSettings.sSelectedTable);
+ }
+
+ IMPL_LINK_NOARG( TableSelectionPage, OnTableDoubleClicked, weld::TreeView&, bool )
+ {
+ if (m_xTableList->count_selected_rows() == 1)
+ getDialog()->travelNext();
+ return true;
+ }
+
+ IMPL_LINK_NOARG( TableSelectionPage, OnTableSelected, weld::TreeView&, void )
+ {
+ updateDialogTravelUI();
+ }
+
+ bool TableSelectionPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!AddressBookSourcePage::commitPage(_eReason))
+ return false;
+
+ AddressSettings& rSettings = getSettings();
+ rSettings.sSelectedTable = m_xTableList->get_selected_text();
+
+ return true;
+ }
+
+ bool TableSelectionPage::canAdvance() const
+ {
+ return AddressBookSourcePage::canAdvance()
+ && (m_xTableList->count_selected_rows() > 0);
+ }
+
+} // namespace abp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/tableselectionpage.hxx b/extensions/source/abpilot/tableselectionpage.hxx
new file mode 100644
index 000000000..a150bf844
--- /dev/null
+++ b/extensions/source/abpilot/tableselectionpage.hxx
@@ -0,0 +1,50 @@
+/* -*- 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 "abspage.hxx"
+#include <vcl/weld.hxx>
+
+namespace abp
+{
+ class TableSelectionPage final : public AddressBookSourcePage
+ {
+ std::unique_ptr<weld::TreeView> m_xTableList;
+
+ public:
+ explicit TableSelectionPage(weld::Container* pPage, OAddressBookSourcePilot* pController);
+ virtual ~TableSelectionPage() override;
+ private:
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+
+ // BuilderPage overridables
+ virtual void Activate() override;
+
+ // OImportPage overridables
+ virtual bool canAdvance() const override;
+
+ DECL_LINK(OnTableSelected, weld::TreeView&, void);
+ DECL_LINK(OnTableDoubleClicked, weld::TreeView&, bool);
+ };
+
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/typeselectionpage.cxx b/extensions/source/abpilot/typeselectionpage.cxx
new file mode 100644
index 000000000..79cfd5d6b
--- /dev/null
+++ b/extensions/source/abpilot/typeselectionpage.cxx
@@ -0,0 +1,224 @@
+/* -*- 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 "typeselectionpage.hxx"
+#include "addresssettings.hxx"
+#include "abspilot.hxx"
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <com/sun/star/sdbc/XDriver.hpp>
+#include <com/sun/star/sdbc/DriverManager.hpp>
+
+namespace abp
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdbc;
+
+ // TypeSelectionPage
+ TypeSelectionPage::TypeSelectionPage(weld::Container* pPage, OAddressBookSourcePilot* pDialog)
+ : AddressBookSourcePage(pPage, pDialog, "modules/sabpilot/ui/selecttypepage.ui", "SelectTypePage")
+ , m_xEvolution(m_xBuilder->weld_radio_button("evolution"))
+ , m_xEvolutionGroupwise(m_xBuilder->weld_radio_button("groupwise"))
+ , m_xEvolutionLdap(m_xBuilder->weld_radio_button("evoldap"))
+ , m_xThunderbird(m_xBuilder->weld_radio_button("thunderbird"))
+ , m_xKab(m_xBuilder->weld_radio_button("kde"))
+ , m_xMacab(m_xBuilder->weld_radio_button("macosx"))
+ , m_xOther(m_xBuilder->weld_radio_button("other"))
+ {
+ //TODO: For now, try to keep offering the same choices like before the
+ // Mozilla cleanup, even if the status of what driver actually
+ // provides which functionality is somewhat unclear, see the discussions
+ // of fdo#57285 "Address Book Data Source Wizard lists 'macOS address
+ // book' on Linux" and fdo#57322 "Moz-free LDAP Address Book driver."
+ // In accordance with ancient OOo 3.3, this is as follows:
+ //
+ // On Linux:
+ // - EVOLUTION, EVOLUTION_GROUPWISE, EVOLUTION_LDAP (if applicable)
+ // - KAB (if applicable)
+ // - OTHER
+ //
+ // On macOS:
+ // - MACAB (if applicable)
+ // - OTHER
+ //
+ // On Windows:
+ // - THUNDERBIRD
+ // - OTHER
+
+#if !defined(_WIN32)
+ bool bHaveEvolution = false;
+ bool bHaveKab = false;
+ bool bHaveMacab = false;
+
+ Reference< XDriverManager2 > xManager = DriverManager::create( pDialog->getORB() );
+
+ try
+ {
+ // check whether Evolution is available
+ Reference< XDriver > xDriver( xManager->getDriverByURL("sdbc:address:evolution:local") );
+ if ( xDriver.is() )
+ bHaveEvolution = true;
+ }
+ catch (...)
+ {
+ }
+
+ // check whether KDE address book is available
+ try
+ {
+ Reference< XDriver > xDriver( xManager->getDriverByURL("sdbc:address:kab") );
+ if ( xDriver.is() )
+ bHaveKab = true;
+ }
+ catch (...)
+ {
+ }
+
+ try
+ {
+ // check whether macOS address book is available
+ Reference< XDriver > xDriver( xManager->getDriverByURL("sdbc:address:macab") );
+ if ( xDriver.is() )
+ bHaveMacab = true;
+ }
+ catch(...)
+ {
+ }
+#else
+ bool const bHaveEvolution = false;
+ bool const bHaveKab = false;
+ bool const bHaveMacab = false;
+#endif
+
+ // Items are displayed in list order
+ m_aAllTypes.push_back( ButtonItem( m_xEvolution.get(), AST_EVOLUTION, bHaveEvolution ) );
+ m_aAllTypes.push_back( ButtonItem( m_xEvolutionGroupwise.get(), AST_EVOLUTION_GROUPWISE, bHaveEvolution ) );
+ m_aAllTypes.push_back( ButtonItem( m_xEvolutionLdap.get(), AST_EVOLUTION_LDAP, bHaveEvolution ) );
+ m_aAllTypes.push_back( ButtonItem( m_xThunderbird.get(), AST_THUNDERBIRD, true ) );
+ m_aAllTypes.push_back( ButtonItem( m_xKab.get(), AST_KAB, bHaveKab ) );
+ m_aAllTypes.push_back( ButtonItem( m_xMacab.get(), AST_MACAB, bHaveMacab ) );
+ m_aAllTypes.push_back( ButtonItem( m_xOther.get(), AST_OTHER, true ) );
+
+ Link<weld::Toggleable&,void> aTypeSelectionHandler = LINK(this, TypeSelectionPage, OnTypeSelected );
+ for (auto const& elem : m_aAllTypes)
+ {
+ if (!elem.m_bVisible)
+ elem.m_pItem->hide();
+ else
+ {
+ elem.m_pItem->connect_toggled( aTypeSelectionHandler );
+ elem.m_pItem->show();
+ }
+ }
+ }
+
+ TypeSelectionPage::~TypeSelectionPage()
+ {
+ for (auto & elem : m_aAllTypes)
+ {
+ elem.m_bVisible = false;
+ }
+ }
+
+ void TypeSelectionPage::Activate()
+ {
+ AddressBookSourcePage::Activate();
+
+ for (auto const& elem : m_aAllTypes)
+ {
+ if( elem.m_pItem->get_active() && elem.m_bVisible )
+ {
+ elem.m_pItem->grab_focus();
+ break;
+ }
+ }
+
+ getDialog()->enableButtons(WizardButtonFlags::PREVIOUS, false);
+ }
+
+ void TypeSelectionPage::Deactivate()
+ {
+ AddressBookSourcePage::Deactivate();
+ getDialog()->enableButtons(WizardButtonFlags::PREVIOUS, true);
+ }
+
+ void TypeSelectionPage::selectType( AddressSourceType _eType )
+ {
+ for (auto const& elem : m_aAllTypes)
+ {
+ elem.m_pItem->set_active( _eType == elem.m_eType );
+ }
+ }
+
+ AddressSourceType TypeSelectionPage::getSelectedType() const
+ {
+ for (auto const& elem : m_aAllTypes)
+ {
+ if ( elem.m_pItem->get_active() && elem.m_bVisible )
+ return elem.m_eType;
+ }
+
+ return AST_INVALID;
+ }
+
+ void TypeSelectionPage::initializePage()
+ {
+ AddressBookSourcePage::initializePage();
+
+ const AddressSettings& rSettings = getSettings();
+ selectType(rSettings.eType);
+ }
+
+ bool TypeSelectionPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+ {
+ if (!AddressBookSourcePage::commitPage(_eReason))
+ return false;
+
+ if (AST_INVALID == getSelectedType( ))
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xContainer.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ compmodule::ModuleRes(RID_STR_NEEDTYPESELECTION)));
+ xBox->run();
+ return false;
+ }
+
+ AddressSettings& rSettings = getSettings();
+ rSettings.eType = getSelectedType();
+
+ return true;
+ }
+
+ bool TypeSelectionPage::canAdvance() const
+ {
+ return AddressBookSourcePage::canAdvance()
+ && (AST_INVALID != getSelectedType());
+ }
+
+ IMPL_LINK(TypeSelectionPage, OnTypeSelected, weld::Toggleable&, rButton, void)
+ {
+ if (!rButton.get_active())
+ return;
+ getDialog()->typeSelectionChanged( getSelectedType() );
+ updateDialogTravelUI();
+ }
+
+} // namespace abp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/typeselectionpage.hxx b/extensions/source/abpilot/typeselectionpage.hxx
new file mode 100644
index 000000000..7c908057d
--- /dev/null
+++ b/extensions/source/abpilot/typeselectionpage.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 "abspage.hxx"
+#include "addresssettings.hxx"
+#include <vcl/weld.hxx>
+
+namespace abp
+{
+
+ class TypeSelectionPage final : public AddressBookSourcePage
+ {
+ std::unique_ptr<weld::RadioButton> m_xEvolution;
+ std::unique_ptr<weld::RadioButton> m_xEvolutionGroupwise;
+ std::unique_ptr<weld::RadioButton> m_xEvolutionLdap;
+ std::unique_ptr<weld::RadioButton> m_xThunderbird;
+ std::unique_ptr<weld::RadioButton> m_xKab;
+ std::unique_ptr<weld::RadioButton> m_xMacab;
+ std::unique_ptr<weld::RadioButton> m_xOther;
+
+ struct ButtonItem {
+ weld::RadioButton* m_pItem;
+ AddressSourceType m_eType;
+ bool m_bVisible;
+
+ ButtonItem( weld::RadioButton *pItem,
+ AddressSourceType eType,
+ bool bVisible ) :
+ m_pItem( pItem ),
+ m_eType( eType ),
+ m_bVisible( bVisible )
+ {}
+ };
+
+ std::vector< ButtonItem > m_aAllTypes;
+
+ public:
+ explicit TypeSelectionPage(weld::Container* pPage, OAddressBookSourcePilot* pController);
+ virtual ~TypeSelectionPage() override;
+
+ // retrieves the currently selected type
+ AddressSourceType getSelectedType() const;
+
+ private:
+ // OWizardPage overridables
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+
+ // BuilderPage overridables
+ virtual void Activate() override;
+ virtual void Deactivate() override;
+
+ // OImportPage overridables
+ virtual bool canAdvance() const override;
+
+ DECL_LINK( OnTypeSelected, weld::Toggleable&, void );
+
+ void selectType( AddressSourceType _eType );
+ };
+
+
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/unodialogabp.cxx b/extensions/source/abpilot/unodialogabp.cxx
new file mode 100644
index 000000000..4409a1911
--- /dev/null
+++ b/extensions/source/abpilot/unodialogabp.cxx
@@ -0,0 +1,156 @@
+/* -*- 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 "unodialogabp.hxx"
+#include "abspilot.hxx"
+#include <comphelper/sequence.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+
+#define PROPERTY_ID_DATASOURCENAME 3
+
+namespace abp
+{
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::ui::dialogs;
+
+ OABSPilotUno::OABSPilotUno(const Reference< XComponentContext >& _rxORB)
+ :OGenericUnoDialog(_rxORB)
+ {
+ registerProperty( "DataSourceName", PROPERTY_ID_DATASOURCENAME, PropertyAttribute::READONLY ,
+ &m_sDataSourceName, cppu::UnoType<decltype(m_sDataSourceName)>::get() );
+ }
+
+ Any SAL_CALL OABSPilotUno::queryInterface( const Type& aType )
+ {
+ Any aReturn = svt::OGenericUnoDialog::queryInterface( aType );
+ return aReturn.hasValue() ? aReturn : OABSPilotUno_JBase::queryInterface( aType );
+ }
+
+ void SAL_CALL OABSPilotUno::acquire( ) noexcept
+ {
+ svt::OGenericUnoDialog::acquire();
+ }
+
+ void SAL_CALL OABSPilotUno::release( ) noexcept
+ {
+ svt::OGenericUnoDialog::release();
+ }
+
+ Sequence< Type > SAL_CALL OABSPilotUno::getTypes( )
+ {
+ return ::comphelper::concatSequences(
+ svt::OGenericUnoDialog::getTypes(),
+ OABSPilotUno_JBase::getTypes()
+ );
+ }
+
+ Sequence<sal_Int8> SAL_CALL OABSPilotUno::getImplementationId( )
+ {
+ return css::uno::Sequence<sal_Int8>();
+ }
+
+ OUString SAL_CALL OABSPilotUno::getImplementationName()
+ {
+ return "org.openoffice.comp.abp.OAddressBookSourcePilot";
+ }
+
+ css::uno::Sequence<OUString> SAL_CALL OABSPilotUno::getSupportedServiceNames()
+ {
+ return { "com.sun.star.ui.dialogs.AddressBookSourcePilot" };
+ }
+
+ Reference<XPropertySetInfo> SAL_CALL OABSPilotUno::getPropertySetInfo()
+ {
+ Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) );
+ return xInfo;
+ }
+
+
+ ::cppu::IPropertyArrayHelper& OABSPilotUno::getInfoHelper()
+ {
+ return *getArrayHelper();
+ }
+
+
+ ::cppu::IPropertyArrayHelper* OABSPilotUno::createArrayHelper( ) const
+ {
+ Sequence< Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+ }
+
+ void SAL_CALL OABSPilotUno::initialize( const Sequence< Any >& aArguments )
+ {
+ Reference<awt::XWindow> xParentWindow;
+ if (aArguments.getLength() == 1 && (aArguments[0] >>= xParentWindow) ) {
+ Sequence< Any > aNewArgs{ Any(PropertyValue(
+ "ParentWindow", 0, Any(xParentWindow), PropertyState_DIRECT_VALUE )) };
+ OGenericUnoDialog::initialize(aNewArgs);
+ } else {
+ OGenericUnoDialog::initialize(aArguments);
+ }
+ }
+
+ std::unique_ptr<weld::DialogController> OABSPilotUno::createDialog(const css::uno::Reference<css::awt::XWindow>& rParent)
+ {
+ return std::make_unique<OAddressBookSourcePilot>(Application::GetFrameWeld(rParent), m_aContext);
+ }
+
+ Any SAL_CALL OABSPilotUno::execute( const Sequence< NamedValue >& /*lArgs*/ )
+ {
+ // not interested in the context, not interested in the args
+ // -> call the execute method of the XExecutableDialog
+ static_cast< XExecutableDialog* >( this )->execute();
+
+ // result interest not really ...
+ // We show this dialog one times only!
+ // User has one chance to accept it or not.
+ // (or he can start it again by using wizard-menu!)
+ // So we should deregister it on our general job execution service by using right protocol parameters.
+ css::uno::Sequence< css::beans::NamedValue > lProtocol { { "Deactivate", css::uno::Any( true ) } };
+ return Any( lProtocol );
+ }
+
+ void OABSPilotUno::executedDialog(sal_Int16 _nExecutionResult)
+ {
+ if ( _nExecutionResult == RET_OK )
+ {
+ const AddressSettings& aSettings = static_cast<OAddressBookSourcePilot*>(m_xDialog.get())->getSettings();
+ m_sDataSourceName = aSettings.bRegisterDataSource ? aSettings.sRegisteredDataSourceName : aSettings.sDataSourceName;
+ }
+ }
+
+
+} // namespace abp
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+org_openoffice_comp_abp_OAddressBookSourcePilot(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new abp::OABSPilotUno(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/abpilot/unodialogabp.hxx b/extensions/source/abpilot/unodialogabp.hxx
new file mode 100644
index 000000000..b8bd940af
--- /dev/null
+++ b/extensions/source/abpilot/unodialogabp.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 <svtools/genericunodialog.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <componentmodule.hxx>
+#include <com/sun/star/task/XJob.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+namespace abp
+{
+ class OABSPilotUno;
+ typedef ::cppu::ImplHelper1< css::task::XJob > OABSPilotUno_JBase;
+ typedef ::comphelper::OPropertyArrayUsageHelper< OABSPilotUno > OABSPilotUno_PBase;
+ /// the UNO wrapper for the address book source pilot
+ class OABSPilotUno
+ : public svt::OGenericUnoDialog
+ , public OABSPilotUno_JBase
+ , public OABSPilotUno_PBase
+ {
+ OUString m_sDataSourceName;
+
+ public:
+ explicit OABSPilotUno(const css::uno::Reference< css::uno::XComponentContext >& _rxORB);
+
+ private:
+ // XInterface (disambiguation)
+ virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
+ virtual void SAL_CALL acquire( ) noexcept override;
+ virtual void SAL_CALL release( ) noexcept override;
+
+ // XTypeProvider
+ virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override;
+ virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId( ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+ // XPropertySet
+ virtual css::uno::Reference< css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override;
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override;
+
+ // XJob
+ virtual css::uno::Any SAL_CALL execute( const css::uno::Sequence< css::beans::NamedValue >& lArgs ) override;
+
+ // XInitialisation
+ virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
+
+ using svt::OGenericUnoDialog::execute;
+ // OGenericUnoDialog overridables
+ virtual std::unique_ptr<weld::DialogController> createDialog(const css::uno::Reference<css::awt::XWindow>& rParent) override;
+ virtual void executedDialog(sal_Int16 _nExecutionResult) override;
+ };
+
+} // namespace abp
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */