summaryrefslogtreecommitdiffstats
path: root/toolkit/source/helper
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 /toolkit/source/helper
parentInitial commit. (diff)
downloadlibreoffice-upstream/4%7.4.7.tar.xz
libreoffice-upstream/4%7.4.7.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 'toolkit/source/helper')
-rw-r--r--toolkit/source/helper/accessibilityclient.cxx232
-rw-r--r--toolkit/source/helper/btndlg.cxx304
-rw-r--r--toolkit/source/helper/formpdfexport.cxx789
-rw-r--r--toolkit/source/helper/imagealign.cxx128
-rw-r--r--toolkit/source/helper/listenermultiplexer.cxx242
-rw-r--r--toolkit/source/helper/property.cxx380
-rw-r--r--toolkit/source/helper/servicenames.cxx24
-rw-r--r--toolkit/source/helper/tkresmgr.cxx57
-rw-r--r--toolkit/source/helper/unopropertyarrayhelper.cxx148
-rw-r--r--toolkit/source/helper/unowrapper.cxx314
-rw-r--r--toolkit/source/helper/vclunohelper.cxx608
11 files changed, 3226 insertions, 0 deletions
diff --git a/toolkit/source/helper/accessibilityclient.cxx b/toolkit/source/helper/accessibilityclient.cxx
new file mode 100644
index 000000000..773bc9bfb
--- /dev/null
+++ b/toolkit/source/helper/accessibilityclient.cxx
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_feature_desktop.h>
+#include <config_wasm_strip.h>
+
+#include <sal/config.h>
+
+#include <toolkit/helper/accessiblefactory.hxx>
+#include <osl/module.h>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include <rtl/ref.hxx>
+#include <tools/svlibrary.h>
+
+#include <helper/accessibilityclient.hxx>
+
+namespace toolkit
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::accessibility;
+
+ namespace
+ {
+#ifndef DISABLE_DYNLOADING
+ oslModule s_hAccessibleImplementationModule = nullptr;
+#endif
+#if HAVE_FEATURE_DESKTOP
+#if !ENABLE_WASM_STRIP_ACCESSIBILITY
+ GetStandardAccComponentFactory s_pAccessibleFactoryFunc = nullptr;
+#endif
+#endif
+ ::rtl::Reference< IAccessibleFactory > s_pFactory;
+ }
+
+
+ //= AccessibleDummyFactory
+
+ namespace {
+
+ class AccessibleDummyFactory:
+ public IAccessibleFactory
+ {
+ public:
+ AccessibleDummyFactory();
+ AccessibleDummyFactory(const AccessibleDummyFactory&) = delete;
+ AccessibleDummyFactory& operator=(const AccessibleDummyFactory&) = delete;
+
+ protected:
+ virtual ~AccessibleDummyFactory() override;
+
+ public:
+ // IAccessibleFactory
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXButton* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXCheckBox* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXRadioButton* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXListBox* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXFixedHyperlink* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXFixedText* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXScrollBar* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXEdit* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXComboBox* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXToolBox* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXHeaderBar* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( SVTXNumericField* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessibleContext >
+ createAccessibleContext( VCLXWindow* /*_pXWindow*/ ) override
+ {
+ return nullptr;
+ }
+ css::uno::Reference< css::accessibility::XAccessible >
+ createAccessible( Menu* /*_pMenu*/, bool /*_bIsMenuBar*/ ) override
+ {
+ return nullptr;
+ }
+ };
+
+ }
+
+ AccessibleDummyFactory::AccessibleDummyFactory()
+ {
+ }
+
+
+ AccessibleDummyFactory::~AccessibleDummyFactory()
+ {
+ }
+
+
+ //= AccessibilityClient
+
+
+ AccessibilityClient::AccessibilityClient()
+ :m_bInitialized( false )
+ {
+ }
+
+#if !ENABLE_WASM_STRIP_ACCESSIBILITY
+#if HAVE_FEATURE_DESKTOP
+#ifndef DISABLE_DYNLOADING
+ extern "C" { static void thisModule() {} }
+#else
+ extern "C" void *getStandardAccessibleFactory();
+#endif
+#endif // HAVE_FEATURE_DESKTOP
+#endif // ENABLE_WASM_STRIP_ACCESSIBILITY
+
+ void AccessibilityClient::ensureInitialized()
+ {
+ if ( m_bInitialized )
+ return;
+
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+
+#if !ENABLE_WASM_STRIP_ACCESSIBILITY
+#if HAVE_FEATURE_DESKTOP
+ // load the library implementing the factory
+ if (!s_pFactory)
+ {
+#ifndef DISABLE_DYNLOADING
+ const OUString sModuleName( SVLIBRARY( "acc" ) );
+ s_hAccessibleImplementationModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, 0 );
+ if ( s_hAccessibleImplementationModule != nullptr )
+ {
+ const OUString sFactoryCreationFunc("getStandardAccessibleFactory");
+ s_pAccessibleFactoryFunc = reinterpret_cast<GetStandardAccComponentFactory>(
+ osl_getFunctionSymbol( s_hAccessibleImplementationModule, sFactoryCreationFunc.pData ));
+
+ }
+ OSL_ENSURE( s_pAccessibleFactoryFunc, "AccessibilityClient::ensureInitialized: could not load the library, or not retrieve the needed symbol!" );
+#else
+ s_pAccessibleFactoryFunc = getStandardAccessibleFactory;
+#endif // DISABLE_DYNLOADING
+
+ // get a factory instance
+ if ( s_pAccessibleFactoryFunc )
+ {
+ IAccessibleFactory* pFactory = static_cast< IAccessibleFactory* >( (*s_pAccessibleFactoryFunc)() );
+ OSL_ENSURE( pFactory, "AccessibilityClient::ensureInitialized: no factory provided by the A11Y lib!" );
+ if ( pFactory )
+ {
+ s_pFactory = pFactory;
+ pFactory->release();
+ }
+ }
+ }
+#endif // HAVE_FEATURE_DESKTOP
+#endif // ENABLE_WASM_STRIP_ACCESSIBILITY
+
+ if (!s_pFactory)
+ // the attempt to load the lib, or to create the factory, failed
+ // -> fall back to a dummy factory
+ s_pFactory = new AccessibleDummyFactory;
+
+ m_bInitialized = true;
+ }
+
+ IAccessibleFactory& AccessibilityClient::getFactory()
+ {
+ ensureInitialized();
+ OSL_ENSURE( s_pFactory.is(), "AccessibilityClient::getFactory: at least a dummy factory should have been created!" );
+ return *s_pFactory;
+ }
+
+
+} // namespace toolkit
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/toolkit/source/helper/btndlg.cxx b/toolkit/source/helper/btndlg.cxx
new file mode 100644
index 000000000..a2471c3f9
--- /dev/null
+++ b/toolkit/source/helper/btndlg.cxx
@@ -0,0 +1,304 @@
+/* -*- 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 <vcl/toolkit/button.hxx>
+#include <vcl/stdtext.hxx>
+#include <helper/btndlg.hxx>
+#include <sal/log.hxx>
+#include <map>
+#include <memory>
+
+struct ImplBtnDlgItem
+{
+ sal_uInt16 mnId;
+ bool mbOwnButton;
+ tools::Long mnSepSize;
+ VclPtr<PushButton> mpPushButton;
+
+ ImplBtnDlgItem() : mnId(0), mbOwnButton(false), mnSepSize(0) {}
+};
+
+void ButtonDialog::ImplInitButtonDialogData()
+{
+ mnButtonSize = 0;
+ mnCurButtonId = 0;
+ mnFocusButtonId = BUTTONDIALOG_BUTTON_NOTFOUND;
+ mbFormat = true;
+}
+
+ButtonDialog::ButtonDialog( WindowType nType ) :
+ Dialog( nType )
+{
+ ImplInitButtonDialogData();
+}
+
+ButtonDialog::~ButtonDialog()
+{
+ disposeOnce();
+}
+
+void ButtonDialog::dispose()
+{
+ for (auto & it : m_ItemList)
+ {
+ if ( it->mbOwnButton )
+ it->mpPushButton.disposeAndClear();
+ }
+ m_ItemList.clear();
+ Dialog::dispose();
+}
+
+VclPtr<PushButton> ButtonDialog::ImplCreatePushButton( ButtonDialogFlags nBtnFlags )
+{
+ VclPtr<PushButton> pBtn;
+ WinBits nStyle = 0;
+
+ if ( nBtnFlags & ButtonDialogFlags::Default )
+ nStyle |= WB_DEFBUTTON;
+ if ( nBtnFlags & ButtonDialogFlags::Cancel )
+ pBtn = VclPtr<CancelButton>::Create( this, nStyle );
+ else if ( nBtnFlags & ButtonDialogFlags::OK )
+ pBtn = VclPtr<OKButton>::Create( this, nStyle );
+ else if ( nBtnFlags & ButtonDialogFlags::Help )
+ pBtn = VclPtr<HelpButton>::Create( this, nStyle );
+ else
+ pBtn = VclPtr<PushButton>::Create( this, nStyle );
+
+ if ( !(nBtnFlags & ButtonDialogFlags::Help) )
+ pBtn->SetClickHdl( LINK( this, ButtonDialog, ImplClickHdl ) );
+
+ return pBtn;
+}
+
+tools::Long ButtonDialog::ImplGetButtonSize()
+{
+ if ( !mbFormat )
+ return mnButtonSize;
+
+ // Calculate ButtonSize
+ tools::Long nLastSepSize = 0;
+ tools::Long nSepSize = 0;
+ maCtrlSize = Size( IMPL_MINSIZE_BUTTON_WIDTH, IMPL_MINSIZE_BUTTON_HEIGHT );
+
+ for (const auto & it : m_ItemList)
+ {
+ nSepSize += nLastSepSize;
+
+ tools::Long nTxtWidth = it->mpPushButton->GetOutDev()->GetCtrlTextWidth(it->mpPushButton->GetText());
+ nTxtWidth += IMPL_EXTRA_BUTTON_WIDTH;
+
+ if ( nTxtWidth > maCtrlSize.Width() )
+ maCtrlSize.setWidth( nTxtWidth );
+
+ tools::Long nTxtHeight = it->mpPushButton->GetTextHeight();
+ nTxtHeight += IMPL_EXTRA_BUTTON_HEIGHT;
+
+ if ( nTxtHeight > maCtrlSize.Height() )
+ maCtrlSize.setHeight( nTxtHeight );
+
+ nSepSize += it->mnSepSize;
+
+ if ( GetStyle() & WB_HORZ )
+ nLastSepSize = IMPL_SEP_BUTTON_X;
+ else
+ nLastSepSize = IMPL_SEP_BUTTON_Y;
+ }
+
+ size_t const nButtonCount = m_ItemList.size();
+
+ if ( GetStyle() & WB_HORZ )
+ mnButtonSize = nSepSize + (nButtonCount*maCtrlSize.Width());
+ else
+ mnButtonSize = nSepSize + (nButtonCount*maCtrlSize.Height());
+
+ return mnButtonSize;
+}
+
+void ButtonDialog::ImplPosControls()
+{
+ if ( !mbFormat )
+ return;
+
+ // Create PushButtons and determine Sizes
+ ImplGetButtonSize();
+
+ // determine dialog size
+ Size aDlgSize = maPageSize;
+ tools::Long nX;
+ tools::Long nY;
+ if ( GetStyle() & WB_HORZ )
+ {
+ if ( mnButtonSize+(IMPL_DIALOG_OFFSET*2) > aDlgSize.Width() )
+ aDlgSize.setWidth( mnButtonSize+(IMPL_DIALOG_OFFSET*2) );
+ if ( GetStyle() & WB_LEFT )
+ nX = IMPL_DIALOG_OFFSET;
+ else if ( GetStyle() & WB_RIGHT )
+ nX = aDlgSize.Width()-mnButtonSize-IMPL_DIALOG_OFFSET;
+ else
+ nX = (aDlgSize.Width()-mnButtonSize)/2;
+
+ aDlgSize.AdjustHeight(IMPL_DIALOG_OFFSET+maCtrlSize.Height() );
+ nY = aDlgSize.Height()-maCtrlSize.Height()-IMPL_DIALOG_OFFSET;
+ }
+ else
+ {
+ if ( mnButtonSize+(IMPL_DIALOG_OFFSET*2) > aDlgSize.Height() )
+ aDlgSize.setHeight( mnButtonSize+(IMPL_DIALOG_OFFSET*2) );
+ if ( GetStyle() & WB_BOTTOM )
+ nY = aDlgSize.Height()-mnButtonSize-IMPL_DIALOG_OFFSET;
+ else if ( GetStyle() & WB_VCENTER )
+ nY = (aDlgSize.Height()-mnButtonSize)/2;
+ else
+ nY = IMPL_DIALOG_OFFSET;
+
+ aDlgSize.AdjustWidth(IMPL_DIALOG_OFFSET+maCtrlSize.Width() );
+ nX = aDlgSize.Width()-maCtrlSize.Width()-IMPL_DIALOG_OFFSET;
+ }
+
+ // Arrange PushButtons
+ for (auto & it : m_ItemList)
+ {
+ if ( GetStyle() & WB_HORZ )
+ nX += it->mnSepSize;
+ else
+ nY += it->mnSepSize;
+
+ it->mpPushButton->SetPosSizePixel( Point( nX, nY ), maCtrlSize );
+ it->mpPushButton->Show();
+
+ if ( GetStyle() & WB_HORZ )
+ nX += maCtrlSize.Width()+IMPL_SEP_BUTTON_X;
+ else
+ nY += maCtrlSize.Height()+IMPL_SEP_BUTTON_Y;
+ }
+
+ SetOutputSizePixel(aDlgSize);
+ SetMinOutputSizePixel(aDlgSize);
+
+ mbFormat = false;
+}
+
+IMPL_LINK( ButtonDialog, ImplClickHdl, Button*, pBtn, void )
+{
+ for (const auto & it : m_ItemList)
+ {
+ if ( it->mpPushButton == pBtn )
+ {
+ mnCurButtonId = it->mnId;
+ if ( IsInExecute() )
+ EndDialog( mnCurButtonId );
+ break;
+ }
+ }
+}
+
+void ButtonDialog::Resize()
+{
+}
+
+void ButtonDialog::StateChanged( StateChangedType nType )
+{
+ if ( nType == StateChangedType::InitShow )
+ {
+ ImplPosControls();
+ for (auto & it : m_ItemList)
+ {
+ if ( it->mpPushButton && it->mbOwnButton )
+ it->mpPushButton->SetZOrder(nullptr, ZOrderFlags::Last);
+ }
+
+ // Set focus on default button.
+ if ( mnFocusButtonId != BUTTONDIALOG_BUTTON_NOTFOUND )
+ {
+ for (auto & it : m_ItemList)
+ {
+ if (it->mnId == mnFocusButtonId )
+ {
+ if (it->mpPushButton->IsVisible())
+ it->mpPushButton->GrabFocus();
+
+ break;
+ }
+ }
+ }
+ }
+
+ Dialog::StateChanged( nType );
+}
+
+void ButtonDialog::AddButton( StandardButtonType eType, sal_uInt16 nId,
+ ButtonDialogFlags nBtnFlags, tools::Long nSepPixel )
+{
+ // PageItem anlegen
+ std::unique_ptr<ImplBtnDlgItem> pItem(new ImplBtnDlgItem);
+ pItem->mnId = nId;
+ pItem->mbOwnButton = true;
+ pItem->mnSepSize = nSepPixel;
+
+ if ( eType == StandardButtonType::OK )
+ nBtnFlags |= ButtonDialogFlags::OK;
+ else if ( eType == StandardButtonType::Help )
+ nBtnFlags |= ButtonDialogFlags::Help;
+ else if ( (eType == StandardButtonType::Cancel) || (eType == StandardButtonType::Close) )
+ nBtnFlags |= ButtonDialogFlags::Cancel;
+ pItem->mpPushButton = ImplCreatePushButton( nBtnFlags );
+
+ // Standard-Buttons have the right text already
+ if ( !((eType == StandardButtonType::OK && pItem->mpPushButton->GetType() == WindowType::OKBUTTON) ||
+ (eType == StandardButtonType::Cancel && pItem->mpPushButton->GetType() == WindowType::CANCELBUTTON) ||
+ (eType == StandardButtonType::Help && pItem->mpPushButton->GetType() == WindowType::HELPBUTTON)) )
+ {
+ std::map<StandardButtonType, OUString> mapButtonTypeToID = {{StandardButtonType::Yes, "yes"},
+ {StandardButtonType::No, "no"}, {StandardButtonType::Retry, "retry"},
+ {StandardButtonType::Close, "close"}, {StandardButtonType::More, "more"},
+ {StandardButtonType::Ignore, "ignore"}, {StandardButtonType::Abort, "abort"},
+ {StandardButtonType::Less, "less"}, {StandardButtonType::Count, "count"}};
+ auto itr = mapButtonTypeToID.find(eType);
+ if (itr != mapButtonTypeToID.end())
+ pItem->mpPushButton->set_id(itr->second);
+ pItem->mpPushButton->SetText( GetStandardText( eType ) );
+ }
+
+ if ( nBtnFlags & ButtonDialogFlags::Focus )
+ mnFocusButtonId = nId;
+
+ m_ItemList.push_back(std::move(pItem));
+
+ mbFormat = true;
+}
+
+void ButtonDialog::RemoveButton( sal_uInt16 nId )
+{
+ auto it = std::find_if(m_ItemList.begin(), m_ItemList.end(),
+ [&nId](const std::unique_ptr<ImplBtnDlgItem>& rItem) { return rItem->mnId == nId; });
+ if (it != m_ItemList.end())
+ {
+ (*it)->mpPushButton->Hide();
+ if ((*it)->mbOwnButton)
+ (*it)->mpPushButton.disposeAndClear();
+ else
+ (*it)->mpPushButton.clear();
+ m_ItemList.erase(it);
+ return;
+ }
+
+ SAL_WARN( "vcl.window", "ButtonDialog::RemoveButton(): ButtonId invalid" );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/toolkit/source/helper/formpdfexport.cxx b/toolkit/source/helper/formpdfexport.cxx
new file mode 100644
index 000000000..1c001cd9e
--- /dev/null
+++ b/toolkit/source/helper/formpdfexport.cxx
@@ -0,0 +1,789 @@
+/* -*- 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 <toolkit/helper/formpdfexport.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/lineend.hxx>
+#include <unordered_map>
+#include <sal/log.hxx>
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/awt/TextAlign.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/form/FormSubmitMethod.hpp>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/pdfextoutdevdata.hxx>
+
+#include <algorithm>
+#include <iterator>
+
+
+namespace toolkitform
+{
+
+
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::style;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+
+ constexpr OUStringLiteral FM_PROP_NAME = u"Name";
+
+ namespace
+ {
+
+ /** determines the FormComponentType of a form control
+ */
+ sal_Int16 classifyFormControl( const Reference< XPropertySet >& _rxModel )
+ {
+ static constexpr OUStringLiteral FM_PROP_CLASSID = u"ClassId";
+ sal_Int16 nControlType = FormComponentType::CONTROL;
+
+ Reference< XPropertySetInfo > xPSI;
+ if ( _rxModel.is() )
+ xPSI = _rxModel->getPropertySetInfo();
+ if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_CLASSID ) )
+ {
+ if( ! (_rxModel->getPropertyValue( FM_PROP_CLASSID ) >>= nControlType) ) {
+ SAL_WARN("toolkit.helper", "classifyFormControl: unable to get property " << FM_PROP_CLASSID);
+ }
+ }
+
+ return nControlType;
+ }
+
+
+ /** (default-)creates a PDF widget according to a given FormComponentType
+ */
+ std::unique_ptr<vcl::PDFWriter::AnyWidget> createDefaultWidget( sal_Int16 _nFormComponentType )
+ {
+ switch ( _nFormComponentType )
+ {
+ case FormComponentType::COMMANDBUTTON:
+ return std::make_unique<vcl::PDFWriter::PushButtonWidget>();
+ case FormComponentType::CHECKBOX:
+ return std::make_unique<vcl::PDFWriter::CheckBoxWidget>();
+ case FormComponentType::RADIOBUTTON:
+ return std::make_unique<vcl::PDFWriter::RadioButtonWidget>();
+ case FormComponentType::LISTBOX:
+ return std::make_unique<vcl::PDFWriter::ListBoxWidget>();
+ case FormComponentType::COMBOBOX:
+ return std::make_unique<vcl::PDFWriter::ComboBoxWidget>();
+
+ case FormComponentType::TEXTFIELD:
+ case FormComponentType::FILECONTROL:
+ case FormComponentType::DATEFIELD:
+ case FormComponentType::TIMEFIELD:
+ case FormComponentType::NUMERICFIELD:
+ case FormComponentType::CURRENCYFIELD:
+ case FormComponentType::PATTERNFIELD:
+ return std::make_unique<vcl::PDFWriter::EditWidget>();
+ }
+ return nullptr;
+ }
+
+
+ /** determines a unique number for the radio group which the given radio
+ button model belongs to
+
+ The number is guaranteed to be
+ <ul><li>unique within the document in which the button lives</li>
+ <li>the same for subsequent calls with other radio button models,
+ which live in the same document, and belong to the same group</li>
+ </ul>
+
+ @precond
+ the model must be part of the form component hierarchy in a document
+ */
+ sal_Int32 determineRadioGroupId( const Reference< XPropertySet >& _rxRadioModel )
+ {
+ OSL_ENSURE( classifyFormControl( _rxRadioModel ) == FormComponentType::RADIOBUTTON,
+ "determineRadioGroupId: this *is* no radio button model!" );
+ // The fact that radio button groups need to be unique within the complete
+ // host document makes it somewhat difficult ...
+ // Problem is that two form radio buttons belong to the same group if
+ // - they have the same parent
+ // - AND they have the same name or group name
+ // This implies that we need some knowledge about (potentially) *all* radio button
+ // groups in the document.
+
+ // get the root-level container
+ Reference< XChild > xChild( _rxRadioModel, UNO_QUERY );
+ Reference< XForm > xParentForm( xChild.is() ? xChild->getParent() : Reference< XInterface >(), UNO_QUERY );
+ OSL_ENSURE( xParentForm.is(), "determineRadioGroupId: no parent form -> group id!" );
+ if ( !xParentForm.is() )
+ return -1;
+
+ while ( xParentForm.is() )
+ {
+ xChild = xParentForm.get();
+ xParentForm.set(xChild->getParent(), css::uno::UNO_QUERY);
+ }
+ Reference< XIndexAccess > xRoot( xChild->getParent(), UNO_QUERY );
+ OSL_ENSURE( xRoot.is(), "determineRadioGroupId: unable to determine the root of the form component hierarchy!" );
+ if ( !xRoot.is() )
+ return -1;
+
+ // count the leafs in the hierarchy, until we encounter radio button
+ ::std::vector< Reference< XIndexAccess > > aAncestors;
+ ::std::vector< sal_Int32 > aPath;
+
+ Reference< XInterface > xNormalizedLookup( _rxRadioModel, UNO_QUERY );
+ Reference< XIndexAccess > xCurrentContainer( xRoot );
+ sal_Int32 nStartWithChild = 0;
+ sal_Int32 nGroupsEncountered = 0;
+ do
+ {
+ std::unordered_map<OUString,sal_Int32> GroupNameMap;
+ std::unordered_map<OUString,sal_Int32> SharedNameMap;
+ sal_Int32 nCount = xCurrentContainer->getCount();
+ sal_Int32 i;
+ for ( i = nStartWithChild; i < nCount; ++i )
+ {
+ Reference< XInterface > xElement( xCurrentContainer->getByIndex( i ), UNO_QUERY );
+ if ( !xElement.is() )
+ {
+ OSL_FAIL( "determineRadioGroupId: very suspicious!" );
+ continue;
+ }
+
+ Reference< XIndexAccess > xNewContainer( xElement, UNO_QUERY );
+ if ( xNewContainer.is() )
+ {
+ // step down the hierarchy
+ aAncestors.push_back( xCurrentContainer );
+ xCurrentContainer = xNewContainer;
+ aPath.push_back( i );
+ nStartWithChild = 0;
+ break;
+ // out of the inner loop, but continue with the outer loop
+ }
+
+ if ( xElement.get() == xNormalizedLookup.get() )
+ {
+ // Our radio button is in this container.
+ // Now take the time to ID this container's groups and return the button's groupId
+ for ( i = 0; i < nCount; ++i )
+ {
+ try
+ {
+ xElement.set( xCurrentContainer->getByIndex( i ), UNO_QUERY_THROW );
+ Reference< XServiceInfo > xModelSI( xElement, UNO_QUERY_THROW );
+ if ( xModelSI->supportsService("com.sun.star.awt.UnoControlRadioButtonModel") )
+ {
+ Reference< XPropertySet > aProps( xElement, UNO_QUERY_THROW );
+
+ OUString sGroupName;
+ aProps->getPropertyValue("GroupName") >>= sGroupName;
+ if ( !sGroupName.isEmpty() )
+ {
+ // map: unique key is the group name, so attempts to add a different ID value
+ // for an existing group are ignored - keeping the first ID - perfect for this scenario.
+ GroupNameMap.emplace( sGroupName, nGroupsEncountered + i );
+
+ if ( xElement.get() == xNormalizedLookup.get() )
+ return GroupNameMap[sGroupName];
+ }
+ else
+ {
+ // Old implementation didn't have a GroupName, just identical Control names.
+ aProps->getPropertyValue( FM_PROP_NAME ) >>= sGroupName;
+ SharedNameMap.emplace( sGroupName, nGroupsEncountered + i );
+
+ if ( xElement.get() == xNormalizedLookup.get() )
+ return SharedNameMap[sGroupName];
+ }
+
+ }
+ }
+ catch( uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("toolkit");
+ }
+ }
+ SAL_WARN("toolkit.helper","determineRadioGroupId: did not find the radios element's group!" );
+ }
+ }
+
+ // we encounter this container the first time. In particular, we did not just step up
+ if ( nStartWithChild == 0 )
+ {
+ // Our control wasn't in this container, so consider every item to be a possible unique group.
+ // This is way too much: Not all of the elements in the current container will form groups.
+ // But anyway, this number is sufficient for our purpose, since sequential group ids are not required.
+ // Ultimately, the container contains *at most* this many groups.
+ nGroupsEncountered += nCount;
+ }
+
+ if ( i >= nCount )
+ {
+ // the loop terminated because there were no more elements
+ // -> step up, if possible
+ if ( aAncestors.empty() )
+ break;
+
+ xCurrentContainer = aAncestors.back(); aAncestors.pop_back();
+ nStartWithChild = aPath.back() + 1; aPath.pop_back();
+ }
+ }
+ while ( true );
+ return -1;
+ }
+
+
+ /** copies a StringItemList to a PDF widget's list
+ */
+ void getStringItemVector( const Reference< XPropertySet >& _rxModel, ::std::vector< OUString >& _rVector )
+ {
+ Sequence< OUString > aListEntries;
+ if( ! (_rxModel->getPropertyValue( "StringItemList" ) >>= aListEntries) ) {
+ SAL_WARN("toolkit.helper", "getStringItemVector: unable to get property StringItemList");
+ }
+ _rVector.insert( _rVector.end(), std::cbegin(aListEntries), std::cend(aListEntries) );
+ }
+ }
+
+
+ /** creates a PDF compatible control descriptor for the given control
+ */
+ std::unique_ptr<vcl::PDFWriter::AnyWidget> describePDFControl( const Reference< XControl >& _rxControl,
+ vcl::PDFExtOutDevData& i_pdfExportData )
+ {
+ std::unique_ptr<vcl::PDFWriter::AnyWidget> Descriptor;
+ OSL_ENSURE( _rxControl.is(), "describePDFControl: invalid (NULL) control!" );
+ if ( !_rxControl.is() )
+ return Descriptor;
+
+ try
+ {
+ Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
+ sal_Int16 nControlType = classifyFormControl( xModelProps );
+ Descriptor = createDefaultWidget( nControlType );
+ if (!Descriptor)
+ // no PDF widget available for this
+ return Descriptor;
+
+ Reference< XPropertySetInfo > xPSI( xModelProps->getPropertySetInfo() );
+ Reference< XServiceInfo > xSI( xModelProps, UNO_QUERY );
+ OSL_ENSURE( xSI.is(), "describePDFControl: no service info!" );
+ // if we survived classifyFormControl, then it's a real form control, and they all have
+ // service infos
+
+
+ // set the common widget properties
+
+
+ // Name, Description, Text
+ if( ! (xModelProps->getPropertyValue( FM_PROP_NAME ) >>= Descriptor->Name) ) {
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_NAME);
+ }
+ if( ! (xModelProps->getPropertyValue( "HelpText" ) >>= Descriptor->Description) ) {
+ SAL_INFO("toolkit.helper", "describePDFControl: unable to get property HelpText");
+ }
+ Any aText;
+ static constexpr OUStringLiteral FM_PROP_TEXT = u"Text";
+ static constexpr OUStringLiteral FM_PROP_LABEL = u"Label";
+ static constexpr OUStringLiteral FM_PROP_VALUE = u"Value";
+ if ( xPSI->hasPropertyByName( FM_PROP_TEXT ) )
+ aText = xModelProps->getPropertyValue( FM_PROP_TEXT );
+ else if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
+ aText = xModelProps->getPropertyValue( FM_PROP_LABEL );
+ else if ( xPSI->hasPropertyByName( FM_PROP_VALUE ) )
+ {
+ double aValue;
+ if (xModelProps->getPropertyValue( FM_PROP_VALUE ) >>= aValue)
+ aText <<= OUString::number(aValue);
+ }
+
+ if ( aText.hasValue() ) {
+ if( ! (aText >>= Descriptor->Text) ) {
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to assign aText to Descriptor->Text");
+ }
+ }
+
+
+ // readonly
+ static constexpr OUStringLiteral FM_PROP_READONLY = u"ReadOnly";
+ if ( xPSI->hasPropertyByName( FM_PROP_READONLY ) )
+ if( ! (xModelProps->getPropertyValue( FM_PROP_READONLY ) >>= Descriptor->ReadOnly) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_READONLY);
+
+
+ // border
+ {
+ static constexpr OUStringLiteral FM_PROP_BORDER = u"Border";
+ if ( xPSI->hasPropertyByName( FM_PROP_BORDER ) )
+ {
+ sal_Int16 nBorderType = 0;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_BORDER ) >>= nBorderType) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_BORDER);
+ Descriptor->Border = ( nBorderType != 0 );
+
+ OUString sBorderColorPropertyName( "BorderColor" );
+ if ( xPSI->hasPropertyByName( sBorderColorPropertyName ) )
+ {
+ Color nBorderColor = COL_TRANSPARENT;
+ if ( xModelProps->getPropertyValue( sBorderColorPropertyName ) >>= nBorderColor )
+ Descriptor->BorderColor = nBorderColor;
+ else
+ Descriptor->BorderColor = COL_BLACK;
+ }
+ }
+ }
+
+
+ // background color
+ static constexpr OUStringLiteral FM_PROP_BACKGROUNDCOLOR = u"BackgroundColor";
+ if ( xPSI->hasPropertyByName( FM_PROP_BACKGROUNDCOLOR ) )
+ {
+ Color nBackColor = COL_TRANSPARENT;
+ xModelProps->getPropertyValue( FM_PROP_BACKGROUNDCOLOR ) >>= nBackColor;
+ Descriptor->Background = true;
+ Descriptor->BackgroundColor = nBackColor;
+ }
+
+
+ // text color
+ static constexpr OUStringLiteral FM_PROP_TEXTCOLOR = u"TextColor";
+ if ( xPSI->hasPropertyByName( FM_PROP_TEXTCOLOR ) )
+ {
+ Color nTextColor = COL_TRANSPARENT;
+ xModelProps->getPropertyValue( FM_PROP_TEXTCOLOR ) >>= nTextColor;
+ Descriptor->TextColor = nTextColor;
+ }
+
+
+ // text style
+ Descriptor->TextStyle = DrawTextFlags::NONE;
+
+ // multi line and word break
+ // The MultiLine property of the control is mapped to both the "MULTILINE" and
+ // "WORDBREAK" style flags
+ static constexpr OUStringLiteral FM_PROP_MULTILINE = u"MultiLine";
+ if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
+ {
+ bool bMultiLine = false;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_MULTILINE ) >>= bMultiLine) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_MULTILINE);
+ if ( bMultiLine )
+ Descriptor->TextStyle |= DrawTextFlags::MultiLine | DrawTextFlags::WordBreak;
+ }
+
+ // horizontal alignment
+ static constexpr OUStringLiteral FM_PROP_ALIGN = u"Align";
+ if ( xPSI->hasPropertyByName( FM_PROP_ALIGN ) )
+ {
+ sal_Int16 nAlign = awt::TextAlign::LEFT;
+ xModelProps->getPropertyValue( FM_PROP_ALIGN ) >>= nAlign;
+ // TODO: when the property is VOID - are there situations/UIs where this
+ // means something else than LEFT?
+ switch ( nAlign )
+ {
+ case awt::TextAlign::LEFT: Descriptor->TextStyle |= DrawTextFlags::Left; break;
+ case awt::TextAlign::CENTER: Descriptor->TextStyle |= DrawTextFlags::Center; break;
+ case awt::TextAlign::RIGHT: Descriptor->TextStyle |= DrawTextFlags::Right; break;
+ default:
+ OSL_FAIL( "describePDFControl: invalid text align!" );
+ }
+ }
+
+ // vertical alignment
+ {
+ OUString sVertAlignPropertyName( "VerticalAlign" );
+ if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
+ {
+ VerticalAlignment nAlign = VerticalAlignment_MIDDLE;
+ xModelProps->getPropertyValue( sVertAlignPropertyName ) >>= nAlign;
+ switch ( nAlign )
+ {
+ case VerticalAlignment_TOP: Descriptor->TextStyle |= DrawTextFlags::Top; break;
+ case VerticalAlignment_MIDDLE: Descriptor->TextStyle |= DrawTextFlags::VCenter; break;
+ case VerticalAlignment_BOTTOM: Descriptor->TextStyle |= DrawTextFlags::Bottom; break;
+ default:
+ OSL_FAIL( "describePDFControl: invalid vertical text align!" );
+ }
+ }
+ }
+
+ // font
+ static constexpr OUStringLiteral FM_PROP_FONT = u"FontDescriptor";
+ if ( xPSI->hasPropertyByName( FM_PROP_FONT ) )
+ {
+ FontDescriptor aUNOFont;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_FONT ) >>= aUNOFont) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_FONT);
+ Descriptor->TextFont = VCLUnoHelper::CreateFont( aUNOFont, vcl::Font() );
+ }
+
+ // tab order
+ OUString aTabIndexString( "TabIndex" );
+ if ( xPSI->hasPropertyByName( aTabIndexString ) )
+ {
+ sal_Int16 nIndex = -1;
+ if( ! (xModelProps->getPropertyValue( aTabIndexString ) >>= nIndex) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << aTabIndexString);
+ Descriptor->TabOrder = nIndex;
+ }
+
+
+ // special widget properties
+
+ // edits
+ if ( Descriptor->getType() == vcl::PDFWriter::Edit )
+ {
+ vcl::PDFWriter::EditWidget* pEditWidget = static_cast< vcl::PDFWriter::EditWidget* >( Descriptor.get() );
+
+ // multiline (already flagged in the TextStyle)
+ pEditWidget->MultiLine = bool( Descriptor->TextStyle & DrawTextFlags::MultiLine );
+
+ // password input
+ OUString sEchoCharPropName( "EchoChar" );
+ if ( xPSI->hasPropertyByName( sEchoCharPropName ) )
+ {
+ sal_Int16 nEchoChar = 0;
+ if ( ( xModelProps->getPropertyValue( sEchoCharPropName ) >>= nEchoChar ) && ( nEchoChar != 0 ) )
+ pEditWidget->Password = true;
+ }
+
+ // file select
+ if ( xSI->supportsService( "com.sun.star.form.component.FileControl" ) )
+ pEditWidget->FileSelect = true;
+
+ // maximum text length
+ static constexpr OUStringLiteral FM_PROP_MAXTEXTLEN = u"MaxTextLen";
+ if ( xPSI->hasPropertyByName( FM_PROP_MAXTEXTLEN ) )
+ {
+ sal_Int16 nMaxTextLength = 0;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_MAXTEXTLEN ) >>= nMaxTextLength) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_MAXTEXTLEN);
+ if ( nMaxTextLength <= 0 )
+ // "-1" has a special meaning for database-bound controls
+ nMaxTextLength = 0;
+ pEditWidget->MaxLen = nMaxTextLength;
+ }
+
+ switch ( nControlType )
+ {
+ case FormComponentType::CURRENCYFIELD:
+ case FormComponentType::NUMERICFIELD:
+ {
+
+ pEditWidget->Format = vcl::PDFWriter::Number;
+
+ static constexpr OUStringLiteral FM_PROP_CURRENCYSYMBOL = u"CurrencySymbol";
+ if ( xPSI->hasPropertyByName( FM_PROP_CURRENCYSYMBOL ) )
+ {
+ OUString sCurrencySymbol;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_CURRENCYSYMBOL ) >>= sCurrencySymbol) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_CURRENCYSYMBOL);
+ pEditWidget->CurrencySymbol = sCurrencySymbol;
+ }
+
+ static constexpr OUStringLiteral FM_PROP_DECIMALACCURACY = u"DecimalAccuracy";
+ if ( xPSI->hasPropertyByName( FM_PROP_DECIMALACCURACY ) )
+ {
+ sal_Int32 nDecimalAccuracy = 0;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_DECIMALACCURACY ) >>= nDecimalAccuracy) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_DECIMALACCURACY);
+ pEditWidget->DecimalAccuracy = nDecimalAccuracy;
+ }
+
+ static constexpr OUStringLiteral FM_PROP_PREPENDCURRENCYSYMBOL = u"PrependCurrencySymbol";
+ if ( xPSI->hasPropertyByName( FM_PROP_PREPENDCURRENCYSYMBOL ) )
+ {
+ bool bPrependCurrencySymbol = true;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_PREPENDCURRENCYSYMBOL ) >>= bPrependCurrencySymbol) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_PREPENDCURRENCYSYMBOL);
+ pEditWidget->PrependCurrencySymbol = bPrependCurrencySymbol;
+ }
+ } break;
+ case FormComponentType::TIMEFIELD:
+ {
+ pEditWidget->Format = vcl::PDFWriter::Time;
+
+ static constexpr OUStringLiteral FM_PROP_TIMEFORMAT = u"TimeFormat";
+ if ( xPSI->hasPropertyByName( FM_PROP_TIMEFORMAT ) )
+ {
+ sal_Int32 nTimeFormat = 0;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_TIMEFORMAT ) >>= nTimeFormat) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_TIMEFORMAT);
+
+ switch ( nTimeFormat )
+ {
+ case 0:
+ pEditWidget->TimeFormat = "HH:MM"; //13:45
+ break;
+ case 1:
+ pEditWidget->TimeFormat = "HH:MM:ss"; //13:45:00
+ break;
+ case 2:
+ pEditWidget->TimeFormat = "h:MMtt"; //01:45 PM
+ break;
+ case 3:
+ pEditWidget->TimeFormat = "h:MM:sstt"; //01:45:00 PM
+ break;
+ }
+ }
+ } break;
+ case FormComponentType::DATEFIELD:
+ {
+ pEditWidget->Format = vcl::PDFWriter::Date;
+
+ static constexpr OUStringLiteral FM_PROP_DATEFORMAT = u"DateFormat";
+ if ( xPSI->hasPropertyByName( FM_PROP_DATEFORMAT ) )
+ {
+ sal_Int32 nDateFormat = 0;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_DATEFORMAT ) >>= nDateFormat) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_DATEFORMAT);
+
+ switch ( nDateFormat )
+ {
+ case 0:
+ case 1:
+ pEditWidget->DateFormat = "mm/dd/yy"; // Standard (short)
+ break;
+ case 2:
+ case 3:
+ pEditWidget->DateFormat = "mm/dd/yyyy"; // Standard (long)
+ break;
+ case 4:
+ pEditWidget->DateFormat = "dd/mm/yy"; // DD/MM/YY
+ break;
+ case 5:
+ pEditWidget->DateFormat = "mm/dd/yy"; // MM/DD/YY
+ break;
+ case 6:
+ pEditWidget->DateFormat = "yy/mm/dd"; // YY/MM/DD
+ break;
+ case 7:
+ pEditWidget->DateFormat = "dd/mm/yyyy"; // DD/MM/YYYY
+ break;
+ case 8:
+ pEditWidget->DateFormat = "mm/dd/yyyy"; // MM/DD/YYYY
+ break;
+ case 9:
+ pEditWidget->DateFormat = "yyyy/mm/dd"; // YYYY/MM/DD
+ break;
+ case 10:
+ pEditWidget->DateFormat = "yy-mm-dd"; // YY-MM-DD
+ break;
+ case 11:
+ pEditWidget->DateFormat = "yyyy-mm-dd"; // YYYY-MM-DD
+ break;
+ }
+ }
+ } break;
+ }
+ }
+
+ // buttons
+ if ( Descriptor->getType() == vcl::PDFWriter::PushButton )
+ {
+ vcl::PDFWriter::PushButtonWidget* pButtonWidget = static_cast< vcl::PDFWriter::PushButtonWidget* >( Descriptor.get() );
+ FormButtonType eButtonType = FormButtonType_PUSH;
+ if( ! (xModelProps->getPropertyValue("ButtonType") >>= eButtonType) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property ButtonType");
+ static constexpr OUStringLiteral FM_PROP_TARGET_URL = u"TargetURL";
+ if ( eButtonType == FormButtonType_SUBMIT )
+ {
+ // if a button is a submit button, then it uses the URL at its parent form
+ Reference< XChild > xChild( xModelProps, UNO_QUERY );
+ Reference < XPropertySet > xParentProps;
+ if ( xChild.is() )
+ xParentProps.set(xChild->getParent(), css::uno::UNO_QUERY);
+ if ( xParentProps.is() )
+ {
+ Reference< XServiceInfo > xParentSI( xParentProps, UNO_QUERY );
+ if ( xParentSI.is() && xParentSI->supportsService("com.sun.star.form.component.HTMLForm") )
+ {
+ if( ! (xParentProps->getPropertyValue( FM_PROP_TARGET_URL ) >>= pButtonWidget->URL) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_TARGET_URL);
+ pButtonWidget->Submit = true;
+ FormSubmitMethod eMethod = FormSubmitMethod_POST;
+ if( ! (xParentProps->getPropertyValue("SubmitMethod") >>= eMethod) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_TARGET_URL);
+ pButtonWidget->SubmitGet = (eMethod == FormSubmitMethod_GET);
+ }
+ }
+ }
+ else if ( eButtonType == FormButtonType_URL )
+ {
+ OUString sURL;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_TARGET_URL ) >>= sURL) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_TARGET_URL);
+ const bool bDocumentLocalTarget = sURL.startsWith("#");
+ if ( bDocumentLocalTarget )
+ {
+ // Register the destination for future handling ...
+ pButtonWidget->Dest = i_pdfExportData.RegisterDest();
+
+ // and put it into the bookmarks, to ensure the future handling really happens
+ ::std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks( i_pdfExportData.GetBookmarks() );
+ vcl::PDFExtOutDevBookmarkEntry aBookmark;
+ aBookmark.nDestId = pButtonWidget->Dest;
+ aBookmark.aBookmark = sURL;
+ rBookmarks.push_back( aBookmark );
+ }
+ else
+ pButtonWidget->URL = sURL;
+
+ pButtonWidget->Submit = false;
+ }
+
+ // TODO:
+ // In PDF files, buttons are either reset, url or submit buttons. So if we have a simple PUSH button
+ // in a document, then this means that we do not export a SubmitToURL, which means that in PDF,
+ // the button is used as reset button.
+ // Is this desired? If no, we would have to reset Descriptor to NULL here, in case eButtonType
+ // != FormButtonType_SUBMIT && != FormButtonType_RESET
+
+ // the PDF exporter defaults the text style, if 0. To prevent this, we have to transfer the UNO
+ // defaults to the PDF widget
+ if ( pButtonWidget->TextStyle == DrawTextFlags::NONE )
+ pButtonWidget->TextStyle = DrawTextFlags::Center | DrawTextFlags::VCenter;
+ }
+
+
+ // check boxes
+ static constexpr OUStringLiteral FM_PROP_STATE = u"State";
+ if ( Descriptor->getType() == vcl::PDFWriter::CheckBox )
+ {
+ vcl::PDFWriter::CheckBoxWidget* pCheckBoxWidget = static_cast< vcl::PDFWriter::CheckBoxWidget* >( Descriptor.get() );
+ sal_Int16 nState = 0;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_STATE ) >>= nState) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_STATE);
+ pCheckBoxWidget->Checked = ( nState != 0 );
+
+ try
+ {
+ xModelProps->getPropertyValue( "RefValue" ) >>= pCheckBoxWidget->OnValue;
+ }
+ catch(...)
+ {
+ }
+
+ try
+ {
+ xModelProps->getPropertyValue( "SecondaryRefValue" ) >>= pCheckBoxWidget->OffValue;
+ }
+ catch(...)
+ {
+ }
+ }
+
+
+ // radio buttons
+ if ( Descriptor->getType() == vcl::PDFWriter::RadioButton )
+ {
+ vcl::PDFWriter::RadioButtonWidget* pRadioWidget = static_cast< vcl::PDFWriter::RadioButtonWidget* >( Descriptor.get() );
+ sal_Int16 nState = 0;
+ if( ! (xModelProps->getPropertyValue( FM_PROP_STATE ) >>= nState) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property " << FM_PROP_STATE);
+ pRadioWidget->Selected = ( nState != 0 );
+ pRadioWidget->RadioGroup = determineRadioGroupId( xModelProps );
+ try
+ {
+ xModelProps->getPropertyValue( "RefValue" ) >>= pRadioWidget->OnValue;
+ }
+ catch(...)
+ {
+ }
+
+ try
+ {
+ xModelProps->getPropertyValue( "SecondaryRefValue" ) >>= pRadioWidget->OffValue;
+ }
+ catch(...)
+ {
+ }
+ }
+
+
+ // list boxes
+ if ( Descriptor->getType() == vcl::PDFWriter::ListBox )
+ {
+ vcl::PDFWriter::ListBoxWidget* pListWidget = static_cast< vcl::PDFWriter::ListBoxWidget* >( Descriptor.get() );
+
+ // drop down
+ if( ! (xModelProps->getPropertyValue( "Dropdown" ) >>= pListWidget->DropDown) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property Dropdown");
+
+ // multi selection
+ if( ! (xModelProps->getPropertyValue("MultiSelection") >>= pListWidget->MultiSelect) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property MultiSelection");
+
+ // entries
+ getStringItemVector( xModelProps, pListWidget->Entries );
+
+ // get selected items
+ Sequence< sal_Int16 > aSelectIndices;
+ if( ! (xModelProps->getPropertyValue("SelectedItems") >>= aSelectIndices) )
+ SAL_WARN("toolkit.helper", "describePDFControl: unable to get property SelectedItems");
+ if( aSelectIndices.hasElements() )
+ {
+ pListWidget->SelectedEntries.resize( 0 );
+ auto nEntriesSize = static_cast<sal_Int16>(pListWidget->Entries.size());
+ std::copy_if(std::cbegin(aSelectIndices), std::cend(aSelectIndices), std::back_inserter(pListWidget->SelectedEntries),
+ [&nEntriesSize](const sal_Int16 nIndex) { return nIndex >= 0 && nIndex < nEntriesSize; });
+ }
+ }
+
+
+ // combo boxes
+ if ( Descriptor->getType() == vcl::PDFWriter::ComboBox )
+ {
+ vcl::PDFWriter::ComboBoxWidget* pComboWidget = static_cast< vcl::PDFWriter::ComboBoxWidget* >( Descriptor.get() );
+
+ // entries
+ getStringItemVector( xModelProps, pComboWidget->Entries );
+ }
+
+
+ // some post-processing
+
+ // text line ends
+ // some controls may (always or dependent on other settings) return UNIX line ends
+ Descriptor->Text = convertLineEnd(Descriptor->Text, LINEEND_CRLF);
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "toolkit", "describePDFControl" );
+ }
+ return Descriptor;
+ }
+
+
+} // namespace toolkitform
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/toolkit/source/helper/imagealign.cxx b/toolkit/source/helper/imagealign.cxx
new file mode 100644
index 000000000..43e7cb012
--- /dev/null
+++ b/toolkit/source/helper/imagealign.cxx
@@ -0,0 +1,128 @@
+/* -*- 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/ImagePosition.hpp>
+#include <com/sun/star/awt/ImageAlign.hpp>
+
+#include <helper/imagealign.hxx>
+#include <osl/diagnose.h>
+
+namespace toolkit
+{
+
+
+ using namespace ::com::sun::star::awt::ImagePosition;
+ using namespace ::com::sun::star::awt::ImageAlign;
+
+ sal_Int16 translateImagePosition( ImageAlign _eVCLAlign )
+ {
+ sal_Int16 nReturn = AboveCenter;
+ switch ( _eVCLAlign )
+ {
+ case ImageAlign::Left: nReturn = LeftCenter; break;
+ case ImageAlign::Top: nReturn = AboveCenter; break;
+ case ImageAlign::Right: nReturn = RightCenter; break;
+ case ImageAlign::Bottom: nReturn = BelowCenter; break;
+ case ImageAlign::LeftTop: nReturn = LeftTop; break;
+ case ImageAlign::LeftBottom: nReturn = LeftBottom; break;
+ case ImageAlign::TopLeft: nReturn = AboveLeft; break;
+ case ImageAlign::TopRight: nReturn = AboveRight; break;
+ case ImageAlign::RightTop: nReturn = RightTop; break;
+ case ImageAlign::RightBottom: nReturn = RightBottom; break;
+ case ImageAlign::BottomLeft: nReturn = BelowLeft; break;
+ case ImageAlign::BottomRight: nReturn = BelowRight; break;
+ case ImageAlign::Center: nReturn = Centered; break;
+ default:
+ OSL_FAIL( "translateImagePosition: unknown IMAGEALIGN value!" );
+ }
+ return nReturn;
+ }
+
+ ImageAlign translateImagePosition( sal_Int16 _eUNOAlign )
+ {
+ ImageAlign nReturn = ImageAlign::Top;
+ switch ( _eUNOAlign )
+ {
+ case LeftCenter: nReturn = ImageAlign::Left; break;
+ case AboveCenter: nReturn = ImageAlign::Top; break;
+ case RightCenter: nReturn = ImageAlign::Right; break;
+ case BelowCenter: nReturn = ImageAlign::Bottom; break;
+ case LeftTop: nReturn = ImageAlign::LeftTop; break;
+ case LeftBottom: nReturn = ImageAlign::LeftBottom; break;
+ case AboveLeft: nReturn = ImageAlign::TopLeft; break;
+ case AboveRight: nReturn = ImageAlign::TopRight; break;
+ case RightTop: nReturn = ImageAlign::RightTop; break;
+ case RightBottom: nReturn = ImageAlign::RightBottom; break;
+ case BelowLeft: nReturn = ImageAlign::BottomLeft; break;
+ case BelowRight: nReturn = ImageAlign::BottomRight; break;
+ case Centered: nReturn = ImageAlign::Center; break;
+ default:
+ OSL_FAIL( "translateImagePosition: unknown css.awt.ImagePosition value!" );
+ }
+ return nReturn;
+ }
+
+ sal_Int16 getCompatibleImageAlign( ImageAlign _eAlign )
+ {
+ sal_Int16 nReturn = TOP;
+ switch ( _eAlign )
+ {
+ case ImageAlign::LeftTop:
+ case ImageAlign::Left:
+ case ImageAlign::LeftBottom: nReturn = LEFT; break;
+
+ case ImageAlign::TopLeft:
+ case ImageAlign::Top:
+ case ImageAlign::TopRight: nReturn = TOP; break;
+
+ case ImageAlign::RightTop:
+ case ImageAlign::Right:
+ case ImageAlign::RightBottom: nReturn = RIGHT; break;
+
+ case ImageAlign::BottomLeft:
+ case ImageAlign::Bottom:
+ case ImageAlign::BottomRight: nReturn = BOTTOM; break;
+
+ case ImageAlign::Center: nReturn = TOP; break;
+ default:
+ OSL_FAIL( "getCompatibleImageAlign: unknown IMAGEALIGN value!" );
+ }
+ return nReturn;
+ }
+
+ sal_Int16 getExtendedImagePosition( sal_Int16 _nImageAlign )
+ {
+ sal_Int16 nReturn = AboveCenter;
+ switch ( _nImageAlign )
+ {
+ case LEFT: nReturn = LeftCenter; break;
+ case TOP: nReturn = AboveCenter; break;
+ case RIGHT: nReturn = RightCenter; break;
+ case BOTTOM: nReturn = BelowCenter; break;
+ default:
+ OSL_FAIL( "getExtendedImagePosition: unknown ImageAlign value!" );
+ }
+ return nReturn;
+ }
+
+
+} // namespace toolkit
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/toolkit/source/helper/listenermultiplexer.cxx b/toolkit/source/helper/listenermultiplexer.cxx
new file mode 100644
index 000000000..eeed767ff
--- /dev/null
+++ b/toolkit/source/helper/listenermultiplexer.cxx
@@ -0,0 +1,242 @@
+/* -*- 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 <toolkit/helper/listenermultiplexer.hxx>
+#include <toolkit/helper/macros.hxx>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+// class EventListenerMultiplexer
+
+EventListenerMultiplexer::EventListenerMultiplexer( ::cppu::OWeakObject& rSource )
+ : ListenerMultiplexerBase( rSource )
+{
+}
+
+void SAL_CALL EventListenerMultiplexer::acquire() noexcept
+{
+ return ListenerMultiplexerBase::acquire();
+}
+
+void SAL_CALL EventListenerMultiplexer::release() noexcept
+{
+ return ListenerMultiplexerBase::release();
+}
+
+// css::uno::XInterface
+css::uno::Any EventListenerMultiplexer::queryInterface( const css::uno::Type & rType )
+{
+ css::uno::Any aRet = ::cppu::queryInterface( rType,
+ static_cast< css::lang::XEventListener* >(this) );
+ return (aRet.hasValue() ? aRet : ListenerMultiplexerBase::queryInterface( rType ));
+}
+
+// css::lang::XEventListener
+void EventListenerMultiplexer::disposing( const css::lang::EventObject& )
+{
+}
+
+
+// class FocusListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( FocusListenerMultiplexer, css::awt::XFocusListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( FocusListenerMultiplexer, css::awt::XFocusListener, focusGained, css::awt::FocusEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( FocusListenerMultiplexer, css::awt::XFocusListener, focusLost, css::awt::FocusEvent )
+
+
+// class WindowListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( WindowListenerMultiplexer, css::awt::XWindowListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( WindowListenerMultiplexer, css::awt::XWindowListener, windowResized, css::awt::WindowEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( WindowListenerMultiplexer, css::awt::XWindowListener, windowMoved, css::awt::WindowEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( WindowListenerMultiplexer, css::awt::XWindowListener, windowShown, css::lang::EventObject )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( WindowListenerMultiplexer, css::awt::XWindowListener, windowHidden, css::lang::EventObject )
+
+
+// class VclContainerListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( VclContainerListenerMultiplexer, css::awt::XVclContainerListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( VclContainerListenerMultiplexer, css::awt::XVclContainerListener, windowAdded, css::awt::VclContainerEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( VclContainerListenerMultiplexer, css::awt::XVclContainerListener, windowRemoved, css::awt::VclContainerEvent )
+
+
+// class KeyListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( KeyListenerMultiplexer, css::awt::XKeyListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( KeyListenerMultiplexer, css::awt::XKeyListener, keyPressed, css::awt::KeyEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( KeyListenerMultiplexer, css::awt::XKeyListener, keyReleased, css::awt::KeyEvent )
+
+
+// class MouseListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( MouseListenerMultiplexer, css::awt::XMouseListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( MouseListenerMultiplexer, css::awt::XMouseListener, mousePressed, css::awt::MouseEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( MouseListenerMultiplexer, css::awt::XMouseListener, mouseReleased, css::awt::MouseEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( MouseListenerMultiplexer, css::awt::XMouseListener, mouseEntered, css::awt::MouseEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( MouseListenerMultiplexer, css::awt::XMouseListener, mouseExited, css::awt::MouseEvent )
+
+
+// class MouseMotionListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( MouseMotionListenerMultiplexer, css::awt::XMouseMotionListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( MouseMotionListenerMultiplexer, css::awt::XMouseMotionListener, mouseDragged, css::awt::MouseEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( MouseMotionListenerMultiplexer, css::awt::XMouseMotionListener, mouseMoved, css::awt::MouseEvent )
+
+
+// class PaintListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( PaintListenerMultiplexer, css::awt::XPaintListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( PaintListenerMultiplexer, css::awt::XPaintListener, windowPaint, css::awt::PaintEvent )
+
+
+// class TopWindowListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( TopWindowListenerMultiplexer, css::awt::XTopWindowListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TopWindowListenerMultiplexer, css::awt::XTopWindowListener, windowOpened, css::lang::EventObject )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TopWindowListenerMultiplexer, css::awt::XTopWindowListener, windowClosing, css::lang::EventObject )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TopWindowListenerMultiplexer, css::awt::XTopWindowListener, windowClosed, css::lang::EventObject )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TopWindowListenerMultiplexer, css::awt::XTopWindowListener, windowMinimized, css::lang::EventObject )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TopWindowListenerMultiplexer, css::awt::XTopWindowListener, windowNormalized, css::lang::EventObject )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TopWindowListenerMultiplexer, css::awt::XTopWindowListener, windowActivated, css::lang::EventObject )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TopWindowListenerMultiplexer, css::awt::XTopWindowListener, windowDeactivated, css::lang::EventObject )
+
+
+// class TextListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( TextListenerMultiplexer, css::awt::XTextListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TextListenerMultiplexer, css::awt::XTextListener, textChanged, css::awt::TextEvent )
+
+
+// class ActionListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( ActionListenerMultiplexer, css::awt::XActionListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( ActionListenerMultiplexer, css::awt::XActionListener, actionPerformed, css::awt::ActionEvent )
+
+
+// class ItemListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( ItemListenerMultiplexer, css::awt::XItemListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( ItemListenerMultiplexer, css::awt::XItemListener, itemStateChanged, css::awt::ItemEvent )
+
+
+// class TabListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( TabListenerMultiplexer, css::awt::XTabListener )
+
+void TabListenerMultiplexer::inserted( sal_Int32 evt )
+IMPL_TABLISTENERMULTIPLEXER_LISTENERMETHOD_BODY_1PARAM( TabListenerMultiplexer, css::awt::XTabListener, inserted, ::sal_Int32 )
+
+void TabListenerMultiplexer::removed( sal_Int32 evt )
+IMPL_TABLISTENERMULTIPLEXER_LISTENERMETHOD_BODY_1PARAM( TabListenerMultiplexer, css::awt::XTabListener, removed, ::sal_Int32 )
+
+void TabListenerMultiplexer::changed( sal_Int32 evt, const css::uno::Sequence< css::beans::NamedValue >& evt2 )
+{
+ sal_Int32 aMulti( evt );
+ ::comphelper::OInterfaceIteratorHelper3 aIt(*this);
+ while( aIt.hasMoreElements() )
+ {
+ css::uno::Reference<css::awt::XTabListener> xListener(aIt.next());
+ try
+ {
+ xListener->changed( aMulti, evt2 );
+ }
+ catch(const css::lang::DisposedException& e)
+ {
+ OSL_ENSURE( e.Context.is(), "caught DisposedException with empty Context field" );
+ if ( e.Context == xListener || !e.Context.is() )
+ aIt.remove();
+ }
+ catch(const css::uno::RuntimeException&)
+ {
+ DISPLAY_EXCEPTION( TabListenerMultiplexer, changed )
+ }
+ }
+}
+
+
+void TabListenerMultiplexer::activated( sal_Int32 evt )
+IMPL_TABLISTENERMULTIPLEXER_LISTENERMETHOD_BODY_1PARAM( TabListenerMultiplexer, css::awt::XTabListener, activated, ::sal_Int32 )
+
+void TabListenerMultiplexer::deactivated( sal_Int32 evt )
+IMPL_TABLISTENERMULTIPLEXER_LISTENERMETHOD_BODY_1PARAM( TabListenerMultiplexer, css::awt::XTabListener, deactivated, ::sal_Int32 )
+
+
+// class ContainerListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( ContainerListenerMultiplexer, css::container::XContainerListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( ContainerListenerMultiplexer, css::container::XContainerListener, elementInserted, css::container::ContainerEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( ContainerListenerMultiplexer, css::container::XContainerListener, elementRemoved, css::container::ContainerEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( ContainerListenerMultiplexer, css::container::XContainerListener, elementReplaced, css::container::ContainerEvent )
+
+
+// class SpinListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( SpinListenerMultiplexer, css::awt::XSpinListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( SpinListenerMultiplexer, css::awt::XSpinListener, up, css::awt::SpinEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( SpinListenerMultiplexer, css::awt::XSpinListener, down, css::awt::SpinEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( SpinListenerMultiplexer, css::awt::XSpinListener, first, css::awt::SpinEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( SpinListenerMultiplexer, css::awt::XSpinListener, last, css::awt::SpinEvent )
+
+
+// class AdjustmentListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( AdjustmentListenerMultiplexer, css::awt::XAdjustmentListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( AdjustmentListenerMultiplexer, css::awt::XAdjustmentListener, adjustmentValueChanged, css::awt::AdjustmentEvent )
+
+
+// class MenuListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( MenuListenerMultiplexer, css::awt::XMenuListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( MenuListenerMultiplexer, css::awt::XMenuListener, itemHighlighted, css::awt::MenuEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( MenuListenerMultiplexer, css::awt::XMenuListener, itemSelected, css::awt::MenuEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( MenuListenerMultiplexer, css::awt::XMenuListener, itemActivated, css::awt::MenuEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( MenuListenerMultiplexer, css::awt::XMenuListener, itemDeactivated, css::awt::MenuEvent )
+
+
+// class TreeSelectionListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( TreeSelectionListenerMultiplexer, css::view::XSelectionChangeListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TreeSelectionListenerMultiplexer, css::view::XSelectionChangeListener, selectionChanged, css::lang::EventObject )
+
+
+// class TreeSelectionListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( TreeExpansionListenerMultiplexer, css::awt::tree::XTreeExpansionListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TreeExpansionListenerMultiplexer, css::awt::tree::XTreeExpansionListener, requestChildNodes, css::awt::tree::TreeExpansionEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD_EXCEPTION( TreeExpansionListenerMultiplexer, css::awt::tree::XTreeExpansionListener, treeExpanding, css::awt::tree::TreeExpansionEvent, css::awt::tree::ExpandVetoException )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD_EXCEPTION( TreeExpansionListenerMultiplexer, css::awt::tree::XTreeExpansionListener, treeCollapsing, css::awt::tree::TreeExpansionEvent, css::awt::tree::ExpandVetoException )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TreeExpansionListenerMultiplexer, css::awt::tree::XTreeExpansionListener, treeExpanded, css::awt::tree::TreeExpansionEvent )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TreeExpansionListenerMultiplexer, css::awt::tree::XTreeExpansionListener, treeCollapsed, css::awt::tree::TreeExpansionEvent )
+
+
+// class TreeEditListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( TreeEditListenerMultiplexer, css::awt::tree::XTreeEditListener )
+
+
+// class SelectionListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( SelectionListenerMultiplexer, css::awt::grid::XGridSelectionListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( SelectionListenerMultiplexer, css::awt::grid::XGridSelectionListener, selectionChanged, css::awt::grid::GridSelectionEvent )
+
+
+// class SelectionListenerMultiplexer
+
+IMPL_LISTENERMULTIPLEXER_BASEMETHODS( TabPageListenerMultiplexer, css::awt::tab::XTabPageContainerListener )
+IMPL_LISTENERMULTIPLEXER_LISTENERMETHOD( TabPageListenerMultiplexer, css::awt::tab::XTabPageContainerListener, tabPageActivated, css::awt::tab::TabPageActivatedEvent )
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/toolkit/source/helper/property.cxx b/toolkit/source/helper/property.cxx
new file mode 100644
index 000000000..cdcba6f2d
--- /dev/null
+++ b/toolkit/source/helper/property.cxx
@@ -0,0 +1,380 @@
+/* -*- 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 <toolkit/helper/property.hxx>
+
+#include <tools/debug.hxx>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/tree/XTreeDataModel.hpp>
+#include <com/sun/star/awt/grid/XGridDataModel.hpp>
+#include <com/sun/star/awt/grid/XGridColumnModel.hpp>
+#include <com/sun/star/view/SelectionType.hpp>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <algorithm>
+#include <string_view>
+
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::awt::XDevice;
+using ::com::sun::star::awt::FontDescriptor;
+using ::com::sun::star::style::VerticalAlignment;
+using ::com::sun::star::graphic::XGraphic;
+
+using namespace com::sun::star;
+
+namespace {
+
+struct ImplPropertyInfo
+{
+ OUString aName;
+ sal_uInt16 nPropId;
+ css::uno::Type aType;
+ sal_Int16 nAttribs;
+ bool bDependsOnOthers; // eg. VALUE depends on MIN/MAX and must be set after MIN/MAX.
+
+ ImplPropertyInfo( OUString const & theName, sal_uInt16 nId, const css::uno::Type& rType,
+ sal_Int16 nAttrs, bool bDepends = false )
+ : aName(theName)
+ , nPropId(nId)
+ , aType(rType)
+ , nAttribs(nAttrs)
+ , bDependsOnOthers(bDepends)
+ {
+ }
+
+};
+
+}
+
+#define DECL_PROP_1( asciiname, id, type, attrib1 ) \
+ ImplPropertyInfo( asciiname, BASEPROPERTY_##id, cppu::UnoType<type>::get(), css::beans::PropertyAttribute::attrib1 )
+#define DECL_PROP_2( asciiname, id, type, attrib1, attrib2 ) \
+ ImplPropertyInfo( asciiname, BASEPROPERTY_##id, cppu::UnoType<type>::get(), css::beans::PropertyAttribute::attrib1 | css::beans::PropertyAttribute::attrib2 )
+#define DECL_PROP_3( asciiname, id, type, attrib1, attrib2, attrib3 ) \
+ ImplPropertyInfo( asciiname, BASEPROPERTY_##id, cppu::UnoType<type>::get(), css::beans::PropertyAttribute::attrib1 | css::beans::PropertyAttribute::attrib2 | css::beans::PropertyAttribute::attrib3 )
+
+#define DECL_DEP_PROP_2( asciiname, id, type, attrib1, attrib2 ) \
+ ImplPropertyInfo( asciiname, BASEPROPERTY_##id, cppu::UnoType<type>::get(), css::beans::PropertyAttribute::attrib1 | css::beans::PropertyAttribute::attrib2, true )
+#define DECL_DEP_PROP_3( asciiname, id, type, attrib1, attrib2, attrib3 ) \
+ ImplPropertyInfo( asciiname, BASEPROPERTY_##id, cppu::UnoType<type>::get(), css::beans::PropertyAttribute::attrib1 | css::beans::PropertyAttribute::attrib2 | css::beans::PropertyAttribute::attrib3, true )
+
+static ImplPropertyInfo* ImplGetPropertyInfos( sal_uInt16& rElementCount )
+{
+ static ImplPropertyInfo aImplPropertyInfos [] = {
+ DECL_PROP_2 ( "AccessibleName", ACCESSIBLENAME, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "Align", ALIGN, sal_Int16, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "Autocomplete", AUTOCOMPLETE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "AutoHScroll", AUTOHSCROLL, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_1 ( "AutoMnemonics", AUTOMNEMONICS, bool, BOUND ),
+ DECL_PROP_2 ( "AutoToggle", AUTOTOGGLE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "AutoVScroll", AUTOVSCROLL, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "BackgroundColor", BACKGROUNDCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_DEP_PROP_2 ( "BlockIncrement", BLOCKINCREMENT, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "Border", BORDER, sal_Int16, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_DEP_PROP_3 ( "BorderColor", BORDERCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "Closeable", CLOSEABLE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "CurrencySymbol", CURRENCYSYMBOL, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "CustomUnitText", CUSTOMUNITTEXT, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_DEP_PROP_3 ( "Date", DATE, util::Date, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "DateFormat", EXTDATEFORMAT, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "DateMax", DATEMAX, util::Date, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "DateMin", DATEMIN, util::Date, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "DateShowCentury", DATESHOWCENTURY, bool, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "DecimalAccuracy", DECIMALACCURACY, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "DefaultButton", DEFAULTBUTTON, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "DefaultControl", DEFAULTCONTROL, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "DesktopAsParent", DESKTOP_AS_PARENT, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "DisplayBackgroundColor", DISPLAYBACKGROUNDCOLOR, sal_Int32, BOUND, MAYBEVOID ),
+ DECL_PROP_2 ( "Dropdown", DROPDOWN, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "EchoChar", ECHOCHAR, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "EditMask", EDITMASK, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "EffectiveDefault", EFFECTIVE_DEFAULT, Any, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "EffectiveMax", EFFECTIVE_MAX, double, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "EffectiveMin", EFFECTIVE_MIN, double, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_DEP_PROP_3 ( "EffectiveValue", EFFECTIVE_VALUE, Any, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "Enabled", ENABLED, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "EnforceFormat", ENFORCE_FORMAT, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "FillColor", FILLCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "FocusOnClick", FOCUSONCLICK, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontRelief", FONTRELIEF, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontEmphasisMark", FONTEMPHASISMARK, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontDescriptor", FONTDESCRIPTOR, FontDescriptor, BOUND, MAYBEDEFAULT ),
+
+ // parts of css::awt::FontDescriptor
+ DECL_PROP_2 ( "FontName", FONTDESCRIPTORPART_NAME, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontStyleName", FONTDESCRIPTORPART_STYLENAME, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontFamily", FONTDESCRIPTORPART_FAMILY, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontCharset", FONTDESCRIPTORPART_CHARSET, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontHeight", FONTDESCRIPTORPART_HEIGHT, float, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontWidth", FONTDESCRIPTORPART_WIDTH, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontPitch", FONTDESCRIPTORPART_PITCH, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontWeight", FONTDESCRIPTORPART_WEIGHT, float, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontCharWidth", FONTDESCRIPTORPART_CHARWIDTH, float, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontOrientation", FONTDESCRIPTORPART_ORIENTATION, float, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontSlant", FONTDESCRIPTORPART_SLANT, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontUnderline", FONTDESCRIPTORPART_UNDERLINE, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontStrikeout", FONTDESCRIPTORPART_STRIKEOUT, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontKerning", FONTDESCRIPTORPART_KERNING, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontWordLineMode", FONTDESCRIPTORPART_WORDLINEMODE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "FontType", FONTDESCRIPTORPART_TYPE, sal_Int16, BOUND, MAYBEDEFAULT ),
+
+ DECL_PROP_3 ( "FormatKey", FORMATKEY, sal_Int32, BOUND, MAYBEVOID, TRANSIENT ),
+ DECL_PROP_3 ( "FormatsSupplier", FORMATSSUPPLIER, Reference< css::util::XNumberFormatsSupplier >, BOUND, MAYBEVOID, TRANSIENT ),
+
+ DECL_PROP_2 ( "Graphic", GRAPHIC, Reference< XGraphic >, BOUND, TRANSIENT ),
+ DECL_PROP_2 ( "GroupName", GROUPNAME, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "HelpText", HELPTEXT, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "HelpURL", HELPURL, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "HideInactiveSelection", HIDEINACTIVESELECTION, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "HighContrastMode", HIGHCONTRASTMODE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "HScroll", HSCROLL, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "HardLineBreaks", HARDLINEBREAKS, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ImageAlign", IMAGEALIGN, sal_Int16, BOUND, MAYBEDEFAULT),
+ DECL_PROP_2 ( "ImagePosition", IMAGEPOSITION, sal_Int16, BOUND, MAYBEDEFAULT),
+ DECL_PROP_2 ( "ImageURL", IMAGEURL, css::uno::Any, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "ItemSeparatorPos", ITEM_SEPARATOR_POS, sal_Int16, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "Label", LABEL, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "LineColor", LINECOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "LineCount", LINECOUNT, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "LineEndFormat", LINE_END_FORMAT, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_DEP_PROP_2 ( "LineIncrement", LINEINCREMENT, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "LiteralMask", LITERALMASK, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "LiveScroll", LIVE_SCROLL, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "MaxTextLen", MAXTEXTLEN, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Moveable", MOVEABLE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_1 ( "MouseTransparent", MOUSETRANSPARENT, bool, BOUND ),
+ DECL_PROP_2 ( "MultiLine", MULTILINE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "MultiSelection", MULTISELECTION, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "MultiSelectionSimpleMode", MULTISELECTION_SIMPLEMODE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "NativeWidgetLook", NATIVE_WIDGET_LOOK, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "NoLabel", NOLABEL, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Orientation", ORIENTATION, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "PaintTransparent", PAINTTRANSPARENT, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "PluginParent", PLUGINPARENT, sal_Int64, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "PrependCurrencySymbol", CURSYM_POSITION, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Printable", PRINTABLE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_DEP_PROP_3 ( "ProgressValue", PROGRESSVALUE, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "ProgressValueMax", PROGRESSVALUE_MAX, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ProgressValueMin", PROGRESSVALUE_MIN, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "PushButtonType", PUSHBUTTONTYPE, sal_Int16, BOUND, MAYBEDEFAULT),
+ DECL_PROP_2 ( "ReadOnly", READONLY, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Repeat", REPEAT, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "AutoRepeat", AUTO_REPEAT, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "RepeatDelay", REPEAT_DELAY, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ScaleImage", SCALEIMAGE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_DEP_PROP_2 ( "ScaleMode", IMAGE_SCALE_MODE, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_DEP_PROP_3 ( "ScrollValue", SCROLLVALUE, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "ScrollValueMax", SCROLLVALUE_MAX, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ScrollValueMin", SCROLLVALUE_MIN, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ScrollWidth", SCROLLWIDTH, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ScrollHeight", SCROLLHEIGHT, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ScrollTop", SCROLLTOP, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ScrollLeft", SCROLLLEFT, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_DEP_PROP_2 ( "SelectedItems", SELECTEDITEMS, Sequence<sal_Int16>, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ShowThousandsSeparator", NUMSHOWTHOUSANDSEP, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Sizeable", SIZEABLE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Spin", SPIN, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "SpinIncrement", SPININCREMENT, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_DEP_PROP_2 ( "SpinValue", SPINVALUE, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "SpinValueMax", SPINVALUE_MAX, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "SpinValueMin", SPINVALUE_MIN, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_DEP_PROP_2 ( "State", STATE, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "StrictFormat", STRICTFORMAT, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "StringItemList", STRINGITEMLIST, Sequence< OUString >, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "TypedItemList", TYPEDITEMLIST, Sequence< Any >, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "VisualEffect", VISUALEFFECT, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "SymbolColor", SYMBOL_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "Tabstop", TABSTOP, bool, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "Text", TEXT, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "TextColor", TEXTCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "TextLineColor", TEXTLINECOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_DEP_PROP_3 ( "Time", TIME, util::Time, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "TimeFormat", EXTTIMEFORMAT, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "TimeMax", TIMEMAX, util::Time, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "TimeMin", TIMEMIN, util::Time, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Title", TITLE, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Toggle", TOGGLE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "TreatAsNumber", TREATASNUMBER, bool, BOUND, MAYBEDEFAULT,TRANSIENT ),
+ DECL_PROP_2 ( "TriState", TRISTATE, bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Unit", UNIT, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "VScroll", VSCROLL, bool, BOUND, MAYBEDEFAULT ),
+ DECL_DEP_PROP_3 ( "Value", VALUE_DOUBLE, double, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "ValueMax", VALUEMAX_DOUBLE, double, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ValueMin", VALUEMIN_DOUBLE, double, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ValueStep", VALUESTEP_DOUBLE, double, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "VerticalAlign", VERTICALALIGN, VerticalAlignment, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_DEP_PROP_3 ( "VisibleSize", VISIBLESIZE, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "Activated", ACTIVATED, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Complete", COMPLETE, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "CurrentItemID", CURRENTITEMID, sal_Int16, BOUND, MAYBEDEFAULT ),
+
+ DECL_PROP_2 ( "MouseWheelBehavior", MOUSE_WHEEL_BEHAVIOUR, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "StepTime", STEP_TIME, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Decoration", DECORATION, sal_Bool, BOUND, MAYBEDEFAULT ),
+
+ DECL_PROP_2 ( "SelectionType", TREE_SELECTIONTYPE, css::view::SelectionType, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "Editable", TREE_EDITABLE, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "DataModel", TREE_DATAMODEL, Reference< css::awt::tree::XTreeDataModel >,BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "RootDisplayed", TREE_ROOTDISPLAYED, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ShowsHandles", TREE_SHOWSHANDLES, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ShowsRootHandles", TREE_SHOWSROOTHANDLES, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "RowHeight", ROW_HEIGHT, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "InvokesStopNodeEditing", TREE_INVOKESSTOPNODEEDITING, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "DialogSourceURL", DIALOGSOURCEURL, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "URL", URL, OUString, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "WritingMode", WRITING_MODE, sal_Int16, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "ContextWritingMode", CONTEXT_WRITING_MODE, sal_Int16, BOUND, MAYBEDEFAULT, TRANSIENT ),
+ DECL_PROP_2 ( "ShowRowHeader", GRID_SHOWROWHEADER, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "RowHeaderWidth", ROW_HEADER_WIDTH, sal_Int32, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_2 ( "ShowColumnHeader", GRID_SHOWCOLUMNHEADER, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "ColumnHeaderHeight", COLUMN_HEADER_HEIGHT, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_1 ( "GridDataModel", GRID_DATAMODEL, Reference< css::awt::grid::XGridDataModel >, BOUND ),
+ DECL_PROP_1 ( "ColumnModel", GRID_COLUMNMODEL, Reference< css::awt::grid::XGridColumnModel >, BOUND ),
+ DECL_PROP_3 ( "SelectionModel", GRID_SELECTIONMODE, css::view::SelectionType, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "EnableVisible", ENABLEVISIBLE, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "ReferenceDevice", REFERENCE_DEVICE, Reference< XDevice >,BOUND, MAYBEDEFAULT, TRANSIENT ),
+ DECL_PROP_3 ( "HeaderBackgroundColor", GRID_HEADER_BACKGROUND, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "HeaderTextColor", GRID_HEADER_TEXT_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "GridLineColor", GRID_LINE_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "RowBackgroundColors", GRID_ROW_BACKGROUND_COLORS, Sequence< sal_Int32 >, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_2 ( "UseGridLines", USE_GRID_LINES, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_DEP_PROP_3 ( "MultiPageValue", MULTIPAGEVALUE, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "AllDialogChildren", USERFORMCONTAINEES, Reference< css::container::XNameContainer >, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "ActiveSelectionBackgroundColor", ACTIVE_SEL_BACKGROUND_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "InactiveSelectionBackgroundColor", INACTIVE_SEL_BACKGROUND_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "ActiveSelectionTextColor", ACTIVE_SEL_TEXT_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "InactiveSelectionTextColor", INACTIVE_SEL_TEXT_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ };
+ rElementCount = SAL_N_ELEMENTS(aImplPropertyInfos);
+ return aImplPropertyInfos;
+}
+
+namespace {
+
+struct ImplPropertyInfoCompareFunctor
+{
+ bool operator()(const ImplPropertyInfo& lhs,const ImplPropertyInfo& rhs) const
+ {
+ return lhs.aName.compareTo(rhs.aName) < 0;
+ }
+ bool operator()(const ImplPropertyInfo& lhs,std::u16string_view rhs) const
+ {
+ return lhs.aName.compareTo(rhs) < 0;
+ }
+};
+
+}
+
+static void ImplAssertValidPropertyArray()
+{
+ static bool bSorted = false;
+ if( !bSorted )
+ {
+ sal_uInt16 nElements;
+ ImplPropertyInfo* pInfo = ImplGetPropertyInfos( nElements );
+ ::std::sort(pInfo, pInfo+nElements,ImplPropertyInfoCompareFunctor());
+ bSorted = true;
+ }
+}
+
+sal_uInt16 GetPropertyId( const OUString& rPropertyName )
+{
+ ImplAssertValidPropertyArray();
+
+ sal_uInt16 nElements;
+ ImplPropertyInfo* pInfo = ImplGetPropertyInfos( nElements );
+ ImplPropertyInfo* pInf = ::std::lower_bound(pInfo,pInfo+nElements,rPropertyName,ImplPropertyInfoCompareFunctor());
+/*
+ (ImplPropertyInfo*)
+ bsearch( &aSearch, pInfo, nElements, sizeof( ImplPropertyInfo ), ImplPropertyInfoCompare );
+*/
+
+ return ( pInf && pInf != (pInfo+nElements) && pInf->aName == rPropertyName) ? pInf->nPropId: 0;
+}
+
+static const ImplPropertyInfo* ImplGetImplPropertyInfo( sal_uInt16 nPropertyId )
+{
+ ImplAssertValidPropertyArray();
+
+ sal_uInt16 nElements;
+ ImplPropertyInfo* pInfo = ImplGetPropertyInfos( nElements );
+ sal_uInt16 n;
+ for ( n = 0; n < nElements && pInfo[n].nPropId != nPropertyId; ++n)
+ ;
+
+ return (n < nElements) ? &pInfo[n] : nullptr;
+}
+
+sal_uInt16 GetPropertyOrderNr( sal_uInt16 nPropertyId )
+{
+ ImplAssertValidPropertyArray();
+
+ sal_uInt16 nElements;
+ ImplPropertyInfo* pInfo = ImplGetPropertyInfos( nElements );
+ for ( sal_uInt16 n = nElements; n; )
+ {
+ if ( pInfo[--n].nPropId == nPropertyId )
+ return n;
+ }
+ return 0xFFFF;
+}
+
+const OUString& GetPropertyName( sal_uInt16 nPropertyId )
+{
+ const ImplPropertyInfo* pImplPropertyInfo = ImplGetImplPropertyInfo( nPropertyId );
+ assert(pImplPropertyInfo && "Invalid PropertyId!");
+ return pImplPropertyInfo->aName;
+}
+
+const css::uno::Type* GetPropertyType( sal_uInt16 nPropertyId )
+{
+ const ImplPropertyInfo* pImplPropertyInfo = ImplGetImplPropertyInfo( nPropertyId );
+ DBG_ASSERT( pImplPropertyInfo, "Invalid PropertyId!" );
+ return pImplPropertyInfo ? &pImplPropertyInfo->aType : nullptr;
+}
+
+sal_Int16 GetPropertyAttribs( sal_uInt16 nPropertyId )
+{
+ const ImplPropertyInfo* pImplPropertyInfo = ImplGetImplPropertyInfo( nPropertyId );
+ DBG_ASSERT( pImplPropertyInfo, "Invalid PropertyId!" );
+ return pImplPropertyInfo ? pImplPropertyInfo->nAttribs : 0;
+}
+
+bool DoesDependOnOthers( sal_uInt16 nPropertyId )
+{
+ const ImplPropertyInfo* pImplPropertyInfo = ImplGetImplPropertyInfo( nPropertyId );
+ DBG_ASSERT( pImplPropertyInfo, "Invalid PropertyId!" );
+ return pImplPropertyInfo && pImplPropertyInfo->bDependsOnOthers;
+}
+
+bool CompareProperties( const css::uno::Any& r1, const css::uno::Any& r2 )
+{
+ return r1 == r2;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/toolkit/source/helper/servicenames.cxx b/toolkit/source/helper/servicenames.cxx
new file mode 100644
index 000000000..825672fd2
--- /dev/null
+++ b/toolkit/source/helper/servicenames.cxx
@@ -0,0 +1,24 @@
+/* -*- 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 <helper/servicenames.hxx>
+
+const char szServiceName_UnoControlDialog[] = "stardiv.vcl.control.Dialog";
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/toolkit/source/helper/tkresmgr.cxx b/toolkit/source/helper/tkresmgr.cxx
new file mode 100644
index 000000000..418c489f0
--- /dev/null
+++ b/toolkit/source/helper/tkresmgr.cxx
@@ -0,0 +1,57 @@
+/* -*- 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 <comphelper/processfactory.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <tools/diagnose_ex.h>
+
+#include <vcl/image.hxx>
+
+#include <helper/tkresmgr.hxx>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::graphic::XGraphic;
+using ::com::sun::star::graphic::XGraphicProvider;
+using namespace ::com::sun::star;
+
+Image TkResMgr::getImageFromURL(const OUString& i_rImageURL)
+{
+ if (i_rImageURL.isEmpty())
+ return Image();
+
+ try
+ {
+ Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext());
+ Reference<XGraphicProvider> xProvider(graphic::GraphicProvider::create(xContext));
+ ::comphelper::NamedValueCollection aMediaProperties;
+ aMediaProperties.put("URL", i_rImageURL);
+ Reference<XGraphic> xGraphic
+ = xProvider->queryGraphic(aMediaProperties.getPropertyValues());
+ return Image(xGraphic);
+ }
+ catch (const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("toolkit");
+ }
+ return Image();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/toolkit/source/helper/unopropertyarrayhelper.cxx b/toolkit/source/helper/unopropertyarrayhelper.cxx
new file mode 100644
index 000000000..0a36f4bf3
--- /dev/null
+++ b/toolkit/source/helper/unopropertyarrayhelper.cxx
@@ -0,0 +1,148 @@
+/* -*- 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 <toolkit/helper/property.hxx>
+#include <map>
+
+#include <helper/unopropertyarrayhelper.hxx>
+
+
+
+UnoPropertyArrayHelper::UnoPropertyArrayHelper( const css::uno::Sequence<sal_Int32>& rIDs )
+{
+ for ( const sal_Int32 nID : rIDs )
+ maIDs.insert( nID );
+}
+
+UnoPropertyArrayHelper::UnoPropertyArrayHelper( const std::vector< sal_uInt16 > &rIDs )
+{
+ for (const auto& rId : rIDs)
+ maIDs.insert( rId );
+}
+
+bool UnoPropertyArrayHelper::ImplHasProperty( sal_uInt16 nPropId ) const
+{
+ if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
+ nPropId = BASEPROPERTY_FONTDESCRIPTOR;
+
+ return maIDs.find( nPropId ) != maIDs.end();
+}
+
+// ::cppu::IPropertyArrayHelper
+sal_Bool UnoPropertyArrayHelper::fillPropertyMembersByHandle( OUString * pPropName, sal_Int16 * pAttributes, sal_Int32 nPropId )
+{
+ sal_uInt16 id = sal::static_int_cast< sal_uInt16 >(nPropId);
+ bool bValid = ImplHasProperty( id );
+ if ( bValid )
+ {
+ if ( pPropName )
+ *pPropName = GetPropertyName( id );
+ if ( pAttributes )
+ *pAttributes = GetPropertyAttribs( id );
+ }
+ return bValid;
+}
+
+css::uno::Sequence< css::beans::Property > UnoPropertyArrayHelper::getProperties()
+{
+ // Sort by names ...
+
+ std::map<sal_Int32, sal_uInt16> aSortedPropsIds;
+ for (const auto& rId : maIDs)
+ {
+ sal_uInt16 nId = sal::static_int_cast< sal_uInt16 >(rId);
+ aSortedPropsIds[ 1+GetPropertyOrderNr( nId ) ] = nId;
+
+ if ( nId == BASEPROPERTY_FONTDESCRIPTOR )
+ {
+ // single properties ...
+ for ( sal_uInt16 i = BASEPROPERTY_FONTDESCRIPTORPART_START; i <= BASEPROPERTY_FONTDESCRIPTORPART_END; i++ )
+ aSortedPropsIds[ 1+GetPropertyOrderNr( i ) ] = i;
+ }
+ }
+
+ sal_uInt32 nProps = aSortedPropsIds.size(); // could be more now
+ css::uno::Sequence< css::beans::Property> aProps( nProps );
+ css::beans::Property* pProps = aProps.getArray();
+
+ sal_uInt32 n = 0;
+ for ( const auto& rPropIds : aSortedPropsIds )
+ {
+ sal_uInt16 nId = rPropIds.second;
+ pProps[n].Name = GetPropertyName( nId );
+ pProps[n].Handle = nId;
+ pProps[n].Type = *GetPropertyType( nId );
+ pProps[n].Attributes = GetPropertyAttribs( nId );
+ ++n;
+ }
+
+ return aProps;
+}
+
+css::beans::Property UnoPropertyArrayHelper::getPropertyByName(const OUString& rPropertyName)
+{
+ css::beans::Property aProp;
+ sal_uInt16 nId = GetPropertyId( rPropertyName );
+ if ( ImplHasProperty( nId ) )
+ {
+ aProp.Name = rPropertyName;
+ aProp.Handle = -1;
+ aProp.Type = *GetPropertyType( nId );
+ aProp.Attributes = GetPropertyAttribs( nId );
+ }
+
+ return aProp;
+}
+
+sal_Bool UnoPropertyArrayHelper::hasPropertyByName(const OUString& rPropertyName)
+{
+ return ImplHasProperty( GetPropertyId( rPropertyName ) );
+}
+
+sal_Int32 UnoPropertyArrayHelper::getHandleByName( const OUString & rPropertyName )
+{
+ sal_Int32 nId = static_cast<sal_Int32>(GetPropertyId( rPropertyName ));
+ return nId ? nId : -1;
+}
+
+sal_Int32 UnoPropertyArrayHelper::fillHandles( sal_Int32* pHandles, const css::uno::Sequence< OUString > & rPropNames )
+{
+ const OUString* pNames = rPropNames.getConstArray();
+ sal_Int32 nValues = rPropNames.getLength();
+ sal_Int32 nValidHandles = 0;
+
+ for ( sal_Int32 n = 0; n < nValues; n++ )
+ {
+ sal_uInt16 nPropId = GetPropertyId( pNames[n] );
+ if ( nPropId && ImplHasProperty( nPropId ) )
+ {
+ pHandles[n] = nPropId;
+ nValidHandles++;
+ }
+ else
+ {
+ pHandles[n] = -1;
+ }
+ }
+ return nValidHandles;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/toolkit/source/helper/unowrapper.cxx b/toolkit/source/helper/unowrapper.cxx
new file mode 100644
index 000000000..080847154
--- /dev/null
+++ b/toolkit/source/helper/unowrapper.cxx
@@ -0,0 +1,314 @@
+/* -*- 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 <toolkit/helper/vclunohelper.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <toolkit/awt/vclxwindows.hxx>
+#include <toolkit/awt/vclxmenu.hxx>
+#include <awt/vclxcontainer.hxx>
+#include <awt/vclxgraphics.hxx>
+#include <awt/vclxtopwindow.hxx>
+#include <awt/vclxwindows.hxx>
+
+#include <toolkit/dllapi.h>
+#include <vcl/menu.hxx>
+
+#include <helper/unowrapper.hxx>
+
+using namespace ::com::sun::star;
+
+static rtl::Reference<VCLXWindow> CreateXWindow( vcl::Window const * pWindow )
+{
+ switch ( pWindow->GetType() )
+ {
+ case WindowType::IMAGEBUTTON:
+ case WindowType::SPINBUTTON:
+ case WindowType::MENUBUTTON:
+ case WindowType::MOREBUTTON:
+ case WindowType::PUSHBUTTON:
+ case WindowType::HELPBUTTON:
+ case WindowType::OKBUTTON:
+ case WindowType::CANCELBUTTON: return new VCLXButton;
+ case WindowType::CHECKBOX: return new VCLXCheckBox;
+ // #i95042#
+ // A Window of type <MetricBox> is inherited from type <ComboBox>.
+ // Thus, it does make more sense to return a <VCLXComboBox> instance
+ // instead of only a <VCLXWindow> instance, especially regarding its
+ // corresponding accessibility API.
+ case WindowType::METRICBOX:
+ case WindowType::COMBOBOX: return new VCLXComboBox;
+ case WindowType::FORMATTEDFIELD: return new SVTXNumericField;
+ case WindowType::SPINFIELD:
+ case WindowType::CURRENCYFIELD: return new VCLXNumericField;
+ case WindowType::DATEFIELD: return new VCLXDateField;
+ case WindowType::MULTILINEEDIT:
+ case WindowType::EDIT: return new VCLXEdit;
+ case WindowType::METRICFIELD: return new VCLXSpinField;
+ case WindowType::MESSBOX:
+ case WindowType::INFOBOX:
+ case WindowType::WARNINGBOX:
+ case WindowType::QUERYBOX:
+ case WindowType::ERRORBOX: return new VCLXMessageBox;
+ case WindowType::FIXEDIMAGE: return new VCLXImageControl;
+ case WindowType::FIXEDTEXT: return new VCLXFixedText;
+ case WindowType::MULTILISTBOX:
+ case WindowType::LISTBOX: return new VCLXListBox;
+ case WindowType::DIALOG:
+ case WindowType::TABDIALOG:
+ case WindowType::BUTTONDIALOG:
+ case WindowType::MODELESSDIALOG: return new VCLXDialog;
+ case WindowType::PATTERNFIELD: return new VCLXPatternField;
+ case WindowType::RADIOBUTTON: return new VCLXRadioButton;
+ case WindowType::SCROLLBAR: return new VCLXScrollBar;
+ case WindowType::TIMEFIELD: return new VCLXTimeField;
+
+ case WindowType::WORKWINDOW:
+ case WindowType::DOCKINGWINDOW:
+ case WindowType::FLOATINGWINDOW:
+ case WindowType::HELPTEXTWINDOW: return new VCLXTopWindow;
+
+ case WindowType::WINDOW:
+ case WindowType::TABPAGE: return new VCLXContainer;
+
+ case WindowType::TOOLBOX: return new VCLXToolBox;
+ case WindowType::TABCONTROL: return new VCLXMultiPage;
+
+ case WindowType::HEADERBAR: return new VCLXHeaderBar;
+
+ // case WindowType::FIXEDLINE:
+ // case WindowType::FIXEDBITMAP:
+ // case WindowType::DATEBOX:
+ // case WindowType::GROUPBOX:
+ // case WindowType::LONGCURRENCYBOX:
+ // case WindowType::SPLITTER:
+ // case WindowType::STATUSBAR:
+ // case WindowType::TABCONTROL:
+ // case WindowType::NUMERICBOX:
+ // case WindowType::TRISTATEBOX:
+ // case WindowType::TIMEBOX:
+ // case WindowType::SPLITWINDOW:
+ // case WindowType::SCROLLBARBOX:
+ // case WindowType::PATTERNBOX:
+ // case WindowType::CURRENCYBOX:
+ default: return new VCLXWindow( true );
+ }
+}
+
+
+
+
+extern "C" {
+
+TOOLKIT_DLLPUBLIC UnoWrapperBase* CreateUnoWrapper()
+{
+ return new UnoWrapper( nullptr );
+}
+
+} // extern "C"
+
+
+UnoWrapper::UnoWrapper( const css::uno::Reference< css::awt::XToolkit>& rxToolkit )
+{
+ mxToolkit = rxToolkit;
+}
+
+void UnoWrapper::Destroy()
+{
+ delete this;
+}
+
+UnoWrapper::~UnoWrapper()
+{
+}
+
+css::uno::Reference< css::awt::XToolkit> UnoWrapper::GetVCLToolkit()
+{
+ if ( !mxToolkit.is() )
+ mxToolkit = VCLUnoHelper::CreateToolkit();
+ return mxToolkit;
+}
+
+css::uno::Reference< css::awt::XWindowPeer> UnoWrapper::GetWindowInterface( vcl::Window* pWindow )
+{
+ css::uno::Reference< css::awt::XWindowPeer> xPeer = pWindow->GetWindowPeer();
+ if ( xPeer )
+ return xPeer;
+
+ rtl::Reference<VCLXWindow> xVCLXWindow = CreateXWindow( pWindow );
+ xVCLXWindow->SetWindow( pWindow );
+ pWindow->SetWindowPeer( xVCLXWindow, xVCLXWindow.get() );
+ return xVCLXWindow;
+}
+
+VclPtr<vcl::Window> UnoWrapper::GetWindow(const css::uno::Reference<css::awt::XWindow>& rWindow)
+{
+ return VCLUnoHelper::GetWindow(rWindow);
+}
+
+void UnoWrapper::SetWindowInterface( vcl::Window* pWindow, const css::uno::Reference< css::awt::XWindowPeer> & xIFace )
+{
+ VCLXWindow* pVCLXWindow = comphelper::getFromUnoTunnel<VCLXWindow>( xIFace );
+
+ assert( pVCLXWindow && "must be a VCLXWindow subclass" );
+ if ( !pVCLXWindow )
+ return;
+
+ if (!pWindow)
+ {
+ // we are disconnecting a peer from a window
+ pVCLXWindow->SetWindow( nullptr );
+ }
+ else
+ {
+ css::uno::Reference< css::awt::XWindowPeer> xPeer = pWindow->GetWindowPeer();
+ if( xPeer.is() )
+ {
+ bool bSameInstance( pVCLXWindow == dynamic_cast< VCLXWindow* >( xPeer.get() ));
+ SAL_WARN_IF( !bSameInstance, "toolkit.helper", "UnoWrapper::SetWindowInterface: there is already a WindowPeer/ComponentInterface for this VCL window" );
+ if ( bSameInstance )
+ return;
+ }
+ pVCLXWindow->SetWindow( pWindow );
+ pWindow->SetWindowPeer( xIFace, pVCLXWindow );
+ }
+}
+
+css::uno::Reference<css::awt::XPopupMenu> UnoWrapper::CreateMenuInterface( PopupMenu* pPopupMenu )
+{
+ return new VCLXPopupMenu(pPopupMenu);
+}
+
+css::uno::Reference< css::awt::XGraphics> UnoWrapper::CreateGraphics( OutputDevice* pOutDev )
+{
+ rtl::Reference<VCLXGraphics> pGrf = new VCLXGraphics;
+ pGrf->Init( pOutDev );
+ return pGrf;
+}
+
+void UnoWrapper::ReleaseAllGraphics( OutputDevice* pOutDev )
+{
+ std::vector< VCLXGraphics* > *pLst = pOutDev->GetUnoGraphicsList();
+ if ( pLst )
+ {
+ for (VCLXGraphics* pGrf : *pLst)
+ {
+ pGrf->SetOutputDevice( nullptr );
+ }
+ }
+
+}
+
+static bool lcl_ImplIsParent( vcl::Window const * pParentWindow, vcl::Window* pPossibleChild )
+{
+ vcl::Window* pWindow = ( pPossibleChild != pParentWindow ) ? pPossibleChild : nullptr;
+ while ( pWindow && ( pWindow != pParentWindow ) )
+ pWindow = pWindow->GetParent();
+
+ return pWindow != nullptr;
+}
+
+void UnoWrapper::WindowDestroyed( vcl::Window* pWindow )
+{
+ // their still might be some children created with css::loader::Java
+ // that would otherwise not be destroyed until the garbage collector cleans up
+ VclPtr< vcl::Window > pChild = pWindow->GetWindow( GetWindowType::FirstChild );
+ while ( pChild )
+ {
+ VclPtr< vcl::Window > pNextChild = pChild->GetWindow( GetWindowType::Next );
+
+ VclPtr< vcl::Window > pClient = pChild->GetWindow( GetWindowType::Client );
+ if ( pClient && pClient->GetWindowPeer() )
+ {
+ css::uno::Reference< css::lang::XComponent > xComp = pClient->GetComponentInterface( false );
+ xComp->dispose();
+ }
+ else
+ {
+ // We need it to dispose the child windows properly (even without window peer),
+ // otherwise the vcl::Window will be leaked.
+ pClient.disposeAndClear();
+ }
+
+ pChild = pNextChild;
+ }
+
+ // find system windows...
+ VclPtr< vcl::Window > pOverlap = pWindow->GetWindow( GetWindowType::Overlap );
+ if ( pOverlap )
+ {
+ pOverlap = pOverlap->GetWindow( GetWindowType::FirstOverlap );
+ while ( pOverlap )
+ {
+ VclPtr< vcl::Window > pNextOverlap = pOverlap->GetWindow( GetWindowType::Next );
+ VclPtr< vcl::Window > pClient = pOverlap->GetWindow( GetWindowType::Client );
+
+ if ( pClient && pClient->GetWindowPeer() && lcl_ImplIsParent( pWindow, pClient ) )
+ {
+ css::uno::Reference< css::lang::XComponent > xComp = pClient->GetComponentInterface( false );
+ xComp->dispose();
+ }
+
+ pOverlap = pNextOverlap;
+ }
+ }
+
+ {
+ VclPtr< vcl::Window > pParent = pWindow->GetParent();
+ if ( pParent && pParent->GetWindowPeer() )
+ pParent->GetWindowPeer()->notifyWindowRemoved( *pWindow );
+ }
+
+ VCLXWindow* pWindowPeer = pWindow->GetWindowPeer();
+ uno::Reference< lang::XComponent > xWindowPeerComp = pWindow->GetComponentInterface( false );
+ OSL_ENSURE( ( pWindowPeer != nullptr ) == xWindowPeerComp.is(),
+ "UnoWrapper::WindowDestroyed: inconsistency in the window's peers!" );
+ if ( pWindowPeer )
+ {
+ pWindowPeer->SetWindow( nullptr );
+ pWindow->SetWindowPeer( nullptr, nullptr );
+ }
+ if ( xWindowPeerComp.is() )
+ xWindowPeerComp->dispose();
+
+ // #102132# Iterate over frames after setting Window peer to NULL,
+ // because while destroying other frames, we get into the method again and try
+ // to destroy this window again...
+ // #i42462#/#116855# no, don't loop: Instead, just ensure that all our top-window-children
+ // are disposed, too (which should also be a valid fix for #102132#, but doesn't have the extreme
+ // performance penalties)
+ VclPtr< vcl::Window > pTopWindowChild = pWindow->GetWindow( GetWindowType::FirstTopWindowChild );
+ while ( pTopWindowChild )
+ {
+ OSL_ENSURE( pTopWindowChild->GetParent() == pWindow,
+ "UnoWrapper::WindowDestroyed: inconsistency in the SystemWindow relationship!" );
+
+ VclPtr< vcl::Window > pNextTopChild = pTopWindowChild->GetWindow( GetWindowType::NextTopWindowSibling );
+
+ pTopWindowChild.disposeAndClear();
+ pTopWindowChild = pNextTopChild;
+ }
+}
+
+
+css::uno::Reference< css::accessibility::XAccessible > UnoWrapper::CreateAccessible( Menu* pMenu, bool bIsMenuBar )
+{
+ return maAccessibleFactoryAccess.getFactory().createAccessible( pMenu, bIsMenuBar );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/toolkit/source/helper/vclunohelper.cxx b/toolkit/source/helper/vclunohelper.cxx
new file mode 100644
index 000000000..ec9d3ddf3
--- /dev/null
+++ b/toolkit/source/helper/vclunohelper.cxx
@@ -0,0 +1,608 @@
+/* -*- 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 <tools/stream.hxx>
+#include <vcl/dibtools.hxx>
+#include <vcl/event.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/ptrstyle.hxx>
+#include <vcl/unohelp.hxx>
+#include <vcl/window.hxx>
+#include <com/sun/star/util/MeasureUnit.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/SimpleFontMetric.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/awt/MouseButton.hpp>
+#include <com/sun/star/embed/EmbedMapUnits.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <awt/vclxbitmap.hxx>
+#include <awt/vclxregion.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <awt/vclxgraphics.hxx>
+#include <toolkit/awt/vclxfont.hxx>
+#include <controls/unocontrolcontainer.hxx>
+#include <controls/unocontrolcontainermodel.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/awt/Toolkit.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/Point.hpp>
+
+using namespace ::com::sun::star;
+
+
+uno::Reference< css::awt::XToolkit> VCLUnoHelper::CreateToolkit()
+{
+ uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference< awt::XToolkit> xToolkit( awt::Toolkit::create(xContext), uno::UNO_QUERY_THROW );
+ return xToolkit;
+}
+
+BitmapEx VCLUnoHelper::GetBitmap( const css::uno::Reference< css::awt::XBitmap>& rxBitmap )
+{
+ BitmapEx aBmp;
+
+ css::uno::Reference< css::graphic::XGraphic > xGraphic( rxBitmap, css::uno::UNO_QUERY );
+ if( xGraphic.is() )
+ {
+ Graphic aGraphic( xGraphic );
+ aBmp = aGraphic.GetBitmapEx();
+ }
+ else if ( rxBitmap.is() )
+ {
+ VCLXBitmap* pVCLBitmap = comphelper::getFromUnoTunnel<VCLXBitmap>( rxBitmap );
+ if ( pVCLBitmap )
+ aBmp = pVCLBitmap->GetBitmap();
+ else
+ {
+ Bitmap aDIB, aMask;
+ {
+ css::uno::Sequence<sal_Int8> aBytes = rxBitmap->getDIB();
+ SvMemoryStream aMem( aBytes.getArray(), aBytes.getLength(), StreamMode::READ );
+ ReadDIB(aDIB, aMem, true);
+ }
+ {
+ css::uno::Sequence<sal_Int8> aBytes = rxBitmap->getMaskDIB();
+ SvMemoryStream aMem( aBytes.getArray(), aBytes.getLength(), StreamMode::READ );
+ ReadDIB(aMask, aMem, true);
+ }
+ aBmp = BitmapEx( aDIB, aMask );
+ }
+ }
+ return aBmp;
+}
+
+css::uno::Reference< css::awt::XBitmap> VCLUnoHelper::CreateBitmap( const BitmapEx& rBitmap )
+{
+ Graphic aGraphic( rBitmap );
+ css::uno::Reference< css::awt::XBitmap> xBmp( aGraphic.GetXGraphic(), css::uno::UNO_QUERY );
+ return xBmp;
+}
+
+css::uno::Reference< css::awt::XBitmap> VCLUnoHelper::CreateVCLXBitmap( const BitmapEx& rBitmap )
+{
+ return css::uno::Reference< css::awt::XBitmap >(new VCLXBitmap(rBitmap));
+}
+
+vcl::Window* VCLUnoHelper::GetWindow( const css::uno::Reference< css::awt::XWindow>& rxWindow )
+{
+ VCLXWindow* pVCLXWindow = comphelper::getFromUnoTunnel<VCLXWindow>( rxWindow );
+ return pVCLXWindow ? pVCLXWindow->GetWindow() : nullptr;
+}
+
+vcl::Window* VCLUnoHelper::GetWindow( const css::uno::Reference< css::awt::XWindow2>& rxWindow )
+{
+ VCLXWindow* pVCLXWindow = comphelper::getFromUnoTunnel<VCLXWindow>( rxWindow );
+ return pVCLXWindow ? pVCLXWindow->GetWindow() : nullptr;
+}
+
+vcl::Window* VCLUnoHelper::GetWindow( const css::uno::Reference< css::awt::XWindowPeer>& rxWindow )
+{
+ VCLXWindow* pVCLXWindow = comphelper::getFromUnoTunnel<VCLXWindow>( rxWindow );
+ return pVCLXWindow ? pVCLXWindow->GetWindow() : nullptr;
+}
+
+vcl::Region VCLUnoHelper::GetRegion( const css::uno::Reference< css::awt::XRegion >& rxRegion )
+{
+ vcl::Region aRegion;
+ VCLXRegion* pVCLRegion = comphelper::getFromUnoTunnel<VCLXRegion>( rxRegion );
+ if ( pVCLRegion )
+ aRegion = pVCLRegion->GetRegion();
+ else
+ {
+ const css::uno::Sequence< css::awt::Rectangle > aRects = rxRegion->getRectangles();
+ for ( const auto& rRect : aRects )
+ aRegion.Union( VCLRectangle( rRect ) );
+ }
+ return aRegion;
+}
+
+css::uno::Reference< css::awt::XWindow> VCLUnoHelper::GetInterface( vcl::Window* pWindow )
+{
+ css::uno::Reference< css::awt::XWindow > xWin;
+ if ( pWindow )
+ {
+ css::uno::Reference< css::awt::XWindowPeer> xPeer = pWindow->GetComponentInterface();
+ xWin.set(xPeer, css::uno::UNO_QUERY);
+ }
+ return xWin;
+}
+
+OutputDevice* VCLUnoHelper::GetOutputDevice( const css::uno::Reference< css::awt::XDevice>& rxDevice )
+{
+ VclPtr<OutputDevice> pOutDev;
+ VCLXDevice* pDev = comphelper::getFromUnoTunnel<VCLXDevice>( rxDevice );
+ if ( pDev )
+ pOutDev = pDev->GetOutputDevice();
+ return pOutDev;
+}
+
+OutputDevice* VCLUnoHelper::GetOutputDevice( const css::uno::Reference< css::awt::XGraphics>& rxGraphics )
+{
+ OutputDevice* pOutDev = nullptr;
+ VCLXGraphics* pGrf = comphelper::getFromUnoTunnel<VCLXGraphics>( rxGraphics );
+ if ( pGrf )
+ pOutDev = pGrf->GetOutputDevice();
+ return pOutDev;
+}
+
+tools::Polygon VCLUnoHelper::CreatePolygon( const css::uno::Sequence< sal_Int32 >& DataX,
+ const css::uno::Sequence< sal_Int32 >& DataY )
+{
+ sal_Int32 nLen = DataX.getLength();
+ const sal_Int32* pDataX = DataX.getConstArray();
+ const sal_Int32* pDataY = DataY.getConstArray();
+ tools::Polygon aPoly( static_cast<sal_uInt16>(nLen) );
+ for ( sal_Int32 n = 0; n < nLen; n++ )
+ {
+ Point aPnt;
+ aPnt.setX( pDataX[n] );
+ aPnt.setY( pDataY[n] );
+ aPoly[n] = aPnt;
+ }
+ return aPoly;
+}
+
+css::uno::Reference< css::awt::XControlContainer> VCLUnoHelper::CreateControlContainer( vcl::Window* pWindow )
+{
+ rtl::Reference<UnoControlContainer> pContainer = new UnoControlContainer( pWindow->GetComponentInterface() );
+
+ rtl::Reference<UnoControlModel> pContainerModel = new UnoControlContainerModel( ::comphelper::getProcessComponentContext() );
+ pContainer->setModel( pContainerModel );
+
+ return pContainer;
+}
+
+css::awt::FontDescriptor VCLUnoHelper::CreateFontDescriptor( const vcl::Font& rFont )
+{
+ css::awt::FontDescriptor aFD;
+ aFD.Name = rFont.GetFamilyName();
+ aFD.StyleName = rFont.GetStyleName();
+ aFD.Height = static_cast<sal_Int16>(rFont.GetFontSize().Height());
+ aFD.Width = static_cast<sal_Int16>(rFont.GetFontSize().Width());
+ aFD.Family = sal::static_int_cast< sal_Int16 >(rFont.GetFamilyType());
+ aFD.CharSet = rFont.GetCharSet();
+ aFD.Pitch = sal::static_int_cast< sal_Int16 >(rFont.GetPitch());
+ aFD.CharacterWidth = vcl::unohelper::ConvertFontWidth(rFont.GetWidthType());
+ aFD.Weight = vcl::unohelper::ConvertFontWeight(rFont.GetWeight());
+ aFD.Slant = vcl::unohelper::ConvertFontSlant(rFont.GetItalic());
+ aFD.Underline = sal::static_int_cast< sal_Int16 >(rFont.GetUnderline());
+ aFD.Strikeout = sal::static_int_cast< sal_Int16 >(rFont.GetStrikeout());
+ aFD.Orientation = rFont.GetOrientation().get() / 10.0;
+ aFD.Kerning = rFont.IsKerning();
+ aFD.WordLineMode = rFont.IsWordLineMode();
+ aFD.Type = 0; // ??? => Only in Metric...
+ return aFD;
+}
+
+vcl::Font VCLUnoHelper::CreateFont( const css::awt::FontDescriptor& rDescr, const vcl::Font& rInitFont )
+{
+ vcl::Font aFont( rInitFont );
+ if ( !rDescr.Name.isEmpty() )
+ aFont.SetFamilyName( rDescr.Name );
+ if ( !rDescr.StyleName.isEmpty() )
+ aFont.SetStyleName( rDescr.StyleName );
+ if ( rDescr.Height )
+ aFont.SetFontSize( Size( rDescr.Width, rDescr.Height ) );
+ if ( static_cast<FontFamily>(rDescr.Family) != FAMILY_DONTKNOW )
+ aFont.SetFamily( static_cast<FontFamily>(rDescr.Family) );
+ if ( static_cast<rtl_TextEncoding>(rDescr.CharSet) != RTL_TEXTENCODING_DONTKNOW )
+ aFont.SetCharSet( static_cast<rtl_TextEncoding>(rDescr.CharSet) );
+ if ( static_cast<FontPitch>(rDescr.Pitch) != PITCH_DONTKNOW )
+ aFont.SetPitch( static_cast<FontPitch>(rDescr.Pitch) );
+ if ( rDescr.CharacterWidth )
+ aFont.SetWidthType(vcl::unohelper::ConvertFontWidth(rDescr.CharacterWidth));
+ if ( rDescr.Weight )
+ aFont.SetWeight(vcl::unohelper::ConvertFontWeight(rDescr.Weight));
+ if ( rDescr.Slant != css::awt::FontSlant_DONTKNOW )
+ aFont.SetItalic(vcl::unohelper::ConvertFontSlant(rDescr.Slant));
+ if ( static_cast<FontLineStyle>(rDescr.Underline) != LINESTYLE_DONTKNOW )
+ aFont.SetUnderline( static_cast<FontLineStyle>(rDescr.Underline) );
+ if ( static_cast<FontStrikeout>(rDescr.Strikeout) != STRIKEOUT_DONTKNOW )
+ aFont.SetStrikeout( static_cast<FontStrikeout>(rDescr.Strikeout) );
+
+ // Not DONTKNOW
+ aFont.SetOrientation( Degree10(static_cast<sal_Int16>(rDescr.Orientation * 10)) );
+ aFont.SetKerning( static_cast<FontKerning>(rDescr.Kerning) );
+ aFont.SetWordLineMode( rDescr.WordLineMode );
+
+ return aFont;
+}
+
+vcl::Font VCLUnoHelper::CreateFont( const css::uno::Reference< css::awt::XFont >& rxFont )
+{
+ vcl::Font aFont;
+ VCLXFont* pVCLXFont = comphelper::getFromUnoTunnel<VCLXFont>( rxFont );
+ if ( pVCLXFont )
+ aFont = pVCLXFont->GetFont();
+ return aFont;
+}
+
+
+css::awt::SimpleFontMetric VCLUnoHelper::CreateFontMetric( const FontMetric& rFontMetric )
+{
+ css::awt::SimpleFontMetric aFM;
+ aFM.Ascent = static_cast<sal_Int16>(rFontMetric.GetAscent());
+ aFM.Descent = static_cast<sal_Int16>(rFontMetric.GetDescent());
+ aFM.Leading = static_cast<sal_Int16>(rFontMetric.GetInternalLeading());
+ aFM.Slant = static_cast<sal_Int16>(rFontMetric.GetSlant());
+ aFM.FirstChar = 0x0020;
+ aFM.LastChar = 0xFFFD;
+ return aFM;
+}
+
+bool VCLUnoHelper::IsZero(const css::awt::Rectangle& rRect)
+{
+ return ( !rRect.X && !rRect.Y && !rRect.Width && !rRect.Height );
+}
+
+MapUnit VCLUnoHelper::UnoEmbed2VCLMapUnit( sal_Int32 nUnoEmbedMapUnit )
+{
+ switch( nUnoEmbedMapUnit )
+ {
+ case css::embed::EmbedMapUnits::ONE_100TH_MM:
+ return MapUnit::Map100thMM;
+ case css::embed::EmbedMapUnits::ONE_10TH_MM:
+ return MapUnit::Map10thMM;
+ case css::embed::EmbedMapUnits::ONE_MM:
+ return MapUnit::MapMM;
+ case css::embed::EmbedMapUnits::ONE_CM:
+ return MapUnit::MapCM;
+ case css::embed::EmbedMapUnits::ONE_1000TH_INCH:
+ return MapUnit::Map1000thInch;
+ case css::embed::EmbedMapUnits::ONE_100TH_INCH:
+ return MapUnit::Map100thInch;
+ case css::embed::EmbedMapUnits::ONE_10TH_INCH:
+ return MapUnit::Map10thInch;
+ case css::embed::EmbedMapUnits::ONE_INCH:
+ return MapUnit::MapInch;
+ case css::embed::EmbedMapUnits::POINT:
+ return MapUnit::MapPoint;
+ case css::embed::EmbedMapUnits::TWIP:
+ return MapUnit::MapTwip;
+ case css::embed::EmbedMapUnits::PIXEL:
+ return MapUnit::MapPixel;
+ }
+
+ OSL_FAIL( "Unexpected UNO map mode is provided!" );
+ return MapUnit::LASTENUMDUMMY;
+}
+
+sal_Int32 VCLUnoHelper::VCL2UnoEmbedMapUnit( MapUnit nVCLMapUnit )
+{
+ switch( nVCLMapUnit )
+ {
+ case MapUnit::Map100thMM:
+ return css::embed::EmbedMapUnits::ONE_100TH_MM;
+ case MapUnit::Map10thMM:
+ return css::embed::EmbedMapUnits::ONE_10TH_MM;
+ case MapUnit::MapMM:
+ return css::embed::EmbedMapUnits::ONE_MM;
+ case MapUnit::MapCM:
+ return css::embed::EmbedMapUnits::ONE_CM;
+ case MapUnit::Map1000thInch:
+ return css::embed::EmbedMapUnits::ONE_1000TH_INCH;
+ case MapUnit::Map100thInch:
+ return css::embed::EmbedMapUnits::ONE_100TH_INCH;
+ case MapUnit::Map10thInch:
+ return css::embed::EmbedMapUnits::ONE_10TH_INCH;
+ case MapUnit::MapInch:
+ return css::embed::EmbedMapUnits::ONE_INCH;
+ case MapUnit::MapPoint:
+ return css::embed::EmbedMapUnits::POINT;
+ case MapUnit::MapTwip:
+ return css::embed::EmbedMapUnits::TWIP;
+ case MapUnit::MapPixel:
+ return css::embed::EmbedMapUnits::PIXEL;
+ default: ; // avoid compiler warning
+ }
+
+ OSL_FAIL( "Unexpected VCL map mode is provided!" );
+ return -1;
+}
+
+using namespace ::com::sun::star::util;
+
+
+namespace
+{
+ enum UnitConversionDirection
+ {
+ FieldUnitToMeasurementUnit,
+ MeasurementUnitToFieldUnit
+ };
+
+ sal_Int16 convertMeasurementUnit( sal_Int16 _nUnit, UnitConversionDirection eDirection, sal_Int16& _rFieldToUNOValueFactor )
+ {
+ static struct _unit_table
+ {
+ FieldUnit eFieldUnit;
+ sal_Int16 nMeasurementUnit;
+ sal_Int16 nFieldToMeasureFactor;
+ } const aUnits[] = {
+ { FieldUnit::NONE, -1 , -1},
+ { FieldUnit::MM, MeasureUnit::MM, 1 }, // must precede MM_10TH
+ { FieldUnit::MM, MeasureUnit::MM_10TH, 10 },
+ { FieldUnit::MM_100TH, MeasureUnit::MM_100TH, 1 },
+ { FieldUnit::CM, MeasureUnit::CM, 1 },
+ { FieldUnit::M, MeasureUnit::M, 1 },
+ { FieldUnit::KM, MeasureUnit::KM, 1 },
+ { FieldUnit::TWIP, MeasureUnit::TWIP, 1 },
+ { FieldUnit::POINT, MeasureUnit::POINT, 1 },
+ { FieldUnit::PICA, MeasureUnit::PICA, 1 },
+ { FieldUnit::INCH, MeasureUnit::INCH, 1 }, // must precede INCH_*TH
+ { FieldUnit::INCH, MeasureUnit::INCH_10TH, 10 },
+ { FieldUnit::INCH, MeasureUnit::INCH_100TH, 100 },
+ { FieldUnit::INCH, MeasureUnit::INCH_1000TH, 1000 },
+ { FieldUnit::FOOT, MeasureUnit::FOOT, 1 },
+ { FieldUnit::MILE, MeasureUnit::MILE, 1 },
+ };
+ for (auto & aUnit : aUnits)
+ {
+ if ( eDirection == FieldUnitToMeasurementUnit )
+ {
+ if ( ( aUnit.eFieldUnit == static_cast<FieldUnit>(_nUnit) ) && ( aUnit.nFieldToMeasureFactor == _rFieldToUNOValueFactor ) )
+ return aUnit.nMeasurementUnit;
+ }
+ else
+ {
+ if ( aUnit.nMeasurementUnit == _nUnit )
+ {
+ _rFieldToUNOValueFactor = aUnit.nFieldToMeasureFactor;
+ return static_cast<sal_Int16>(aUnit.eFieldUnit);
+ }
+ }
+ }
+ if ( eDirection == FieldUnitToMeasurementUnit )
+ return -1;
+
+ _rFieldToUNOValueFactor = 1;
+ return sal_Int16(FieldUnit::NONE);
+ }
+}
+
+//= MeasurementUnitConversion
+
+
+sal_Int16 VCLUnoHelper::ConvertToMeasurementUnit( FieldUnit _nFieldUnit, sal_Int16 _nUNOToFieldValueFactor )
+{
+ return convertMeasurementUnit( static_cast<sal_Int16>(_nFieldUnit), FieldUnitToMeasurementUnit, _nUNOToFieldValueFactor );
+}
+
+
+FieldUnit VCLUnoHelper::ConvertToFieldUnit( sal_Int16 _nMeasurementUnit, sal_Int16& _rFieldToUNOValueFactor )
+{
+ return static_cast<FieldUnit>(convertMeasurementUnit( _nMeasurementUnit, MeasurementUnitToFieldUnit, _rFieldToUNOValueFactor ));
+}
+
+
+MapUnit /* MapModeUnit */ VCLUnoHelper::ConvertToMapModeUnit(sal_Int16 /* com.sun.star.util.MeasureUnit.* */ _nMeasureUnit)
+{
+ MapUnit eMode;
+ switch(_nMeasureUnit)
+ {
+ case css::util::MeasureUnit::MM_100TH:
+ eMode = MapUnit::Map100thMM;
+ break;
+
+ case css::util::MeasureUnit::MM_10TH:
+ eMode = MapUnit::Map10thMM;
+ break;
+
+ case css::util::MeasureUnit::MM:
+ eMode = MapUnit::MapMM;
+ break;
+
+ case css::util::MeasureUnit::CM:
+ eMode = MapUnit::MapCM;
+ break;
+
+ case css::util::MeasureUnit::INCH_1000TH:
+ eMode = MapUnit::Map1000thInch;
+ break;
+
+ case css::util::MeasureUnit::INCH_100TH:
+ eMode = MapUnit::Map100thInch;
+ break;
+
+ case css::util::MeasureUnit::INCH_10TH:
+ eMode = MapUnit::Map10thInch;
+ break;
+
+ case css::util::MeasureUnit::INCH:
+ eMode = MapUnit::MapInch;
+ break;
+
+ case css::util::MeasureUnit::POINT:
+ eMode = MapUnit::MapPoint;
+ break;
+
+ case css::util::MeasureUnit::TWIP:
+ eMode = MapUnit::MapTwip;
+ break;
+
+ case css::util::MeasureUnit::PIXEL:
+ eMode = MapUnit::MapPixel;
+ break;
+
+ case css::util::MeasureUnit::APPFONT:
+ eMode = MapUnit::MapAppFont;
+ break;
+
+ case css::util::MeasureUnit::SYSFONT:
+ eMode = MapUnit::MapSysFont;
+ break;
+
+ default:
+ throw css::lang::IllegalArgumentException("Unsupported measure unit.", nullptr, 1 );
+ }
+ return eMode;
+}
+
+::Size VCLUnoHelper::ConvertToVCLSize(css::awt::Size const& _aSize)
+{
+ ::Size aVCLSize(_aSize.Width, _aSize.Height);
+ return aVCLSize;
+}
+
+css::awt::Size VCLUnoHelper::ConvertToAWTSize(::Size /* VCLSize */ const& _aSize)
+{
+ css::awt::Size aAWTSize(_aSize.Width(), _aSize.Height());
+ return aAWTSize;
+}
+
+
+::Point VCLUnoHelper::ConvertToVCLPoint(css::awt::Point const& _aPoint)
+{
+ ::Point aVCLPoint(_aPoint.X, _aPoint.Y);
+ return aVCLPoint;
+}
+
+css::awt::Point VCLUnoHelper::ConvertToAWTPoint(::Point /* VCLPoint */ const& _aPoint)
+{
+ css::awt::Point aAWTPoint(_aPoint.X(), _aPoint.Y());
+ return aAWTPoint;
+}
+
+::tools::Rectangle VCLUnoHelper::ConvertToVCLRect( css::awt::Rectangle const & _rRect )
+{
+ return ::tools::Rectangle( _rRect.X, _rRect.Y, _rRect.X + _rRect.Width - 1, _rRect.Y + _rRect.Height - 1 );
+}
+
+css::awt::Rectangle VCLUnoHelper::ConvertToAWTRect( ::tools::Rectangle const & _rRect )
+{
+ return css::awt::Rectangle( _rRect.Left(), _rRect.Top(), _rRect.GetWidth(), _rRect.GetHeight() );
+}
+
+awt::MouseEvent VCLUnoHelper::createMouseEvent( const ::MouseEvent& _rVclEvent, const uno::Reference< uno::XInterface >& _rxContext )
+{
+ awt::MouseEvent aMouseEvent;
+ aMouseEvent.Source = _rxContext;
+
+ aMouseEvent.Modifiers = 0;
+ if ( _rVclEvent.IsShift() )
+ aMouseEvent.Modifiers |= css::awt::KeyModifier::SHIFT;
+ if ( _rVclEvent.IsMod1() )
+ aMouseEvent.Modifiers |= css::awt::KeyModifier::MOD1;
+ if ( _rVclEvent.IsMod2() )
+ aMouseEvent.Modifiers |= css::awt::KeyModifier::MOD2;
+
+ aMouseEvent.Buttons = 0;
+ if ( _rVclEvent.IsLeft() )
+ aMouseEvent.Buttons |= css::awt::MouseButton::LEFT;
+ if ( _rVclEvent.IsRight() )
+ aMouseEvent.Buttons |= css::awt::MouseButton::RIGHT;
+ if ( _rVclEvent.IsMiddle() )
+ aMouseEvent.Buttons |= css::awt::MouseButton::MIDDLE;
+
+ aMouseEvent.X = _rVclEvent.GetPosPixel().X();
+ aMouseEvent.Y = _rVclEvent.GetPosPixel().Y();
+ aMouseEvent.ClickCount = _rVclEvent.GetClicks();
+ aMouseEvent.PopupTrigger = false;
+
+ return aMouseEvent;
+}
+
+::MouseEvent VCLUnoHelper::createVCLMouseEvent( const awt::MouseEvent& _rAwtEvent )
+{
+ ::MouseEvent aMouseEvent( Point( _rAwtEvent.X, _rAwtEvent.Y ), _rAwtEvent.ClickCount,
+ ::MouseEventModifiers::NONE, _rAwtEvent.Buttons, _rAwtEvent.Modifiers );
+
+ return aMouseEvent;
+}
+
+awt::KeyEvent VCLUnoHelper::createKeyEvent( const ::KeyEvent& _rVclEvent, const uno::Reference< uno::XInterface >& _rxContext )
+{
+ awt::KeyEvent aKeyEvent;
+ aKeyEvent.Source = _rxContext;
+
+ aKeyEvent.Modifiers = 0;
+ if ( _rVclEvent.GetKeyCode().IsShift() )
+ aKeyEvent.Modifiers |= awt::KeyModifier::SHIFT;
+ if ( _rVclEvent.GetKeyCode().IsMod1() )
+ aKeyEvent.Modifiers |= awt::KeyModifier::MOD1;
+ if ( _rVclEvent.GetKeyCode().IsMod2() )
+ aKeyEvent.Modifiers |= awt::KeyModifier::MOD2;
+ if ( _rVclEvent.GetKeyCode().IsMod3() )
+ aKeyEvent.Modifiers |= awt::KeyModifier::MOD3;
+
+ aKeyEvent.KeyCode = _rVclEvent.GetKeyCode().GetCode();
+ aKeyEvent.KeyChar = _rVclEvent.GetCharCode();
+ aKeyEvent.KeyFunc = ::sal::static_int_cast< sal_Int16 >( _rVclEvent.GetKeyCode().GetFunction());
+
+ return aKeyEvent;
+}
+
+::KeyEvent VCLUnoHelper::createVCLKeyEvent( const awt::KeyEvent& _rAwtEvent )
+{
+ sal_Unicode nChar = _rAwtEvent.KeyChar;
+ vcl::KeyCode aKeyCode( _rAwtEvent.KeyCode, _rAwtEvent.Modifiers & awt::KeyModifier::SHIFT,
+ _rAwtEvent.Modifiers & awt::KeyModifier::MOD1,
+ _rAwtEvent.Modifiers & awt::KeyModifier::MOD2,
+ _rAwtEvent.Modifiers & awt::KeyModifier::MOD3 );
+
+ return ::KeyEvent (nChar, aKeyCode);
+
+}
+
+::PointerStyle VCLUnoHelper::getMousePointer(const css::uno::Reference<css::awt::XWindowPeer>& rWindowPeer)
+{
+ ::PointerStyle eType = ::PointerStyle::Arrow; // default ?
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(rWindowPeer);
+ if (pWindow)
+ eType = pWindow->GetPointer();
+ return eType;
+}
+
+void VCLUnoHelper::setMousePointer(const css::uno::Reference<css::awt::XWindowPeer>& rWindowPeer, ::PointerStyle ePointer)
+{
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(rWindowPeer);
+ if (!pWindow)
+ return;
+ pWindow->SetPointer(ePointer);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */