weld Property Browser

Replaced the odd HyperlinkField Edit whose text can be clicked on to activate
listeners, with an ordinary Edit and a Button beside it which can be clicked
instead to do that. I couldn't find a real world use of this HyperlinkField in
the forms or control properties, nor in casual experimentation in the sidebar
in the basicide dialog editor.

Also replaced the other strange Edit-alike TextView with a real Edit entry and
a dropdown which can be used to support entry of multi-line labels

Change-Id: Iad5265e404f6de14c8e760d617dbad49cd6ddead
Reviewed-on: https://gerrit.libreoffice.org/82213
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/basctl/source/dlged/propbrw.cxx b/basctl/source/dlged/propbrw.cxx
index c6565dd..2f7ff78 100644
--- a/basctl/source/dlged/propbrw.cxx
+++ b/basctl/source/dlged/propbrw.cxx
@@ -85,6 +85,7 @@ const long WIN_BORDER = 2;

PropBrw::PropBrw (DialogWindowLayout& rLayout_):
    DockingWindow(&rLayout_),
    m_xContentArea(VclPtr<VclVBox>::Create(this)),
    m_bInitialStateChange(true),
    m_xContextDocument(SfxViewShell::Current() ? SfxViewShell::Current()->GetCurrentDocument() : Reference<XModel>()),
    pView(nullptr)
@@ -93,11 +94,18 @@ PropBrw::PropBrw (DialogWindowLayout& rLayout_):
    SetMinOutputSizePixel(Size(STD_MIN_SIZE_X,STD_MIN_SIZE_Y));
    SetOutputSizePixel(aPropWinSize);

    // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
    // transparent children of the widget
    m_xContentArea->SetControlBackground(m_xContentArea->GetSettings().GetStyleSettings().GetWindowColor());
    m_xContentArea->SetBackground(m_xContentArea->GetControlBackground());
    m_xContentArea->SetStyle(m_xContentArea->GetStyle() & ~WB_CLIPCHILDREN);
    m_xContentArea->Show();

    try
    {
        // create a frame wrapper for myself
        m_xMeAsFrame = frame::Frame::create( comphelper::getProcessComponentContext() );
        m_xMeAsFrame->initialize( VCLUnoHelper::GetInterface ( this ) );
        m_xMeAsFrame->initialize(VCLUnoHelper::GetInterface(m_xContentArea));
        m_xMeAsFrame->setName( "form property browser" );  // change name!
    }
    catch (const Exception&)
@@ -126,7 +134,7 @@ void PropBrw::ImplReCreateController()
        // a ComponentContext for the
        ::cppu::ContextEntry_Init aHandlerContextInfo[] =
        {
            ::cppu::ContextEntry_Init( "DialogParentWindow", Any( VCLUnoHelper::GetInterface ( this ) ) ),
            ::cppu::ContextEntry_Init( "DialogParentWindow", Any(VCLUnoHelper::GetInterface(this))),
            ::cppu::ContextEntry_Init( "ContextDocument", Any( m_xContextDocument ) )
        };
        Reference< XComponentContext > xInspectorContext(
@@ -153,8 +161,6 @@ void PropBrw::ImplReCreateController()
            else
            {
                xAsXController->attachFrame( Reference<XFrame>(m_xMeAsFrame,UNO_QUERY_THROW) );
                m_xBrowserComponentWindow = m_xMeAsFrame->getComponentWindow();
                DBG_ASSERT(m_xBrowserComponentWindow.is(), "PropBrw::PropBrw: attached the controller, but have no component window!");
            }
        }

@@ -163,13 +169,8 @@ void PropBrw::ImplReCreateController()
        aPropWinSize.AdjustWidth( -(2*WIN_BORDER) );
        aPropWinSize.AdjustHeight( -(2*WIN_BORDER) );

        if ( m_xBrowserComponentWindow.is() )
        {
            m_xBrowserComponentWindow->setPosSize(aPropWinPos.X(), aPropWinPos.Y(), aPropWinSize.Width(), aPropWinSize.Height(),
                css::awt::PosSize::WIDTH | css::awt::PosSize::HEIGHT |
                css::awt::PosSize::X | css::awt::PosSize::Y);
            m_xBrowserComponentWindow->setVisible(true);
        }
        VclContainer::setLayoutAllocation(*m_xContentArea, aPropWinPos, aPropWinSize);
        m_xContentArea->Show();
    }
    catch (const Exception&)
    {
@@ -177,20 +178,16 @@ void PropBrw::ImplReCreateController()
        try
        {
            ::comphelper::disposeComponent(m_xBrowserController);
            ::comphelper::disposeComponent(m_xBrowserComponentWindow);
        }
        catch(const Exception&)
        {
        }

        m_xBrowserController.clear();
        m_xBrowserComponentWindow.clear();
    }

    Resize();
}


PropBrw::~PropBrw()
{
    disposeOnce();
@@ -200,6 +197,7 @@ void PropBrw::dispose()
{
    if ( m_xBrowserController.is() )
        ImplDestroyController();
    m_xContentArea.disposeAndClear();
    DockingWindow::dispose();
}

@@ -227,7 +225,6 @@ void PropBrw::ImplDestroyController()
    m_xBrowserController.clear();
}


bool PropBrw::Close()
{
    ImplDestroyController();
@@ -238,7 +235,6 @@ bool PropBrw::Close()
    return DockingWindow::Close();
}


Sequence< Reference< XInterface > >
    PropBrw::CreateMultiSelectionSequence( const SdrMarkList& _rMarkList )
{
@@ -430,25 +426,6 @@ OUString PropBrw::GetHeadlineName( const Reference< XPropertySet >& _rxObject )
    return aName;
}


void PropBrw::Resize()
{
    DockingWindow::Resize();

    // adjust size
    Size aSize_ = GetOutputSizePixel();
    Size aPropWinSize( aSize_ );
    aPropWinSize.AdjustWidth( -(2*WIN_BORDER) );
    aPropWinSize.AdjustHeight( -(2*WIN_BORDER) );

    if (m_xBrowserComponentWindow.is())
    {
        m_xBrowserComponentWindow->setPosSize(0, 0, aPropWinSize.Width(), aPropWinSize.Height(),
            css::awt::PosSize::WIDTH | css::awt::PosSize::HEIGHT);
    }
}


void PropBrw::ImplUpdate( const Reference< XModel >& _rxContextDocument, SdrView* pNewView )
{
    Reference< XModel > xContextDocument( _rxContextDocument );
@@ -482,8 +459,7 @@ void PropBrw::ImplUpdate( const Reference< XModel >& _rxContextDocument, SdrView
        // set focus on initialization
        if ( m_bInitialStateChange )
        {
            if ( m_xBrowserComponentWindow.is() )
                m_xBrowserComponentWindow->setFocus();
            m_xContentArea->GrabFocus();
            m_bInitialStateChange = false;
        }

diff --git a/basctl/source/inc/propbrw.hxx b/basctl/source/inc/propbrw.hxx
index 123b477..6bc9066 100644
--- a/basctl/source/inc/propbrw.hxx
+++ b/basctl/source/inc/propbrw.hxx
@@ -29,6 +29,7 @@
#include <svl/lstner.hxx>
#include <svl/SfxBroadcaster.hxx>
#include <svx/svdmark.hxx>
#include <vcl/layout.hxx>
#include "bastypes.hxx"

class SfxBindings;
@@ -43,19 +44,17 @@ class DialogWindowLayout;
class PropBrw final : public DockingWindow, public SfxListener, public SfxBroadcaster
{
private:
    VclPtr<VclBox> m_xContentArea;
    bool        m_bInitialStateChange;

    css::uno::Reference< css::frame::XFrame2 >
                    m_xMeAsFrame;
    css::uno::Reference< css::beans::XPropertySet >
                    m_xBrowserController;
    css::uno::Reference< css::awt::XWindow >
                    m_xBrowserComponentWindow;
    css::uno::Reference< css::frame::XModel >
                    m_xContextDocument;

    SdrView*        pView;
    virtual void Resize() override;
    virtual bool Close() override;

    typedef std::vector< css::uno::Reference< css::uno::XInterface> > InterfaceArray;
diff --git a/extensions/UIConfig_spropctrlr.mk b/extensions/UIConfig_spropctrlr.mk
index a0a078e..a07d773 100644
--- a/extensions/UIConfig_spropctrlr.mk
+++ b/extensions/UIConfig_spropctrlr.mk
@@ -10,12 +10,28 @@
$(eval $(call gb_UIConfig_UIConfig,modules/spropctrlr))

$(eval $(call gb_UIConfig_add_uifiles,modules/spropctrlr,\
	extensions/uiconfig/spropctrlr/ui/browserline \
	extensions/uiconfig/spropctrlr/ui/browserpage \
	extensions/uiconfig/spropctrlr/ui/colorlistbox \
	extensions/uiconfig/spropctrlr/ui/combobox \
	extensions/uiconfig/spropctrlr/ui/controlfontdialog \
	extensions/uiconfig/spropctrlr/ui/datefield \
	extensions/uiconfig/spropctrlr/ui/datatypedialog \
	extensions/uiconfig/spropctrlr/ui/datetimefield \
	extensions/uiconfig/spropctrlr/ui/formlinksdialog \
	extensions/uiconfig/spropctrlr/ui/formattedcontrol \
	extensions/uiconfig/spropctrlr/ui/formattedsample \
	extensions/uiconfig/spropctrlr/ui/formproperties \
	extensions/uiconfig/spropctrlr/ui/hyperlinkfield \
	extensions/uiconfig/spropctrlr/ui/labelselectiondialog \
	extensions/uiconfig/spropctrlr/ui/listbox \
	extensions/uiconfig/spropctrlr/ui/listselectdialog \
	extensions/uiconfig/spropctrlr/ui/multiline \
	extensions/uiconfig/spropctrlr/ui/numericfield \
	extensions/uiconfig/spropctrlr/ui/taborder \
	extensions/uiconfig/spropctrlr/ui/textfield \
	extensions/uiconfig/spropctrlr/ui/timefield \
	extensions/uiconfig/spropctrlr/ui/urlcontrol \
))

# vim: set noet sw=4 ts=4:
diff --git a/extensions/inc/strings.hrc b/extensions/inc/strings.hrc
index 1bece38..63dc3ce 100644
--- a/extensions/inc/strings.hrc
+++ b/extensions/inc/strings.hrc
@@ -257,7 +257,6 @@
#define RID_STR_STANDARD                        NC_("RID_STR_STANDARD", "Default")
#define RID_STR_PROPPAGE_DEFAULT                NC_("RID_STR_PROPPAGE_DEFAULT", "General")
#define RID_STR_PROPPAGE_DATA                   NC_("RID_STR_PROPPAGE_DATA", "Data")
#define RID_STR_HELP_SECTION_LABEL              NC_("RID_STR_HELP_SECTION_LABEL", "Help")
#define RID_EMBED_IMAGE_PLACEHOLDER             NC_("RID_EMBED_IMAGE_PLACEHOLDER", "<Embedded-Image>")
#define RID_STR_TEXT_FORMAT                     NC_("RID_STR_TEXT_FORMAT", "Text")

diff --git a/extensions/source/propctrlr/browserline.cxx b/extensions/source/propctrlr/browserline.cxx
index afb01b6..6dcd483 100644
--- a/extensions/source/propctrlr/browserline.cxx
+++ b/extensions/source/propctrlr/browserline.cxx
@@ -29,9 +29,10 @@
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>

#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <vcl/weldutils.hxx>

namespace pcr
{
@@ -51,235 +52,159 @@ namespace pcr

    namespace PropertyLineElement = ::com::sun::star::inspection::PropertyLineElement;

    OBrowserLine::OBrowserLine( const OUString& _rEntryName, vcl::Window* pParent )
            :m_sEntryName( _rEntryName )
            ,m_aFtTitle(VclPtr<FixedText>::Create(pParent))
            ,m_pControlWindow( nullptr )
            ,m_pBrowseButton(nullptr)
            ,m_pAdditionalBrowseButton( nullptr )
            ,m_pClickListener( nullptr )
            ,m_pTheParent(pParent)
            ,m_nNameWidth(0)
            ,m_nEnableFlags( 0xFFFF )
            ,m_bIndentTitle( false )
            ,m_bReadOnly( false )
    OBrowserLine::OBrowserLine(const OUString& rEntryName, weld::Container* pParent, weld::SizeGroup* pLabelGroup,
                               weld::Container* pInitialControlParent, bool bInterimBuilder)
        : m_sEntryName(rEntryName)
        , m_xBuilder(bInterimBuilder
                     ? Application::CreateInterimBuilder(pParent, "modules/spropctrlr/ui/browserline.ui")
                     : Application::CreateBuilder(pParent, "modules/spropctrlr/ui/browserline.ui"))
        , m_xContainer(m_xBuilder->weld_container("BrowserLine"))
        , m_xFtTitle(m_xBuilder->weld_label("label"))
        , m_xBrowseButton(m_xBuilder->weld_button("browse"))
        , m_xAdditionalBrowseButton(m_xBuilder->weld_button("morebrowse"))
        , m_pInitialControlParent(pInitialControlParent) // controls start with this as their parent and need to be moved into m_xContainer
        , m_pParent(pParent)
        , m_pControlWindow( nullptr )
        , m_pBrowseButton(nullptr)
        , m_pAdditionalBrowseButton( nullptr )
        , m_pClickListener( nullptr )
        , m_nNameWidth(0)
        , m_nEnableFlags( 0xFFFF )
        , m_bIndentTitle( false )
        , m_bReadOnly( false )
    {
        m_aFtTitle->Show();
        pLabelGroup->add_widget(m_xFtTitle.get());
    }

    OBrowserLine::~OBrowserLine()
    {
        implHideBrowseButton(true);
        implHideBrowseButton(false);
        m_aFtTitle.disposeAndClear();
        m_pParent->move(m_xContainer.get(), nullptr);
    }


    void OBrowserLine::IndentTitle( bool _bIndent )
    {
        if ( m_bIndentTitle != _bIndent )
        {
            m_bIndentTitle = _bIndent;
            impl_layoutComponents();
        }
    }

    void OBrowserLine::SetComponentHelpIds(const OString& _rHelpId)
    void OBrowserLine::SetComponentHelpIds(const OString& rHelpId)
    {
        if ( m_pControlWindow )
            m_pControlWindow->SetHelpId( _rHelpId );
        if (m_pControlWindow)
            m_pControlWindow->set_help_id(rHelpId);

        if ( m_pBrowseButton )
        {
            m_pBrowseButton->SetHelpId( _rHelpId );
            m_pBrowseButton->set_help_id(rHelpId);

            if ( m_pAdditionalBrowseButton )
            {
                m_pAdditionalBrowseButton->SetHelpId( _rHelpId );
                m_pAdditionalBrowseButton->set_help_id(rHelpId);
            }
        }
    }

    void OBrowserLine::setControl( const Reference< XPropertyControl >& _rxControl )
    void OBrowserLine::setControl( const Reference< XPropertyControl >& rxControl )
    {
        m_xControl = _rxControl;
        m_pControlWindow = m_xControl.is() ? VCLUnoHelper::GetWindow( _rxControl->getControlWindow() ) : VclPtr<vcl::Window>();
        m_xControl = rxControl;
        auto xWindow = m_xControl->getControlWindow();
        if (weld::TransportAsXWindow* pTunnel = dynamic_cast<weld::TransportAsXWindow*>(xWindow.get()))
            m_pControlWindow = pTunnel->getWidget();
        else
            m_pControlWindow = nullptr;
        DBG_ASSERT( m_pControlWindow, "OBrowserLine::setControl: setting NULL controls/windows is not allowed!" );

        if ( m_pControlWindow )
        {
            m_pControlWindow->SetParent( m_pTheParent );
            m_pControlWindow->Show();
            m_pInitialControlParent->move(m_pControlWindow, m_xContainer.get());
            m_pControlWindow->set_grid_left_attach(1);
            m_xFtTitle->set_mnemonic_widget(m_pControlWindow);
            m_pControlWindow->show();
        }
        impl_layoutComponents();
    }


    vcl::Window* OBrowserLine::GetRefWindow()
    {
        vcl::Window* pRefWindow = m_aFtTitle.get();

        if(m_pBrowseButton)
        {
            pRefWindow = m_pBrowseButton;
        }
        else if ( m_pControlWindow )
        {
            pRefWindow = m_pControlWindow;
        }
        return pRefWindow;
    }


    void OBrowserLine::SetTabOrder(vcl::Window* pRefWindow, ZOrderFlags nFlags )
    {
        m_aFtTitle->SetZOrder(pRefWindow,nFlags);
        if ( m_pControlWindow )
            m_pControlWindow->SetZOrder( m_aFtTitle.get(), ZOrderFlags::Behind );

        if ( m_pBrowseButton && m_pControlWindow )
            m_pBrowseButton->SetZOrder( m_pControlWindow, ZOrderFlags::Behind );

        if ( m_pAdditionalBrowseButton && m_pBrowseButton )
            m_pAdditionalBrowseButton->SetZOrder( m_pBrowseButton, ZOrderFlags::Behind );
    }


    bool OBrowserLine::GrabFocus()
    {
        bool bRes=false;

        if ( m_pControlWindow && m_pControlWindow->IsEnabled() )
        if (m_pControlWindow && m_pControlWindow->get_sensitive())
        {
            m_pControlWindow->GrabFocus();
            m_pControlWindow->grab_focus();
            bRes = true;
        }
        else if ( m_pAdditionalBrowseButton && m_pAdditionalBrowseButton->IsEnabled() )
        else if ( m_pAdditionalBrowseButton && m_pAdditionalBrowseButton->get_sensitive() )
        {
            m_pAdditionalBrowseButton->GrabFocus();
            m_pAdditionalBrowseButton->grab_focus();
            bRes = true;
        }
        else if ( m_pBrowseButton && m_pBrowseButton->IsEnabled() )
        else if ( m_pBrowseButton && m_pBrowseButton->get_sensitive() )
        {
            m_pBrowseButton->GrabFocus();
            m_pBrowseButton->grab_focus();
            bRes = true;
        }
        return bRes;
    }


    void OBrowserLine::SetPosSizePixel( Point _rPos, Size _rSize )
    {
        m_aLinePos = _rPos;
        m_aOutputSize = _rSize;

        impl_layoutComponents();
    }


    void OBrowserLine::Show(bool bFlag)
    {
        m_aFtTitle->Show(bFlag);
        if ( m_pControlWindow )
            m_pControlWindow->Show( bFlag );
        m_xFtTitle->set_visible(bFlag);
        if (m_pControlWindow)
            m_pControlWindow->set_visible( bFlag );
        if ( m_pBrowseButton )
            m_pBrowseButton->Show( bFlag );
            m_pBrowseButton->set_visible( bFlag );
        if ( m_pAdditionalBrowseButton )
            m_pAdditionalBrowseButton->Show( bFlag );
            m_pAdditionalBrowseButton->set_visible( bFlag );
    }


    void OBrowserLine::Hide()
    {
        Show(false);
    }


    bool OBrowserLine::IsVisible() const
    {
        return m_aFtTitle->IsVisible();
        return m_xFtTitle->get_visible();
    }


    void OBrowserLine::impl_layoutComponents()
    void OBrowserLine::SetTitle(const OUString& rNewTitle )
    {
        {
            Point aTitlePos( m_aLinePos.X(), m_aLinePos.Y() + 8 );
            Size aTitleSize( m_nNameWidth - 3, m_aOutputSize.Height() );

            if ( m_bIndentTitle )
            {
                Size aIndent( m_pTheParent->LogicToPixel(Size(8, 0), MapMode(MapUnit::MapAppFont)) );
                aTitlePos.AdjustX(aIndent.Width() );
                aTitleSize.AdjustWidth( -(aIndent.Width()) );
            }
            m_aFtTitle->SetPosSizePixel( aTitlePos, aTitleSize );
        }

        sal_Int32 nBrowseButtonSize = m_aOutputSize.Height() - 4;

        if ( m_pControlWindow )
        {
            Point aControlPos( m_aLinePos.X() + m_nNameWidth, m_aLinePos.Y() + 2 );
            m_pControlWindow->SetPosPixel( aControlPos );

            Size aControlSize( m_aOutputSize.Width() - 4 - m_nNameWidth - nBrowseButtonSize - 4, m_pControlWindow->GetSizePixel().Height() );
            if ( m_pAdditionalBrowseButton )
                aControlSize.AdjustWidth( -(nBrowseButtonSize + 4) );
            m_pControlWindow->SetSizePixel( aControlSize );
        }

        if ( m_pBrowseButton )
        {
            Point aButtonPos( m_aOutputSize.Width() - 4 - nBrowseButtonSize, m_aLinePos.Y() + 2 );
            Size aButtonSize( nBrowseButtonSize, nBrowseButtonSize );
            m_pBrowseButton->SetPosSizePixel( aButtonPos, aButtonSize );

            if ( m_pAdditionalBrowseButton )
            {
                aButtonPos.AdjustX( -(nBrowseButtonSize + 4) );
                m_pAdditionalBrowseButton->SetPosSizePixel( aButtonPos, aButtonSize );
            }
        }
    }


    void OBrowserLine::SetTitle(const OUString& _rNewTitle )
    {
        if ( GetTitle() == _rNewTitle )
        if ( GetTitle() == rNewTitle )
            return;
        m_aFtTitle->SetText( _rNewTitle );
        if ( m_pControlWindow )
            m_pControlWindow->SetAccessibleName( _rNewTitle );
        m_xFtTitle->set_label( rNewTitle );
        if (m_pControlWindow)
            m_pControlWindow->set_accessible_name(rNewTitle);
        if ( m_pBrowseButton )
            m_pBrowseButton->SetAccessibleName( _rNewTitle );
            m_pBrowseButton->set_accessible_name( rNewTitle );
        FullFillTitleString();
    }

    void OBrowserLine::FullFillTitleString()
    {
        if( m_pTheParent )
        OUStringBuffer aText(m_xFtTitle->get_label());

        int n10DotsWidth = m_xFtTitle->get_pixel_size("..........").Width();
        int nTextWidth = m_xFtTitle->get_pixel_size(aText.toString()).Width();
        int nDiff = m_nNameWidth - nTextWidth;
        int nExtraChars = (nDiff * 10) / n10DotsWidth;
        for (int i = 0; i < nExtraChars; ++i)
            aText.append(".");

        // for Issue 69452
        if (AllSettings::GetLayoutRTL())
        {
            OUStringBuffer aText( m_aFtTitle->GetText() );

            while( m_pTheParent->GetTextWidth( aText.toString() ) < m_nNameWidth )
                        aText.append("...........");

            // for Issue 69452
            if (AllSettings::GetLayoutRTL())
            {
                sal_Unicode const cRTL_mark = 0x200F;
                aText.append( OUString(cRTL_mark) );
            }

            m_aFtTitle->SetText( aText.makeStringAndClear() );
            sal_Unicode const cRTL_mark = 0x200F;
            aText.append( OUString(cRTL_mark) );
        }
    }

        m_xFtTitle->set_label(aText.makeStringAndClear());
    }

    OUString OBrowserLine::GetTitle() const
    {
        OUString sDisplayName = m_aFtTitle->GetText();
        OUString sDisplayName = m_xFtTitle->get_label();

        // for Issue 69452
        if (AllSettings::GetLayoutRTL())
@@ -293,7 +218,6 @@ namespace pcr
        return sDisplayName;
    }


    void OBrowserLine::SetReadOnly( bool _bReadOnly )
    {
        if ( m_bReadOnly != _bReadOnly )
@@ -303,37 +227,35 @@ namespace pcr
        }
    }


    namespace
    {
        void implSetBitIfAffected( sal_uInt16& _nEnabledBits, sal_Int16 _nAffectedMask, sal_Int16 _nTestBit, bool _bSet )
        void implSetBitIfAffected(sal_uInt16& nEnabledBits, sal_Int16 _nAffectedMask, sal_Int16 _nTestBit, bool _bSet)
        {
            if ( _nAffectedMask & _nTestBit )
            {
                if ( _bSet )
                    _nEnabledBits |= _nTestBit;
                    nEnabledBits |= _nTestBit;
                else
                    _nEnabledBits &= ~_nTestBit;
                    nEnabledBits &= ~_nTestBit;
            }
        }

        void implEnable( vcl::Window* _pWindow, sal_uInt16 _nEnabledBits, sal_uInt16 _nMatchBits  )
        void implEnable(weld::Widget* pWindow, sal_uInt16 nEnabledBits, sal_uInt16 nMatchBits)
        {
            if ( _pWindow )
                _pWindow->Enable( ( _nEnabledBits & _nMatchBits ) == _nMatchBits );
            if (pWindow)
                pWindow->set_sensitive((nEnabledBits & nMatchBits) == nMatchBits);
        }

        void implEnable( vcl::Window* _pWindow, bool _bEnable )
        void implEnable(weld::Widget* pWindow, bool bEnable)
        {
            if ( _pWindow )
                _pWindow->Enable( _bEnable );
            if (pWindow)
                pWindow->set_sensitive(bEnable);
        }
    }


    void OBrowserLine::implUpdateEnabledDisabled()
    {
        implEnable( m_aFtTitle.get(),           m_nEnableFlags, PropertyLineElement::CompleteLine );
        implEnable( m_xFtTitle.get(),           m_nEnableFlags, PropertyLineElement::CompleteLine );
        if ( m_pControlWindow )
            implEnable( m_pControlWindow,       m_nEnableFlags, PropertyLineElement::CompleteLine | PropertyLineElement::InputControl );

@@ -349,7 +271,6 @@ namespace pcr
        }
    }


    void OBrowserLine::EnablePropertyLine( bool _bEnable )
    {
        implSetBitIfAffected( m_nEnableFlags, PropertyLineElement::CompleteLine, PropertyLineElement::CompleteLine, _bEnable );
@@ -365,33 +286,35 @@ namespace pcr
        implUpdateEnabledDisabled();
    }


    PushButton& OBrowserLine::impl_ensureButton( bool _bPrimary )
    weld::Button& OBrowserLine::impl_ensureButton(bool bPrimary)
    {
        VclPtr<PushButton>& rpButton = _bPrimary ? m_pBrowseButton : m_pAdditionalBrowseButton;
        weld::Button* pButton;
        if (bPrimary)
            pButton = m_pBrowseButton;
        else
            pButton = m_pAdditionalBrowseButton;

        if ( !rpButton )
        if (!pButton )
        {
            rpButton = VclPtr<PushButton>::Create( m_pTheParent, WB_NOPOINTERFOCUS );
            rpButton->SetGetFocusHdl( LINK( this, OBrowserLine, OnButtonFocus ) );
            rpButton->SetClickHdl( LINK( this, OBrowserLine, OnButtonClicked ) );
            rpButton->SetText("...");
            if (bPrimary)
                pButton = m_pBrowseButton = m_xBrowseButton.get();
            else
                pButton = m_pAdditionalBrowseButton = m_xAdditionalBrowseButton.get();
            pButton->connect_focus_in(LINK(this, OBrowserLine, OnButtonFocus));
            pButton->connect_clicked(LINK(this, OBrowserLine, OnButtonClicked));
        }

        rpButton->Show();
        pButton->show();

        impl_layoutComponents();

        return *rpButton;
        return *pButton;
    }


    void OBrowserLine::ShowBrowseButton( const OUString& _rImageURL, bool _bPrimary )
    void OBrowserLine::ShowBrowseButton( const OUString& rImageURL, bool bPrimary )
    {
        PushButton& rButton( impl_ensureButton( _bPrimary ) );
        weld::Button& rButton( impl_ensureButton( bPrimary ) );

        OSL_PRECOND( !_rImageURL.isEmpty(), "OBrowserLine::ShowBrowseButton: use the other version if you don't have an image!" );
        Image aImage;
        OSL_PRECOND( !rImageURL.isEmpty(), "OBrowserLine::ShowBrowseButton: use the other version if you don't have an image!" );
        Reference<XGraphic> xGraphic;
        try
        {
            Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
@@ -399,73 +322,74 @@ namespace pcr

            Sequence< PropertyValue > aMediaProperties(1);
            aMediaProperties[0].Name = "URL";
            aMediaProperties[0].Value <<= _rImageURL;
            aMediaProperties[0].Value <<= rImageURL;

            Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties ), css::uno::UNO_SET_THROW );
            aImage = Image( xGraphic );
            xGraphic = Reference<XGraphic>(xGraphicProvider->queryGraphic(aMediaProperties), css::uno::UNO_SET_THROW);
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
        }

        rButton.SetModeImage( aImage );
        rButton.set_image(xGraphic);
    }

    void OBrowserLine::ShowBrowseButton( const Image& _rImage, bool _bPrimary )
    void OBrowserLine::ShowBrowseButton(const css::uno::Reference<css::graphic::XGraphic>& rGraphic, bool bPrimary)
    {
        PushButton& rButton( impl_ensureButton( _bPrimary ) );
        if ( !!_rImage )
            rButton.SetModeImage( _rImage );
        weld::Button& rButton( impl_ensureButton( bPrimary ) );
        rButton.set_image(rGraphic);
    }

    void OBrowserLine::ShowBrowseButton( bool _bPrimary )
    void OBrowserLine::ShowBrowseButton( bool bPrimary )
    {
        impl_ensureButton( _bPrimary );
        impl_ensureButton(bPrimary);
    }

    void OBrowserLine::implHideBrowseButton(bool _bPrimary)
    void OBrowserLine::implHideBrowseButton(bool bPrimary)
    {
        VclPtr<PushButton>& rpButton = _bPrimary ? m_pBrowseButton : m_pAdditionalBrowseButton;

        if ( rpButton )
        if (bPrimary)
        {
            rpButton->Hide();
            rpButton.disposeAndClear();
            if (m_pBrowseButton)
            {
                m_pBrowseButton->hide();
                m_pBrowseButton = nullptr;
            }
        }
        else
        {
            if (m_pAdditionalBrowseButton)
            {
                m_pAdditionalBrowseButton->hide();
                m_pAdditionalBrowseButton = nullptr;
            }
        }
    }

    void OBrowserLine::HideBrowseButton(bool _bPrimary)
    void OBrowserLine::HideBrowseButton(bool bPrimary)
    {
        implHideBrowseButton(_bPrimary);
        impl_layoutComponents();
        implHideBrowseButton(bPrimary);
    }

    void OBrowserLine::SetTitleWidth(sal_uInt16 nWidth)
    {
        if (m_nNameWidth != nWidth+10)
        {
            m_nNameWidth = nWidth+10;
            impl_layoutComponents();
        }
        int nMinDotsWidth = m_xFtTitle->get_pixel_size("...").Width();
        if (m_nNameWidth != nWidth + nMinDotsWidth)
            m_nNameWidth = nWidth + nMinDotsWidth;
        FullFillTitleString();
    }


    void OBrowserLine::SetClickListener( IButtonClickListener* _pListener )
    {
        m_pClickListener = _pListener;
    }


    IMPL_LINK( OBrowserLine, OnButtonClicked, Button*, _pButton, void )
    IMPL_LINK(OBrowserLine, OnButtonClicked, weld::Button&, rButton, void)
    {
        if ( m_pClickListener )
            m_pClickListener->buttonClicked( this, _pButton == m_pBrowseButton );
            m_pClickListener->buttonClicked(this, &rButton == m_pBrowseButton);
    }


    IMPL_LINK_NOARG( OBrowserLine, OnButtonFocus, Control&, void )
    IMPL_LINK_NOARG( OBrowserLine, OnButtonFocus, weld::Widget&, void )
    {
        if ( m_xControl.is() )
        {
@@ -483,5 +407,4 @@ namespace pcr

} // namespace pcr


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/browserline.hxx b/extensions/source/propctrlr/browserline.hxx
index 45b98a5..fb84174 100644
--- a/extensions/source/propctrlr/browserline.hxx
+++ b/extensions/source/propctrlr/browserline.hxx
@@ -23,6 +23,7 @@
#include <com/sun/star/inspection/XPropertyControl.hpp>
#include <vcl/fixed.hxx>
#include <vcl/button.hxx>
#include <vcl/weld.hxx>

namespace com { namespace sun { namespace star { namespace inspection { namespace PropertyLineElement
{
@@ -40,7 +41,7 @@ namespace pcr
    class IButtonClickListener
    {
    public:
        virtual void    buttonClicked( OBrowserLine* _pLine, bool _bPrimary ) = 0;
        virtual void    buttonClicked( OBrowserLine* pLine, bool bPrimary ) = 0;

    protected:
        ~IButtonClickListener() {}
@@ -51,77 +52,76 @@ namespace pcr
    {
    private:
        OUString                m_sEntryName;
        VclPtr<FixedText>       m_aFtTitle;
        Size                    m_aOutputSize;
        Point                   m_aLinePos;
        std::unique_ptr<weld::Builder> m_xBuilder;
        std::unique_ptr<weld::Container> m_xContainer;
        std::unique_ptr<weld::Label> m_xFtTitle;
        std::unique_ptr<weld::Button> m_xBrowseButton;
        std::unique_ptr<weld::Button> m_xAdditionalBrowseButton;
        css::uno::Reference< css::inspection::XPropertyControl >
                                m_xControl;
        VclPtr<vcl::Window>     m_pControlWindow;
        VclPtr<PushButton>      m_pBrowseButton;
        VclPtr<PushButton>      m_pAdditionalBrowseButton;
        weld::Container*        m_pInitialControlParent;
        weld::Container*        m_pParent;
        weld::Widget*           m_pControlWindow;
        weld::Button*           m_pBrowseButton;
        weld::Button*           m_pAdditionalBrowseButton;
        IButtonClickListener*   m_pClickListener;
        VclPtr<vcl::Window>     m_pTheParent;
        sal_uInt16              m_nNameWidth;
        sal_uInt16              m_nEnableFlags;
        bool                    m_bIndentTitle;
        bool                    m_bReadOnly;

    public:
                            OBrowserLine( const OUString& _rEntryName, vcl::Window* pParent);
                            ~OBrowserLine();
        OBrowserLine(const OUString& rEntryName, weld::Container* pParent, weld::SizeGroup* pLabelGroup,
                     weld::Container* pInitialControlParent, bool bInterimBuilder);
        ~OBrowserLine();

        void setControl( const css::uno::Reference< css::inspection::XPropertyControl >& _rxControl );
        void setControl( const css::uno::Reference< css::inspection::XPropertyControl >& rxControl );
        const css::uno::Reference< css::inspection::XPropertyControl >& getControl() const
        {
            return m_xControl;
        }
        vcl::Window* getControlWindow() const
        weld::Widget* getControlWindow() const
        {
            return m_pControlWindow;
        }

        const OUString&     GetEntryName() const { return m_sEntryName; }

        void                SetComponentHelpIds(const OString& _rHelpId);
        void                SetComponentHelpIds(const OString& rHelpId);

        void                SetTitle(const OUString& rString );
        void                FullFillTitleString();
        OUString            GetTitle() const;
        void                SetTitleWidth(sal_uInt16);

        void                SetPosSizePixel(Point aPos,Size aSize);
        int                 GetRowHeight() const { return m_xContainer->get_preferred_size().Height(); }
        void                Show(bool bFlag=true);
        void                Hide();
        bool                IsVisible() const;

        vcl::Window*        GetRefWindow();
        void                SetTabOrder(vcl::Window* pRefWindow, ZOrderFlags nFlags );

        bool                GrabFocus();
        void                ShowBrowseButton( const OUString& _rImageURL, bool _bPrimary );
        void                ShowBrowseButton( const Image& _rImage, bool _bPrimary );
        void                ShowBrowseButton( bool _bPrimary );
        void                HideBrowseButton( bool _bPrimary );
        void                ShowBrowseButton( const OUString& rImageURL, bool bPrimary );
        void                ShowBrowseButton( const css::uno::Reference<css::graphic::XGraphic>& rGraphic, bool bPrimary );
        void                ShowBrowseButton( bool bPrimary );
        void                HideBrowseButton( bool bPrimary );

        void                EnablePropertyControls( sal_Int16 _nControls, bool _bEnable );
        void                EnablePropertyLine( bool _bEnable );
        void                EnablePropertyControls( sal_Int16 nControls, bool bEnable );
        void                EnablePropertyLine( bool bEnable );

        void                SetReadOnly( bool _bReadOnly );
        void                SetReadOnly( bool bReadOnly );

        void                SetClickListener( IButtonClickListener* _pListener );
        void                SetClickListener( IButtonClickListener* pListener );

        void                IndentTitle( bool _bIndent );
        void                IndentTitle( bool bIndent );

    private:
        DECL_LINK( OnButtonClicked, Button*, void );
        DECL_LINK( OnButtonFocus, Control&, void );
        DECL_LINK( OnButtonClicked, weld::Button&, void );
        DECL_LINK( OnButtonFocus, weld::Widget&, void );

        void    implHideBrowseButton(bool _bPrimary);
        void    implHideBrowseButton(bool bPrimary);
        void    implUpdateEnabledDisabled();

        void    impl_layoutComponents();

        PushButton& impl_ensureButton( bool _bPrimary );
        weld::Button& impl_ensureButton(bool bPrimary);
    };


diff --git a/extensions/source/propctrlr/browserlistbox.cxx b/extensions/source/propctrlr/browserlistbox.cxx
index b98f3c1..11b6ecf 100644
--- a/extensions/source/propctrlr/browserlistbox.cxx
+++ b/extensions/source/propctrlr/browserlistbox.cxx
@@ -41,12 +41,7 @@

namespace pcr
{


    #define FRAME_OFFSET 4
        // TODO: find out what this is really for ... and check if it does make sense in the new
        // browser environment
    #define LAYOUT_HELP_WINDOW_DISTANCE_APPFONT 3

    using ::com::sun::star::uno::Any;
    using ::com::sun::star::uno::Exception;
@@ -137,8 +132,8 @@ namespace pcr
        };

    private:
        VclPtr<OBrowserListBox>     m_pContext;
        NotificationMode            m_eMode;
        OBrowserListBox* m_pContext;
        NotificationMode m_eMode;

    public:
        /** creates an instance
@@ -188,7 +183,7 @@ namespace pcr

        /** checks whether the instance is already disposed
        */
        bool impl_isDisposed_nothrow() const { return m_pContext.get() == nullptr; }
        bool impl_isDisposed_nothrow() const { return m_pContext == nullptr; }

        /** notifies the given event originating from the given control
        @throws DisposedException
@@ -198,21 +193,18 @@ namespace pcr
        void impl_notify_throw( const Reference< XPropertyControl >& _rxControl, ControlEventType _eType );
    };


    PropertyControlContext_Impl::PropertyControlContext_Impl( OBrowserListBox& _rContextImpl )
        :m_pContext( &_rContextImpl )
        ,m_eMode( eAsynchronously )
        : m_pContext( &_rContextImpl )
        , m_eMode( eAsynchronously )
    {
    }


    PropertyControlContext_Impl::~PropertyControlContext_Impl()
    {
        if ( !impl_isDisposed_nothrow() )
            dispose();
    }


    void PropertyControlContext_Impl::dispose()
    {
        SolarMutexGuard aGuard;
@@ -223,14 +215,12 @@ namespace pcr
        m_pContext = nullptr;
    }


    void PropertyControlContext_Impl::setNotificationMode( NotificationMode _eMode )
    {
        SolarMutexGuard aGuard;
        m_eMode = _eMode;
    }


    void PropertyControlContext_Impl::impl_notify_throw( const Reference< XPropertyControl >& _rxControl, ControlEventType _eType )
    {
        ::comphelper::AnyEventRef pEvent;
@@ -251,37 +241,31 @@ namespace pcr
        SharedNotifier::getNotifier()->addEvent( pEvent, this );
    }


    void SAL_CALL PropertyControlContext_Impl::focusGained( const Reference< XPropertyControl >& Control )
    {
        impl_notify_throw( Control, FOCUS_GAINED );
    }


    void SAL_CALL PropertyControlContext_Impl::valueChanged( const Reference< XPropertyControl >& Control )
    {
        impl_notify_throw( Control, VALUE_CHANGED );
    }


    void SAL_CALL PropertyControlContext_Impl::activateNextControl( const Reference< XPropertyControl >& CurrentControl )
    {
        impl_notify_throw( CurrentControl, ACTIVATE_NEXT );
    }


    void SAL_CALL PropertyControlContext_Impl::acquire() throw()
    {
        PropertyControlContext_Impl_Base::acquire();
    }


    void SAL_CALL PropertyControlContext_Impl::release() throw()
    {
        PropertyControlContext_Impl_Base::release();
    }


    void PropertyControlContext_Impl::processEvent( const ::comphelper::AnyEvent& _rEvent )
    {
        SolarMutexGuard aGuard;
@@ -300,7 +284,6 @@ namespace pcr
        }
    }


    void PropertyControlContext_Impl::impl_processEvent_throw( const ::comphelper::AnyEvent& _rEvent )
    {
        const ControlEvent& rControlEvent = static_cast< const ControlEvent& >( _rEvent );
@@ -318,70 +301,45 @@ namespace pcr
        }
    }

    OBrowserListBox::OBrowserListBox( vcl::Window* pParent)
            :Control(pParent, WB_DIALOGCONTROL | WB_CLIPCHILDREN)
            ,m_aLinesPlayground(VclPtr<vcl::Window>::Create(this,WB_DIALOGCONTROL | WB_CLIPCHILDREN))
            ,m_aVScroll(VclPtr<ScrollBar>::Create(this,WB_VSCROLL|WB_REPEAT|WB_DRAG))
            ,m_pHelpWindow( VclPtr<InspectorHelpWindow>::Create( this ) )
            ,m_pLineListener(nullptr)
            ,m_pControlObserver( nullptr )
            ,m_nYOffset(0)
            ,m_nCurrentPreferredHelpHeight(0)
            ,m_nTheNameSize(0)
            ,m_bIsActive(false)
            ,m_bUpdate(true)
            ,m_pControlContextImpl( new PropertyControlContext_Impl( *this ) )
    OBrowserListBox::OBrowserListBox(weld::Builder& rBuilder, weld::Container* pContainer, bool bInterimBuilder)
        : m_xScrolledWindow(rBuilder.weld_scrolled_window("scrolledwindow"))
        , m_xLinesPlayground(rBuilder.weld_container("playground"))
        , m_xSizeGroup(rBuilder.create_size_group())
        , m_xHelpWindow(new InspectorHelpWindow(rBuilder))
        , m_pInitialControlParent(pContainer)
        , m_pLineListener(nullptr)
        , m_pControlObserver( nullptr )
        , m_nTheNameSize(0)
        , m_nRowHeight(0)
        , m_bInterimBuilder(bInterimBuilder)
        , m_pControlContextImpl( new PropertyControlContext_Impl( *this ) )
    {
        ScopedVclPtrInstance<ListBox> aListBox(this, WB_DROPDOWN);
        ScopedVclPtrInstance<Edit> aEditBox(this);
        m_nRowHeight = std::max(aListBox->get_preferred_size().Height(),
                                aEditBox->get_preferred_size().Height());
        m_nRowHeight += 2;
        SetBackground( pParent->GetBackground() );
        m_aLinesPlayground->SetBackground( GetBackground() );

        m_aLinesPlayground->SetPosPixel(Point(0,0));
        m_aLinesPlayground->SetPaintTransparent(true);
        m_aLinesPlayground->Show();
        m_aVScroll->Hide();
        m_aVScroll->SetScrollHdl(LINK(this, OBrowserListBox, ScrollHdl));
        m_xScrolledWindow->set_size_request(-1, m_xScrolledWindow->get_text_height() * 20);
    }

    OBrowserListBox::~OBrowserListBox()
    {
        disposeOnce();
    }

    void OBrowserListBox::dispose()
    {
        OSL_ENSURE( !IsModified(), "OBrowserListBox::~OBrowserListBox: still modified - should have been committed before!" );
            // doing the commit here, while we, as well as our owner, as well as some other components,
            // are already "half dead" (means within their dtor) is potentially dangerous.
            // By definition, CommitModified has to be called (if necessary) before destruction

        // doing the commit here, while we, as well as our owner, as well as some other components,
        // are already "half dead" (means within their dtor) is potentially dangerous.
        // By definition, CommitModified has to be called (if necessary) before destruction
        m_pControlContextImpl->dispose();
        m_pControlContextImpl.clear();

        Hide();
        Clear();
        m_aLinesPlayground.disposeAndClear();
        m_aVScroll.disposeAndClear();
        m_pHelpWindow.disposeAndClear();
        Control::dispose();
    }


    bool OBrowserListBox::IsModified( ) const
    bool OBrowserListBox::IsModified() const
    {
        bool bModified = false;

        if ( m_bIsActive && m_xActiveControl.is() )
        if (m_xScrolledWindow->get_visible() && m_xActiveControl.is())
            bModified = m_xActiveControl->isModified();

        return bModified;
    }


    void OBrowserListBox::CommitModified( )
    {
        if ( IsModified() && m_xActiveControl.is() )
@@ -401,226 +359,48 @@ namespace pcr
        }
    }


    void OBrowserListBox::ActivateListBox(bool _bActive)
    {
        m_bIsActive = _bActive;
        if (m_bIsActive)
        {
            // TODO: what's the sense of this?
            m_aVScroll->SetThumbPos(100);
            MoveThumbTo(0);
            Resize();
        }
    }


    long OBrowserListBox::impl_getPrefererredHelpHeight()
    {
        return HasHelpSection() ? m_pHelpWindow->GetOptimalHeightPixel() : 0;
        return HasHelpSection() ? m_xHelpWindow->GetOptimalHeightPixel() : 0;
    }


    void OBrowserListBox::Resize()
    {
        tools::Rectangle aPlayground( Point( 0, 0 ), GetOutputSizePixel() );
        Size aHelpWindowDistance( LogicToPixel(Size(0, LAYOUT_HELP_WINDOW_DISTANCE_APPFONT), MapMode(MapUnit::MapAppFont)) );

        long nHelpWindowHeight = m_nCurrentPreferredHelpHeight = impl_getPrefererredHelpHeight();
        bool bPositionHelpWindow = ( nHelpWindowHeight != 0 );

        tools::Rectangle aLinesArea( aPlayground );
        if ( bPositionHelpWindow )
        {
            aLinesArea.AdjustBottom( -nHelpWindowHeight );
            aLinesArea.AdjustBottom( -(aHelpWindowDistance.Height()) );
        }
        m_aLinesPlayground->SetPosSizePixel( aLinesArea.TopLeft(), aLinesArea.GetSize() );

        UpdateVScroll();

        bool bNeedScrollbar = m_aLines.size() > static_cast<sal_uInt32>(CalcVisibleLines());
        if ( !bNeedScrollbar )
        {
            if ( m_aVScroll->IsVisible() )
                m_aVScroll->Hide();
            // scroll to top
            m_nYOffset = 0;
            m_aVScroll->SetThumbPos( 0 );
        }
        else
        {
            Size aVScrollSize( m_aVScroll->GetSizePixel() );

            // adjust the playground's width
            aLinesArea.AdjustRight( -(aVScrollSize.Width()) );
            m_aLinesPlayground->SetPosSizePixel( aLinesArea.TopLeft(), aLinesArea.GetSize() );

            // position the scrollbar
            aVScrollSize.setHeight( aLinesArea.GetHeight() );
            Point aVScrollPos( aLinesArea.GetWidth(), 0 );
            m_aVScroll->SetPosSizePixel( aVScrollPos, aVScrollSize );
        }

        for ( ListBoxLines::size_type i = 0; i < m_aLines.size(); ++i )
            m_aOutOfDateLines.insert( i );

        // repaint
        EnablePaint(false);
        UpdatePlayGround();
        EnablePaint(true);

        // show the scrollbar
        if ( bNeedScrollbar )
            m_aVScroll->Show();

        // position the help window
        if ( bPositionHelpWindow )
        {
            tools::Rectangle aHelpArea( aPlayground );
            aHelpArea.SetTop( aLinesArea.Bottom() + aHelpWindowDistance.Height() );
            m_pHelpWindow->SetPosSizePixel( aHelpArea.TopLeft(), aHelpArea.GetSize() );
        }
    }


    void OBrowserListBox::SetListener( IPropertyLineListener* _pListener )
    {
        m_pLineListener = _pListener;
    }


    void OBrowserListBox::SetObserver( IPropertyControlObserver* _pObserver )
    {
        m_pControlObserver = _pObserver;
    }


    void OBrowserListBox::EnableHelpSection( bool _bEnable )
    {
        m_pHelpWindow->Show( _bEnable );
        Resize();
        m_xHelpWindow->Show( _bEnable );
    }


    bool OBrowserListBox::HasHelpSection() const
    {
        return m_pHelpWindow->IsVisible();
        return m_xHelpWindow->IsVisible();
    }


    void OBrowserListBox::SetHelpText( const OUString& _rHelpText )
    {
        OSL_ENSURE( HasHelpSection(), "OBrowserListBox::SetHelpText: help section not visible!" );
        m_pHelpWindow->SetText( _rHelpText );
        if ( m_nCurrentPreferredHelpHeight != impl_getPrefererredHelpHeight() )
            Resize();
        m_xHelpWindow->SetText( _rHelpText );
    }


    void OBrowserListBox::SetHelpLineLimites( sal_Int32 _nMinLines, sal_Int32 _nMaxLines )
    void OBrowserListBox::SetHelpLineLimites(sal_Int32 nMinLines, sal_Int32 nMaxLines)
    {
        m_pHelpWindow->SetLimits( _nMinLines, _nMaxLines );
        m_xHelpWindow->SetLimits(nMinLines, nMaxLines);
    }


    sal_uInt16 OBrowserListBox::CalcVisibleLines()
    {
        Size aSize(m_aLinesPlayground->GetOutputSizePixel());
        sal_uInt16 nResult = 0;
        if (0 != m_nRowHeight)
            nResult = static_cast<sal_uInt16>(aSize.Height())/m_nRowHeight;

        return nResult;
    }


    void OBrowserListBox::UpdateVScroll()
    {
        sal_uInt16 nLines = CalcVisibleLines();
        m_aVScroll->SetPageSize(nLines-1);
        m_aVScroll->SetVisibleSize(nLines-1);

        size_t nCount = m_aLines.size();
        if (nCount>0)
        {
            m_aVScroll->SetRange(Range(0,nCount-1));
            m_nYOffset = -m_aVScroll->GetThumbPos()*m_nRowHeight;
        }
        else
        {
            m_aVScroll->SetRange(Range(0,0));
            m_nYOffset = 0;
        }
    }


    void OBrowserListBox::PositionLine( ListBoxLines::size_type _nIndex )
    {
        Size aSize(m_aLinesPlayground->GetOutputSizePixel());
        Point aPos(0, m_nYOffset);

        aSize.setHeight( m_nRowHeight );

        aPos.AdjustY(_nIndex * m_nRowHeight );

        if ( _nIndex < m_aLines.size() )
        {
            BrowserLinePointer pLine = m_aLines[ _nIndex ].pLine;

            pLine->SetPosSizePixel( aPos, aSize );
            pLine->SetTitleWidth( m_nTheNameSize + 2 * FRAME_OFFSET );

            // show the line if necessary
            if ( !pLine->IsVisible() )
                pLine->Show();
        }
    }


    void OBrowserListBox::UpdatePosNSize()
    {
        for ( auto const & aLoop: m_aOutOfDateLines )
        {
            DBG_ASSERT( aLoop < m_aLines.size(), "OBrowserListBox::UpdatePosNSize: invalid line index!" );
            if ( aLoop < m_aLines.size() )
                PositionLine( aLoop );
        }
        m_aOutOfDateLines.clear();
    }


    void OBrowserListBox::UpdatePlayGround()
    {
        sal_Int32 nThumbPos = m_aVScroll->GetThumbPos();
        sal_Int32 nLines = CalcVisibleLines();

        ListBoxLines::size_type nEnd = nThumbPos + nLines;
        if (nEnd >= m_aLines.size())
            nEnd = m_aLines.size()-1;

        if ( !m_aLines.empty() )
        {
            for ( ListBoxLines::size_type i = nThumbPos; i <= nEnd; ++i )
                m_aOutOfDateLines.insert( i );
            UpdatePosNSize();
        }
        for (auto& line : m_aLines)
            line.pLine->SetTitleWidth(m_nTheNameSize);
    }


    void OBrowserListBox::DisableUpdate()
    {
        m_bUpdate = false;
    }


    void OBrowserListBox::EnableUpdate()
    {
        m_bUpdate = true;
        Resize();
    }


    void OBrowserListBox::SetPropertyValue(const OUString& _rEntryName, const Any& _rValue, bool _bUnknownValue )
    {
        ListBoxLines::iterator line = std::find_if(m_aLines.begin(), m_aLines.end(),
@@ -640,7 +420,6 @@ namespace pcr
        }
    }


    sal_uInt16 OBrowserListBox::GetPropertyPos( const OUString& _rEntryName ) const
    {
        sal_uInt16 nPos = 0;
@@ -656,7 +435,6 @@ namespace pcr
        return EDITOR_LIST_ENTRY_NOTFOUND;
    }


    bool OBrowserListBox::impl_getBrowserLineForName( const OUString& _rEntryName, BrowserLinePointer& _out_rpLine ) const
    {
        ListBoxLines::const_iterator line = std::find_if(m_aLines.begin(), m_aLines.end(),
@@ -669,7 +447,6 @@ namespace pcr
        return ( nullptr != _out_rpLine.get() );
    }


    void OBrowserListBox::EnablePropertyControls( const OUString& _rEntryName, sal_Int16 _nControls, bool _bEnable )
    {
        BrowserLinePointer pLine;
@@ -677,7 +454,6 @@ namespace pcr
            pLine->EnablePropertyControls( _nControls, _bEnable );
    }


    void OBrowserListBox::EnablePropertyLine( const OUString& _rEntryName, bool _bEnable )
    {
        BrowserLinePointer pLine;
@@ -685,7 +461,6 @@ namespace pcr
            pLine->EnablePropertyLine( _bEnable );
    }


    Reference< XPropertyControl > OBrowserListBox::GetPropertyControl( const OUString& _rEntryName )
    {
        BrowserLinePointer pLine;
@@ -694,23 +469,24 @@ namespace pcr
        return nullptr;
    }


    void OBrowserListBox::InsertEntry(const OLineDescriptor& _rPropertyData, sal_uInt16 _nPos)
    void OBrowserListBox::InsertEntry(const OLineDescriptor& rPropertyData, sal_uInt16 _nPos)
    {
        // create a new line
        BrowserLinePointer pBrowserLine( new OBrowserLine( _rPropertyData.sName, m_aLinesPlayground.get() ) );
        BrowserLinePointer pBrowserLine(new OBrowserLine(rPropertyData.sName, m_xLinesPlayground.get(),
                                                         m_xSizeGroup.get(), m_pInitialControlParent,
                                                         m_bInterimBuilder));

        // check that the name is unique
        for (auto const& line : m_aLines)
        {
            if (line.aName == _rPropertyData.sName)
            if (line.aName == rPropertyData.sName)
            {
                // already have another line for this name!
                assert(false);
            }
        }

        ListBoxLine aNewLine( _rPropertyData.sName, pBrowserLine, _rPropertyData.xPropertyHandler );
        ListBoxLine aNewLine( rPropertyData.sName, pBrowserLine, rPropertyData.xPropertyHandler );
        ListBoxLines::size_type nInsertPos = _nPos;
        if ( _nPos >= m_aLines.size() )
        {
@@ -721,29 +497,19 @@ namespace pcr
            m_aLines.insert( m_aLines.begin() + _nPos, aNewLine );

        pBrowserLine->SetTitleWidth(m_nTheNameSize);
        if (m_bUpdate)
        {
            UpdateVScroll();
            Invalidate();
        }

        // initialize the entry
        ChangeEntry(_rPropertyData, nInsertPos);
        ChangeEntry(rPropertyData, nInsertPos);

        // update the positions of possibly affected lines
        ListBoxLines::size_type nUpdatePos = nInsertPos;
        while ( nUpdatePos < m_aLines.size() )
            m_aOutOfDateLines.insert( nUpdatePos++ );
        UpdatePosNSize( );
        m_nRowHeight = std::max(m_nRowHeight, pBrowserLine->GetRowHeight() + 6); // 6 is spacing of the "playground" in browserpage.ui
        m_xScrolledWindow->vadjustment_set_step_increment(m_nRowHeight);
    }


    sal_Int32 OBrowserListBox::GetMinimumWidth() const
    {
        return m_nTheNameSize + 2 * FRAME_OFFSET + (m_nRowHeight - 4) * 8;
    }


    sal_Int32 OBrowserListBox::GetMinimumHeight()
    {
        // assume that we want to display 5 rows, at least
@@ -751,106 +517,56 @@ namespace pcr

        if ( HasHelpSection() )
        {
            Size aHelpWindowDistance( LogicToPixel(Size(0, LAYOUT_HELP_WINDOW_DISTANCE_APPFONT), MapMode(MapUnit::MapAppFont)) );
            nMinHeight += aHelpWindowDistance.Height();

            nMinHeight += m_pHelpWindow->GetMinimalHeightPixel();
            nMinHeight += m_xHelpWindow->GetMinimalHeightPixel();
        }

        return nMinHeight;
    }


    void OBrowserListBox::ShowEntry(sal_uInt16 _nPos)
    void OBrowserListBox::ShowEntry(sal_uInt16 nPos)
    {
        if ( _nPos < m_aLines.size() )
        if (nPos == 0)
        {
            sal_Int32 nThumbPos = m_aVScroll->GetThumbPos();
            // special case the simple entry 0 situation
            m_xScrolledWindow->vadjustment_set_value(0);
            return;
        }

            if (_nPos < nThumbPos)
                MoveThumbTo(_nPos);
            else
        if (nPos < m_aLines.size())
        {
            unsigned const nWinHeight = m_xScrolledWindow->vadjustment_get_page_size();

            auto nThumbPos = m_xScrolledWindow->vadjustment_get_value();
            int const nWinTop = nThumbPos;
            int const nWinBottom = nWinTop + nWinHeight;

            auto nCtrlPosY = nPos * m_nRowHeight;

            int const nSelectedItemTop = nCtrlPosY;
            int const nSelectedItemBottom = nCtrlPosY + m_nRowHeight;
            bool const shouldScrollDown = nSelectedItemBottom >= nWinBottom;
            bool const shouldScrollUp = nSelectedItemTop <= nWinTop;
            bool const isNeedToScroll = shouldScrollDown || shouldScrollUp;

            if (isNeedToScroll)
            {
                sal_Int32 nLines = CalcVisibleLines();
                if (_nPos >= nThumbPos + nLines)
                    MoveThumbTo(_nPos - nLines + 1);
                if (shouldScrollDown)
                {
                    int nOffset = nSelectedItemBottom - nWinBottom;
                    nThumbPos += nOffset;
                }
                else
                {
                    int nOffset = nWinTop - nSelectedItemTop;
                    nThumbPos -= nOffset;
                    if(nThumbPos < 0)
                        nThumbPos = 0;
                }
                m_xScrolledWindow->vadjustment_set_value(nThumbPos);
            }
        }

    }


    void OBrowserListBox::MoveThumbTo(sal_Int32 _nNewThumbPos)
    {
        // disable painting to prevent flicker
        m_aLinesPlayground->EnablePaint(false);

        sal_Int32 nDelta = _nNewThumbPos - m_aVScroll->GetThumbPos();
        // adjust the scrollbar
        m_aVScroll->SetThumbPos(_nNewThumbPos);
        sal_Int32 nThumbPos = _nNewThumbPos;

        m_nYOffset = -m_aVScroll->GetThumbPos() * m_nRowHeight;

        sal_Int32 nLines = CalcVisibleLines();
        ListBoxLines::size_type nEnd = nThumbPos + nLines;

        m_aLinesPlayground->Scroll(0, -nDelta * m_nRowHeight, ScrollFlags::Children);

        if (1 == nDelta)
        {
            // TODO: what's the sense of this two PositionLines? Why not just one call?
            PositionLine(nEnd-1);
            PositionLine(nEnd);
        }
        else if (-1 == nDelta)
        {
            PositionLine(nThumbPos);
        }
        else if (0 != nDelta)
        {
            UpdatePlayGround();
        }

        m_aLinesPlayground->EnablePaint(true);
        m_aLinesPlayground->Invalidate(InvalidateFlags::Children);
    }


    IMPL_LINK(OBrowserListBox, ScrollHdl, ScrollBar*, _pScrollBar, void )
    {
        DBG_ASSERT(_pScrollBar == m_aVScroll.get(), "OBrowserListBox::ScrollHdl: where does this come from?");

        // disable painting to prevent flicker
        m_aLinesPlayground->EnablePaint(false);

        sal_Int32 nThumbPos = m_aVScroll->GetThumbPos();

        sal_Int32 nDelta = m_aVScroll->GetDelta();
        m_nYOffset = -nThumbPos * m_nRowHeight;

        ListBoxLines::size_type nEnd = nThumbPos + CalcVisibleLines();

        m_aLinesPlayground->Scroll(0, -nDelta * m_nRowHeight, ScrollFlags::Children);

        if (1 == nDelta)
        {
            PositionLine(nEnd-1);
            PositionLine(nEnd);
        }
        else if (nDelta==-1)
        {
            PositionLine(nThumbPos);
        }
        else if (nDelta!=0 || m_aVScroll->GetType() == ScrollType::DontKnow)
        {
            UpdatePlayGround();
        }

        m_aLinesPlayground->EnablePaint(true);
    }


    void OBrowserListBox::buttonClicked( OBrowserLine* _pLine, bool _bPrimary )
    {
        DBG_ASSERT( _pLine, "OBrowserListBox::buttonClicked: invalid browser line!" );
@@ -860,7 +576,6 @@ namespace pcr
        }
    }


    void OBrowserListBox::impl_setControlAsPropertyValue( const ListBoxLine& _rLine, const Any& _rPropertyValue )
    {
        Reference< XPropertyControl > xControl( _rLine.pLine->getControl() );
@@ -889,7 +604,6 @@ namespace pcr
        }
    }


    Any OBrowserListBox::impl_getControlAsPropertyValue( const ListBoxLine& _rLine )
    {
        Reference< XPropertyControl > xControl( _rLine.pLine->getControl() );
@@ -911,7 +625,6 @@ namespace pcr
        return aPropertyValue;
    }


    sal_uInt16 OBrowserListBox::impl_getControlPos( const Reference< XPropertyControl >& _rxControl ) const
    {
        sal_uInt16 nPos = 0;
@@ -1006,7 +719,6 @@ namespace pcr
        }
    }


    void OBrowserListBox::Clear()
    {
        for (auto const& line : m_aLines)
@@ -1020,7 +732,6 @@ namespace pcr
        clearContainer( m_aLines );
    }


    bool OBrowserListBox::RemoveEntry( const OUString& _rName )
    {
        ListBoxLines::iterator it = std::find_if(m_aLines.begin(), m_aLines.end(),
@@ -1029,34 +740,22 @@ namespace pcr
        if ( it == m_aLines.end() )
            return false;

        ListBoxLines::size_type nPos = static_cast<ListBoxLines::size_type>(std::distance(m_aLines.begin(), it));
        m_aLines.erase( it );
        m_aOutOfDateLines.erase( m_aLines.size() );

        // update the positions of possibly affected lines
        while ( nPos < m_aLines.size() )
            m_aOutOfDateLines.insert( nPos++ );
        UpdatePosNSize( );

        return true;
    }


    void OBrowserListBox::ChangeEntry( const OLineDescriptor& _rPropertyData, ListBoxLines::size_type nPos )
    void OBrowserListBox::ChangeEntry( const OLineDescriptor& rPropertyData, ListBoxLines::size_type nPos )
    {
        OSL_PRECOND( _rPropertyData.Control.is(), "OBrowserListBox::ChangeEntry: invalid control!" );
        if ( !_rPropertyData.Control.is() )
        OSL_PRECOND( rPropertyData.Control.is(), "OBrowserListBox::ChangeEntry: invalid control!" );
        if ( !rPropertyData.Control.is() )
            return;

        if ( nPos == EDITOR_LIST_REPLACE_EXISTING )
            nPos = GetPropertyPos( _rPropertyData.sName );
            nPos = GetPropertyPos( rPropertyData.sName );

        if ( nPos < m_aLines.size() )
        {
            vcl::Window* pRefWindow = nullptr;
            if ( nPos > 0 )
                pRefWindow = m_aLines[nPos-1].pLine->GetRefWindow();

            // the current line and control
            ListBoxLine& rLine = m_aLines[nPos];

@@ -1067,40 +766,36 @@ namespace pcr
            lcl_implDisposeControl_nothrow( xControl );

            // set the new control at the line
            rLine.pLine->setControl( _rPropertyData.Control );
            rLine.pLine->setControl( rPropertyData.Control );
            xControl = rLine.pLine->getControl();

            if ( xControl.is() )
                xControl->setControlContext( m_pControlContextImpl.get() );

            // the initial property value
            if ( _rPropertyData.bUnknownValue )
            if ( rPropertyData.bUnknownValue )
                xControl->setValue( Any() );
            else
                impl_setControlAsPropertyValue( rLine, _rPropertyData.aValue );
                impl_setControlAsPropertyValue( rLine, rPropertyData.aValue );

            rLine.pLine->SetTitle(_rPropertyData.DisplayName);
            rLine.xHandler = _rPropertyData.xPropertyHandler;
            rLine.pLine->SetTitle(rPropertyData.DisplayName);
            rLine.xHandler = rPropertyData.xPropertyHandler;

            sal_uInt16 nTextWidth = static_cast<sal_uInt16>(m_aLinesPlayground->GetTextWidth(_rPropertyData.DisplayName));
            if (m_nTheNameSize< nTextWidth)
                m_nTheNameSize = nTextWidth;

            if ( _rPropertyData.HasPrimaryButton )
            if ( rPropertyData.HasPrimaryButton )
            {
                if ( !_rPropertyData.PrimaryButtonImageURL.isEmpty() )
                    rLine.pLine->ShowBrowseButton( _rPropertyData.PrimaryButtonImageURL, true );
                else if ( _rPropertyData.PrimaryButtonImage.is() )
                    rLine.pLine->ShowBrowseButton( Image( _rPropertyData.PrimaryButtonImage ), true );
                if ( !rPropertyData.PrimaryButtonImageURL.isEmpty() )
                    rLine.pLine->ShowBrowseButton( rPropertyData.PrimaryButtonImageURL, true );
                else if ( rPropertyData.PrimaryButtonImage.is() )
                    rLine.pLine->ShowBrowseButton( rPropertyData.PrimaryButtonImage, true );
                else
                    rLine.pLine->ShowBrowseButton( true );

                if ( _rPropertyData.HasSecondaryButton )
                if ( rPropertyData.HasSecondaryButton )
                {
                    if ( !_rPropertyData.SecondaryButtonImageURL.isEmpty() )
                        rLine.pLine->ShowBrowseButton( _rPropertyData.SecondaryButtonImageURL, false );
                    else if ( _rPropertyData.SecondaryButtonImage.is() )
                        rLine.pLine->ShowBrowseButton( Image( _rPropertyData.SecondaryButtonImage ), false );
                    if ( !rPropertyData.SecondaryButtonImageURL.isEmpty() )
                        rLine.pLine->ShowBrowseButton( rPropertyData.SecondaryButtonImageURL, false );
                    else if ( rPropertyData.SecondaryButtonImage.is() )
                        rLine.pLine->ShowBrowseButton( rPropertyData.SecondaryButtonImage, false );
                    else
                        rLine.pLine->ShowBrowseButton( false );
                }
@@ -1115,21 +810,15 @@ namespace pcr
                rLine.pLine->HideBrowseButton( false );
            }

            DBG_ASSERT( ( _rPropertyData.IndentLevel == 0 ) || ( _rPropertyData.IndentLevel == 1 ),
            DBG_ASSERT( ( rPropertyData.IndentLevel == 0 ) || ( rPropertyData.IndentLevel == 1 ),
                "OBrowserListBox::ChangeEntry: unsupported indent level!" );
            rLine.pLine->IndentTitle( _rPropertyData.IndentLevel > 0 );
            rLine.pLine->IndentTitle( rPropertyData.IndentLevel > 0 );

            if ( nPos > 0 )
                rLine.pLine->SetTabOrder( pRefWindow, ZOrderFlags::Behind );
            else
                rLine.pLine->SetTabOrder( pRefWindow, ZOrderFlags::First );

            m_aOutOfDateLines.insert( nPos );
            rLine.pLine->SetComponentHelpIds(
                HelpIdUrl::getHelpId( _rPropertyData.HelpURL )
                HelpIdUrl::getHelpId( rPropertyData.HelpURL )
            );

            if ( _rPropertyData.bReadOnly )
            if ( rPropertyData.bReadOnly )
            {
                rLine.pLine->SetReadOnly( true );

@@ -1140,98 +829,23 @@ namespace pcr
                // So, we manually switch this to read-only.
                if ( xControl.is() && ( xControl->getControlType() == PropertyControlType::Unknown ) )
                {
                    vcl::Window *pWindow = rLine.pLine->getControlWindow();
                    Edit* pControlWindowAsEdit = dynamic_cast<Edit*>(pWindow);
                    weld::Widget* pWindow = rLine.pLine->getControlWindow();
                    weld::Entry* pControlWindowAsEdit = dynamic_cast<weld::Entry*>(pWindow);
                    if (pControlWindowAsEdit)
                        pControlWindowAsEdit->SetReadOnly();
                        pControlWindowAsEdit->set_editable(false);
                    else
                        pWindow->Enable(false);
                        pWindow->set_sensitive(false);
                }
            }
        }
    }


    bool OBrowserListBox::PreNotify( NotifyEvent& _rNEvt )
    {
        switch ( _rNEvt.GetType() )
        {
            case MouseNotifyEvent::KEYINPUT:
            sal_uInt16 nTextWidth = m_xLinesPlayground->get_pixel_size(rPropertyData.DisplayName).Width();
            if (m_nTheNameSize< nTextWidth)
            {
                const KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent();
                if  (   ( pKeyEvent->GetKeyCode().GetModifier() != 0 )
                    ||  (   ( pKeyEvent->GetKeyCode().GetCode() != KEY_PAGEUP )
                        &&  ( pKeyEvent->GetKeyCode().GetCode() != KEY_PAGEDOWN )
                        )
                    )
                    break;

                long nScrollOffset = 0;
                if ( m_aVScroll->IsVisible() )
                {
                    if ( pKeyEvent->GetKeyCode().GetCode() == KEY_PAGEUP )
                        nScrollOffset = -m_aVScroll->GetPageSize();
                    else if ( pKeyEvent->GetKeyCode().GetCode() == KEY_PAGEDOWN )
                        nScrollOffset = m_aVScroll->GetPageSize();
                }

                if ( nScrollOffset )
                {
                    long nNewThumbPos = m_aVScroll->GetThumbPos() + nScrollOffset;
                    nNewThumbPos = std::max( nNewThumbPos, m_aVScroll->GetRangeMin() );
                    nNewThumbPos = std::min( nNewThumbPos, m_aVScroll->GetRangeMax() );
                    m_aVScroll->DoScroll( nNewThumbPos );
                    nNewThumbPos = m_aVScroll->GetThumbPos();

                    sal_uInt16 nFocusControlPos = 0;
                    sal_uInt16 nActiveControlPos = impl_getControlPos( m_xActiveControl );
                    if ( nActiveControlPos < nNewThumbPos )
                        nFocusControlPos = static_cast<sal_uInt16>(nNewThumbPos);
                    else if ( nActiveControlPos >= nNewThumbPos + CalcVisibleLines() )
                        nFocusControlPos = static_cast<sal_uInt16>(nNewThumbPos) + CalcVisibleLines() - 1;
                    if ( nFocusControlPos )
                    {
                        if ( nFocusControlPos < m_aLines.size() )
                        {
                            m_aLines[ nFocusControlPos ].pLine->GrabFocus();
                        }
                        else
                            OSL_FAIL( "OBrowserListBox::PreNotify: internal error, invalid focus control position!" );
                    }
                }

                return true;
                // handled this. In particular, we also consume PageUp/Down events if we do not use them for scrolling,
                // otherwise they would be used to scroll the document view, which does not sound like it is desired by
                // the user.
            }
            default:
                break;
        }
        return Control::PreNotify( _rNEvt );
    }

    bool OBrowserListBox::EventNotify( NotifyEvent& _rNEvt )
    {
        if ( _rNEvt.GetType() == MouseNotifyEvent::COMMAND)
        {
            const CommandEvent* pCommand = _rNEvt.GetCommandEvent();
            if  (   ( CommandEventId::Wheel == pCommand->GetCommand() )
                ||  ( CommandEventId::StartAutoScroll == pCommand->GetCommand() )
                ||  ( CommandEventId::AutoScroll == pCommand->GetCommand() )
                )
            {
                // interested in scroll events if we have a scrollbar
                if ( m_aVScroll->IsVisible() )
                {
                    HandleScrollCommand( *pCommand, nullptr, m_aVScroll.get() );
                }
                m_nTheNameSize = nTextWidth;
                UpdatePlayGround();
            }
        }
        return Control::EventNotify(_rNEvt);
    }


} // namespace pcr


diff --git a/extensions/source/propctrlr/browserlistbox.hxx b/extensions/source/propctrlr/browserlistbox.hxx
index c99bf87..8ebbee9 100644
--- a/extensions/source/propctrlr/browserlistbox.hxx
+++ b/extensions/source/propctrlr/browserlistbox.hxx
@@ -28,6 +28,7 @@
#include <com/sun/star/inspection/XPropertyHandler.hpp>
#include <vcl/scrbar.hxx>
#include <vcl/button.hxx>
#include <vcl/weld.hxx>
#include <tools/link.hxx>
#include <rtl/ref.hxx>

@@ -71,48 +72,30 @@ namespace pcr
    typedef std::vector< ListBoxLine > ListBoxLines;


    class OBrowserListBox final : public Control
                            ,public IButtonClickListener
    class OBrowserListBox final : public IButtonClickListener
    {
        VclPtr<Window>              m_aLinesPlayground;
        VclPtr<ScrollBar>           m_aVScroll;
        VclPtr<InspectorHelpWindow> m_pHelpWindow;
        std::unique_ptr<weld::ScrolledWindow> m_xScrolledWindow;
        std::unique_ptr<weld::Container> m_xLinesPlayground;
        std::unique_ptr<weld::SizeGroup> m_xSizeGroup;
        std::unique_ptr<InspectorHelpWindow> m_xHelpWindow;
        weld::Container*            m_pInitialControlParent;
        ListBoxLines                m_aLines;
        IPropertyLineListener*      m_pLineListener;
        IPropertyControlObserver*   m_pControlObserver;
        long                        m_nYOffset;
        long                        m_nCurrentPreferredHelpHeight;
        css::uno::Reference< css::inspection::XPropertyControl >
                                    m_xActiveControl;
        sal_uInt16                  m_nTheNameSize;
        long                        m_nRowHeight;
        std::set<ListBoxLines::size_type> m_aOutOfDateLines;
        bool                    m_bIsActive : 1;
        bool                    m_bUpdate : 1;
        int                         m_nRowHeight;
        bool                        m_bInterimBuilder;
        ::rtl::Reference< PropertyControlContext_Impl >
                                    m_pControlContextImpl;

        void    PositionLine( ListBoxLines::size_type _nIndex );
        void    UpdatePosNSize();
        void    UpdatePlayGround();
        void    UpdateVScroll();
        void    ShowEntry(sal_uInt16 nPos);
        void    MoveThumbTo(sal_Int32 nNewThumbPos);
        void    Resize() override;

    public:
        explicit                    OBrowserListBox( vcl::Window* pParent );

                                    virtual ~OBrowserListBox() override;
        virtual void                dispose() override;

        void                        ActivateListBox( bool _bActive );

        sal_uInt16                  CalcVisibleLines();
        void                        EnableUpdate();
        void                        DisableUpdate();
        bool                        EventNotify( NotifyEvent& _rNEvt ) override;
        virtual bool                PreNotify( NotifyEvent& _rNEvt ) override;
        explicit OBrowserListBox(weld::Builder& rBuilder, weld::Container* pContainer, bool bInterimBuilder);
        ~OBrowserListBox();

        void                        SetListener( IPropertyLineListener* _pListener );
        void                        SetObserver( IPropertyControlObserver* _pObserver );
@@ -153,10 +136,6 @@ namespace pcr
        // IButtonClickListener
        void    buttonClicked( OBrowserLine* _pLine, bool _bPrimary ) override;

        using Window::SetHelpText;

        DECL_LINK( ScrollHdl, ScrollBar*, void );

        /** retrieves the index of a given control in our line list
            @param _rxControl
                The control to lookup. Must denote a control of one of the lines in ->m_aLines
@@ -194,8 +173,6 @@ namespace pcr
            currently don't have a help section
        */
        long        impl_getPrefererredHelpHeight();

        using Window::Activate;
    };


diff --git a/extensions/source/propctrlr/browserpage.cxx b/extensions/source/propctrlr/browserpage.cxx
index ac058cb..9bba600 100644
--- a/extensions/source/propctrlr/browserpage.cxx
+++ b/extensions/source/propctrlr/browserpage.cxx
@@ -17,60 +17,25 @@
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <vcl/svapp.hxx>
#include "browserpage.hxx"

namespace pcr
{
    #define LAYOUT_BORDER_LEFT      3
    #define LAYOUT_BORDER_TOP       3
    #define LAYOUT_BORDER_RIGHT     3
    #define LAYOUT_BORDER_BOTTOM    3

    OBrowserPage::OBrowserPage(vcl::Window* pParent)
            :TabPage(pParent,0)
            ,m_aListBox(VclPtr<OBrowserListBox>::Create(this))
    OBrowserPage::OBrowserPage(weld::Container* pParent, weld::Container* pInitialControlContainer, bool bInterimBuilder)
        : m_pParent(pParent)
        , m_xBuilder(bInterimBuilder
                     ? Application::CreateInterimBuilder(pParent, "modules/spropctrlr/ui/browserpage.ui")
                     : Application::CreateBuilder(pParent, "modules/spropctrlr/ui/browserpage.ui"))
        , m_xContainer(m_xBuilder->weld_container("BrowserPage"))
        , m_xListBox(std::make_unique<OBrowserListBox>(*m_xBuilder, pInitialControlContainer, bInterimBuilder))
    {
        m_aListBox->SetBackground(GetBackground());
        m_aListBox->SetPaintTransparent( true );
        m_aListBox->Show();
    }

    OBrowserPage::~OBrowserPage()
    {
        disposeOnce();
        m_pParent->move(m_xContainer.get(), nullptr);
    }

    void OBrowserPage::dispose()
    {
        m_aListBox.disposeAndClear();
        TabPage::dispose();
    }

    void OBrowserPage::Resize()
    {
        Size aSize( GetOutputSizePixel() );
        aSize.AdjustWidth( -(LAYOUT_BORDER_LEFT + LAYOUT_BORDER_RIGHT) );
        aSize.AdjustHeight( -(LAYOUT_BORDER_TOP + LAYOUT_BORDER_BOTTOM) );
        m_aListBox->SetPosSizePixel( Point( LAYOUT_BORDER_LEFT, LAYOUT_BORDER_TOP ), aSize );
    }

    void OBrowserPage::StateChanged(StateChangedType nType)
    {
        Window::StateChanged( nType);
        if (StateChangedType::Visible == nType && m_aListBox)
            m_aListBox->ActivateListBox(IsVisible());
    }

    sal_Int32 OBrowserPage::getMinimumWidth() const
    {
        return m_aListBox->GetMinimumWidth() + LAYOUT_BORDER_LEFT + LAYOUT_BORDER_RIGHT;
    }

    sal_Int32 OBrowserPage::getMinimumHeight()
    {
        return m_aListBox->GetMinimumHeight() + LAYOUT_BORDER_TOP + LAYOUT_BORDER_BOTTOM;
    }

} // namespace pcr

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/browserpage.hxx b/extensions/source/propctrlr/browserpage.hxx
index 983b9f9..1499921 100644
--- a/extensions/source/propctrlr/browserpage.hxx
+++ b/extensions/source/propctrlr/browserpage.hxx
@@ -20,39 +20,51 @@
#ifndef INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_BROWSERPAGE_HXX
#define INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_BROWSERPAGE_HXX

#include <vcl/tabpage.hxx>
#include <vcl/builderpage.hxx>
#include "browserlistbox.hxx"


namespace pcr
{

    class OBrowserPage : public TabPage
    class OBrowserPage
    {
    private:
        VclPtr<OBrowserListBox>     m_aListBox;
        weld::Container* m_pParent;
        std::unique_ptr<weld::Builder> m_xBuilder;
        std::unique_ptr<weld::Container> m_xContainer;
        std::unique_ptr<OBrowserListBox> m_xListBox;

    protected:
        virtual void Resize() override;
        virtual void StateChanged(StateChangedType nType) override;
        OUString m_aPageTitle;

    public:
        explicit OBrowserPage(vcl::Window* pParent);
        virtual ~OBrowserPage() override;
        virtual void dispose() override;
        // if bInterimBuilder wasn't needed this could inherit from BuilderPage
        explicit OBrowserPage(weld::Container* pParent, weld::Container* pContainer, bool bInterimBuilder);
        ~OBrowserPage();

        sal_Int32 getMinimumWidth() const;
        sal_Int32 getMinimumHeight();
        void SetPageTitle(const OUString& rPageTitle) { m_aPageTitle = rPageTitle; }
        const OUString& GetPageTitle() const { return m_aPageTitle; }

              OBrowserListBox& getListBox() { return *m_aListBox.get(); }
        const OBrowserListBox& getListBox() const { return *m_aListBox.get(); }
        void SetHelpId(const OString& rHelpId) { m_xContainer->set_help_id(rHelpId); }
        OString GetHelpId() const { return m_xContainer->get_help_id(); }

        OBrowserListBox& getListBox() { return *m_xListBox; }
        const OBrowserListBox& getListBox() const { return *m_xListBox; }

        void detach()
        {
            assert(m_pParent && "already attached");
            m_pParent->move(m_xContainer.get(), nullptr);
            m_pParent = nullptr;
        }

        void reattach(weld::Container* pNewParent)
        {
            assert(!m_pParent && "already attached");
            m_pParent = pNewParent;
            m_pParent->move(m_xContainer.get(), pNewParent);
        }
    };


} // namespace pcr


#endif // INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_BROWSERPAGE_HXX


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/browserview.cxx b/extensions/source/propctrlr/browserview.cxx
index 2b7f003..35d0626 100644
--- a/extensions/source/propctrlr/browserview.cxx
+++ b/extensions/source/propctrlr/browserview.cxx
@@ -29,94 +29,38 @@ namespace pcr
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;

    OPropertyBrowserView::OPropertyBrowserView(vcl::Window* _pParent)
                  :Window(_pParent, WB_3DLOOK)
                  ,m_nActivePage(0)
    OPropertyBrowserView::OPropertyBrowserView(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder, bool bInterimBuilder)
        : m_xPropBox(new OPropertyEditor(rContext, rBuilder, bInterimBuilder))
        , m_nActivePage(0)
    {
        m_pPropBox = VclPtr<OPropertyEditor>::Create( this );
        m_pPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
        m_pPropBox->setPageActivationHandler(LINK(this, OPropertyBrowserView, OnPageActivation));

        m_pPropBox->Show();
        m_xPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
        m_xPropBox->setPageActivationHandler(LINK(this, OPropertyBrowserView, OnPageActivation));
    }


    IMPL_LINK_NOARG(OPropertyBrowserView, OnPageActivation, LinkParamNone*, void)
    {
        m_nActivePage = m_pPropBox->GetCurPage();
        m_nActivePage = m_xPropBox->GetCurPage();
        m_aPageActivationHandler.Call(nullptr);
    }


    OPropertyBrowserView::~OPropertyBrowserView()
    {
        disposeOnce();
        sal_uInt16 nTmpPage = m_xPropBox->GetCurPage();
        if (nTmpPage)
            m_nActivePage = nTmpPage;
    }

    void OPropertyBrowserView::dispose()
    {
        if(m_pPropBox)
        {
            sal_uInt16 nTmpPage = m_pPropBox->GetCurPage();
            if (nTmpPage)
                m_nActivePage = nTmpPage;
        }
        m_pPropBox.disposeAndClear();
        vcl::Window::dispose();
    }


    void OPropertyBrowserView::activatePage(sal_uInt16 _nPage)
    {
        m_nActivePage = _nPage;
        getPropertyBox().SetPage(m_nActivePage);
    }


    void OPropertyBrowserView::GetFocus()
    {
        if (m_pPropBox)
            m_pPropBox->GrabFocus();
        else
            Window::GetFocus();
    }


    bool OPropertyBrowserView::EventNotify( NotifyEvent& _rNEvt )
    {
        if ( MouseNotifyEvent::KEYINPUT == _rNEvt.GetType() )
        {
            sal_uInt16 nKey = _rNEvt.GetKeyEvent()->GetKeyCode().GetCode();

            if ( ( KEY_DELETE == nKey ) || ( KEY_BACKSPACE == nKey ) )
                // silence this, we don't want to propagate this outside the property
                // browser, as it will probably do harm there
                // #i63285#
                return true;
        }
        return Window::EventNotify(_rNEvt);
    }


    void OPropertyBrowserView::Resize()
    {
        Size aSize = GetOutputSizePixel();
        m_pPropBox->SetSizePixel(aSize);
    }

    css::awt::Size OPropertyBrowserView::getMinimumSize() const
    {
        Size aSize = GetOutputSizePixel();
        if( m_pPropBox )
        {
            aSize.setHeight( m_pPropBox->getMinimumHeight() );
            aSize.setWidth( m_pPropBox->getMinimumWidth() );
        }
        return css::awt::Size( aSize.Width(), aSize.Height() );
        ::Size aSize = m_xPropBox->get_preferred_size();
        return css::awt::Size(aSize.Width(), aSize.Height());
    }


} // namespace pcr


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/browserview.hxx b/extensions/source/propctrlr/browserview.hxx
index 46f188e..c26f57d 100644
--- a/extensions/source/propctrlr/browserview.hxx
+++ b/extensions/source/propctrlr/browserview.hxx
@@ -20,37 +20,28 @@
#ifndef INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_BROWSERVIEW_HXX
#define INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_BROWSERVIEW_HXX

#include <com/sun/star/beans/XPropertySet.hpp>
#include <vcl/window.hxx>
#include <com/sun/star/awt/Size.hpp>

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <vcl/weld.hxx>

namespace pcr
{


    class OPropertyEditor;

    class OPropertyBrowserView final : public vcl::Window
    class OPropertyBrowserView final
    {
        VclPtr<OPropertyEditor>     m_pPropBox;
        std::unique_ptr<OPropertyEditor> m_xPropBox;
        sal_uInt16                  m_nActivePage;
        Link<LinkParamNone*,void>   m_aPageActivationHandler;

        virtual void Resize() override;
        virtual void GetFocus() override;
        virtual bool EventNotify( NotifyEvent& _rNEvt ) override;

    public:
        explicit OPropertyBrowserView( vcl::Window* pParent);
        explicit OPropertyBrowserView(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder, bool bInterimBuilder);
        ~OPropertyBrowserView();

        virtual ~OPropertyBrowserView() override;
        virtual void dispose() override;

        OPropertyEditor&    getPropertyBox() { return *m_pPropBox; }
        OPropertyEditor&    getPropertyBox() { return *m_xPropBox; }

        // page handling
        sal_uInt16  getActivaPage() const { return m_nActivePage; }
        sal_uInt16  getActivePage() const { return m_nActivePage; }
        void        activatePage(sal_uInt16 _nPage);

        void    setPageActivationHandler(const Link<LinkParamNone*,void>& _rHdl) { m_aPageActivationHandler = _rHdl; }
@@ -61,10 +52,8 @@ namespace pcr
        DECL_LINK(OnPageActivation, LinkParamNone*, void);
    };


} // namespace pcr


#endif // INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_BROWSERVIEW_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/commoncontrol.cxx b/extensions/source/propctrlr/commoncontrol.cxx
index 1619bc3..f224349 100644
--- a/extensions/source/propctrlr/commoncontrol.cxx
+++ b/extensions/source/propctrlr/commoncontrol.cxx
@@ -66,18 +66,6 @@ namespace pcr
        }
    }


    void CommonBehaviourControlHelper::autoSizeWindow()
    {
        ScopedVclPtrInstance< ComboBox > aComboBox(getVclWindow(), WB_DROPDOWN);
        aComboBox->SetPosSizePixel(Point(0,0), Size(100,100));
        getVclWindow()->SetSizePixel(aComboBox->GetSizePixel());

        // TODO/UNOize: why do the controls this themselves? Shouldn't this be the task
        // of the browser listbox/line?
    }


    void CommonBehaviourControlHelper::activateNextControl() const
    {
        try
@@ -91,23 +79,47 @@ namespace pcr
        }
    }


    IMPL_LINK_NOARG( CommonBehaviourControlHelper, EditModifiedHdl, Edit&, void )
    IMPL_LINK_NOARG( CommonBehaviourControlHelper, EditModifiedHdl, weld::Entry&, void )
    {
        setModified();
    }

    IMPL_LINK_NOARG( CommonBehaviourControlHelper, ModifiedHdl, ListBox&, void )
    IMPL_LINK_NOARG( CommonBehaviourControlHelper, ModifiedHdl, weld::ComboBox&, void )
    {
        setModified();
        // notify as soon as the Data source is changed, don't wait until we lose focus
        // because the Content dropdown cannot be populated after it is popped up
        // and going from Data source direct to Content may give focus-lost to
        // Content after the popup attempt is made
        notifyModifiedValue();
    }

    IMPL_LINK_NOARG( CommonBehaviourControlHelper, MetricModifiedHdl, weld::MetricSpinButton&, void )
    {
        setModified();
    }

    IMPL_LINK_NOARG( CommonBehaviourControlHelper, ColorModifiedHdl, SvxColorListBox&, void )
    IMPL_LINK_NOARG( CommonBehaviourControlHelper, FormattedModifiedHdl, weld::FormattedSpinButton&, void )
    {
        setModified();
    }

    IMPL_LINK_NOARG( CommonBehaviourControlHelper, GetFocusHdl, Control&, void )
    IMPL_LINK_NOARG( CommonBehaviourControlHelper, TimeModifiedHdl, weld::TimeSpinButton&, void )
    {
        setModified();
    }

    IMPL_LINK_NOARG( CommonBehaviourControlHelper, DateModifiedHdl, SvtCalendarBox&, void )
    {
        setModified();
    }

    IMPL_LINK_NOARG( CommonBehaviourControlHelper, ColorModifiedHdl, ColorListBox&, void )
    {
        setModified();
    }

    IMPL_LINK_NOARG( CommonBehaviourControlHelper, GetFocusHdl, weld::Widget&, void )
    {
        try
        {
@@ -120,8 +132,7 @@ namespace pcr
        }
    }


    IMPL_LINK_NOARG( CommonBehaviourControlHelper, LoseFocusHdl, Control&, void )
    IMPL_LINK_NOARG( CommonBehaviourControlHelper, LoseFocusHdl, weld::Widget&, void )
    {
        // TODO/UNOize: should this be outside the default control's implementations? If somebody
        // has an own control implementation, which does *not* do this - would this be allowed?
@@ -129,8 +140,6 @@ namespace pcr
        notifyModifiedValue();
    }


} // namespace pcr


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/commoncontrol.hxx b/extensions/source/propctrlr/commoncontrol.hxx
index 10ca002..2f304dc 100644
--- a/extensions/source/propctrlr/commoncontrol.hxx
+++ b/extensions/source/propctrlr/commoncontrol.hxx
@@ -25,20 +25,19 @@
#include <cppuhelper/compbase.hxx>
#include <cppuhelper/basemutex.hxx>
#include <tools/link.hxx>
#include <vcl/window.hxx>
#include <tools/wintypes.hxx>
#include <vcl/weld.hxx>
#include <vcl/weldutils.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <type_traits>

class NotifyEvent;
class Control;
class ListBox;
class SvxColorListBox;
class Edit;
class ColorListBox;
class SvtCalendarBox;

namespace pcr
{


    //= CommonBehaviourControlHelper

    /** A helper class for implementing the <type scope="css::inspection">XPropertyControl</type>
@@ -58,16 +57,16 @@ namespace pcr

    public:
        /** creates the instance
            @param  _nControlType
            @param  nControlType
                the type of the control - one of the <type scope="css::inspection">PropertyControlType</type>
                constants
            @param _pAntiImpl
            @param pAntiImpl
                Reference to the instance as whose "impl-class" we act i.e. the CommonBehaviourControl<> template,
                which is why we hold it without acquiring it/
        */
        CommonBehaviourControlHelper(
            sal_Int16 _nControlType,
            css::inspection::XPropertyControl& _rAntiImpl);
            sal_Int16 nControlType,
            css::inspection::XPropertyControl& rAntiImpl);

        virtual ~CommonBehaviourControlHelper();

@@ -79,7 +78,7 @@ namespace pcr
        /// @throws css::uno::RuntimeException
        const css::uno::Reference< css::inspection::XPropertyControlContext >& getControlContext() const { return m_xContext; }
        /// @throws css::uno::RuntimeException
        void setControlContext( const css::uno::Reference< css::inspection::XPropertyControlContext >& _controlcontext );
        void setControlContext( const css::uno::Reference< css::inspection::XPropertyControlContext >& controlcontext );
        /// @throws css::uno::RuntimeException
        bool isModified(  ) const { return m_bModified; }
        /// @throws css::uno::RuntimeException
@@ -89,17 +88,19 @@ namespace pcr
        */
        void activateNextControl() const;

        /// automatically size the window given in the ctor
        void    autoSizeWindow();

        virtual vcl::Window* getVclWindow() = 0;
        virtual weld::Widget* getWidget() = 0;

        /// may be used by derived classes, they forward the event to the PropCtrListener
        DECL_LINK( ModifiedHdl, ListBox&, void );
        DECL_LINK( ColorModifiedHdl, SvxColorListBox&, void );
        DECL_LINK( EditModifiedHdl, Edit&, void );
        DECL_LINK( GetFocusHdl, Control&, void );
        DECL_LINK( LoseFocusHdl, Control&, void );
        DECL_LINK( ModifiedHdl, weld::ComboBox&, void );
        DECL_LINK( ColorModifiedHdl, ColorListBox&, void );
        DECL_LINK( EditModifiedHdl, weld::Entry&, void );
        DECL_LINK( TextViewModifiedHdl, weld::TextView&, void );
        DECL_LINK( MetricModifiedHdl, weld::MetricSpinButton&, void );
        DECL_LINK( FormattedModifiedHdl, weld::FormattedSpinButton&, void );
        DECL_LINK( TimeModifiedHdl, weld::TimeSpinButton&, void );
        DECL_LINK( DateModifiedHdl, SvtCalendarBox&, void );
        DECL_LINK( GetFocusHdl, weld::Widget&, void );
        DECL_LINK( LoseFocusHdl, weld::Widget&, void );
    };


@@ -111,7 +112,7 @@ namespace pcr
        @param TControlInterface
            an interface class which is derived from (or identical to) <type scope="css::inspection">XPropertyControl</type>
        @param TControlWindow
            a class which is derived from vcl::Window
            a class which is derived from weld::Widget
    */
    template < class TControlInterface, class TControlWindow >
    class CommonBehaviourControl    :public ::cppu::BaseMutex
@@ -121,81 +122,85 @@ namespace pcr
    protected:
        typedef ::cppu::WeakComponentImplHelper< TControlInterface >    ComponentBaseClass;

        inline CommonBehaviourControl( sal_Int16 _nControlType, vcl::Window* _pParentWindow, WinBits _nWindowStyle, bool _bDoSetHandlers = true );
        inline CommonBehaviourControl(sal_Int16 nControlType,
                                      std::unique_ptr<weld::Builder> xBuilder,
                                      std::unique_ptr<TControlWindow> xWidget,
                                      bool bReadOnly);

        virtual ~CommonBehaviourControl() override
        {
            clear_widgetry();
        }

        // XPropertyControl - delegated to ->m_aImplControl
        virtual ::sal_Int16 SAL_CALL getControlType() override
            { return CommonBehaviourControlHelper::getControlType(); }
        virtual css::uno::Reference< css::inspection::XPropertyControlContext > SAL_CALL getControlContext() override
            { return CommonBehaviourControlHelper::getControlContext(); }
        virtual void SAL_CALL setControlContext( const css::uno::Reference< css::inspection::XPropertyControlContext >& _controlcontext ) override
            { CommonBehaviourControlHelper::setControlContext( _controlcontext ); }
        virtual void SAL_CALL setControlContext( const css::uno::Reference< css::inspection::XPropertyControlContext >& controlcontext ) override
            { CommonBehaviourControlHelper::setControlContext( controlcontext ); }
        virtual css::uno::Reference< css::awt::XWindow > SAL_CALL getControlWindow() override
            { return VCLUnoHelper::GetInterface( m_pControlWindow ); }
            { return new weld::TransportAsXWindow(getWidget()); }
        virtual sal_Bool SAL_CALL isModified(  ) override
            { return CommonBehaviourControlHelper::isModified(); }
        virtual void SAL_CALL notifyModifiedValue(  ) override
            { CommonBehaviourControlHelper::notifyModifiedValue(); }

        void clear_widgetry()
        {
            if (!m_xControlWindow)
                return;
            weld::Widget* pWidget = getWidget();
            std::unique_ptr<weld::Container> xParent(pWidget->weld_parent());
            xParent->move(pWidget, nullptr);
            m_xControlWindow.reset();
            m_xBuilder.reset();
        }

        // XComponent
        virtual void SAL_CALL disposing() override
            { m_pControlWindow.disposeAndClear(); }

       //  CommonBehaviourControlHelper::getVclWindow
        virtual vcl::Window*  getVclWindow() override
            { return m_pControlWindow.get(); }
        {
            clear_widgetry();
        }

        TControlWindow*       getTypedControlWindow()
            { return m_pControlWindow.get(); }
            { return m_xControlWindow.get(); }
        const TControlWindow* getTypedControlWindow() const
            { return m_pControlWindow.get(); }
            { return m_xControlWindow.get(); }

        virtual void SetModifyHandler()
        {
            m_xControlWindow->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) );
            m_xControlWindow->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) );
        }

        /** checks whether the instance is already disposed
            @throws DisposedException
                if the instance is already disposed
        */
        inline void impl_checkDisposed_throw();
    protected:
        std::unique_ptr<weld::Builder> m_xBuilder;
    private:
        VclPtr<TControlWindow>         m_pControlWindow;
        void implSetModifyHandler(const Edit&);
        void implSetModifyHandler(const ListBox&);
        void implSetModifyHandler(const SvxColorListBox&);
        std::unique_ptr<TControlWindow> m_xControlWindow;
    };


    //= CommonBehaviourControl - implementation

    template< class TControlInterface, class TControlWindow >
    inline CommonBehaviourControl< TControlInterface, TControlWindow >::CommonBehaviourControl ( sal_Int16 _nControlType, vcl::Window* _pParentWindow, WinBits _nWindowStyle, bool _bDoSetHandlers)
        :ComponentBaseClass( m_aMutex )
        ,CommonBehaviourControlHelper( _nControlType, *this )
        ,m_pControlWindow( VclPtr<TControlWindow>::Create( _pParentWindow, _nWindowStyle ) )
    inline CommonBehaviourControl< TControlInterface, TControlWindow >::CommonBehaviourControl(sal_Int16 nControlType,
                                                                                               std::unique_ptr<weld::Builder> xBuilder,
                                                                                               std::unique_ptr<TControlWindow> xWidget,
                                                                                               bool bReadOnly)
        : ComponentBaseClass( m_aMutex )
        , CommonBehaviourControlHelper( nControlType, *this )
        , m_xBuilder(std::move(xBuilder))
        , m_xControlWindow(std::move(xWidget))
    {
        if ( _bDoSetHandlers )
        if (bReadOnly)
        {
            implSetModifyHandler(*m_pControlWindow);
            m_pControlWindow->SetGetFocusHdl( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) );
            m_pControlWindow->SetLoseFocusHdl( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) );
            // disable widget by default, entries will overide to enable the widget but set it non-editable
            m_xControlWindow->set_sensitive(false);
        }
        autoSizeWindow();
    }

    template< class TControlInterface, class TControlWindow >
    inline void CommonBehaviourControl< TControlInterface, TControlWindow >::implSetModifyHandler(const Edit&)
    {
        m_pControlWindow->SetModifyHdl( LINK( this, CommonBehaviourControlHelper, EditModifiedHdl ) );
    }

    template< class TControlInterface, class TControlWindow >
    inline void CommonBehaviourControl< TControlInterface, TControlWindow >::implSetModifyHandler(const ListBox&)
    {
        m_pControlWindow->SetModifyHdl( LINK( this, CommonBehaviourControlHelper, ModifiedHdl ) );
    }

    template< class TControlInterface, class TControlWindow >
    inline void CommonBehaviourControl< TControlInterface, TControlWindow >::implSetModifyHandler(const SvxColorListBox&)
    {
        m_pControlWindow->SetModifyHdl( LINK( this, CommonBehaviourControlHelper, ColorModifiedHdl ) );
    }

    template< class TControlInterface, class TControlWindow >
@@ -205,10 +210,8 @@ namespace pcr
            throw css::lang::DisposedException( OUString(), *this );
    }


} // namespace pcr


#endif // INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_COMMONCONTROL_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/eformspropertyhandler.cxx b/extensions/source/propctrlr/eformspropertyhandler.cxx
index 65f98612..c177095 100644
--- a/extensions/source/propctrlr/eformspropertyhandler.cxx
+++ b/extensions/source/propctrlr/eformspropertyhandler.cxx
@@ -407,7 +407,6 @@ namespace pcr
        return aReturn;
    }


    LineDescriptor SAL_CALL EFormsPropertyHandler::describePropertyLine( const OUString& _rPropertyName,
        const Reference< XPropertyControlFactory >& _rxControlFactory )
    {
@@ -473,7 +472,6 @@ namespace pcr
        return aDescriptor;
    }


    InteractiveSelectionResult SAL_CALL EFormsPropertyHandler::onInteractivePropertySelection( const OUString& _rPropertyName, sal_Bool /*_bPrimary*/, Any& _rData, const Reference< XObjectInspectorUI >& _rxInspectorUI )
    {
        if ( !_rxInspectorUI.is() )
diff --git a/extensions/source/propctrlr/fontdialog.cxx b/extensions/source/propctrlr/fontdialog.cxx
index 43ad19c..2319aa8 100644
--- a/extensions/source/propctrlr/fontdialog.cxx
+++ b/extensions/source/propctrlr/fontdialog.cxx
@@ -21,6 +21,8 @@
#include "fontdialog.hxx"
#include <strings.hrc>
#include "modulepcr.hxx"
#include <vcl/outdev.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include <vcl/unohelp.hxx>
#include <i18nlangtag/languagetag.hxx>
diff --git a/extensions/source/propctrlr/formcomponenthandler.cxx b/extensions/source/propctrlr/formcomponenthandler.cxx
index 833359f..6af595e 100644
--- a/extensions/source/propctrlr/formcomponenthandler.cxx
+++ b/extensions/source/propctrlr/formcomponenthandler.cxx
@@ -997,13 +997,16 @@ namespace pcr
        case PROPERTY_ID_TARGET_URL:
        case PROPERTY_ID_IMAGE_URL:
        {
            aDescriptor.Control = new OFileUrlControl( impl_getDefaultDialogParent_nothrow() );
            std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/urlcontrol.ui", m_xContext));
            auto pControl = new OFileUrlControl(std::make_unique<URLBox>(xBuilder->weld_combo_box("urlcontrol")), std::move(xBuilder), false);
            pControl->SetModifyHandler();
            aDescriptor.Control = pControl;

            aDescriptor.PrimaryButtonId = PROPERTY_ID_TARGET_URL == nPropId
                ? OUStringLiteral(UID_PROP_DLG_ATTR_TARGET_URL)
                : OUStringLiteral(UID_PROP_DLG_IMAGE_URL);
            break;
        }
        break;

        case PROPERTY_ID_ECHO_CHAR:
            nControlType = PropertyControlType::CharacterField;
@@ -1096,16 +1099,21 @@ namespace pcr

                    if ( bIsFormatKey )
                    {
                        OFormatSampleControl* pControl = new OFormatSampleControl( impl_getDefaultDialogParent_nothrow() );
                        std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/formattedsample.ui", m_xContext));
                        auto pControl = new OFormatSampleControl(xBuilder->weld_container("formattedsample"), std::move(xBuilder), false);
                        pControl->SetModifyHandler();

                        pControl->SetFormatSupplier(pSupplier);

                        aDescriptor.Control = pControl;
                        pControl->SetFormatSupplier( pSupplier );

                        aDescriptor.PrimaryButtonId = UID_PROP_DLG_NUMBER_FORMAT;
                    }
                    else
                    {
                        OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );
                        aDescriptor.Control = pControl;
                        std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/formattedcontrol.ui", m_xContext));
                        auto pControl = new OFormattedNumericControl(xBuilder->weld_formatted_spin_button("formattedcontrol"), std::move(xBuilder), false);
                        pControl->SetModifyHandler();

                        FormatDescription aDesc;
                        aDesc.pSupplier = pSupplier;
@@ -1114,6 +1122,8 @@ namespace pcr
                            aDesc.nKey = 0;

                        pControl->SetFormatDescription( aDesc );

                        aDescriptor.Control = pControl;
                    }
                }
            }
@@ -1138,42 +1148,36 @@ namespace pcr
        case PROPERTY_ID_VALUEMAX:
        case PROPERTY_ID_DEFAULT_VALUE:
        case PROPERTY_ID_VALUE:
        {
            std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/formattedcontrol.ui", m_xContext));
            auto pControl = new OFormattedNumericControl(xBuilder->weld_formatted_spin_button("formattedcontrol"), std::move(xBuilder), false);
            pControl->SetModifyHandler();
            aDescriptor.Control = pControl;

            // we don't set a formatter so the control uses a default (which uses the application
            // language and a default numeric format)
            // but we set the decimal digits
            pControl->SetDecimalDigits(
                ::comphelper::getINT16( m_xComponent->getPropertyValue( PROPERTY_DECIMAL_ACCURACY ) )
            );

            // and the default value for the property
            try
            {
                OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER | WB_SPIN | WB_REPEAT );
                aDescriptor.Control = pControl;

                // we don't set a formatter so the control uses a default (which uses the application
                // language and a default numeric format)
                // but we set the decimal digits
                pControl->SetDecimalDigits(
                    ::comphelper::getINT16( m_xComponent->getPropertyValue( PROPERTY_DECIMAL_ACCURACY ) )
                );

                // and the thousands separator
                pControl->SetThousandsSep(
                    ::comphelper::getBOOL( m_xComponent->getPropertyValue(PROPERTY_SHOWTHOUSANDSEP) )
                );

                // and the default value for the property
                try
                if (m_xPropertyState.is() && ((PROPERTY_ID_VALUEMIN == nPropId) || (PROPERTY_ID_VALUEMAX == nPropId)))
                {
                    if (m_xPropertyState.is() && ((PROPERTY_ID_VALUEMIN == nPropId) || (PROPERTY_ID_VALUEMAX == nPropId)))
                    {
                        double nDefault = 0;
                        if ( m_xPropertyState->getPropertyDefault( aProperty.Name ) >>= nDefault )
                            pControl->SetDefaultValue( nDefault );
                    }
                    double nDefault = 0;
                    if ( m_xPropertyState->getPropertyDefault( aProperty.Name ) >>= nDefault )
                        pControl->SetDefaultValue(nDefault);
                }
                catch (const Exception&)
                {
                    // just ignore it
                }

                // and allow empty values only for the default value and the value
                pControl->EnableEmptyField( ( PROPERTY_ID_DEFAULT_VALUE == nPropId )
                                        ||  ( PROPERTY_ID_VALUE == nPropId ) );
            }
            catch (const Exception&)
            {
                // just ignore it
            }

            break;
        }

        default:
            if ( TypeClass_BYTE <= eType && eType <= TypeClass_DOUBLE )
@@ -1278,11 +1282,12 @@ namespace pcr
        {
            case PROPERTY_ID_REPEAT_DELAY:
            {
                OTimeDurationControl* pControl = new OTimeDurationControl( impl_getDefaultDialogParent_nothrow() );
                aDescriptor.Control = pControl;

                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/numericfield.ui", m_xContext));
                auto pControl = new ONumericControl(xBuilder->weld_metric_spin_button("numericfield", FieldUnit::MILLISECOND), std::move(xBuilder), bReadOnly);
                pControl->SetModifyHandler();
                pControl->setMinValue( Optional< double >( true, 0 ) );
                pControl->setMaxValue( Optional< double >( true, std::numeric_limits< double >::max() ) );
                aDescriptor.Control = pControl;
            }
            break;

@@ -1704,12 +1709,10 @@ namespace pcr
                {
                    OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
                    DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
                    if ( pControl )
                    if (pControl)
                    {
                        if ( bAccuracy )
                            pControl->SetDecimalDigits( nNewDigits );
                        else
                            pControl->SetThousandsSep( bUseSep );
                    }
                }
            }
@@ -2374,13 +2377,12 @@ namespace pcr
        }
    }


    void FormComponentPropertyHandler::impl_displaySQLError_nothrow( const ::dbtools::SQLExceptionInfo& _rErrorDescriptor ) const
    {
        ::dbtools::showError( _rErrorDescriptor, VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ), m_xContext );
        auto pTopLevel = impl_getDefaultDialogFrame_nothrow();
        ::dbtools::showError(_rErrorDescriptor, pTopLevel ? pTopLevel->GetXWindow() : nullptr, m_xContext);
    }


    bool FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow() const
    {
        if ( !m_xRowSetConnection.is() )
@@ -2640,7 +2642,8 @@ namespace pcr
            Reference< XPropertySet > xDialogProps( xDialog, UNO_QUERY_THROW );
            xDialogProps->setPropertyValue("QueryComposer", makeAny( xComposer ) );
            xDialogProps->setPropertyValue("RowSet",        makeAny( m_xComponent ) );
            xDialogProps->setPropertyValue("ParentWindow",  makeAny( VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ) ) );
            if (auto pTopLevel = impl_getDefaultDialogFrame_nothrow())
                xDialogProps->setPropertyValue("ParentWindow",  makeAny(pTopLevel->GetXWindow()));
            xDialogProps->setPropertyValue("Title",         makeAny( sPropertyUIName ) );

            _rClearBeforeDialog.clear();
diff --git a/extensions/source/propctrlr/handlerhelper.cxx b/extensions/source/propctrlr/handlerhelper.cxx
index 19ba0de..0f29819 100644
--- a/extensions/source/propctrlr/handlerhelper.cxx
+++ b/extensions/source/propctrlr/handlerhelper.cxx
@@ -24,8 +24,9 @@
#include "enumrepresentation.hxx"
#include "formmetadata.hxx"

#include <com/sun/star/inspection/StringRepresentation.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/inspection/StringRepresentation.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/util/XModifiable.hpp>
#include <com/sun/star/awt/XWindow.hpp>
@@ -36,6 +37,8 @@
#include <tools/diagnose_ex.h>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <vcl/weldutils.hxx>
#include <vcl/window.hxx>

#include <algorithm>
@@ -241,11 +244,11 @@ namespace pcr
    }


    void PropertyHandlerHelper::setContextDocumentModified( const Reference<XComponentContext> & _rContext )
    void PropertyHandlerHelper::setContextDocumentModified( const Reference<XComponentContext> & rContext )
    {
        try
        {
            Reference< XModifiable > xDocumentModifiable( getContextDocument_throw(_rContext), UNO_QUERY_THROW );
            Reference< XModifiable > xDocumentModifiable( getContextDocument_throw(rContext), UNO_QUERY_THROW );
            xDocumentModifiable->setModified( true );
        }
        catch( const Exception& )
@@ -254,12 +257,12 @@ namespace pcr
        }
    }

    Reference< XInterface > PropertyHandlerHelper::getContextDocument( const Reference<XComponentContext> & _rContext )
    Reference< XInterface > PropertyHandlerHelper::getContextDocument( const Reference<XComponentContext> & rContext )
    {
        Reference< XInterface > xI;
        try
        {
            xI = getContextDocument_throw( _rContext );
            xI = getContextDocument_throw( rContext );
        }
        catch( const Exception& )
        {
@@ -268,36 +271,20 @@ namespace pcr
        return xI;
    }

    Reference< XInterface > PropertyHandlerHelper::getContextDocument_throw( const Reference<XComponentContext> & _rContext )
    Reference< XInterface > PropertyHandlerHelper::getContextDocument_throw( const Reference<XComponentContext> & rContext )
    {
        Reference< XInterface > xI;
        Any aReturn = _rContext->getValueByName( "ContextDocument" );
        Any aReturn = rContext->getValueByName( "ContextDocument" );
        aReturn >>= xI;
        return xI;
    }


    vcl::Window* PropertyHandlerHelper::getDialogParentWindow( const Reference<XComponentContext>& _rContext )
    {
        vcl::Window* pInspectorWindow = nullptr;
        try
        {
            Reference< XWindow > xInspectorWindow( _rContext->getValueByName( "DialogParentWindow" ), UNO_QUERY_THROW );
            pInspectorWindow = VCLUnoHelper::GetWindow( xInspectorWindow ).get();
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
        }
        return pInspectorWindow;
    }

    weld::Window* PropertyHandlerHelper::getDialogParentFrame(const Reference<XComponentContext>& _rContext)
    weld::Window* PropertyHandlerHelper::getDialogParentFrame(const Reference<XComponentContext>& rContext)
    {
        weld::Window* pInspectorWindow = nullptr;
        try
        {
            Reference< XWindow > xInspectorWindow( _rContext->getValueByName( "DialogParentWindow" ), UNO_QUERY_THROW );
            Reference< XWindow > xInspectorWindow(rContext->getValueByName( "DialogParentWindow" ), UNO_QUERY_THROW);
            pInspectorWindow = Application::GetFrameWeld(xInspectorWindow);
        }
        catch( const Exception& )
@@ -306,6 +293,37 @@ namespace pcr
        }
        return pInspectorWindow;
    }

    std::unique_ptr<weld::Builder> PropertyHandlerHelper::makeBuilder(const OUString& rUIFile, const Reference<XComponentContext>& rContext)
    {
        bool bInterimBuilder(true);
        Any aReturn = rContext->getValueByName("InterimBuilder");
        aReturn >>= bInterimBuilder;

        Reference<XWindow> xWindow(rContext->getValueByName("BuilderParent"), UNO_QUERY_THROW);
        weld::TransportAsXWindow& rTunnel = dynamic_cast<weld::TransportAsXWindow&>(*xWindow);

        // bInterimBuilder for the hosted in sidebar in basic IDE case
        if (!bInterimBuilder)
            return std::unique_ptr<weld::Builder>(Application::CreateBuilder(rTunnel.getWidget(), rUIFile));
        return std::unique_ptr<weld::Builder>(Application::CreateInterimBuilder(rTunnel.getWidget(), rUIFile));
    }

    void PropertyHandlerHelper::setBuilderParent(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Widget* pParent, bool bInterimBuilder)
    {
        Reference<css::container::XNameContainer> xName(rContext, UNO_QUERY_THROW);
        xName->insertByName("InterimBuilder", makeAny(bInterimBuilder));
        Reference<XWindow> xWindow(new weld::TransportAsXWindow(pParent));
        xName->insertByName("BuilderParent", makeAny(xWindow));
    }

    void PropertyHandlerHelper::clearBuilderParent(css::uno::Reference<css::uno::XComponentContext>& rContext)
    {
        Reference<css::container::XNameContainer> xName(rContext, UNO_QUERY_THROW);
        xName->removeByName("InterimBuilder");
        xName->removeByName("BuilderParent");
    }

} // namespace pcr


diff --git a/extensions/source/propctrlr/handlerhelper.hxx b/extensions/source/propctrlr/handlerhelper.hxx
index e1eeed0..c170538 100644
--- a/extensions/source/propctrlr/handlerhelper.hxx
+++ b/extensions/source/propctrlr/handlerhelper.hxx
@@ -30,8 +30,7 @@

#include <vector>

namespace vcl { class Window; }
namespace weld { class Window; }
namespace weld { class Builder; class Widget; class Window; }
namespace com { namespace sun { namespace star {
    namespace inspection {
        struct LineDescriptor;
@@ -193,13 +192,12 @@ namespace pcr
        /** gets the window of the ObjectInspector in which a property handler lives

            The method looks up a value called "DialogParentWindow" in the given UNO component context,
            queries it for XWindow, and returns the respective vcl::Window*. If either of those steps fails,
            queries it for XWindow, and returns the respective weld::Window*. If either of those steps fails,
            this is asserted in a non-product version, and silently ignore otherwise.

            @param  _rContext
                the component context which was used to create the component calling this method
        */
        static vcl::Window* getDialogParentWindow( const css::uno::Reference< css::uno::XComponentContext > & _rContext );
        static weld::Window* getDialogParentFrame( const css::uno::Reference< css::uno::XComponentContext > & _rContext );


@@ -215,6 +213,12 @@ namespace pcr
            return ( _nPropertyAttributes & css::beans::PropertyAttribute::READONLY ) != 0;
        }

        static std::unique_ptr<weld::Builder> makeBuilder(const OUString& rUIFile, const css::uno::Reference<css::uno::XComponentContext>& rContext);

        static void setBuilderParent(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Widget* pParent, bool bInterim);

        static void clearBuilderParent(css::uno::Reference<css::uno::XComponentContext>& rContext);

    private:
        PropertyHandlerHelper( const PropertyHandlerHelper& ) = delete;
        PropertyHandlerHelper& operator=( const PropertyHandlerHelper& ) = delete;
diff --git a/extensions/source/propctrlr/inspectorhelpwindow.cxx b/extensions/source/propctrlr/inspectorhelpwindow.cxx
index 68f8b94..699f64c 100644
--- a/extensions/source/propctrlr/inspectorhelpwindow.cxx
+++ b/extensions/source/propctrlr/inspectorhelpwindow.cxx
@@ -23,123 +23,58 @@

namespace pcr
{

    //= InspectorHelpWindow


    InspectorHelpWindow::InspectorHelpWindow( vcl::Window* _pParent )
        :Window( _pParent, WB_DIALOGCONTROL )
        ,m_aSeparator( VclPtr<FixedLine>::Create(this) )
        ,m_aHelpText( VclPtr<MultiLineEdit>::Create(this, WB_LEFT | WB_READONLY | WB_AUTOVSCROLL) )
        ,m_nMinLines( 3 )
        ,m_nMaxLines( 8 )
    InspectorHelpWindow::InspectorHelpWindow(weld::Builder& rBuilder)
        : m_xHelpFrame(rBuilder.weld_widget("helpframe"))
        , m_xHelpText(rBuilder.weld_text_view("helptext"))
        , m_nMinLines( 3 )
        , m_nMaxLines( 8 )
    {
        SetBackground();
        SetPaintTransparent(true);
        m_aSeparator->SetText( PcrRes(RID_STR_HELP_SECTION_LABEL) );
        m_aSeparator->SetBackground();
        m_aSeparator->Show();

        m_aHelpText->SetControlBackground( /*m_aSeparator->GetBackground().GetColor() */);
        m_aHelpText->SetBackground();
        m_aHelpText->SetPaintTransparent(true);
        m_aHelpText->Show();
    }

    InspectorHelpWindow::~InspectorHelpWindow()
    {
        disposeOnce();
    }

    void InspectorHelpWindow::dispose()
    void InspectorHelpWindow::SetText(const OUString& rStr)
    {
        m_aSeparator.disposeAndClear();
        m_aHelpText.disposeAndClear();
        vcl::Window::dispose();
        m_xHelpText->set_text(rStr);
    }

    void InspectorHelpWindow::SetText( const OUString& _rStr )
    void InspectorHelpWindow::SetLimits(sal_Int32 nMinLines, sal_Int32 nMaxLines)
    {
        m_aHelpText->SetText( _rStr );
        m_nMinLines = nMinLines;
        m_nMaxLines = nMaxLines;
    }


    void InspectorHelpWindow::SetLimits( sal_Int32 _nMinLines, sal_Int32 _nMaxLines )
    {
        m_nMinLines = _nMinLines;
        m_nMaxLines = _nMaxLines;
    }


    long InspectorHelpWindow::impl_getHelpTextBorderHeight()
    {
        sal_Int32 nTop(0), nBottom(0), nDummy(0);
        m_aHelpText->GetBorder( nDummy, nTop, nDummy, nBottom );
        return nTop + nBottom;
    }


    long InspectorHelpWindow::impl_getSpaceAboveTextWindow()
    {
        Size aSeparatorSize(LogicToPixel(Size(0, 8), MapMode(MapUnit::MapAppFont)));
        Size a3AppFontSize(LogicToPixel(Size(3, 3), MapMode(MapUnit::MapAppFont)));
        return aSeparatorSize.Height() + a3AppFontSize.Height();
    }


    long InspectorHelpWindow::GetMinimalHeightPixel()
    {
        return impl_getMinimalTextWindowHeight() + impl_getSpaceAboveTextWindow();
        return impl_getMinimalTextWindowHeight();
    }


    long InspectorHelpWindow::impl_getMinimalTextWindowHeight()
    {
        return impl_getHelpTextBorderHeight() + m_aHelpText->GetTextHeight() * m_nMinLines;
        return m_xHelpText->get_height_rows(m_nMinLines);
    }


    long InspectorHelpWindow::impl_getMaximalTextWindowHeight()
    {
        return impl_getHelpTextBorderHeight() + m_aHelpText->GetTextHeight() * m_nMaxLines;
        return m_xHelpText->get_height_rows(m_nMaxLines);
    }


    long InspectorHelpWindow::GetOptimalHeightPixel()
    {
        // --- calc the height as needed for the mere text window
        long nMinTextWindowHeight = impl_getMinimalTextWindowHeight();
        long nMaxTextWindowHeight = impl_getMaximalTextWindowHeight();

        tools::Rectangle aTextRect( Point( 0, 0 ), m_aHelpText->GetOutputSizePixel() );
        aTextRect = m_aHelpText->GetTextRect( aTextRect, m_aHelpText->GetText(),
            DrawTextFlags::Left | DrawTextFlags::Top | DrawTextFlags::MultiLine | DrawTextFlags::WordBreak );
        long nActTextWindowHeight = impl_getHelpTextBorderHeight() + aTextRect.GetHeight();
        long nActTextWindowHeight = m_xHelpFrame->get_preferred_size().Height();

        long nOptTextWindowHeight = std::max( nMinTextWindowHeight, std::min( nMaxTextWindowHeight, nActTextWindowHeight ) );

        // --- then add the space above the text window
        return nOptTextWindowHeight + impl_getSpaceAboveTextWindow();
        return nOptTextWindowHeight;
    }


    void InspectorHelpWindow::Resize()
    {
        Size a3AppFont(LogicToPixel(Size(3, 3), MapMode(MapUnit::MapAppFont)));

        tools::Rectangle aPlayground( Point( 0, 0 ), GetOutputSizePixel() );

        tools::Rectangle aSeparatorArea( aPlayground );
        aSeparatorArea.SetBottom( aSeparatorArea.Top() + LogicToPixel(Size(0, 8), MapMode(MapUnit::MapAppFont)).Height() );
        m_aSeparator->SetPosSizePixel( aSeparatorArea.TopLeft(), aSeparatorArea.GetSize() );

        tools::Rectangle aTextArea( aPlayground );
        aTextArea.SetTop( aSeparatorArea.Bottom() + a3AppFont.Height() );
        m_aHelpText->SetPosSizePixel( aTextArea.TopLeft(), aTextArea.GetSize() );
    }


} // namespace pcr


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/inspectorhelpwindow.hxx b/extensions/source/propctrlr/inspectorhelpwindow.hxx
index 4cae0ba..5c2a672 100644
--- a/extensions/source/propctrlr/inspectorhelpwindow.hxx
+++ b/extensions/source/propctrlr/inspectorhelpwindow.hxx
@@ -20,50 +20,41 @@
#define INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_INSPECTORHELPWINDOW_HXX

#include <vcl/fixed.hxx>
#include <vcl/weld.hxx>
#include <svtools/svmedit.hxx>


namespace pcr
{


    //= InspectorHelpWindow

    class InspectorHelpWindow : public vcl::Window
    class InspectorHelpWindow
    {
    private:
        VclPtr<FixedLine>       m_aSeparator;
        VclPtr<MultiLineEdit>   m_aHelpText;
        std::unique_ptr<weld::Widget> m_xHelpFrame;
        std::unique_ptr<weld::TextView> m_xHelpText;

        sal_Int32       m_nMinLines;
        sal_Int32       m_nMaxLines;

    public:
        explicit InspectorHelpWindow( vcl::Window* _pParent );
        virtual ~InspectorHelpWindow() override;
        virtual void dispose() override;
        explicit InspectorHelpWindow(weld::Builder& rBuilder);
        ~InspectorHelpWindow();

        virtual void    SetText( const OUString& rStr ) override;
        void            SetText(const OUString& rStr);

        void            SetLimits( sal_Int32 _nMinLines, sal_Int32 _nMaxLines );
        void            SetLimits(sal_Int32 nMinLines, sal_Int32 nMaxLines);
        long            GetMinimalHeightPixel();
        long            GetOptimalHeightPixel();

    protected:
        // Window overridables
        virtual void    Resize() override;
        void            Show(bool bShow) { m_xHelpFrame->set_visible(bShow); }
        bool            IsVisible() const { return m_xHelpFrame->get_visible(); }

    private:
        long            impl_getMinimalTextWindowHeight();
        long            impl_getMaximalTextWindowHeight();
        long            impl_getHelpTextBorderHeight();
        long            impl_getSpaceAboveTextWindow();
    };


} // namespace pcr


#endif // HELPWINDOW_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/linedescriptor.hxx b/extensions/source/propctrlr/linedescriptor.hxx
index 00b4e37..df44fbb 100644
--- a/extensions/source/propctrlr/linedescriptor.hxx
+++ b/extensions/source/propctrlr/linedescriptor.hxx
@@ -22,13 +22,9 @@
#include <vcl/image.hxx>
#include <com/sun/star/inspection/LineDescriptor.hpp>


namespace pcr
{


    //= OLineDescriptor

    struct OLineDescriptor : public css::inspection::LineDescriptor
    {
        OUString                    sName;              // the name of the property
@@ -51,10 +47,8 @@ namespace pcr
        }
    };


} // namespace pcr


#endif // INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_LINEDESCRIPTOR_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/propcontroller.cxx b/extensions/source/propctrlr/propcontroller.cxx
index 739f83a..faa0ae9 100644
--- a/extensions/source/propctrlr/propcontroller.cxx
+++ b/extensions/source/propctrlr/propcontroller.cxx
@@ -20,6 +20,7 @@
#include "pcrservices.hxx"
#include "propcontroller.hxx"
#include "pcrstrings.hxx"
#include "handlerhelper.hxx"
#include "standardcontrol.hxx"
#include "linedescriptor.hxx"
#include <strings.hrc>
@@ -44,8 +45,9 @@
#include <toolkit/awt/vclxwindow.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <comphelper/property.hxx>
#include <vcl/weld.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <vcl/weldutils.hxx>
#include <osl/mutex.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <cppuhelper/component_context.hxx>
@@ -57,18 +59,14 @@
#include <sal/macros.h>
#include <sal/log.hxx>


// !!! outside the namespace !!!
extern "C" void createRegistryInfo_OPropertyBrowserController()
{
    ::pcr::OAutoRegistration< ::pcr::OPropertyBrowserController > aAutoRegistration;
}


namespace pcr
{


    using namespace ::com::sun::star;
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::awt;
@@ -83,23 +81,19 @@ namespace pcr
    using namespace ::com::sun::star::ucb;
    using namespace ::comphelper;


    //= OPropertyBrowserController


    OPropertyBrowserController::OPropertyBrowserController( const Reference< XComponentContext >& _rxContext )
            :m_xContext(_rxContext)
            ,m_aDisposeListeners( m_aMutex )
            ,m_aControlObservers( m_aMutex )
            ,m_pView(nullptr)
            ,m_bContainerFocusListening( false )
            ,m_bSuspendingPropertyHandlers( false )
            ,m_bConstructed( false )
            ,m_bBindingIntrospectee( false )
            ,m_bInterimBuilder( false )
    {
    }


    OPropertyBrowserController::~OPropertyBrowserController()
    {
        // stop listening for property changes
@@ -107,10 +101,8 @@ namespace pcr
        stopInspection( true );
    }


    IMPLEMENT_FORWARD_REFCOUNT( OPropertyBrowserController, OPropertyBrowserController_Base )


    Any SAL_CALL OPropertyBrowserController::queryInterface( const Type& _rType )
    {
        Any aReturn = OPropertyBrowserController_Base::queryInterface( _rType );
@@ -350,6 +342,9 @@ namespace pcr
        // revoke as focus listener from the old container window
        stopContainerWindowListening();

        m_xPropView.reset();
        m_xBuilder.reset();

        m_xFrame = _rxFrame;
        if (!m_xFrame.is())
            return;
@@ -357,28 +352,33 @@ namespace pcr
        // TODO: this construction perhaps should be done outside. Don't know the exact meaning of attachFrame.
        // Maybe it is intended to only announce the frame to the controller, and the instance doing this
        // announcement is responsible for calling setComponent, too.
        Reference< XWindow > xContainerWindow = m_xFrame->getContainerWindow();
        VCLXWindow* pContainerWindow = comphelper::getUnoTunnelImplementation<VCLXWindow>(xContainerWindow);
        VclPtr<vcl::Window> pParentWin = pContainerWindow ? pContainerWindow->GetWindow() : VclPtr<vcl::Window>();
        if (!pParentWin)
            throw RuntimeException("The frame is invalid. Unable to extract the container window.",*this);
        Reference<XWindow> xContainerWindow = m_xFrame->getContainerWindow();

        Construct( pParentWin );
        try
        OUString sUIFile("modules/spropctrlr/ui/formproperties.ui");
        std::unique_ptr<weld::Builder> xBuilder;

        if (weld::TransportAsXWindow* pTunnel = dynamic_cast<weld::TransportAsXWindow*>(xContainerWindow.get()))
        {
            m_xFrame->setComponent( VCLUnoHelper::GetInterface( m_pView ), this );
            xBuilder.reset(Application::CreateBuilder(pTunnel->getWidget(), sUIFile));
            m_bInterimBuilder = false;
        }
        catch( const Exception& )
        else
        {
            OSL_FAIL( "OPropertyBrowserController::attachFrame: caught an exception!" );
            VCLXWindow* pContainerWindow = comphelper::getUnoTunnelImplementation<VCLXWindow>(xContainerWindow);
            VclPtr<vcl::Window> pParentWin = pContainerWindow ? pContainerWindow->GetWindow() : VclPtr<vcl::Window>();
            if (!pParentWin)
                throw RuntimeException("The frame is invalid. Unable to extract the container window.",*this);
            xBuilder.reset(Application::CreateInterimBuilder(pParentWin, sUIFile));
            m_bInterimBuilder = true;
        }

        Construct(xContainerWindow, std::move(xBuilder));

        startContainerWindowListening();

        UpdateUI();
    }


    sal_Bool SAL_CALL OPropertyBrowserController::attachModel( const Reference< XModel >& _rxModel )
    {
        Reference< XObjectInspectorModel > xModel( _rxModel, UNO_QUERY );
@@ -479,21 +479,18 @@ namespace pcr
        }
    }


    Reference< XModel > SAL_CALL OPropertyBrowserController::getModel(  )
    {
        // have no model
        return Reference< XModel >();
    }


    Reference< XFrame > SAL_CALL OPropertyBrowserController::getFrame(  )
    {
        return m_xFrame;
    }


    void SAL_CALL OPropertyBrowserController::dispose(  )
    void SAL_CALL OPropertyBrowserController::dispose()
    {
        SolarMutexGuard aSolarGuard;

@@ -506,8 +503,8 @@ namespace pcr
        m_aDisposeListeners.disposeAndClear(aEvt);
        m_aControlObservers.disposeAndClear(aEvt);

        // don't delete explicitly (this is done by the frame we reside in)
        m_pView = nullptr;
        m_xPropView.reset();
        m_xBuilder.reset();

        if ( m_xView.is() )
            m_xView->removeEventListener( static_cast< XPropertyChangeListener* >( this ) );
@@ -517,19 +514,16 @@ namespace pcr
        impl_bindToNewModel_nothrow( nullptr );
    }


    void SAL_CALL OPropertyBrowserController::addEventListener( const Reference< XEventListener >& _rxListener )
    {
        m_aDisposeListeners.addInterface(_rxListener);
    }


    void SAL_CALL OPropertyBrowserController::removeEventListener( const Reference< XEventListener >& _rxListener )
    {
        m_aDisposeListeners.removeInterface(_rxListener);
    }


    OUString SAL_CALL OPropertyBrowserController::getImplementationName(  )
    {
        return getImplementationName_static();
@@ -592,7 +586,8 @@ namespace pcr
        if ( m_xView.is() && ( m_xView == _rSource.Source ) )
        {
            m_xView = nullptr;
            m_pView = nullptr;
            m_xPropView.reset();
            m_xBuilder.reset();
        }

        auto it = std::find_if(m_aInspectedObjects.begin(), m_aInspectedObjects.end(),
@@ -616,7 +611,7 @@ namespace pcr
        OUString sOldSelection = m_sPageSelection;
        m_sPageSelection.clear();

        const sal_uInt16 nCurrentPage = m_pView->getActivaPage();
        const sal_uInt16 nCurrentPage = m_xPropView->getActivePage();
        if ( sal_uInt16(-1) != nCurrentPage )
        {
            for (auto const& pageId : m_aPageIds)
@@ -645,42 +640,39 @@ namespace pcr
        return nPageId;
    }


    void OPropertyBrowserController::selectPageFromViewData()
    {
        sal_uInt16 nNewPage = impl_getPageIdForCategory_nothrow( m_sPageSelection );

        if ( haveView() && ( nNewPage != sal_uInt16(-1) ) )
            m_pView->activatePage( nNewPage );
            m_xPropView->activatePage( nNewPage );

        // just in case ...
        updateViewDataFromActivePage();
    }


    void OPropertyBrowserController::Construct(vcl::Window* _pParentWin)
    void OPropertyBrowserController::Construct(const Reference<XWindow>& rContainerWindow, std::unique_ptr<weld::Builder> xBuilder)
    {
        DBG_ASSERT(!haveView(), "OPropertyBrowserController::Construct: already have a view!");
        DBG_ASSERT(_pParentWin, "OPropertyBrowserController::Construct: invalid parent window!");
        assert(xBuilder.get() && "OPropertyBrowserController::Construct: invalid parent window!");

        m_pView = VclPtr<OPropertyBrowserView>::Create(_pParentWin);
        m_pView->setPageActivationHandler(LINK(this, OPropertyBrowserController, OnPageActivation));
        m_xBuilder = std::move(xBuilder);

        m_xPropView.reset(new OPropertyBrowserView(m_xContext, *m_xBuilder, m_bInterimBuilder));
        m_xPropView->setPageActivationHandler(LINK(this, OPropertyBrowserController, OnPageActivation));

        // add as dispose listener for our view. The view is disposed by the frame we're plugged into,
        // and this disposal _deletes_ the view, so it would be deadly if we use our m_pView member
        // and this disposal _deletes_ the view, so it would be deadly if we use our m_xPropView member
        // after that
        m_xView = VCLUnoHelper::GetInterface(m_pView);
        m_xView = rContainerWindow;
        if (m_xView.is())
            m_xView->addEventListener( static_cast< XPropertyChangeListener* >( this ) );

        getPropertyBox().SetLineListener(this);
        getPropertyBox().SetControlObserver(this);
        impl_initializeView_nothrow();

        m_pView->Show();
    }


    void SAL_CALL OPropertyBrowserController::propertyChange( const PropertyChangeEvent& _rEvent )
    {
        if ( _rEvent.Source == m_xModel )
@@ -724,70 +716,112 @@ namespace pcr
            impl_broadcastPropertyChange_nothrow( _rEvent.PropertyName, aNewValue, _rEvent.OldValue, false );
    }


    Reference< XPropertyControl > SAL_CALL OPropertyBrowserController::createPropertyControl( ::sal_Int16 ControlType, sal_Bool CreateReadOnly )
    Reference< XPropertyControl > SAL_CALL OPropertyBrowserController::createPropertyControl( ::sal_Int16 ControlType, sal_Bool bCreateReadOnly )
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        Reference< XPropertyControl > xControl;

        // default winbits: a border only
        WinBits nWinBits = WB_BORDER;

        // read-only-ness
        CreateReadOnly |= impl_isReadOnlyModel_throw() ? 1 : 0;
        if ( CreateReadOnly )
            nWinBits |= WB_READONLY;
        bCreateReadOnly |= impl_isReadOnlyModel_throw() ? 1 : 0;

        switch ( ControlType )
        {
            case PropertyControlType::StringListField:
                xControl = new OMultilineEditControl( &getPropertyBox(), eStringList, nWinBits | WB_DROPDOWN | WB_TABSTOP );
                break;

            case PropertyControlType::MultiLineTextField:
                xControl = new OMultilineEditControl( &getPropertyBox(), eMultiLineText, nWinBits | WB_DROPDOWN | WB_TABSTOP );
            case PropertyControlType::StringListField:
            {
                bool bMultiLineTextField = ControlType == PropertyControlType::MultiLineTextField;
                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/multiline.ui", m_xContext));
                auto pControl = new OMultilineEditControl(xBuilder->weld_container("multiline"), std::move(xBuilder),
                                                          bMultiLineTextField ? eMultiLineText : eStringList, bCreateReadOnly);
                pControl->SetModifyHandler();
                xControl = pControl;
                break;
            }

            case PropertyControlType::ListBox:
                xControl = new OListboxControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_DROPDOWN);
            {
                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/listbox.ui", m_xContext));
                auto pControl = new OListboxControl(xBuilder->weld_combo_box("listbox"), std::move(xBuilder), bCreateReadOnly);
                pControl->SetModifyHandler();
                xControl = pControl;
                break;
            }

            case PropertyControlType::ComboBox:
                xControl = new OComboboxControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_DROPDOWN);
            {
                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/combobox.ui", m_xContext));
                auto pControl = new OComboboxControl(xBuilder->weld_combo_box("combobox"), std::move(xBuilder), bCreateReadOnly);
                pControl->SetModifyHandler();
                xControl = pControl;
                break;
            }

            case PropertyControlType::TextField:
                xControl = new OEditControl( &getPropertyBox(), false, nWinBits | WB_TABSTOP );
                break;

            case PropertyControlType::CharacterField:
                xControl = new OEditControl( &getPropertyBox(), true, nWinBits | WB_TABSTOP );
            {
                bool bCharacterField = ControlType == PropertyControlType::CharacterField;
                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/textfield.ui", m_xContext));
                auto pControl = new OEditControl(xBuilder->weld_entry("textfield"), std::move(xBuilder), bCharacterField, bCreateReadOnly);
                pControl->SetModifyHandler();
                xControl = pControl;
                break;
            }

            case PropertyControlType::NumericField:
                xControl = new ONumericControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_SPIN | WB_REPEAT );
            {
                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/numericfield.ui", m_xContext));
                auto pControl = new ONumericControl(xBuilder->weld_metric_spin_button("numericfield", FieldUnit::NONE), std::move(xBuilder), bCreateReadOnly);
                pControl->SetModifyHandler();
                xControl = pControl;
                break;
            }

            case PropertyControlType::DateTimeField:
                xControl = new ODateTimeControl( &getPropertyBox(), nWinBits | WB_TABSTOP );
            {
                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/datetimefield.ui", m_xContext));
                auto pControl = new ODateTimeControl(xBuilder->weld_container("datetimefield"), std::move(xBuilder), bCreateReadOnly);
                pControl->SetModifyHandler();
                xControl = pControl;
                break;
            }

            case PropertyControlType::DateField:
                xControl = new ODateControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_SPIN | WB_REPEAT );
            {
                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/datefield.ui", m_xContext));
                auto pControl = new ODateControl(std::make_unique<SvtCalendarBox>(xBuilder->weld_menu_button("datefield")), std::move(xBuilder), bCreateReadOnly);
                pControl->SetModifyHandler();
                xControl = pControl;
                break;
            }

            case PropertyControlType::TimeField:
                xControl = new OTimeControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_SPIN | WB_REPEAT );
            {
                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/timefield.ui", m_xContext));
                auto pControl = new OTimeControl(xBuilder->weld_time_spin_button("timefield", TimeFieldFormat::F_SEC), std::move(xBuilder), bCreateReadOnly);
                pControl->SetModifyHandler();
                xControl = pControl;
                break;
            }

            case PropertyControlType::ColorListBox:
                xControl = new OColorControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_DROPDOWN );
            {
                weld::Window* pTopLevel = PropertyHandlerHelper::getDialogParentFrame(m_xContext);
                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/colorlistbox.ui", m_xContext));
                auto pControl = new OColorControl(std::make_unique<ColorListBox>(xBuilder->weld_menu_button("colorlistbox"), pTopLevel), std::move(xBuilder), bCreateReadOnly);
                pControl->SetModifyHandler();
                xControl = pControl;
                break;
            }

            case PropertyControlType::HyperlinkField:
                xControl = new OHyperlinkControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_DROPDOWN );
            {
                std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/hyperlinkfield.ui", m_xContext));
                auto pControl = new OHyperlinkControl(xBuilder->weld_container("hyperlinkfield"), std::move(xBuilder), bCreateReadOnly);
                pControl->SetModifyHandler();
                xControl = pControl;
                break;
            }

            default:
                throw IllegalArgumentException( OUString(), *this, 1 );
@@ -1044,8 +1078,8 @@ namespace pcr
    css::awt::Size SAL_CALL OPropertyBrowserController::getMinimumSize()
    {
        css::awt::Size aSize;
        if( m_pView )
            return m_pView->getMinimumSize();
        if( m_xPropView )
            return m_xPropView->getMinimumSize();
        else
            return aSize;
    }
@@ -1136,10 +1170,6 @@ namespace pcr
                // too early, will return later
                return;

            getPropertyBox().DisableUpdate();

            bool bHaveFocus = getPropertyBox().HasChildPathFocus();

            // create our tab pages
            impl_buildCategories_throw();
            // (and allow for pages to be actually unused)
@@ -1205,21 +1235,17 @@ namespace pcr
            }
            m_aPageIds.swap( aSurvivingPageIds );


            getPropertyBox().Show();
            getPropertyBox().EnableUpdate();
            if ( bHaveFocus )
                getPropertyBox().GrabFocus();

            // activate the first page
            if ( !m_aPageIds.empty() )
            {
                Sequence< PropertyCategoryDescriptor > aCategories( m_xModel->describeCategories() );
                if ( aCategories.hasElements() )
                    m_pView->activatePage( m_aPageIds[ aCategories[0].ProgrammaticName ] );
                    m_xPropView->activatePage( m_aPageIds[ aCategories[0].ProgrammaticName ] );
                else
                    // allowed: if we default-created the pages ...
                    m_pView->activatePage( m_aPageIds.begin()->second );
                    m_xPropView->activatePage( m_aPageIds.begin()->second );
            }

            // activate the previously active page (if possible)
@@ -1332,7 +1358,7 @@ namespace pcr
        }
        catch(const PropertyVetoException& eVetoException)
        {
            std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_pView ? m_pView->GetFrameWeld() : nullptr,
            std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xPropView->getPropertyBox().getWidget(),
                                                          VclMessageType::Info, VclButtonsType::Ok,
                                                          eVetoException.Message));
            xInfoBox->run();
@@ -1389,25 +1415,6 @@ namespace pcr
        if ( _rObjects.empty() )
            return;

        // create a component context for the handlers, containing some information about where
        // they live
        Reference< XComponentContext > xHandlerContext( m_xContext );

        // if our own creator did not pass a dialog parent window, use our own view for this
        Reference< XWindow > xParentWindow;
        Any any = m_xContext->getValueByName( "DialogParentWindow" );
        any >>= xParentWindow;
        if ( !xParentWindow.is() )
        {
            ::cppu::ContextEntry_Init aHandlerContextInfo[] =
            {
                ::cppu::ContextEntry_Init( "DialogParentWindow", makeAny( VCLUnoHelper::GetInterface( m_pView ) ) )
            };
            xHandlerContext = ::cppu::createComponentContext(
                aHandlerContextInfo, SAL_N_ELEMENTS( aHandlerContextInfo ),
                m_xContext );
        }

        Sequence< Any > aHandlerFactories;
        if ( m_xModel.is() )
            aHandlerFactories = m_xModel->getHandlerFactories();
@@ -1574,16 +1581,16 @@ namespace pcr
    }


    void OPropertyBrowserController::showCategory( const OUString& _rCategory, sal_Bool _bShow )
    void OPropertyBrowserController::showCategory( const OUString& rCategory, sal_Bool bShow )
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( !haveView() )
            throw RuntimeException();

        sal_uInt16 nPageId = impl_getPageIdForCategory_nothrow( _rCategory );
        sal_uInt16 nPageId = impl_getPageIdForCategory_nothrow( rCategory );
        OSL_ENSURE( nPageId != sal_uInt16(-1), "OPropertyBrowserController::showCategory: invalid category!" );

        getPropertyBox().ShowPropertyPage( nPageId, _bShow );
        getPropertyBox().ShowPropertyPage( nPageId, bShow );
    }


diff --git a/extensions/source/propctrlr/propcontroller.hxx b/extensions/source/propctrlr/propcontroller.hxx
index 0dbbe5c..ee35d79 100644
--- a/extensions/source/propctrlr/propcontroller.hxx
+++ b/extensions/source/propctrlr/propcontroller.hxx
@@ -52,19 +52,15 @@
#include <cppuhelper/interfacecontainer.hxx>
#include <cppuhelper/implbase.hxx>
#include <comphelper/broadcasthelper.hxx>
#include <vcl/weld.hxx>

#include <map>
#include <memory>
#include <unordered_map>
#include <vector>

namespace vcl { class Window; }


namespace pcr
{


    class OPropertyEditor;
    struct OLineDescriptor;

@@ -102,7 +98,8 @@ namespace pcr
        ::comphelper::OInterfaceContainerHelper2   m_aDisposeListeners;
        ::comphelper::OInterfaceContainerHelper2   m_aControlObservers;
        // meta data about the properties
        VclPtr<OPropertyBrowserView>        m_pView;
        std::unique_ptr<weld::Builder> m_xBuilder;
        std::unique_ptr<OPropertyBrowserView> m_xPropView;

        OUString                     m_sPageSelection;
        OUString                     m_sLastValidPageSelection;
@@ -137,6 +134,7 @@ namespace pcr
        bool        m_bSuspendingPropertyHandlers;
        bool        m_bConstructed;
        bool        m_bBindingIntrospectee;
        bool        m_bInterimBuilder;

    protected:
        DECLARE_XINTERFACE()
@@ -170,7 +168,7 @@ namespace pcr
        // XLayoutConstrains
        virtual css::awt::Size SAL_CALL getMinimumSize(  ) override;
        virtual css::awt::Size SAL_CALL getPreferredSize(  ) override;
        virtual css::awt::Size SAL_CALL calcAdjustedSize( const css::awt::Size& aNewSize ) override;
        virtual css::awt::Size SAL_CALL calcAdjustedSize( const css::awt::Size& rNewSize ) override;

        // XPropertyChangeListener
        virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& _rEvent ) override;
@@ -241,8 +239,8 @@ namespace pcr
        // stop the inspection
        void stopInspection( bool _bCommitModified );

        bool haveView() const { return nullptr != m_pView; }
        OPropertyEditor&    getPropertyBox() { return m_pView->getPropertyBox(); }
        bool haveView() const { return m_xPropView.get() != nullptr; }
        OPropertyEditor&    getPropertyBox() { return m_xPropView->getPropertyBox(); }

        // does the inspection of the objects as indicated by our model
        void doInspection();
@@ -307,7 +305,7 @@ namespace pcr
        */
        bool impl_findObjectProperty_nothrow( const OUString& _rName, OrderedPropertyMap::const_iterator* _pProperty = nullptr );

        void Construct(vcl::Window* _pParentWin);
        void Construct(const css::uno::Reference<css::awt::XWindow>& rContainerWindow, std::unique_ptr<weld::Builder> xBuilder);

        /** retrieves the property handler for a given property name
            @param  _rPropertyName
diff --git a/extensions/source/propctrlr/propertyeditor.cxx b/extensions/source/propctrlr/propertyeditor.cxx
index 5e90428..0b0de48a 100644
--- a/extensions/source/propctrlr/propertyeditor.cxx
+++ b/extensions/source/propctrlr/propertyeditor.cxx
@@ -17,6 +17,7 @@
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "handlerhelper.hxx"
#include "propertyeditor.hxx"
#include "browserpage.hxx"
#include "linedescriptor.hxx"
@@ -24,372 +25,249 @@
#include <tools/debug.hxx>
#include <osl/diagnose.h>


namespace pcr
{


    #define LAYOUT_BORDER_LEFT      3
    #define LAYOUT_BORDER_TOP       3
    #define LAYOUT_BORDER_RIGHT     3
    #define LAYOUT_BORDER_BOTTOM    3

    using ::com::sun::star::uno::Any;
    using ::com::sun::star::inspection::XPropertyControl;
    using ::com::sun::star::uno::Reference;




    OPropertyEditor::OPropertyEditor( vcl::Window* pParent)
            :Control(pParent, WB_DIALOGCONTROL)
            ,m_aTabControl( VclPtr<TabControl>::Create(this) )
            ,m_pListener(nullptr)
            ,m_pObserver(nullptr)
            ,m_nNextId(1)
            ,m_bHasHelpSection( false )
            ,m_nMinHelpLines( 0 )
            ,m_nMaxHelpLines( 0 )
    OPropertyEditor::OPropertyEditor(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder, bool bInterimBuilder)
        : m_xContainer(rBuilder.weld_container("box"))
        , m_xTabControl(rBuilder.weld_notebook("tabcontrol"))
        , m_xControlHoldingParent(rBuilder.weld_container("controlparent")) // controls initially have this parent before they are moved
        , m_xContext(rContext)
        , m_pListener(nullptr)
        , m_pObserver(nullptr)
        , m_nNextId(1)
        , m_bHasHelpSection(false)
        , m_bInterimBuilder(bInterimBuilder)
        , m_nMinHelpLines(0)
        , m_nMaxHelpLines(0)
    {
        PropertyHandlerHelper::setBuilderParent(rContext, m_xControlHoldingParent.get(), bInterimBuilder);

        m_aTabControl->Show();
        m_aTabControl->SetDeactivatePageHdl(LINK(this, OPropertyEditor, OnPageDeactivate));
        m_aTabControl->SetActivatePageHdl(LINK(this, OPropertyEditor, OnPageActivate));
        m_aTabControl->SetBackground(GetBackground());
        m_aTabControl->SetPaintTransparent(true);
        m_xTabControl->connect_leave_page(LINK(this, OPropertyEditor, OnPageDeactivate));
        m_xTabControl->connect_enter_page(LINK(this, OPropertyEditor, OnPageActivate));
    }


    OPropertyEditor::~OPropertyEditor()
    {
        disposeOnce();
    }

    void OPropertyEditor::dispose()
    {
        Hide();
        PropertyHandlerHelper::clearBuilderParent(m_xContext);
        ClearAll();
        m_aTabControl.disposeAndClear();
        Control::dispose();
    }


    void OPropertyEditor::ClearAll()
    {
        m_nNextId=1;
        sal_uInt16 nCount = m_aTabControl->GetPageCount();
        for(long i = nCount-1; i >= 0; --i)
        {
            sal_uInt16 nID = m_aTabControl->GetPageId(static_cast<sal_uInt16>(i));
            VclPtr<OBrowserPage> pPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(nID));
            if (pPage)
            {
                pPage->EnableInput(false);
                m_aTabControl->RemovePage(nID);
                pPage.disposeAndClear();
            }
        }
        m_aTabControl->Clear();

        {
            MapStringToPageId aEmpty;
            m_aPropertyPageIds.swap( aEmpty );
        }

        for (auto& rEntry : m_aHiddenPages)
            rEntry.second.pPage.disposeAndClear();
        m_aPropertyPageIds.clear();
        m_aShownPages.clear();
        m_aHiddenPages.clear();
    }


    sal_Int32 OPropertyEditor::getMinimumHeight() const
    {
        sal_Int32 nMinHeight( LAYOUT_BORDER_TOP + LAYOUT_BORDER_BOTTOM );

        if ( m_aTabControl->GetPageCount() > 0 )
        int nCount = m_xTabControl->get_n_pages();
        for (int i = nCount - 1; i >= 0; --i)
        {
            sal_uInt16 nFirstID = m_aTabControl->GetPageId( 0 );

            // reserve space for the tabs themself
            tools::Rectangle aTabArea( m_aTabControl->GetTabBounds( nFirstID ) );
            nMinHeight += aTabArea.GetHeight();

            // ask the page how much it requires
            OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( nFirstID ) );
            if ( pPage )
                nMinHeight += pPage->getMinimumHeight();
            OString sID = m_xTabControl->get_page_ident(i);
            m_xTabControl->remove_page(sID);
        }
        else
            nMinHeight += 250;  // arbitrary ...

        return nMinHeight;
        assert(m_xTabControl->get_n_pages() == 0);
    }


    sal_Int32 OPropertyEditor::getMinimumWidth() const
    Size OPropertyEditor::get_preferred_size() const
    {
        sal_uInt16 nCount = m_aTabControl->GetPageCount();
        sal_Int32 nPageMinWidth = 0;
        for(long i = nCount-1; i >= 0; --i)
        {
            sal_uInt16 nID = m_aTabControl->GetPageId(static_cast<sal_uInt16>(i));
            OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(nID));
            if (pPage)
            {
                sal_Int32 nCurPageMinWidth = pPage->getMinimumWidth();
                if( nCurPageMinWidth > nPageMinWidth )
                    nPageMinWidth = nCurPageMinWidth;
            }
        }
        return nPageMinWidth+6;
        return m_xTabControl->get_preferred_size();
    }


    void OPropertyEditor::CommitModified()
    {
        // commit all of my pages, if necessary

        sal_uInt16 nCount = m_aTabControl->GetPageCount();
        for ( sal_uInt16 i=0; i<nCount; ++i )
        for (auto& page : m_aShownPages)
        {
            sal_uInt16 nID = m_aTabControl->GetPageId( i );
            OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( nID ) );

            if ( pPage && pPage->getListBox().IsModified() )
            OBrowserPage* pPage = page.second.xPage.get();
            if (pPage && pPage->getListBox().IsModified() )
                pPage->getListBox().CommitModified();
        }
    }


    void OPropertyEditor::GetFocus()
    {
        if ( m_aTabControl )
            m_aTabControl->GrabFocus();
    }


    OBrowserPage* OPropertyEditor::getPage( const OUString& _rPropertyName )
    OBrowserPage* OPropertyEditor::getPage(const OUString& rPropertyName)
    {
        OBrowserPage* pPage = nullptr;
        MapStringToPageId::const_iterator aPropertyPageIdPos = m_aPropertyPageIds.find( _rPropertyName );
        if ( aPropertyPageIdPos != m_aPropertyPageIds.end() )
            pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( aPropertyPageIdPos->second ) );
        MapStringToPageId::const_iterator aPropertyPageIdPos = m_aPropertyPageIds.find(rPropertyName);
        if (aPropertyPageIdPos != m_aPropertyPageIds.end())
            pPage = getPage(aPropertyPageIdPos->second);
        return pPage;
    }


    const OBrowserPage* OPropertyEditor::getPage( const OUString& _rPropertyName ) const
    {
        return const_cast< OPropertyEditor* >( this )->getPage( _rPropertyName );
    }


    OBrowserPage* OPropertyEditor::getPage( sal_uInt16 _rPageId )
    OBrowserPage* OPropertyEditor::getPage(sal_uInt16 rPageId)
    {
        return static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( _rPageId ) );
        OBrowserPage* pPage = nullptr;
        auto aPagePos = m_aShownPages.find(rPageId);
        if (aPagePos != m_aShownPages.end())
            pPage = aPagePos->second.xPage.get();
        return pPage;
    }


    const OBrowserPage* OPropertyEditor::getPage( sal_uInt16 _rPageId ) const
    const OBrowserPage* OPropertyEditor::getPage(sal_uInt16 rPageId) const
    {
        return const_cast< OPropertyEditor* >( this )->getPage( _rPageId );
        return const_cast<OPropertyEditor*>(this)->getPage(rPageId);
    }


    void OPropertyEditor::Resize()
    {
        tools::Rectangle aPlayground(
            Point( LAYOUT_BORDER_LEFT, LAYOUT_BORDER_TOP ),
            Size(
                GetOutputSizePixel().Width() - LAYOUT_BORDER_LEFT - LAYOUT_BORDER_RIGHT,
                GetOutputSizePixel().Height() - LAYOUT_BORDER_TOP - LAYOUT_BORDER_BOTTOM
            )
        );

        tools::Rectangle aTabArea( aPlayground );
        m_aTabControl->SetPosSizePixel( aTabArea.TopLeft(), aTabArea.GetSize() );
    }


    sal_uInt16 OPropertyEditor::AppendPage( const OUString & _rText, const OString& _rHelpId )
    sal_uInt16 OPropertyEditor::AppendPage(const OUString& rText, const OString& rHelpId)
    {
        // obtain a new id
        sal_uInt16 nId = m_nNextId++;
        // insert the id
        m_aTabControl->InsertPage(nId, _rText);
        OString sIdent = OString::number(nId);
        m_xTabControl->append_page(sIdent, rText);

        // create a new page
        VclPtrInstance<OBrowserPage> pPage(m_aTabControl.get());
        pPage->SetText( _rText );
        auto xPage = std::make_unique<OBrowserPage>(m_xTabControl->get_page(sIdent), m_xControlHoldingParent.get(), m_bInterimBuilder);
        xPage->SetPageTitle(rText);
        // some knittings
        pPage->SetSizePixel(m_aTabControl->GetTabPageSizePixel());
        pPage->getListBox().SetListener(m_pListener);
        pPage->getListBox().SetObserver(m_pObserver);
        pPage->getListBox().EnableHelpSection( m_bHasHelpSection );
        pPage->getListBox().SetHelpLineLimites( m_nMinHelpLines, m_nMaxHelpLines );
        pPage->SetHelpId( _rHelpId );
        xPage->getListBox().SetListener(m_pListener);
        xPage->getListBox().SetObserver(m_pObserver);
        xPage->getListBox().EnableHelpSection(m_bHasHelpSection);
        xPage->getListBox().SetHelpLineLimites(m_nMinHelpLines, m_nMaxHelpLines);
        xPage->SetHelpId(rHelpId);

        m_aShownPages[nId] = PropertyPage(m_xTabControl->get_n_pages() - 1, rText, std::move(xPage));

        // immediately activate the page
        m_aTabControl->SetTabPage(nId, pPage);
        m_aTabControl->SetCurPageId(nId);
        m_xTabControl->set_current_page(sIdent);

        return nId;
    }


    void OPropertyEditor::SetHelpId( const OString& rHelpId )
    {
        Control::SetHelpId("");
        m_aTabControl->SetHelpId(rHelpId);
        m_xTabControl->set_help_id(rHelpId);
    }


    void OPropertyEditor::RemovePage(sal_uInt16 nID)
    {
        VclPtr<OBrowserPage> pPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(nID));
        auto aPagePos = m_aShownPages.find(nID);
        if (aPagePos == m_aShownPages.end())
            return;

        if (pPage)
            pPage->EnableInput(false);
        m_aTabControl->RemovePage(nID);
        pPage.disposeAndClear();
        m_aShownPages.erase(aPagePos);
        OString sIdent(OString::number(nID));
        m_xTabControl->remove_page(sIdent);
    }


    void OPropertyEditor::SetPage(sal_uInt16 nId)
    {
        m_aTabControl->SetCurPageId(nId);
        m_xTabControl->set_current_page(OString::number(nId));
    }


    sal_uInt16 OPropertyEditor::GetCurPage() const
    {
        if(m_aTabControl->GetPageCount()>0)
            return m_aTabControl->GetCurPageId();
        else
            return 0;
        return m_xTabControl->get_current_page_ident().toUInt32();
    }


    void OPropertyEditor::Update(const std::function<void(OBrowserListBox *)>& _aUpdateFunction)
    {
        // forward this to all our pages
        sal_uInt16 nCount = m_aTabControl->GetPageCount();
        for (sal_uInt16 i=0;i<nCount;++i)
        int nCount = m_xTabControl->get_n_pages();
        for (int i = 0; i < nCount; ++i)
        {
            sal_uInt16 nID = m_aTabControl->GetPageId(i);
            OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(nID));
            sal_uInt16 nID = m_xTabControl->get_page_ident(i).toUInt32();
            OBrowserPage* pPage = getPage(nID);
            if (pPage)
                _aUpdateFunction(&pPage->getListBox());
        }
    }

    void OPropertyEditor::EnableUpdate()
    {
        Update(std::mem_fn(&OBrowserListBox::EnableUpdate));
    }

    void OPropertyEditor::DisableUpdate()
    {
        Update(std::mem_fn(&OBrowserListBox::DisableUpdate));
    }


    void OPropertyEditor::forEachPage( PageOperation _pOperation )
    {
        sal_uInt16 nCount = m_aTabControl->GetPageCount();
        for ( sal_uInt16 i=0; i<nCount; ++i )
        int nCount = m_xTabControl->get_n_pages();
        for (int i = 0; i < nCount; ++i)
        {
            sal_uInt16 nID = m_aTabControl->GetPageId(i);
            OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( nID ) );
            if ( !pPage )
            sal_uInt16 nID = m_xTabControl->get_page_ident(i).toUInt32();
            OBrowserPage* pPage = getPage(nID);
            if (!pPage)
                continue;
            (this->*_pOperation)( *pPage, nullptr );
        }
    }


    void OPropertyEditor::setPageLineListener( OBrowserPage& _rPage, const void* )
    void OPropertyEditor::setPageLineListener( OBrowserPage& rPage, const void* )
    {
        _rPage.getListBox().SetListener( m_pListener );
        rPage.getListBox().SetListener( m_pListener );
    }


    void OPropertyEditor::SetLineListener(IPropertyLineListener* _pListener)
    void OPropertyEditor::SetLineListener(IPropertyLineListener* pListener)
    {
        m_pListener = _pListener;
        m_pListener = pListener;
        forEachPage( &OPropertyEditor::setPageLineListener );
    }


    void OPropertyEditor::setPageControlObserver( OBrowserPage& _rPage, const void* )
    void OPropertyEditor::setPageControlObserver( OBrowserPage& rPage, const void* )
    {
        _rPage.getListBox().SetObserver( m_pObserver );
        rPage.getListBox().SetObserver( m_pObserver );
    }


    void OPropertyEditor::SetControlObserver( IPropertyControlObserver* _pObserver )
    {
        m_pObserver = _pObserver;
        forEachPage( &OPropertyEditor::setPageControlObserver );
    }


    void OPropertyEditor::EnableHelpSection( bool _bEnable )
    void OPropertyEditor::EnableHelpSection( bool bEnable )
    {
        m_bHasHelpSection = _bEnable;
        m_bHasHelpSection = bEnable;
        forEachPage( &OPropertyEditor::enableHelpSection );
    }


    void OPropertyEditor::SetHelpText( const OUString& _rHelpText )
    void OPropertyEditor::SetHelpText( const OUString& rHelpText )
    {
        sal_uInt16 nCount = m_aTabControl->GetPageCount();
        for ( sal_uInt16 i=0; i<nCount; ++i )
        int nCount = m_xTabControl->get_n_pages();
        for (int i = 0; i < nCount; ++i)
        {
            sal_uInt16 nID = m_aTabControl->GetPageId(i);
            OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( nID ) );
            if ( !pPage )
            sal_uInt16 nID = m_xTabControl->get_page_ident(i).toUInt32();
            OBrowserPage* pPage = getPage(nID);
            if (!pPage)
                continue;
            setHelpSectionText( *pPage, &_rHelpText );
            setHelpSectionText( *pPage, &rHelpText );
        }
    }


    void OPropertyEditor::SetHelpLineLimites( sal_Int32 _nMinLines, sal_Int32 _nMaxLines )
    void OPropertyEditor::SetHelpLineLimites( sal_Int32 nMinLines, sal_Int32 nMaxLines )
    {
        m_nMinHelpLines = _nMinLines;
        m_nMaxHelpLines = _nMaxLines;
        m_nMinHelpLines = nMinLines;
        m_nMaxHelpLines = nMaxLines;
        forEachPage( &OPropertyEditor::setHelpLineLimits );
    }


    void OPropertyEditor::enableHelpSection( OBrowserPage& _rPage, const void* )
    void OPropertyEditor::enableHelpSection( OBrowserPage& rPage, const void* )
    {
        _rPage.getListBox().EnableHelpSection( m_bHasHelpSection );
        rPage.getListBox().EnableHelpSection( m_bHasHelpSection );
    }


    void OPropertyEditor::setHelpSectionText( OBrowserPage& _rPage, const void* _pPointerToOUString )
    void OPropertyEditor::setHelpSectionText( OBrowserPage& rPage, const void* pPointerToOUString )
    {
        OSL_ENSURE( _pPointerToOUString, "OPropertyEditor::setHelpSectionText: invalid argument!" );
        if ( !_pPointerToOUString )
        OSL_ENSURE( pPointerToOUString, "OPropertyEditor::setHelpSectionText: invalid argument!" );
        if ( !pPointerToOUString )
            return;

        const OUString& rText( *static_cast<const OUString*>(_pPointerToOUString) );
        _rPage.getListBox().SetHelpText( rText );
        const OUString& rText( *static_cast<const OUString*>(pPointerToOUString) );
        rPage.getListBox().SetHelpText( rText );
    }


    void OPropertyEditor::setHelpLineLimits( OBrowserPage& _rPage, const void* )
    void OPropertyEditor::setHelpLineLimits( OBrowserPage& rPage, const void* )
    {
        _rPage.getListBox().SetHelpLineLimites( m_nMinHelpLines, m_nMaxHelpLines );
        rPage.getListBox().SetHelpLineLimites( m_nMinHelpLines, m_nMaxHelpLines );
    }


    void OPropertyEditor::InsertEntry( const OLineDescriptor& rData, sal_uInt16 _nPageId, sal_uInt16 nPos )
    void OPropertyEditor::InsertEntry( const OLineDescriptor& rData, sal_uInt16 nPageId, sal_uInt16 nPos )
    {
        // let the current page handle this
        OBrowserPage* pPage = getPage( _nPageId );
        OBrowserPage* pPage = getPage(nPageId);
        DBG_ASSERT( pPage, "OPropertyEditor::InsertEntry: don't have such a page!" );
        if ( !pPage )
            return;
@@ -398,24 +276,22 @@ namespace pcr

        OSL_ENSURE( m_aPropertyPageIds.find( rData.sName ) == m_aPropertyPageIds.end(),
            "OPropertyEditor::InsertEntry: property already present in the map!" );
        m_aPropertyPageIds.emplace( rData.sName, _nPageId );
        m_aPropertyPageIds.emplace( rData.sName, nPageId );
    }


    void OPropertyEditor::RemoveEntry( const OUString& _rName )
    void OPropertyEditor::RemoveEntry( const OUString& rName )
    {
        OBrowserPage* pPage = getPage( _rName );
        OBrowserPage* pPage = getPage( rName );
        if ( pPage )
        {
            OSL_VERIFY( pPage->getListBox().RemoveEntry( _rName ) );
            OSL_VERIFY( pPage->getListBox().RemoveEntry( rName ) );

            OSL_ENSURE( m_aPropertyPageIds.find( _rName ) != m_aPropertyPageIds.end(),
            OSL_ENSURE( m_aPropertyPageIds.find( rName ) != m_aPropertyPageIds.end(),
                "OPropertyEditor::RemoveEntry: property not present in the map!" );
            m_aPropertyPageIds.erase( _rName );
            m_aPropertyPageIds.erase( rName );
        }
    }


    void OPropertyEditor::ChangeEntry( const OLineDescriptor& rData )
    {
        OBrowserPage* pPage = getPage( rData.sName );
@@ -423,7 +299,6 @@ namespace pcr
            pPage->getListBox().ChangeEntry( rData, EDITOR_LIST_REPLACE_EXISTING );
    }


    void OPropertyEditor::SetPropertyValue( const OUString& rEntryName, const Any& _rValue, bool _bUnknownValue )
    {
        OBrowserPage* pPage = getPage( rEntryName );
@@ -431,7 +306,6 @@ namespace pcr
            pPage->getListBox().SetPropertyValue( rEntryName, _rValue, _bUnknownValue );
    }


    sal_uInt16 OPropertyEditor::GetPropertyPos( const OUString& rEntryName ) const
    {
        sal_uInt16 nVal=EDITOR_LIST_ENTRY_NOTFOUND;
@@ -441,90 +315,100 @@ namespace pcr
        return nVal;
    }


    void OPropertyEditor::ShowPropertyPage( sal_uInt16 _nPageId, bool _bShow )
    void OPropertyEditor::ShowPropertyPage(sal_uInt16 nPageId, bool bShow)
    {
        if ( !_bShow )
        OString sIdent(OString::number(nPageId));
        if (!bShow)
        {
            sal_uInt16 nPagePos = m_aTabControl->GetPagePos( _nPageId );
            if ( TAB_PAGE_NOTFOUND == nPagePos )
                return;
            DBG_ASSERT( m_aHiddenPages.find( _nPageId ) == m_aHiddenPages.end(), "OPropertyEditor::ShowPropertyPage: page already hidden!" );
            assert(m_aHiddenPages.find(nPageId) == m_aHiddenPages.end() && "OPropertyEditor::ShowPropertyPage: page already hidden!");
            assert(m_aShownPages.find(nPageId) != m_aShownPages.end() && "OPropertyEditor::ShowPropertyPage: page not shown to hide!");

            m_aHiddenPages[ _nPageId ] = HiddenPage( nPagePos, m_aTabControl->GetTabPage( _nPageId ) );
            m_aTabControl->RemovePage( _nPageId );
            auto aPagePos = m_aShownPages.find(nPageId);
            if (aPagePos != m_aShownPages.end())
            {
                aPagePos->second.xPage->detach();
                m_xTabControl->remove_page(sIdent);

                m_aHiddenPages[nPageId] = std::move(aPagePos->second);
                m_aShownPages.erase(aPagePos);
            }
        }
        else
        {
            std::map< sal_uInt16, HiddenPage >::iterator aPagePos = m_aHiddenPages.find( _nPageId );
            if ( aPagePos == m_aHiddenPages.end() )
                return;
            assert(m_aShownPages.find(nPageId) == m_aShownPages.end() && "OPropertyEditor::ShowPropertyPage: page already shown!");
            assert(m_aHiddenPages.find(nPageId) != m_aHiddenPages.end() && "OPropertyEditor::ShowPropertyPage: page not hidden to show!");

            aPagePos->second.pPage->SetSizePixel( m_aTabControl->GetTabPageSizePixel() );
            m_aTabControl->InsertPage( aPagePos->first, aPagePos->second.pPage->GetText(), aPagePos->second.nPos );
            m_aTabControl->SetTabPage( aPagePos->first, aPagePos->second.pPage );
            auto aPagePos = m_aHiddenPages.find(nPageId);
            if (aPagePos != m_aHiddenPages.end())
            {
                m_xTabControl->insert_page(sIdent, aPagePos->second.sLabel, aPagePos->second.nPos);
                aPagePos->second.xPage->reattach(m_xTabControl->get_page(sIdent));

            m_aHiddenPages.erase( aPagePos );
                m_aShownPages[nPageId] = std::move(aPagePos->second);
                m_aHiddenPages.erase(aPagePos);
            }
        }
    }


    void OPropertyEditor::EnablePropertyControls( const OUString& _rEntryName, sal_Int16 _nControls, bool _bEnable )
    void OPropertyEditor::EnablePropertyControls( const OUString& rEntryName, sal_Int16 nControls, bool bEnable )
    {
        for ( sal_uInt16 i = 0; i < m_aTabControl->GetPageCount(); ++i )
        for (auto& rPage : m_aShownPages)
        {
            OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( m_aTabControl->GetPageId( i ) ) );
            if ( pPage )
                pPage->getListBox().EnablePropertyControls( _rEntryName, _nControls, _bEnable );
            OBrowserPage* pPage = rPage.second.xPage.get();
            if (pPage)
                pPage->getListBox().EnablePropertyControls( rEntryName, nControls, bEnable );
        }
    }


    void OPropertyEditor::EnablePropertyLine( const OUString& _rEntryName, bool _bEnable )
    void OPropertyEditor::EnablePropertyLine( const OUString& rEntryName, bool bEnable )
    {
        for ( sal_uInt16 i = 0; i < m_aTabControl->GetPageCount(); ++i )
        for (auto& rPage : m_aShownPages)
        {
            OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( m_aTabControl->GetPageId( i ) ) );
            if ( pPage )
                pPage->getListBox().EnablePropertyLine( _rEntryName, _bEnable );
            OBrowserPage* pPage = rPage.second.xPage.get();
            if (pPage)
                pPage->getListBox().EnablePropertyLine( rEntryName, bEnable );
        }
    }


    Reference< XPropertyControl > OPropertyEditor::GetPropertyControl(const OUString& rEntryName)
    {
        Reference< XPropertyControl > xControl;
        // let the current page handle this
        OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(m_aTabControl->GetCurPageId()));
        OBrowserPage* pPage = getPage(m_xTabControl->get_current_page_ident().toUInt32());
        if (pPage)
            xControl = pPage->getListBox().GetPropertyControl(rEntryName);
        return xControl;
    }


    IMPL_LINK_NOARG(OPropertyEditor, OnPageActivate, TabControl*, void)
    IMPL_LINK_NOARG(OPropertyEditor, OnPageActivate, const OString&, void)
    {
        m_aPageActivationHandler.Call(nullptr);
    }


    IMPL_LINK_NOARG(OPropertyEditor, OnPageDeactivate, TabControl *, bool)
    IMPL_LINK(OPropertyEditor, OnPageDeactivate, const OString&, rIdent, bool)
    {
        // commit the data on the current (to-be-deactivated) tab page
        // (79404)
        sal_Int32 nCurrentId = m_aTabControl->GetCurPageId();
        OBrowserPage* pCurrentPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(static_cast<sal_uInt16>(nCurrentId)));
        if ( !pCurrentPage )
        OBrowserPage* pCurrentPage = getPage(rIdent.toUInt32());
        if (!pCurrentPage)
            return true;

        if ( pCurrentPage->getListBox().IsModified() )
        if (pCurrentPage->getListBox().IsModified())
            pCurrentPage->getListBox().CommitModified();

        return true;
    }

    OPropertyEditor::PropertyPage::PropertyPage()
        : nPos(0)
    {
    }

    OPropertyEditor::PropertyPage::PropertyPage(sal_uInt16 nPagePos, const OUString& rLabel, std::unique_ptr<OBrowserPage> pPage)
        : nPos(nPagePos), sLabel(rLabel), xPage(std::move(pPage))
    {
    }

} // namespace pcr


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/propertyeditor.hxx b/extensions/source/propctrlr/propertyeditor.hxx
index 39b416f..3d9265c 100644
--- a/extensions/source/propctrlr/propertyeditor.hxx
+++ b/extensions/source/propctrlr/propertyeditor.hxx
@@ -23,57 +23,53 @@
#include "pcrcommon.hxx"

#include <com/sun/star/inspection/XPropertyControl.hpp>
#include <vcl/tabctrl.hxx>
#include <vcl/tabpage.hxx>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <vcl/weld.hxx>
#include <map>

namespace pcr
{

    class IPropertyLineListener;
    class IPropertyControlObserver;
    class OBrowserPage;
    struct OLineDescriptor;
    class OBrowserListBox;


    //= OPropertyEditor

    class OPropertyEditor final : public Control
    class OPropertyEditor final
    {
    private:
        typedef std::map< OUString, sal_uInt16 >   MapStringToPageId;
        struct HiddenPage
        struct PropertyPage
        {
            sal_uInt16  nPos;
            VclPtr<TabPage>    pPage;
            HiddenPage() : nPos( 0 ), pPage( nullptr ) { }
            HiddenPage( sal_uInt16 _nPos, TabPage* _pPage ) : nPos( _nPos ), pPage( _pPage ) { }
            sal_uInt16 nPos;
            OUString sLabel;
            std::unique_ptr<OBrowserPage> xPage;
            PropertyPage();
            PropertyPage(sal_uInt16 nPagePos, const OUString& rLabel, std::unique_ptr<OBrowserPage> pPage);
        };

        VclPtr<TabControl>          m_aTabControl;
        std::unique_ptr<weld::Container> m_xContainer;
        std::unique_ptr<weld::Notebook> m_xTabControl;
        // controls initially have this parent before they are moved
        std::unique_ptr<weld::Container> m_xControlHoldingParent;
        css::uno::Reference<css::uno::XComponentContext> m_xContext;
        IPropertyLineListener*      m_pListener;
        IPropertyControlObserver*   m_pObserver;
        sal_uInt16                  m_nNextId;
        Link<LinkParamNone*,void>   m_aPageActivationHandler;
        bool                        m_bHasHelpSection;
        bool                        m_bInterimBuilder;
        sal_Int32                   m_nMinHelpLines;
        sal_Int32                   m_nMaxHelpLines;

        MapStringToPageId                       m_aPropertyPageIds;
        std::map< sal_uInt16, HiddenPage >    m_aHiddenPages;

        void                        Resize() override;
        void                        GetFocus() override;
        MapStringToPageId           m_aPropertyPageIds;
        std::map<sal_uInt16, PropertyPage> m_aShownPages;
        std::map<sal_uInt16, PropertyPage> m_aHiddenPages;

    public:
        explicit                    OPropertyEditor (vcl::Window* pParent);

                                    virtual ~OPropertyEditor() override;
        virtual void                dispose() override;

        void                        EnableUpdate();
        void                        DisableUpdate();
        explicit OPropertyEditor(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder, bool bInterimBuilder);
        ~OPropertyEditor();

        void                        SetLineListener( IPropertyLineListener* );
        void                        SetControlObserver( IPropertyControlObserver* );
@@ -105,15 +101,18 @@ namespace pcr

        void                        setPageActivationHandler(const Link<LinkParamNone*,void>& _rHdl) { m_aPageActivationHandler = _rHdl; }

        sal_Int32                   getMinimumWidth() const;
        sal_Int32                   getMinimumHeight() const;
        Size                        get_preferred_size() const;

        weld::Container*            getWidget() const { return m_xTabControl.get(); }
        weld::Container*            getControlHoldingParent() const { return m_xControlHoldingParent.get(); }

        void                        Show() { m_xTabControl->show(); }
        void                        Hide() { m_xTabControl->hide(); }
        void                        GrabFocus() { m_xTabControl->grab_focus(); }

        void                        CommitModified();

    private:
        using Window::SetHelpText;
        using Window::Update;

        OBrowserPage* getPage( sal_uInt16 _rPageId );
        const OBrowserPage* getPage( sal_uInt16 _rPageId ) const;

@@ -131,8 +130,8 @@ namespace pcr
        static void setHelpSectionText( OBrowserPage& _rPage, const void* _pPointerToOUString );
        void    setHelpLineLimits( OBrowserPage& _rPage, const void* );

        DECL_LINK(OnPageDeactivate, TabControl*, bool);
        DECL_LINK(OnPageActivate, TabControl*, void);
        DECL_LINK(OnPageDeactivate, const OString&, bool);
        DECL_LINK(OnPageActivate, const OString&, void);
    };


diff --git a/extensions/source/propctrlr/propertyhandler.cxx b/extensions/source/propctrlr/propertyhandler.cxx
index c9d0217..b4f846f 100644
--- a/extensions/source/propctrlr/propertyhandler.cxx
+++ b/extensions/source/propctrlr/propertyhandler.cxx
@@ -305,11 +305,6 @@ namespace pcr
        ) );
    }

    vcl::Window* PropertyHandler::impl_getDefaultDialogParent_nothrow() const
    {
        return PropertyHandlerHelper::getDialogParentWindow( m_xContext );
    }

    weld::Window* PropertyHandler::impl_getDefaultDialogFrame_nothrow() const
    {
        return PropertyHandlerHelper::getDialogParentFrame(m_xContext);
diff --git a/extensions/source/propctrlr/propertyhandler.hxx b/extensions/source/propctrlr/propertyhandler.hxx
index da77b68..2f4cb76 100644
--- a/extensions/source/propctrlr/propertyhandler.hxx
+++ b/extensions/source/propctrlr/propertyhandler.hxx
@@ -137,7 +137,6 @@ namespace pcr

        /** retrieves a window which can be used as parent for dialogs
        */
        vcl::Window* impl_getDefaultDialogParent_nothrow() const;
        weld::Window* impl_getDefaultDialogFrame_nothrow() const;

        /** retrieves the property id for a given property name
diff --git a/extensions/source/propctrlr/standardcontrol.cxx b/extensions/source/propctrlr/standardcontrol.cxx
index 9f0f2c2..6d2cba9 100644
--- a/extensions/source/propctrlr/standardcontrol.cxx
+++ b/extensions/source/propctrlr/standardcontrol.cxx
@@ -55,11 +55,8 @@
#include <limits>
#include <memory>


namespace pcr
{


    using namespace ::com::sun::star;
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::awt;
@@ -68,117 +65,89 @@ namespace pcr
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::inspection;


    //= OTimeControl


    OTimeControl::OTimeControl( vcl::Window* pParent, WinBits nWinStyle )
        :OTimeControl_Base( PropertyControlType::TimeField, pParent, nWinStyle )
    OTimeControl::OTimeControl(std::unique_ptr<weld::TimeSpinButton> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : OTimeControl_Base(PropertyControlType::TimeField, std::move(xBuilder), std::move(xWidget), bReadOnly)
    {
        getTypedControlWindow()->SetStrictFormat( true );
        getTypedControlWindow()->SetFormat( TimeFieldFormat::F_SEC );
        getTypedControlWindow()->EnableEmptyFieldValue( true );
    }


    void SAL_CALL OTimeControl::setValue( const Any& _rValue )
    {
        util::Time aUNOTime;
        if ( !( _rValue >>= aUNOTime ) )
        {
            getTypedControlWindow()->SetText( "" );
            getTypedControlWindow()->SetEmptyTime();
            getTypedControlWindow()->set_text("");
            getTypedControlWindow()->set_value(tools::Time(tools::Time::EMPTY));
        }
        else
        {
            getTypedControlWindow()->SetTime( ::tools::Time(aUNOTime) );
            getTypedControlWindow()->set_value(::tools::Time(aUNOTime));
        }
    }


    Any SAL_CALL OTimeControl::getValue()
    {
        Any aPropValue;
        if ( !getTypedControlWindow()->GetText().isEmpty() )
        if ( !getTypedControlWindow()->get_text().isEmpty() )
        {
            aPropValue <<= getTypedControlWindow()->GetTime().GetUNOTime();
            aPropValue <<= getTypedControlWindow()->get_value().GetUNOTime();
        }
        return aPropValue;
    }


    Type SAL_CALL OTimeControl::getValueType()
    {
        return ::cppu::UnoType<util::Time>::get();
    }


    //= ODateControl


    ODateControl::ODateControl( vcl::Window* pParent, WinBits nWinStyle )
        :ODateControl_Base( PropertyControlType::DateField, pParent, nWinStyle | WB_DROPDOWN )
    ODateControl::ODateControl(std::unique_ptr<SvtCalendarBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : ODateControl_Base(PropertyControlType::DateField, std::move(xBuilder), std::move(xWidget), bReadOnly)
    {
        CalendarField* pControlWindow = getTypedControlWindow();
        pControlWindow->SetStrictFormat(true);

        pControlWindow->SetMin( ::Date( 1,1,1600 ) );
        pControlWindow->SetFirst( ::Date( 1,1,1600 ) );
        pControlWindow->SetLast( ::Date( 1, 1, 9999 ) );
        pControlWindow->SetMax( ::Date( 1, 1, 9999 ) );

        pControlWindow->SetExtDateFormat( ExtDateFieldFormat::SystemShortYYYY );
        pControlWindow->EnableEmptyFieldValue( true );
    }


    void SAL_CALL ODateControl::setValue( const Any& _rValue )
    {
        util::Date aUNODate;
        if ( !( _rValue >>= aUNODate ) )
        {
            getTypedControlWindow()->SetText( "" );
            getTypedControlWindow()->SetEmptyDate();
            getTypedControlWindow()->set_date(::Date(::Date::SYSTEM));
        }
        else
        {
            ::Date aDate( aUNODate.Day, aUNODate.Month, aUNODate.Year );
            getTypedControlWindow()->SetDate( aDate );
            getTypedControlWindow()->set_date(aDate);
        }
    }


    Any SAL_CALL ODateControl::getValue()
    {
        Any aPropValue;
        if ( !getTypedControlWindow()->GetText().isEmpty() )
        {
            ::Date aDate( getTypedControlWindow()->GetDate() );
        ::Date aDate(getTypedControlWindow()->get_date());
        if (!aDate.IsEmpty())
            aPropValue <<= aDate.GetUNODate();
        }
        return aPropValue;
    }


    Type SAL_CALL ODateControl::getValueType()
    {
        return ::cppu::UnoType<util::Date>::get();
    }


    //= OEditControl


    OEditControl::OEditControl(vcl::Window* _pParent, bool _bPW, WinBits _nWinStyle)
        :OEditControl_Base( _bPW ? PropertyControlType::CharacterField : PropertyControlType::TextField, _pParent, _nWinStyle )
    OEditControl::OEditControl(std::unique_ptr<weld::Entry> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bPW, bool bReadOnly)
        : OEditControl_Base( bPW ? PropertyControlType::CharacterField : PropertyControlType::TextField, std::move(xBuilder), std::move(xWidget), bReadOnly )
    {
        m_bIsPassword = _bPW;
        m_bIsPassword = bPW;

        if ( m_bIsPassword )
           getTypedControlWindow()->SetMaxTextLen( 1 );
        auto pWidget = getTypedControlWindow();
        pWidget->set_sensitive(true);
        pWidget->set_editable(!bReadOnly);

        if (m_bIsPassword)
           pWidget->set_max_length( 1 );
    }


    void SAL_CALL OEditControl::setValue( const Any& _rValue )
    {
        OUString sText;
@@ -194,15 +163,14 @@ namespace pcr
        else
            _rValue >>= sText;

        getTypedControlWindow()->SetText( sText );
        getTypedControlWindow()->set_text( sText );
    }


    Any SAL_CALL OEditControl::getValue()
    {
        Any aPropValue;

        OUString sText( getTypedControlWindow()->GetText() );
        OUString sText( getTypedControlWindow()->get_text() );
        if ( m_bIsPassword )
        {
            if ( !sText.isEmpty() )
@@ -214,13 +182,11 @@ namespace pcr
        return aPropValue;
    }


    Type SAL_CALL OEditControl::getValueType()
    {
        return m_bIsPassword ? ::cppu::UnoType<sal_Int16>::get() : ::cppu::UnoType<OUString>::get();
    }


    void OEditControl::setModified()
    {
        OEditControl_Base::setModified();
@@ -230,20 +196,18 @@ namespace pcr
            notifyModifiedValue();
    }


    static long ImplCalcLongValue( double nValue, sal_uInt16 nDigits )
    static int ImplCalcLongValue( double nValue, sal_uInt16 nDigits )
    {
        double n = nValue;
        for ( sal_uInt16 d = 0; d < nDigits; ++d )
            n *= 10;

        if ( !o3tl::convertsToAtMost(n, std::numeric_limits< long >::max()) )
            return std::numeric_limits< long >::max();
        return static_cast<long>(n);
        if ( !o3tl::convertsToAtMost(n, std::numeric_limits<int>::max()) )
            return std::numeric_limits<int>::max();
        return static_cast<int>(n);
    }


    static double ImplCalcDoubleValue( long nValue, sal_uInt16 nDigits )
    static double ImplCalcDoubleValue( int nValue, sal_uInt16 nDigits )
    {
        double n = nValue;
        for ( sal_uInt16 d = 0; d < nDigits; ++d )
@@ -251,30 +215,20 @@ namespace pcr
        return n;
    }




    ODateTimeControl::ODateTimeControl( vcl::Window* _pParent, WinBits _nWinStyle)
        :ODateTimeControl_Base( PropertyControlType::DateTimeField, _pParent, _nWinStyle )
    ODateTimeControl::ODateTimeControl(std::unique_ptr<weld::Container> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : ODateTimeControl_Base(PropertyControlType::DateTimeField, std::move(xBuilder), std::move(xWidget), bReadOnly)
        , m_xDate(std::make_unique<SvtCalendarBox>(m_xBuilder->weld_menu_button("datefield")))
        , m_xTime(m_xBuilder->weld_time_spin_button("timefield", TimeFieldFormat::F_SEC))
    {
        getTypedControlWindow()->EnableEmptyField( true );

        // determine a default format
        LanguageType eSysLanguage = SvtSysLocale().GetLanguageTag().getLanguageType( false);

        getTypedControlWindow()->SetFormatter( getTypedControlWindow()->StandardFormatter() );
        SvNumberFormatter* pFormatter = getTypedControlWindow()->GetFormatter();
        sal_uLong nStandardDateTimeFormat = pFormatter->GetStandardFormat( SvNumFormatType::DATETIME, eSysLanguage );

        getTypedControlWindow()->SetFormatKey( nStandardDateTimeFormat );
    }


    void SAL_CALL ODateTimeControl::setValue( const Any& _rValue )
    {
        if ( !_rValue.hasValue() )
        {
            getTypedControlWindow()->SetText( "" );
            m_xDate->set_date(::Date(::Date::SYSTEM));
            m_xTime->set_text("");
            m_xTime->set_value(tools::Time(tools::Time::EMPTY));
        }
        else
        {
@@ -284,30 +238,17 @@ namespace pcr
            ::DateTime aDateTime( ::DateTime::EMPTY );
            ::utl::typeConvert( aUNODateTime, aDateTime );

            double nValue = aDateTime - ::DateTime( getTypedControlWindow()->GetFormatter()->GetNullDate() );
            getTypedControlWindow()->SetValue( nValue );
            m_xDate->set_date(aDateTime);
            m_xTime->set_value(aDateTime);
        }
    }


    Any SAL_CALL ODateTimeControl::getValue()
    {
        Any aPropValue;
        if ( !getTypedControlWindow()->GetText().isEmpty() )
        if (!m_xTime->get_text().isEmpty())
        {
            double nValue = getTypedControlWindow()->GetValue();

            ::DateTime aDateTime( getTypedControlWindow()->GetFormatter()->GetNullDate() );

            // add the "days" part
            double nDays = floor( nValue );
            aDateTime.AddDays( nDays );

            // add the "time" part
            double nTime = nValue - nDays;
            nTime = ::rtl::math::round( nTime * 86400.0 ) / 86400.0;
                // we're not interested in 100th seconds, and this here prevents rounding errors
            aDateTime.AddTime( nTime );
            ::DateTime aDateTime(m_xDate->get_date(), m_xTime->get_value());

            util::DateTime aUNODateTime;
            ::utl::typeConvert( aDateTime, aUNODateTime );
@@ -317,156 +258,65 @@ namespace pcr
        return aPropValue;
    }


    Type SAL_CALL ODateTimeControl::getValueType()
    {
        return ::cppu::UnoType<util::DateTime>::get();
    }


    //= HyperlinkInput


    HyperlinkInput::HyperlinkInput( vcl::Window* _pParent, WinBits _nWinStyle )
        :Edit( _pParent, _nWinStyle )
    {
        ::svtools::ColorConfig aColorConfig;
        ::svtools::ColorConfigValue aLinkColor( aColorConfig.GetColorValue( ::svtools::LINKS ) );

        AllSettings aAllSettings( GetSettings() );
        StyleSettings aStyleSettings( aAllSettings.GetStyleSettings() );

        vcl::Font aFieldFont( aStyleSettings.GetFieldFont() );
        aFieldFont.SetUnderline( LINESTYLE_SINGLE );
        aFieldFont.SetColor( aLinkColor.nColor );
        aStyleSettings.SetFieldFont( aFieldFont );

        aStyleSettings.SetFieldTextColor( aLinkColor.nColor );

        aAllSettings.SetStyleSettings( aStyleSettings );
        SetSettings( aAllSettings );
    }


    void HyperlinkInput::MouseMove( const ::MouseEvent& rMEvt )
    {
        Edit::MouseMove( rMEvt );

        PointerStyle ePointerStyle( PointerStyle::Text );

        if ( !rMEvt.IsLeaveWindow() )
        {
            if ( impl_textHitTest( rMEvt.GetPosPixel() ) )
                ePointerStyle = PointerStyle::RefHand;
        }

        SetPointer( ePointerStyle );
    }


    void HyperlinkInput::MouseButtonDown( const ::MouseEvent& rMEvt )
    {
        Edit::MouseButtonDown( rMEvt );

        if ( impl_textHitTest( rMEvt.GetPosPixel() ) )
            m_aMouseButtonDownPos = rMEvt.GetPosPixel();
        else
        {
            m_aMouseButtonDownPos.setX(-1);
            m_aMouseButtonDownPos.setY(-1);
        }
    }


    void HyperlinkInput::MouseButtonUp( const ::MouseEvent& rMEvt )
    {
        Edit::MouseButtonUp( rMEvt );

        impl_checkEndClick( rMEvt );
    }


    bool HyperlinkInput::impl_textHitTest( const ::Point& _rWindowPos )
    {
        sal_Int32 nPos = GetCharPos( _rWindowPos );
        return ( ( nPos != EDIT_NOLIMIT ) && ( nPos < GetText().getLength() ) );
    }


    void HyperlinkInput::impl_checkEndClick( const ::MouseEvent& rMEvt )
    {
        const MouseSettings& rMouseSettings( GetSettings().GetMouseSettings() );
        if  (   ( std::abs( rMEvt.GetPosPixel().X() - m_aMouseButtonDownPos.X() ) < rMouseSettings.GetStartDragWidth() )
            &&  ( std::abs( rMEvt.GetPosPixel().Y() - m_aMouseButtonDownPos.Y() ) < rMouseSettings.GetStartDragHeight() )
            )
            Application::PostUserEvent( m_aClickHandler );
    }


    void HyperlinkInput::Tracking( const TrackingEvent& rTEvt )
    {
        Edit::Tracking( rTEvt );

        if ( rTEvt.IsTrackingEnded() )
            impl_checkEndClick( rTEvt.GetMouseEvent() );
    }


    //= OHyperlinkControl


    OHyperlinkControl::OHyperlinkControl( vcl::Window* _pParent, WinBits _nWinStyle )
        :OHyperlinkControl_Base( PropertyControlType::HyperlinkField, _pParent, _nWinStyle )
        ,m_aActionListeners( m_aMutex )
    OHyperlinkControl::OHyperlinkControl(std::unique_ptr<weld::Container> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : OHyperlinkControl_Base(PropertyControlType::HyperlinkField, std::move(xBuilder), std::move(xWidget), bReadOnly)
        , m_xEntry(m_xBuilder->weld_entry("entry"))
        , m_xButton(m_xBuilder->weld_button("button"))
        , m_aActionListeners(m_aMutex)
    {
        getTypedControlWindow()->SetClickHdl( LINK( this, OHyperlinkControl, OnHyperlinkClicked ) );
    }
        auto pWidget = getTypedControlWindow();
        pWidget->set_sensitive(true);
        m_xEntry->set_editable(!bReadOnly);

        m_xButton->connect_clicked(LINK(this, OHyperlinkControl, OnHyperlinkClicked));
    }

    Any SAL_CALL OHyperlinkControl::getValue()
    {
        OUString sText = getTypedControlWindow()->GetText();
        OUString sText = m_xEntry->get_text();
        return makeAny( sText );
    }


    void SAL_CALL OHyperlinkControl::setValue( const Any& _value )
    {
        OUString sText;
        _value >>= sText;
        getTypedControlWindow()->SetText( sText );
        m_xEntry->set_text( sText );
    }


    Type SAL_CALL OHyperlinkControl::getValueType()
    {
        return ::cppu::UnoType<OUString>::get();
    }


    void SAL_CALL OHyperlinkControl::addActionListener( const Reference< XActionListener >& listener )
    {
        if ( listener.is() )
            m_aActionListeners.addInterface( listener );
    }


    void SAL_CALL OHyperlinkControl::removeActionListener( const Reference< XActionListener >& listener )
    {
        m_aActionListeners.removeInterface( listener );
    }


    void SAL_CALL OHyperlinkControl::disposing()
    {
        m_xButton.reset();
        m_xEntry.reset();
        OHyperlinkControl_Base::disposing();

        EventObject aEvent( *this );
        m_aActionListeners.disposeAndClear( aEvent );
    }


    IMPL_LINK_NOARG( OHyperlinkControl, OnHyperlinkClicked, void*, void )
    IMPL_LINK_NOARG( OHyperlinkControl, OnHyperlinkClicked, weld::Button&, void )
    {
        ActionEvent aEvent( *this, "clicked" );
        m_aActionListeners.forEach< XActionListener >(
@@ -474,41 +324,33 @@ namespace pcr
                { return xListener->actionPerformed(aEvent); });
    }


    //= ONumericControl


    ONumericControl::ONumericControl( vcl::Window* _pParent, WinBits _nWinStyle )
        :ONumericControl_Base( PropertyControlType::NumericField, _pParent, _nWinStyle )
        ,m_eValueUnit( FieldUnit::NONE )
        ,m_nFieldToUNOValueFactor( 1 )
    ONumericControl::ONumericControl(std::unique_ptr<weld::MetricSpinButton> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : ONumericControl_Base(PropertyControlType::NumericField, std::move(xBuilder), std::move(xWidget), bReadOnly)
        , m_eValueUnit( FieldUnit::NONE )
        , m_nFieldToUNOValueFactor( 1 )
    {
        getTypedControlWindow()->EnableEmptyFieldValue( true );
        getTypedControlWindow()->SetStrictFormat( true );
        Optional< double > value( getMaxValue() );
        value.Value = -value.Value;
        setMinValue( value );
    }


    ::sal_Int16 SAL_CALL ONumericControl::getDecimalDigits()
    {
        return getTypedControlWindow()->GetDecimalDigits();
        return getTypedControlWindow()->get_digits();
    }


    void SAL_CALL ONumericControl::setDecimalDigits( ::sal_Int16 _decimaldigits )
    {
        getTypedControlWindow()->SetDecimalDigits( _decimaldigits );
        getTypedControlWindow()->set_digits( _decimaldigits );
    }


    Optional< double > SAL_CALL ONumericControl::getMinValue()
    {
        Optional< double > aReturn( true, 0 );

        sal_Int64 minValue = getTypedControlWindow()->GetMin();
        if ( minValue == std::numeric_limits< sal_Int64 >::min() )
        int minValue = getTypedControlWindow()->get_min(FieldUnit::NONE);
        if ( minValue == std::numeric_limits<int>::min() )
            aReturn.IsPresent = false;
        else
            aReturn.Value = static_cast<double>(minValue);
@@ -516,22 +358,20 @@ namespace pcr
        return aReturn;
    }


    void SAL_CALL ONumericControl::setMinValue( const Optional< double >& _minvalue )
    {
        if ( !_minvalue.IsPresent )
            getTypedControlWindow()->SetMin( std::numeric_limits< sal_Int64 >::min() );
            getTypedControlWindow()->set_min( std::numeric_limits<int>::min(), FieldUnit::NONE );
        else
            getTypedControlWindow()->SetMin( impl_apiValueToFieldValue_nothrow( _minvalue.Value ) , m_eValueUnit);
            getTypedControlWindow()->set_min( impl_apiValueToFieldValue_nothrow( _minvalue.Value ) , m_eValueUnit);
    }


    Optional< double > SAL_CALL ONumericControl::getMaxValue()
    {
        Optional< double > aReturn( true, 0 );

        sal_Int64 maxValue = getTypedControlWindow()->GetMax();
        if ( maxValue == std::numeric_limits< sal_Int64 >::max() )
        int maxValue = getTypedControlWindow()->get_max(FieldUnit::NONE);
        if ( maxValue == std::numeric_limits<int>::max() )
            aReturn.IsPresent = false;
        else
            aReturn.Value = static_cast<double>(maxValue);
@@ -539,22 +379,19 @@ namespace pcr
        return aReturn;
    }


    void SAL_CALL ONumericControl::setMaxValue( const Optional< double >& _maxvalue )
    {
        if ( !_maxvalue.IsPresent )
            getTypedControlWindow()->SetMax( std::numeric_limits< sal_Int64 >::max() );
            getTypedControlWindow()->set_max( std::numeric_limits<int>::max(), FieldUnit::NONE );
        else
            getTypedControlWindow()->SetMax( impl_apiValueToFieldValue_nothrow( _maxvalue.Value ), m_eValueUnit );
            getTypedControlWindow()->set_max( impl_apiValueToFieldValue_nothrow( _maxvalue.Value ), m_eValueUnit );
    }


    ::sal_Int16 SAL_CALL ONumericControl::getDisplayUnit()
    {
        return VCLUnoHelper::ConvertToMeasurementUnit( getTypedControlWindow()->GetUnit(), 1 );
        return VCLUnoHelper::ConvertToMeasurementUnit( getTypedControlWindow()->get_unit(), 1 );
    }


    void SAL_CALL ONumericControl::setDisplayUnit( ::sal_Int16 _displayunit )
    {
        if ( ( _displayunit < MeasureUnit::MM_100TH ) || ( _displayunit > MeasureUnit::PERCENT ) )
@@ -574,16 +411,14 @@ namespace pcr
            // everything which survived the checks above should result in a factor of 1, i.e.,
            // it should have a direct counterpart as FieldUnit
            throw RuntimeException();
        getTypedControlWindow()->MetricFormatter::SetUnit( eFieldUnit );
        getTypedControlWindow()->set_unit(eFieldUnit);
    }


    ::sal_Int16 SAL_CALL ONumericControl::getValueUnit()
    {
        return VCLUnoHelper::ConvertToMeasurementUnit( m_eValueUnit, m_nFieldToUNOValueFactor );
    }


    void SAL_CALL ONumericControl::setValueUnit( ::sal_Int16 _valueunit )
    {
        if ( ( _valueunit < MeasureUnit::MM_100TH ) || ( _valueunit > MeasureUnit::PERCENT ) )
@@ -591,64 +426,54 @@ namespace pcr
        m_eValueUnit = VCLUnoHelper::ConvertToFieldUnit( _valueunit, m_nFieldToUNOValueFactor );
    }


    void SAL_CALL ONumericControl::setValue( const Any& _rValue )
    {
        if ( !_rValue.hasValue() )
        {
            getTypedControlWindow()->SetText( "" );
            getTypedControlWindow()->SetEmptyFieldValue();
            getTypedControlWindow()->set_text( "" );
        }
        else
        {
            double nValue( 0 );
            OSL_VERIFY( _rValue >>= nValue );
            long nControlValue = impl_apiValueToFieldValue_nothrow( nValue );
            getTypedControlWindow()->SetValue( nControlValue, m_eValueUnit );
            auto nControlValue = impl_apiValueToFieldValue_nothrow( nValue );
            getTypedControlWindow()->set_value( nControlValue, m_eValueUnit );
        }
    }


    long ONumericControl::impl_apiValueToFieldValue_nothrow( double _nApiValue ) const
    int ONumericControl::impl_apiValueToFieldValue_nothrow( double _nApiValue ) const
    {
        long nControlValue = ImplCalcLongValue( _nApiValue, getTypedControlWindow()->GetDecimalDigits() );
        int nControlValue = ImplCalcLongValue( _nApiValue, getTypedControlWindow()->get_digits() );
        nControlValue /= m_nFieldToUNOValueFactor;
        return nControlValue;
    }


    double ONumericControl::impl_fieldValueToApiValue_nothrow( sal_Int64 _nFieldValue ) const
    double ONumericControl::impl_fieldValueToApiValue_nothrow( int nFieldValue ) const
    {
        double nApiValue = ImplCalcDoubleValue( static_cast<long>(_nFieldValue), getTypedControlWindow()->GetDecimalDigits() );
        double nApiValue = ImplCalcDoubleValue( nFieldValue, getTypedControlWindow()->get_digits() );
        nApiValue *= m_nFieldToUNOValueFactor;
        return nApiValue;
    }


    Any SAL_CALL ONumericControl::getValue()
    {
        Any aPropValue;
        if ( !getTypedControlWindow()->GetText().isEmpty() )
        if ( !getTypedControlWindow()->get_text().isEmpty() )
        {
            double nValue = impl_fieldValueToApiValue_nothrow( getTypedControlWindow()->GetValue( m_eValueUnit ) );
            double nValue = impl_fieldValueToApiValue_nothrow( getTypedControlWindow()->get_value( m_eValueUnit ) );
            aPropValue <<= nValue;
        }
        return aPropValue;
    }


    Type SAL_CALL ONumericControl::getValueType()
    {
        return ::cppu::UnoType<double>::get();
    }


    //= OColorControl

    #define LB_DEFAULT_COUNT 20

    OColorControl::OColorControl(vcl::Window* pParent, WinBits nWinStyle)
        : OColorControl_Base(PropertyControlType::ColorListBox, pParent, nWinStyle)
    OColorControl::OColorControl(std::unique_ptr<ColorListBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : OColorControl_Base(PropertyControlType::ColorListBox, std::move(xBuilder), std::move(xWidget), bReadOnly)
    {
        getTypedControlWindow()->SetSlotId(SID_FM_CTL_PROPERTIES);
    }
@@ -685,22 +510,14 @@ namespace pcr
    }

    //= OListboxControl

    OListboxControl::OListboxControl( vcl::Window* pParent, WinBits nWinStyle)
        :OListboxControl_Base( PropertyControlType::ListBox, pParent, nWinStyle )
    OListboxControl::OListboxControl(std::unique_ptr<weld::ComboBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : OListboxControl_Base(PropertyControlType::ListBox, std::move(xBuilder), std::move(xWidget), bReadOnly)
    {
        getTypedControlWindow()->SetDropDownLineCount( LB_DEFAULT_COUNT );
        if ( ( nWinStyle & WB_READONLY ) != 0 )
        {
            getTypedControlWindow()->SetReadOnly();
            getTypedControlWindow()->Enable();
        }
    }


    Any SAL_CALL OListboxControl::getValue()
    {
        OUString sControlValue( getTypedControlWindow()->GetSelectedEntry() );
        OUString sControlValue( getTypedControlWindow()->get_active_text() );

        Any aPropValue;
        if ( !sControlValue.isEmpty() )
@@ -708,347 +525,118 @@ namespace pcr
        return aPropValue;
    }


    Type SAL_CALL OListboxControl::getValueType()
    {
        return ::cppu::UnoType<OUString>::get();
    }


    void SAL_CALL OListboxControl::setValue( const Any& _rValue )
    {
        if ( !_rValue.hasValue() )
            getTypedControlWindow()->SetNoSelection();
            getTypedControlWindow()->set_active(-1);
        else
        {
            OUString sSelection;
            _rValue >>= sSelection;

            if ( sSelection != getTypedControlWindow()->GetSelectedEntry() )
                getTypedControlWindow()->SelectEntry( sSelection );
            if (getTypedControlWindow()->find_text(sSelection) == -1)
                getTypedControlWindow()->insert_text(0, sSelection);

            if ( !getTypedControlWindow()->IsEntrySelected( sSelection ) )
            {
                getTypedControlWindow()->InsertEntry( sSelection, 0 );
                getTypedControlWindow()->SelectEntry( sSelection );
            }
            if (sSelection != getTypedControlWindow()->get_active_text())
                getTypedControlWindow()->set_active_text(sSelection);
        }
    }


    void SAL_CALL OListboxControl::clearList()
    {
        getTypedControlWindow()->Clear();
        getTypedControlWindow()->clear();
    }


    void SAL_CALL OListboxControl::prependListEntry( const OUString& NewEntry )
    {
        getTypedControlWindow()->InsertEntry( NewEntry, 0 );
        getTypedControlWindow()->insert_text(0, NewEntry);
    }


    void SAL_CALL OListboxControl::appendListEntry( const OUString& NewEntry )
    {
        getTypedControlWindow()->InsertEntry( NewEntry );
        getTypedControlWindow()->append_text(NewEntry);
    }

    Sequence< OUString > SAL_CALL OListboxControl::getListEntries(  )
    Sequence< OUString > SAL_CALL OListboxControl::getListEntries()
    {
        const sal_Int32 nCount = getTypedControlWindow()->GetEntryCount();
        const sal_Int32 nCount = getTypedControlWindow()->get_count();
        Sequence< OUString > aRet(nCount);
        OUString* pIter = aRet.getArray();
        for (sal_Int32 i = 0; i < nCount ; ++i,++pIter)
            *pIter = getTypedControlWindow()->GetEntry(i);
            *pIter = getTypedControlWindow()->get_text(i);

        return aRet;
    }


    void OListboxControl::setModified()
    {
        OListboxControl_Base::setModified();

        if ( !getTypedControlWindow()->IsTravelSelect() )
            // fire a commit
            notifyModifiedValue();
        // fire a commit
        notifyModifiedValue();
    }


    //= OComboboxControl


    OComboboxControl::OComboboxControl( vcl::Window* pParent, WinBits nWinStyle)
        :OComboboxControl_Base( PropertyControlType::ComboBox, pParent, nWinStyle )
    OComboboxControl::OComboboxControl(std::unique_ptr<weld::ComboBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : OComboboxControl_Base(PropertyControlType::ComboBox, std::move(xBuilder), std::move(xWidget), bReadOnly)
    {
        getTypedControlWindow()->SetDropDownLineCount( LB_DEFAULT_COUNT );
        getTypedControlWindow()->SetSelectHdl( LINK( this, OComboboxControl, OnEntrySelected ) );
        getTypedControlWindow()->connect_changed( LINK( this, OComboboxControl, OnEntrySelected ) );
    }


    void SAL_CALL OComboboxControl::setValue( const Any& _rValue )
    {
        OUString sText;
        _rValue >>= sText;
        getTypedControlWindow()->SetText( sText );
        getTypedControlWindow()->set_entry_text( sText );
    }


    Any SAL_CALL OComboboxControl::getValue()
    {
        return makeAny( getTypedControlWindow()->GetText() );
        return makeAny( getTypedControlWindow()->get_active_text() );
    }


    Type SAL_CALL OComboboxControl::getValueType()
    {
        return ::cppu::UnoType<OUString>::get();
    }


    void SAL_CALL OComboboxControl::clearList()
    {
        getTypedControlWindow()->Clear();
        getTypedControlWindow()->clear();
    }


    void SAL_CALL OComboboxControl::prependListEntry( const OUString& NewEntry )
    {
        getTypedControlWindow()->InsertEntry( NewEntry, 0 );
        getTypedControlWindow()->insert_text(0, NewEntry);
    }


    void SAL_CALL OComboboxControl::appendListEntry( const OUString& NewEntry )
    {
        getTypedControlWindow()->InsertEntry( NewEntry );
        getTypedControlWindow()->append_text( NewEntry );
    }

    Sequence< OUString > SAL_CALL OComboboxControl::getListEntries(  )
    {
        const sal_Int32 nCount = getTypedControlWindow()->GetEntryCount();
        const sal_Int32 nCount = getTypedControlWindow()->get_count();
        Sequence< OUString > aRet(nCount);
        OUString* pIter = aRet.getArray();
        for (sal_Int32 i = 0; i < nCount ; ++i,++pIter)
            *pIter = getTypedControlWindow()->GetEntry(i);
            *pIter = getTypedControlWindow()->get_text(i);

        return aRet;
    }


    IMPL_LINK_NOARG( OComboboxControl, OnEntrySelected, ComboBox&, void )
    IMPL_LINK_NOARG( OComboboxControl, OnEntrySelected, weld::ComboBox&, void )
    {
        if ( !getTypedControlWindow()->IsTravelSelect() )
            // fire a commit
            notifyModifiedValue();
        // fire a commit
        notifyModifiedValue();
    }


    //= OMultilineFloatingEdit

    class OMultilineFloatingEdit : public FloatingWindow
    {
    private:
        VclPtr<MultiLineEdit>   m_aImplEdit;

    protected:
        virtual void    Resize() override;

    public:
        explicit        OMultilineFloatingEdit(vcl::Window* _pParen);
        virtual         ~OMultilineFloatingEdit() override;
        virtual void    dispose() override;
        MultiLineEdit&  getEdit() { return *m_aImplEdit.get(); }

    protected:
        virtual bool    PreNotify(NotifyEvent& _rNEvt) override;
    };


    OMultilineFloatingEdit::OMultilineFloatingEdit(vcl::Window* _pParent)
        :FloatingWindow(_pParent, WB_BORDER)
        ,m_aImplEdit(VclPtr<MultiLineEdit>::Create(this, WB_VSCROLL|WB_IGNORETAB|WB_NOBORDER))
    {
        m_aImplEdit->Show();
    }

    OMultilineFloatingEdit::~OMultilineFloatingEdit()
    {
        disposeOnce();
    }

    void OMultilineFloatingEdit::dispose()
    {
        m_aImplEdit.disposeAndClear();
        FloatingWindow::dispose();
    }

    void OMultilineFloatingEdit::Resize()
    {
        m_aImplEdit->SetSizePixel(GetOutputSizePixel());
    }


    bool OMultilineFloatingEdit::PreNotify(NotifyEvent& _rNEvt)
    {
        bool bResult = true;

        MouseNotifyEvent nSwitch = _rNEvt.GetType();
        if (MouseNotifyEvent::KEYINPUT == nSwitch)
        {
            const vcl::KeyCode& aKeyCode = _rNEvt.GetKeyEvent()->GetKeyCode();
            sal_uInt16 nKey = aKeyCode.GetCode();

            if  (   (   (KEY_RETURN == nKey)
                    && !aKeyCode.IsShift()
                    )
                ||  (   (KEY_UP == nKey)
                    &&  aKeyCode.IsMod2()
                    )
                )
            {
                EndPopupMode();
            }
            else
                bResult=FloatingWindow::PreNotify(_rNEvt);
        }
        else
            bResult=FloatingWindow::PreNotify(_rNEvt);

        return bResult;
    }


    //= DropDownEditControl_Base


    DropDownEditControl::DropDownEditControl( vcl::Window* _pParent, WinBits _nStyle )
        :Edit( _pParent, _nStyle )
        ,m_pFloatingEdit( nullptr )
        ,m_pDropdownButton( nullptr )
        ,m_nOperationMode( eStringList )
        ,m_bDropdown(false)
        ,m_pHelper(nullptr)
    {
        SetCompoundControl( true );

        m_pImplEdit = VclPtr<MultiLineEdit>::Create( this, WB_TABSTOP | WB_IGNORETAB | WB_NOBORDER | (_nStyle & WB_READONLY) );
        SetSubEdit( m_pImplEdit );
        m_pImplEdit->Show();

        if ( _nStyle & WB_DROPDOWN )
        {
            m_pDropdownButton = VclPtr<PushButton>::Create( this, WB_NOLIGHTBORDER | WB_RECTSTYLE | WB_NOTABSTOP);
            m_pDropdownButton->SetSymbol(SymbolType::SPIN_DOWN);
            m_pDropdownButton->SetClickHdl( LINK( this, DropDownEditControl, DropDownHdl ) );
            m_pDropdownButton->Show();
        }

        m_pFloatingEdit = VclPtr<OMultilineFloatingEdit>::Create(this);

        m_pFloatingEdit->SetPopupModeEndHdl( LINK( this, DropDownEditControl, ReturnHdl ) );
        m_pFloatingEdit->getEdit().SetReadOnly( ( _nStyle & WB_READONLY ) != 0 );
    }


    void DropDownEditControl::setControlHelper( CommonBehaviourControlHelper& _rControlHelper )
    {
        m_pHelper = &_rControlHelper;
        m_pFloatingEdit->getEdit().SetModifyHdl( LINK( &_rControlHelper, CommonBehaviourControlHelper, EditModifiedHdl ) );
        m_pImplEdit->SetGetFocusHdl( LINK( &_rControlHelper, CommonBehaviourControlHelper, GetFocusHdl ) );
        m_pImplEdit->SetModifyHdl( LINK( &_rControlHelper, CommonBehaviourControlHelper, EditModifiedHdl ) );
        m_pImplEdit->SetLoseFocusHdl( LINK( &_rControlHelper, CommonBehaviourControlHelper, LoseFocusHdl ) );
    }


    DropDownEditControl::~DropDownEditControl()
    {
        disposeOnce();
    }

    void DropDownEditControl::dispose()
    {
        SetSubEdit(nullptr);
        m_pImplEdit.disposeAndClear();
        m_pFloatingEdit.disposeAndClear();
        m_pDropdownButton.disposeAndClear();
        Edit::dispose();
    }


    void DropDownEditControl::Resize()
    {
        ::Size aOutSz = GetOutputSizePixel();

        if (m_pDropdownButton!=nullptr)
        {
            long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
            nSBWidth = CalcZoom( nSBWidth );
            m_pImplEdit->setPosSizePixel( 0, 1, aOutSz.Width() - nSBWidth, aOutSz.Height()-2 );
            m_pDropdownButton->setPosSizePixel( aOutSz.Width() - nSBWidth, 0, nSBWidth, aOutSz.Height() );
        }
        else
            m_pImplEdit->setPosSizePixel( 0, 1, aOutSz.Width(), aOutSz.Height()-2 );
    }


    bool DropDownEditControl::PreNotify( NotifyEvent& rNEvt )
    {
        bool bResult = true;

        if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT)
        {
            const vcl::KeyCode& aKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
            sal_uInt16 nKey = aKeyCode.GetCode();

            if ( nKey == KEY_RETURN && !aKeyCode.IsShift() )
            {
                if ( m_pHelper )
                {
                    m_pHelper->LoseFocusHdl( *m_pImplEdit.get() );
                    m_pHelper->activateNextControl();
                }
            }
            else if ( nKey == KEY_DOWN && aKeyCode.IsMod2() )
            {
                Invalidate();
                ShowDropDown( true );
            }
            else if (   KEYGROUP_CURSOR == aKeyCode.GetGroup()
                    ||  nKey == KEY_HELP
                    ||  KEYGROUP_FKEYS == aKeyCode.GetGroup()
                    ||  m_nOperationMode == eMultiLineText
                    )
            {
                bResult = Edit::PreNotify( rNEvt );
            }
            else if ( m_nOperationMode == eStringList )
            {
                Selection aSel = m_pImplEdit->GetSelection();
                if ( aSel.Min() != aSel.Max() )
                {
                    aSel.Min() = FindPos( aSel.Min() );
                    aSel.Max() = FindPos( aSel.Max() );
                }
                else
                {
                    aSel.Min() = FindPos( aSel.Min() );
                    aSel.Max() = aSel.Min();
                }
                Invalidate();
                ShowDropDown( true );
                m_pFloatingEdit->getEdit().GrabFocus();
                m_pFloatingEdit->getEdit().SetSelection( aSel );
                vcl::Window* pFocusWin = Application::GetFocusWindow();
                pFocusWin->KeyInput( *rNEvt.GetKeyEvent() );
            }
        }
        else
            bResult = Edit::PreNotify(rNEvt);

        return bResult;
    }


    namespace
    {

@@ -1103,215 +691,118 @@ namespace pcr
        }
    }


    #define STD_HEIGHT  100
    void DropDownEditControl::ShowDropDown( bool bShow )
    void OMultilineEditControl::CheckEntryTextViewMisMatch()
    {
        if (bShow)
        {
            ::Point aMePos= GetPosPixel();
            aMePos = GetParent()->OutputToScreenPixel( aMePos );
            ::Size aSize=GetSizePixel();
            ::tools::Rectangle aRect(aMePos,aSize);
            aSize.setHeight( STD_HEIGHT );
            m_pFloatingEdit->SetOutputSizePixel(aSize);
            m_pFloatingEdit->StartPopupMode( aRect, FloatWinPopupFlags::Down );

            m_pFloatingEdit->Show();
            m_pFloatingEdit->getEdit().GrabFocus();
            m_pFloatingEdit->getEdit().SetSelection(Selection(m_pFloatingEdit->getEdit().GetText().getLength()));
            m_bDropdown = true;
            if ( m_nOperationMode == eMultiLineText )
                m_pFloatingEdit->getEdit().SetText( m_pImplEdit->GetText() );
            m_pImplEdit->SetText("");
        }
        else
        {
            m_pFloatingEdit->Hide();
            m_pFloatingEdit->Invalidate();
            m_pFloatingEdit->Update();

            // transfer the text from the floating edit to our own edit
            OUString sDisplayText( m_pFloatingEdit->getEdit().GetText() );
            if ( m_nOperationMode == eStringList )
                sDisplayText = lcl_convertListToDisplayText( lcl_convertMultiLineToList( sDisplayText ) );

            m_pImplEdit->SetText( sDisplayText );
            GetParent()->Invalidate( InvalidateFlags::Children );
            m_bDropdown = false;
            m_pImplEdit->GrabFocus();
        }
        // if there are newlines or something else which the entry cannot show, then make
        // just the multiline dropdown editable as the canonical source for text
        m_xEntry->set_sensitive(m_xEntry->get_text() == m_xTextView->get_text());
    }


    long DropDownEditControl::FindPos(long nSinglePos)
    void OMultilineEditControl::SetStringListValue(const StlSyntaxSequence<OUString>& rStrings)
    {
        long nPos = 0;
        OUString aOutput;
        OUString aStr = m_pFloatingEdit->getEdit().GetText();
        OUString aStr1 = GetText();

        if ((nSinglePos == 0) || (nSinglePos == aStr1.getLength()))
        {
            return nSinglePos;
        }

        if (!aStr.isEmpty())
        {
            long nDiff=0;

            sal_Int32 nIdx {0};
            OUString aInput = aStr.getToken(0, '\n', nIdx );

            if (!aInput.isEmpty())
            {
                aOutput += "\"" + aInput + "\"";
                nDiff++;
            }

            if (nSinglePos <= aOutput.getLength())
            {
                nPos=nSinglePos-nDiff;
            }
            else
            {
                while (nIdx>0)
                {
                    aInput=aStr.getToken(0, '\n', nIdx);
                    if (!aInput.isEmpty())
                    {
                        aOutput += ";\"" + aInput + "\"";
                        nDiff += 2;

                        if (nSinglePos <= aOutput.getLength())
                        {
                            nPos=nSinglePos-nDiff;
                            break;
                        }
                    }
                }
            }
        }
        return nPos;
        m_xEntry->set_text(lcl_convertListToDisplayText(rStrings));
        m_xTextView->set_text(lcl_convertListToMultiLine(rStrings));
        CheckEntryTextViewMisMatch();
    }


    IMPL_LINK_NOARG( DropDownEditControl, ReturnHdl, FloatingWindow*, void)
    StlSyntaxSequence<OUString> OMultilineEditControl::GetStringListValue() const
    {
        OUString aStr = m_pFloatingEdit->getEdit().GetText();
        OUString aStr2 = GetText();
        ShowDropDown(false);

        if (aStr!=aStr2 || ( m_nOperationMode == eStringList ) )
        {
            if ( m_pHelper )
                m_pHelper->notifyModifiedValue();
        }
        return lcl_convertMultiLineToList(m_xTextView->get_text());
    }


    IMPL_LINK_NOARG( DropDownEditControl, DropDownHdl, Button*, void )
    void OMultilineEditControl::SetTextValue(const OUString& rText)
    {
        ShowDropDown(!m_bDropdown);
        OSL_PRECOND( m_nOperationMode == eMultiLineText, "OMultilineEditControl::SetTextValue: illegal call!" );

        m_xTextView->set_text(rText);
        m_xEntry->set_text(rText);
        CheckEntryTextViewMisMatch();
    }


    void DropDownEditControl::SetStringListValue( const StlSyntaxSequence< OUString >& _rStrings )
    OUString OMultilineEditControl::GetTextValue() const
    {
        SetText( lcl_convertListToDisplayText( _rStrings ) );
        m_pFloatingEdit->getEdit().SetText( lcl_convertListToMultiLine( _rStrings ) );
        OSL_PRECOND( m_nOperationMode == eMultiLineText, "OMultilineEditControl::GetTextValue: illegal call!" );
        return m_xTextView->get_text();
    }


    StlSyntaxSequence< OUString > DropDownEditControl::GetStringListValue() const
    {
        return lcl_convertMultiLineToList( m_pFloatingEdit->getEdit().GetText() );
    }


    void DropDownEditControl::SetTextValue( const OUString& _rText )
    {
        OSL_PRECOND( m_nOperationMode == eMultiLineText, "DropDownEditControl::SetTextValue: illegal call!" );

        m_pFloatingEdit->getEdit().SetText( _rText );
        SetText( _rText );
    }


    OUString DropDownEditControl::GetTextValue() const
    {
        OSL_PRECOND( m_nOperationMode == eMultiLineText, "DropDownEditControl::GetTextValue: illegal call!" );
        return GetText();
    }


    //= OMultilineEditControl


    OMultilineEditControl::OMultilineEditControl( vcl::Window* pParent, MultiLineOperationMode _eMode, WinBits nWinStyle )
        :OMultilineEditControl_Base( _eMode == eMultiLineText ? PropertyControlType::MultiLineTextField : PropertyControlType::StringListField
                                   , pParent
                                   , ( nWinStyle | WB_DIALOGCONTROL ) & ( ~WB_READONLY | ~WB_DROPDOWN )
                                   , false )
    OMultilineEditControl::OMultilineEditControl(std::unique_ptr<weld::Container> xWidget, std::unique_ptr<weld::Builder> xBuilder, MultiLineOperationMode eMode, bool bReadOnly)
        : OMultilineEditControl_Base(eMode == eMultiLineText ? PropertyControlType::MultiLineTextField : PropertyControlType::StringListField,
                                    std::move(xBuilder), std::move(xWidget), bReadOnly)
        , m_nOperationMode(eMode)
        , m_xEntry(m_xBuilder->weld_entry("entry"))
        , m_xButton(m_xBuilder->weld_menu_button("button"))
        , m_xPopover(m_xBuilder->weld_widget("popover"))
        , m_xTextView(m_xBuilder->weld_text_view("textview"))
        , m_xOk(m_xBuilder->weld_button("ok"))
    {
        getTypedControlWindow()->setOperationMode( _eMode );
        getTypedControlWindow()->setControlHelper( *this );
        m_xButton->set_popover(m_xPopover.get());
        m_xTextView->set_size_request(m_xTextView->get_approximate_digit_width() * 30, m_xTextView->get_height_rows(8));
        m_xOk->connect_clicked(LINK(this, OMultilineEditControl, ButtonHandler));
    }

    IMPL_LINK_NOARG(OMultilineEditControl, TextViewModifiedHdl, weld::TextView&, void)
    {
        m_xEntry->set_text(m_xTextView->get_text());
        CheckEntryTextViewMisMatch();
        setModified();
    }

    IMPL_LINK_NOARG(OMultilineEditControl, ButtonHandler, weld::Button&, void)
    {
        m_xButton->set_active(false);
        notifyModifiedValue();
    }

    void SAL_CALL OMultilineEditControl::setValue( const Any& _rValue )
    {
        impl_checkDisposed_throw();

        switch ( getTypedControlWindow()->getOperationMode() )
        switch (m_nOperationMode)
        {
        case eMultiLineText:
        {
            OUString sText;
            if ( !( _rValue >>= sText ) && _rValue.hasValue() )
                throw IllegalTypeException();
            getTypedControlWindow()->SetTextValue( sText );
        }
        break;
        case eStringList:
        {
            Sequence< OUString > aStringLines;
            if ( !( _rValue >>= aStringLines ) && _rValue.hasValue() )
                throw IllegalTypeException();
            getTypedControlWindow()->SetStringListValue( StlSyntaxSequence<OUString>(aStringLines) );
        }
        break;
            case eMultiLineText:
            {
                OUString sText;
                if ( !( _rValue >>= sText ) && _rValue.hasValue() )
                    throw IllegalTypeException();
                SetTextValue(sText);
                break;
            }
            case eStringList:
            {
                Sequence< OUString > aStringLines;
                if ( !( _rValue >>= aStringLines ) && _rValue.hasValue() )
                    throw IllegalTypeException();
                SetStringListValue( StlSyntaxSequence<OUString>(aStringLines) );
                break;
            }
        }
    }


    Any SAL_CALL OMultilineEditControl::getValue()
    {
        impl_checkDisposed_throw();

        Any aValue;
        switch ( getTypedControlWindow()->getOperationMode() )
        switch (m_nOperationMode)
        {
        case eMultiLineText:
            aValue <<= getTypedControlWindow()->GetTextValue();
            break;
        case eStringList:
            aValue <<= getTypedControlWindow()->GetStringListValue();
            break;
            case eMultiLineText:
                aValue <<= GetTextValue();
                break;
            case eStringList:
                aValue <<= GetStringListValue();
                break;
        }
        return aValue;
    }


    Type SAL_CALL OMultilineEditControl::getValueType()
    {
        if ( getTypedControlWindow()->getOperationMode() == eMultiLineText )
        if (m_nOperationMode == eMultiLineText)
            return ::cppu::UnoType<OUString>::get();
        return cppu::UnoType<Sequence< OUString >>::get();
    }


} // namespace pcr


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/standardcontrol.hxx b/extensions/source/propctrlr/standardcontrol.hxx
index f78c225..27f09e9 100644
--- a/extensions/source/propctrlr/standardcontrol.hxx
+++ b/extensions/source/propctrlr/standardcontrol.hxx
@@ -27,19 +27,11 @@
#include <com/sun/star/inspection/XStringListControl.hpp>
#include <com/sun/star/inspection/XHyperlinkControl.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <vcl/field.hxx>
#include <svtools/ctrlbox.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/combobox.hxx>
#include <svtools/calendar.hxx>
#include <vcl/fmtfield.hxx>
#include <svx/colorbox.hxx>

#include <set>

class PushButton;
class MultiLineEdit;

namespace pcr
{

@@ -54,8 +46,8 @@ namespace pcr
    class ListLikeControlWithModifyHandler : public TListboxWindow
    {
    public:
        ListLikeControlWithModifyHandler( vcl::Window* _pParent, WinBits _nStyle )
            : TListboxWindow( _pParent, _nStyle )
        ListLikeControlWithModifyHandler( vcl::Window* pParent, WinBits _nStyle )
            : TListboxWindow( pParent, _nStyle )
        {
            TListboxWindow::SetSelectHdl( LINK(this, ListLikeControlWithModifyHandler, OnSelect) );
        }
@@ -77,114 +69,140 @@ namespace pcr
    }

    //= OTimeControl

    typedef CommonBehaviourControl< css::inspection::XPropertyControl, TimeField > OTimeControl_Base;
    typedef CommonBehaviourControl<css::inspection::XPropertyControl, weld::TimeSpinButton> OTimeControl_Base;
    class OTimeControl : public OTimeControl_Base
    {
    public:
        OTimeControl( vcl::Window* pParent, WinBits nWinStyle );
        OTimeControl(std::unique_ptr<weld::TimeSpinButton> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
        virtual void SAL_CALL setValue( const css::uno::Any& _value ) override;
        virtual css::uno::Type SAL_CALL getValueType() override;

        virtual void SetModifyHandler() override
        {
            OTimeControl_Base::SetModifyHandler();
            getTypedControlWindow()->connect_value_changed( LINK( this, CommonBehaviourControlHelper, TimeModifiedHdl ) );
        }

        virtual weld::Widget* getWidget() override { return &getTypedControlWindow()->get_widget(); }
    };


    //= ODateControl

    typedef CommonBehaviourControl< css::inspection::XPropertyControl, CalendarField > ODateControl_Base;
    typedef CommonBehaviourControl<css::inspection::XPropertyControl, SvtCalendarBox> ODateControl_Base;
    class ODateControl : public ODateControl_Base
    {
    public:
        ODateControl( vcl::Window* pParent, WinBits nWinStyle );
        ODateControl(std::unique_ptr<SvtCalendarBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
        virtual void SAL_CALL setValue( const css::uno::Any& _value ) override;
        virtual css::uno::Type SAL_CALL getValueType() override;

        virtual void SetModifyHandler() override
        {
            ODateControl_Base::SetModifyHandler();
            getTypedControlWindow()->connect_selected( LINK( this, CommonBehaviourControlHelper, DateModifiedHdl ) );
        }

        virtual weld::Widget* getWidget() override { return &getTypedControlWindow()->get_button(); }
    };


    //= OEditControl

    typedef CommonBehaviourControl< css::inspection::XPropertyControl, Edit > OEditControl_Base;
    typedef CommonBehaviourControl<css::inspection::XPropertyControl, weld::Entry> OEditControl_Base;
    class OEditControl final : public OEditControl_Base
    {
        bool m_bIsPassword : 1;

    public:
        OEditControl( vcl::Window* _pParent, bool _bPassWord, WinBits nWinStyle );
        OEditControl(std::unique_ptr<weld::Entry> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bPassWord, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
        virtual void SAL_CALL setValue( const css::uno::Any& _value ) override;
        virtual css::uno::Type SAL_CALL getValueType() override;

        virtual void SetModifyHandler() override
        {
            OEditControl_Base::SetModifyHandler();
            getTypedControlWindow()->connect_changed( LINK( this, CommonBehaviourControlHelper, EditModifiedHdl ) );
        }

    private:
        // CommonBehaviourControlHelper::modified
        virtual void setModified() override;
        virtual weld::Widget* getWidget() override { return getTypedControlWindow(); }
    };


    //= ODateTimeControl

    typedef CommonBehaviourControl< css::inspection::XPropertyControl, FormattedField > ODateTimeControl_Base;
    typedef CommonBehaviourControl<css::inspection::XPropertyControl, weld::Container> ODateTimeControl_Base;
    class ODateTimeControl : public ODateTimeControl_Base
    {
    private:
        std::unique_ptr<SvtCalendarBox> m_xDate;
        std::unique_ptr<weld::TimeSpinButton> m_xTime;

    public:
        ODateTimeControl( vcl::Window* pParent,WinBits nWinStyle );
        ODateTimeControl(std::unique_ptr<weld::Container> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        virtual void SetModifyHandler() override
        {
            m_xDate->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) );
            m_xDate->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) );
            m_xTime->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) );
            m_xTime->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) );

            m_xDate->connect_selected( LINK( this, CommonBehaviourControlHelper, DateModifiedHdl ) );
            m_xTime->connect_value_changed( LINK( this, CommonBehaviourControlHelper, TimeModifiedHdl ) );
        }

        virtual void SAL_CALL disposing() override
        {
            m_xTime.reset();
            m_xDate.reset();
            ODateTimeControl_Base::disposing();
        }

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
        virtual void SAL_CALL setValue( const css::uno::Any& _value ) override;
        virtual css::uno::Type SAL_CALL getValueType() override;

        virtual weld::Widget* getWidget() override { return getTypedControlWindow(); }
    };


    //= HyperlinkInput

    class HyperlinkInput : public Edit
    {
    private:
        Point             m_aMouseButtonDownPos;
        Link<void*,void>  m_aClickHandler;

    public:
        HyperlinkInput( vcl::Window* _pParent, WinBits _nWinStyle );

        /** sets the handler which will (asynchronously, with locked SolarMutex) be called
            when the hyperlink has been clicked by the user
        */
        void    SetClickHdl( const Link<void*,void>& _rHdl ) { m_aClickHandler = _rHdl; }

    protected:
        virtual void        MouseMove( const MouseEvent& rMEvt ) override;
        virtual void        MouseButtonDown( const MouseEvent& rMEvt ) override;
        virtual void        MouseButtonUp( const MouseEvent& rMEvt ) override;
        virtual void        Tracking( const TrackingEvent& rTEvt ) override;

    private:
        void    impl_checkEndClick( const MouseEvent& rMEvt );
        bool    impl_textHitTest( const Point& rWindowPos );
    };


    //= OHyperlinkControl

    typedef CommonBehaviourControl< css::inspection::XHyperlinkControl, HyperlinkInput > OHyperlinkControl_Base;
    typedef CommonBehaviourControl<css::inspection::XHyperlinkControl, weld::Container> OHyperlinkControl_Base;
    class OHyperlinkControl final : public OHyperlinkControl_Base
    {
        ::comphelper::OInterfaceContainerHelper2   m_aActionListeners;
    private:
        std::unique_ptr<weld::Entry> m_xEntry;
        std::unique_ptr<weld::Button> m_xButton;

        ::comphelper::OInterfaceContainerHelper2 m_aActionListeners;

    public:
        OHyperlinkControl( vcl::Window* _pParent, WinBits _nWinStyle );
        OHyperlinkControl(std::unique_ptr<weld::Container> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
        virtual void SAL_CALL setValue( const css::uno::Any& _value ) override;
        virtual css::uno::Type SAL_CALL getValueType() override;

        virtual void SetModifyHandler() override
        {
            m_xEntry->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) );
            m_xEntry->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) );
            m_xButton->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) );
            m_xButton->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) );

            m_xEntry->connect_changed( LINK( this, CommonBehaviourControlHelper, EditModifiedHdl ) );
        }

        virtual weld::Widget* getWidget() override { return getTypedControlWindow(); }

        // XHyperlinkControl
        virtual void SAL_CALL addActionListener( const css::uno::Reference< css::awt::XActionListener >& listener ) override;
        virtual void SAL_CALL removeActionListener( const css::uno::Reference< css::awt::XActionListener >& listener ) override;
@@ -193,27 +211,11 @@ namespace pcr
        // XComponent
        virtual void SAL_CALL disposing() override;

        DECL_LINK( OnHyperlinkClicked, void*, void );
        DECL_LINK(OnHyperlinkClicked, weld::Button&, void);
    };


    //= CustomConvertibleNumericField

    class CustomConvertibleNumericField : public MetricField
    {
    public:
        CustomConvertibleNumericField( vcl::Window* _pParent, WinBits _nStyle )
            :MetricField( _pParent, _nStyle )
        {
        }

        sal_Int64 GetLastValue() const { return mnLastValue; }
    };


    //= ONumericControl

    typedef CommonBehaviourControl< css::inspection::XNumericControl, CustomConvertibleNumericField > ONumericControl_Base;
    typedef CommonBehaviourControl<css::inspection::XNumericControl, weld::MetricSpinButton> ONumericControl_Base;
    class ONumericControl : public ONumericControl_Base
    {
    private:
@@ -221,7 +223,7 @@ namespace pcr
        sal_Int16   m_nFieldToUNOValueFactor;

    public:
        ONumericControl( vcl::Window* pParent, WinBits nWinStyle );
        ONumericControl(std::unique_ptr<weld::MetricSpinButton> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
@@ -240,51 +242,60 @@ namespace pcr
        virtual ::sal_Int16 SAL_CALL getValueUnit() override;
        virtual void SAL_CALL setValueUnit( ::sal_Int16 _valueunit ) override;

        virtual void SetModifyHandler() override
        {
            ONumericControl_Base::SetModifyHandler();
            getTypedControlWindow()->connect_value_changed( LINK( this, CommonBehaviourControlHelper, MetricModifiedHdl ) );
        }

    private:
        virtual weld::Widget* getWidget() override { return &getTypedControlWindow()->get_widget(); }

        /** converts an API value (<code>double</code>, as passed into <code>set[Max|Min|]Value) into
            a <code>long</code> value which can be passed to our NumericField.
            a <code>int</code> value which can be passed to our NumericField.

            The conversion respects our decimal digits as well as our value factor (<member>m_nFieldToUNOValueFactor</member>).
        */
        long    impl_apiValueToFieldValue_nothrow( double _nApiValue ) const;
        int    impl_apiValueToFieldValue_nothrow( double nApiValue ) const;

        /** converts a control value, as obtained from our Numeric field, into a value which can passed
            to outer callers via our UNO API.
        */
        double  impl_fieldValueToApiValue_nothrow( sal_Int64 _nFieldValue ) const;
        double  impl_fieldValueToApiValue_nothrow( int nFieldValue ) const;
    };


    //= OColorControl

    typedef CommonBehaviourControl  <   css::inspection::XPropertyControl
                                    ,   ListLikeControlWithModifyHandler<SvxColorListBox>
                                    >   OColorControl_Base;
    typedef CommonBehaviourControl<css::inspection::XPropertyControl, ColorListBox> OColorControl_Base;
    class OColorControl : public OColorControl_Base
    {
    public:
        OColorControl( vcl::Window* pParent, WinBits nWinStyle );
        OColorControl(std::unique_ptr<ColorListBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
        virtual void SAL_CALL setValue( const css::uno::Any& _value ) override;
        virtual css::uno::Type SAL_CALL getValueType() override;

        virtual void SetModifyHandler() override
        {
            OColorControl_Base::SetModifyHandler();
            getTypedControlWindow()->SetSelectHdl(LINK(this, CommonBehaviourControlHelper, ColorModifiedHdl));
        }

    protected:
        // CommonBehaviourControlHelper::setModified
        virtual void setModified() override;

    private:
        virtual weld::Widget* getWidget() override { return &getTypedControlWindow()->get_widget(); }
    };


    //= OListboxControl

    typedef CommonBehaviourControl  <   css::inspection::XStringListControl
                                    ,   ListLikeControlWithModifyHandler< ListBox >
                                    >   OListboxControl_Base;
    typedef CommonBehaviourControl<css::inspection::XStringListControl, weld::ComboBox> OListboxControl_Base;
    class OListboxControl : public OListboxControl_Base
    {
    public:
        OListboxControl( vcl::Window* pParent, WinBits nWinStyle );
        OListboxControl(std::unique_ptr<weld::ComboBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
@@ -297,19 +308,24 @@ namespace pcr
        virtual void SAL_CALL appendListEntry( const OUString& NewEntry ) override;
        virtual css::uno::Sequence< OUString > SAL_CALL getListEntries(  ) override;

        virtual void SetModifyHandler() override
        {
            OListboxControl_Base::SetModifyHandler();
            getTypedControlWindow()->connect_changed(LINK(this, CommonBehaviourControlHelper, ModifiedHdl));
        }

    protected:
        // CommonBehaviourControlHelper::setModified
        virtual void setModified() override;
        virtual weld::Widget* getWidget() override { return getTypedControlWindow(); }
    };


    //= OComboboxControl

    typedef CommonBehaviourControl< css::inspection::XStringListControl, ComboBox > OComboboxControl_Base;
    typedef CommonBehaviourControl< css::inspection::XStringListControl, weld::ComboBox > OComboboxControl_Base;
    class OComboboxControl final : public OComboboxControl_Base
    {
    public:
        OComboboxControl( vcl::Window* pParent, WinBits nWinStyle );
        OComboboxControl(std::unique_ptr<weld::ComboBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
@@ -322,8 +338,17 @@ namespace pcr
        virtual void SAL_CALL appendListEntry( const OUString& NewEntry ) override;
        virtual css::uno::Sequence< OUString > SAL_CALL getListEntries(  ) override;

        virtual void SetModifyHandler() override
        {
            OComboboxControl_Base::SetModifyHandler();
            getTypedControlWindow()->connect_changed(LINK(this, CommonBehaviourControlHelper, ModifiedHdl));
        }

        // CommonBehaviourControlHelper::setModified
        virtual weld::Widget* getWidget() override { return getTypedControlWindow(); }

    private:
        DECL_LINK( OnEntrySelected, ComboBox&, void );
        DECL_LINK( OnEntrySelected, weld::ComboBox&, void );
    };


@@ -335,68 +360,63 @@ namespace pcr
        eMultiLineText
    };

    //= DropDownEditControl

    class OMultilineFloatingEdit;
    /** an Edit field which can be used as ControlWindow, and has a drop-down button
    */
    class DropDownEditControl final : public Edit
    //= OMultilineEditControl
    typedef CommonBehaviourControl<css::inspection::XPropertyControl, weld::Container> OMultilineEditControl_Base;
    class OMultilineEditControl : public OMultilineEditControl_Base
    {
        VclPtr<OMultilineFloatingEdit>      m_pFloatingEdit;
        VclPtr<MultiLineEdit>               m_pImplEdit;
        VclPtr<PushButton>                  m_pDropdownButton;
        MultiLineOperationMode              m_nOperationMode;
        bool                                m_bDropdown : 1;
        CommonBehaviourControlHelper*       m_pHelper;
    private:
        MultiLineOperationMode m_nOperationMode;
        std::unique_ptr<weld::Entry> m_xEntry;
        std::unique_ptr<weld::MenuButton> m_xButton;
        std::unique_ptr<weld::Widget> m_xPopover;
        std::unique_ptr<weld::TextView> m_xTextView;
        std::unique_ptr<weld::Button> m_xOk;

    public:
        DropDownEditControl( vcl::Window* _pParent, WinBits _nStyle );
        virtual ~DropDownEditControl() override;
        virtual void dispose() override;

        void           setControlHelper( CommonBehaviourControlHelper& _rControlHelper );
        void setOperationMode( MultiLineOperationMode _eMode ) { m_nOperationMode = _eMode; }
        MultiLineOperationMode getOperationMode() const { return m_nOperationMode; }

        void            SetTextValue( const OUString& _rText );
        void            SetTextValue(const OUString& rText);
        OUString        GetTextValue() const;

        void            SetStringListValue( const StlSyntaxSequence< OUString >& _rStrings );
        StlSyntaxSequence< OUString >
                        GetStringListValue() const;

    private:
        // Window overridables
        virtual bool    PreNotify( NotifyEvent& rNEvt ) override;
        virtual void    Resize() override;
        DECL_LINK(ButtonHandler, weld::Button&, void);
        DECL_LINK(TextViewModifiedHdl, weld::TextView&, void);

        long            FindPos(long nSinglePos);
        void CheckEntryTextViewMisMatch();

        DECL_LINK( ReturnHdl, FloatingWindow*, void );
        DECL_LINK( DropDownHdl, Button*, void );

        void ShowDropDown( bool bShow );
    };


    //= OMultilineEditControl

    typedef CommonBehaviourControl< css::inspection::XPropertyControl, DropDownEditControl > OMultilineEditControl_Base;
    class OMultilineEditControl : public OMultilineEditControl_Base
    {
    public:
        OMultilineEditControl( vcl::Window* pParent, MultiLineOperationMode _eMode, WinBits nWinStyle  );
        OMultilineEditControl(std::unique_ptr<weld::Container> xWidget, std::unique_ptr<weld::Builder> xBuilder, MultiLineOperationMode eMode, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
        virtual void SAL_CALL setValue( const css::uno::Any& _value ) override;
        virtual css::uno::Type SAL_CALL getValueType() override;
        virtual weld::Widget* getWidget() override { return getTypedControlWindow(); }

        virtual void SetModifyHandler() override
        {
            m_xEntry->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) );
            m_xEntry->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) );
            m_xButton->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) );
            m_xButton->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) );

            m_xEntry->connect_changed( LINK( this, CommonBehaviourControlHelper, EditModifiedHdl ) );
            m_xTextView->connect_changed( LINK( this, OMultilineEditControl, TextViewModifiedHdl ) );
        }

        virtual void SAL_CALL disposing() override
        {
            m_xOk.reset();
            m_xTextView.reset();
            m_xButton.reset();
            m_xEntry.reset();
            OMultilineEditControl_Base::disposing();
        }

    };


} // namespace pcr


#endif // INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_STANDARDCONTROL_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/propctrlr/usercontrol.cxx b/extensions/source/propctrlr/usercontrol.cxx
index 3aa2ec9..60378da 100644
--- a/extensions/source/propctrlr/usercontrol.cxx
+++ b/extensions/source/propctrlr/usercontrol.cxx
@@ -41,79 +41,71 @@ namespace pcr

    namespace PropertyControlType = ::com::sun::star::inspection::PropertyControlType;


    // NumberFormatSampleField


    bool NumberFormatSampleField::PreNotify( NotifyEvent& rNEvt )
    IMPL_LINK(OFormatSampleControl, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
    {
        // want to handle two keys myself : Del/Backspace should empty the window (setting my prop to "standard" this way)
        if (MouseNotifyEvent::KEYINPUT == rNEvt.GetType())
        sal_uInt16 nKey = rKeyEvent.GetKeyCode().GetCode();
        if ((KEY_DELETE == nKey) || (KEY_BACKSPACE == nKey))
        {
            sal_uInt16 nKey = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();

            if ((KEY_DELETE == nKey) || (KEY_BACKSPACE == nKey))
            {
                SetText( "" );
                if ( m_pHelper )
                    m_pHelper->setModified();
                return true;
            }
            m_xSpinButton->set_text("");
            m_xEntry->set_text("");
            setModified();
        }

        return FormattedField::PreNotify( rNEvt );
        return true;
    }


    void NumberFormatSampleField::SetFormatSupplier( const SvNumberFormatsSupplierObj* pSupplier )
    void OFormatSampleControl::SetFormatSupplier( const SvNumberFormatsSupplierObj* pSupplier )
    {
        if ( pSupplier )
        if (pSupplier)
        {
            TreatAsNumber( true );
            m_xSpinButton->treat_as_number(true);

            SvNumberFormatter* pFormatter = pSupplier->GetNumberFormatter();
            SetFormatter( pFormatter );
            SetValue( 1234.56789 );
            m_xSpinButton->set_formatter(pFormatter);
            m_xSpinButton->set_value( 1234.56789 );
        }
        else
        {
            TreatAsNumber( false );
            SetFormatter( nullptr );
            SetText( "" );
            m_xSpinButton->treat_as_number(false);
            m_xSpinButton->set_formatter(nullptr);
            m_xSpinButton->set_text( "" );
        }

        m_xEntry->set_text(m_xSpinButton->get_text());
    }


    // OFormatSampleControl


    OFormatSampleControl::OFormatSampleControl( vcl::Window* pParent )
        :OFormatSampleControl_Base( PropertyControlType::Unknown, pParent, WB_READONLY | WB_TABSTOP | WB_BORDER )
    OFormatSampleControl::OFormatSampleControl(std::unique_ptr<weld::Container> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : OFormatSampleControl_Base(PropertyControlType::Unknown, std::move(xBuilder), std::move(xWidget), bReadOnly)
        , m_xSpinButton(m_xBuilder->weld_formatted_spin_button("sample"))
        , m_xEntry(m_xBuilder->weld_entry("entry"))
    {
        getTypedControlWindow()->setControlHelper(*this);
        m_xSpinButton->treat_as_number(true);
        m_xEntry->connect_key_press(LINK(this, OFormatSampleControl, KeyInputHdl));
    }


    void SAL_CALL OFormatSampleControl::setValue( const Any& _rValue )
    {
        sal_Int32 nFormatKey = 0;
        if ( _rValue >>= nFormatKey )
        {
            // else set the new format key, the text will be reformatted
            getTypedControlWindow()->SetFormatKey( nFormatKey );
            m_xSpinButton->set_format_key( nFormatKey );

            SvNumberFormatter* pNF = getTypedControlWindow()->GetFormatter();
            SvNumberFormatter* pNF = m_xSpinButton->get_formatter();
            const SvNumberformat* pEntry = pNF->GetEntry( nFormatKey );
            OSL_ENSURE( pEntry, "OFormatSampleControl::setValue: invalid format entry!" );

            const bool bIsTextFormat = ( pEntry && pEntry->IsTextFormat() );
            if ( bIsTextFormat )
                getTypedControlWindow()->SetText( PcrRes( RID_STR_TEXT_FORMAT ) );
                m_xSpinButton->set_text( PcrRes( RID_STR_TEXT_FORMAT ) );
            else
                getTypedControlWindow()->SetValue( pEntry ? getPreviewValue( *pEntry ) : 1234.56789 );
                m_xSpinButton->set_value( pEntry ? getPreviewValue( *pEntry ) : 1234.56789 );
        }
        else
            getTypedControlWindow()->SetText( "" );
            m_xSpinButton->set_text( "" );

        m_xEntry->set_text(m_xSpinButton->get_text());
    }

    double OFormatSampleControl::getPreviewValue( const SvNumberformat& i_rEntry )
@@ -155,71 +147,62 @@ namespace pcr
    Any SAL_CALL OFormatSampleControl::getValue()
    {
        Any aPropValue;
        if ( !getTypedControlWindow()->GetText().isEmpty() )
            aPropValue <<= static_cast<sal_Int32>(getTypedControlWindow()->GetFormatKey());
        if ( !m_xSpinButton->get_text().isEmpty() )
            aPropValue <<= m_xSpinButton->get_value();
        return aPropValue;
    }


    Type SAL_CALL OFormatSampleControl::getValueType()
    {
        return ::cppu::UnoType<sal_Int32>::get();
    }




    OFormattedNumericControl::OFormattedNumericControl( vcl::Window* pParent, WinBits nWinStyle )
        :OFormattedNumericControl_Base( PropertyControlType::Unknown, pParent, nWinStyle )
    OFormattedNumericControl::OFormattedNumericControl(std::unique_ptr<weld::FormattedSpinButton> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : OFormattedNumericControl_Base(PropertyControlType::Unknown, std::move(xBuilder), std::move(xWidget), bReadOnly)
    {
        getTypedControlWindow()->TreatAsNumber(true);
        getTypedControlWindow()->treat_as_number(true);
    }


    OFormattedNumericControl::~OFormattedNumericControl()
    {
    }


    void SAL_CALL OFormattedNumericControl::setValue( const Any& _rValue )
    {
        double nValue( 0 );
        if ( _rValue >>= nValue )
            getTypedControlWindow()->SetValue( nValue );
            getTypedControlWindow()->set_value( nValue );
        else
            getTypedControlWindow()->SetText("");
            getTypedControlWindow()->set_text("");
    }


    Any SAL_CALL OFormattedNumericControl::getValue()
    {
        Any aPropValue;
        if ( !getTypedControlWindow()->GetText().isEmpty() )
            aPropValue <<= getTypedControlWindow()->GetValue();
        if ( !getTypedControlWindow()->get_text().isEmpty() )
            aPropValue <<= getTypedControlWindow()->get_value();
        return aPropValue;
    }


    Type SAL_CALL OFormattedNumericControl::getValueType()
    {
        return ::cppu::UnoType<double>::get();
    }


    void OFormattedNumericControl::SetFormatDescription(const FormatDescription& rDesc)
    {
        bool bFallback = true;

        if (rDesc.pSupplier)
        {
            getTypedControlWindow()->TreatAsNumber(true);
            getTypedControlWindow()->treat_as_number(true);

            SvNumberFormatter* pFormatter = rDesc.pSupplier->GetNumberFormatter();
            if (pFormatter != getTypedControlWindow()->GetFormatter())
                getTypedControlWindow()->SetFormatter(pFormatter);
            getTypedControlWindow()->SetFormatKey(rDesc.nKey);
            if (pFormatter != getTypedControlWindow()->get_formatter())
                getTypedControlWindow()->set_formatter(pFormatter);
            getTypedControlWindow()->set_format_key(rDesc.nKey);

            const SvNumberformat* pEntry = getTypedControlWindow()->GetFormatter()->GetEntry(getTypedControlWindow()->GetFormatKey());
            const SvNumberformat* pEntry = getTypedControlWindow()->get_formatter()->GetEntry(getTypedControlWindow()->get_format_key());
            DBG_ASSERT( pEntry, "OFormattedNumericControl::SetFormatDescription: invalid format key!" );
            if ( pEntry )
            {
@@ -230,100 +213,51 @@ namespace pcr

        if ( bFallback )
        {
            getTypedControlWindow()->TreatAsNumber(false);
            getTypedControlWindow()->SetFormatter(nullptr);
            getTypedControlWindow()->SetText("");
            getTypedControlWindow()->treat_as_number(false);
            getTypedControlWindow()->set_formatter(nullptr);
            getTypedControlWindow()->set_text("");
        }
    }


    //= OFileUrlControl


    OFileUrlControl::OFileUrlControl( vcl::Window* pParent )
        :OFileUrlControl_Base( PropertyControlType::Unknown, pParent, WB_TABSTOP | WB_BORDER | WB_DROPDOWN )
    OFileUrlControl::OFileUrlControl(std::unique_ptr<URLBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly)
        : OFileUrlControl_Base(PropertyControlType::Unknown, std::move(xBuilder), std::move(xWidget), bReadOnly)
    {
        getTypedControlWindow()->SetDropDownLineCount( 10 );
        getTypedControlWindow()->DisableHistory();
        getTypedControlWindow()->SetPlaceHolder( PcrRes( RID_EMBED_IMAGE_PLACEHOLDER ) ) ;
    }


    OFileUrlControl::~OFileUrlControl()
    {
    }


    void SAL_CALL OFileUrlControl::setValue( const Any& _rValue )
    {
        OUString sURL;
        if (  _rValue >>= sURL )
        {
            if (GraphicObject::isGraphicObjectUniqueIdURL(sURL))
                getTypedControlWindow()->DisplayURL( getTypedControlWindow()->GetPlaceHolder() );
                getTypedControlWindow()->set_entry_text(getTypedControlWindow()->GetPlaceHolder());
            else
                getTypedControlWindow()->DisplayURL( sURL );
                getTypedControlWindow()->set_entry_text(sURL);
        }
        else
            getTypedControlWindow()->SetText( "" );
            getTypedControlWindow()->set_entry_text( "" );
    }


    Any SAL_CALL OFileUrlControl::getValue()
    {
        Any aPropValue;
        if ( !getTypedControlWindow()->GetText().isEmpty() )
                aPropValue <<= getTypedControlWindow()->GetURL();
        if (!getTypedControlWindow()->get_active_text().isEmpty())
            aPropValue <<= getTypedControlWindow()->GetURL();
        return aPropValue;
    }


    Type SAL_CALL OFileUrlControl::getValueType()
    {
        return ::cppu::UnoType<OUString>::get();
    }


    //= OTimeDurationControl


    OTimeDurationControl::OTimeDurationControl( vcl::Window* pParent )
        :ONumericControl( pParent, WB_BORDER | WB_TABSTOP )
    {
        getTypedControlWindow()->SetUnit( FieldUnit::CUSTOM );
        getTypedControlWindow()->SetCustomUnitText(" ms");
        getTypedControlWindow()->SetCustomConvertHdl( LINK( this, OTimeDurationControl, OnCustomConvert ) );
    }


    OTimeDurationControl::~OTimeDurationControl()
    {
    }


    ::sal_Int16 SAL_CALL OTimeDurationControl::getControlType()
    {
        // don't use the base class'es method, it would claim we're a standard control, which
        // we in fact aren't
        return PropertyControlType::Unknown;
    }


    IMPL_LINK_NOARG( OTimeDurationControl, OnCustomConvert, MetricFormatter&, void )
    {
        long nMultiplier = 1;
        if ( getTypedControlWindow()->GetCurUnitText().equalsIgnoreAsciiCase( "ms" ) )
            nMultiplier = 1;
        if ( getTypedControlWindow()->GetCurUnitText().equalsIgnoreAsciiCase( "s" ) )
            nMultiplier = 1000;
        else if ( getTypedControlWindow()->GetCurUnitText().equalsIgnoreAsciiCase( "m" ) )
            nMultiplier = 1000 * 60;
        else if ( getTypedControlWindow()->GetCurUnitText().equalsIgnoreAsciiCase( "h" ) )
            nMultiplier = 1000 * 60 * 60;

        getTypedControlWindow()->SetValue( getTypedControlWindow()->GetLastValue() * nMultiplier );
    }


} // namespace pcr


diff --git a/extensions/source/propctrlr/usercontrol.hxx b/extensions/source/propctrlr/usercontrol.hxx
index e9e29aa..a801273 100644
--- a/extensions/source/propctrlr/usercontrol.hxx
+++ b/extensions/source/propctrlr/usercontrol.hxx
@@ -28,79 +28,69 @@

class SvNumberFormatsSupplierObj;


namespace pcr
{


    //= NumberFormatSampleField

    class NumberFormatSampleField : public FormattedField
    {
    public:
        NumberFormatSampleField( vcl::Window* _pParent, WinBits _nStyle )
            : FormattedField(_pParent, _nStyle)
            , m_pHelper(nullptr)
        {
        }

        void         SetFormatSupplier( const SvNumberFormatsSupplierObj* pSupplier );
        void         setControlHelper( CommonBehaviourControlHelper& _rControlHelper ) { m_pHelper = &_rControlHelper; }

    protected:
        virtual bool PreNotify( NotifyEvent& rNEvt ) override;
    private:
        CommonBehaviourControlHelper* m_pHelper;
    };


    //= OFormatSampleControl

    typedef CommonBehaviourControl< css::inspection::XPropertyControl, NumberFormatSampleField > OFormatSampleControl_Base;
    typedef CommonBehaviourControl<css::inspection::XPropertyControl, weld::Container> OFormatSampleControl_Base;
    class OFormatSampleControl : public OFormatSampleControl_Base
    {
    private:
        std::unique_ptr<weld::FormattedSpinButton> m_xSpinButton;
        std::unique_ptr<weld::Entry> m_xEntry;

        DECL_LINK(KeyInputHdl, const KeyEvent&, bool);

    public:
        explicit OFormatSampleControl( vcl::Window* pParent );
        OFormatSampleControl(std::unique_ptr<weld::Container> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
        virtual void SAL_CALL setValue( const css::uno::Any& _value ) override;
        virtual css::uno::Type SAL_CALL getValueType() override;

        void SetFormatSupplier( const SvNumberFormatsSupplierObj* _pSupplier )
        virtual void SAL_CALL disposing() override
        {
            getTypedControlWindow()->SetFormatSupplier( _pSupplier );
            m_xEntry.reset();
            m_xSpinButton.reset();
            OFormatSampleControl_Base::disposing();
        }

        virtual void SetModifyHandler() override
        {
            m_xEntry->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) );
            m_xEntry->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) );
            m_xSpinButton->connect_value_changed(LINK(this, CommonBehaviourControlHelper, FormattedModifiedHdl));
        }

        void SetFormatSupplier(const SvNumberFormatsSupplierObj* pSupplier);

        virtual weld::Widget* getWidget() override { return getTypedControlWindow(); }

        /** returns the default preview value for the given format key
        *
        * \param _pNF the number formatter
        * \param _nFormatKey the format key
        * \return current date or time or the value 1234.56789
        */
        static double getPreviewValue(SvNumberFormatter const * _pNF, sal_Int32 _nFormatKey);
        static double getPreviewValue(SvNumberFormatter const * pNF, sal_Int32 nFormatKey);

    private:
        static double getPreviewValue( const SvNumberformat& i_rEntry );
    };


    //= FormatDescription

    struct FormatDescription
    {
        SvNumberFormatsSupplierObj*     pSupplier;
        sal_Int32                       nKey;
    };


    //= OFormattedNumericControl

    typedef CommonBehaviourControl< css::inspection::XPropertyControl, FormattedField > OFormattedNumericControl_Base;
    typedef CommonBehaviourControl<css::inspection::XPropertyControl, weld::FormattedSpinButton> OFormattedNumericControl_Base;
    class OFormattedNumericControl : public OFormattedNumericControl_Base
    {
    public:
        OFormattedNumericControl( vcl::Window* pParent, WinBits nWinStyle);
        OFormattedNumericControl(std::unique_ptr<weld::FormattedSpinButton> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
@@ -110,53 +100,47 @@ namespace pcr
        void SetFormatDescription( const FormatDescription& rDesc );

        // make some FormattedField methods available
        void SetDecimalDigits(sal_uInt16 nPrecision) { getTypedControlWindow()->SetDecimalDigits(nPrecision); }
        void SetDefaultValue(double dDef) { getTypedControlWindow()->SetDefaultValue(dDef); }
        void EnableEmptyField(bool bEnable) { getTypedControlWindow()->EnableEmptyField(bEnable); }
        void SetThousandsSep(bool bEnable) { getTypedControlWindow()->SetThousandsSep(bEnable); }
        void SetDecimalDigits(sal_uInt16 nPrecision) { getTypedControlWindow()->set_digits(nPrecision); }
        void SetDefaultValue(double dDef) { getTypedControlWindow()->set_value(dDef); }

        virtual void SetModifyHandler() override
        {
            OFormattedNumericControl_Base::SetModifyHandler();
            getTypedControlWindow()->connect_value_changed(LINK(this, CommonBehaviourControlHelper, FormattedModifiedHdl));
        }

        virtual weld::Widget* getWidget() override { return getTypedControlWindow(); }

    protected:
        virtual ~OFormattedNumericControl() override;
    };


    //= OFileUrlControl

    typedef CommonBehaviourControl< css::inspection::XPropertyControl, ::svt::FileURLBox > OFileUrlControl_Base;
    typedef CommonBehaviourControl<css::inspection::XPropertyControl, URLBox> OFileUrlControl_Base;
    class OFileUrlControl : public OFileUrlControl_Base
    {
    public:
        explicit OFileUrlControl( vcl::Window* pParent );
        OFileUrlControl(std::unique_ptr<URLBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly);

        // XPropertyControl
        virtual css::uno::Any SAL_CALL getValue() override;
        virtual void SAL_CALL setValue( const css::uno::Any& _value ) override;
        virtual css::uno::Type SAL_CALL getValueType() override;

        virtual void SetModifyHandler() override
        {
            OFileUrlControl_Base::SetModifyHandler();
            getTypedControlWindow()->connect_changed(LINK(this, CommonBehaviourControlHelper, ModifiedHdl));
        }

        virtual weld::Widget* getWidget() override { return getTypedControlWindow()->getWidget(); }

    protected:
        virtual ~OFileUrlControl() override;
    };


    //= OTimeDurationControl

    class OTimeDurationControl : public ONumericControl
    {
    public:
        explicit OTimeDurationControl( vcl::Window* pParent );
        virtual ~OTimeDurationControl() override;

        // XPropertyControl
        ::sal_Int16 SAL_CALL getControlType() override;

    private:
        DECL_LINK( OnCustomConvert, MetricFormatter&, void );
    };


} // namespace pcr


#endif // INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_USERCONTROL_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/uiconfig/spropctrlr/ui/browserline.ui b/extensions/uiconfig/spropctrlr/ui/browserline.ui
new file mode 100644
index 0000000..38e5492
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/browserline.ui
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkGrid" id="BrowserLine">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="vexpand">True</property>
    <property name="column_spacing">6</property>
    <child>
      <object class="GtkLabel" id="label">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="xalign">0</property>
      </object>
      <packing>
        <property name="left_attach">0</property>
        <property name="top_attach">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkButton" id="morebrowse">
        <property name="label">...</property>
        <property name="can_focus">True</property>
        <property name="receives_default">True</property>
        <property name="no_show_all">True</property>
      </object>
      <packing>
        <property name="left_attach">3</property>
        <property name="top_attach">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkButton" id="browse">
        <property name="label">...</property>
        <property name="can_focus">True</property>
        <property name="receives_default">True</property>
        <property name="no_show_all">True</property>
      </object>
      <packing>
        <property name="left_attach">2</property>
        <property name="top_attach">0</property>
      </packing>
    </child>
    <child>
      <placeholder/>
    </child>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/browserpage.ui b/extensions/uiconfig/spropctrlr/ui/browserpage.ui
new file mode 100644
index 0000000..cf0267a
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/browserpage.ui
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkGrid" id="BrowserPage">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="vexpand">True</property>
    <property name="row_spacing">6</property>
    <child>
      <object class="GtkScrolledWindow" id="scrolledwindow">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
        <property name="vexpand">True</property>
        <property name="hscrollbar_policy">never</property>
        <child>
          <object class="GtkViewport">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkBox">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="orientation">vertical</property>
                <child>
                  <object class="GtkBox" id="playground">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="valign">start</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="border_width">6</property>
                    <property name="orientation">vertical</property>
                    <property name="spacing">6</property>
                    <property name="homogeneous">True</property>
                    <child>
                      <placeholder/>
                    </child>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
      <packing>
        <property name="left_attach">0</property>
        <property name="top_attach">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkFrame" id="helpframe">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label_xalign">0</property>
        <property name="shadow_type">none</property>
        <child>
          <object class="GtkAlignment">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="top_padding">6</property>
            <property name="left_padding">12</property>
            <child>
              <object class="GtkTextView" id="helptext">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="editable">False</property>
                <property name="cursor_visible">False</property>
              </object>
            </child>
          </object>
        </child>
        <child type="label">
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes" context="browserpage|help">Help</property>
            <attributes>
              <attribute name="weight" value="bold"/>
            </attributes>
          </object>
        </child>
      </object>
      <packing>
        <property name="left_attach">0</property>
        <property name="top_attach">1</property>
      </packing>
    </child>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/colorlistbox.ui b/extensions/uiconfig/spropctrlr/ui/colorlistbox.ui
new file mode 100644
index 0000000..81ca192
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/colorlistbox.ui
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkMenuButton" id="colorlistbox">
    <property name="visible">True</property>
    <property name="can_focus">True</property>
    <property name="receives_default">True</property>
    <property name="hexpand">True</property>
    <property name="draw_indicator">True</property>
    <property name="label" translatable="no"></property>
    <property name="xalign">0</property>
    <child>
      <placeholder/>
    </child>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/combobox.ui b/extensions/uiconfig/spropctrlr/ui/combobox.ui
new file mode 100644
index 0000000..fecc3c4
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/combobox.ui
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkComboBoxText" id="combobox">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="has_entry">True</property>
    <child internal-child="entry">
      <object class="GtkEntry">
        <property name="can_focus">True</property>
      </object>
    </child>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/datefield.ui b/extensions/uiconfig/spropctrlr/ui/datefield.ui
new file mode 100644
index 0000000..95f2807
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/datefield.ui
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="sfx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkMenuButton" id="datefield">
    <property name="visible">True</property>
    <property name="can_focus">True</property>
    <property name="receives_default">False</property>
    <property name="hexpand">True</property>
    <property name="draw_indicator">True</property>
    <property name="label" translatable="no"></property>
    <child>
      <placeholder/>
    </child>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/datetimefield.ui b/extensions/uiconfig/spropctrlr/ui/datetimefield.ui
new file mode 100644
index 0000000..10f5a14
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/datetimefield.ui
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="sfx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkAdjustment" id="adjustment1">
    <property name="upper">86400000</property>
    <property name="step_increment">1000</property>
    <property name="page_increment">60000</property>
  </object>
  <object class="GtkBox" id="datetimefield">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="spacing">3</property>
    <child>
      <object class="GtkMenuButton" id="datefield">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="receives_default">False</property>
        <property name="hexpand">True</property>
        <property name="draw_indicator">True</property>
        <property name="label" translatable="no"></property>
        <child>
          <placeholder/>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkSpinButton" id="timefield">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
        <property name="adjustment">adjustment1</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">1</property>
      </packing>
    </child>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/formattedcontrol.ui b/extensions/uiconfig/spropctrlr/ui/formattedcontrol.ui
new file mode 100644
index 0000000..a5b3c0c
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/formattedcontrol.ui
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkAdjustment" id="adjustmentForwardBackward">
    <property name="lower">-10000</property>
    <property name="upper">10000</property>
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkSpinButton" id="formattedcontrol">
    <property name="visible">True</property>
    <property name="can_focus">True</property>
    <property name="hexpand">True</property>
    <property name="activates_default">True</property>
    <property name="caps_lock_warning">False</property>
    <property name="adjustment">adjustmentForwardBackward</property>
    <property name="digits">2</property>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/formattedsample.ui b/extensions/uiconfig/spropctrlr/ui/formattedsample.ui
new file mode 100644
index 0000000..9cdeedf
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/formattedsample.ui
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkAdjustment" id="adjustmentForwardBackward">
    <property name="lower">-10000</property>
    <property name="upper">10000</property>
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkBox" id="formattedsample">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <child>
      <object class="GtkEntry" id="entry">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkSpinButton" id="sample">
        <property name="can_focus">True</property>
        <property name="no_show_all">True</property>
        <property name="hexpand">True</property>
        <property name="activates_default">True</property>
        <property name="caps_lock_warning">False</property>
        <property name="adjustment">adjustmentForwardBackward</property>
        <property name="digits">2</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">1</property>
      </packing>
    </child>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/formproperties.ui b/extensions/uiconfig/spropctrlr/ui/formproperties.ui
new file mode 100644
index 0000000..51dbdbd
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/formproperties.ui
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkBox" id="box">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="vexpand">True</property>
    <property name="orientation">vertical</property>
    <child>
      <object class="GtkNotebook" id="tabcontrol">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
        <property name="vexpand">True</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkBox" id="controlparent">
        <property name="can_focus">False</property>
        <property name="no_show_all">True</property>
        <property name="orientation">vertical</property>
        <child>
          <placeholder/>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">1</property>
      </packing>
    </child>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/hyperlinkfield.ui b/extensions/uiconfig/spropctrlr/ui/hyperlinkfield.ui
new file mode 100644
index 0000000..cc8da4a
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/hyperlinkfield.ui
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="sfx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkBox" id="hyperlinkfield">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="spacing">6</property>
    <child>
      <object class="GtkEntry" id="entry">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkButton" id="button">
        <property name="label">...</property>
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="receives_default">True</property>
        <property name="tooltip_text" translatable="yes" context="hyperlinkfield|tooltip">Activate link</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">1</property>
      </packing>
    </child>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/listbox.ui b/extensions/uiconfig/spropctrlr/ui/listbox.ui
new file mode 100644
index 0000000..2936106
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/listbox.ui
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkComboBoxText" id="listbox">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/multiline.ui b/extensions/uiconfig/spropctrlr/ui/multiline.ui
new file mode 100644
index 0000000..420b82ec
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/multiline.ui
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkPopover" id="popover">
    <property name="can_focus">False</property>
    <child>
      <object class="GtkBox" id="container">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <property name="spacing">6</property>
        <child>
          <object class="GtkScrolledWindow" id="textviewscroll">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="shadow_type">in</property>
            <child>
              <object class="GtkTextView" id="textview">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="wrap_mode">word</property>
              </object>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="ok">
            <property name="label">gtk-ok</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="use_stock">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
  <object class="GtkBox" id="multiline">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="spacing">6</property>
    <child>
      <object class="GtkEntry" id="entry">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkMenuButton" id="button">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="receives_default">True</property>
        <property name="tooltip_text" translatable="yes" context="multiline|tooltip">Multiline Editing</property>
        <property name="draw_indicator">True</property>
        <property name="label" translatable="no"></property>
        <child>
          <placeholder/>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">1</property>
      </packing>
    </child>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/numericfield.ui b/extensions/uiconfig/spropctrlr/ui/numericfield.ui
new file mode 100644
index 0000000..3251ba3
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/numericfield.ui
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkAdjustment" id="adjustment1">
    <property name="upper">100</property>
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkSpinButton" id="numericfield">
    <property name="visible">True</property>
    <property name="can_focus">True</property>
    <property name="hexpand">True</property>
    <property name="adjustment">adjustment1</property>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/textfield.ui b/extensions/uiconfig/spropctrlr/ui/textfield.ui
new file mode 100644
index 0000000..d19bf85
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/textfield.ui
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkEntry" id="textfield">
    <property name="visible">True</property>
    <property name="can_focus">True</property>
    <property name="hexpand">True</property>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/timefield.ui b/extensions/uiconfig/spropctrlr/ui/timefield.ui
new file mode 100644
index 0000000..d7fd3f7
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/timefield.ui
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="sfx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkAdjustment" id="adjustment1">
    <property name="upper">86400000</property>
    <property name="step_increment">1000</property>
    <property name="page_increment">60000</property>
  </object>
  <object class="GtkSpinButton" id="timefield">
    <property name="visible">True</property>
    <property name="can_focus">True</property>
    <property name="hexpand">True</property>
    <property name="adjustment">adjustment1</property>
  </object>
</interface>
diff --git a/extensions/uiconfig/spropctrlr/ui/urlcontrol.ui b/extensions/uiconfig/spropctrlr/ui/urlcontrol.ui
new file mode 100644
index 0000000..621169d
--- /dev/null
+++ b/extensions/uiconfig/spropctrlr/ui/urlcontrol.ui
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkComboBoxText" id="urlcontrol">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="has_entry">True</property>
    <child internal-child="entry">
      <object class="GtkEntry">
        <property name="can_focus">True</property>
      </object>
    </child>
  </object>
</interface>
diff --git a/include/svtools/ctrlbox.hxx b/include/svtools/ctrlbox.hxx
index 1de4677..0a5e512 100644
--- a/include/svtools/ctrlbox.hxx
+++ b/include/svtools/ctrlbox.hxx
@@ -310,6 +310,10 @@ public:
    void grab_focus() { m_xControl->grab_focus(); }

    void connect_activated(const Link<SvtCalendarBox&, void>& rActivatedHdl) { m_aActivatedHdl = rActivatedHdl; }
    void connect_selected(const Link<SvtCalendarBox&, void>& rSelectHdl) { m_aSelectHdl = rSelectHdl; }

    void connect_focus_in(const Link<weld::Widget&, void>& rLink) { m_xControl->connect_focus_in(rLink); }
    void connect_focus_out(const Link<weld::Widget&, void>& rLink) { m_xControl->connect_focus_out(rLink); }
private:
    DECL_LINK(SelectHdl, weld::Calendar&, void);
    DECL_LINK(ActivateHdl, weld::Calendar&, void);
@@ -320,6 +324,7 @@ private:
    std::unique_ptr<weld::Calendar> m_xCalendar;

    Link<SvtCalendarBox&, void> m_aActivatedHdl;
    Link<SvtCalendarBox&, void> m_aSelectHdl;

    void set_label_from_date();
};
diff --git a/include/svtools/inettbc.hxx b/include/svtools/inettbc.hxx
index b6851e8..37f18b5 100644
--- a/include/svtools/inettbc.hxx
+++ b/include/svtools/inettbc.hxx
@@ -85,6 +85,7 @@ class SVT_DLLPUBLIC URLBox

    Idle                            aChangedIdle;
    OUString                        aBaseURL;
    OUString                        aPlaceHolder;
    rtl::Reference< MatchContext_Impl > pCtx;
    std::unique_ptr<SvtURLBox_Impl> pImpl;
    INetProtocol                    eSmartProtocol;
@@ -139,6 +140,13 @@ public:

    static OUString     ParseSmart( const OUString& aText, const OUString& aBaseURL );

    void                SetPlaceHolder(const OUString& sPlaceHolder) { aPlaceHolder = sPlaceHolder; }
    const OUString&     GetPlaceHolder() const { return aPlaceHolder; }
    bool                MatchesPlaceHolder(const OUString& sToMatch) const
    {
        return (!aPlaceHolder.isEmpty() && aPlaceHolder == sToMatch);
    }

    void                SetFilter(const OUString& _sFilter);
};

diff --git a/include/svx/colorbox.hxx b/include/svx/colorbox.hxx
index 5bbc7e4..dcf9aa85 100644
--- a/include/svx/colorbox.hxx
+++ b/include/svx/colorbox.hxx
@@ -142,6 +142,7 @@ public:
    void set_visible(bool bShow) { m_xButton->set_visible(bShow); }
    void set_help_id(const OString& rHelpId) { m_xButton->set_help_id(rHelpId); }
    void connect_focus_in(const Link<weld::Widget&, void>& rLink) { m_xButton->connect_focus_in(rLink); }
    void connect_focus_out(const Link<weld::Widget&, void>& rLink) { m_xButton->connect_focus_out(rLink); }
    weld::MenuButton& get_widget() { return *m_xButton; }
};

diff --git a/include/vcl/builderpage.hxx b/include/vcl/builderpage.hxx
index 6f721dd..85d9acc 100644
--- a/include/vcl/builderpage.hxx
+++ b/include/vcl/builderpage.hxx
@@ -33,6 +33,7 @@ public:
    virtual void Activate();
    virtual void Deactivate();

    void SetHelpId(const OString& rHelpId) { m_xContainer->set_help_id(rHelpId); }
    OString GetHelpId() const { return m_xContainer->get_help_id(); }

protected:
diff --git a/include/vcl/ivctrl.hxx b/include/vcl/ivctrl.hxx
index 3328d82..82e44af 100644
--- a/include/vcl/ivctrl.hxx
+++ b/include/vcl/ivctrl.hxx
@@ -314,7 +314,7 @@ public:
    VclPtr<vcl::Window> GetPage(const OString& rPageId);

    void RemovePage(const OString& rPageId);
    void InsertPage(const OString& rPageId, const OUString& rLabel, const Image& rImage, const OUString& rTooltip, VclPtr<vcl::Window> xPage);
    void InsertPage(const OString& rPageId, const OUString& rLabel, const Image& rImage, const OUString& rTooltip, VclPtr<vcl::Window> xPage, int nPos = -1);

    void SetActivatePageHdl( const Link<VerticalTabControl*,void>& rLink ) { m_aActivateHdl = rLink; }
    void SetDeactivatePageHdl( const Link<VerticalTabControl*, bool>& rLink ) { m_aDeactivateHdl = rLink; }
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 82dd5fb..e68d46c 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -361,7 +361,11 @@ public:
    virtual void set_current_page(int nPage) = 0;
    virtual void set_current_page(const OString& rIdent) = 0;
    virtual void remove_page(const OString& rIdent) = 0;
    virtual void append_page(const OString& rIdent, const OUString& rLabel) = 0;
    virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) = 0;
    void append_page(const OString& rIdent, const OUString& rLabel)
    {
        insert_page(rIdent, rLabel, -1);
    }
    virtual void set_tab_label_text(const OString& rIdent, const OUString& rLabel) = 0;
    virtual OUString get_tab_label_text(const OString& rIdent) const = 0;
    virtual int get_n_pages() const = 0;
@@ -1413,9 +1417,14 @@ public:
    }

    virtual void set_formatter(SvNumberFormatter* pFormatter) = 0;
    virtual SvNumberFormatter* get_formatter() = 0;
    virtual sal_Int32 get_format_key() const = 0;
    virtual void set_format_key(sal_Int32 nFormatKey) = 0;

    virtual void set_digits(unsigned int digits) = 0;

    virtual void treat_as_number(bool bSet) = 0;

    void connect_value_changed(const Link<FormattedSpinButton&, void>& rLink)
    {
        m_aValueChangedHdl = rLink;
@@ -1763,6 +1772,14 @@ public:
    void set_position(int nCursorPos) { m_xSpinButton->set_position(nCursorPos); }
    void set_text(const OUString& rText) { m_xSpinButton->set_text(rText); }
    OUString get_text() const { return m_xSpinButton->get_text(); }
    void connect_focus_in(const Link<Widget&, void>& rLink)
    {
        m_xSpinButton->connect_focus_in(rLink);
    }
    void connect_focus_out(const Link<Widget&, void>& rLink)
    {
        m_xSpinButton->connect_focus_out(rLink);
    }
    weld::SpinButton& get_widget() { return *m_xSpinButton; }
};

diff --git a/reportdesign/source/ui/inc/propbrw.hxx b/reportdesign/source/ui/inc/propbrw.hxx
index f09e8c2..4efe63e 100644
--- a/reportdesign/source/ui/inc/propbrw.hxx
+++ b/reportdesign/source/ui/inc/propbrw.hxx
@@ -28,6 +28,7 @@
#include <svl/SfxBroadcaster.hxx>
#include <svl/lstner.hxx>
#include <vcl/dockwin.hxx>
#include <vcl/layout.hxx>
#include <svx/svdmark.hxx>

namespace rptui
@@ -42,6 +43,8 @@ class OObjectBase;

class PropBrw final : public DockingWindow , public SfxListener, public SfxBroadcaster
{
    VclPtr<VclVBox> m_xContentArea;

    css::uno::Reference< css::uno::XComponentContext >
                        m_xInspectorContext;
    css::uno::Reference< css::uno::XComponentContext >
@@ -50,8 +53,6 @@ class PropBrw final : public DockingWindow , public SfxListener, public SfxBroad
                        m_xMeAsFrame;
    css::uno::Reference< css::inspection::XObjectInspector >
                        m_xBrowserController;
    css::uno::Reference< css::awt::XWindow >
                        m_xBrowserComponentWindow;
    css::uno::Reference< css::uno::XInterface>
                        m_xLastSection; /// is the previously displayed section
    OUString            m_sLastActivePage;
@@ -62,7 +63,6 @@ class PropBrw final : public DockingWindow , public SfxListener, public SfxBroad
    PropBrw(PropBrw const &) = delete;
    void operator =(PropBrw const &) = delete;

    virtual void Resize() override;
    virtual bool Close() override;

    css::uno::Sequence< css::uno::Reference< css::uno::XInterface> >
diff --git a/reportdesign/source/ui/report/propbrw.cxx b/reportdesign/source/ui/report/propbrw.cxx
index ad6d8f1..6ab6f3c 100644
--- a/reportdesign/source/ui/report/propbrw.cxx
+++ b/reportdesign/source/ui/report/propbrw.cxx
@@ -87,21 +87,29 @@ namespace


PropBrw::PropBrw(const Reference< XComponentContext >& _xORB, vcl::Window* pParent, ODesignView*  _pDesignView)
          :DockingWindow(pParent,WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_3DLOOK|WB_ROLLABLE))
          ,m_xORB(_xORB)
          ,m_pDesignView(_pDesignView)
          ,m_pView( nullptr )
          ,m_bInitialStateChange(true)
    : DockingWindow(pParent,WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_3DLOOK|WB_ROLLABLE))
    , m_xContentArea(VclPtr<VclVBox>::Create(this))
    , m_xORB(_xORB)
    , m_pDesignView(_pDesignView)
    , m_pView( nullptr )
    , m_bInitialStateChange(true)
{

    Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y);
    SetOutputSizePixel(aPropWinSize);

    // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
    // transparent children of the widget
    m_xContentArea->SetControlBackground(m_xContentArea->GetSettings().GetStyleSettings().GetWindowColor());
    m_xContentArea->SetBackground(m_xContentArea->GetControlBackground());
    m_xContentArea->SetStyle(m_xContentArea->GetStyle() & ~WB_CLIPCHILDREN);
    m_xContentArea->Show();

    try
    {
        // create a frame wrapper for myself
        m_xMeAsFrame = Frame::create( m_xORB );
        m_xMeAsFrame->initialize( VCLUnoHelper::GetInterface ( this ) );
        m_xMeAsFrame->initialize(VCLUnoHelper::GetInterface(m_xContentArea));
        m_xMeAsFrame->setName("report property browser");  // change name!
    }
    catch (Exception&)
@@ -139,8 +147,6 @@ PropBrw::PropBrw(const Reference< XComponentContext >& _xORB, vcl::Window* pPare
            else
            {
                m_xBrowserController->attachFrame( Reference<XFrame>(m_xMeAsFrame, UNO_QUERY_THROW));
                m_xBrowserComponentWindow = m_xMeAsFrame->getComponentWindow();
                OSL_ENSURE(m_xBrowserComponentWindow.is(), "PropBrw::PropBrw: attached the controller, but have no component window!");
                if ( bEnableHelpSection )
                {
                    uno::Reference< inspection::XObjectInspector > xInspector( m_xBrowserController, uno::UNO_SET_THROW );
@@ -156,22 +162,15 @@ PropBrw::PropBrw(const Reference< XComponentContext >& _xORB, vcl::Window* pPare
            try
            {
                ::comphelper::disposeComponent(m_xBrowserController);
                ::comphelper::disposeComponent(m_xBrowserComponentWindow);
            }
            catch(Exception&) { }
            m_xBrowserController.clear();
            m_xBrowserComponentWindow.clear();
        }
    }

    if (m_xBrowserComponentWindow.is())
    {
    VclContainer::setLayoutAllocation(*m_xContentArea, Point(0, 0), aPropWinSize);
    m_xContentArea->Show();

        m_xBrowserComponentWindow->setPosSize(0, 0, aPropWinSize.Width(), aPropWinSize.Height(),
            awt::PosSize::WIDTH | awt::PosSize::HEIGHT | awt::PosSize::X | awt::PosSize::Y);
        Resize();
        m_xBrowserComponentWindow->setVisible(true);
    }
    ::rptui::notifySystemWindow(pParent,this,::comphelper::mem_fun(&TaskPaneList::AddWindow));
}

@@ -203,6 +202,7 @@ void PropBrw::dispose()

    ::rptui::notifySystemWindow(this,this,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
    m_pDesignView.clear();
    m_xContentArea.disposeAndClear();
    DockingWindow::dispose();
}

@@ -225,7 +225,6 @@ void PropBrw::implDetachController()

    m_xMeAsFrame.clear();
    m_xBrowserController.clear();
    m_xBrowserComponentWindow.clear();
}

OUString PropBrw::getCurrentPage() const
@@ -428,39 +427,6 @@ uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(const uno::Referen
    return aSize;
}

void PropBrw::Resize()
{
    Window::Resize();

    Reference< awt::XLayoutConstrains > xLayoutConstrains( m_xBrowserController, UNO_QUERY );
    if( xLayoutConstrains.is() )
    {
        ::Size aMinSize = getMinimumSize();
        SetMinOutputSizePixel( aMinSize );
        ::Size aSize = GetOutputSizePixel();
        bool bResize = false;
        if( aSize.Width() < aMinSize.Width() )
        {
            aSize.setWidth( aMinSize.Width() );
            bResize = true;
        }
        if( aSize.Height() < aMinSize.Height() )
        {
            aSize.setHeight( aMinSize.Height() );
            bResize = true;
        }
        if( bResize )
            SetOutputSizePixel( aSize );
    }
    // adjust size
    if (m_xBrowserComponentWindow.is())
    {
        Size  aSize = GetOutputSizePixel();
        m_xBrowserComponentWindow->setPosSize(0, 0, aSize.Width(), aSize.Height(),
            awt::PosSize::WIDTH | awt::PosSize::HEIGHT);
    }
}

void PropBrw::Update( OSectionView* pNewView )
{
    try
@@ -559,8 +525,7 @@ void PropBrw::Update( const uno::Reference< uno::XInterface>& _xReportComponent)

IMPL_LINK_NOARG( PropBrw, OnAsyncGetFocus, void*, void )
{
    if (m_xBrowserComponentWindow.is())
        m_xBrowserComponentWindow->setFocus();
    m_xContentArea->GrabFocus();
}

void PropBrw::LoseFocus()
diff --git a/sfx2/source/appl/workwin.cxx b/sfx2/source/appl/workwin.cxx
index f372857..16c0d16 100644
--- a/sfx2/source/appl/workwin.cxx
+++ b/sfx2/source/appl/workwin.cxx
@@ -969,10 +969,8 @@ SfxChild_Impl* SfxWorkWindow::FindChild_Impl( const vcl::Window* rWindow ) const
    return nullptr;
}


void SfxWorkWindow::ShowChildren_Impl()
{

    bool bInvisible = ( !IsVisible_Impl() || ( !pWorkWin->IsReallyVisible() && !pWorkWin->IsReallyShown() ));

    for (std::unique_ptr<SfxChild_Impl>& pCli : aChildren)
diff --git a/solenv/sanitizers/ui/modules/spropctrlr.suppr b/solenv/sanitizers/ui/modules/spropctrlr.suppr
index 5adffba..466a329 100644
--- a/solenv/sanitizers/ui/modules/spropctrlr.suppr
+++ b/solenv/sanitizers/ui/modules/spropctrlr.suppr
@@ -1,3 +1,13 @@
extensions/uiconfig/spropctrlr/ui/browserline.ui://GtkLabel[@id='label'] orphan-label
extensions/uiconfig/spropctrlr/ui/datetimefield.ui://GtkSpinButton[@id='timefield'] no-labelled-by
extensions/uiconfig/spropctrlr/ui/formattedcontrol.ui://GtkSpinButton[@id='formattedcontrol'] no-labelled-by
extensions/uiconfig/spropctrlr/ui/formattedsample.ui://GtkEntry[@id='entry'] no-labelled-by
extensions/uiconfig/spropctrlr/ui/formattedsample.ui://GtkSpinButton[@id='sample'] no-labelled-by
extensions/uiconfig/spropctrlr/ui/formlinksdialog.ui://GtkLabel[@id='explanationLabel'] orphan-label
extensions/uiconfig/spropctrlr/ui/formlinksdialog.ui://GtkLabel[@id='detailLabel'] orphan-label
extensions/uiconfig/spropctrlr/ui/formlinksdialog.ui://GtkLabel[@id='masterLabel'] orphan-label
extensions/uiconfig/spropctrlr/ui/hyperlinkfield.ui://GtkEntry[@id='entry'] no-labelled-by
extensions/uiconfig/spropctrlr/ui/multiline.ui://GtkEntry[@id='entry'] no-labelled-by
extensions/uiconfig/spropctrlr/ui/numericfield.ui://GtkSpinButton[@id='numericfield'] no-labelled-by
extensions/uiconfig/spropctrlr/ui/textfield.ui://GtkEntry[@id='textfield'] no-labelled-by
extensions/uiconfig/spropctrlr/ui/timefield.ui://GtkSpinButton[@id='timefield'] no-labelled-by
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
index f186d3978..42919c8 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -1756,6 +1756,7 @@ void SvtCalendarBox::set_label_from_date()
IMPL_LINK_NOARG(SvtCalendarBox, SelectHdl, weld::Calendar&, void)
{
    set_label_from_date();
    m_aSelectHdl.Call(*this);
}

IMPL_LINK_NOARG(SvtCalendarBox, ActivateHdl, weld::Calendar&, void)
diff --git a/svtools/source/control/inettbc.cxx b/svtools/source/control/inettbc.cxx
index 1bf5619..60a827d 100644
--- a/svtools/source/control/inettbc.cxx
+++ b/svtools/source/control/inettbc.cxx
@@ -2071,6 +2071,8 @@ OUString URLBox::GetURL()
    ::osl::MutexGuard aGuard( theSvtMatchContextMutex::get() );

    OUString aText(m_xWidget->get_active_text());
    if (MatchesPlaceHolder(aText))
        return aPlaceHolder;

    // try to get the right case preserving URL from the list of URLs
    for(std::vector<OUString>::iterator i = pImpl->aCompletions.begin(), j = pImpl->aURLs.begin(); i != pImpl->aCompletions.end() && j != pImpl->aURLs.end(); ++i, ++j)
diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk
index f4a7e0a..db7a92f 100644
--- a/svx/UIConfig_svx.mk
+++ b/svx/UIConfig_svx.mk
@@ -52,6 +52,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\
	svx/uiconfig/ui/formfielddialog \
	svx/uiconfig/ui/formlinkwarndialog \
	svx/uiconfig/ui/formnavimenu \
	svx/uiconfig/ui/formpropertydialog \
	svx/uiconfig/ui/functionmenu \
	svx/uiconfig/ui/gallerymenu1 \
	svx/uiconfig/ui/gallerymenu2 \
diff --git a/svx/source/form/fmPropBrw.cxx b/svx/source/form/fmPropBrw.cxx
index 61f9c74..e7fdd4f 100644
--- a/svx/source/form/fmPropBrw.cxx
+++ b/svx/source/form/fmPropBrw.cxx
@@ -35,7 +35,6 @@
#include <svx/svdpagv.hxx>
#include <svx/svxids.hrc>

#include <com/sun/star/awt/XLayoutConstrains.hpp>
#include <com/sun/star/awt/XControlContainer.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
@@ -65,7 +64,9 @@
#include <tools/diagnose_ex.h>
#include <unotools/confignode.hxx>
#include <vcl/stdtext.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <vcl/weldutils.hxx>

#include <algorithm>

@@ -83,27 +84,16 @@ using namespace ::svxform;
using ::com::sun::star::awt::XWindow;

//= FmPropBrwMgr


SFX_IMPL_FLOATINGWINDOW(FmPropBrwMgr, SID_FM_SHOW_PROPERTIES)

SFX_IMPL_MODELESSDIALOGCONTOLLER(FmPropBrwMgr, SID_FM_SHOW_PROPERTIES)

FmPropBrwMgr::FmPropBrwMgr( vcl::Window* _pParent, sal_uInt16 _nId,
                            SfxBindings* _pBindings, SfxChildWinInfo* _pInfo)
              :SfxChildWindow(_pParent, _nId)
{
    SetWindow( VclPtr<FmPropBrw>::Create( ::comphelper::getProcessComponentContext(), _pBindings, this, _pParent, _pInfo ) );
    static_cast<SfxFloatingWindow*>(GetWindow())->Initialize( _pInfo );
    SetController(std::make_shared<FmPropBrw>(::comphelper::getProcessComponentContext(), _pBindings, this, _pParent->GetFrameWeld(), _pInfo));
    static_cast<FmPropBrw*>(GetController().get())->Initialize( _pInfo );
}


const long STD_WIN_SIZE_X = 300;
const long STD_WIN_SIZE_Y = 350;

const long STD_MIN_SIZE_X = 250;
const long STD_MIN_SIZE_Y = 250;


static OUString GetUIHeadlineName(sal_Int16 nClassId, const Any& aUnoObj)
{
    const char* pClassNameResourceId = nullptr;
@@ -183,79 +173,46 @@ static OUString GetUIHeadlineName(sal_Int16 nClassId, const Any& aUnoObj)
    return SvxResId(pClassNameResourceId);
}

FmPropBrw::FmPropBrw( const Reference< XComponentContext >& _xORB, SfxBindings* _pBindings,
            SfxChildWindow* _pMgr, vcl::Window* _pParent, const SfxChildWinInfo* _pInfo )
    :SfxFloatingWindow(_pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_3DLOOK|WB_ROLLABLE) )
    ,SfxControllerItem(SID_FM_PROPERTY_CONTROL, *_pBindings)
    ,m_bInitialStateChange(true)
    ,m_xORB(_xORB)
FmPropBrw::FmPropBrw(const Reference< XComponentContext >& _xORB, SfxBindings* _pBindings,
                     SfxChildWindow* _pMgr, weld::Window* _pParent, const SfxChildWinInfo* _pInfo)
    : SfxModelessDialogController(_pBindings, _pMgr, _pParent, "svx/ui/formpropertydialog.ui", "FormPropertyDialog")
    , SfxControllerItem(SID_FM_PROPERTY_CONTROL, *_pBindings)
    , m_bInitialStateChange(true)
    , m_pParent(_pParent)
    , m_nAsyncGetFocusId(nullptr)
    , m_xContainer(m_xBuilder->weld_container("container"))
    , m_xORB(_xORB)
{

    ::Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y);
    SetMinOutputSizePixel(::Size(STD_MIN_SIZE_X,STD_MIN_SIZE_Y));
    SetOutputSizePixel(aPropWinSize);
    m_xContainer->set_size_request(m_xContainer->get_approximate_digit_width() * 72, m_xContainer->get_text_height() * 20);

    try
    {
        // create a frame wrapper for myself
        m_xMeAsFrame = Frame::create(m_xORB);

        // create an intermediate window, which is to be the container window of the frame
        // Do *not* use |this| as container window for the frame, this would result in undefined
        // responsibility for this window (as soon as we initialize a frame with a window, the frame
        // is responsible for its life time, but |this| is controlled by the belonging SfxChildWindow)
        // #i34249#
        VclPtr<vcl::Window> pContainerWindow = VclPtr<vcl::Window>::Create( this );
        pContainerWindow->Show();
        m_xFrameContainerWindow = VCLUnoHelper::GetInterface ( pContainerWindow );

        m_xMeAsFrame->initialize( m_xFrameContainerWindow );
        // transport the container area of this dialog to be the container window of the frame
        css::uno::Reference<css::awt::XWindow> xFrameContainerWindow(new weld::TransportAsXWindow(m_xContainer.get()));
        m_xMeAsFrame->initialize(xFrameContainerWindow);
        m_xMeAsFrame->setName("form property browser");
    }
    catch (Exception&)
    catch (const Exception&)
    {
        OSL_FAIL("FmPropBrw::FmPropBrw: could not create/initialize my frame!");
        m_xMeAsFrame.clear();
    }

    if (m_xMeAsFrame.is())
        _pMgr->SetFrame( Reference<XFrame>(m_xMeAsFrame,UNO_QUERY_THROW) );


    if ( m_xBrowserComponentWindow.is() )
        m_xBrowserComponentWindow->setVisible( true );

    if ( _pInfo )
        m_sLastActivePage = _pInfo->aExtraString;
}


void FmPropBrw::Resize()
{
    SfxFloatingWindow::Resize();

    if ( m_xFrameContainerWindow.is() )
    {
        try
        {
            ::Size aOutputSize( GetOutputSizePixel() );
            m_xFrameContainerWindow->setPosSize( 0, 0, aOutputSize.Width(), aOutputSize.Height(), awt::PosSize::POSSIZE );
        }
        catch( const Exception& )
        {
            OSL_FAIL( "FmPropBrw::Resize: caught an exception!" );
        }
    }
}


FmPropBrw::~FmPropBrw()
{
    disposeOnce();
}
    if (m_nAsyncGetFocusId)
    {
        Application::RemoveUserEvent(m_nAsyncGetFocusId);
        m_nAsyncGetFocusId = nullptr;
    }

void FmPropBrw::dispose()
{
    if (m_xBrowserController.is())
        implDetachController();
    try
@@ -279,10 +236,8 @@ void FmPropBrw::dispose()
        DBG_UNHANDLED_EXCEPTION("svx");
    }
    ::SfxControllerItem::dispose();
    SfxFloatingWindow::dispose();
}


OUString FmPropBrw::getCurrentPage() const
{
    OUString sCurrentPage;
@@ -303,7 +258,6 @@ OUString FmPropBrw::getCurrentPage() const
    return sCurrentPage;
}


void FmPropBrw::implDetachController()
{
    m_sLastActivePage = getCurrentPage();
@@ -324,15 +278,16 @@ void FmPropBrw::implDetachController()

    // we attached a frame to the controller manually, so we need to manually tell it that it's detached, too
    if ( m_xBrowserController.is() )
    {
        m_xBrowserController->attachFrame( nullptr );
    }

    m_xBrowserController.clear();
    m_xInspectorModel.clear();
    m_xMeAsFrame.clear();
}


bool FmPropBrw::Close()
void FmPropBrw::Close()
{
    // suspend the controller (it is allowed to veto)
    if ( m_xMeAsFrame.is() )
@@ -341,7 +296,7 @@ bool FmPropBrw::Close()
        {
            Reference< XController > xController( m_xMeAsFrame->getController() );
            if ( xController.is() && !xController->suspend( true ) )
                return false;
                return;
        }
        catch( const Exception& )
        {
@@ -351,26 +306,17 @@ bool FmPropBrw::Close()

    implDetachController();

    if( IsRollUp() )
        RollDown();

    // remember our bindings: while we're closed, we're deleted, too, so accessing the bindings after this
    // would be deadly
    // 10/19/00 - 79321 - FS
    SfxBindings& rBindings = SfxControllerItem::GetBindings();

    bool bClose = SfxFloatingWindow::Close();
    SfxModelessDialogController::Close();

    if (bClose)
    {
        rBindings.Invalidate(SID_FM_CTL_PROPERTIES);
        rBindings.Invalidate(SID_FM_PROPERTIES);
    }

    return bClose;
    rBindings.Invalidate(SID_FM_CTL_PROPERTIES);
    rBindings.Invalidate(SID_FM_PROPERTIES);
}


bool FmPropBrw::implIsReadOnlyModel() const
{
    try
@@ -439,55 +385,21 @@ void FmPropBrw::implSetNewSelection( const InterfaceBag& _rSelection )
        if ( implIsReadOnlyModel() )
            sTitle += SvxResId(RID_STR_READONLY_VIEW);

        SetText( sTitle );

        Reference< css::awt::XLayoutConstrains > xLayoutConstrains( m_xBrowserController, UNO_QUERY );
        if( xLayoutConstrains.is() )
        {
            ::Size aConstrainedSize;
            css::awt::Size aMinSize = xLayoutConstrains->getMinimumSize();

            sal_Int32 nLeft(0), nTop(0), nRight(0), nBottom(0);
            GetBorder( nLeft, nTop, nRight, nBottom );
            aMinSize.Width += nLeft + nRight + 8;
            aMinSize.Height += nTop + nBottom + 8;

            aConstrainedSize.setHeight( aMinSize.Height );
            aConstrainedSize.setWidth( aMinSize.Width );
            SetMinOutputSizePixel( aConstrainedSize );
            aConstrainedSize = GetOutputSizePixel();
            bool bResize = false;
            if( aConstrainedSize.Width() < aMinSize.Width )
            {
                aConstrainedSize.setWidth( aMinSize.Width );
                bResize = true;
            }
            if( aConstrainedSize.Height() < aMinSize.Height )
            {
                aConstrainedSize.setHeight( aMinSize.Height );
                bResize = true;
            }
            if( bResize )
                SetOutputSizePixel( aConstrainedSize );
        }
        m_xDialog->set_title(sTitle);
    }
}


void FmPropBrw::FillInfo( SfxChildWinInfo& rInfo ) const
{
    rInfo.bVisible = false;
    rInfo.aExtraString = getCurrentPage();
}


IMPL_LINK_NOARG( FmPropBrw, OnAsyncGetFocus, void*, void )
{
    if (m_xBrowserComponentWindow.is())
        m_xBrowserComponentWindow->setFocus();
    m_nAsyncGetFocusId = nullptr;
}


namespace
{
    bool lcl_shouldEnableHelpSection( const Reference< XComponentContext >& _rxContext )
@@ -528,7 +440,7 @@ void FmPropBrw::impl_createPropertyBrowser_throw( FmFormShell* _pFormShell )
    }

    // the default parent window for message boxes
    Reference< XWindow > xParentWindow( VCLUnoHelper::GetInterface ( this ) );
    Reference< XWindow > xParentWindow(m_xDialog->GetXWindow());

    // the mapping from control models to control shapes
    Reference< XMap > xControlMap;
@@ -566,14 +478,11 @@ void FmPropBrw::impl_createPropertyBrowser_throw( FmFormShell* _pFormShell )

    if ( !m_xBrowserController.is() )
    {
        vcl::Window *pWin = GetParent();
        ShowServiceNotAvailableError(pWin ? pWin->GetFrameWeld() : nullptr, "com.sun.star.inspection.ObjectInspector", true);
        ShowServiceNotAvailableError(m_pParent, "com.sun.star.inspection.ObjectInspector", true);
    }
    else
    {
        m_xBrowserController->attachFrame( Reference<XFrame>(m_xMeAsFrame,UNO_QUERY_THROW) );
        m_xBrowserComponentWindow = m_xMeAsFrame->getComponentWindow();
        DBG_ASSERT( m_xBrowserComponentWindow.is(), "FmPropBrw::impl_createPropertyBrowser_throw: attached the controller, but have no component window!" );
    }

    if ( bEnableHelpSection )
@@ -605,7 +514,6 @@ void FmPropBrw::impl_ensurePropertyBrowser_nothrow( FmFormShell* _pFormShell )
            ::comphelper::disposeComponent( m_xBrowserController );
        m_xBrowserController.clear();
        m_xInspectorModel.clear();
        m_xBrowserComponentWindow.clear();

        // and create a new one
        impl_createPropertyBrowser_throw( _pFormShell );
@@ -641,7 +549,7 @@ void FmPropBrw::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPool
            if ( m_bInitialStateChange )
            {
                // if we're just newly created, we want to have the focus
                PostUserEvent( LINK( this, FmPropBrw, OnAsyncGetFocus ), nullptr, true );
                m_nAsyncGetFocusId = Application::PostUserEvent(LINK(this, FmPropBrw, OnAsyncGetFocus));

                // and additionally, we want to show the page which was active during
                // our previous incarnation
diff --git a/svx/source/inc/fmPropBrw.hxx b/svx/source/inc/fmPropBrw.hxx
index 34315d9..1d856b9 100644
--- a/svx/source/inc/fmPropBrw.hxx
+++ b/svx/source/inc/fmPropBrw.hxx
@@ -40,10 +40,13 @@ public:
class SfxBindings;
class FmFormShell;

class FmPropBrw final : public SfxFloatingWindow, public SfxControllerItem
class FmPropBrw final : public SfxModelessDialogController, public SfxControllerItem
{
    bool            m_bInitialStateChange;
    weld::Window*   m_pParent;
    ImplSVEvent*    m_nAsyncGetFocusId;
    OUString        m_sLastActivePage;
    std::unique_ptr<weld::Container> m_xContainer;
    css::uno::Reference< css::uno::XComponentContext >
                    m_xInspectorContext;
    css::uno::Reference< css::uno::XComponentContext >
@@ -56,14 +59,10 @@ class FmPropBrw final : public SfxFloatingWindow, public SfxControllerItem
                    m_xInspectorModel;
    css::uno::Reference< css::frame::XController >
                    m_xBrowserController;
    css::uno::Reference< css::awt::XWindow >
                    m_xBrowserComponentWindow;
    css::uno::Reference< css::awt::XWindow >
                    m_xFrameContainerWindow;

    virtual void StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) override;
    virtual void FillInfo( SfxChildWinInfo& rInfo ) const override;
    virtual bool Close() override;
    virtual void Close() override;

    DECL_LINK( OnAsyncGetFocus, void*, void );

@@ -77,16 +76,12 @@ public:
        const css::uno::Reference< css::uno::XComponentContext >& _xORB,
        SfxBindings* pBindings,
        SfxChildWindow* pMgr,
        vcl::Window* pParent,
        weld::Window* pParent,
        const SfxChildWinInfo* _pInfo
    );
    virtual ~FmPropBrw() override;
    virtual void dispose() override;

    using SfxFloatingWindow::StateChanged;

private:
    virtual void        Resize() override;

    /** creates the PropertyBrowser (aka ObjectInspector) and plugs it into our frame

@@ -98,12 +93,10 @@ private:

    /** creates a property browser

        After this method returns, m_xBrowserController and m_xBrowserComponentWindow are
        not <NULL/>.
        After this method returns, m_xBrowserController is not <NULL/>.

    @precond
        we don't have an ObjectInspector, yet, i.e. m_xBrowserController and m_xBrowserComponentWindow
        are <NULL/>.
        we don't have an ObjectInspector, yet, i.e. m_xBrowserController is <NULL/>.
    */
    void    impl_createPropertyBrowser_throw( FmFormShell* _pFormShell );
};
diff --git a/svx/uiconfig/ui/formpropertydialog.ui b/svx/uiconfig/ui/formpropertydialog.ui
new file mode 100644
index 0000000..30409cb
--- /dev/null
+++ b/svx/uiconfig/ui/formpropertydialog.ui
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="svx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkDialog" id="FormPropertyDialog">
    <property name="can_focus">False</property>
    <property name="border_width">6</property>
    <property name="default_width">0</property>
    <property name="type_hint">dialog</property>
    <child>
      <placeholder/>
    </child>
    <child internal-child="vbox">
      <object class="GtkBox" id="dialog-vbox1">
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child internal-child="action_area">
          <object class="GtkButtonBox" id="dialog-action_area1">
            <property name="can_focus">False</property>
            <property name="no_show_all">True</property>
            <property name="layout_style">end</property>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="pack_type">end</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkGrid" id="container">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
diff --git a/toolkit/source/awt/vclxtoolkit.cxx b/toolkit/source/awt/vclxtoolkit.cxx
index b3bf486..27ceb86 100644
--- a/toolkit/source/awt/vclxtoolkit.cxx
+++ b/toolkit/source/awt/vclxtoolkit.cxx
@@ -1886,6 +1886,9 @@ css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::ImplCreateWindow(
    if ( !pNewWindow )
        pNewWindow = ImplCreateWindow( &pNewComp, rDescriptor, pParent, nWinBits, aPair.second );

    if (!pNewWindow)
        fprintf(stderr, "debug here\n");

    DBG_ASSERT( pNewWindow, "createWindow: Unknown Component!" );
    SAL_INFO_IF( !pNewComp, "toolkit", "createWindow: No special Interface!" );

diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index ae1aaa0..844281c 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -2334,12 +2334,12 @@ public:
        }
    }

    virtual void append_page(const OString& rIdent, const OUString& rLabel) override
    virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) override
    {
        sal_uInt16 nPageCount = m_xNotebook->GetPageCount();
        sal_uInt16 nLastPageId = nPageCount ? m_xNotebook->GetPageId(nPageCount - 1) : 0;
        sal_uInt16 nNewPageId = nLastPageId + 1;
        m_xNotebook->InsertPage(nNewPageId, rLabel);
        m_xNotebook->InsertPage(nNewPageId, rLabel, nPos == -1 ? TAB_APPEND : nPos);
        VclPtrInstance<TabPage> xPage(m_xNotebook);
        VclPtrInstance<VclGrid> xGrid(xPage);
        xPage->Show();
@@ -2458,12 +2458,12 @@ public:
            m_aPages.erase(m_aPages.begin() + nPageIndex);
    }

    virtual void append_page(const OString& rIdent, const OUString& rLabel) override
    virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) override
    {
        VclPtrInstance<VclGrid> xGrid(m_xNotebook->GetPageParent());
        xGrid->set_hexpand(true);
        xGrid->set_vexpand(true);
        m_xNotebook->InsertPage(rIdent, rLabel, Image(), "", xGrid);
        m_xNotebook->InsertPage(rIdent, rLabel, Image(), "", xGrid, nPos);
    }

    virtual int get_n_pages() const override
@@ -5242,6 +5242,11 @@ public:
        m_xButton->SetFormatter(pFormatter);
    }

    virtual SvNumberFormatter* get_formatter() override
    {
        return m_xButton->GetFormatter();
    }

    virtual sal_Int32 get_format_key() const override
    {
        return m_xButton->GetFormatKey();
@@ -5251,6 +5256,16 @@ public:
    {
        m_xButton->SetFormatKey(nFormatKey);
    }

    virtual void treat_as_number(bool bSet) override
    {
        m_xButton->TreatAsNumber(bSet);
    }

    virtual void set_digits(unsigned int digits) override
    {
        m_xButton->SetDecimalDigits(digits);
    }
};

class SalInstanceLabel : public SalInstanceWidget, public virtual weld::Label
diff --git a/vcl/source/control/ivctrl.cxx b/vcl/source/control/ivctrl.cxx
index 8cef33b..5a20afa 100644
--- a/vcl/source/control/ivctrl.cxx
+++ b/vcl/source/control/ivctrl.cxx
@@ -554,13 +554,22 @@ OString VerticalTabControl::GetPageId(sal_uInt16 nIndex) const
}

void VerticalTabControl::InsertPage(const rtl::OString &rIdent, const rtl::OUString& rLabel, const Image& rImage,
                                    const rtl::OUString& rTooltip, VclPtr<vcl::Window> xPage)
                                    const rtl::OUString& rTooltip, VclPtr<vcl::Window> xPage, int nPos)
{
    SvxIconChoiceCtrlEntry* pEntry = m_xChooser->InsertEntry(rLabel, rImage);
    pEntry->SetQuickHelpText(rTooltip);
    m_xChooser->ArrangeIcons();
    maPageList.emplace_back(new VerticalTabPageData);
    VerticalTabPageData* pNew = maPageList.back().get();
    VerticalTabPageData* pNew;
    if (nPos == -1)
    {
        maPageList.emplace_back(new VerticalTabPageData);
        pNew = maPageList.back().get();
    }
    else
    {
        maPageList.emplace(maPageList.begin() + nPos, new VerticalTabPageData);
        pNew = maPageList[nPos].get();
    }
    pNew->sId = rIdent;
    pNew->pEntry = pEntry;
    pNew->xPage = xPage;
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index fc9a04f..5c7b8ae 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -5458,7 +5458,7 @@ private:
            remove_page(m_pOverFlowNotebook, sIdent);

            GtkWidget* pPage = m_aPages[nPageIndex]->getWidget();
            append_page(m_pNotebook, sIdent, sLabel, pPage);
            insert_page(m_pNotebook, sIdent, sLabel, pPage, -1);

            GtkWidget* pTabWidget = gtk_notebook_get_tab_label(m_pNotebook,
                                                               gtk_notebook_get_nth_page(m_pNotebook, i));
@@ -5575,14 +5575,14 @@ private:
        enable_notify_events();
    }

    void append_page(GtkNotebook *pNotebook, const OString& rIdent, const OUString& rLabel, GtkWidget *pChild)
    void insert_page(GtkNotebook *pNotebook, const OString& rIdent, const OUString& rLabel, GtkWidget *pChild, int nPos)
    {
        disable_notify_events();

        GtkWidget *pTabWidget = gtk_label_new(MapToGtkAccelerator(rLabel).getStr());
        gtk_buildable_set_name(GTK_BUILDABLE(pTabWidget), rIdent.getStr());

        gtk_notebook_append_page(pNotebook, pChild, pTabWidget);
        gtk_notebook_insert_page(pNotebook, pChild, pTabWidget, nPos);
        gtk_widget_show(pChild);
        gtk_widget_show(pTabWidget);

@@ -5691,7 +5691,7 @@ private:
            OString sIdent(get_page_ident(m_pNotebook, 0));
            OUString sLabel(get_tab_label_text(m_pNotebook, 0));
            remove_page(m_pNotebook, sIdent);
            append_page(m_pOverFlowNotebook, sIdent, sLabel, gtk_grid_new());
            insert_page(m_pOverFlowNotebook, sIdent, sLabel, gtk_grid_new(), -1);
            GtkWidget* pTabWidget = gtk_notebook_get_tab_label(m_pOverFlowNotebook,
                                                               gtk_notebook_get_nth_page(m_pOverFlowNotebook, i));
            gtk_widget_set_hexpand(pTabWidget, true);
@@ -6043,7 +6043,7 @@ public:
            m_aPages.erase(m_aPages.begin() + nPageIndex);
    }

    virtual void append_page(const OString& rIdent, const OUString& rLabel) override
    virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) override
    {
        if (m_bOverFlowBoxActive)
        {
@@ -6055,7 +6055,7 @@ public:
        gtk_widget_hide(GTK_WIDGET(m_pOverFlowNotebook));
        m_bOverFlowBoxActive = false;

        append_page(m_pNotebook, rIdent, rLabel, gtk_grid_new());
        insert_page(m_pNotebook, rIdent, rLabel, gtk_grid_new(), nPos);
    }

    virtual ~GtkInstanceNotebook() override
@@ -10580,6 +10580,7 @@ private:
    SvNumberFormatter* m_pFormatter;
    Color* m_pLastOutputColor;
    sal_uInt32 m_nFormatKey;
    bool m_bTreatAsNumber;
    gulong m_nValueChangedSignalId;
    gulong m_nOutputSignalId;
    gulong m_nInputSignalId;
@@ -10620,7 +10621,7 @@ private:

        sal_uInt32 nFormatKey = m_nFormatKey; // IsNumberFormat changes the FormatKey!

        if (m_pFormatter->IsTextFormat(nFormatKey))
        if (m_pFormatter->IsTextFormat(nFormatKey) && m_bTreatAsNumber)
            // for detection of values like "1,1" in fields that are formatted as text
            nFormatKey = 0;

@@ -10671,6 +10672,7 @@ public:
        , m_pFormatter(nullptr)
        , m_pLastOutputColor(nullptr)
        , m_nFormatKey(0)
        , m_bTreatAsNumber(true)
        , m_nValueChangedSignalId(g_signal_connect(pButton, "value-changed", G_CALLBACK(signalValueChanged), this))
        , m_nOutputSignalId(g_signal_connect(pButton, "output", G_CALLBACK(signalOutput), this))
        , m_nInputSignalId(g_signal_connect(pButton, "input", G_CALLBACK(signalInput), this))
@@ -10718,6 +10720,11 @@ public:
        signal_output();
    }

    virtual SvNumberFormatter* get_formatter() override
    {
        return m_pFormatter;
    }

    virtual sal_Int32 get_format_key() const override
    {
        return m_nFormatKey;
@@ -10728,6 +10735,18 @@ public:
        m_nFormatKey = nFormatKey;
    }

    virtual void treat_as_number(bool bSet) override
    {
        m_bTreatAsNumber = bSet;
    }

    virtual void set_digits(unsigned int digits) override
    {
        disable_notify_events();
        gtk_spin_button_set_digits(m_pButton, digits);
        enable_notify_events();
    }

    virtual ~GtkInstanceFormattedSpinButton() override
    {
        g_signal_handler_disconnect(m_pButton, m_nInputSignalId);