summaryrefslogtreecommitdiffstats
path: root/svtools/source/dialogs
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 /svtools/source/dialogs
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.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--svtools/source/dialogs/PlaceEditDialog.cxx374
-rw-r--r--svtools/source/dialogs/ServerDetailsControls.cxx492
-rw-r--r--svtools/source/dialogs/ServerDetailsControls.hxx143
-rw-r--r--svtools/source/dialogs/addresstemplate.cxx1122
-rw-r--r--svtools/source/dialogs/colrdlg.cxx161
-rw-r--r--svtools/source/dialogs/insdlg.cxx356
-rw-r--r--svtools/source/dialogs/prnsetup.cxx351
-rw-r--r--svtools/source/dialogs/restartdialog.cxx124
8 files changed, 3123 insertions, 0 deletions
diff --git a/svtools/source/dialogs/PlaceEditDialog.cxx b/svtools/source/dialogs/PlaceEditDialog.cxx
new file mode 100644
index 000000000..b61abd58e
--- /dev/null
+++ b/svtools/source/dialogs/PlaceEditDialog.cxx
@@ -0,0 +1,374 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <config_oauth2.h>
+
+#include <svtools/PlaceEditDialog.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <svtools/svtresid.hxx>
+#include <svtools/strings.hrc>
+#include <svtools/place.hxx>
+
+#include "ServerDetailsControls.hxx"
+
+using namespace com::sun::star::uno;
+
+PlaceEditDialog::PlaceEditDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "svt/ui/placeedit.ui", "PlaceEditDialog")
+ , m_xCurrentDetails()
+ , m_nCurrentType( 0 )
+ , m_bLabelChanged( false )
+ , m_bShowPassword( true )
+ , m_xEDServerName(m_xBuilder->weld_entry("name"))
+ , m_xLBServerType(m_xBuilder->weld_combo_box("type"))
+ , m_xEDUsername(m_xBuilder->weld_entry("login"))
+ , m_xFTUsernameLabel(m_xBuilder->weld_label("loginLabel"))
+ , m_xBTOk(m_xBuilder->weld_button("ok"))
+ , m_xBTCancel(m_xBuilder->weld_button("cancel"))
+ , m_xBTDelete(m_xBuilder->weld_button("delete"))
+ , m_xBTRepoRefresh(m_xBuilder->weld_button("repositoriesRefresh"))
+ , m_xCBPassword(m_xBuilder->weld_check_button("rememberPassword"))
+ , m_xEDPassword(m_xBuilder->weld_entry("password"))
+ , m_xFTPasswordLabel(m_xBuilder->weld_label("passwordLabel"))
+ , m_xTypeGrid(m_xBuilder->weld_widget("TypeGrid"))
+
+ , m_xRepositoryBox(m_xBuilder->weld_widget("RepositoryDetails"))
+ , m_xFTRepository(m_xBuilder->weld_label("repositoryLabel"))
+ , m_xLBRepository(m_xBuilder->weld_combo_box("repositories"))
+
+ , m_xEDShare(m_xBuilder->weld_entry("share"))
+ , m_xFTShare(m_xBuilder->weld_label("shareLabel"))
+
+ , m_xDetailsGrid(m_xBuilder->weld_widget("Details"))
+ , m_xHostBox(m_xBuilder->weld_widget("HostDetails"))
+ , m_xEDHost(m_xBuilder->weld_entry("host"))
+ , m_xFTHost(m_xBuilder->weld_label("hostLabel"))
+ , m_xEDPort(m_xBuilder->weld_spin_button("port"))
+ , m_xFTPort(m_xBuilder->weld_label("portLabel"))
+ , m_xEDRoot(m_xBuilder->weld_entry("path"))
+ , m_xFTRoot(m_xBuilder->weld_label("pathLabel"))
+
+ , m_xCBDavs(m_xBuilder->weld_check_button("webdavs"))
+{
+ m_xBTOk->connect_clicked( LINK( this, PlaceEditDialog, OKHdl) );
+ m_xBTOk->set_sensitive( false );
+
+ m_xEDServerName->connect_changed( LINK( this, PlaceEditDialog, EditLabelHdl) );
+
+ // This constructor is called when user request a place creation, so
+ // delete button is hidden.
+ m_xBTDelete->hide();
+
+ m_xLBServerType->connect_changed( LINK( this, PlaceEditDialog, SelectTypeHdl ) );
+ m_xEDUsername->connect_changed( LINK( this, PlaceEditDialog, EditUsernameHdl ) );
+ m_xEDPassword->connect_changed( LINK( this, PlaceEditDialog, EditUsernameHdl ) );
+
+ InitDetails( );
+}
+
+PlaceEditDialog::PlaceEditDialog(weld::Window* pParent, const std::shared_ptr<Place>& rPlace)
+ : GenericDialogController(pParent, "svt/ui/placeedit.ui", "PlaceEditDialog")
+ , m_xCurrentDetails( )
+ , m_bLabelChanged( true )
+ , m_bShowPassword( false )
+ , m_xEDServerName(m_xBuilder->weld_entry("name"))
+ , m_xLBServerType(m_xBuilder->weld_combo_box("type"))
+ , m_xEDUsername(m_xBuilder->weld_entry("login"))
+ , m_xFTUsernameLabel(m_xBuilder->weld_label("loginLabel"))
+ , m_xBTOk(m_xBuilder->weld_button("ok"))
+ , m_xBTCancel(m_xBuilder->weld_button("cancel"))
+ , m_xBTDelete(m_xBuilder->weld_button("delete"))
+ , m_xBTRepoRefresh(m_xBuilder->weld_button("repositoriesRefresh"))
+ , m_xCBPassword(m_xBuilder->weld_check_button("rememberPassword"))
+ , m_xEDPassword(m_xBuilder->weld_entry("password"))
+ , m_xFTPasswordLabel(m_xBuilder->weld_label("passwordLabel"))
+ , m_xTypeGrid(m_xBuilder->weld_widget("TypeGrid"))
+
+ , m_xRepositoryBox(m_xBuilder->weld_widget("RepositoryDetails"))
+ , m_xFTRepository(m_xBuilder->weld_label("repositoryLabel"))
+ , m_xLBRepository(m_xBuilder->weld_combo_box("repositories"))
+
+ , m_xEDShare(m_xBuilder->weld_entry("share"))
+ , m_xFTShare(m_xBuilder->weld_label("shareLabel"))
+
+ , m_xDetailsGrid(m_xBuilder->weld_widget("Details"))
+ , m_xHostBox(m_xBuilder->weld_widget("HostDetails"))
+ , m_xEDHost(m_xBuilder->weld_entry("host"))
+ , m_xFTHost(m_xBuilder->weld_label("hostLabel"))
+ , m_xEDPort(m_xBuilder->weld_spin_button("port"))
+ , m_xFTPort(m_xBuilder->weld_label("portLabel"))
+ , m_xEDRoot(m_xBuilder->weld_entry("path"))
+ , m_xFTRoot(m_xBuilder->weld_label("pathLabel"))
+
+ , m_xCBDavs(m_xBuilder->weld_check_button("webdavs"))
+{
+ m_xEDPassword->hide();
+ m_xFTPasswordLabel->hide();
+ m_xCBPassword->hide();
+
+ m_xBTOk->connect_clicked( LINK( this, PlaceEditDialog, OKHdl) );
+ m_xBTDelete->connect_clicked( LINK( this, PlaceEditDialog, DelHdl) );
+
+ m_xEDServerName->connect_changed( LINK( this, PlaceEditDialog, ModifyHdl) );
+ m_xLBServerType->connect_changed( LINK( this, PlaceEditDialog, SelectTypeHdl ) );
+
+ InitDetails( );
+
+ m_xEDServerName->set_text(rPlace->GetName());
+
+ // Fill the boxes with the URL parts
+ bool bSuccess = false;
+ for (size_t i = 0 ; i < m_aDetailsContainers.size( ) && !bSuccess; ++i)
+ {
+ INetURLObject& rUrl = rPlace->GetUrlObject();
+ bSuccess = m_aDetailsContainers[i]->setUrl( rUrl );
+ if ( bSuccess )
+ {
+ // Fill the Username field
+ if ( rUrl.HasUserData( ) )
+ {
+ m_xEDUsername->set_text( rUrl.GetUser(INetURLObject::DecodeMechanism::WithCharset) );
+ m_aDetailsContainers[i]->setUsername( rUrl.GetUser(INetURLObject::DecodeMechanism::WithCharset) );
+ }
+
+ m_xLBServerType->set_active(i);
+ SelectType(true);
+ }
+ }
+
+ // In edit mode user can't change connection type
+ m_xTypeGrid->hide();
+}
+
+PlaceEditDialog::~PlaceEditDialog()
+{
+}
+
+OUString PlaceEditDialog::GetServerUrl()
+{
+ OUString sUrl;
+ if (m_xCurrentDetails)
+ {
+ INetURLObject aUrl = m_xCurrentDetails->getUrl();
+ OUString sUsername = m_xEDUsername->get_text().trim();
+ if ( !sUsername.isEmpty( ) )
+ aUrl.SetUser( sUsername );
+ if ( !aUrl.HasError( ) )
+ sUrl = aUrl.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ }
+
+ return sUrl;
+}
+
+std::shared_ptr<Place> PlaceEditDialog::GetPlace()
+{
+ return std::make_shared<Place>(m_xEDServerName->get_text(), GetServerUrl(), true);
+}
+
+void PlaceEditDialog::InitDetails( )
+{
+ // Create CMIS controls for each server type
+
+ // Load the ServerType entries
+ bool bSkipGDrive = OUString( GDRIVE_CLIENT_ID ).isEmpty() ||
+ OUString( GDRIVE_CLIENT_SECRET ).isEmpty();
+ bool bSkipAlfresco = OUString( ALFRESCO_CLOUD_CLIENT_ID ).isEmpty() ||
+ OUString( ALFRESCO_CLOUD_CLIENT_SECRET ).isEmpty();
+ bool bSkipOneDrive= OUString( ONEDRIVE_CLIENT_ID ).isEmpty() ||
+ OUString( ONEDRIVE_CLIENT_SECRET ).isEmpty();
+
+ Sequence< OUString > aTypesUrlsList( officecfg::Office::Common::Misc::CmisServersUrls::get() );
+ Sequence< OUString > aTypesNamesList( officecfg::Office::Common::Misc::CmisServersNames::get() );
+
+ int nPos = 0;
+ auto nSize = std::min(aTypesUrlsList.getLength(), aTypesNamesList.getLength());
+ for ( sal_Int32 i = 0; i < nSize; ++i )
+ {
+ OUString sUrl = aTypesUrlsList[i].replaceFirst("<host", OUStringConcatenation("<" + SvtResId(STR_SVT_HOST))).replaceFirst("port>", OUStringConcatenation(SvtResId(STR_SVT_PORT) + ">"));
+
+ if ((sUrl == GDRIVE_BASE_URL && bSkipGDrive) ||
+ (sUrl.startsWith( ALFRESCO_CLOUD_BASE_URL) && bSkipAlfresco) ||
+ (sUrl == ONEDRIVE_BASE_URL && bSkipOneDrive))
+ {
+ // this service is not supported
+ continue;
+ }
+
+ m_xLBServerType->insert_text(nPos, aTypesNamesList[i].replaceFirst("Other CMIS", SvtResId(STR_SVT_OTHER_CMIS)));
+
+ std::shared_ptr<DetailsContainer> xCmisDetails(std::make_shared<CmisDetailsContainer>(this, sUrl));
+ xCmisDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
+ m_aDetailsContainers.push_back(xCmisDetails);
+
+ ++nPos;
+ }
+
+ // Create WebDAV / FTP / SSH details control
+ std::shared_ptr<DetailsContainer> xDavDetails(std::make_shared<DavDetailsContainer>(this));
+ xDavDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
+ m_aDetailsContainers.push_back(xDavDetails);
+
+ std::shared_ptr<DetailsContainer> xFtpDetails(std::make_shared<HostDetailsContainer>(this, 21, "ftp"));
+ xFtpDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
+ m_aDetailsContainers.push_back(xFtpDetails);
+
+ std::shared_ptr<DetailsContainer> xSshDetails(std::make_shared<HostDetailsContainer>(this, 22, "sftp"));
+ xSshDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
+ m_aDetailsContainers.push_back(xSshDetails);
+
+ // Remove Windows Share entry from dialog on Windows OS, where it's non-functional
+#if defined(_WIN32)
+ // nPos is the position of first item that is pre-defined in svtools/uiconfig/ui/placeedit.ui,
+ // after other CMIS types were inserted
+ m_xLBServerType->remove(nPos + 3);
+#else
+ // Create Windows Share control
+ std::shared_ptr<DetailsContainer> xSmbDetails(std::make_shared<SmbDetailsContainer>(this));
+ xSmbDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
+ m_aDetailsContainers.push_back(xSmbDetails);
+#endif
+
+ // Set default to first value
+ m_xLBServerType->set_active(0);
+
+ if (m_xLBServerType->get_active_text() == "--------------------" )
+ m_xLBServerType->set_active(1);
+
+ SelectType(true);
+}
+
+IMPL_LINK( PlaceEditDialog, OKHdl, weld::Button&, /*rBtn*/, void)
+{
+ if ( !m_xCurrentDetails )
+ return;
+
+ OUString sUrl = m_xCurrentDetails->getUrl().GetHost( INetURLObject::DecodeMechanism::WithCharset );
+
+ if ( sUrl.startsWith( GDRIVE_BASE_URL )
+ || sUrl.startsWith( ALFRESCO_CLOUD_BASE_URL )
+ || sUrl.startsWith( ONEDRIVE_BASE_URL ) )
+ {
+ m_xBTRepoRefresh->clicked();
+
+ sUrl = m_xCurrentDetails->getUrl().GetHost( INetURLObject::DecodeMechanism::WithCharset );
+ INetURLObject aHostUrl( sUrl );
+ OUString sRepoId = aHostUrl.GetMark();
+
+ if ( !sRepoId.isEmpty() )
+ {
+ m_xDialog->response(RET_OK);
+ }
+ else
+ {
+ // TODO: repository id missing. Auth error?
+ }
+ }
+ else
+ {
+ m_xDialog->response(RET_OK);
+ }
+}
+
+IMPL_LINK( PlaceEditDialog, DelHdl, weld::Button&, /*rButton*/, void)
+{
+ // ReUsing existing symbols...
+ m_xDialog->response(RET_NO);
+}
+
+IMPL_LINK_NOARG( PlaceEditDialog, EditHdl, DetailsContainer*, void )
+{
+ if( !m_bLabelChanged )
+ {
+ if( !m_xEDUsername->get_text().isEmpty( ) )
+ {
+ OUString sLabel = SvtResId( STR_SVT_DEFAULT_SERVICE_LABEL );
+ OUString sUser = m_xEDUsername->get_text();
+
+ int nLength = sUser.indexOf( '@' );
+ if( nLength < 0 )
+ nLength = sUser.getLength();
+
+ sLabel = sLabel.replaceFirst( "$user$", sUser.subView( 0, nLength ) );
+ sLabel = sLabel.replaceFirst( "$service$", m_xLBServerType->get_active_text() );
+
+ m_xEDServerName->set_text( sLabel );
+ m_bLabelChanged = false;
+ }
+ else
+ {
+ m_xEDServerName->set_text( m_xLBServerType->get_active_text( ) );
+ }
+ }
+
+ OUString sUrl = GetServerUrl( );
+ OUString sName = m_xEDServerName->get_text().trim();
+ m_xBTOk->set_sensitive( !sName.isEmpty( ) && !sUrl.isEmpty( ) );
+}
+
+IMPL_LINK_NOARG( PlaceEditDialog, ModifyHdl, weld::Entry&, void )
+{
+ EditHdl(nullptr);
+}
+
+IMPL_LINK_NOARG( PlaceEditDialog, EditLabelHdl, weld::Entry&, void )
+{
+ m_bLabelChanged = true;
+ EditHdl(nullptr);
+}
+
+IMPL_LINK_NOARG( PlaceEditDialog, EditUsernameHdl, weld::Entry&, void )
+{
+ for ( auto& rxDetailsContainer : m_aDetailsContainers )
+ {
+ rxDetailsContainer->setUsername( m_xEDUsername->get_text() );
+ rxDetailsContainer->setPassword( m_xEDPassword->get_text() );
+ }
+
+ EditHdl(nullptr);
+}
+
+IMPL_LINK_NOARG( PlaceEditDialog, SelectTypeHdl, weld::ComboBox&, void )
+{
+ SelectType(false);
+}
+
+void PlaceEditDialog::SelectType(bool bSkipSeparator)
+{
+ if ( m_xLBServerType->get_active_text() == "--------------------" )
+ {
+ if (bSkipSeparator)
+ m_xLBServerType->set_active(m_nCurrentType);
+ else
+ m_xLBServerType->set_active(-1);
+ return;
+ }
+
+ if (m_xCurrentDetails)
+ m_xCurrentDetails->set_visible(false);
+
+ const int nPos = m_xLBServerType->get_active( );
+ m_xCurrentDetails = m_aDetailsContainers[nPos];
+ m_nCurrentType = nPos;
+
+ m_xCurrentDetails->set_visible(true);
+
+ m_xCBPassword->set_visible( m_bShowPassword && m_xCurrentDetails->enableUserCredentials() );
+ m_xEDPassword->set_visible( m_bShowPassword && m_xCurrentDetails->enableUserCredentials() );
+ m_xFTPasswordLabel->set_visible( m_bShowPassword && m_xCurrentDetails->enableUserCredentials() );
+ m_xEDUsername->set_visible( m_xCurrentDetails->enableUserCredentials() );
+ m_xFTUsernameLabel->set_visible( m_xCurrentDetails->enableUserCredentials() );
+
+ m_xDialog->resize_to_request();
+
+ EditHdl(nullptr);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/dialogs/ServerDetailsControls.cxx b/svtools/source/dialogs/ServerDetailsControls.cxx
new file mode 100644
index 000000000..24a6de413
--- /dev/null
+++ b/svtools/source/dialogs/ServerDetailsControls.cxx
@@ -0,0 +1,492 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/task/PasswordContainer.hpp>
+#include <com/sun/star/task/XPasswordContainer2.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <o3tl/safeint.hxx>
+#include <rtl/uri.hxx>
+#include <ucbhelper/content.hxx>
+#include <ucbhelper/commandenvironment.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <svtools/PlaceEditDialog.hxx>
+#include <config_oauth2.h>
+
+#include "ServerDetailsControls.hxx"
+
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::task;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+
+DetailsContainer::DetailsContainer(PlaceEditDialog* pDialog)
+ : m_pDialog(pDialog)
+{
+ m_pDialog->m_xEDPort->connect_output(LINK(this, DetailsContainer, FormatPortHdl));
+}
+
+//format without thousand separator
+IMPL_STATIC_LINK(DetailsContainer, FormatPortHdl, weld::SpinButton&, rSpinButton, void)
+{
+ rSpinButton.set_text(OUString::number(rSpinButton.get_value()));
+}
+
+DetailsContainer::~DetailsContainer( )
+{
+}
+
+void DetailsContainer::set_visible( bool )
+{
+ m_pDialog->m_xDetailsGrid->set_sensitive(true);
+
+ m_pDialog->m_xEDHost->connect_changed( LINK( this, DetailsContainer, ValueChangeHdl ) );
+ m_pDialog->m_xEDPort->connect_changed( LINK( this, DetailsContainer, ValueChangeHdl ) );
+ m_pDialog->m_xEDRoot->connect_changed( LINK( this, DetailsContainer, ValueChangeHdl ) );
+}
+
+INetURLObject DetailsContainer::getUrl( )
+{
+ // Don't use that class directly: make it smarter by subclassing it.
+ return INetURLObject( );
+}
+
+bool DetailsContainer::setUrl( const INetURLObject& )
+{
+ // That class doesn't contain any logic... it defers the dirty work
+ // to the sub classes.
+ return false;
+}
+
+void DetailsContainer::notifyChange( )
+{
+ m_aChangeHdl.Call( this );
+}
+
+IMPL_LINK_NOARG( DetailsContainer, ValueChangeHdl, weld::Entry&, void )
+{
+ notifyChange( );
+}
+
+HostDetailsContainer::HostDetailsContainer(PlaceEditDialog* pDialog, sal_uInt16 nPort, const OUString& sScheme) :
+ DetailsContainer( pDialog ),
+ m_nDefaultPort( nPort ),
+ m_sScheme( sScheme )
+{
+ set_visible( false );
+}
+
+void HostDetailsContainer::set_visible( bool bShow )
+{
+ m_pDialog->m_xFTHost->set_visible( bShow );
+ m_pDialog->m_xHostBox->set_visible( bShow );
+ m_pDialog->m_xEDRoot->set_visible( bShow );
+ m_pDialog->m_xFTRoot->set_visible( bShow );
+
+ DetailsContainer::set_visible( bShow );
+
+ if ( bShow )
+ {
+ if (m_pDialog->m_xEDPort->get_value() == 0)
+ m_pDialog->m_xEDPort->set_value( m_nDefaultPort );
+ m_pDialog->m_xEDHost->set_text( m_sHost );
+ }
+ else
+ m_pDialog->m_xEDPort->set_value( 0 );
+}
+
+INetURLObject HostDetailsContainer::getUrl( )
+{
+ OUString sHost = m_pDialog->m_xEDHost->get_text().trim();
+ sal_Int64 nPort = m_pDialog->m_xEDPort->get_value();
+ OUString sPath = m_pDialog->m_xEDRoot->get_text().trim();
+
+ OUString sUrl;
+ if ( !sHost.isEmpty( ) )
+ {
+ sUrl = m_sScheme + "://" + sHost;
+ if ( nPort != m_nDefaultPort )
+ sUrl += ":" + OUString::number( nPort );
+ if ( !sPath.isEmpty( ) )
+ if ( sPath.indexOf( '/' ) != 0 )
+ sUrl += "/";
+ sUrl += sPath;
+ }
+
+ return INetURLObject( sUrl );
+}
+
+bool HostDetailsContainer::setUrl( const INetURLObject& rUrl )
+{
+ bool bSuccess = verifyScheme( INetURLObject::GetScheme( rUrl.GetProtocol( ) ) );
+
+ if ( bSuccess )
+ {
+ m_sHost = rUrl.GetHost( );
+ m_pDialog->m_xEDHost->set_text( rUrl.GetHost( ) );
+ m_pDialog->m_xEDPort->set_value( rUrl.GetPort( ) );
+ m_pDialog->m_xEDRoot->set_text( rUrl.GetURLPath() );
+ }
+
+ return bSuccess;
+}
+
+bool HostDetailsContainer::verifyScheme( const OUString& sScheme )
+{
+ return sScheme == OUStringConcatenation( m_sScheme + "://" );
+}
+
+DavDetailsContainer::DavDetailsContainer(PlaceEditDialog* pBuilder)
+ : HostDetailsContainer(pBuilder, 80, "http")
+{
+ m_pDialog->m_xCBDavs->connect_toggled(LINK(this, DavDetailsContainer, ToggledDavsHdl));
+
+ set_visible( false );
+}
+
+void DavDetailsContainer::set_visible( bool bShow )
+{
+ HostDetailsContainer::set_visible( bShow );
+
+ if ( !bShow )
+ m_pDialog->m_xCBDavs->set_active(false);
+
+ m_pDialog->m_xCBDavs->set_visible(bShow);
+}
+
+bool DavDetailsContainer::verifyScheme( const OUString& rScheme )
+{
+ bool bValid = false;
+ if ( rScheme == "http://" )
+ {
+ bValid = true;
+ m_pDialog->m_xCBDavs->set_active(false);
+ ToggledDavsHdl(*m_pDialog->m_xCBDavs);
+ }
+ else if ( rScheme == "https://" )
+ {
+ bValid = true;
+ m_pDialog->m_xCBDavs->set_active(true);
+ ToggledDavsHdl(*m_pDialog->m_xCBDavs);
+ }
+ return bValid;
+}
+
+IMPL_LINK( DavDetailsContainer, ToggledDavsHdl, weld::Toggleable&, rCheckBox, void )
+{
+ // Change default port if needed
+ bool bCheckedDavs = rCheckBox.get_active();
+ if ( m_pDialog->m_xEDPort->get_value() == 80 && bCheckedDavs )
+ m_pDialog->m_xEDPort->set_value( 443 );
+ else if ( m_pDialog->m_xEDPort->get_value() == 443 && !bCheckedDavs )
+ m_pDialog->m_xEDPort->set_value( 80 );
+
+ OUString sScheme( "http" );
+ if ( bCheckedDavs )
+ sScheme = "https";
+ setScheme( sScheme );
+
+ notifyChange( );
+}
+
+SmbDetailsContainer::SmbDetailsContainer(PlaceEditDialog* pDialog)
+ : DetailsContainer(pDialog)
+{
+ m_pDialog->m_xEDShare->connect_changed( LINK( this, DetailsContainer, ValueChangeHdl ) );
+
+ set_visible( false );
+}
+
+INetURLObject SmbDetailsContainer::getUrl( )
+{
+ OUString sHost = m_pDialog->m_xEDHost->get_text().trim( );
+ OUString sShare = m_pDialog->m_xEDShare->get_text().trim( );
+ OUString sPath = m_pDialog->m_xEDRoot->get_text().trim( );
+
+ OUString sUrl;
+ if ( !sHost.isEmpty( ) )
+ {
+ sUrl = "smb://" + sHost + "/";
+ if ( !sShare.isEmpty( ) )
+ sUrl += sShare;
+ if ( !sPath.isEmpty( ) )
+ if ( sPath.indexOf( '/' ) != 0 )
+ sUrl += "/";
+ sUrl += sPath;
+ }
+
+ return INetURLObject( sUrl );
+}
+
+bool SmbDetailsContainer::setUrl( const INetURLObject& rUrl )
+{
+ bool bSuccess = rUrl.GetProtocol() == INetProtocol::Smb;
+
+ if ( bSuccess )
+ {
+ OUString sShare = rUrl.getName( 0 );
+ OUString sFullPath = rUrl.GetURLPath( );
+ OUString sPath;
+ if ( sFullPath.getLength( ) > sShare.getLength( ) )
+ {
+ sal_Int32 nPos = sShare.getLength( );
+ if ( nPos != 0 )
+ ++nPos;
+ sPath = sFullPath.copy( nPos );
+ }
+
+ m_sHost = rUrl.GetHost( );
+ m_pDialog->m_xEDHost->set_text( m_sHost );
+ m_pDialog->m_xEDShare->set_text( sShare );
+ m_pDialog->m_xEDRoot->set_text( sPath );
+ }
+
+ return bSuccess;
+}
+
+void SmbDetailsContainer::set_visible( bool bShow )
+{
+ m_pDialog->m_xEDShare->set_visible( bShow );
+ m_pDialog->m_xFTShare->set_visible( bShow );
+ m_pDialog->m_xEDRoot->set_visible( bShow );
+ m_pDialog->m_xFTRoot->set_visible( bShow );
+
+ m_pDialog->m_xFTHost->set_visible( bShow );
+ m_pDialog->m_xHostBox->set_visible( bShow );
+ m_pDialog->m_xEDPort->set_sensitive( !bShow );
+ m_pDialog->m_xFTPort->set_sensitive( !bShow );
+
+ if ( bShow )
+ m_pDialog->m_xEDHost->set_text( m_sHost );
+}
+
+CmisDetailsContainer::CmisDetailsContainer(PlaceEditDialog* pParentDialog, OUString const & sBinding) :
+ DetailsContainer( pParentDialog ),
+ m_sUsername( ),
+ m_xCmdEnv( ),
+ m_aRepoIds( ),
+ m_sRepoId( ),
+ m_sBinding( sBinding ),
+ m_xParentDialog(pParentDialog->getDialog()->GetXWindow())
+{
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< XInteractionHandler > xGlobalInteractionHandler =
+ InteractionHandler::createWithParent(xContext, m_xParentDialog);
+ m_xCmdEnv = new ucbhelper::CommandEnvironment( xGlobalInteractionHandler, Reference< XProgressHandler >() );
+
+ set_visible( false );
+}
+
+void CmisDetailsContainer::set_visible( bool bShow )
+{
+ m_pDialog->m_xLBRepository->connect_changed( LINK( this, CmisDetailsContainer, SelectRepoHdl ) );
+ m_pDialog->m_xBTRepoRefresh->connect_clicked( LINK( this, CmisDetailsContainer, RefreshReposHdl ) );
+
+ m_pDialog->m_xEDHost->set_text( m_sBinding );
+
+ if( ( m_sBinding == GDRIVE_BASE_URL )
+ || m_sBinding.startsWith( ALFRESCO_CLOUD_BASE_URL )
+ || ( m_sBinding == ONEDRIVE_BASE_URL ) )
+ {
+ m_pDialog->m_xFTHost->hide();
+ m_pDialog->m_xHostBox->hide();
+ m_pDialog->m_xFTRepository->hide();
+ m_pDialog->m_xRepositoryBox->hide();
+ m_pDialog->m_xEDRoot->hide();
+ m_pDialog->m_xFTRoot->hide();
+ }
+ else
+ {
+ m_pDialog->m_xFTHost->set_visible( bShow );
+ m_pDialog->m_xHostBox->set_visible( bShow );
+ m_pDialog->m_xFTRepository->set_visible( bShow );
+ m_pDialog->m_xRepositoryBox->set_visible( bShow );
+ m_pDialog->m_xEDRoot->set_visible( bShow );
+ m_pDialog->m_xFTRoot->set_visible( bShow );
+ }
+
+ DetailsContainer::set_visible( bShow );
+ m_pDialog->m_xEDPort->set_sensitive( !bShow );
+ m_pDialog->m_xFTPort->set_sensitive( !bShow );
+}
+
+INetURLObject CmisDetailsContainer::getUrl( )
+{
+ OUString sBindingUrl = m_pDialog->m_xEDHost->get_text().trim();
+ OUString sPath = m_pDialog->m_xEDRoot->get_text().trim();
+
+ bool bSkip = true;
+ if( ( m_sBinding == GDRIVE_BASE_URL )
+ || m_sBinding.startsWith( ALFRESCO_CLOUD_BASE_URL )
+ || ( m_sBinding == ONEDRIVE_BASE_URL ) )
+ {
+ bSkip = m_sUsername.isEmpty();
+ }
+ else
+ {
+ bSkip = m_sRepoId.isEmpty();
+ }
+
+ OUString sUrl;
+ if ( !sBindingUrl.isEmpty( ) && !bSkip )
+ {
+ OUString sEncodedBinding = rtl::Uri::encode(
+ sBindingUrl + "#" + m_sRepoId,
+ rtl_UriCharClassRelSegment,
+ rtl_UriEncodeKeepEscapes,
+ RTL_TEXTENCODING_UTF8 );
+ sUrl = "vnd.libreoffice.cmis://" + sEncodedBinding;
+ }
+ sUrl += sPath;
+
+ return INetURLObject( sUrl );
+}
+
+bool CmisDetailsContainer::setUrl( const INetURLObject& rUrl )
+{
+ bool bSuccess = rUrl.GetProtocol() == INetProtocol::Cmis;
+
+ if ( bSuccess )
+ {
+ OUString sDecodedHost = rUrl.GetHost( INetURLObject::DecodeMechanism::WithCharset );
+ INetURLObject aHostUrl( sDecodedHost );
+ m_sBinding = aHostUrl.GetURLNoMark( );
+ m_sRepoId = aHostUrl.GetMark( );
+
+ m_pDialog->m_xEDHost->set_text( m_sBinding );
+ m_pDialog->m_xEDRoot->set_text( rUrl.GetURLPath() );
+ }
+ return bSuccess;
+}
+
+void CmisDetailsContainer::setUsername( const OUString& rUsername )
+{
+ m_sUsername = rUsername;
+}
+
+void CmisDetailsContainer::setPassword( const OUString& rPass )
+{
+ m_sPassword = rPass;
+}
+
+void CmisDetailsContainer::selectRepository( )
+{
+ // Get the repo ID and call the Change listener
+ const int nPos = m_pDialog->m_xLBRepository->get_active();
+ if( o3tl::make_unsigned(nPos) < m_aRepoIds.size() )
+ {
+ m_sRepoId = m_aRepoIds[nPos];
+ notifyChange( );
+ }
+}
+
+IMPL_LINK_NOARG( CmisDetailsContainer, RefreshReposHdl, weld::Button&, void )
+{
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< XPasswordContainer2 > xMasterPasswd = PasswordContainer::create( xContext );
+
+
+ OUString sBindingUrl = m_pDialog->m_xEDHost->get_text().trim( );
+
+ OUString sEncodedUsername = "";
+
+ if ( !m_sUsername.isEmpty( ) )
+ {
+ sEncodedUsername = rtl::Uri::encode(m_sUsername,
+ rtl_UriCharClassUserinfo,
+ rtl_UriEncodeKeepEscapes,
+ RTL_TEXTENCODING_UTF8 )
+ + "@";
+ }
+
+ // Clean the listbox
+ m_pDialog->m_xLBRepository->clear();
+ m_aRepoIds.clear();
+
+ // Compute the URL
+ OUString sUrl;
+ if ( !sBindingUrl.isEmpty( ) )
+ {
+ OUString sEncodedBinding = rtl::Uri::encode(
+ sBindingUrl,
+ rtl_UriCharClassRelSegment,
+ rtl_UriEncodeKeepEscapes,
+ RTL_TEXTENCODING_UTF8 );
+ sUrl = "vnd.libreoffice.cmis://" + sEncodedUsername + sEncodedBinding;
+ }
+
+ // temporary remember the password
+ try
+ {
+ if( !sUrl.isEmpty() && !m_sUsername.isEmpty() && !m_sPassword.isEmpty() )
+ {
+ Reference< XInteractionHandler > xInteractionHandler =
+ InteractionHandler::createWithParent(xContext, m_xParentDialog);
+
+ Sequence<OUString> aPasswd { m_sPassword };
+
+ xMasterPasswd->add(
+ sUrl, m_sUsername, aPasswd, xInteractionHandler );
+ }
+ }
+ catch( const Exception& )
+ {}
+
+ try
+ {
+ // Get the Content
+ ::ucbhelper::Content aCnt( sUrl, m_xCmdEnv, comphelper::getProcessComponentContext() );
+ Sequence<OUString> aProps { "Title" };
+ Reference< XResultSet > xResultSet( aCnt.createCursor( aProps ), UNO_SET_THROW );
+ Reference< XContentAccess > xAccess( xResultSet, UNO_QUERY_THROW );
+ while ( xResultSet->next() )
+ {
+ OUString sURL = xAccess->queryContentIdentifierString( );
+ INetURLObject aURL( sURL );
+ OUString sId = aURL.GetURLPath( INetURLObject::DecodeMechanism::WithCharset );
+ sId = sId.copy( 1 );
+ m_aRepoIds.push_back( sId );
+
+ Reference< XRow > xRow( xResultSet, UNO_QUERY );
+ OUString sName = xRow->getString( 1 );
+ m_pDialog->m_xLBRepository->append_text(sName);
+ }
+ }
+ catch ( const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "svtools.dialogs", "RefreshReposHdl" );
+ }
+
+ // Auto-select the first one
+ if (m_pDialog->m_xLBRepository->get_count() > 0)
+ {
+ m_pDialog->m_xLBRepository->set_active(0);
+ selectRepository( );
+ }
+
+ // remove temporary password
+ try
+ {
+ xMasterPasswd->remove( sUrl, m_sUsername );
+ }
+ catch( const Exception& )
+ {}
+}
+
+IMPL_LINK_NOARG( CmisDetailsContainer, SelectRepoHdl, weld::ComboBox&, void )
+{
+ selectRepository( );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/dialogs/ServerDetailsControls.hxx b/svtools/source/dialogs/ServerDetailsControls.hxx
new file mode 100644
index 000000000..b0f892fe2
--- /dev/null
+++ b/svtools/source/dialogs/ServerDetailsControls.hxx
@@ -0,0 +1,143 @@
+/* -*- 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/.
+ */
+#ifndef INCLUDED_SVTOOLS_SERVERDETAILSCONTROLS_HXX
+#define INCLUDED_SVTOOLS_SERVERDETAILSCONTROLS_HXX
+
+#include <vector>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <tools/link.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/weld.hxx>
+
+namespace com :: sun :: star :: ucb { class XCommandEnvironment; }
+namespace com :: sun :: star :: awt { class XWindow; }
+
+namespace weld {
+ class Button;
+ class ComboBox;
+ class Entry;
+ class SpinButton;
+ class ToggleButton;
+}
+
+class PlaceEditDialog;
+
+class DetailsContainer
+{
+ protected:
+ PlaceEditDialog* m_pDialog;
+ Link<DetailsContainer*,void> m_aChangeHdl;
+
+ public:
+ DetailsContainer(PlaceEditDialog* pDialog);
+ virtual ~DetailsContainer( );
+
+ void setChangeHdl( const Link<DetailsContainer*,void>& rLink ) { m_aChangeHdl = rLink; }
+
+ virtual void set_visible( bool bShow );
+ virtual INetURLObject getUrl( );
+
+ /** Try to split the URL in the controls of that container.
+
+ \param sUrl the URL to split
+ \return true if the split worked, false otherwise.
+ */
+ virtual bool setUrl( const INetURLObject& rUrl );
+
+ virtual void setUsername( const OUString& /*rUsername*/ ) { };
+ virtual void setPassword( const OUString& ) { };
+
+ virtual bool enableUserCredentials( ) { return true; };
+
+ protected:
+ void notifyChange( );
+ DECL_LINK(ValueChangeHdl, weld::Entry&, void);
+ DECL_STATIC_LINK(DetailsContainer, FormatPortHdl, weld::SpinButton&, void);
+};
+
+class HostDetailsContainer : public DetailsContainer
+{
+ private:
+ sal_uInt16 m_nDefaultPort;
+ OUString m_sScheme;
+ OUString m_sHost;
+
+ public:
+ HostDetailsContainer(PlaceEditDialog* pDialog, sal_uInt16 nPort, const OUString& sScheme);
+
+ virtual void set_visible( bool bShow ) override;
+ virtual INetURLObject getUrl( ) override;
+ virtual bool setUrl( const INetURLObject& rUrl ) override;
+
+ protected:
+ void setScheme( const OUString& sScheme ) { m_sScheme = sScheme; }
+
+ /** Verifies that the scheme split from the URL can be handled by
+ the container and set the proper controls accordingly if needed.
+ */
+ virtual bool verifyScheme( const OUString& rScheme );
+};
+
+class DavDetailsContainer final : public HostDetailsContainer
+{
+ public:
+ DavDetailsContainer(PlaceEditDialog* pDialog);
+
+ virtual void set_visible( bool bShow ) override;
+ virtual bool enableUserCredentials( ) override { return false; };
+
+ private:
+ virtual bool verifyScheme( const OUString& rScheme ) override;
+
+ DECL_LINK(ToggledDavsHdl, weld::Toggleable&, void);
+};
+
+class SmbDetailsContainer final : public DetailsContainer
+{
+ private:
+ OUString m_sHost;
+
+ public:
+ SmbDetailsContainer(PlaceEditDialog* pDialog);
+
+ virtual INetURLObject getUrl( ) override;
+ virtual bool setUrl( const INetURLObject& rUrl ) override;
+ virtual void set_visible( bool bShow ) override;
+};
+
+class CmisDetailsContainer final : public DetailsContainer
+{
+ private:
+ OUString m_sUsername;
+ OUString m_sPassword;
+ css::uno::Reference< css::ucb::XCommandEnvironment > m_xCmdEnv;
+ std::vector< OUString > m_aRepoIds;
+ OUString m_sRepoId;
+ OUString m_sBinding;
+ css::uno::Reference< css::awt::XWindow > m_xParentDialog;
+
+ public:
+ CmisDetailsContainer(PlaceEditDialog* pDialog, OUString const & sBinding);
+
+ virtual void set_visible( bool bShow ) override;
+ virtual INetURLObject getUrl( ) override;
+ virtual bool setUrl( const INetURLObject& rUrl ) override;
+ virtual void setUsername( const OUString& rUsername ) override;
+ virtual void setPassword( const OUString& rPass ) override;
+
+ private:
+ void selectRepository( );
+ DECL_LINK ( RefreshReposHdl, weld::Button&, void );
+ DECL_LINK ( SelectRepoHdl, weld::ComboBox&, void );
+};
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/dialogs/addresstemplate.cxx b/svtools/source/dialogs/addresstemplate.cxx
new file mode 100644
index 000000000..6f29151e3
--- /dev/null
+++ b/svtools/source/dialogs/addresstemplate.cxx
@@ -0,0 +1,1122 @@
+/* -*- 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 <memory>
+#include <svtools/addresstemplate.hxx>
+#include <svtools/strings.hrc>
+#include <svtools/svtresid.hxx>
+#include <tools/debug.hxx>
+#include <comphelper/interaction.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/string.hxx>
+#include <unotools/configitem.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+#include <osl/diagnose.h>
+#include <com/sun/star/util/AliasProgrammaticPair.hpp>
+#include <com/sun/star/ui/dialogs/AddressBookSourcePilot.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <svl/filenotation.hxx>
+#include <tools/urlobj.hxx>
+#include <algorithm>
+#include <map>
+#include <set>
+#include <array>
+#include <strings.hxx>
+
+
+namespace svt
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::ui::dialogs;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::task;
+ using namespace ::comphelper;
+ using namespace ::utl;
+
+ typedef std::set<OUString> StringBag;
+ typedef std::map<OUString, OUString> MapString2String;
+
+ namespace
+ {
+ OUString lcl_getSelectedDataSource( const weld::ComboBox& dataSourceCombo )
+ {
+ OUString selectedDataSource = dataSourceCombo.get_active_text();
+ if (dataSourceCombo.find_text(selectedDataSource) == -1)
+ {
+ // none of the pre-selected entries -> assume a path to a database document
+ OFileNotation aFileNotation( selectedDataSource, OFileNotation::N_SYSTEM );
+ selectedDataSource = aFileNotation.get( OFileNotation::N_URL );
+ }
+ return selectedDataSource;
+ }
+
+ // = IAssignmentData
+
+ class IAssignmentData
+ {
+ public:
+ virtual ~IAssignmentData();
+
+ /// the data source to use for the address book
+ virtual OUString getDatasourceName() const = 0;
+
+ /// the command to use for the address book
+ virtual OUString getCommand() const = 0;
+
+ /// checks whether or not there is an assignment for a given logical field
+ virtual bool hasFieldAssignment(const OUString& _rLogicalName) = 0;
+ /// retrieves the assignment for a given logical field
+ virtual OUString getFieldAssignment(const OUString& _rLogicalName) = 0;
+
+ /// set the assignment for a given logical field
+ virtual void setFieldAssignment(const OUString& _rLogicalName, const OUString& _rAssignment) = 0;
+
+ virtual void setDatasourceName(const OUString& _rName) = 0;
+ virtual void setCommand(const OUString& _rCommand) = 0;
+ };
+
+ }
+
+ IAssignmentData::~IAssignmentData()
+ {
+ }
+
+
+ // = AssignmentTransientData
+
+ namespace {
+
+ class AssignmentTransientData : public IAssignmentData
+ {
+ protected:
+ OUString m_sDSName;
+ OUString m_sTableName;
+ MapString2String m_aAliases;
+
+ public:
+ AssignmentTransientData(
+ const OUString& _rDataSourceName,
+ const OUString& _rTableName,
+ const Sequence< AliasProgrammaticPair >& _rFields
+ );
+
+ // IAssignmentData overridables
+ virtual OUString getDatasourceName() const override;
+ virtual OUString getCommand() const override;
+
+ virtual bool hasFieldAssignment(const OUString& _rLogicalName) override;
+ virtual OUString getFieldAssignment(const OUString& _rLogicalName) override;
+ virtual void setFieldAssignment(const OUString& _rLogicalName, const OUString& _rAssignment) override;
+
+ virtual void setDatasourceName(const OUString& _rName) override;
+ virtual void setCommand(const OUString& _rCommand) override;
+ };
+
+ }
+
+ AssignmentTransientData::AssignmentTransientData(
+ const OUString& _rDataSourceName, const OUString& _rTableName,
+ const Sequence< AliasProgrammaticPair >& _rFields )
+ :m_sDSName( _rDataSourceName )
+ ,m_sTableName( _rTableName )
+ {
+ // fill our aliases structure
+ // first collect all known programmatic names
+ StringBag aKnownNames;
+
+ OUString const sLogicalFieldNames(STR_LOGICAL_FIELD_NAMES);
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OUString aToken = sLogicalFieldNames.getToken(0, ';', nIndex);
+ aKnownNames.insert(aToken);
+ }
+ while ( nIndex >= 0);
+
+ // loop through the given names
+ for (const AliasProgrammaticPair& rField : _rFields)
+ {
+ if ( aKnownNames.end() != aKnownNames.find( rField.ProgrammaticName ) )
+ {
+ m_aAliases[ rField.ProgrammaticName ] = rField.Alias;
+ }
+ else
+ {
+ SAL_WARN( "svtools", "AssignmentTransientData::AssignmentTransientData: unknown programmatic name: "
+ << rField.ProgrammaticName );
+ }
+ }
+ }
+
+
+ OUString AssignmentTransientData::getDatasourceName() const
+ {
+ return m_sDSName;
+ }
+
+
+ OUString AssignmentTransientData::getCommand() const
+ {
+ return m_sTableName;
+ }
+
+
+ bool AssignmentTransientData::hasFieldAssignment(const OUString& _rLogicalName)
+ {
+ MapString2String::const_iterator aPos = m_aAliases.find( _rLogicalName );
+ return ( m_aAliases.end() != aPos )
+ && ( !aPos->second.isEmpty() );
+ }
+
+
+ OUString AssignmentTransientData::getFieldAssignment(const OUString& _rLogicalName)
+ {
+ OUString sReturn;
+ MapString2String::const_iterator aPos = m_aAliases.find( _rLogicalName );
+ if ( m_aAliases.end() != aPos )
+ sReturn = aPos->second;
+
+ return sReturn;
+ }
+
+
+ void AssignmentTransientData::setFieldAssignment(const OUString& _rLogicalName, const OUString& _rAssignment)
+ {
+ m_aAliases[ _rLogicalName ] = _rAssignment;
+ }
+
+
+ void AssignmentTransientData::setDatasourceName(const OUString&)
+ {
+ OSL_FAIL( "AssignmentTransientData::setDatasourceName: cannot be implemented for transient data!" );
+ }
+
+
+ void AssignmentTransientData::setCommand(const OUString&)
+ {
+ OSL_FAIL( "AssignmentTransientData::setCommand: cannot be implemented for transient data!" );
+ }
+
+
+ // = AssignmentPersistentData
+
+ namespace {
+
+ class AssignmentPersistentData
+ :public ::utl::ConfigItem
+ ,public IAssignmentData
+ {
+ protected:
+ StringBag m_aStoredFields;
+
+ protected:
+ css::uno::Any getProperty(const OUString& _rLocalName) const;
+
+ OUString getStringProperty(const char* _pLocalName) const;
+ OUString getStringProperty(const OUString& _rLocalName) const;
+
+ void setStringProperty(const char* _pLocalName, const OUString& _rValue);
+
+ public:
+ AssignmentPersistentData();
+
+ // IAssignmentData overridables
+ virtual OUString getDatasourceName() const override;
+ virtual OUString getCommand() const override;
+
+ virtual bool hasFieldAssignment(const OUString& _rLogicalName) override;
+ virtual OUString getFieldAssignment(const OUString& _rLogicalName) override;
+ virtual void setFieldAssignment(const OUString& _rLogicalName, const OUString& _rAssignment) override;
+
+ virtual void setDatasourceName(const OUString& _rName) override;
+ virtual void setCommand(const OUString& _rCommand) override;
+
+ virtual void Notify( const css::uno::Sequence<OUString>& aPropertyNames) override;
+
+ private:
+ virtual void ImplCommit() override;
+ void clearFieldAssignment(const OUString& _rLogicalName);
+ };
+
+ }
+
+void AssignmentPersistentData::Notify( const css::uno::Sequence<OUString>& )
+{
+}
+
+void AssignmentPersistentData::ImplCommit()
+{
+}
+
+
+ AssignmentPersistentData::AssignmentPersistentData()
+ :ConfigItem("Office.DataAccess/AddressBook")
+ {
+ const Sequence< OUString > aStoredNames = GetNodeNames("Fields");
+ m_aStoredFields.insert(aStoredNames.begin(), aStoredNames.end());
+ }
+
+ bool AssignmentPersistentData::hasFieldAssignment(const OUString& _rLogicalName)
+ {
+ return (m_aStoredFields.end() != m_aStoredFields.find(_rLogicalName));
+ }
+
+
+ OUString AssignmentPersistentData::getFieldAssignment(const OUString& _rLogicalName)
+ {
+ OUString sAssignment;
+ if (hasFieldAssignment(_rLogicalName))
+ {
+ OUString sFieldPath = "Fields/" + _rLogicalName + "/AssignedFieldName";
+ sAssignment = getStringProperty(sFieldPath);
+ }
+ return sAssignment;
+ }
+
+
+ Any AssignmentPersistentData::getProperty(const OUString& _rLocalName) const
+ {
+ Sequence< OUString > aProperties(&_rLocalName, 1);
+ Sequence< Any > aValues = const_cast<AssignmentPersistentData*>(this)->GetProperties(aProperties);
+ DBG_ASSERT(aValues.getLength() == 1, "AssignmentPersistentData::getProperty: invalid sequence length!");
+ return aValues[0];
+ }
+
+
+ OUString AssignmentPersistentData::getStringProperty(const OUString& _rLocalName) const
+ {
+ OUString sReturn;
+ getProperty( _rLocalName ) >>= sReturn;
+ return sReturn;
+ }
+
+
+ OUString AssignmentPersistentData::getStringProperty(const char* _pLocalName) const
+ {
+ OUString sReturn;
+ getProperty(OUString::createFromAscii(_pLocalName)) >>= sReturn;
+ return sReturn;
+ }
+
+
+ void AssignmentPersistentData::setStringProperty(const char* _pLocalName, const OUString& _rValue)
+ {
+ Sequence< OUString > aNames { OUString::createFromAscii(_pLocalName) };
+ Sequence< Any > aValues{ Any(_rValue) };
+ PutProperties(aNames, aValues);
+ }
+
+
+ void AssignmentPersistentData::setFieldAssignment(const OUString& _rLogicalName, const OUString& _rAssignment)
+ {
+ if (_rAssignment.isEmpty())
+ {
+ if (hasFieldAssignment(_rLogicalName))
+ {
+ // the assignment exists but it should be reset
+ clearFieldAssignment(_rLogicalName);
+ }
+ return;
+ }
+
+ // Fields
+ OUString sDescriptionNodePath("Fields");
+
+ // Fields/<field>
+ OUString sFieldElementNodePath = sDescriptionNodePath + "/" + _rLogicalName;
+
+ Sequence< PropertyValue > aNewFieldDescription{
+ // Fields/<field>/ProgrammaticFieldName
+ comphelper::makePropertyValue(sFieldElementNodePath + "/ProgrammaticFieldName",
+ _rLogicalName),
+ // Fields/<field>/AssignedFieldName
+ comphelper::makePropertyValue(sFieldElementNodePath + "/AssignedFieldName",
+ _rAssignment)
+ };
+
+ // just set the new value
+ bool bSuccess =
+ SetSetProperties(sDescriptionNodePath, aNewFieldDescription);
+ DBG_ASSERT(bSuccess, "AssignmentPersistentData::setFieldAssignment: could not commit the changes a field!");
+ }
+
+
+ void AssignmentPersistentData::clearFieldAssignment(const OUString& _rLogicalName)
+ {
+ if (!hasFieldAssignment(_rLogicalName))
+ // nothing to do
+ return;
+
+ Sequence< OUString > aNames(&_rLogicalName, 1);
+ ClearNodeElements("Fields", aNames);
+ }
+
+
+ OUString AssignmentPersistentData::getDatasourceName() const
+ {
+ return getStringProperty( "DataSourceName" );
+ }
+
+
+ OUString AssignmentPersistentData::getCommand() const
+ {
+ return getStringProperty( "Command" );
+ }
+
+
+ void AssignmentPersistentData::setDatasourceName(const OUString& _rName)
+ {
+ setStringProperty( "DataSourceName", _rName );
+ }
+
+
+ void AssignmentPersistentData::setCommand(const OUString& _rCommand)
+ {
+ setStringProperty( "Command", _rCommand );
+ }
+
+
+ // = AddressBookSourceDialogData
+
+ struct AddressBookSourceDialogData
+ {
+ std::array<std::unique_ptr<weld::Label>, FIELD_PAIRS_VISIBLE*2> pFieldLabels;
+ std::array<std::unique_ptr<weld::ComboBox>, FIELD_PAIRS_VISIBLE*2> pFields;
+
+ /// when working transient, we need the data source
+ Reference< XDataSource >
+ m_xTransientDataSource;
+ /// current scroll pos in the field list
+ sal_Int32 nFieldScrollPos;
+ /// indicates that we've an odd field number. This member is for efficiency only, it's redundant.
+ bool bOddFieldNumber : 1;
+ /// indicates that we're working with the real persistent configuration
+ bool bWorkingPersistent : 1;
+
+ /// the strings to use as labels for the field selection listboxes
+ std::vector<OUString> aFieldLabels;
+ // the current field assignment
+ std::vector<OUString> aFieldAssignments;
+ /// the logical field names
+ std::vector<OUString> aLogicalFieldNames;
+
+ std::unique_ptr<IAssignmentData> pConfigData;
+
+
+ AddressBookSourceDialogData( )
+ :pFieldLabels{{nullptr}}
+ ,pFields{{nullptr}}
+ ,nFieldScrollPos(0)
+ ,bOddFieldNumber(false)
+ ,bWorkingPersistent( true )
+ ,pConfigData( new AssignmentPersistentData )
+ {
+ }
+
+ AddressBookSourceDialogData( const Reference< XDataSource >& _rxTransientDS, const OUString& _rDataSourceName,
+ const OUString& _rTableName, const Sequence< AliasProgrammaticPair >& _rFields )
+ :pFieldLabels{{nullptr}}
+ ,pFields{{nullptr}}
+ ,m_xTransientDataSource( _rxTransientDS )
+ ,nFieldScrollPos(0)
+ ,bOddFieldNumber(false)
+ ,bWorkingPersistent( false )
+ ,pConfigData( new AssignmentTransientData( _rDataSourceName, _rTableName, _rFields ) )
+ {
+ }
+
+ // Copy assignment is forbidden and not implemented.
+ AddressBookSourceDialogData (const AddressBookSourceDialogData &) = delete;
+ AddressBookSourceDialogData & operator= (const AddressBookSourceDialogData &) = delete;
+ };
+
+ // = AddressBookSourceDialog
+ AddressBookSourceDialog::AddressBookSourceDialog(weld::Window* pParent,
+ const Reference< XComponentContext >& _rxORB )
+ : GenericDialogController(pParent, "svt/ui/addresstemplatedialog.ui", "AddressTemplateDialog")
+ , m_sNoFieldSelection(SvtResId(STR_NO_FIELD_SELECTION))
+ , m_xORB(_rxORB)
+ , m_pImpl( new AddressBookSourceDialogData )
+ {
+ implConstruct();
+ }
+
+ AddressBookSourceDialog::AddressBookSourceDialog(weld::Window* pParent, const Reference< XComponentContext >& _rxORB,
+ const Reference< XDataSource >& _rxTransientDS, const OUString& _rDataSourceName,
+ const OUString& _rTable, const Sequence< AliasProgrammaticPair >& _rMapping )
+ : GenericDialogController(pParent, "svt/ui/addresstemplatedialog.ui", "AddressTemplateDialog")
+ , m_sNoFieldSelection(SvtResId(STR_NO_FIELD_SELECTION))
+ , m_xORB(_rxORB)
+ , m_pImpl( new AddressBookSourceDialogData( _rxTransientDS, _rDataSourceName, _rTable, _rMapping ) )
+ {
+ implConstruct();
+ }
+
+ void AddressBookSourceDialog::implConstruct()
+ {
+ m_xOKButton = m_xBuilder->weld_button("ok");
+ m_xDatasource = m_xBuilder->weld_combo_box("datasource");
+ m_xAdministrateDatasources = m_xBuilder->weld_button("admin");
+ m_xTable = m_xBuilder->weld_combo_box("datatable");
+ m_xFieldScroller = m_xBuilder->weld_scrolled_window("scrollwindow", true);
+ m_xGrid = m_xBuilder->weld_widget("grid");
+
+ for (sal_Int32 row=0; row<FIELD_PAIRS_VISIBLE; ++row)
+ {
+ for (sal_Int32 column=0; column<2; ++column)
+ {
+ // the label
+ m_pImpl->pFieldLabels[row * 2 + column] = m_xBuilder->weld_label("label" + OString::number(row * 2 + column));
+ // the listbox
+ m_pImpl->pFields[row * 2 + column] = m_xBuilder->weld_combo_box("box" + OString::number(row * 2 + column));
+ m_pImpl->pFields[row * 2 + column]->connect_changed(LINK(this, AddressBookSourceDialog, OnFieldSelect));
+ }
+ }
+
+ initializeDatasources();
+
+ // for the moment, we have a hard coded list of all known fields.
+ // A better solution would be to store all known field translations in the configuration, which could be
+ // extensible by the user in an arbitrary way.
+ // But for the moment we need a quick solution ...
+ // (the main thing would be to store the translations to use here in the user interface, besides that, the code
+ // should be adjustable with a rather small effort.)
+
+ // initialize the strings for the field labels
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_FIRSTNAME ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_LASTNAME ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_COMPANY));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_DEPARTMENT ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_STREET ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_ZIPCODE ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_CITY ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_STATE));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_COUNTRY ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_HOMETEL ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_WORKTEL ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_OFFICETEL));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_MOBILE));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_TELOTHER));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_PAGER));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_FAX ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_EMAIL ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_URL ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_TITLE ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_POSITION ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_INITIALS ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_ADDRFORM ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_SALUTATION ));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_ID));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_CALENDAR));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_INVITE));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_NOTE));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_USER1));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_USER2));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_USER3));
+ m_pImpl->aFieldLabels.push_back( SvtResId( STR_FIELD_USER4));
+
+ tools::Long nLabelWidth = 0;
+ tools::Long nListBoxWidth = m_pImpl->pFields[0]->get_approximate_digit_width() * 18;
+ for (auto const& fieldLabel : m_pImpl->aFieldLabels)
+ {
+ m_pImpl->pFieldLabels[0]->set_label(fieldLabel);
+ nLabelWidth = std::max(nLabelWidth, m_pImpl->pFieldLabels[0]->get_preferred_size().Width());
+ }
+ for (sal_Int32 row=0; row<FIELD_PAIRS_VISIBLE; ++row)
+ {
+ for (sal_Int32 column=0; column<2; ++column)
+ {
+ m_pImpl->pFieldLabels[row * 2 + column]->set_size_request(nLabelWidth, -1);
+ m_pImpl->pFields[row * 2 + column]->set_size_request(nListBoxWidth, -1);
+ }
+ }
+
+ // force an even number of known fields
+ m_pImpl->bOddFieldNumber = (m_pImpl->aFieldLabels.size() % 2) != 0;
+ if (m_pImpl->bOddFieldNumber)
+ m_pImpl->aFieldLabels.emplace_back();
+
+ // limit the scrollbar range accordingly
+ sal_Int32 nOverallFieldPairs = m_pImpl->aFieldLabels.size() / 2;
+ m_xFieldScroller->vadjustment_configure(0, 0, nOverallFieldPairs,
+ 1, FIELD_PAIRS_VISIBLE - 1, FIELD_PAIRS_VISIBLE);
+
+ // reset the current field assignments
+ m_pImpl->aFieldAssignments.resize(m_pImpl->aFieldLabels.size());
+ // (empty strings mean "no assignment")
+
+ // some knittings
+ m_xFieldScroller->connect_vadjustment_changed(LINK(this, AddressBookSourceDialog, OnFieldScroll));
+ m_xAdministrateDatasources->connect_clicked(LINK(this, AddressBookSourceDialog, OnAdministrateDatasources));
+ m_xDatasource->set_entry_completion(true);
+ m_xTable->set_entry_completion(true);
+ m_xTable->connect_focus_in(LINK(this, AddressBookSourceDialog, OnComboGetFocus));
+ m_xDatasource->connect_focus_in(LINK(this, AddressBookSourceDialog, OnComboGetFocus));
+ m_xTable->connect_focus_out(LINK(this, AddressBookSourceDialog, OnComboLoseFocus));
+ m_xDatasource->connect_focus_out(LINK(this, AddressBookSourceDialog, OnComboLoseFocus));
+ m_xTable->connect_changed(LINK(this, AddressBookSourceDialog, OnComboSelect));
+ m_xDatasource->connect_changed(LINK(this, AddressBookSourceDialog, OnComboSelect));
+ m_xOKButton->connect_clicked(LINK(this, AddressBookSourceDialog, OnOkClicked));
+
+ // initialize the field controls
+ resetFields();
+ // tdf#136494 wait until contents are filled before getting preferred height
+ m_xFieldScroller->set_size_request(-1, m_xGrid->get_preferred_size().Height());
+ m_xFieldScroller->vadjustment_set_value(0);
+ m_pImpl->nFieldScrollPos = -1;
+ implScrollFields(0, false, false);
+
+ // the logical names
+ OUString sLogicalFieldNames(STR_LOGICAL_FIELD_NAMES);
+ sal_Int32 nAdjustedTokenCount = comphelper::string::getTokenCount(sLogicalFieldNames, ';') + (m_pImpl->bOddFieldNumber ? 1 : 0);
+ DBG_ASSERT(nAdjustedTokenCount == static_cast<sal_Int32>(m_pImpl->aFieldLabels.size()),
+ "AddressBookSourceDialog::AddressBookSourceDialog: inconsistence between logical and UI field names!");
+ m_pImpl->aLogicalFieldNames.reserve(nAdjustedTokenCount);
+ sal_Int32 nIdx{ 0 };
+ for (sal_Int32 i = 0; i<nAdjustedTokenCount; ++i)
+ m_pImpl->aLogicalFieldNames.push_back(sLogicalFieldNames.getToken(0, ';', nIdx));
+
+ Application::PostUserEvent(LINK(this, AddressBookSourceDialog, OnDelayedInitialize), nullptr, false);
+
+ // so the dialog will at least show up before we do the loading of the
+ // configuration data and the (maybe time consuming) analysis of the data source/table to select
+
+ if (m_pImpl->bWorkingPersistent)
+ return;
+
+ m_xAdministrateDatasources->hide();
+ }
+
+ void AddressBookSourceDialog::getFieldMapping(Sequence< AliasProgrammaticPair >& _rMapping) const
+ {
+ _rMapping.realloc( m_pImpl->aLogicalFieldNames.size() );
+ AliasProgrammaticPair* pPair = _rMapping.getArray();
+
+ for (auto const& logicalFieldName : m_pImpl->aLogicalFieldNames)
+ {
+ if ( m_pImpl->pConfigData->hasFieldAssignment(logicalFieldName) )
+ {
+ // the user gave us an assignment for this field
+ pPair->ProgrammaticName = logicalFieldName;
+ pPair->Alias = m_pImpl->pConfigData->getFieldAssignment(logicalFieldName);
+ ++pPair;
+ }
+ }
+
+ _rMapping.realloc( pPair - _rMapping.getArray() );
+ }
+
+ void AddressBookSourceDialog::loadConfiguration()
+ {
+ OUString sName = m_pImpl->pConfigData->getDatasourceName();
+ INetURLObject aURL( sName );
+ if( aURL.GetProtocol() != INetProtocol::NotValid )
+ {
+ OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ sName = aFileNotation.get(OFileNotation::N_SYSTEM);
+ }
+
+ m_xDatasource->set_entry_text(sName);
+ m_xTable->set_entry_text(m_pImpl->pConfigData->getCommand());
+ // we ignore the CommandType: only tables are supported
+
+ // the logical names for the fields
+ // AddressBookSourceDialog::loadConfiguration: inconsistence between field names and field assignments!
+ assert(m_pImpl->aLogicalFieldNames.size() == m_pImpl->aFieldAssignments.size());
+
+ auto aAssignment = m_pImpl->aFieldAssignments.begin();
+ for (auto const& logicalFieldName : m_pImpl->aLogicalFieldNames)
+ {
+ *aAssignment = m_pImpl->pConfigData->getFieldAssignment(logicalFieldName);
+ ++aAssignment;
+ }
+ }
+
+ AddressBookSourceDialog::~AddressBookSourceDialog()
+ {
+ }
+
+ void AddressBookSourceDialog::initializeDatasources()
+ {
+ if (!m_xDatabaseContext.is())
+ {
+ DBG_ASSERT(m_xORB.is(), "AddressBookSourceDialog::initializeDatasources: no service factory!");
+ if (!m_xORB.is())
+ return;
+
+ try
+ {
+ m_xDatabaseContext = DatabaseContext::create(m_xORB);
+ }
+ catch(const Exception&) { }
+ if (!m_xDatabaseContext.is())
+ {
+ ShowServiceNotAvailableError(m_xDialog.get(), u"com.sun.star.sdb.DatabaseContext", false);
+ return;
+ }
+ }
+ m_xDatasource->clear();
+
+ // fill the datasources listbox
+ try
+ {
+ const css::uno::Sequence<OUString> aElementNames = m_xDatabaseContext->getElementNames();
+ for (const OUString& rDatasourceName : aElementNames)
+ m_xDatasource->append_text(rDatasourceName);
+ }
+ catch(Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "svtools", "AddressBookSourceDialog::initializeDatasources: caught an exception while asking for the data source names!");
+ }
+ }
+
+ IMPL_LINK(AddressBookSourceDialog, OnFieldScroll, weld::ScrolledWindow&, rScrollBar, void)
+ {
+ implScrollFields(rScrollBar.vadjustment_get_value(), true, true);
+ }
+
+ void AddressBookSourceDialog::resetTables()
+ {
+ if (!m_xDatabaseContext.is())
+ return;
+
+ weld::WaitObject aWaitCursor(m_xDialog.get());
+
+ // no matter what we do here, we handled the currently selected data source (no matter if successful or not)
+ m_xDatasource->save_value();
+
+ // create an interaction handler (may be needed for connecting)
+ Reference< XInteractionHandler > xHandler;
+ try
+ {
+ xHandler.set(
+ InteractionHandler::createWithParent(m_xORB, m_xDialog->GetXWindow()),
+ UNO_QUERY_THROW );
+ }
+ catch(const Exception&) { }
+ if (!xHandler.is())
+ {
+ ShowServiceNotAvailableError(m_xDialog.get(), u"com.sun.star.task.InteractionHandler", true);
+ return;
+ }
+
+ // the currently selected table
+ OUString sOldTable = m_xTable->get_active_text();
+
+ m_xTable->clear();
+
+ m_xCurrentDatasourceTables= nullptr;
+
+ // get the tables of the connection
+ Sequence< OUString > aTableNames;
+ Any aException;
+ try
+ {
+ Reference< XCompletedConnection > xDS;
+ if ( m_pImpl->bWorkingPersistent )
+ {
+ OUString sSelectedDS = lcl_getSelectedDataSource(*m_xDatasource);
+
+ // get the data source the user has chosen and let it build a connection
+ INetURLObject aURL( sSelectedDS );
+ if ( aURL.GetProtocol() != INetProtocol::NotValid || m_xDatabaseContext->hasByName(sSelectedDS) )
+ m_xDatabaseContext->getByName( sSelectedDS ) >>= xDS;
+ }
+ else
+ {
+ xDS.set(m_pImpl->m_xTransientDataSource, css::uno::UNO_QUERY);
+ }
+
+ // build the connection
+ Reference< XConnection > xConn;
+ if (xDS.is())
+ xConn = xDS->connectWithCompletion(xHandler);
+
+ // get the table names
+ Reference< XTablesSupplier > xSupplTables(xConn, UNO_QUERY);
+ if (xSupplTables.is())
+ {
+ m_xCurrentDatasourceTables = xSupplTables->getTables();
+ if (m_xCurrentDatasourceTables.is())
+ aTableNames = m_xCurrentDatasourceTables->getElementNames();
+ }
+ }
+ catch(const SQLContext& e) { aException <<= e; }
+ catch(const SQLWarning& e) { aException <<= e; }
+ catch(const SQLException& e) { aException <<= e; }
+ catch(Exception&)
+ {
+ OSL_FAIL("AddressBookSourceDialog::resetTables: could not retrieve the table!");
+ }
+
+ if (aException.hasValue())
+ {
+ Reference< XInteractionRequest > xRequest = new OInteractionRequest(aException);
+ try
+ {
+ xHandler->handle(xRequest);
+ }
+ catch(Exception&) { }
+ return;
+ }
+
+ bool bKnowOldTable = false;
+ // fill the table list
+ for (const OUString& rTableName : std::as_const(aTableNames))
+ {
+ m_xTable->append_text(rTableName);
+ if (rTableName == sOldTable)
+ bKnowOldTable = true;
+ }
+
+ // set the old table, if the new data source knows a table with this name, too. Else reset the tables edit field.
+ if (!bKnowOldTable)
+ sOldTable.clear();
+ m_xTable->set_entry_text(sOldTable);
+
+ resetFields();
+ }
+
+ void AddressBookSourceDialog::resetFields()
+ {
+ weld::WaitObject aWaitCursor(m_xDialog.get());
+
+ // no matter what we do here, we handled the currently selected table (no matter if successful or not)
+ m_xDatasource->save_value();
+
+ OUString sSelectedTable = m_xTable->get_active_text();
+ Sequence< OUString > aColumnNames;
+ try
+ {
+ if (m_xCurrentDatasourceTables.is())
+ {
+ // get the table and the columns
+ Reference< XColumnsSupplier > xSuppTableCols;
+ if (m_xCurrentDatasourceTables->hasByName(sSelectedTable))
+ xSuppTableCols.set(
+ m_xCurrentDatasourceTables->getByName(sSelectedTable),
+ css::uno::UNO_QUERY);
+ Reference< XNameAccess > xColumns;
+ if (xSuppTableCols.is())
+ xColumns = xSuppTableCols->getColumns();
+ if (xColumns.is())
+ aColumnNames = xColumns->getElementNames();
+ }
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("AddressBookSourceDialog::resetFields: could not retrieve the table columns!");
+ }
+
+
+ // for quicker access
+ ::std::set< OUString > aColumnNameSet(std::cbegin(aColumnNames), std::cend(aColumnNames));
+
+ std::vector<OUString>::iterator aInitialSelection = m_pImpl->aFieldAssignments.begin() + m_pImpl->nFieldScrollPos;
+
+ OUString sSaveSelection;
+ for (sal_Int32 i=0; i<FIELD_CONTROLS_VISIBLE; ++i, ++aInitialSelection)
+ {
+ weld::ComboBox* pListbox = m_pImpl->pFields[i].get();
+ sSaveSelection = pListbox->get_active_text();
+
+ pListbox->clear();
+
+ // the one entry for "no selection"
+ pListbox->append_text(m_sNoFieldSelection);
+ // as it's entry data, set the index of the list box in our array
+ pListbox->set_id(0, OUString::number(i));
+
+ // the field names
+ for (const OUString& rColumnName : std::as_const(aColumnNames))
+ pListbox->append_text(rColumnName);
+
+ if (!aInitialSelection->isEmpty() && (aColumnNameSet.end() != aColumnNameSet.find(*aInitialSelection)))
+ // we can select the entry as specified in our field assignment array
+ pListbox->set_active_text(*aInitialSelection);
+ else
+ // try to restore the selection
+ if (aColumnNameSet.end() != aColumnNameSet.find(sSaveSelection))
+ // the old selection is a valid column name
+ pListbox->set_active_text(sSaveSelection);
+ else
+ // select the <none> entry
+ pListbox->set_active(0);
+ }
+
+ // adjust m_pImpl->aFieldAssignments
+ for (auto & fieldAssignment : m_pImpl->aFieldAssignments)
+ if (!fieldAssignment.isEmpty())
+ if (aColumnNameSet.end() == aColumnNameSet.find(fieldAssignment))
+ fieldAssignment.clear();
+ }
+
+ IMPL_LINK(AddressBookSourceDialog, OnFieldSelect, weld::ComboBox&, rListbox, void)
+ {
+ // the index of the affected list box in our array
+ sal_Int32 nListBoxIndex = rListbox.get_id(0).toInt32();
+ DBG_ASSERT(nListBoxIndex >= 0 && nListBoxIndex < FIELD_CONTROLS_VISIBLE,
+ "AddressBookSourceDialog::OnFieldScroll: invalid list box entry!");
+
+ // update the array where we remember the field selections
+ if (0 == rListbox.get_active())
+ // it's the "no field selection" entry
+ m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex].clear();
+ else
+ // it's a regular field entry
+ m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex] = rListbox.get_active_text();
+ }
+
+
+ void AddressBookSourceDialog::implScrollFields(sal_Int32 _nPos, bool _bAdjustFocus, bool _bAdjustScrollbar)
+ {
+ if (_nPos == m_pImpl->nFieldScrollPos)
+ // nothing to do
+ return;
+
+ // loop through our field control rows and do some adjustments
+ // for the new texts
+ auto pLeftLabelControl = m_pImpl->pFieldLabels.begin();
+ auto pRightLabelControl = pLeftLabelControl+1;
+ auto pLeftColumnLabel = m_pImpl->aFieldLabels.cbegin() + 2 * _nPos;
+ auto pRightColumnLabel = pLeftColumnLabel + 1;
+
+ // for the focus movement and the selection scroll
+ auto pLeftListControl = m_pImpl->pFields.begin();
+ auto pRightListControl = pLeftListControl + 1;
+
+ // for the focus movement
+ sal_Int32 nOldFocusRow = -1;
+ sal_Int32 nOldFocusColumn = 0;
+
+ // for the selection scroll
+ auto pLeftAssignment = m_pImpl->aFieldAssignments.cbegin() + 2 * _nPos;
+ auto pRightAssignment = pLeftAssignment + 1;
+
+ // loop
+ for (sal_Int32 i=0; i<FIELD_PAIRS_VISIBLE; ++i)
+ {
+ if ((*pLeftListControl)->has_focus())
+ {
+ nOldFocusRow = i;
+ nOldFocusColumn = 0;
+ }
+ else if ((*pRightListControl)->has_focus())
+ {
+ nOldFocusRow = i;
+ nOldFocusColumn = 1;
+ }
+
+ // the new texts of the label controls
+ (*pLeftLabelControl)->set_label(*pLeftColumnLabel);
+ (*pRightLabelControl)->set_label(*pRightColumnLabel);
+
+ // we may have to hide the controls in the right column, if we have no label text for it
+ // (which means we have an odd number of fields, though we forced our internal arrays to
+ // be even-sized for easier handling)
+ // (If sometimes we support an arbitrary number of field assignments, we would have to care for
+ // an invisible left hand side column, too. But right now, the left hand side controls are always
+ // visible)
+ bool bHideRightColumn = pRightColumnLabel->isEmpty();
+ (*pRightLabelControl)->set_visible(!bHideRightColumn);
+ (*pRightListControl)->set_visible(!bHideRightColumn);
+ // the new selections of the listboxes
+ implSelectField(pLeftListControl->get(), *pLeftAssignment);
+ implSelectField(pRightListControl->get(), *pRightAssignment);
+
+ // increment ...
+ if ( i < FIELD_PAIRS_VISIBLE - 1 )
+ { // (not in the very last round, here the +=2 could result in an invalid
+ // iterator position, which causes an abort in a non-product version
+ pLeftLabelControl += 2;
+ pRightLabelControl += 2;
+ pLeftColumnLabel += 2;
+ pRightColumnLabel += 2;
+
+ pLeftListControl += 2;
+ pRightListControl += 2;
+ pLeftAssignment += 2;
+ pRightAssignment += 2;
+ }
+ }
+
+ if (_bAdjustFocus && (nOldFocusRow >= 0))
+ { // we have to adjust the focus and one of the list boxes has the focus
+ sal_Int32 nDelta = m_pImpl->nFieldScrollPos - _nPos;
+ // the new row for the focus
+ sal_Int32 nNewFocusRow = nOldFocusRow + nDelta;
+ // normalize
+ nNewFocusRow = std::min(nNewFocusRow, sal_Int32(FIELD_PAIRS_VISIBLE - 1), ::std::less< sal_Int32 >());
+ nNewFocusRow = std::max(nNewFocusRow, sal_Int32(0), ::std::less< sal_Int32 >());
+ // set the new focus (in the same column)
+ m_pImpl->pFields[nNewFocusRow * 2 + nOldFocusColumn]->grab_focus();
+ }
+
+ m_pImpl->nFieldScrollPos = _nPos;
+
+ if (_bAdjustScrollbar)
+ m_xFieldScroller->vadjustment_set_value(m_pImpl->nFieldScrollPos);
+ }
+
+ void AddressBookSourceDialog::implSelectField(weld::ComboBox* pBox, const OUString& rText)
+ {
+ if (!rText.isEmpty())
+ // a valid field name
+ pBox->set_active_text(rText);
+ else
+ // no selection for this item
+ pBox->set_active(0);
+ }
+
+ IMPL_LINK_NOARG(AddressBookSourceDialog, OnDelayedInitialize, void*, void)
+ {
+ // load the initial data from the configuration
+ loadConfiguration();
+ resetTables();
+ // will reset the tables/fields implicitly
+
+ if ( !m_pImpl->bWorkingPersistent )
+ if ( m_pImpl->pFields[0] )
+ m_pImpl->pFields[0]->grab_focus();
+ }
+
+ IMPL_LINK(AddressBookSourceDialog, OnComboSelect, weld::ComboBox&, rBox, void)
+ {
+ if (&rBox == m_xDatasource.get())
+ resetTables();
+ else
+ resetFields();
+ }
+
+ IMPL_STATIC_LINK(AddressBookSourceDialog, OnComboGetFocus, weld::Widget&, rBox, void)
+ {
+ dynamic_cast<weld::ComboBox&>(rBox).save_value();
+ }
+
+ IMPL_LINK(AddressBookSourceDialog, OnComboLoseFocus, weld::Widget&, rControl, void)
+ {
+ weld::ComboBox& rBox = dynamic_cast<weld::ComboBox&>(rControl);
+ if (rBox.get_value_changed_from_saved())
+ {
+ if (&rBox == m_xDatasource.get())
+ resetTables();
+ else
+ resetFields();
+ }
+ }
+
+ IMPL_LINK_NOARG(AddressBookSourceDialog, OnOkClicked, weld::Button&, void)
+ {
+ OUString sSelectedDS = lcl_getSelectedDataSource(*m_xDatasource);
+ if ( m_pImpl->bWorkingPersistent )
+ {
+ m_pImpl->pConfigData->setDatasourceName(sSelectedDS);
+ m_pImpl->pConfigData->setCommand(m_xTable->get_active_text());
+ }
+
+ // AddressBookSourceDialog::loadConfiguration: inconsistence between field names and field assignments!
+ assert(m_pImpl->aLogicalFieldNames.size() == m_pImpl->aFieldAssignments.size());
+
+ // set the field assignments
+ auto aAssignment = m_pImpl->aFieldAssignments.cbegin();
+ for (auto const& logicalFieldName : m_pImpl->aLogicalFieldNames)
+ {
+ m_pImpl->pConfigData->setFieldAssignment(logicalFieldName, *aAssignment);
+ ++aAssignment;
+ }
+
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK_NOARG(AddressBookSourceDialog, OnAdministrateDatasources, weld::Button&, void)
+ {
+ // create the dialog object
+ Reference< XExecutableDialog > xAdminDialog;
+ try
+ {
+ xAdminDialog = AddressBookSourcePilot::createWithParent(m_xORB, m_xDialog->GetXWindow());
+ }
+ catch(const Exception&) { }
+ if (!xAdminDialog.is())
+ {
+ ShowServiceNotAvailableError(m_xDialog.get(), u"com.sun.star.ui.dialogs.AddressBookSourcePilot", true);
+ return;
+ }
+
+ // execute the dialog
+ try
+ {
+ if ( xAdminDialog->execute() == RET_OK )
+ {
+ Reference<XPropertySet> xProp(xAdminDialog,UNO_QUERY);
+ if ( xProp.is() )
+ {
+ OUString sName;
+ xProp->getPropertyValue("DataSourceName") >>= sName;
+
+ INetURLObject aURL( sName );
+ if( aURL.GetProtocol() != INetProtocol::NotValid )
+ {
+ OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ sName = aFileNotation.get(OFileNotation::N_SYSTEM);
+ }
+ m_xDatasource->append_text(sName);
+ m_pImpl->pConfigData.reset( new AssignmentPersistentData );
+ loadConfiguration();
+ resetTables();
+ // will reset the fields implicitly
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("AddressBookSourceDialog::OnAdministrateDatasources: an error occurred while executing the administration dialog!");
+ }
+
+ // re-fill the data source list
+ // try to preserve the current selection
+
+// initializeDatasources();
+ }
+
+} // namespace svt
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/dialogs/colrdlg.cxx b/svtools/source/dialogs/colrdlg.cxx
new file mode 100644
index 000000000..27008ccfc
--- /dev/null
+++ b/svtools/source/dialogs/colrdlg.cxx
@@ -0,0 +1,161 @@
+/* -*- 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 <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/cui/AsynchronousColorPicker.hpp>
+#include <com/sun/star/cui/ColorPicker.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+
+#include <svtools/colrdlg.hxx>
+#include <svtools/dialogclosedlistener.hxx>
+#include <vcl/weld.hxx>
+#include <osl/diagnose.h>
+
+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;
+
+const OUStringLiteral sColor = u"Color";
+
+SvColorDialog::SvColorDialog()
+ : meMode(svtools::ColorPickerMode::Select)
+{
+}
+
+SvColorDialog::~SvColorDialog()
+{
+}
+void SvColorDialog::SetColor( const Color& rColor )
+{
+ maColor = rColor;
+}
+
+void SvColorDialog::SetMode( svtools::ColorPickerMode eMode )
+{
+ meMode = eMode;
+}
+
+short SvColorDialog::Execute(weld::Window* pParent)
+{
+ short ret = 0;
+ try
+ {
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+
+ Reference<css::awt::XWindow> xParent;
+ if (pParent)
+ xParent = pParent->GetXWindow();
+
+ Reference< XExecutableDialog > xDialog = css::cui::ColorPicker::createWithParent(xContext, xParent);
+ Reference< XPropertyAccess > xPropertyAccess( xDialog, UNO_QUERY_THROW );
+
+ Sequence< PropertyValue > props{
+ comphelper::makePropertyValue(OUString( sColor ), maColor),
+ comphelper::makePropertyValue("Mode", static_cast<sal_Int16>(meMode))
+ };
+
+ xPropertyAccess->setPropertyValues( props );
+
+ ret = xDialog->execute();
+
+ if( ret )
+ {
+ props = xPropertyAccess->getPropertyValues();
+ for( const auto& rProp : std::as_const(props) )
+ {
+ if( rProp.Name == sColor )
+ {
+ rProp.Value >>= maColor;
+ }
+ }
+ }
+ }
+ catch(Exception&)
+ {
+ OSL_ASSERT(false);
+ }
+
+ return ret;
+}
+
+void SvColorDialog::ExecuteAsync(weld::Window* pParent, const std::function<void(sal_Int32)>& func)
+{
+ m_aResultFunc = func;
+
+ try
+ {
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+
+ Reference<css::awt::XWindow> xParent;
+ if (pParent)
+ xParent = pParent->GetXWindow();
+
+ mxDialog = css::cui::AsynchronousColorPicker::createWithParent(xContext, xParent);
+ Reference< XPropertyAccess > xPropertyAccess( mxDialog, UNO_QUERY_THROW );
+
+ Sequence< PropertyValue > props{
+ comphelper::makePropertyValue(OUString( sColor ), maColor),
+ comphelper::makePropertyValue("Mode", static_cast<sal_Int16>(meMode))
+ };
+
+ xPropertyAccess->setPropertyValues( props );
+
+ rtl::Reference< ::svt::DialogClosedListener > pListener = new ::svt::DialogClosedListener();
+ pListener->SetDialogClosedLink( LINK( this, SvColorDialog, DialogClosedHdl ) );
+
+ mxDialog->startExecuteModal( pListener );
+ }
+ catch(Exception&)
+ {
+ OSL_ASSERT(false);
+ }
+}
+
+IMPL_LINK( SvColorDialog, DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, pEvent, void )
+{
+ sal_Int32 nResult = 0;
+ sal_Int16 nDialogRet = pEvent->DialogResult;
+ if( nDialogRet == ExecutableDialogResults::OK )
+ {
+ nResult = RET_OK;
+
+ Reference< XPropertyAccess > xPropertyAccess( mxDialog, UNO_QUERY_THROW );
+ Sequence< PropertyValue > props = xPropertyAccess->getPropertyValues();
+
+ for( const auto& rProp : std::as_const(props) )
+ {
+ if( rProp.Name == sColor )
+ {
+ rProp.Value >>= maColor;
+ }
+ }
+ }
+
+ m_aResultFunc(nResult);
+ mxDialog.clear();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/dialogs/insdlg.cxx b/svtools/source/dialogs/insdlg.cxx
new file mode 100644
index 000000000..adaa1b905
--- /dev/null
+++ b/svtools/source/dialogs/insdlg.cxx
@@ -0,0 +1,356 @@
+/* -*- 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 <svtools/insdlg.hxx>
+#include <svtools/strings.hrc>
+#include <svtools/svtresid.hxx>
+
+#include <unotools/configmgr.hxx>
+#include <comphelper/classids.hxx>
+#include <sot/stg.hxx>
+#include <sal/macros.h>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+using namespace ::com::sun::star;
+
+#if defined _WIN32
+#include <prewin.h>
+#include <oleidl.h>
+#include <postwin.h>
+#else
+typedef Size SIZEL;
+typedef Point POINTL;
+#endif
+
+// this struct conforms to the Microsoft
+// OBJECTDESCRIPTOR -> see oleidl.h
+// (MS platform sdk)
+
+namespace {
+
+struct OleObjectDescriptor
+{
+ sal_uInt32 cbSize;
+ ClsId clsid;
+ sal_uInt32 dwDrawAspect;
+ SIZEL sizel;
+ POINTL pointl;
+ sal_uInt32 dwStatus;
+ sal_uInt32 dwFullUserTypeName;
+ sal_uInt32 dwSrcOfCopy;
+};
+
+#if defined _WIN32
+static_assert(sizeof(OleObjectDescriptor) == sizeof(OBJECTDESCRIPTOR));
+// check the two fields that we use here
+static_assert(offsetof(OleObjectDescriptor, dwFullUserTypeName)
+ == offsetof(OBJECTDESCRIPTOR, dwFullUserTypeName));
+static_assert(offsetof(OleObjectDescriptor, dwSrcOfCopy)
+ == offsetof(OBJECTDESCRIPTOR, dwSrcOfCopy));
+#endif
+
+}
+
+/********************** SvObjectServerList ********************************
+**************************************************************************/
+
+const SvObjectServer * SvObjectServerList::Get( std::u16string_view rHumanName ) const
+{
+ for(const auto & i : aObjectServerList)
+ {
+ if( rHumanName == i.GetHumanName() )
+ return &i;
+ }
+ return nullptr;
+}
+
+const SvObjectServer * SvObjectServerList::Get( const SvGlobalName & rName ) const
+{
+ for(const auto & i : aObjectServerList)
+ {
+ if( rName == i.GetClassName() )
+ return &i;
+ }
+ return nullptr;
+}
+
+void SvObjectServerList::Remove( const SvGlobalName & rName )
+{
+ aObjectServerList.erase(std::remove_if(aObjectServerList.begin(), aObjectServerList.end(),
+ [rName](const SvObjectServer& rServer) { return rServer.GetClassName() == rName; }),
+ aObjectServerList.end());
+}
+
+
+void SvObjectServerList::FillInsertObjects()
+/* [Description]
+
+ The list is filled with all types which can be selected in the insert-dialog.
+*/
+{
+ try{
+ uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
+
+ uno::Reference< lang::XMultiServiceFactory > sProviderMSFactory =
+ configuration::theDefaultProvider::get(xContext);
+
+ uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", uno::Any(OUString( "/org.openoffice.Office.Embedding/ObjectNames" ))}
+ }));
+ uno::Reference< container::XNameAccess > xNameAccess(
+ sProviderMSFactory->createInstanceWithArguments( "com.sun.star.configuration.ConfigurationAccess", aArguments ),
+ uno::UNO_QUERY );
+
+ if( xNameAccess.is())
+ {
+ const uno::Sequence< OUString > seqNames= xNameAccess->getElementNames();
+
+ OUString aStringProductName( "%PRODUCTNAME" );
+ sal_Int32 nStringProductNameLength = aStringProductName.getLength();
+
+ OUString aStringProductVersion( "%PRODUCTVERSION" );
+ sal_Int32 nStringProductVersionLength = aStringProductVersion.getLength();
+
+ for( const auto& rName : seqNames )
+ {
+ uno::Reference< container::XNameAccess > xEntry ;
+ xNameAccess->getByName( rName ) >>= xEntry;
+ if ( xEntry.is() )
+ {
+ OUString aUIName;
+ OUString aClassID;
+ xEntry->getByName("ObjectUIName") >>= aUIName;
+ xEntry->getByName("ClassID") >>= aClassID;
+
+ if ( !aUIName.isEmpty() )
+ {
+ // replace %PRODUCTNAME
+ sal_Int32 nIndex = aUIName.indexOf( aStringProductName );
+ while( nIndex != -1 )
+ {
+ aUIName = aUIName.replaceAt(
+ nIndex, nStringProductNameLength,
+ utl::ConfigManager::getProductName() );
+ nIndex = aUIName.indexOf( aStringProductName );
+ }
+
+ // replace %PRODUCTVERSION
+ nIndex = aUIName.indexOf( aStringProductVersion );
+ while( nIndex != -1 )
+ {
+ aUIName = aUIName.replaceAt(
+ nIndex, nStringProductVersionLength,
+ utl::ConfigManager::getProductVersion() );
+ nIndex = aUIName.indexOf( aStringProductVersion );
+ }
+ }
+
+ SvGlobalName aClassName;
+ if( aClassName.MakeId( aClassID) )
+ {
+ if( !Get( aClassName ) )
+ // not entered yet
+ aObjectServerList.emplace_back( aClassName, aUIName );
+ }
+ }
+ }
+ }
+
+
+#ifdef _WIN32
+ SvGlobalName aOleFact( SO3_OUT_CLASSID );
+ OUString aOleObj( SvtResId( STR_FURTHER_OBJECT ) );
+ aObjectServerList.push_back( SvObjectServer( aOleFact, aOleObj ) );
+#endif
+
+ }catch(const container::NoSuchElementException&)
+ {
+ }catch(const uno::Exception&)
+ {
+ }
+ catch(...)
+ {
+ }
+}
+
+OUString SvPasteObjectHelper::GetSotFormatUIName( SotClipboardFormatId nId )
+{
+ struct SotResourcePair
+ {
+ SotClipboardFormatId mnSotId;
+ TranslateId mpResId;
+ };
+
+ static const SotResourcePair aSotResourcePairs[] =
+ {
+ { SotClipboardFormatId::STRING, STR_FORMAT_STRING },
+ { SotClipboardFormatId::BITMAP, STR_FORMAT_BITMAP },
+ { SotClipboardFormatId::GDIMETAFILE, STR_FORMAT_GDIMETAFILE },
+ { SotClipboardFormatId::RTF, STR_FORMAT_RTF },
+ { SotClipboardFormatId::DRAWING, STR_FORMAT_ID_DRAWING },
+ { SotClipboardFormatId::SVXB, STR_FORMAT_ID_SVXB },
+ { SotClipboardFormatId::INTERNALLINK_STATE, STR_FORMAT_ID_INTERNALLINK_STATE },
+ { SotClipboardFormatId::SOLK, STR_FORMAT_ID_SOLK },
+ { SotClipboardFormatId::NETSCAPE_BOOKMARK, STR_FORMAT_ID_NETSCAPE_BOOKMARK },
+ { SotClipboardFormatId::STARSERVER, STR_FORMAT_ID_STARSERVER },
+ { SotClipboardFormatId::STAROBJECT, STR_FORMAT_ID_STAROBJECT },
+ { SotClipboardFormatId::APPLETOBJECT, STR_FORMAT_ID_APPLETOBJECT },
+ { SotClipboardFormatId::PLUGIN_OBJECT, STR_FORMAT_ID_PLUGIN_OBJECT },
+ { SotClipboardFormatId::STARWRITER_30, STR_FORMAT_ID_STARWRITER_30 },
+ { SotClipboardFormatId::STARWRITER_40, STR_FORMAT_ID_STARWRITER_40 },
+ { SotClipboardFormatId::STARWRITER_50, STR_FORMAT_ID_STARWRITER_50 },
+ { SotClipboardFormatId::STARWRITERWEB_40, STR_FORMAT_ID_STARWRITERWEB_40 },
+ { SotClipboardFormatId::STARWRITERWEB_50, STR_FORMAT_ID_STARWRITERWEB_50 },
+ { SotClipboardFormatId::STARWRITERGLOB_40, STR_FORMAT_ID_STARWRITERGLOB_40 },
+ { SotClipboardFormatId::STARWRITERGLOB_50, STR_FORMAT_ID_STARWRITERGLOB_50 },
+ { SotClipboardFormatId::STARDRAW, STR_FORMAT_ID_STARDRAW },
+ { SotClipboardFormatId::STARDRAW_40, STR_FORMAT_ID_STARDRAW_40 },
+ { SotClipboardFormatId::STARIMPRESS_50, STR_FORMAT_ID_STARIMPRESS_50 },
+ { SotClipboardFormatId::STARDRAW_50, STR_FORMAT_ID_STARDRAW_50 },
+ { SotClipboardFormatId::STARCALC, STR_FORMAT_ID_STARCALC },
+ { SotClipboardFormatId::STARCALC_40, STR_FORMAT_ID_STARCALC_40 },
+ { SotClipboardFormatId::STARCALC_50, STR_FORMAT_ID_STARCALC_50 },
+ { SotClipboardFormatId::STARCHART, STR_FORMAT_ID_STARCHART },
+ { SotClipboardFormatId::STARCHART_40, STR_FORMAT_ID_STARCHART_40 },
+ { SotClipboardFormatId::STARCHART_50, STR_FORMAT_ID_STARCHART_50 },
+ { SotClipboardFormatId::STARIMAGE, STR_FORMAT_ID_STARIMAGE },
+ { SotClipboardFormatId::STARIMAGE_40, STR_FORMAT_ID_STARIMAGE_40 },
+ { SotClipboardFormatId::STARIMAGE_50, STR_FORMAT_ID_STARIMAGE_50 },
+ { SotClipboardFormatId::STARMATH, STR_FORMAT_ID_STARMATH },
+ { SotClipboardFormatId::STARMATH_40, STR_FORMAT_ID_STARMATH_40 },
+ { SotClipboardFormatId::STARMATH_50, STR_FORMAT_ID_STARMATH_50 },
+ { SotClipboardFormatId::STAROBJECT_PAINTDOC, STR_FORMAT_ID_STAROBJECT_PAINTDOC },
+ { SotClipboardFormatId::HTML, STR_FORMAT_ID_HTML },
+ { SotClipboardFormatId::HTML_SIMPLE, STR_FORMAT_ID_HTML_SIMPLE },
+ { SotClipboardFormatId::BIFF_5, STR_FORMAT_ID_BIFF_5 },
+ { SotClipboardFormatId::BIFF_8, STR_FORMAT_ID_BIFF_8 },
+ { SotClipboardFormatId::SYLK, STR_FORMAT_ID_SYLK },
+ { SotClipboardFormatId::LINK, STR_FORMAT_ID_LINK },
+ { SotClipboardFormatId::DIF, STR_FORMAT_ID_DIF },
+ { SotClipboardFormatId::MSWORD_DOC, STR_FORMAT_ID_MSWORD_DOC },
+ { SotClipboardFormatId::STAR_FRAMESET_DOC, STR_FORMAT_ID_STAR_FRAMESET_DOC },
+ { SotClipboardFormatId::OFFICE_DOC, STR_FORMAT_ID_OFFICE_DOC },
+ { SotClipboardFormatId::NOTES_DOCINFO, STR_FORMAT_ID_NOTES_DOCINFO },
+ { SotClipboardFormatId::SFX_DOC, STR_FORMAT_ID_SFX_DOC },
+ { SotClipboardFormatId::STARCHARTDOCUMENT_50,STR_FORMAT_ID_STARCHARTDOCUMENT_50 },
+ { SotClipboardFormatId::GRAPHOBJ, STR_FORMAT_ID_GRAPHOBJ },
+ { SotClipboardFormatId::STARWRITER_60, STR_FORMAT_ID_STARWRITER_60 },
+ { SotClipboardFormatId::STARWRITERWEB_60, STR_FORMAT_ID_STARWRITERWEB_60 },
+ { SotClipboardFormatId::STARWRITERGLOB_60, STR_FORMAT_ID_STARWRITERGLOB_60 },
+ { SotClipboardFormatId::STARDRAW_60, STR_FORMAT_ID_STARDRAW_60 },
+ { SotClipboardFormatId::STARIMPRESS_60, STR_FORMAT_ID_STARIMPRESS_60 },
+ { SotClipboardFormatId::STARCALC_60, STR_FORMAT_ID_STARCALC_60 },
+ { SotClipboardFormatId::STARCHART_60, STR_FORMAT_ID_STARCHART_60 },
+ { SotClipboardFormatId::STARMATH_60, STR_FORMAT_ID_STARMATH_60 },
+ { SotClipboardFormatId::WMF, STR_FORMAT_ID_WMF },
+ { SotClipboardFormatId::DBACCESS_QUERY, STR_FORMAT_ID_DBACCESS_QUERY },
+ { SotClipboardFormatId::DBACCESS_TABLE, STR_FORMAT_ID_DBACCESS_TABLE },
+ { SotClipboardFormatId::DBACCESS_COMMAND, STR_FORMAT_ID_DBACCESS_COMMAND },
+ { SotClipboardFormatId::DIALOG_60, STR_FORMAT_ID_DIALOG_60 },
+ { SotClipboardFormatId::FILEGRPDESCRIPTOR, STR_FORMAT_ID_FILEGRPDESCRIPTOR },
+ { SotClipboardFormatId::HTML_NO_COMMENT, STR_FORMAT_ID_HTML_NO_COMMENT },
+ { SotClipboardFormatId::RICHTEXT, STR_FORMAT_ID_RICHTEXT },
+ { SotClipboardFormatId::STRING_TSVC, STR_FORMAT_ID_STRING_TSVC },
+ { SotClipboardFormatId::PNG, STR_FORMAT_ID_PNG_BITMAP },
+ };
+
+ TranslateId pResId;
+
+ sal_uInt32 const nCount = SAL_N_ELEMENTS( aSotResourcePairs );
+ for (sal_uInt32 i = 0; ( i < nCount ) && !pResId; ++i)
+ {
+ if( aSotResourcePairs[ i ].mnSotId == nId )
+ pResId = aSotResourcePairs[ i ].mpResId;
+ }
+
+ OUString aUIName;
+ if (pResId)
+ aUIName = SvtResId(pResId);
+ else
+ aUIName = SotExchange::GetFormatName( nId );
+
+ return aUIName;
+}
+
+bool SvPasteObjectHelper::GetEmbeddedName(const TransferableDataHelper& rData, OUString& _rName, OUString& _rSource, SotClipboardFormatId const & _nFormat)
+{
+ if( _nFormat != SotClipboardFormatId::EMBED_SOURCE_OLE && _nFormat != SotClipboardFormatId::EMBEDDED_OBJ_OLE )
+ return false;
+
+ datatransfer::DataFlavor aFlavor;
+ SotExchange::GetFormatDataFlavor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE, aFlavor );
+
+ if( !rData.HasFormat( aFlavor ) )
+ return false;
+
+ uno::Any aAny = rData.GetAny(aFlavor, OUString());
+ if (!aAny.hasValue())
+ return false;
+
+ uno::Sequence< sal_Int8 > anySequence;
+ aAny >>= anySequence;
+
+ OleObjectDescriptor* pOleObjDescr =
+ reinterpret_cast< OleObjectDescriptor* >( anySequence.getArray( ) );
+
+ // determine the user friendly description of the embedded object
+ if ( pOleObjDescr->dwFullUserTypeName )
+ {
+ // we set the pointer to the start of user friendly description
+ // string. it starts at &OleObjectDescriptor + dwFullUserTypeName.
+ // dwFullUserTypeName is the offset in bytes.
+ // the user friendly description string is '\0' terminated.
+ const sal_Unicode* pUserTypeName =
+ reinterpret_cast< sal_Unicode* >(
+ reinterpret_cast< char* >( pOleObjDescr ) +
+ pOleObjDescr->dwFullUserTypeName );
+
+ _rName += pUserTypeName;
+ // the following statement was here for historical reasons, it is commented out since it causes bug i49460
+ // _nFormat = SotClipboardFormatId::EMBED_SOURCE_OLE;
+ }
+
+ // determine the source of the embedded object
+ if ( pOleObjDescr->dwSrcOfCopy )
+ {
+ // we set the pointer to the start of source string
+ // it starts at &OleObjectDescriptor + dwSrcOfCopy.
+ // dwSrcOfCopy is the offset in bytes.
+ // the source string is '\0' terminated.
+ const sal_Unicode* pSrcOfCopy =
+ reinterpret_cast< sal_Unicode* >(
+ reinterpret_cast< char* >( pOleObjDescr ) +
+ pOleObjDescr->dwSrcOfCopy );
+
+ _rSource += pSrcOfCopy;
+ }
+ else
+ _rSource = SvtResId(STR_UNKNOWN_SOURCE);
+
+ return true;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/dialogs/prnsetup.cxx b/svtools/source/dialogs/prnsetup.cxx
new file mode 100644
index 000000000..60dba4348
--- /dev/null
+++ b/svtools/source/dialogs/prnsetup.cxx
@@ -0,0 +1,351 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <svtools/prnsetup.hxx>
+#include <svtools/strings.hrc>
+#include <svtools/svtresid.hxx>
+#include <vcl/QueueInfo.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/print.hxx>
+#include <vcl/event.hxx>
+#include <sal/log.hxx>
+
+void ImplFillPrnDlgListBox( const Printer* pPrinter,
+ weld::ComboBox* pBox, weld::Button* pPropBtn )
+{
+ ImplFreePrnDlgListBox( pBox );
+
+ const std::vector<OUString>& rPrinters = Printer::GetPrinterQueues();
+ unsigned int nCount = rPrinters.size();
+ if ( nCount )
+ {
+ for( unsigned int i = 0; i < nCount; i++ )
+ pBox->append_text( rPrinters[i] );
+ pBox->set_active_text(pPrinter->GetName());
+ }
+
+ pBox->set_sensitive(nCount != 0);
+ pPropBtn->set_visible( pPrinter->HasSupport( PrinterSupport::SetupDialog ) );
+}
+
+
+void ImplFreePrnDlgListBox( weld::ComboBox* pBox, bool bClear )
+{
+ if ( bClear )
+ pBox->clear();
+}
+
+
+Printer* ImplPrnDlgListBoxSelect( const weld::ComboBox* pBox, weld::Button* pPropBtn,
+ Printer const * pPrinter, Printer* pTempPrinterIn )
+{
+ VclPtr<Printer> pTempPrinter( pTempPrinterIn );
+ if ( pBox->get_active() != -1 )
+ {
+ const QueueInfo* pInfo = Printer::GetQueueInfo( pBox->get_active_text(), true );
+ if( pInfo)
+ {
+ if ( !pTempPrinter )
+ {
+ if ( (pPrinter->GetName() == pInfo->GetPrinterName()) &&
+ (pPrinter->GetDriverName() == pInfo->GetDriver()) )
+ pTempPrinter = VclPtr<Printer>::Create( pPrinter->GetJobSetup() );
+ else
+ pTempPrinter = VclPtr<Printer>::Create( *pInfo );
+ }
+ else
+ {
+ if ( (pTempPrinter->GetName() != pInfo->GetPrinterName()) ||
+ (pTempPrinter->GetDriverName() != pInfo->GetDriver()) )
+ {
+ pTempPrinter.disposeAndClear();
+ pTempPrinter = VclPtr<Printer>::Create( *pInfo );
+ }
+ }
+
+ pPropBtn->set_sensitive(pTempPrinter->HasSupport(PrinterSupport::SetupDialog));
+ }
+ else
+ pPropBtn->set_sensitive(false);
+ }
+ else
+ pPropBtn->set_sensitive(false);
+
+ return pTempPrinter;
+}
+
+
+Printer* ImplPrnDlgUpdatePrinter( Printer const * pPrinter, Printer* pTempPrinterIn )
+{
+ VclPtr<Printer> pTempPrinter( pTempPrinterIn );
+ OUString aPrnName;
+ if ( pTempPrinter )
+ aPrnName = pTempPrinter->GetName();
+ else
+ aPrnName = pPrinter->GetName();
+
+ if ( ! Printer::GetQueueInfo( aPrnName, false ) )
+ {
+ pTempPrinter.disposeAndClear();
+ pTempPrinter = VclPtr<Printer>::Create();
+ }
+
+ return pTempPrinter;
+}
+
+
+void ImplPrnDlgUpdateQueueInfo( const weld::ComboBox* pBox, QueueInfo& rInfo )
+{
+ if ( pBox->get_active() != -1 )
+ {
+ const QueueInfo* pInfo = Printer::GetQueueInfo( pBox->get_active_text(), true );
+ if( pInfo )
+ rInfo = *pInfo;
+ }
+}
+
+
+static OUString ImplPrnDlgAddString(const OUString& rStr, std::u16string_view rAddStr)
+{
+ OUString aStr(rStr);
+ if (!aStr.isEmpty())
+ aStr += "; " ;
+ return aStr + rAddStr;
+}
+
+
+static OUString ImplPrnDlgAddResString(const OUString& rStr, TranslateId pResId)
+{
+ return ImplPrnDlgAddString(rStr, SvtResId(pResId));
+}
+
+
+OUString ImplPrnDlgGetStatusText( const QueueInfo& rInfo )
+{
+ OUString aStr;
+ PrintQueueFlags nStatus = rInfo.GetStatus();
+
+ // Default-Printer
+ if ( !rInfo.GetPrinterName().isEmpty() &&
+ (rInfo.GetPrinterName() == Printer::GetDefaultPrinterName()) )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_DEFPRINTER );
+
+ // Status
+ if ( nStatus & PrintQueueFlags::Ready )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_READY );
+ if ( nStatus & PrintQueueFlags::Paused )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PAUSED );
+ if ( nStatus & PrintQueueFlags::PendingDeletion )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PENDING );
+ if ( nStatus & PrintQueueFlags::Busy )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_BUSY );
+ if ( nStatus & PrintQueueFlags::Initializing )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_INITIALIZING );
+ if ( nStatus & PrintQueueFlags::Waiting )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_WAITING );
+ if ( nStatus & PrintQueueFlags::WarmingUp )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_WARMING_UP );
+ if ( nStatus & PrintQueueFlags::Processing )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PROCESSING );
+ if ( nStatus & PrintQueueFlags::Printing )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PRINTING );
+ if ( nStatus & PrintQueueFlags::Offline )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_OFFLINE );
+ if ( nStatus & PrintQueueFlags::Error )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_ERROR );
+ if ( nStatus & PrintQueueFlags::StatusUnknown )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_SERVER_UNKNOWN );
+ if ( nStatus & PrintQueueFlags::PaperJam )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PAPER_JAM );
+ if ( nStatus & PrintQueueFlags::PaperOut )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PAPER_OUT );
+ if ( nStatus & PrintQueueFlags::ManualFeed )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_MANUAL_FEED );
+ if ( nStatus & PrintQueueFlags::PaperProblem )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PAPER_PROBLEM );
+ if ( nStatus & PrintQueueFlags::IOActive )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_IO_ACTIVE );
+ if ( nStatus & PrintQueueFlags::OutputBinFull )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_OUTPUT_BIN_FULL );
+ if ( nStatus & PrintQueueFlags::TonerLow )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_TONER_LOW );
+ if ( nStatus & PrintQueueFlags::NoToner )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_NO_TONER );
+ if ( nStatus & PrintQueueFlags::PagePunt )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PAGE_PUNT );
+ if ( nStatus & PrintQueueFlags::UserIntervention )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_USER_INTERVENTION );
+ if ( nStatus & PrintQueueFlags::OutOfMemory )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_OUT_OF_MEMORY );
+ if ( nStatus & PrintQueueFlags::DoorOpen )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_DOOR_OPEN );
+ if ( nStatus & PrintQueueFlags::PowerSave )
+ aStr = ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_POWER_SAVE );
+
+ // Number of jobs
+ sal_uInt32 nJobs = rInfo.GetJobs();
+ if ( nJobs && (nJobs != QUEUE_JOBS_DONTKNOW) )
+ {
+ OUString aJobStr( SvtResId( STR_SVT_PRNDLG_JOBCOUNT ) );
+ OUString aJobs( OUString::number( nJobs ) );
+ aStr = ImplPrnDlgAddString(aStr, aJobStr.replaceAll("%d", aJobs));
+ }
+
+ return aStr;
+}
+
+PrinterSetupDialog::PrinterSetupDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "svt/ui/printersetupdialog.ui", "PrinterSetupDialog")
+ , m_xLbName(m_xBuilder->weld_combo_box("name"))
+ , m_xBtnProperties(m_xBuilder->weld_button("properties"))
+ , m_xBtnOptions(m_xBuilder->weld_button("options"))
+ , m_xFiStatus(m_xBuilder->weld_label("status"))
+ , m_xFiType(m_xBuilder->weld_label("type"))
+ , m_xFiLocation(m_xBuilder->weld_label("location"))
+ , m_xFiComment(m_xBuilder->weld_label("comment"))
+ , maStatusTimer("PrinterSetupDialog maStatusTimer")
+{
+ m_xLbName->make_sorted();
+
+ // show options button only if link is set
+ m_xBtnOptions->hide();
+
+ mpPrinter = nullptr;
+ mpTempPrinter = nullptr;
+
+ maStatusTimer.SetTimeout( IMPL_PRINTDLG_STATUS_UPDATE );
+ maStatusTimer.SetInvokeHandler( LINK( this, PrinterSetupDialog, ImplStatusHdl ) );
+ m_xBtnProperties->connect_clicked( LINK( this, PrinterSetupDialog, ImplPropertiesHdl ) );
+ m_xLbName->connect_changed( LINK( this, PrinterSetupDialog, ImplChangePrinterHdl ) );
+ m_xDialog->connect_focus_in( LINK( this, PrinterSetupDialog, ImplGetFocusHdl ) );
+ Application::AddEventListener(LINK( this, PrinterSetupDialog, ImplDataChangedHdl ) );
+}
+
+PrinterSetupDialog::~PrinterSetupDialog()
+{
+ Application::RemoveEventListener(LINK( this, PrinterSetupDialog, ImplDataChangedHdl ) );
+ ImplFreePrnDlgListBox(m_xLbName.get(), false);
+}
+
+void PrinterSetupDialog::SetOptionsHdl(const Link<weld::Button&, void>& rLink)
+{
+ m_xBtnOptions->connect_clicked(rLink);
+ m_xBtnOptions->set_accessible_description(SvtResId(STR_A11Y_DESC_OPTIONS));
+ m_xBtnOptions->set_visible(rLink.IsSet());
+}
+
+void PrinterSetupDialog::ImplSetInfo()
+{
+ const QueueInfo* pInfo = Printer::GetQueueInfo(m_xLbName->get_active_text(), true);
+ if ( pInfo )
+ {
+ m_xFiType->set_label( pInfo->GetDriver() );
+ m_xFiLocation->set_label( pInfo->GetLocation() );
+ m_xFiComment->set_label( pInfo->GetComment() );
+ m_xFiStatus->set_label( ImplPrnDlgGetStatusText( *pInfo ) );
+ }
+ else
+ {
+ const OUString aTempStr;
+ m_xFiType->set_label( aTempStr );
+ m_xFiLocation->set_label( aTempStr );
+ m_xFiComment->set_label( aTempStr );
+ m_xFiStatus->set_label( aTempStr );
+ }
+}
+
+IMPL_LINK_NOARG(PrinterSetupDialog, ImplStatusHdl, Timer *, void)
+{
+ QueueInfo aInfo;
+ ImplPrnDlgUpdateQueueInfo(m_xLbName.get(), aInfo);
+ m_xFiStatus->set_label( ImplPrnDlgGetStatusText( aInfo ) );
+}
+
+
+IMPL_LINK_NOARG(PrinterSetupDialog, ImplPropertiesHdl, weld::Button&, void)
+{
+ if ( !mpTempPrinter )
+ mpTempPrinter = VclPtr<Printer>::Create( mpPrinter->GetJobSetup() );
+ mpTempPrinter->Setup(m_xDialog.get());
+}
+
+IMPL_LINK_NOARG(PrinterSetupDialog, ImplChangePrinterHdl, weld::ComboBox&, void)
+{
+ mpTempPrinter = ImplPrnDlgListBoxSelect(m_xLbName.get(), m_xBtnProperties.get(),
+ mpPrinter, mpTempPrinter);
+ ImplSetInfo();
+}
+
+IMPL_LINK(PrinterSetupDialog, ImplGetFocusHdl, weld::Widget&, rWidget, void)
+{
+ if (rWidget.is_visible())
+ ImplStatusHdl(&maStatusTimer);
+}
+
+IMPL_LINK(PrinterSetupDialog, ImplDataChangedHdl, VclSimpleEvent&, rEvt, void)
+{
+ VclEventId nEvent = rEvt.GetId();
+ if (nEvent != VclEventId::ApplicationDataChanged)
+ return;
+
+ DataChangedEvent* pData = static_cast<DataChangedEvent*>(static_cast<VclWindowEvent&>(rEvt).GetData());
+ if (!pData || pData->GetType() != DataChangedEventType::PRINTER)
+ return;
+
+ mpTempPrinter = ImplPrnDlgUpdatePrinter(mpPrinter, mpTempPrinter);
+ Printer* pPrn;
+ if (mpTempPrinter)
+ pPrn = mpTempPrinter;
+ else
+ pPrn = mpPrinter;
+ ImplFillPrnDlgListBox(pPrn, m_xLbName.get(), m_xBtnProperties.get());
+ ImplSetInfo();
+}
+
+short PrinterSetupDialog::run()
+{
+ if ( !mpPrinter || mpPrinter->IsPrinting() || mpPrinter->IsJobActive() )
+ {
+ SAL_WARN( "svtools.dialogs", "PrinterSetupDialog::execute() - No Printer or printer is printing" );
+ return RET_CANCEL;
+ }
+
+ Printer::updatePrinters();
+
+ ImplFillPrnDlgListBox(mpPrinter, m_xLbName.get(), m_xBtnProperties.get());
+ ImplSetInfo();
+ maStatusTimer.Start();
+
+ // start dialog
+ short nRet = GenericDialogController::run();
+
+ // update data if the dialog was terminated with OK
+ if ( nRet == RET_OK && mpTempPrinter )
+ mpPrinter->SetPrinterProps( mpTempPrinter );
+
+ maStatusTimer.Stop();
+
+ return nRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/dialogs/restartdialog.cxx b/svtools/source/dialogs/restartdialog.cxx
new file mode 100644
index 000000000..30954f176
--- /dev/null
+++ b/svtools/source/dialogs/restartdialog.cxx
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <cassert>
+
+#include <com/sun/star/task/OfficeRestartManager.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <svtools/restartdialog.hxx>
+#include <tools/link.hxx>
+#include <vcl/weld.hxx>
+
+namespace {
+
+class RestartDialog : public weld::GenericDialogController{
+public:
+ RestartDialog(weld::Window* parent, svtools::RestartReason reason)
+ : GenericDialogController(parent, "svt/ui/restartdialog.ui", "RestartDialog")
+ , btnYes_(m_xBuilder->weld_button("yes"))
+ , btnNo_(m_xBuilder->weld_button("no"))
+ {
+ switch (reason) {
+ case svtools::RESTART_REASON_JAVA:
+ reason_ = m_xBuilder->weld_widget("reason_java");
+ break;
+ case svtools::RESTART_REASON_PDF_AS_STANDARD_JOB_FORMAT:
+ reason_ = m_xBuilder->weld_widget("reason_pdf");
+ break;
+ case svtools::RESTART_REASON_BIBLIOGRAPHY_INSTALL:
+ reason_ = m_xBuilder->weld_widget("reason_bibliography_install");
+ break;
+ case svtools::RESTART_REASON_MAILMERGE_INSTALL:
+ reason_ = m_xBuilder->weld_widget("reason_mailmerge_install");
+ break;
+ case svtools::RESTART_REASON_LANGUAGE_CHANGE:
+ reason_ = m_xBuilder->weld_widget("reason_language_change");
+ break;
+ case svtools::RESTART_REASON_ADDING_PATH:
+ reason_ = m_xBuilder->weld_widget("reason_adding_path");
+ break;
+ case svtools::RESTART_REASON_ASSIGNING_JAVAPARAMETERS:
+ reason_ = m_xBuilder->weld_widget("reason_assigning_javaparameters");
+ break;
+ case svtools::RESTART_REASON_ASSIGNING_FOLDERS:
+ reason_ = m_xBuilder->weld_widget("reason_assigning_folders");
+ break;
+ case svtools::RESTART_REASON_EXP_FEATURES:
+ reason_ = m_xBuilder->weld_widget("reason_exp_features");
+ break;
+ case svtools::RESTART_REASON_EXTENSION_INSTALL:
+ reason_ = m_xBuilder->weld_widget("reason_extension_install");
+ break;
+ case svtools::RESTART_REASON_SKIA:
+ reason_ = m_xBuilder->weld_widget("reason_skia");
+ break;
+ case svtools::RESTART_REASON_OPENCL:
+ reason_ = m_xBuilder->weld_widget("reason_opencl");
+ break;
+ case svtools::RESTART_REASON_THREADING:
+ reason_ = m_xBuilder->weld_widget("reason_threading");
+ break;
+ case svtools::RESTART_REASON_MSCOMPATIBLE_FORMS_MENU:
+ reason_ = m_xBuilder->weld_widget("reason_mscompatible_formsmenu");
+ break;
+ case svtools::RESTART_REASON_SAVE:
+ reason_ = m_xBuilder->weld_widget("reason_save");
+ break;
+ case svtools::RESTART_REASON_UI_CHANGE:
+ reason_ = m_xBuilder->weld_widget("reason_uichange");
+ break;
+ default:
+ assert(false); // this cannot happen
+ }
+ reason_->show();
+ btnYes_->connect_clicked(LINK(this, RestartDialog, hdlYes));
+ btnNo_->connect_clicked(LINK(this, RestartDialog, hdlNo));
+ }
+private:
+ DECL_LINK(hdlYes, weld::Button&, void);
+ DECL_LINK(hdlNo, weld::Button&, void);
+
+ std::unique_ptr<weld::Widget> reason_;
+ std::unique_ptr<weld::Button> btnYes_;
+ std::unique_ptr<weld::Button> btnNo_;
+};
+
+IMPL_LINK_NOARG(RestartDialog, hdlYes, weld::Button&, void)
+{
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(RestartDialog, hdlNo, weld::Button&, void)
+{
+ m_xDialog->response(RET_CANCEL);
+}
+
+}
+
+bool svtools::executeRestartDialog(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ weld::Window* parent, RestartReason reason)
+{
+ auto xRestartManager = css::task::OfficeRestartManager::get(context);
+ if (xRestartManager->isRestartRequested(false))
+ return true; // don't try to show another dialog when restart is already in progress
+ RestartDialog aDlg(parent, reason);
+ if (aDlg.run()) {
+ xRestartManager->requestRestart(
+ css::uno::Reference< css::task::XInteractionHandler >());
+ return true;
+ }
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */