/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
 
 
#include <tools/debug.hxx>
#include <vcl/fixedhyper.hxx>
#include <vcl/prgsbar.hxx>
#include <vcl/svapp.hxx>
#include <svtools/svmedit.hxx>
#include <unoiface.hxx>
#include <svtools/filectrl.hxx>
#include <roadmap.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/awt/LineEndFormat.hpp>
#include <cppuhelper/queryinterface.hxx>
#include <toolkit/helper/convert.hxx>
#include <toolkit/helper/property.hxx>
#include <svtools/fmtfield.hxx>
#include <svl/numuno.hxx>
#include <svtools/calendar.hxx>
#include <svtools/treelistbox.hxx>
#include "treecontrolpeer.hxx"
#include "svtxgridcontrol.hxx"
#include <table/tablecontrol.hxx>
 
namespace
{
    void lcl_setWinBits( vcl::Window* _pWindow, WinBits _nBits, bool _bSet )
    {
        WinBits nStyle = _pWindow->GetStyle();
        if ( _bSet )
            nStyle |= _nBits;
        else
            nStyle &= ~_nBits;
        _pWindow->SetStyle( nStyle );
    }
}
 
 
//  help function for the toolkit...
 
 
extern "C" {
 
SAL_DLLPUBLIC_EXPORT vcl::Window* CreateWindow( VCLXWindow** ppNewComp, const css::awt::WindowDescriptor* pDescriptor, vcl::Window* pParent, WinBits nWinBits )
{
    vcl::Window* pWindow = nullptr;
    OUString aServiceName( pDescriptor->WindowServiceName );
    if ( aServiceName.equalsIgnoreAsciiCase( "MultiLineEdit" ) )
    {
        if ( pParent )
        {
            pWindow = VclPtr<MultiLineEdit>::Create( pParent, nWinBits|WB_IGNORETAB);
            static_cast< MultiLineEdit* >( pWindow )->DisableSelectionOnFocus();
            *ppNewComp = new VCLXMultiLineEdit;
        }
        else
        {
            *ppNewComp = nullptr;
            return nullptr;
        }
    }
    else if ( aServiceName.equalsIgnoreAsciiCase( "FileControl" ) )
    {
        if ( pParent )
        {
            pWindow = VclPtr<FileControl>::Create( pParent, nWinBits );
            *ppNewComp = new VCLXFileControl;
        }
        else
        {
            *ppNewComp = nullptr;
            return nullptr;
        }
    }
    else if (aServiceName.equalsIgnoreAsciiCase("FormattedField") )
    {
        pWindow = VclPtr<FormattedField>::Create( pParent, nWinBits );
        *ppNewComp = new SVTXFormattedField;
    }
    else if (aServiceName.equalsIgnoreAsciiCase("NumericField") )
    {
        pWindow = VclPtr<DoubleNumericField>::Create( pParent, nWinBits );
        *ppNewComp = new SVTXNumericField;
    }
    else if (aServiceName.equalsIgnoreAsciiCase("LongCurrencyField") )
    {
        pWindow = VclPtr<DoubleCurrencyField>::Create( pParent, nWinBits );
        *ppNewComp = new SVTXCurrencyField;
    }
    else if (aServiceName.equalsIgnoreAsciiCase("datefield") )
    {
        pWindow = VclPtr<CalendarField>::Create( pParent, nWinBits);
        static_cast<CalendarField*>(pWindow)->EnableToday();
        static_cast<CalendarField*>(pWindow)->EnableNone();
        static_cast<CalendarField*>(pWindow)->EnableEmptyFieldValue( true );
        SVTXDateField * newComp = new SVTXDateField;
        *ppNewComp = newComp;
        newComp->SetFormatter( static_cast<FormatterBase*>(static_cast<DateField*>(pWindow)) );
    }
    else if (aServiceName.equalsIgnoreAsciiCase("roadmap") )
    {
        pWindow = VclPtr< ::svt::ORoadmap>::Create( pParent, WB_TABSTOP );
        *ppNewComp = new SVTXRoadmap;
    }
    else if ( aServiceName.equalsIgnoreAsciiCase( "ProgressBar" ) )
    {
        if ( pParent )
        {
            pWindow = VclPtr<ProgressBar>::Create( pParent, nWinBits );
            *ppNewComp = new VCLXProgressBar;
        }
        else
        {
            *ppNewComp = nullptr;
            return nullptr;
        }
    }
    else if ( aServiceName.equalsIgnoreAsciiCase( "Tree" ) )
    {
        TreeControlPeer* pPeer = new TreeControlPeer;
        *ppNewComp = pPeer;
        pWindow = pPeer->createVclControl( pParent, nWinBits );
    }
    else if ( aServiceName.equalsIgnoreAsciiCase( "FixedHyperlink" ) )
    {
        if ( pParent )
        {
            pWindow = VclPtr<FixedHyperlink>::Create( pParent, nWinBits );
            *ppNewComp = new VCLXFixedHyperlink;
        }
        else
        {
            *ppNewComp = nullptr;
            return nullptr;
        }
    }
    else if ( aServiceName.equalsIgnoreAsciiCase( "Grid" ) )
    {
        if ( pParent )
        {
            pWindow = VclPtr< ::svt::table::TableControl>::Create(pParent, nWinBits);
            *ppNewComp = new SVTXGridControl;
        }
        else
        {
            *ppNewComp = nullptr;
            return nullptr;
        }
    }
    return pWindow;
}
 
}   // extern "C"
 
 
//  class VCLXMultiLineEdit
 
VCLXMultiLineEdit::VCLXMultiLineEdit()
    :maTextListeners( *this )
    ,meLineEndType( LINEEND_LF )    // default behavior before introducing this property: LF (unix-like)
{
}
 
VCLXMultiLineEdit::~VCLXMultiLineEdit()
{
}
 
css::uno::Any VCLXMultiLineEdit::queryInterface( const css::uno::Type & rType )
{
    css::uno::Any aRet = ::cppu::queryInterface( rType,
                                        static_cast< css::awt::XTextComponent* >(this),
                                        static_cast< css::awt::XTextArea* >(this),
                                        static_cast< css::awt::XTextLayoutConstrains* >(this),
                                        static_cast< css::lang::XTypeProvider* >(this) );
    return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
}
 
// css::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXMultiLineEdit )
    cppu::UnoType<css::awt::XTextComponent>::get(),
    cppu::UnoType<css::awt::XTextArea>::get(),
    cppu::UnoType<css::awt::XTextLayoutConstrains>::get(),
    VCLXWindow::getTypes()
IMPL_XTYPEPROVIDER_END
 
void VCLXMultiLineEdit::addTextListener( const css::uno::Reference< css::awt::XTextListener > & l )
{
    maTextListeners.addInterface( l );
}
 
void VCLXMultiLineEdit::removeTextListener( const css::uno::Reference< css::awt::XTextListener > & l )
{
    maTextListeners.removeInterface( l );
}
 
void VCLXMultiLineEdit::setText( const OUString& aText )
{
    SolarMutexGuard aGuard;
 
    VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
    if ( pEdit )
    {
        pEdit->SetText( aText );
 
        // #107218# Call same listeners like VCL would do after user interaction
        SetSynthesizingVCLEvent( true );
        pEdit->SetModifyFlag();
        pEdit->Modify();
        SetSynthesizingVCLEvent( false );
    }
}
 
void VCLXMultiLineEdit::insertText( const css::awt::Selection& rSel, const OUString& aText )
{
    SolarMutexGuard aGuard;
 
    VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
    if ( pEdit )
    {
        setSelection( rSel );
        pEdit->ReplaceSelected( aText );
    }
}
 
OUString VCLXMultiLineEdit::getText()
{
    SolarMutexGuard aGuard;
 
    OUString aText;
    VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
    if ( pEdit )
        aText = pEdit->GetText( meLineEndType );
    return aText;
}
 
OUString VCLXMultiLineEdit::getSelectedText()
{
    SolarMutexGuard aGuard;
 
    OUString aText;
    VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
    if ( pMultiLineEdit)
        aText = pMultiLineEdit->GetSelected( meLineEndType );
    return aText;
 
}
 
void VCLXMultiLineEdit::setSelection( const css::awt::Selection& aSelection )
{
    SolarMutexGuard aGuard;
 
    VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
    if ( pMultiLineEdit )
    {
        pMultiLineEdit->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
    }
}
 
css::awt::Selection VCLXMultiLineEdit::getSelection()
{
    SolarMutexGuard aGuard;
 
    css::awt::Selection aSel;
    VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
    if ( pMultiLineEdit )
    {
        aSel.Min = pMultiLineEdit->GetSelection().Min();
        aSel.Max = pMultiLineEdit->GetSelection().Max();
    }
    return aSel;
}
 
sal_Bool VCLXMultiLineEdit::isEditable()
{
    SolarMutexGuard aGuard;
 
    VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
    return pMultiLineEdit && !pMultiLineEdit->IsReadOnly() && pMultiLineEdit->IsEnabled();
}
 
void VCLXMultiLineEdit::setEditable( sal_Bool bEditable )
{
    SolarMutexGuard aGuard;
 
    VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
    if ( pMultiLineEdit )
        pMultiLineEdit->SetReadOnly( !bEditable );
}
 
void VCLXMultiLineEdit::setMaxTextLen( sal_Int16 nLen )
{
    SolarMutexGuard aGuard;
 
    VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
    if ( pMultiLineEdit )
        pMultiLineEdit->SetMaxTextLen( nLen );
}
 
sal_Int16 VCLXMultiLineEdit::getMaxTextLen()
{
    SolarMutexGuard aGuard;
 
    VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
    return pMultiLineEdit ? static_cast<sal_Int16>(pMultiLineEdit->GetMaxTextLen()) : sal_Int16(0);
}
 
OUString VCLXMultiLineEdit::getTextLines()
{
    SolarMutexGuard aGuard;
 
    OUString aText;
    VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
    if ( pEdit )
        aText = pEdit->GetTextLines( meLineEndType );
    return aText;
}
 
css::awt::Size VCLXMultiLineEdit::getMinimumSize()
{
    SolarMutexGuard aGuard;
 
    css::awt::Size aSz;
    VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
    if ( pEdit )
        aSz = AWTSize(pEdit->CalcMinimumSize());
    return aSz;
}
 
css::awt::Size VCLXMultiLineEdit::getPreferredSize()
{
    return getMinimumSize();
}
 
css::awt::Size VCLXMultiLineEdit::calcAdjustedSize( const css::awt::Size& rNewSize )
{
    SolarMutexGuard aGuard;
 
    css::awt::Size aSz = rNewSize;
    VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
    if ( pEdit )
        aSz = AWTSize(pEdit->CalcAdjustedSize( VCLSize(rNewSize )));
    return aSz;
}
 
css::awt::Size VCLXMultiLineEdit::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines )
{
    SolarMutexGuard aGuard;
 
    css::awt::Size aSz;
    VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
    if ( pEdit )
        aSz = AWTSize(pEdit->CalcBlockSize( nCols, nLines ));
    return aSz;
}
 
void VCLXMultiLineEdit::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines )
{
    SolarMutexGuard aGuard;
 
    nCols = nLines = 0;
    VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
    if ( pEdit )
    {
        sal_uInt16 nC, nL;
        pEdit->GetMaxVisColumnsAndLines( nC, nL );
        nCols = nC;
        nLines = nL;
    }
}
 
void VCLXMultiLineEdit::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
    switch ( rVclWindowEvent.GetId() )
    {
        case VclEventId::EditModify:
        {
            if ( maTextListeners.getLength() )
            {
                css::awt::TextEvent aEvent;
                aEvent.Source = static_cast<cppu::OWeakObject*>(this);
                maTextListeners.textChanged( aEvent );
            }
        }
        break;
        default:
        {
            VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
        }
        break;
    }
}
 
void VCLXMultiLineEdit::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
    SolarMutexGuard aGuard;
 
    VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
    if ( !pMultiLineEdit )
        return;
 
    sal_uInt16 nPropType = GetPropertyId( PropertyName );
    switch ( nPropType )
    {
        case BASEPROPERTY_LINE_END_FORMAT:
        {
            sal_Int16 nLineEndType = css::awt::LineEndFormat::LINE_FEED;
            OSL_VERIFY( Value >>= nLineEndType );
            switch ( nLineEndType )
            {
            case css::awt::LineEndFormat::CARRIAGE_RETURN:           meLineEndType = LINEEND_CR; break;
            case css::awt::LineEndFormat::LINE_FEED:                 meLineEndType = LINEEND_LF; break;
            case css::awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED: meLineEndType = LINEEND_CRLF; break;
            default: OSL_FAIL( "VCLXMultiLineEdit::setProperty: invalid line end value!" ); break;
            }
        }
        break;
 
        case BASEPROPERTY_READONLY:
        {
            bool b;
            if ( Value >>= b )
                pMultiLineEdit->SetReadOnly( b );
        }
        break;
        case BASEPROPERTY_MAXTEXTLEN:
        {
            sal_Int16 n = sal_Int16();
            if ( Value >>= n )
                pMultiLineEdit->SetMaxTextLen( n );
        }
        break;
        case BASEPROPERTY_HIDEINACTIVESELECTION:
        {
            bool b;
            if ( Value >>= b )
            {
                pMultiLineEdit->EnableFocusSelectionHide( b );
                lcl_setWinBits( pMultiLineEdit, WB_NOHIDESELECTION, !b );
            }
        }
        break;
        default:
        {
            VCLXWindow::setProperty( PropertyName, Value );
        }
    }
}
 
css::uno::Any VCLXMultiLineEdit::getProperty( const OUString& PropertyName )
{
    SolarMutexGuard aGuard;
 
    css::uno::Any aProp;
    VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
    if ( pMultiLineEdit )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch ( nPropType )
        {
            case BASEPROPERTY_LINE_END_FORMAT:
            {
                sal_Int16 nLineEndType = css::awt::LineEndFormat::LINE_FEED;
                switch ( meLineEndType )
                {
                case LINEEND_CR:   nLineEndType = css::awt::LineEndFormat::CARRIAGE_RETURN; break;
                case LINEEND_LF:   nLineEndType = css::awt::LineEndFormat::LINE_FEED; break;
                case LINEEND_CRLF: nLineEndType = css::awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED; break;
                default: OSL_FAIL( "VCLXMultiLineEdit::getProperty: invalid line end value!" ); break;
                }
                aProp <<= nLineEndType;
            }
            break;
 
            case BASEPROPERTY_READONLY:
            {
                aProp <<= pMultiLineEdit->IsReadOnly();
            }
            break;
            case BASEPROPERTY_MAXTEXTLEN:
            {
                aProp <<= static_cast<sal_Int16>(pMultiLineEdit->GetMaxTextLen());
            }
            break;
            default:
            {
                aProp = VCLXWindow::getProperty( PropertyName );
            }
        }
    }
    return aProp;
}
 
void SAL_CALL VCLXMultiLineEdit::setFocus(  )
{
    SolarMutexGuard aGuard;
 
    // don't grab the focus if we already have it. Reason is that the only thing which the edit
    // does is forwarding the focus to its text window. This text window then does a "select all".
    // So if the text window already has the focus, and we give the focus to the multi line
    // edit, then all which happens is that everything is selected.
    // #i27072#
    if ( GetWindow() && !GetWindow()->HasChildPathFocus() )
        GetWindow()->GrabFocus();
}
 
void VCLXMultiLineEdit::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     // FIXME: elide duplication ?
                     BASEPROPERTY_LINE_END_FORMAT,
                     BASEPROPERTY_READONLY,
                     BASEPROPERTY_MAXTEXTLEN,
                     BASEPROPERTY_HIDEINACTIVESELECTION,
                     0);
    VCLXWindow::ImplGetPropertyIds( rIds, true );
}
 
//  class VCLXFileControl
 
VCLXFileControl::VCLXFileControl() : maTextListeners( *this )
{
}
 
VCLXFileControl::~VCLXFileControl()
{
    VclPtr< FileControl > pControl = GetAs< FileControl >();
    if ( pControl )
        pControl->GetEdit().SetModifyHdl( Link<Edit&,void>() );
}
 
css::uno::Any VCLXFileControl::queryInterface( const css::uno::Type & rType )
{
    css::uno::Any aRet = ::cppu::queryInterface( rType,
                                        static_cast< css::awt::XTextComponent* >(this),
                                        static_cast< css::awt::XTextLayoutConstrains* >(this),
                                        static_cast< css::lang::XTypeProvider* >(this) );
    return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
}
 
// css::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXFileControl )
    cppu::UnoType<css::awt::XTextComponent>::get(),
    cppu::UnoType<css::awt::XTextLayoutConstrains>::get(),
    VCLXWindow::getTypes()
IMPL_XTYPEPROVIDER_END
 
void SAL_CALL VCLXFileControl::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
    SolarMutexGuard aGuard;
 
    VclPtr< FileControl > pControl = GetAs< FileControl >();
    if ( !pControl )
        return;
 
    sal_uInt16 nPropType = GetPropertyId( PropertyName );
    switch ( nPropType )
    {
    case BASEPROPERTY_HIDEINACTIVESELECTION:
    {
        bool bValue(false);
        OSL_VERIFY( Value >>= bValue );
 
        lcl_setWinBits( pControl, WB_NOHIDESELECTION, !bValue );
        lcl_setWinBits( &pControl->GetEdit(), WB_NOHIDESELECTION, !bValue );
    }
    break;
 
    default:
        VCLXWindow::setProperty( PropertyName, Value );
        break;
    }
}
 
void VCLXFileControl::SetWindow( const VclPtr< vcl::Window > &pWindow )
{
    VclPtr< FileControl > pPrevFileControl = GetAsDynamic< FileControl >();
    if ( pPrevFileControl )
        pPrevFileControl->SetEditModifyHdl( Link<Edit&,void>() );
 
    FileControl* pNewFileControl = dynamic_cast<FileControl*>( pWindow.get() );
    if ( pNewFileControl )
        pNewFileControl->SetEditModifyHdl( LINK( this, VCLXFileControl, ModifyHdl ) );
 
    VCLXWindow::SetWindow( pWindow );
}
 
void VCLXFileControl::addTextListener( const css::uno::Reference< css::awt::XTextListener > & l )
{
    maTextListeners.addInterface( l );
}
 
void VCLXFileControl::removeTextListener( const css::uno::Reference< css::awt::XTextListener > & l )
{
    maTextListeners.removeInterface( l );
}
 
void VCLXFileControl::setText( const OUString& aText )
{
    SolarMutexGuard aGuard;
 
    VclPtr<vcl::Window> pWindow = GetWindow();
    if ( pWindow )
    {
        pWindow->SetText( aText );
 
        // also in Java a textChanged is triggered, not in VCL.
        // css::awt::Toolkit should be JAVA-compliant...
        ModifyHdl();
    }
}
 
void VCLXFileControl::insertText( const css::awt::Selection& rSel, const OUString& aText )
{
    SolarMutexGuard aGuard;
 
    VclPtr< FileControl > pFileControl = GetAs< FileControl >();
    if ( pFileControl )
    {
        pFileControl->GetEdit().SetSelection( Selection( rSel.Min, rSel.Max ) );
        pFileControl->GetEdit().ReplaceSelected( aText );
    }
}
 
OUString VCLXFileControl::getText()
{
    SolarMutexGuard aGuard;
 
    OUString aText;
    VclPtr<vcl::Window> pWindow = GetWindow();
    if ( pWindow )
        aText = pWindow->GetText();
    return aText;
}
 
OUString VCLXFileControl::getSelectedText()
{
    SolarMutexGuard aGuard;
 
    OUString aText;
    VclPtr< FileControl > pFileControl = GetAs< FileControl >();
    if ( pFileControl)
        aText = pFileControl->GetEdit().GetSelected();
    return aText;
 
}
 
void VCLXFileControl::setSelection( const css::awt::Selection& aSelection )
{
    SolarMutexGuard aGuard;
 
    VclPtr< FileControl > pFileControl = GetAs< FileControl >();
    if ( pFileControl )
        pFileControl->GetEdit().SetSelection( Selection( aSelection.Min, aSelection.Max ) );
}
 
css::awt::Selection VCLXFileControl::getSelection()
{
    SolarMutexGuard aGuard;
 
    css::awt::Selection aSel;
    VclPtr< FileControl > pFileControl = GetAs< FileControl >();
    if ( pFileControl )
    {
        aSel.Min = pFileControl->GetEdit().GetSelection().Min();
        aSel.Max = pFileControl->GetEdit().GetSelection().Max();
    }
    return aSel;
}
 
sal_Bool VCLXFileControl::isEditable()
{
    SolarMutexGuard aGuard;
 
    VclPtr< FileControl > pFileControl = GetAs< FileControl >();
    return pFileControl && !pFileControl->GetEdit().IsReadOnly() && pFileControl->GetEdit().IsEnabled();
}
 
void VCLXFileControl::setEditable( sal_Bool bEditable )
{
    SolarMutexGuard aGuard;
 
    VclPtr< FileControl > pFileControl = GetAs< FileControl >();
    if ( pFileControl )
        pFileControl->GetEdit().SetReadOnly( !bEditable );
}
 
void VCLXFileControl::setMaxTextLen( sal_Int16 nLen )
{
    SolarMutexGuard aGuard;
 
    VclPtr< FileControl > pFileControl = GetAs< FileControl >();
    if ( pFileControl )
        pFileControl->GetEdit().SetMaxTextLen( nLen );
}
 
sal_Int16 VCLXFileControl::getMaxTextLen()
{
    SolarMutexGuard aGuard;
 
    VclPtr< FileControl > pFileControl = GetAs< FileControl >();
    return pFileControl ? pFileControl->GetEdit().GetMaxTextLen() : 0;
}
 
 
IMPL_LINK_NOARG(VCLXFileControl, ModifyHdl, Edit&, void)
{
    ModifyHdl();
}
 
void VCLXFileControl::ModifyHdl()
{
    css::awt::TextEvent aEvent;
    aEvent.Source = static_cast<cppu::OWeakObject*>(this);
    maTextListeners.textChanged( aEvent );
}
 
css::awt::Size VCLXFileControl::getMinimumSize()
{
    SolarMutexGuard aGuard;
 
    css::awt::Size aSz;
    VclPtr< FileControl > pControl = GetAs< FileControl >();
    if ( pControl )
    {
        Size aTmpSize = pControl->GetEdit().CalcMinimumSize();
        aTmpSize.AdjustWidth(pControl->GetButton().CalcMinimumSize().Width() );
        aSz = AWTSize(pControl->CalcWindowSize( aTmpSize ));
    }
    return aSz;
}
 
css::awt::Size VCLXFileControl::getPreferredSize()
{
    css::awt::Size aSz = getMinimumSize();
    aSz.Height += 4;
    return aSz;
}
 
css::awt::Size VCLXFileControl::calcAdjustedSize( const css::awt::Size& rNewSize )
{
    SolarMutexGuard aGuard;
 
    css::awt::Size aSz =rNewSize;
    VclPtr< FileControl > pControl = GetAs< FileControl >();
    if ( pControl )
    {
        css::awt::Size aMinSz = getMinimumSize();
        if ( aSz.Height != aMinSz.Height )
            aSz.Height = aMinSz.Height;
    }
    return aSz;
}
 
css::awt::Size VCLXFileControl::getMinimumSize( sal_Int16 nCols, sal_Int16 )
{
    SolarMutexGuard aGuard;
 
    css::awt::Size aSz;
    VclPtr< FileControl > pControl = GetAs< FileControl >();
    if ( pControl )
    {
        aSz = AWTSize(pControl->GetEdit().CalcSize( nCols ));
        aSz.Width += pControl->GetButton().CalcMinimumSize().Width();
    }
    return aSz;
}
 
void VCLXFileControl::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines )
{
    SolarMutexGuard aGuard;
 
    nCols = 0;
    nLines = 1;
    VclPtr< FileControl > pControl = GetAs< FileControl >();
    if ( pControl )
        nCols = pControl->GetEdit().GetMaxVisChars();
}
 
void VCLXFileControl::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     // FIXME: elide duplication ?
                     BASEPROPERTY_HIDEINACTIVESELECTION,
                     0);
    VCLXWindow::ImplGetPropertyIds( rIds, true );
}
 
 
//  class SVTXFormattedField
 
 
SVTXFormattedField::SVTXFormattedField()
    :bIsStandardSupplier(true)
    ,nKeyToSetDelayed(-1)
{
}
 
 
SVTXFormattedField::~SVTXFormattedField()
{
}
 
 
void SVTXFormattedField::SetWindow( const VclPtr< vcl::Window > &_pWindow )
{
    VCLXSpinField::SetWindow(_pWindow);
    if (GetAs< FormattedField >())
        GetAs< FormattedField >()->SetAutoColor(true);
}
 
 
void SVTXFormattedField::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch (nPropType)
        {
            case BASEPROPERTY_ENFORCE_FORMAT:
            {
                bool bEnable( true );
                if ( Value >>= bEnable )
                    pField->EnableNotANumber( !bEnable );
            }
            break;
 
            case BASEPROPERTY_EFFECTIVE_MIN:
            case BASEPROPERTY_VALUEMIN_DOUBLE:
                SetMinValue(Value);
                break;
 
            case BASEPROPERTY_EFFECTIVE_MAX:
            case BASEPROPERTY_VALUEMAX_DOUBLE:
                SetMaxValue(Value);
                break;
 
            case BASEPROPERTY_EFFECTIVE_DEFAULT:
                SetDefaultValue(Value);
                break;
 
            case BASEPROPERTY_TREATASNUMBER:
            {
                bool b;
                if ( Value >>= b )
                    SetTreatAsNumber(b);
            }
            break;
 
            case BASEPROPERTY_FORMATSSUPPLIER:
                if (!Value.hasValue())
                    setFormatsSupplier(css::uno::Reference< css::util::XNumberFormatsSupplier > (nullptr));
                else
                {
                    css::uno::Reference< css::util::XNumberFormatsSupplier > xNFS;
                    if ( Value >>= xNFS )
                        setFormatsSupplier(xNFS);
                }
                break;
            case BASEPROPERTY_FORMATKEY:
                if (!Value.hasValue())
                    setFormatKey(0);
                else
                {
                    sal_Int32 n = 0;
                    if ( Value >>= n )
                        setFormatKey(n);
                }
                break;
 
            case BASEPROPERTY_EFFECTIVE_VALUE:
            case BASEPROPERTY_VALUE_DOUBLE:
            {
                const css::uno::TypeClass rTC = Value.getValueType().getTypeClass();
                if (rTC != css::uno::TypeClass_STRING)
                    // no string
                    if (rTC != css::uno::TypeClass_DOUBLE)
                        // no double
                        if (Value.hasValue())
                        {   // but a value
                            // try if it is something convertible
                            sal_Int32 nValue = 0;
                            if (!(Value >>= nValue))
                                throw css::lang::IllegalArgumentException();
                            SetValue(css::uno::makeAny(static_cast<double>(nValue)));
                            break;
                        }
 
                SetValue(Value);
            }
            break;
            case BASEPROPERTY_VALUESTEP_DOUBLE:
            {
                double d = 0.0;
                if ( Value >>= d )
                     pField->SetSpinSize( d );
                else
                {
                    sal_Int32 n = 0;
                    if ( Value >>= n )
                         pField->SetSpinSize( n );
                }
            }
            break;
            case BASEPROPERTY_DECIMALACCURACY:
            {
                sal_Int32 n = 0;
                if ( Value >>= n )
                     pField->SetDecimalDigits( static_cast<sal_uInt16>(n) );
            }
            break;
            case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
            {
                    bool b;
                    if ( Value >>= b )
                     pField->SetThousandsSep( b );
            }
            break;
 
            default:
                VCLXSpinField::setProperty( PropertyName, Value );
        }
 
        if (BASEPROPERTY_TEXTCOLOR == nPropType)
        {   // after setting a new text color, think again about the AutoColor flag of the control
            // 17.05.2001 - 86859 - frank.schoenheit@germany.sun.com
            pField->SetAutoColor(!Value.hasValue());
        }
    }
    else
        VCLXSpinField::setProperty( PropertyName, Value );
}
 
 
css::uno::Any SVTXFormattedField::getProperty( const OUString& PropertyName )
{
    SolarMutexGuard aGuard;
 
    css::uno::Any aReturn;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch (nPropType)
        {
            case BASEPROPERTY_EFFECTIVE_MIN:
            case BASEPROPERTY_VALUEMIN_DOUBLE:
                aReturn = GetMinValue();
                break;
 
            case BASEPROPERTY_EFFECTIVE_MAX:
            case BASEPROPERTY_VALUEMAX_DOUBLE:
                aReturn = GetMaxValue();
                break;
 
            case BASEPROPERTY_EFFECTIVE_DEFAULT:
                aReturn = GetDefaultValue();
                break;
 
            case BASEPROPERTY_TREATASNUMBER:
                aReturn <<= GetTreatAsNumber();
                break;
 
            case BASEPROPERTY_EFFECTIVE_VALUE:
            case BASEPROPERTY_VALUE_DOUBLE:
                aReturn = GetValue();
                break;
 
            case BASEPROPERTY_VALUESTEP_DOUBLE:
                aReturn <<= pField->GetSpinSize();
                break;
 
            case BASEPROPERTY_DECIMALACCURACY:
                aReturn <<= pField->GetDecimalDigits();
                break;
 
            case BASEPROPERTY_FORMATSSUPPLIER:
            {
                if (!bIsStandardSupplier)
                {   // ansonsten void
                    css::uno::Reference< css::util::XNumberFormatsSupplier >  xSupplier = m_xCurrentSupplier.get();
                    aReturn <<= xSupplier;
                }
            }
            break;
 
            case BASEPROPERTY_FORMATKEY:
            {
                if (!bIsStandardSupplier)
                    aReturn <<= getFormatKey();
            }
            break;
 
            default:
                aReturn = VCLXSpinField::getProperty(PropertyName);
        }
    }
    return aReturn;
}
 
css::uno::Any SVTXFormattedField::convertEffectiveValue(const css::uno::Any& rValue)
{
    css::uno::Any aReturn;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (!pField)
        return aReturn;
 
    switch (rValue.getValueType().getTypeClass())
    {
        case css::uno::TypeClass_DOUBLE:
            if (pField->TreatingAsNumber())
            {
                double d = 0.0;
                rValue >>= d;
                aReturn <<= d;
            }
            else
            {
                SvNumberFormatter* pFormatter = pField->GetFormatter();
                if (!pFormatter)
                    pFormatter = pField->StandardFormatter();
                    // should never fail
 
                Color* pDum;
                double d = 0.0;
                rValue >>= d;
                OUString sConverted;
                pFormatter->GetOutputString(d, 0, sConverted, &pDum);
                aReturn <<= sConverted;
            }
            break;
        case css::uno::TypeClass_STRING:
        {
            OUString aStr;
            rValue >>= aStr;
            if (pField->TreatingAsNumber())
            {
                SvNumberFormatter* pFormatter = pField->GetFormatter();
                if (!pFormatter)
                    pFormatter = pField->StandardFormatter();
 
                double dVal;
                sal_uInt32 nTestFormat(0);
                if (!pFormatter->IsNumberFormat(aStr, nTestFormat, dVal))
                    aReturn.clear();
                aReturn <<= dVal;
            }
            else
                aReturn <<= aStr;
        }
        break;
        default:
            aReturn.clear();
            break;
    }
    return aReturn;
}
 
 
void SVTXFormattedField::SetMinValue(const css::uno::Any& rValue)
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (!pField)
        return;
 
    switch (rValue.getValueType().getTypeClass())
 
    {
        case css::uno::TypeClass_DOUBLE:
        {
            double d = 0.0;
            rValue >>= d;
            pField->SetMinValue(d);
        }
            break;
        default:
            DBG_ASSERT(rValue.getValueType().getTypeClass() == css::uno::TypeClass_VOID, "SVTXFormattedField::SetMinValue : invalid argument (an exception will be thrown) !");
            if ( rValue.getValueType().getTypeClass() != css::uno::TypeClass_VOID )
 
            {
                throw css::lang::IllegalArgumentException();
            }
            pField->ClearMinValue();
            break;
    }
}
 
 
css::uno::Any SVTXFormattedField::GetMinValue()
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (!pField || !pField->HasMinValue())
        return css::uno::Any();
 
    css::uno::Any aReturn;
    aReturn <<= pField->GetMinValue();
    return aReturn;
}
 
 
void SVTXFormattedField::SetMaxValue(const css::uno::Any& rValue)
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (!pField)
        return;
 
    switch (rValue.getValueType().getTypeClass())
 
    {
        case css::uno::TypeClass_DOUBLE:
        {
            double d = 0.0;
            rValue >>= d;
            pField->SetMaxValue(d);
        }
            break;
        default:
            if (rValue.getValueType().getTypeClass() != css::uno::TypeClass_VOID)
 
            {
                throw css::lang::IllegalArgumentException();
            }
            pField->ClearMaxValue();
            break;
    }
}
 
 
css::uno::Any SVTXFormattedField::GetMaxValue()
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (!pField || !pField->HasMaxValue())
        return css::uno::Any();
 
    css::uno::Any aReturn;
    aReturn <<= pField->GetMaxValue();
    return aReturn;
}
 
 
void SVTXFormattedField::SetDefaultValue(const css::uno::Any& rValue)
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (!pField)
        return;
 
    css::uno::Any aConverted = convertEffectiveValue(rValue);
 
    switch (aConverted.getValueType().getTypeClass())
 
    {
        case css::uno::TypeClass_DOUBLE:
        {
            double d = 0.0;
            aConverted >>= d;
            pField->SetDefaultValue(d);
        }
        break;
        case css::uno::TypeClass_STRING:
        {
            OUString aStr;
            aConverted >>= aStr;
            pField->SetDefaultText( aStr );
        }
        break;
        default:
            pField->EnableEmptyField(true);
                // only void accepted
            break;
    }
}
 
 
css::uno::Any SVTXFormattedField::GetDefaultValue()
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (!pField || pField->IsEmptyFieldEnabled())
        return css::uno::Any();
 
    css::uno::Any aReturn;
    if (pField->TreatingAsNumber())
        aReturn <<= pField->GetDefaultValue();
    else
        aReturn <<= pField->GetDefaultText();
    return aReturn;
}
 
 
bool SVTXFormattedField::GetTreatAsNumber()
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (pField)
        return pField->TreatingAsNumber();
 
    return true;
}
 
 
void SVTXFormattedField::SetTreatAsNumber(bool bSet)
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (pField)
        pField->TreatAsNumber(bSet);
}
 
 
css::uno::Any SVTXFormattedField::GetValue()
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (!pField)
        return css::uno::Any();
 
    css::uno::Any aReturn;
    if (!pField->TreatingAsNumber())
    {
        OUString sText = pField->GetTextValue();
        aReturn <<= sText;
    }
    else
    {
        if (!pField->GetText().isEmpty())    // empty is returned as void by default
            aReturn <<= pField->GetValue();
    }
 
    return aReturn;
}
 
 
void SVTXFormattedField::SetValue(const css::uno::Any& rValue)
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (!pField)
        return;
 
    if (!rValue.hasValue())
    {
        pField->SetText("");
    }
    else
    {
        if (rValue.getValueType().getTypeClass() == css::uno::TypeClass_DOUBLE )
        {
            double d = 0.0;
            rValue >>= d;
            pField->SetValue(d);
        }
        else
        {
            DBG_ASSERT(rValue.getValueType().getTypeClass() == css::uno::TypeClass_STRING, "SVTXFormattedField::SetValue : invalid argument !");
 
            OUString sText;
            rValue >>= sText;
            if (!pField->TreatingAsNumber())
                pField->SetTextFormatted(sText);
            else
                pField->SetTextValue(sText);
        }
    }
//  NotifyTextListeners();
}
 
 
void SVTXFormattedField::setFormatsSupplier(const css::uno::Reference< css::util::XNumberFormatsSupplier > & xSupplier)
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
 
    SvNumberFormatsSupplierObj* pNew = nullptr;
    if (!xSupplier.is())
    {
        if (pField)
        {
            pNew = new SvNumberFormatsSupplierObj(pField->StandardFormatter());
            bIsStandardSupplier = true;
        }
    }
    else
    {
        pNew = SvNumberFormatsSupplierObj::getImplementation(xSupplier);
        bIsStandardSupplier = false;
    }
 
    if (!pNew)
        return;     // TODO : how to process ?
 
    m_xCurrentSupplier = pNew;
    if (!pField)
        return;
 
    // save the actual value
    css::uno::Any aCurrent = GetValue();
    pField->SetFormatter(m_xCurrentSupplier->GetNumberFormatter(), false);
    if (nKeyToSetDelayed != -1)
    {
        pField->SetFormatKey(nKeyToSetDelayed);
        nKeyToSetDelayed = -1;
    }
    SetValue(aCurrent);
    NotifyTextListeners();
}
 
 
sal_Int32 SVTXFormattedField::getFormatKey() const
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetFormatKey() : 0;
}
 
 
void SVTXFormattedField::setFormatKey(sal_Int32 nKey)
{
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if (!pField)
        return;
 
    if (pField->GetFormatter())
        pField->SetFormatKey(nKey);
    else
    {
        // probably I am in a block, in which first the key and next the formatter will be set,
        // initially this happens quite certain, as the properties are set in alphabetic sequence,
        // and the FormatsSupplier is processed before the FormatKey
        nKeyToSetDelayed = nKey;
    }
    NotifyTextListeners();
}
 
 
void SVTXFormattedField::NotifyTextListeners()
{
    if ( GetTextListeners().getLength() )
    {
        css::awt::TextEvent aEvent;
        aEvent.Source = static_cast<cppu::OWeakObject*>(this);
        GetTextListeners().textChanged( aEvent );
    }
}
 
void SVTXFormattedField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     // FIXME: elide duplication ?
                     BASEPROPERTY_EFFECTIVE_MIN,
                     BASEPROPERTY_VALUEMIN_DOUBLE,
                     BASEPROPERTY_EFFECTIVE_MAX,
                     BASEPROPERTY_VALUEMAX_DOUBLE,
                     BASEPROPERTY_EFFECTIVE_DEFAULT,
                     BASEPROPERTY_TREATASNUMBER,
                     BASEPROPERTY_EFFECTIVE_VALUE,
                     BASEPROPERTY_VALUE_DOUBLE,
                     BASEPROPERTY_VALUESTEP_DOUBLE,
                     BASEPROPERTY_DECIMALACCURACY,
                     BASEPROPERTY_FORMATSSUPPLIER,
                     BASEPROPERTY_NUMSHOWTHOUSANDSEP,
                     BASEPROPERTY_FORMATKEY,
                     BASEPROPERTY_TREATASNUMBER,
                     BASEPROPERTY_ENFORCE_FORMAT,
                     0);
    VCLXWindow::ImplGetPropertyIds( rIds, true );
    VCLXSpinField::ImplGetPropertyIds( rIds );
}
 
 
//  class SVTXRoadmap
 
using namespace svt;
 
SVTXRoadmap::SVTXRoadmap() : maItemListeners( *this )
{
}
 
SVTXRoadmap::~SVTXRoadmap()
{
}
 
void SVTXRoadmap::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
    switch ( rVclWindowEvent.GetId() )
    {
        case VclEventId::RoadmapItemSelected:
        {
            SolarMutexGuard aGuard;
            VclPtr<::svt::ORoadmap> pField = GetAs< svt::ORoadmap >();
            if ( pField )
            {
                sal_Int16 CurItemID = pField->GetCurrentRoadmapItemID();
                css::awt::ItemEvent aEvent;
                aEvent.Selected = CurItemID;
                aEvent.Highlighted = CurItemID;
                aEvent.ItemId = CurItemID;
                maItemListeners.itemStateChanged( aEvent );
            }
        }
        break;
        default:
            SVTXRoadmap_Base::ProcessWindowEvent( rVclWindowEvent );
            break;
    }
}
 
 
void SVTXRoadmap::propertyChange( const css::beans::PropertyChangeEvent& evt )
{
    SolarMutexGuard aGuard;
    VclPtr<::svt::ORoadmap> pField = GetAs< svt::ORoadmap >();
    if ( !pField )
        return;
 
    css::uno::Reference< css::uno::XInterface > xRoadmapItem;
    xRoadmapItem = evt.Source;
    sal_Int32 nID = 0;
    css::uno::Reference< css::beans::XPropertySet > xPropertySet( xRoadmapItem, css::uno::UNO_QUERY );
    css::uno::Any aValue = xPropertySet->getPropertyValue("ID");
    aValue >>= nID;
 
    OUString sPropertyName = evt.PropertyName;
    if ( sPropertyName == "Enabled" )
    {
        bool bEnable = false;
        evt.NewValue >>= bEnable;
        pField->EnableRoadmapItem( static_cast<RoadmapTypes::ItemId>(nID) , bEnable );
    }
    else if ( sPropertyName == "Label" )
    {
        OUString sLabel;
        evt.NewValue >>= sLabel;
        pField->ChangeRoadmapItemLabel( static_cast<RoadmapTypes::ItemId>(nID) , sLabel );
    }
    else if  ( sPropertyName == "ID" )
    {
        sal_Int32 nNewID = 0;
        evt.NewValue >>= nNewID;
        evt.OldValue >>= nID;
        pField->ChangeRoadmapItemID( static_cast<RoadmapTypes::ItemId>(nID), static_cast<RoadmapTypes::ItemId>(nNewID) );
    }
//    else
        // TODO handle Interactive appropriately
}
 
 
void SVTXRoadmap::addItemListener( const css::uno::Reference< css::awt::XItemListener >& l )
{
    maItemListeners.addInterface( l );
}
 
void SVTXRoadmap::removeItemListener( const css::uno::Reference< css::awt::XItemListener >& l )
{
    maItemListeners.removeInterface( l );
}
 
RMItemData SVTXRoadmap::GetRMItemData( const css::container::ContainerEvent& _rEvent )
{
    RMItemData aCurRMItemData;
    css::uno::Reference< css::uno::XInterface > xRoadmapItem;
    _rEvent.Element >>= xRoadmapItem;
    css::uno::Reference< css::beans::XPropertySet > xPropertySet( xRoadmapItem, css::uno::UNO_QUERY );
    if ( xPropertySet.is() )
    {
        css::uno::Any aValue = xPropertySet->getPropertyValue("Label");
        aValue >>= aCurRMItemData.Label;
        aValue = xPropertySet->getPropertyValue("ID");
        aValue >>= aCurRMItemData.n_ID;
        aValue = xPropertySet->getPropertyValue("Enabled");
        aValue >>= aCurRMItemData.b_Enabled;
    }
    else
    {
        aCurRMItemData.b_Enabled = false;
        aCurRMItemData.n_ID = 0;
    }
    return aCurRMItemData;
}
 
void SVTXRoadmap::elementInserted( const css::container::ContainerEvent& _rEvent )
{
    SolarMutexGuard aGuard;
    VclPtr<::svt::ORoadmap> pField = GetAs< svt::ORoadmap >();
    if ( pField )
    {
        RMItemData CurItemData = GetRMItemData(  _rEvent );
        sal_Int32 InsertIndex = 0;
        _rEvent.Accessor >>= InsertIndex;
        pField->InsertRoadmapItem( InsertIndex, CurItemData.Label, static_cast<RoadmapTypes::ItemId>(CurItemData.n_ID), CurItemData.b_Enabled );
    }
}
 
void SVTXRoadmap::elementRemoved( const css::container::ContainerEvent& _rEvent )
{
    SolarMutexGuard aGuard;
    VclPtr<::svt::ORoadmap> pField = GetAs< svt::ORoadmap >();
    if ( pField )
    {
        sal_Int32 DelIndex = 0;
        _rEvent.Accessor >>= DelIndex;
        pField->DeleteRoadmapItem(DelIndex);
    }
}
 
void SVTXRoadmap::elementReplaced( const css::container::ContainerEvent& _rEvent )
{
    SolarMutexGuard aGuard;
    VclPtr<::svt::ORoadmap> pField = GetAs< svt::ORoadmap >();
    if ( pField )
    {
        RMItemData CurItemData = GetRMItemData(  _rEvent );
        sal_Int32 ReplaceIndex = 0;
        _rEvent.Accessor >>= ReplaceIndex;
        pField->ReplaceRoadmapItem( ReplaceIndex, CurItemData.Label, static_cast<RoadmapTypes::ItemId>(CurItemData.n_ID), CurItemData.b_Enabled );
    }
}
 
 
void SVTXRoadmap::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
    SolarMutexGuard aGuard;
 
    VclPtr<::svt::ORoadmap> pField = GetAs< svt::ORoadmap >();
    if ( pField )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch (nPropType)
        {
            case BASEPROPERTY_COMPLETE:
            {
                bool b = false;
                Value >>= b;
                pField->SetRoadmapComplete( b);
            }
            break;
 
            case BASEPROPERTY_ACTIVATED:
            {
                   bool b = false;
                Value >>= b;
                pField->SetRoadmapInteractive( b);
            }
            break;
 
            case BASEPROPERTY_CURRENTITEMID:
            {
                   sal_Int32 nId = 0;
                Value >>= nId;
                pField->SelectRoadmapItemByID( static_cast<RoadmapTypes::ItemId>(nId) );
            }
            break;
 
            case BASEPROPERTY_TEXT:
            {
                   OUString aStr;
                Value >>= aStr;
                pField->SetText( aStr );
                pField->Invalidate();
            }
            break;
 
            default:
                SVTXRoadmap_Base::setProperty( PropertyName, Value );
                break;
        }
 
    }
    else
        SVTXRoadmap_Base::setProperty( PropertyName, Value );
}
 
 
css::uno::Any SVTXRoadmap::getProperty( const OUString& PropertyName )
{
    SolarMutexGuard aGuard;
 
    css::uno::Any aReturn;
 
    VclPtr<::svt::ORoadmap> pField = GetAs< svt::ORoadmap >();
    if ( pField )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch (nPropType)
        {
            case BASEPROPERTY_COMPLETE:
                aReturn <<= pField->IsRoadmapComplete();
                break;
            case BASEPROPERTY_ACTIVATED:
                aReturn <<= pField->IsRoadmapInteractive();
                break;
            case BASEPROPERTY_CURRENTITEMID:
                aReturn <<= pField->GetCurrentRoadmapItemID();
                break;
            default:
                aReturn = SVTXRoadmap_Base::getProperty(PropertyName);
                break;
        }
    }
    return aReturn;
}
 
void SVTXRoadmap::ImplSetNewImage()
{
    OSL_PRECOND( GetWindow(), "SVTXRoadmap::ImplSetNewImage: window is required to be not-NULL!" );
    VclPtr< ::svt::ORoadmap > pButton = GetAs< ::svt::ORoadmap >();
    pButton->SetRoadmapBitmap( GetImage().GetBitmapEx() );
}
 
void SVTXRoadmap::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_COMPLETE,
                     BASEPROPERTY_ACTIVATED,
                     BASEPROPERTY_CURRENTITEMID,
                     BASEPROPERTY_TEXT,
                     0);
    VCLXWindow::ImplGetPropertyIds( rIds, true );
    VCLXGraphicControl::ImplGetPropertyIds( rIds );
}
 
 
//  class SVTXNumericField
 
SVTXNumericField::SVTXNumericField()
{
}
 
SVTXNumericField::~SVTXNumericField()
{
}
 
css::uno::Any SVTXNumericField::queryInterface( const css::uno::Type & rType )
{
    css::uno::Any aRet = ::cppu::queryInterface( rType,
                                        static_cast< css::awt::XNumericField* >(this),
                                        static_cast< css::lang::XTypeProvider* >(this) );
    return (aRet.hasValue() ? aRet : SVTXFormattedField::queryInterface( rType ));
}
 
// css::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( SVTXNumericField )
    cppu::UnoType<css::awt::XNumericField>::get(),
    SVTXFormattedField::getTypes()
IMPL_XTYPEPROVIDER_END
 
 
void SVTXNumericField::setValue( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetValue( Value );
}
 
double SVTXNumericField::getValue()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetValue() : 0;
}
 
void SVTXNumericField::setMin( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetMinValue( Value );
}
 
double SVTXNumericField::getMin()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetMinValue() : 0;
}
 
void SVTXNumericField::setMax( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetMaxValue( Value );
}
 
double SVTXNumericField::getMax()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetMaxValue() : 0;
}
 
void SVTXNumericField::setFirst( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetSpinFirst( Value );
}
 
double SVTXNumericField::getFirst()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetSpinFirst() : 0;
}
 
void SVTXNumericField::setLast( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetSpinLast( Value );
}
 
double SVTXNumericField::getLast()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetSpinLast() : 0;
}
 
void SVTXNumericField::setSpinSize( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetSpinSize( Value );
}
 
double SVTXNumericField::getSpinSize()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetSpinSize() : 0;
}
 
void SVTXNumericField::setDecimalDigits( sal_Int16 Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetDecimalDigits( Value );
}
 
sal_Int16 SVTXNumericField::getDecimalDigits()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetDecimalDigits() : 0;
}
 
void SVTXNumericField::setStrictFormat( sal_Bool bStrict )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetStrictFormat( bStrict );
}
 
sal_Bool SVTXNumericField::isStrictFormat()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField && pField->IsStrictFormat();
}
 
void SVTXNumericField::GetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
    SVTXFormattedField::ImplGetPropertyIds( rIds );
}
 
 
//  class SVTXCurrencyField
 
SVTXCurrencyField::SVTXCurrencyField()
{
}
 
SVTXCurrencyField::~SVTXCurrencyField()
{
}
 
css::uno::Any SVTXCurrencyField::queryInterface( const css::uno::Type & rType )
{
    css::uno::Any aRet = ::cppu::queryInterface( rType,
                                        static_cast< css::awt::XCurrencyField* >(this),
                                        static_cast< css::lang::XTypeProvider* >(this) );
    return (aRet.hasValue() ? aRet : SVTXFormattedField::queryInterface( rType ));
}
 
// css::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( SVTXCurrencyField )
    cppu::UnoType<css::awt::XCurrencyField>::get(),
    SVTXFormattedField::getTypes()
IMPL_XTYPEPROVIDER_END
 
void SVTXCurrencyField::setValue( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetValue( Value );
}
 
double SVTXCurrencyField::getValue()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetValue() : 0;
}
 
void SVTXCurrencyField::setMin( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetMinValue( Value );
}
 
double SVTXCurrencyField::getMin()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetMinValue() : 0;
}
 
void SVTXCurrencyField::setMax( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetMaxValue( Value );
}
 
double SVTXCurrencyField::getMax()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetMaxValue() : 0;
}
 
void SVTXCurrencyField::setFirst( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetSpinFirst( Value );
}
 
double SVTXCurrencyField::getFirst()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetSpinFirst() : 0;
}
 
void SVTXCurrencyField::setLast( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetSpinLast( Value );
}
 
double SVTXCurrencyField::getLast()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetSpinLast() : 0;
}
 
void SVTXCurrencyField::setSpinSize( double Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetSpinSize( Value );
}
 
double SVTXCurrencyField::getSpinSize()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetSpinSize() : 0;
}
 
void SVTXCurrencyField::setDecimalDigits( sal_Int16 Value )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetDecimalDigits( Value );
}
 
sal_Int16 SVTXCurrencyField::getDecimalDigits()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField ? pField->GetDecimalDigits() : 0;
}
 
void SVTXCurrencyField::setStrictFormat( sal_Bool bStrict )
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    if ( pField )
        pField->SetStrictFormat( bStrict );
}
 
sal_Bool SVTXCurrencyField::isStrictFormat()
{
    SolarMutexGuard aGuard;
 
    VclPtr<FormattedField> pField = GetAs< FormattedField >();
    return pField && pField->IsStrictFormat();
}
 
void SVTXCurrencyField::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
    SolarMutexGuard aGuard;
 
    VclPtr< DoubleCurrencyField > pField = GetAs< DoubleCurrencyField >();
    if ( pField )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch (nPropType)
        {
            case BASEPROPERTY_CURRENCYSYMBOL:
            {
                OUString aStr;
                Value >>= aStr;
                pField->setCurrencySymbol( aStr );
            }
            break;
            case BASEPROPERTY_CURSYM_POSITION:
            {
                bool b = false;
                Value >>= b;
                pField->setPrependCurrSym(b);
            }
            break;
 
            default:
                SVTXFormattedField::setProperty(PropertyName, Value);
        }
    }
    else
        SVTXFormattedField::setProperty(PropertyName, Value);
}
 
css::uno::Any SVTXCurrencyField::getProperty( const OUString& PropertyName )
{
    SolarMutexGuard aGuard;
 
    css::uno::Any aReturn;
 
    VclPtr< DoubleCurrencyField > pField = GetAs< DoubleCurrencyField >();
    if ( pField )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch (nPropType)
        {
            case BASEPROPERTY_CURRENCYSYMBOL:
            {
                aReturn <<= pField->getCurrencySymbol();
            }
            break;
            case BASEPROPERTY_CURSYM_POSITION:
            {
                aReturn <<= pField->getPrependCurrSym();
            }
            break;
            default:
                return SVTXFormattedField::getProperty(PropertyName);
        }
    }
    return SVTXFormattedField::getProperty(PropertyName);
}
 
void SVTXCurrencyField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_CURRENCYSYMBOL,
                     BASEPROPERTY_CURSYM_POSITION,
                     0);
    SVTXFormattedField::ImplGetPropertyIds( rIds );
}
 
 
//  class VCLXProgressBar
 
 
VCLXProgressBar::VCLXProgressBar()
            :m_nValue(0)
            ,m_nValueMin(0)
            ,m_nValueMax(100)
{
}
 
VCLXProgressBar::~VCLXProgressBar()
{
}
 
void VCLXProgressBar::ImplUpdateValue()
{
    VclPtr< ProgressBar > pProgressBar = GetAs< ProgressBar >();
    if ( !pProgressBar )
        return;
 
    sal_Int32 nVal;
    sal_Int32 nValMin;
    sal_Int32 nValMax;
 
    // check min and max
    if (m_nValueMin < m_nValueMax)
    {
        nValMin = m_nValueMin;
        nValMax = m_nValueMax;
    }
    else
    {
        nValMin = m_nValueMax;
        nValMax = m_nValueMin;
    }
 
    // check value
    if (m_nValue < nValMin)
    {
        nVal = nValMin;
    }
    else if (m_nValue > nValMax)
    {
        nVal = nValMax;
    }
    else
    {
        nVal = m_nValue;
    }
 
    // calculate percent
    sal_Int32 nPercent;
    if (nValMin != nValMax)
    {
        nPercent = 100 * (nVal - nValMin) / (nValMax - nValMin);
    }
    else
    {
        nPercent = 0;
    }
 
    // set progressbar value
    pProgressBar->SetValue( static_cast<sal_uInt16>(nPercent) );
}
 
// css::uno::XInterface
css::uno::Any VCLXProgressBar::queryInterface( const css::uno::Type & rType )
{
    css::uno::Any aRet = ::cppu::queryInterface( rType,
                                        static_cast< css::awt::XProgressBar* >(this),
                                        static_cast< css::lang::XTypeProvider* >(this) );
    return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
}
 
// css::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXProgressBar )
    cppu::UnoType<css::awt::XProgressBar>::get(),
    VCLXWindow::getTypes()
IMPL_XTYPEPROVIDER_END
 
// css::awt::XProgressBar
void VCLXProgressBar::setForegroundColor( sal_Int32 nColor )
{
    SolarMutexGuard aGuard;
 
    VclPtr<vcl::Window> pWindow = GetWindow();
    if ( pWindow )
    {
        pWindow->SetControlForeground( Color(nColor) );
    }
}
 
void VCLXProgressBar::setBackgroundColor( sal_Int32 nColor )
{
    SolarMutexGuard aGuard;
 
    VclPtr<vcl::Window> pWindow = GetWindow();
    if ( pWindow )
    {
        Color aColor = Color( nColor );
        pWindow->SetBackground( aColor );
        pWindow->SetControlBackground( aColor );
        pWindow->Invalidate();
    }
}
 
void VCLXProgressBar::setValue( sal_Int32 nValue )
{
    SolarMutexGuard aGuard;
 
    m_nValue = nValue;
    ImplUpdateValue();
}
 
void VCLXProgressBar::setRange( sal_Int32 nMin, sal_Int32 nMax )
{
    SolarMutexGuard aGuard;
 
    if ( nMin < nMax )
    {
        // take correct min and max
        m_nValueMin = nMin;
        m_nValueMax = nMax;
    }
    else
    {
        // change min and max
        m_nValueMin = nMax;
        m_nValueMax = nMin;
    }
 
    ImplUpdateValue();
}
 
sal_Int32 VCLXProgressBar::getValue()
{
    SolarMutexGuard aGuard;
 
    return m_nValue;
}
 
// css::awt::VclWindowPeer
void VCLXProgressBar::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
    SolarMutexGuard aGuard;
 
    VclPtr< ProgressBar > pProgressBar = GetAs< ProgressBar >();
    if ( !pProgressBar )
        return;
 
    sal_uInt16 nPropType = GetPropertyId( PropertyName );
    switch ( nPropType )
    {
        case BASEPROPERTY_PROGRESSVALUE:
        {
            if ( Value >>= m_nValue )
                ImplUpdateValue();
        }
        break;
        case BASEPROPERTY_PROGRESSVALUE_MIN:
        {
            if ( Value >>= m_nValueMin )
                ImplUpdateValue();
        }
        break;
        case BASEPROPERTY_PROGRESSVALUE_MAX:
        {
            if ( Value >>= m_nValueMax )
                ImplUpdateValue();
        }
        break;
        case BASEPROPERTY_FILLCOLOR:
        {
            VclPtr<vcl::Window> pWindow = GetWindow();
            if ( pWindow )
            {
                bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID;
 
                if ( bVoid )
                {
                    pWindow->SetControlForeground();
                }
                else
                {
                    sal_Int32 nColor = 0;
                    if ( Value >>= nColor )
                    {
                        Color aColor = Color( nColor );
                        pWindow->SetControlForeground( aColor );
                    }
                }
            }
        }
        break;
        default:
            VCLXWindow::setProperty( PropertyName, Value );
            break;
    }
}
 
css::uno::Any VCLXProgressBar::getProperty( const OUString& PropertyName )
{
    SolarMutexGuard aGuard;
 
    css::uno::Any aProp;
    VclPtr< ProgressBar > pProgressBar = GetAs< ProgressBar >();
    if ( pProgressBar )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch ( nPropType )
        {
            case BASEPROPERTY_PROGRESSVALUE:
            {
                 aProp <<= m_nValue;
            }
            break;
            case BASEPROPERTY_PROGRESSVALUE_MIN:
            {
                 aProp <<= m_nValueMin;
            }
            break;
            case BASEPROPERTY_PROGRESSVALUE_MAX:
            {
                 aProp <<= m_nValueMax;
            }
            break;
            default:
                aProp = VCLXWindow::getProperty( PropertyName );
                break;
        }
    }
    return aProp;
}
 
void VCLXProgressBar::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_PROGRESSVALUE,
                     BASEPROPERTY_PROGRESSVALUE_MIN,
                     BASEPROPERTY_PROGRESSVALUE_MAX,
                     BASEPROPERTY_FILLCOLOR,
                     0);
    VCLXWindow::ImplGetPropertyIds( rIds, true );
}
 
 
//  class SVTXDateField
 
SVTXDateField::SVTXDateField()
    :VCLXDateField()
{
}
 
SVTXDateField::~SVTXDateField()
{
}
 
void SAL_CALL SVTXDateField::setProperty( const OUString& PropertyName, const css::uno::Any& Value )
{
    VCLXDateField::setProperty( PropertyName, Value );
 
    // some properties need to be forwarded to the sub edit, too
    SolarMutexGuard g;
    VclPtr< Edit > pSubEdit = GetWindow() ? static_cast< Edit* >( GetWindow().get() )->GetSubEdit() : nullptr;
    if ( !pSubEdit )
        return;
 
    switch ( GetPropertyId( PropertyName ) )
    {
    case BASEPROPERTY_TEXTLINECOLOR:
        if ( !Value.hasValue() )
            pSubEdit->SetTextLineColor();
        else
        {
            sal_Int32 nColor = 0;
            if ( Value >>= nColor )
                pSubEdit->SetTextLineColor( Color( nColor ) );
        }
        break;
    }
}
 
void SVTXDateField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_TEXTLINECOLOR,
                     0);
    VCLXDateField::ImplGetPropertyIds( rIds );
}
 
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

V614 Uninitialized variable 'b' used. Consider checking the first actual argument of the 'SetThousandsSep' function.

V614 Uninitialized variable 'b' used. Consider checking the first actual argument of the 'SetTreatAsNumber' function.

V614 Uninitialized variable 'b' used. Consider checking the first actual argument of the 'EnableFocusSelectionHide' function.

V614 Uninitialized variable 'b' used. Consider checking the first actual argument of the 'SetReadOnly' function.

V547 Expression '!bValue' is always true.

V547 Expression '!bEnable' is always false.

V547 Expression '!bValue' is always true.