diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /toolkit/source/awt | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
25 files changed, 19998 insertions, 0 deletions
diff --git a/toolkit/source/awt/animatedimagespeer.cxx b/toolkit/source/awt/animatedimagespeer.cxx new file mode 100644 index 000000000..b542b564b --- /dev/null +++ b/toolkit/source/awt/animatedimagespeer.cxx @@ -0,0 +1,476 @@ +/* -*- 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 <awt/animatedimagespeer.hxx> +#include <toolkit/helper/property.hxx> + +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/graphic/GraphicProvider.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/awt/ImageScaleMode.hpp> + +#include <comphelper/namedvaluecollection.hxx> +#include <comphelper/processfactory.hxx> +#include <o3tl/safeint.hxx> +#include <tools/diagnose_ex.h> +#include <tools/urlobj.hxx> +#include <vcl/toolkit/throbber.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> + +#include <limits> +#include <string_view> + +namespace toolkit +{ + + + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::lang::EventObject; + using ::com::sun::star::container::ContainerEvent; + using ::com::sun::star::awt::XAnimatedImages; + using ::com::sun::star::awt::Size; + using ::com::sun::star::graphic::XGraphicProvider; + using ::com::sun::star::beans::XPropertySet; + using ::com::sun::star::graphic::XGraphic; + + namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode; + + //= helper + + namespace + { + + OUString lcl_getHighContrastURL( OUString const& i_imageURL ) + { + INetURLObject aURL( i_imageURL ); + if ( aURL.GetProtocol() != INetProtocol::PrivSoffice ) + { + OSL_VERIFY( aURL.insertName( u"sifr", false, 0 ) ); + return aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ); + } + // the private: scheme is not considered to be hierarchical by INetURLObject, so manually insert the + // segment + const sal_Int32 separatorPos = i_imageURL.indexOf( '/' ); + ENSURE_OR_RETURN( separatorPos != -1, "lcl_getHighContrastURL: unsupported URL scheme - cannot automatically determine HC version!", i_imageURL ); + + OUString composer = OUString::Concat(i_imageURL.subView(0, separatorPos)) + "/sifr" + + i_imageURL.subView(separatorPos); + return composer; + } + + + bool lcl_ensureImage_throw( Reference< XGraphicProvider > const& i_graphicProvider, const bool i_isHighContrast, const AnimatedImagesPeer::CachedImage& i_cachedImage ) + { + if ( !i_cachedImage.xGraphic.is() ) + { + ::comphelper::NamedValueCollection aMediaProperties; + if ( i_isHighContrast ) + { + // try (to find) the high-contrast version of the graphic first + aMediaProperties.put( "URL", lcl_getHighContrastURL( i_cachedImage.sImageURL ) ); + i_cachedImage.xGraphic = i_graphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ); + } + if ( !i_cachedImage.xGraphic.is() ) + { + aMediaProperties.put( "URL", i_cachedImage.sImageURL ); + i_cachedImage.xGraphic = i_graphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ); + } + } + return i_cachedImage.xGraphic.is(); + } + + + Size lcl_getGraphicSizePixel( Reference< XGraphic > const& i_graphic ) + { + Size aSizePixel; + try + { + if ( i_graphic.is() ) + { + const Reference< XPropertySet > xGraphicProps( i_graphic, UNO_QUERY_THROW ); + OSL_VERIFY( xGraphicProps->getPropertyValue("SizePixel") >>= aSizePixel ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("toolkit"); + } + return aSizePixel; + } + + + void lcl_init( Sequence< OUString > const& i_imageURLs, ::std::vector< AnimatedImagesPeer::CachedImage >& o_images ) + { + o_images.resize(0); + size_t count = size_t( i_imageURLs.getLength() ); + o_images.reserve( count ); + for ( const auto& rImageURL : i_imageURLs ) + { + o_images.emplace_back( AnimatedImagesPeer::CachedImage{ rImageURL, nullptr } ); + } + } + + + } + + + //= AnimatedImagesPeer + + + AnimatedImagesPeer::AnimatedImagesPeer() + { + } + + + AnimatedImagesPeer::~AnimatedImagesPeer() + { + } + + + void SAL_CALL AnimatedImagesPeer::startAnimation() + { + SolarMutexGuard aGuard; + VclPtr<Throbber> pThrobber = GetAsDynamic<Throbber>(); + if (pThrobber) + pThrobber->start(); + } + + void SAL_CALL AnimatedImagesPeer::stopAnimation() + { + SolarMutexGuard aGuard; + VclPtr<Throbber> pThrobber = GetAsDynamic<Throbber>(); + if (pThrobber) + pThrobber->stop(); + } + + sal_Bool SAL_CALL AnimatedImagesPeer::isAnimationRunning() + { + SolarMutexGuard aGuard; + VclPtr<Throbber> pThrobber = GetAsDynamic<Throbber>(); + if (pThrobber) + return pThrobber->isRunning(); + return false; + } + + void SAL_CALL AnimatedImagesPeer::setProperty( const OUString& i_propertyName, const Any& i_value ) + { + SolarMutexGuard aGuard; + + VclPtr<Throbber> pThrobber = GetAsDynamic<Throbber>(); + if ( pThrobber ) + { + VCLXWindow::setProperty( i_propertyName, i_value ); + return; + } + + const sal_uInt16 nPropertyId = GetPropertyId( i_propertyName ); + switch ( nPropertyId ) + { + case BASEPROPERTY_STEP_TIME: + { + sal_Int32 nStepTime( 0 ); + if ( i_value >>= nStepTime ) + pThrobber->setStepTime( nStepTime ); + break; + } + case BASEPROPERTY_AUTO_REPEAT: + { + bool bRepeat( true ); + if ( i_value >>= bRepeat ) + pThrobber->setRepeat( bRepeat ); + break; + } + + case BASEPROPERTY_IMAGE_SCALE_MODE: + { + sal_Int16 nScaleMode( ImageScaleMode::ANISOTROPIC ); + VclPtr<ImageControl> pImageControl = GetAsDynamic< ImageControl >(); + if ( pImageControl && ( i_value >>= nScaleMode ) ) + pImageControl->SetScaleMode( nScaleMode ); + } + break; + + default: + AnimatedImagesPeer_Base::setProperty( i_propertyName, i_value ); + break; + } + } + + + Any SAL_CALL AnimatedImagesPeer::getProperty( const OUString& i_propertyName ) + { + SolarMutexGuard aGuard; + + Any aReturn; + + VclPtr<Throbber> pThrobber = GetAsDynamic<Throbber>(); + if ( !pThrobber ) + return VCLXWindow::getProperty( i_propertyName ); + + const sal_uInt16 nPropertyId = GetPropertyId( i_propertyName ); + switch ( nPropertyId ) + { + case BASEPROPERTY_STEP_TIME: + aReturn <<= pThrobber->getStepTime(); + break; + + case BASEPROPERTY_AUTO_REPEAT: + aReturn <<= pThrobber->getRepeat(); + break; + + case BASEPROPERTY_IMAGE_SCALE_MODE: + { + VclPtr<ImageControl> pImageControl = GetAsDynamic<ImageControl>(); + aReturn <<= ( pImageControl ? pImageControl->GetScaleMode() : ImageScaleMode::ANISOTROPIC ); + } + break; + + default: + aReturn = AnimatedImagesPeer_Base::getProperty( i_propertyName ); + break; + } + + return aReturn; + } + + + void AnimatedImagesPeer::ProcessWindowEvent( const VclWindowEvent& i_windowEvent ) + { + if ( i_windowEvent.GetId() == VclEventId::WindowResize ) + { + updateImageList_nothrow(); + } + + AnimatedImagesPeer_Base::ProcessWindowEvent( i_windowEvent ); + } + + + void AnimatedImagesPeer::impl_updateImages_nolck( const Reference< XInterface >& i_animatedImages ) + { + SolarMutexGuard aGuard; + + updateImageList_nothrow( Reference< XAnimatedImages >( i_animatedImages, UNO_QUERY_THROW ) ); + } + + + void SAL_CALL AnimatedImagesPeer::elementInserted( const ContainerEvent& i_event ) + { + SolarMutexGuard aGuard; + Reference< XAnimatedImages > xAnimatedImages( i_event.Source, UNO_QUERY_THROW ); + + sal_Int32 nPosition(0); + OSL_VERIFY( i_event.Accessor >>= nPosition ); + size_t position = size_t( nPosition ); + if ( position > maCachedImageSets.size() ) + { + OSL_ENSURE( false, "AnimatedImagesPeer::elementInserted: illegal accessor/index!" ); + updateImageList_nothrow( xAnimatedImages ); + } + + Sequence< OUString > aImageURLs; + OSL_VERIFY( i_event.Element >>= aImageURLs ); + ::std::vector< CachedImage > aImages; + lcl_init( aImageURLs, aImages ); + maCachedImageSets.insert( maCachedImageSets.begin() + position, aImages ); + updateImageList_nothrow(); + } + + + void SAL_CALL AnimatedImagesPeer::elementRemoved( const ContainerEvent& i_event ) + { + SolarMutexGuard aGuard; + Reference< XAnimatedImages > xAnimatedImages( i_event.Source, UNO_QUERY_THROW ); + + sal_Int32 nPosition(0); + OSL_VERIFY( i_event.Accessor >>= nPosition ); + size_t position = size_t( nPosition ); + if ( position >= maCachedImageSets.size() ) + { + OSL_ENSURE( false, "AnimatedImagesPeer::elementRemoved: illegal accessor/index!" ); + updateImageList_nothrow( xAnimatedImages ); + } + + maCachedImageSets.erase( maCachedImageSets.begin() + position ); + updateImageList_nothrow(); + } + + + void SAL_CALL AnimatedImagesPeer::elementReplaced( const ContainerEvent& i_event ) + { + SolarMutexGuard aGuard; + Reference< XAnimatedImages > xAnimatedImages( i_event.Source, UNO_QUERY_THROW ); + + sal_Int32 nPosition(0); + OSL_VERIFY( i_event.Accessor >>= nPosition ); + size_t position = size_t( nPosition ); + if ( position >= maCachedImageSets.size() ) + { + OSL_ENSURE( false, "AnimatedImagesPeer::elementReplaced: illegal accessor/index!" ); + updateImageList_nothrow( xAnimatedImages ); + } + + Sequence< OUString > aImageURLs; + OSL_VERIFY( i_event.Element >>= aImageURLs ); + ::std::vector< CachedImage > aImages; + lcl_init( aImageURLs, aImages ); + maCachedImageSets[ position ] = aImages; + updateImageList_nothrow(); + } + + + void SAL_CALL AnimatedImagesPeer::disposing( const EventObject& i_event ) + { + VCLXWindow::disposing( i_event ); + } + + + void SAL_CALL AnimatedImagesPeer::modified( const EventObject& i_event ) + { + impl_updateImages_nolck( i_event.Source ); + } + + + void SAL_CALL AnimatedImagesPeer::dispose( ) + { + AnimatedImagesPeer_Base::dispose(); + SolarMutexGuard aGuard; + maCachedImageSets.resize(0); + } + + void AnimatedImagesPeer::updateImageList_nothrow() + { + VclPtr<Throbber> pThrobber = GetAsDynamic<Throbber>(); + if ( !pThrobber ) + return; + + try + { + // collect the image sizes of the different image sets + const Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); + const Reference< XGraphicProvider > xGraphicProvider( css::graphic::GraphicProvider::create(xContext) ); + + const bool isHighContrast = pThrobber->GetSettings().GetStyleSettings().GetHighContrastMode(); + + sal_Int32 nPreferredSet = -1; + const size_t nImageSetCount = maCachedImageSets.size(); + if ( nImageSetCount < 2 ) + { + nPreferredSet = sal_Int32( nImageSetCount ) - 1; + } + else + { + ::std::vector< Size > aImageSizes( nImageSetCount ); + for ( size_t nImageSet = 0; nImageSet < nImageSetCount; ++nImageSet ) + { + ::std::vector< CachedImage > const& rImageSet( maCachedImageSets[ nImageSet ] ); + if ( ( rImageSet.empty() ) + || ( !lcl_ensureImage_throw( xGraphicProvider, isHighContrast, rImageSet[0] ) ) + ) + { + aImageSizes[ nImageSet ] = Size( SAL_MAX_INT32, SAL_MAX_INT32 ); + } + else + { + aImageSizes[ nImageSet ] = lcl_getGraphicSizePixel( rImageSet[0].xGraphic ); + } + } + + // find the set with the smallest difference between window size and image size + const ::Size aWindowSizePixel = pThrobber->GetSizePixel(); + tools::Long nMinimalDistance = ::std::numeric_limits< tools::Long >::max(); + for ( ::std::vector< Size >::const_iterator check = aImageSizes.begin(); + check != aImageSizes.end(); + ++check + ) + { + if ( ( check->Width > aWindowSizePixel.Width() ) + || ( check->Height > aWindowSizePixel.Height() ) + ) + // do not use an image set which doesn't fit into the window + continue; + + const sal_Int64 distance = + ( aWindowSizePixel.Width() - check->Width ) * ( aWindowSizePixel.Width() - check->Width ) + + ( aWindowSizePixel.Height() - check->Height ) * ( aWindowSizePixel.Height() - check->Height ); + if ( distance < nMinimalDistance ) + { + nMinimalDistance = distance; + nPreferredSet = check - aImageSizes.begin(); + } + } + } + + // found a set? + std::vector< Image > aImages; + if ( ( nPreferredSet >= 0 ) && ( o3tl::make_unsigned( nPreferredSet ) < nImageSetCount ) ) + { + // => set the images + ::std::vector< CachedImage > const& rImageSet( maCachedImageSets[ nPreferredSet ] ); + aImages.resize( rImageSet.size() ); + sal_Int32 imageIndex = 0; + for ( const auto& rCachedImage : rImageSet ) + { + lcl_ensureImage_throw( xGraphicProvider, isHighContrast, rCachedImage ); + aImages[ imageIndex++ ] = Image(rCachedImage.xGraphic); + } + } + pThrobber->setImageList( std::move(aImages) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("toolkit"); + } + } + + + void AnimatedImagesPeer::updateImageList_nothrow( const Reference< XAnimatedImages >& i_images ) + { + try + { + const sal_Int32 nImageSetCount = i_images->getImageSetCount(); + maCachedImageSets.resize(0); + for ( sal_Int32 set = 0; set < nImageSetCount; ++set ) + { + const Sequence< OUString > aImageURLs( i_images->getImageSet( set ) ); + ::std::vector< CachedImage > aImages; + lcl_init( aImageURLs, aImages ); + maCachedImageSets.push_back( aImages ); + } + + updateImageList_nothrow(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("toolkit"); + } + } + +} // namespace toolkit + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/asynccallback.cxx b/toolkit/source/awt/asynccallback.cxx new file mode 100644 index 000000000..751647447 --- /dev/null +++ b/toolkit/source/awt/asynccallback.cxx @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <vcl/svapp.hxx> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/awt/XRequestCallback.hpp> + +/// anonymous implementation namespace +namespace { + +class AsyncCallback: + public ::cppu::WeakImplHelper< + css::lang::XServiceInfo, + css::awt::XRequestCallback> +{ +public: + AsyncCallback() {} + AsyncCallback(const AsyncCallback&) = delete; + AsyncCallback& operator=(const AsyncCallback&) = delete; + + // css::lang::XServiceInfo: + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService(const OUString & ServiceName) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // css::awt::XRequestCallback: + virtual void SAL_CALL addCallback(const css::uno::Reference< css::awt::XCallback > & xCallback, const css::uno::Any & aData) override; + +private: + + struct CallbackData + { + CallbackData( const css::uno::Reference< css::awt::XCallback >& rCallback, const css::uno::Any& rAny ) : + xCallback( rCallback ), aData( rAny ) {} + + css::uno::Reference< css::awt::XCallback > xCallback; + css::uno::Any aData; + }; + + DECL_STATIC_LINK( AsyncCallback, Notify_Impl, void*, void ); + + virtual ~AsyncCallback() override {} +}; + +// com.sun.star.uno.XServiceInfo: +OUString SAL_CALL AsyncCallback::getImplementationName() +{ + return "com.sun.star.awt.comp.AsyncCallback"; +} + +sal_Bool SAL_CALL AsyncCallback::supportsService(OUString const & serviceName) +{ + return cppu::supportsService(this, serviceName); +} + +css::uno::Sequence< OUString > SAL_CALL AsyncCallback::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AsyncCallback" }; +} + +// css::awt::XRequestCallback: +void SAL_CALL AsyncCallback::addCallback(const css::uno::Reference< css::awt::XCallback > & xCallback, const css::uno::Any & aData) +{ + if ( Application::IsInMain() ) + { + // NOTE: We don't need SolarMutexGuard here as Application::PostUserEvent is thread-safe + CallbackData* pCallbackData = new CallbackData( xCallback, aData ); + Application::PostUserEvent( LINK( this, AsyncCallback, Notify_Impl ), pCallbackData ); + } +} + +// private asynchronous link to call reference to the callback object +IMPL_STATIC_LINK( AsyncCallback, Notify_Impl, void*, p, void ) +{ + CallbackData* pCallbackData = static_cast<CallbackData*>(p); + try + { + // Asynchronous execution + // Check pointer and reference before! + if ( pCallbackData && pCallbackData->xCallback.is() ) + pCallbackData->xCallback->notify( pCallbackData->aData ); + } + catch ( css::uno::Exception& ) + { + } + + delete pCallbackData; +} + +} // closing anonymous implementation namespace + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_awt_comp_AsyncCallback_get_implementation( + css::uno::XComponentContext *, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new AsyncCallback()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/non-interactable-containers.xml b/toolkit/source/awt/non-interactable-containers.xml new file mode 100644 index 000000000..00f3f2a93 --- /dev/null +++ b/toolkit/source/awt/non-interactable-containers.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + --> + +<dialog xmlns="http://openoffice.org/2007/layout" + xmlns:cnt="http://openoffice.org/2007/layout/container" + title="Interactable Containers" optimumsize="true" + border="true" sizeable="true" moveable="true"> + <hbox> + <table columns="3" cnt:title="Page 1"> + <pushbutton cnt:x-expand="false" cnt:row-span="2" label="1,1" /> + <pushbutton cnt:y-expand="false" label="1,2" /> + <pushbutton cnt:y-expand="false" label="1,3" /> + <pushbutton cnt:col-span="2" label="2,1" /> + </table> + </hbox> +</dialog> diff --git a/toolkit/source/awt/scrollabledialog.cxx b/toolkit/source/awt/scrollabledialog.cxx new file mode 100644 index 000000000..bcc8d18e0 --- /dev/null +++ b/toolkit/source/awt/scrollabledialog.cxx @@ -0,0 +1,173 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <helper/scrollabledialog.hxx> +#include <vcl/settings.hxx> + +namespace toolkit +{ + +// Using WB_AUTOHSCROLL, WB_AUTOVSCROLL here sucks big time, there is a +// problem in the toolkit class where there are some clashing IDs +// ( css::awt::VclWindowPeerAttribute::VSCROLL has the same value +// as css::awt::WindowAttribute::NODECORATION and they are used +// in the same bitmap :-( WB_VSCROLL & WB_HSCROLL apparently are only for +// child classes ( whole thing is a mess if you ask me ) +ScrollableDialog::ScrollableDialog( vcl::Window* pParent, WinBits nStyle, Dialog::InitFlag eFlag ) + : Dialog( pParent, nStyle & ~( WB_AUTOHSCROLL | WB_AUTOVSCROLL ), eFlag ), + maHScrollBar( VclPtr<ScrollBar>::Create(this, WB_HSCROLL | WB_DRAG) ), + maVScrollBar( VclPtr<ScrollBar>::Create(this, WB_VSCROLL | WB_DRAG) ), + mbHasHoriBar( false ), + mbHasVertBar( false ), + maScrollVis( None ) +{ + Link<ScrollBar*,void> aLink( LINK( this, ScrollableDialog, ScrollBarHdl ) ); + maVScrollBar->SetScrollHdl( aLink ); + maHScrollBar->SetScrollHdl( aLink ); + + ScrollBarVisibility aVis = None; + + if ( nStyle & ( WB_AUTOHSCROLL | WB_AUTOVSCROLL ) ) + { + if ( nStyle & WB_AUTOHSCROLL ) + aVis = Hori; + if ( nStyle & WB_AUTOVSCROLL ) + { + if ( aVis == Hori ) + aVis = Both; + else + aVis = Vert; + } + } + setScrollVisibility( aVis ); + mnScrWidth = Dialog::GetSettings().GetStyleSettings().GetScrollBarSize(); +} + +void ScrollableDialog::setScrollVisibility( ScrollBarVisibility rVisState ) +{ + maScrollVis = rVisState; + if ( maScrollVis == Hori || maScrollVis == Both ) + { + mbHasHoriBar = true; + maHScrollBar->Show(); + } + if ( maScrollVis == Vert || maScrollVis == Both ) + { + mbHasVertBar = true; + maVScrollBar->Show(); + } + if ( mbHasHoriBar || mbHasVertBar ) + SetStyle( Dialog::GetStyle() | WB_CLIPCHILDREN ); +} + +ScrollableDialog::~ScrollableDialog() +{ + disposeOnce(); +} + +void ScrollableDialog::dispose() +{ + maHScrollBar.disposeAndClear(); + maVScrollBar.disposeAndClear(); + Dialog::dispose(); +} + +void ScrollableDialog::lcl_Scroll( tools::Long nX, tools::Long nY ) +{ + tools::Long nXScroll = mnScrollPos.X() - nX; + tools::Long nYScroll = mnScrollPos.Y() - nY; + mnScrollPos = Point( nX, nY ); + + tools::Rectangle aScrollableArea( 0, 0, maScrollArea.Width(), maScrollArea.Height() ); + Scroll(nXScroll, nYScroll, aScrollableArea ); + // Manually scroll all children ( except the scrollbars ) + for ( int index = 0; index < GetChildCount(); ++index ) + { + vcl::Window* pChild = GetChild( index ); + if ( pChild && pChild != maVScrollBar.get() && pChild != maHScrollBar.get() ) + { + Point aPos = pChild->GetPosPixel(); + aPos += Point( nXScroll, nYScroll ); + pChild->SetPosPixel( aPos ); + } + } +} + +IMPL_LINK( ScrollableDialog, ScrollBarHdl, ScrollBar*, pSB, void ) +{ + sal_uInt16 nPos = static_cast<sal_uInt16>(pSB->GetThumbPos()); + if( pSB == maVScrollBar.get() ) + lcl_Scroll(mnScrollPos.X(), nPos ); + else if( pSB == maHScrollBar.get() ) + lcl_Scroll(nPos, mnScrollPos.Y() ); +} + +void ScrollableDialog::SetScrollTop( tools::Long nTop ) +{ + Point aOld = mnScrollPos; + lcl_Scroll( mnScrollPos.X() , mnScrollPos.Y() - nTop ); + maHScrollBar->SetThumbPos( 0 ); + // new pos is 0,0 + mnScrollPos = aOld; +} +void ScrollableDialog::SetScrollLeft( tools::Long nLeft ) +{ + Point aOld = mnScrollPos; + lcl_Scroll( mnScrollPos.X() - nLeft , mnScrollPos.Y() ); + maVScrollBar->SetThumbPos( 0 ); + // new pos is 0,0 + mnScrollPos = aOld; +} + +void ScrollableDialog::SetScrollWidth( tools::Long nWidth ) +{ + maScrollArea.setWidth( nWidth ); + ResetScrollBars(); +} + +void ScrollableDialog::SetScrollHeight( tools::Long nHeight ) +{ + maScrollArea.setHeight( nHeight ); + ResetScrollBars(); +} + +void ScrollableDialog::Resize() +{ + ResetScrollBars(); +} + +void ScrollableDialog::ResetScrollBars() +{ + Size aOutSz = GetOutputSizePixel(); + + Point aVPos( aOutSz.Width() - mnScrWidth, 0 ); + Point aHPos( 0, aOutSz.Height() - mnScrWidth ); + + maVScrollBar->SetPosSizePixel( aVPos, Size( mnScrWidth, GetSizePixel().Height() - mnScrWidth ) ); + maHScrollBar->SetPosSizePixel( aHPos, Size( GetSizePixel().Width() - mnScrWidth, mnScrWidth ) ); + + maHScrollBar->SetRangeMax( maScrollArea.Width() + mnScrWidth ); + maHScrollBar->SetVisibleSize( GetSizePixel().Width() ); + + maVScrollBar->SetRangeMax( maScrollArea.Height() + mnScrWidth ); + maVScrollBar->SetVisibleSize( GetSizePixel().Height() ); +} + +} // toolkit +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/stylesettings.cxx b/toolkit/source/awt/stylesettings.cxx new file mode 100644 index 000000000..75c2b687d --- /dev/null +++ b/toolkit/source/awt/stylesettings.cxx @@ -0,0 +1,926 @@ +/* -*- 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 "stylesettings.hxx" +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +#include <com/sun/star/lang/DisposedException.hpp> + +#include <osl/diagnose.h> +#include <osl/mutex.hxx> +#include <vcl/event.hxx> +#include <vcl/window.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> + + +namespace toolkit +{ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::lang::EventObject; + using ::com::sun::star::awt::FontDescriptor; + using ::com::sun::star::awt::XStyleChangeListener; + + + IMPL_LINK( WindowStyleSettings, OnWindowEvent, VclWindowEvent&, rEvent, void ) + { + if ( rEvent.GetId() != VclEventId::WindowDataChanged ) + return; + const DataChangedEvent* pDataChangedEvent = static_cast< const DataChangedEvent* >( rEvent.GetData() ); + if ( !pDataChangedEvent || ( pDataChangedEvent->GetType() != DataChangedEventType::SETTINGS ) ) + return; + if ( !( pDataChangedEvent->GetFlags() & AllSettingsFlags::STYLE ) ) + return; + + EventObject aEvent( *pOwningWindow ); + aStyleChangeListeners.notifyEach( &XStyleChangeListener::styleSettingsChanged, aEvent ); + } + + + //= StyleMethodGuard + + namespace { + + class StyleMethodGuard + { + public: + explicit StyleMethodGuard( const VCLXWindow* pOwningWindow ) + { + if ( pOwningWindow == nullptr ) + throw DisposedException(); + } + + private: + SolarMutexGuard m_aGuard; + }; + + } + + //= WindowStyleSettings + + + WindowStyleSettings::WindowStyleSettings(::osl::Mutex& i_rListenerMutex, VCLXWindow& i_rOwningWindow ) + : pOwningWindow( &i_rOwningWindow ) + ,aStyleChangeListeners( i_rListenerMutex ) + { + VclPtr<vcl::Window> pWindow = i_rOwningWindow.GetWindow(); + if ( !pWindow ) + throw RuntimeException(); + pWindow->AddEventListener( LINK( this, WindowStyleSettings, OnWindowEvent ) ); + } + + + WindowStyleSettings::~WindowStyleSettings() + { + } + + + void WindowStyleSettings::dispose() + { + StyleMethodGuard aGuard( pOwningWindow ); + + VclPtr<vcl::Window> pWindow = pOwningWindow->GetWindow(); + OSL_ENSURE( pWindow, "WindowStyleSettings::dispose: window has been reset before we could revoke the listener!" ); + if ( pWindow ) + pWindow->RemoveEventListener( LINK( this, WindowStyleSettings, OnWindowEvent ) ); + + EventObject aEvent( *this ); + aStyleChangeListeners.disposeAndClear( aEvent ); + + pOwningWindow = nullptr; + } + + + sal_Int32 WindowStyleSettings::ImplGetStyleColor( Color const & (StyleSettings::*i_pGetter)() const ) const + { + const VclPtr<vcl::Window>& pWindow = pOwningWindow->GetWindow(); + const AllSettings aAllSettings = pWindow->GetSettings(); + const StyleSettings& aStyleSettings = aAllSettings.GetStyleSettings(); + return sal_Int32((aStyleSettings.*i_pGetter)()); + } + + void WindowStyleSettings::ImplSetStyleColor( void (StyleSettings::*i_pSetter)( Color const & ), sal_Int32 i_nColor ) + { + VclPtr<vcl::Window> pWindow = pOwningWindow->GetWindow(); + AllSettings aAllSettings = pWindow->GetSettings(); + StyleSettings aStyleSettings = aAllSettings.GetStyleSettings(); + (aStyleSettings.*i_pSetter)( Color(ColorTransparency, i_nColor) ); + aAllSettings.SetStyleSettings( aStyleSettings ); + pWindow->SetSettings( aAllSettings ); + } + + FontDescriptor WindowStyleSettings::ImplGetStyleFont( vcl::Font const & (StyleSettings::*i_pGetter)() const ) const + { + const VclPtr<vcl::Window>& pWindow = pOwningWindow->GetWindow(); + const AllSettings aAllSettings = pWindow->GetSettings(); + const StyleSettings& aStyleSettings = aAllSettings.GetStyleSettings(); + return VCLUnoHelper::CreateFontDescriptor( (aStyleSettings.*i_pGetter)() ); + } + + void WindowStyleSettings::ImplSetStyleFont( void (StyleSettings::*i_pSetter)( vcl::Font const &), + vcl::Font const & (StyleSettings::*i_pGetter)() const, const FontDescriptor& i_rFont ) + { + VclPtr<vcl::Window> pWindow = pOwningWindow->GetWindow(); + AllSettings aAllSettings = pWindow->GetSettings(); + StyleSettings aStyleSettings = aAllSettings.GetStyleSettings(); + const vcl::Font aNewFont = VCLUnoHelper::CreateFont( i_rFont, (aStyleSettings.*i_pGetter)() ); + (aStyleSettings.*i_pSetter)( aNewFont ); + aAllSettings.SetStyleSettings( aStyleSettings ); + pWindow->SetSettings( aAllSettings ); + } + + ::sal_Int32 SAL_CALL WindowStyleSettings::getActiveBorderColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetActiveBorderColor ); + } + + + void SAL_CALL WindowStyleSettings::setActiveBorderColor( ::sal_Int32 _activebordercolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetActiveBorderColor, _activebordercolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getActiveColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetActiveColor ); + } + + + void SAL_CALL WindowStyleSettings::setActiveColor( ::sal_Int32 _activecolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetActiveColor, _activecolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getActiveTabColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetActiveTabColor ); + } + + + void SAL_CALL WindowStyleSettings::setActiveTabColor( ::sal_Int32 _activetabcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetActiveTabColor, _activetabcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getActiveTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetActiveTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setActiveTextColor( ::sal_Int32 _activetextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetActiveTextColor, _activetextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getButtonRolloverTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetButtonRolloverTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setButtonRolloverTextColor( ::sal_Int32 _buttonrollovertextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetButtonRolloverTextColor, _buttonrollovertextcolor ); + // Also need to set ActionButtonRolloverTextColor as this setting can't be + // set through the UNO interface otherwise. + // Previously this setting was used to set colors for both scenarios, + // but action button setting was added to differentiate the buttons from + // "normal" buttons in some themes. + ImplSetStyleColor( &StyleSettings::SetActionButtonRolloverTextColor, _buttonrollovertextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getButtonTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetButtonTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setButtonTextColor( ::sal_Int32 _buttontextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetButtonTextColor, _buttontextcolor ); + // Also need to set ActionButtonTextColor and DefaultActionButtonTextColor + // as this two settings can't be set through the UNO interface otherwise. + // Previously this setting was used to set colors for all three scenarios, + // but action button setting was added to differentiate the buttons from + // "normal" buttons in some themes. + ImplSetStyleColor( &StyleSettings::SetActionButtonTextColor, _buttontextcolor ); + ImplSetStyleColor( &StyleSettings::SetDefaultActionButtonTextColor, _buttontextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getCheckedColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetCheckedColor ); + } + + + void SAL_CALL WindowStyleSettings::setCheckedColor( ::sal_Int32 _checkedcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetCheckedColor, _checkedcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getDarkShadowColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetDarkShadowColor ); + } + + + void SAL_CALL WindowStyleSettings::setDarkShadowColor( ::sal_Int32 _darkshadowcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetDarkShadowColor, _darkshadowcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getDeactiveBorderColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetDeactiveBorderColor ); + } + + + void SAL_CALL WindowStyleSettings::setDeactiveBorderColor( ::sal_Int32 _deactivebordercolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetDeactiveBorderColor, _deactivebordercolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getDeactiveColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetDeactiveColor ); + } + + + void SAL_CALL WindowStyleSettings::setDeactiveColor( ::sal_Int32 _deactivecolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetDeactiveColor, _deactivecolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getDeactiveTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetDeactiveTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setDeactiveTextColor( ::sal_Int32 _deactivetextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetDeactiveTextColor, _deactivetextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getDialogColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetDialogColor ); + } + + + void SAL_CALL WindowStyleSettings::setDialogColor( ::sal_Int32 _dialogcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetDialogColor, _dialogcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getDialogTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetDialogTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setDialogTextColor( ::sal_Int32 _dialogtextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetDialogTextColor, _dialogtextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getDisableColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetDisableColor ); + } + + + void SAL_CALL WindowStyleSettings::setDisableColor( ::sal_Int32 _disablecolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetDisableColor, _disablecolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getFaceColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetFaceColor ); + } + + + void SAL_CALL WindowStyleSettings::setFaceColor( ::sal_Int32 _facecolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetFaceColor, _facecolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getFaceGradientColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + const VclPtr<vcl::Window>& pWindow = pOwningWindow->GetWindow(); + const AllSettings aAllSettings = pWindow->GetSettings(); + const StyleSettings& aStyleSettings = aAllSettings.GetStyleSettings(); + return sal_Int32(aStyleSettings.GetFaceGradientColor()); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getFieldColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetFieldColor ); + } + + + void SAL_CALL WindowStyleSettings::setFieldColor( ::sal_Int32 _fieldcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetFieldColor, _fieldcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getFieldRolloverTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetFieldRolloverTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setFieldRolloverTextColor( ::sal_Int32 _fieldrollovertextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetFieldRolloverTextColor, _fieldrollovertextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getFieldTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetFieldTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setFieldTextColor( ::sal_Int32 _fieldtextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetFieldTextColor, _fieldtextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getGroupTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetGroupTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setGroupTextColor( ::sal_Int32 _grouptextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetGroupTextColor, _grouptextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getHelpColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetHelpColor ); + } + + + void SAL_CALL WindowStyleSettings::setHelpColor( ::sal_Int32 _helpcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetHelpColor, _helpcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getHelpTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetHelpTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setHelpTextColor( ::sal_Int32 _helptextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetHelpTextColor, _helptextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getHighlightColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetHighlightColor ); + } + + + void SAL_CALL WindowStyleSettings::setHighlightColor( ::sal_Int32 _highlightcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetHighlightColor, _highlightcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getHighlightTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetHighlightTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setHighlightTextColor( ::sal_Int32 _highlighttextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetHighlightTextColor, _highlighttextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getInactiveTabColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetInactiveTabColor ); + } + + + void SAL_CALL WindowStyleSettings::setInactiveTabColor( ::sal_Int32 _inactivetabcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetInactiveTabColor, _inactivetabcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getLabelTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetLabelTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setLabelTextColor( ::sal_Int32 _labeltextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetLabelTextColor, _labeltextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getLightColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetLightColor ); + } + + + void SAL_CALL WindowStyleSettings::setLightColor( ::sal_Int32 _lightcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetLightColor, _lightcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getMenuBarColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetMenuBarColor ); + } + + + void SAL_CALL WindowStyleSettings::setMenuBarColor( ::sal_Int32 _menubarcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetMenuBarColor, _menubarcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getMenuBarTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetMenuBarTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setMenuBarTextColor( ::sal_Int32 _menubartextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetMenuBarTextColor, _menubartextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getMenuBorderColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetMenuBorderColor ); + } + + + void SAL_CALL WindowStyleSettings::setMenuBorderColor( ::sal_Int32 _menubordercolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetMenuBorderColor, _menubordercolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getMenuColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetMenuColor ); + } + + + void SAL_CALL WindowStyleSettings::setMenuColor( ::sal_Int32 _menucolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetMenuColor, _menucolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getMenuHighlightColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetMenuHighlightColor ); + } + + + void SAL_CALL WindowStyleSettings::setMenuHighlightColor( ::sal_Int32 _menuhighlightcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetMenuHighlightColor, _menuhighlightcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getMenuHighlightTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetMenuHighlightTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setMenuHighlightTextColor( ::sal_Int32 _menuhighlighttextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetMenuHighlightTextColor, _menuhighlighttextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getMenuTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetMenuTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setMenuTextColor( ::sal_Int32 _menutextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetMenuTextColor, _menutextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getMonoColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetMonoColor ); + } + + + void SAL_CALL WindowStyleSettings::setMonoColor( ::sal_Int32 _monocolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetMonoColor, _monocolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getRadioCheckTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetRadioCheckTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setRadioCheckTextColor( ::sal_Int32 _radiochecktextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetRadioCheckTextColor, _radiochecktextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getSeparatorColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + const VclPtr<vcl::Window>& pWindow = pOwningWindow->GetWindow(); + const AllSettings aAllSettings = pWindow->GetSettings(); + const StyleSettings& aStyleSettings = aAllSettings.GetStyleSettings(); + return sal_Int32(aStyleSettings.GetSeparatorColor()); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getShadowColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetShadowColor ); + } + + + void SAL_CALL WindowStyleSettings::setShadowColor( ::sal_Int32 _shadowcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetShadowColor, _shadowcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getWindowColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetWindowColor ); + } + + + void SAL_CALL WindowStyleSettings::setWindowColor( ::sal_Int32 _windowcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetWindowColor, _windowcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getWindowTextColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetWindowTextColor ); + } + + + void SAL_CALL WindowStyleSettings::setWindowTextColor( ::sal_Int32 _windowtextcolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetWindowTextColor, _windowtextcolor ); + } + + + ::sal_Int32 SAL_CALL WindowStyleSettings::getWorkspaceColor() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleColor( &StyleSettings::GetWorkspaceColor ); + } + + + void SAL_CALL WindowStyleSettings::setWorkspaceColor( ::sal_Int32 _workspacecolor ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleColor( &StyleSettings::SetWorkspaceColor, _workspacecolor ); + } + + + sal_Bool SAL_CALL WindowStyleSettings::getHighContrastMode() + { + StyleMethodGuard aGuard( pOwningWindow ); + const VclPtr<vcl::Window>& pWindow = pOwningWindow->GetWindow(); + const AllSettings aAllSettings = pWindow->GetSettings(); + const StyleSettings& aStyleSettings = aAllSettings.GetStyleSettings(); + return aStyleSettings.GetHighContrastMode(); + } + + + void SAL_CALL WindowStyleSettings::setHighContrastMode( sal_Bool _highcontrastmode ) + { + StyleMethodGuard aGuard( pOwningWindow ); + VclPtr<vcl::Window> pWindow = pOwningWindow->GetWindow(); + AllSettings aAllSettings = pWindow->GetSettings(); + StyleSettings aStyleSettings = aAllSettings.GetStyleSettings(); + aStyleSettings.SetHighContrastMode( _highcontrastmode ); + aAllSettings.SetStyleSettings( aStyleSettings ); + pWindow->SetSettings( aAllSettings ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getApplicationFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetAppFont ); + } + + + void SAL_CALL WindowStyleSettings::setApplicationFont( const FontDescriptor& _applicationfont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetAppFont, &StyleSettings::GetAppFont, _applicationfont ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getHelpFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetHelpFont ); + } + + + void SAL_CALL WindowStyleSettings::setHelpFont( const FontDescriptor& _helpfont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetHelpFont, &StyleSettings::GetHelpFont, _helpfont ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getTitleFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetTitleFont ); + } + + + void SAL_CALL WindowStyleSettings::setTitleFont( const FontDescriptor& _titlefont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetTitleFont, &StyleSettings::GetTitleFont, _titlefont ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getFloatTitleFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetFloatTitleFont ); + } + + + void SAL_CALL WindowStyleSettings::setFloatTitleFont( const FontDescriptor& _floattitlefont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetFloatTitleFont, &StyleSettings::GetFloatTitleFont, _floattitlefont ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getMenuFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetMenuFont ); + } + + + void SAL_CALL WindowStyleSettings::setMenuFont( const FontDescriptor& _menufont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetMenuFont, &StyleSettings::GetMenuFont, _menufont ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getToolFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetToolFont ); + } + + + void SAL_CALL WindowStyleSettings::setToolFont( const FontDescriptor& _toolfont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetToolFont, &StyleSettings::GetToolFont, _toolfont ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getGroupFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetGroupFont ); + } + + + void SAL_CALL WindowStyleSettings::setGroupFont( const FontDescriptor& _groupfont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetGroupFont, &StyleSettings::GetGroupFont, _groupfont ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getLabelFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetLabelFont ); + } + + + void SAL_CALL WindowStyleSettings::setLabelFont( const FontDescriptor& _labelfont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetLabelFont, &StyleSettings::GetLabelFont, _labelfont ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getRadioCheckFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetRadioCheckFont ); + } + + + void SAL_CALL WindowStyleSettings::setRadioCheckFont( const FontDescriptor& _radiocheckfont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetRadioCheckFont, &StyleSettings::GetRadioCheckFont, _radiocheckfont ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getPushButtonFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetPushButtonFont ); + } + + + void SAL_CALL WindowStyleSettings::setPushButtonFont( const FontDescriptor& _pushbuttonfont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetPushButtonFont, &StyleSettings::GetPushButtonFont, _pushbuttonfont ); + } + + + FontDescriptor SAL_CALL WindowStyleSettings::getFieldFont() + { + StyleMethodGuard aGuard( pOwningWindow ); + return ImplGetStyleFont( &StyleSettings::GetFieldFont ); + } + + + void SAL_CALL WindowStyleSettings::setFieldFont( const FontDescriptor& _fieldfont ) + { + StyleMethodGuard aGuard( pOwningWindow ); + ImplSetStyleFont( &StyleSettings::SetFieldFont, &StyleSettings::GetFieldFont, _fieldfont ); + } + + + void SAL_CALL WindowStyleSettings::addStyleChangeListener( const Reference< XStyleChangeListener >& i_rListener ) + { + StyleMethodGuard aGuard( pOwningWindow ); + if ( i_rListener.is() ) + aStyleChangeListeners.addInterface( i_rListener ); + } + + + void SAL_CALL WindowStyleSettings::removeStyleChangeListener( const Reference< XStyleChangeListener >& i_rListener ) + { + StyleMethodGuard aGuard( pOwningWindow ); + if ( i_rListener.is() ) + aStyleChangeListeners.removeInterface( i_rListener ); + } + + +} // namespace toolkit + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/stylesettings.hxx b/toolkit/source/awt/stylesettings.hxx new file mode 100644 index 000000000..4e3f0b2df --- /dev/null +++ b/toolkit/source/awt/stylesettings.hxx @@ -0,0 +1,181 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_TOOLKIT_SOURCE_AWT_STYLESETTINGS_HXX +#define INCLUDED_TOOLKIT_SOURCE_AWT_STYLESETTINGS_HXX + +#include <com/sun/star/awt/XStyleSettings.hpp> + +#include <comphelper/interfacecontainer3.hxx> +#include <cppuhelper/implbase.hxx> +#include <tools/link.hxx> + +namespace osl +{ + class Mutex; +} +class Color; +class VCLXWindow; +class VclWindowEvent; +class StyleSettings; +namespace vcl { class Font; } + +namespace toolkit +{ + + + //= WindowStyleSettings + + typedef ::cppu::WeakImplHelper < css::awt::XStyleSettings + > WindowStyleSettings_Base; + class WindowStyleSettings : public WindowStyleSettings_Base + { + public: + WindowStyleSettings( ::osl::Mutex& i_rListenerMutex, VCLXWindow& i_rOwningWindow ); + virtual ~WindowStyleSettings() override; + + void dispose(); + + // XStyleSettings + virtual ::sal_Int32 SAL_CALL getActiveBorderColor() override; + virtual void SAL_CALL setActiveBorderColor( ::sal_Int32 _activebordercolor ) override; + virtual ::sal_Int32 SAL_CALL getActiveColor() override; + virtual void SAL_CALL setActiveColor( ::sal_Int32 _activecolor ) override; + virtual ::sal_Int32 SAL_CALL getActiveTabColor() override; + virtual void SAL_CALL setActiveTabColor( ::sal_Int32 _activetabcolor ) override; + virtual ::sal_Int32 SAL_CALL getActiveTextColor() override; + virtual void SAL_CALL setActiveTextColor( ::sal_Int32 _activetextcolor ) override; + virtual ::sal_Int32 SAL_CALL getButtonRolloverTextColor() override; + virtual void SAL_CALL setButtonRolloverTextColor( ::sal_Int32 _buttonrollovertextcolor ) override; + virtual ::sal_Int32 SAL_CALL getButtonTextColor() override; + virtual void SAL_CALL setButtonTextColor( ::sal_Int32 _buttontextcolor ) override; + virtual ::sal_Int32 SAL_CALL getCheckedColor() override; + virtual void SAL_CALL setCheckedColor( ::sal_Int32 _checkedcolor ) override; + virtual ::sal_Int32 SAL_CALL getDarkShadowColor() override; + virtual void SAL_CALL setDarkShadowColor( ::sal_Int32 _darkshadowcolor ) override; + virtual ::sal_Int32 SAL_CALL getDeactiveBorderColor() override; + virtual void SAL_CALL setDeactiveBorderColor( ::sal_Int32 _deactivebordercolor ) override; + virtual ::sal_Int32 SAL_CALL getDeactiveColor() override; + virtual void SAL_CALL setDeactiveColor( ::sal_Int32 _deactivecolor ) override; + virtual ::sal_Int32 SAL_CALL getDeactiveTextColor() override; + virtual void SAL_CALL setDeactiveTextColor( ::sal_Int32 _deactivetextcolor ) override; + virtual ::sal_Int32 SAL_CALL getDialogColor() override; + virtual void SAL_CALL setDialogColor( ::sal_Int32 _dialogcolor ) override; + virtual ::sal_Int32 SAL_CALL getDialogTextColor() override; + virtual void SAL_CALL setDialogTextColor( ::sal_Int32 _dialogtextcolor ) override; + virtual ::sal_Int32 SAL_CALL getDisableColor() override; + virtual void SAL_CALL setDisableColor( ::sal_Int32 _disablecolor ) override; + virtual ::sal_Int32 SAL_CALL getFaceColor() override; + virtual void SAL_CALL setFaceColor( ::sal_Int32 _facecolor ) override; + virtual ::sal_Int32 SAL_CALL getFaceGradientColor() override; + virtual ::sal_Int32 SAL_CALL getFieldColor() override; + virtual void SAL_CALL setFieldColor( ::sal_Int32 _fieldcolor ) override; + virtual ::sal_Int32 SAL_CALL getFieldRolloverTextColor() override; + virtual void SAL_CALL setFieldRolloverTextColor( ::sal_Int32 _fieldrollovertextcolor ) override; + virtual ::sal_Int32 SAL_CALL getFieldTextColor() override; + virtual void SAL_CALL setFieldTextColor( ::sal_Int32 _fieldtextcolor ) override; + virtual ::sal_Int32 SAL_CALL getGroupTextColor() override; + virtual void SAL_CALL setGroupTextColor( ::sal_Int32 _grouptextcolor ) override; + virtual ::sal_Int32 SAL_CALL getHelpColor() override; + virtual void SAL_CALL setHelpColor( ::sal_Int32 _helpcolor ) override; + virtual ::sal_Int32 SAL_CALL getHelpTextColor() override; + virtual void SAL_CALL setHelpTextColor( ::sal_Int32 _helptextcolor ) override; + virtual ::sal_Int32 SAL_CALL getHighlightColor() override; + virtual void SAL_CALL setHighlightColor( ::sal_Int32 _highlightcolor ) override; + virtual ::sal_Int32 SAL_CALL getHighlightTextColor() override; + virtual void SAL_CALL setHighlightTextColor( ::sal_Int32 _highlighttextcolor ) override; + virtual ::sal_Int32 SAL_CALL getInactiveTabColor() override; + virtual void SAL_CALL setInactiveTabColor( ::sal_Int32 _inactivetabcolor ) override; + virtual ::sal_Int32 SAL_CALL getLabelTextColor() override; + virtual void SAL_CALL setLabelTextColor( ::sal_Int32 _labeltextcolor ) override; + virtual ::sal_Int32 SAL_CALL getLightColor() override; + virtual void SAL_CALL setLightColor( ::sal_Int32 _lightcolor ) override; + virtual ::sal_Int32 SAL_CALL getMenuBarColor() override; + virtual void SAL_CALL setMenuBarColor( ::sal_Int32 _menubarcolor ) override; + virtual ::sal_Int32 SAL_CALL getMenuBarTextColor() override; + virtual void SAL_CALL setMenuBarTextColor( ::sal_Int32 _menubartextcolor ) override; + virtual ::sal_Int32 SAL_CALL getMenuBorderColor() override; + virtual void SAL_CALL setMenuBorderColor( ::sal_Int32 _menubordercolor ) override; + virtual ::sal_Int32 SAL_CALL getMenuColor() override; + virtual void SAL_CALL setMenuColor( ::sal_Int32 _menucolor ) override; + virtual ::sal_Int32 SAL_CALL getMenuHighlightColor() override; + virtual void SAL_CALL setMenuHighlightColor( ::sal_Int32 _menuhighlightcolor ) override; + virtual ::sal_Int32 SAL_CALL getMenuHighlightTextColor() override; + virtual void SAL_CALL setMenuHighlightTextColor( ::sal_Int32 _menuhighlighttextcolor ) override; + virtual ::sal_Int32 SAL_CALL getMenuTextColor() override; + virtual void SAL_CALL setMenuTextColor( ::sal_Int32 _menutextcolor ) override; + virtual ::sal_Int32 SAL_CALL getMonoColor() override; + virtual void SAL_CALL setMonoColor( ::sal_Int32 _monocolor ) override; + virtual ::sal_Int32 SAL_CALL getRadioCheckTextColor() override; + virtual void SAL_CALL setRadioCheckTextColor( ::sal_Int32 _radiochecktextcolor ) override; + virtual ::sal_Int32 SAL_CALL getSeparatorColor() override; + virtual ::sal_Int32 SAL_CALL getShadowColor() override; + virtual void SAL_CALL setShadowColor( ::sal_Int32 _shadowcolor ) override; + virtual ::sal_Int32 SAL_CALL getWindowColor() override; + virtual void SAL_CALL setWindowColor( ::sal_Int32 _windowcolor ) override; + virtual ::sal_Int32 SAL_CALL getWindowTextColor() override; + virtual void SAL_CALL setWindowTextColor( ::sal_Int32 _windowtextcolor ) override; + virtual ::sal_Int32 SAL_CALL getWorkspaceColor() override; + virtual void SAL_CALL setWorkspaceColor( ::sal_Int32 _workspacecolor ) override; + virtual sal_Bool SAL_CALL getHighContrastMode() override; + virtual void SAL_CALL setHighContrastMode( sal_Bool _highcontrastmode ) override; + virtual css::awt::FontDescriptor SAL_CALL getApplicationFont() override; + virtual void SAL_CALL setApplicationFont( const css::awt::FontDescriptor& _applicationfont ) override; + virtual css::awt::FontDescriptor SAL_CALL getHelpFont() override; + virtual void SAL_CALL setHelpFont( const css::awt::FontDescriptor& _helpfont ) override; + virtual css::awt::FontDescriptor SAL_CALL getTitleFont() override; + virtual void SAL_CALL setTitleFont( const css::awt::FontDescriptor& _titlefont ) override; + virtual css::awt::FontDescriptor SAL_CALL getFloatTitleFont() override; + virtual void SAL_CALL setFloatTitleFont( const css::awt::FontDescriptor& _floattitlefont ) override; + virtual css::awt::FontDescriptor SAL_CALL getMenuFont() override; + virtual void SAL_CALL setMenuFont( const css::awt::FontDescriptor& _menufont ) override; + virtual css::awt::FontDescriptor SAL_CALL getToolFont() override; + virtual void SAL_CALL setToolFont( const css::awt::FontDescriptor& _toolfont ) override; + virtual css::awt::FontDescriptor SAL_CALL getGroupFont() override; + virtual void SAL_CALL setGroupFont( const css::awt::FontDescriptor& _groupfont ) override; + virtual css::awt::FontDescriptor SAL_CALL getLabelFont() override; + virtual void SAL_CALL setLabelFont( const css::awt::FontDescriptor& _labelfont ) override; + virtual css::awt::FontDescriptor SAL_CALL getRadioCheckFont() override; + virtual void SAL_CALL setRadioCheckFont( const css::awt::FontDescriptor& _radiocheckfont ) override; + virtual css::awt::FontDescriptor SAL_CALL getPushButtonFont() override; + virtual void SAL_CALL setPushButtonFont( const css::awt::FontDescriptor& _pushbuttonfont ) override; + virtual css::awt::FontDescriptor SAL_CALL getFieldFont() override; + virtual void SAL_CALL setFieldFont( const css::awt::FontDescriptor& _fieldfont ) override; + virtual void SAL_CALL addStyleChangeListener( const css::uno::Reference< css::awt::XStyleChangeListener >& Listener ) override; + virtual void SAL_CALL removeStyleChangeListener( const css::uno::Reference< css::awt::XStyleChangeListener >& Listener ) override; + + private: + void ImplSetStyleFont( void (StyleSettings::*i_pSetter)( vcl::Font const &), + vcl::Font const & (StyleSettings::*i_pGetter)() const, const css::awt::FontDescriptor& i_rFont ); + void ImplSetStyleColor( void (StyleSettings::*i_pSetter)( Color const & ), sal_Int32 i_nColor ); + sal_Int32 ImplGetStyleColor( Color const & (StyleSettings::*i_pGetter)() const ) const; + css::awt::FontDescriptor ImplGetStyleFont( vcl::Font const & (StyleSettings::*i_pGetter)() const ) const; + DECL_LINK( OnWindowEvent, VclWindowEvent&, void ); + + VCLXWindow* pOwningWindow; + ::comphelper::OInterfaceContainerHelper3<css::awt::XStyleChangeListener> aStyleChangeListeners; + }; + + +} // namespace toolkit + + +#endif // INCLUDED_TOOLKIT_SOURCE_AWT_STYLESETTINGS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxaccessiblecomponent.cxx b/toolkit/source/awt/vclxaccessiblecomponent.cxx new file mode 100644 index 000000000..767004c35 --- /dev/null +++ b/toolkit/source/awt/vclxaccessiblecomponent.cxx @@ -0,0 +1,830 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/convert.hxx> +#include <toolkit/awt/vclxfont.hxx> +#include <vcl/toolkit/dialog.hxx> +#include <vcl/vclevent.hxx> +#include <vcl/window.hxx> +#include <vcl/toolkit/edit.hxx> +#include <vcl/settings.hxx> +#include <tools/debug.hxx> +#include <unotools/accessiblestatesethelper.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/menu.hxx> + +using namespace ::com::sun::star; +using namespace ::comphelper; + +VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXWindow ) +{ + m_xVCLXWindow = pVCLXWindow; + + DBG_ASSERT( pVCLXWindow->GetWindow(), "VCLXAccessibleComponent - no window!" ); + m_xEventSource = pVCLXWindow->GetWindow(); + if ( m_xEventSource ) + { + m_xEventSource->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) ); + m_xEventSource->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); + } + + // announce the XAccessible of our creator to the base class + lateInit( pVCLXWindow ); +} + +VCLXWindow* VCLXAccessibleComponent::GetVCLXWindow() const +{ + return m_xVCLXWindow.get(); +} + +void VCLXAccessibleComponent::DisconnectEvents() +{ + if ( m_xEventSource ) + { + m_xEventSource->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) ); + m_xEventSource->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); + m_xEventSource.clear(); + } +} + +VCLXAccessibleComponent::~VCLXAccessibleComponent() +{ + ensureDisposed(); + DisconnectEvents(); +} + +IMPLEMENT_FORWARD_XINTERFACE3( VCLXAccessibleComponent, OAccessibleExtendedComponentHelper, OAccessibleImplementationAccess, VCLXAccessibleComponent_BASE ) +css::uno::Sequence< css::uno::Type > SAL_CALL VCLXAccessibleComponent::getTypes() +{ + return ::comphelper::concatSequences( + OAccessibleExtendedComponentHelper::getTypes(), + OAccessibleImplementationAccess::getTypes(), + VCLXAccessibleComponent_BASE::getTypes() + ); +} +IMPLEMENT_GET_IMPLEMENTATION_ID( VCLXAccessibleComponent ) + +OUString VCLXAccessibleComponent::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleWindow"; +} + +sal_Bool VCLXAccessibleComponent::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +uno::Sequence< OUString > VCLXAccessibleComponent::getSupportedServiceNames() +{ + uno::Sequence< OUString > aNames { "com.sun.star.awt.AccessibleWindow" }; + return aNames; +} + +IMPL_LINK( VCLXAccessibleComponent, WindowEventListener, VclWindowEvent&, rEvent, void ) +{ + /* Ignore VclEventId::WindowEndPopupMode, because the UNO accessibility wrapper + * might have been destroyed by the previous VCLEventListener (if no AT tool + * is running), e.g. sub-toolbars in impress. + */ + if ( m_xVCLXWindow.is() /* #122218# */ && (rEvent.GetId() != VclEventId::WindowEndPopupMode) ) + { + DBG_ASSERT( rEvent.GetWindow(), "Window???" ); + if( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() || ( rEvent.GetId() == VclEventId::ObjectDying ) ) + { + ProcessWindowEvent( rEvent ); + } + } +} + +IMPL_LINK( VCLXAccessibleComponent, WindowChildEventListener, VclWindowEvent&, rEvent, void ) +{ + if ( m_xVCLXWindow.is() /* #i68079# */ ) + { + DBG_ASSERT( rEvent.GetWindow(), "Window???" ); + if( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() ) + { + // #103087# to prevent an early release of the component + uno::Reference< accessibility::XAccessibleContext > xHoldAlive = this; + + ProcessWindowChildEvent( rEvent ); + } + } +} + +uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::GetChildAccessible( const VclWindowEvent& rVclWindowEvent ) +{ + // checks if the data in the window event is our direct child + // and returns its accessible + + // MT: Change this later, normally a show/hide event shouldn't have the vcl::Window* in pData. + vcl::Window* pChildWindow = static_cast<vcl::Window *>(rVclWindowEvent.GetData()); + if( pChildWindow && GetWindow() == pChildWindow->GetAccessibleParentWindow() ) + return pChildWindow->GetAccessible( rVclWindowEvent.GetId() == VclEventId::WindowShow ); + else + return uno::Reference< accessibility::XAccessible > (); +} + +void VCLXAccessibleComponent::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) +{ + uno::Any aOldValue, aNewValue; + uno::Reference< accessibility::XAccessible > xAcc; + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::WindowShow: // send create on show for direct accessible children + { + xAcc = GetChildAccessible( rVclWindowEvent ); + if( xAcc.is() ) + { + aNewValue <<= xAcc; + NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue ); + } + } + break; + case VclEventId::WindowHide: // send destroy on hide for direct accessible children + { + xAcc = GetChildAccessible( rVclWindowEvent ); + if( xAcc.is() ) + { + aOldValue <<= xAcc; + NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue ); + } + } + break; + default: break; + } +} + +void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + uno::Any aOldValue, aNewValue; + + vcl::Window* pAccWindow = rVclWindowEvent.GetWindow(); + assert(pAccWindow && "VCLXAccessibleComponent::ProcessWindowEvent - Window?"); + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::ObjectDying: + { + DisconnectEvents(); + m_xVCLXWindow.clear(); + } + break; + case VclEventId::WindowChildDestroyed: + { + vcl::Window* pWindow = static_cast<vcl::Window*>(rVclWindowEvent.GetData()); + DBG_ASSERT( pWindow, "VclEventId::WindowChildDestroyed - Window=?" ); + if ( pWindow->GetAccessible( false ).is() ) + { + aOldValue <<= pWindow->GetAccessible( false ); + NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue ); + } + } + break; + case VclEventId::WindowActivate: + { + sal_Int16 aAccessibleRole = getAccessibleRole(); + // avoid notification if a child frame is already active + // only one frame may be active at a given time + if ( !pAccWindow->HasActiveChildFrame() && + ( aAccessibleRole == accessibility::AccessibleRole::FRAME || + aAccessibleRole == accessibility::AccessibleRole::ALERT || + aAccessibleRole == accessibility::AccessibleRole::DIALOG ) ) // #i18891# + { + aNewValue <<= accessibility::AccessibleStateType::ACTIVE; + NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + } + break; + case VclEventId::WindowDeactivate: + { + sal_Int16 aAccessibleRole = getAccessibleRole(); + if ( aAccessibleRole == accessibility::AccessibleRole::FRAME || + aAccessibleRole == accessibility::AccessibleRole::ALERT || + aAccessibleRole == accessibility::AccessibleRole::DIALOG ) // #i18891# + { + aOldValue <<= accessibility::AccessibleStateType::ACTIVE; + NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + } + break; + case VclEventId::WindowGetFocus: + case VclEventId::ControlGetFocus: + { + if( (pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VclEventId::ControlGetFocus) || + (!pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VclEventId::WindowGetFocus) ) + { + // if multiple listeners were registered it is possible that the + // focus was changed during event processing (eg SfxTopWindow ) + // #106082# allow ChildPathFocus only for CompoundControls, for windows the focus must be in the window itself + if( (pAccWindow->IsCompoundControl() && pAccWindow->HasChildPathFocus()) || + (!pAccWindow->IsCompoundControl() && pAccWindow->HasFocus()) ) + { + aNewValue <<= accessibility::AccessibleStateType::FOCUSED; + NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + } + } + break; + case VclEventId::WindowLoseFocus: + case VclEventId::ControlLoseFocus: + { + if( (pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VclEventId::ControlLoseFocus) || + (!pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VclEventId::WindowLoseFocus) ) + { + aOldValue <<= accessibility::AccessibleStateType::FOCUSED; + NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + } + break; + case VclEventId::WindowFrameTitleChanged: + { + OUString aOldName( *static_cast<OUString*>(rVclWindowEvent.GetData()) ); + OUString aNewName( getAccessibleName() ); + aOldValue <<= aOldName; + aNewValue <<= aNewName; + NotifyAccessibleEvent( accessibility::AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue ); + } + break; + case VclEventId::WindowEnabled: + { + aNewValue <<= accessibility::AccessibleStateType::ENABLED; + NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + aNewValue <<= accessibility::AccessibleStateType::SENSITIVE; + NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VclEventId::WindowDisabled: + { + aOldValue <<= accessibility::AccessibleStateType::SENSITIVE; + NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + + aOldValue <<= accessibility::AccessibleStateType::ENABLED; + NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VclEventId::WindowMove: + case VclEventId::WindowResize: + { + NotifyAccessibleEvent( accessibility::AccessibleEventId::BOUNDRECT_CHANGED, aOldValue, aNewValue ); + } + break; + case VclEventId::WindowMenubarAdded: + { + MenuBar* pMenuBar = static_cast<MenuBar*>(rVclWindowEvent.GetData()); + if ( pMenuBar ) + { + uno::Reference< accessibility::XAccessible > xChild( pMenuBar->GetAccessible() ); + if ( xChild.is() ) + { + aNewValue <<= xChild; + NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue ); + } + } + } + break; + case VclEventId::WindowMenubarRemoved: + { + MenuBar* pMenuBar = static_cast<MenuBar*>(rVclWindowEvent.GetData()); + if ( pMenuBar ) + { + uno::Reference< accessibility::XAccessible > xChild( pMenuBar->GetAccessible() ); + if ( xChild.is() ) + { + aOldValue <<= xChild; + NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue ); + } + } + } + break; + case VclEventId::WindowMinimize: + { + aNewValue <<= accessibility::AccessibleStateType::ICONIFIED; + NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VclEventId::WindowNormalize: + { + aOldValue <<= accessibility::AccessibleStateType::ICONIFIED; + NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + default: + { + } + break; + } +} + +void VCLXAccessibleComponent::disposing() +{ + DisconnectEvents(); + + OAccessibleExtendedComponentHelper::disposing(); + + m_xVCLXWindow.clear(); +} + +vcl::Window* VCLXAccessibleComponent::GetWindow() const +{ + return GetVCLXWindow() ? GetVCLXWindow()->GetWindow() + : nullptr; +} + +void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ) +{ + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( !pWindow ) + return; + + vcl::Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy(); + if ( pLabeledBy && pLabeledBy != pWindow ) + { + uno::Sequence< uno::Reference< uno::XInterface > > aSequence { pLabeledBy->GetAccessible() }; + rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY, aSequence ) ); + } + + vcl::Window* pLabelFor = pWindow->GetAccessibleRelationLabelFor(); + if ( pLabelFor && pLabelFor != pWindow ) + { + uno::Sequence< uno::Reference< uno::XInterface > > aSequence { pLabelFor->GetAccessible() }; + rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR, aSequence ) ); + } + + vcl::Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf(); + if ( pMemberOf && pMemberOf != pWindow ) + { + uno::Sequence< uno::Reference< uno::XInterface > > aSequence { pMemberOf->GetAccessible() }; + rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) ); + } +} + +void VCLXAccessibleComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) +{ + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + if ( pWindow->IsVisible() ) + { + rStateSet.AddState( accessibility::AccessibleStateType::VISIBLE ); + rStateSet.AddState( accessibility::AccessibleStateType::SHOWING ); + } + else + { + rStateSet.AddState( accessibility::AccessibleStateType::INVALID ); + } + + if ( pWindow->IsEnabled() ) + { + rStateSet.AddState( accessibility::AccessibleStateType::ENABLED ); + rStateSet.AddState( accessibility::AccessibleStateType::SENSITIVE ); + } + + if ( pWindow->HasChildPathFocus() && + ( getAccessibleRole() == accessibility::AccessibleRole::FRAME || + getAccessibleRole() == accessibility::AccessibleRole::ALERT || + getAccessibleRole() == accessibility::AccessibleRole::DIALOG ) ) // #i18891# + rStateSet.AddState( accessibility::AccessibleStateType::ACTIVE ); + + if ( pWindow->HasFocus() || ( pWindow->IsCompoundControl() && pWindow->HasChildPathFocus() ) ) + rStateSet.AddState( accessibility::AccessibleStateType::FOCUSED ); + + if ( pWindow->IsWait() ) + rStateSet.AddState( accessibility::AccessibleStateType::BUSY ); + + if ( pWindow->GetStyle() & WB_SIZEABLE ) + rStateSet.AddState( accessibility::AccessibleStateType::RESIZABLE ); + // 6. frame doesn't have MOVABLE state + // 10. for password text, where is the sensitive state? + if( ( getAccessibleRole() == accessibility::AccessibleRole::FRAME ||getAccessibleRole() == accessibility::AccessibleRole::DIALOG )&& pWindow->GetStyle() & WB_MOVEABLE ) + rStateSet.AddState( accessibility::AccessibleStateType::MOVEABLE ); + if( pWindow->IsDialog() ) + { + Dialog *pDlg = static_cast< Dialog* >( pWindow.get() ); + if( pDlg->IsInExecute() ) + rStateSet.AddState( accessibility::AccessibleStateType::MODAL ); + } + //If a combobox or list's edit child isn't read-only,EDITABLE state + //should be set. + if( pWindow && pWindow->GetType() == WindowType::COMBOBOX ) + { + if( !( pWindow->GetStyle() & WB_READONLY) || + !static_cast<Edit*>(pWindow.get())->IsReadOnly() ) + rStateSet.AddState( accessibility::AccessibleStateType::EDITABLE ); + } + + VclPtr<vcl::Window> pChild = pWindow->GetWindow( GetWindowType::FirstChild ); + + while( pWindow && pChild ) + { + VclPtr<vcl::Window> pWinTemp = pChild->GetWindow( GetWindowType::FirstChild ); + if( pWinTemp && pWinTemp->GetType() == WindowType::EDIT ) + { + if( !( pWinTemp->GetStyle() & WB_READONLY) || + !static_cast<Edit*>(pWinTemp.get())->IsReadOnly() ) + rStateSet.AddState( accessibility::AccessibleStateType::EDITABLE ); + break; + } + if( pChild->GetType() == WindowType::EDIT ) + { + if( !( pChild->GetStyle() & WB_READONLY) || + !static_cast<Edit*>(pChild.get())->IsReadOnly()) + rStateSet.AddState( accessibility::AccessibleStateType::EDITABLE ); + break; + } + pChild = pChild->GetWindow( GetWindowType::Next ); + } + } + else + { + rStateSet.AddState( accessibility::AccessibleStateType::DEFUNC ); + } + +/* + +MUST BE SET FROM DERIVED CLASSES: + +CHECKED +COLLAPSED +EXPANDED +EXPANDABLE +EDITABLE +FOCUSABLE +HORIZONTAL +VERTICAL +ICONIFIED +MULTILINE +MULTI_SELECTABLE +PRESSED +SELECTABLE +SELECTED +SINGLE_LINE +TRANSIENT + + */ +} + + +// accessibility::XAccessibleContext +sal_Int32 VCLXAccessibleComponent::getAccessibleChildCount() +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nChildren = 0; + if ( GetWindow() ) + nChildren = GetWindow()->GetAccessibleChildWindowCount(); + + return nChildren; +} + +uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleChild( sal_Int32 i ) +{ + OExternalLockGuard aGuard( this ); + + if ( i >= getAccessibleChildCount() ) + throw lang::IndexOutOfBoundsException(); + + uno::Reference< accessibility::XAccessible > xAcc; + if ( GetWindow() ) + { + vcl::Window* pChild = GetWindow()->GetAccessibleChildWindow( static_cast<sal_uInt16>(i) ); + if ( pChild ) + xAcc = pChild->GetAccessible(); + } + + return xAcc; +} + +uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getVclParent() const +{ + uno::Reference< accessibility::XAccessible > xAcc; + if ( GetWindow() ) + { + vcl::Window* pParent = GetWindow()->GetAccessibleParentWindow(); + if ( pParent ) + xAcc = pParent->GetAccessible(); + } + return xAcc; +} + +uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleParent( ) +{ + OExternalLockGuard aGuard( this ); + + // we do _not_ have a foreign-controlled parent -> default to our VCL parent + uno::Reference< accessibility::XAccessible > xAcc = getVclParent(); + + return xAcc; +} + +sal_Int32 VCLXAccessibleComponent::getAccessibleIndexInParent( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nIndex = -1; + + if ( GetWindow() ) + { + vcl::Window* pParent = GetWindow()->GetAccessibleParentWindow(); + if ( pParent ) + { + // Iterate over all the parent's children and search for this object. + // this should be compatible with the code in SVX + uno::Reference< accessibility::XAccessible > xParentAcc( pParent->GetAccessible() ); + if ( xParentAcc.is() ) + { + uno::Reference< accessibility::XAccessibleContext > xParentContext ( xParentAcc->getAccessibleContext() ); + if ( xParentContext.is() ) + { + sal_Int32 nChildCount = xParentContext->getAccessibleChildCount(); + for ( sal_Int32 i=0; i<nChildCount; i++ ) + { + uno::Reference< accessibility::XAccessible > xChild( xParentContext->getAccessibleChild(i) ); + if ( xChild.is() ) + { + uno::Reference< accessibility::XAccessibleContext > xChildContext = xChild->getAccessibleContext(); + if ( xChildContext == static_cast<accessibility::XAccessibleContext*>(this) ) + { + nIndex = i; + break; + } + } + } + } + } + } + } + return nIndex; +} + +sal_Int16 VCLXAccessibleComponent::getAccessibleRole( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int16 nRole = 0; + + if ( GetWindow() ) + nRole = GetWindow()->GetAccessibleRole(); + + return nRole; +} + +OUString VCLXAccessibleComponent::getAccessibleDescription( ) +{ + OExternalLockGuard aGuard( this ); + + OUString aDescription; + + if ( GetWindow() ) + aDescription = GetWindow()->GetAccessibleDescription(); + + return aDescription; +} + +OUString VCLXAccessibleComponent::getAccessibleName( ) +{ + OExternalLockGuard aGuard( this ); + + OUString aName; + if ( GetWindow() ) + { + aName = GetWindow()->GetAccessibleName(); +#if OSL_DEBUG_LEVEL > 0 + aName += " (Type = " + OUString::number(static_cast<sal_Int32>(GetWindow()->GetType())) + ")"; +#endif + } + return aName; +} + +OUString VCLXAccessibleComponent::getAccessibleId( ) +{ + OExternalLockGuard aGuard( this ); + + OUString aId; + if ( GetWindow() ) + { + const OUString &aWindowId = GetWindow()->get_id(); + aId = aWindowId; + } + return aId; +} + +uno::Reference< accessibility::XAccessibleRelationSet > VCLXAccessibleComponent::getAccessibleRelationSet( ) +{ + OExternalLockGuard aGuard( this ); + + rtl::Reference<utl::AccessibleRelationSetHelper> pRelationSetHelper = new utl::AccessibleRelationSetHelper; + FillAccessibleRelationSet( *pRelationSetHelper ); + return pRelationSetHelper; +} + +uno::Reference< accessibility::XAccessibleStateSet > VCLXAccessibleComponent::getAccessibleStateSet( ) +{ + OExternalLockGuard aGuard( this ); + + rtl::Reference<utl::AccessibleStateSetHelper> pStateSetHelper = new utl::AccessibleStateSetHelper; + FillAccessibleStateSet( *pStateSetHelper ); + return pStateSetHelper; +} + +lang::Locale VCLXAccessibleComponent::getLocale() +{ + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLanguageTag().getLocale(); +} + +uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + OExternalLockGuard aGuard( this ); + + uno::Reference< accessibility::XAccessible > xChild; + for ( sal_uInt32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i ) + { + uno::Reference< accessibility::XAccessible > xAcc = getAccessibleChild( i ); + if ( xAcc.is() ) + { + uno::Reference< accessibility::XAccessibleComponent > xComp( xAcc->getAccessibleContext(), uno::UNO_QUERY ); + if ( xComp.is() ) + { + tools::Rectangle aRect = VCLRectangle( xComp->getBounds() ); + Point aPos = VCLPoint( rPoint ); + if ( aRect.Contains( aPos ) ) + { + xChild = xAcc; + break; + } + } + } + } + + return xChild; +} + +// accessibility::XAccessibleComponent +awt::Rectangle VCLXAccessibleComponent::implGetBounds() +{ + awt::Rectangle aBounds ( 0, 0, 0, 0 ); + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + tools::Rectangle aRect = pWindow->GetWindowExtentsRelative( nullptr ); + aBounds = AWTRectangle( aRect ); + vcl::Window* pParent = pWindow->GetAccessibleParentWindow(); + if ( pParent ) + { + tools::Rectangle aParentRect = pParent->GetWindowExtentsRelative( nullptr ); + awt::Point aParentScreenLoc = AWTPoint( aParentRect.TopLeft() ); + aBounds.X -= aParentScreenLoc.X; + aBounds.Y -= aParentScreenLoc.Y; + } + } + + return aBounds; +} + +awt::Point VCLXAccessibleComponent::getLocationOnScreen( ) +{ + OExternalLockGuard aGuard( this ); + + awt::Point aPos; + if ( GetWindow() ) + { + tools::Rectangle aRect = GetWindow()->GetWindowExtentsRelative( nullptr ); + aPos.X = aRect.Left(); + aPos.Y = aRect.Top(); + } + + return aPos; +} + +void VCLXAccessibleComponent::grabFocus( ) +{ + OExternalLockGuard aGuard( this ); + + uno::Reference< accessibility::XAccessibleStateSet > xStates = getAccessibleStateSet(); + if ( m_xVCLXWindow.is() && xStates.is() && xStates->contains( accessibility::AccessibleStateType::FOCUSABLE ) ) + m_xVCLXWindow->setFocus(); +} + +sal_Int32 SAL_CALL VCLXAccessibleComponent::getForeground( ) +{ + OExternalLockGuard aGuard( this ); + + Color nColor; + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + if ( pWindow->IsControlForeground() ) + nColor = pWindow->GetControlForeground(); + else + { + vcl::Font aFont; + if ( pWindow->IsControlFont() ) + aFont = pWindow->GetControlFont(); + else + aFont = pWindow->GetFont(); + nColor = aFont.GetColor(); + // COL_AUTO is not very meaningful for AT + if ( nColor == COL_AUTO) + nColor = pWindow->GetTextColor(); + } + } + + return sal_Int32(nColor); +} + +sal_Int32 SAL_CALL VCLXAccessibleComponent::getBackground( ) +{ + OExternalLockGuard aGuard( this ); + + Color nColor; + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + if ( pWindow->IsControlBackground() ) + nColor = pWindow->GetControlBackground(); + else + nColor = pWindow->GetBackground().GetColor(); + } + + return sal_Int32(nColor); +} + +// XAccessibleExtendedComponent + +uno::Reference< awt::XFont > SAL_CALL VCLXAccessibleComponent::getFont( ) +{ + OExternalLockGuard aGuard( this ); + + uno::Reference< awt::XFont > xFont; + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + uno::Reference< awt::XDevice > xDev( pWindow->GetComponentInterface(), uno::UNO_QUERY ); + if ( xDev.is() ) + { + vcl::Font aFont; + if ( pWindow->IsControlFont() ) + aFont = pWindow->GetControlFont(); + else + aFont = pWindow->GetFont(); + rtl::Reference<VCLXFont> pVCLXFont = new VCLXFont; + pVCLXFont->Init( *xDev, aFont ); + xFont = pVCLXFont; + } + } + + return xFont; +} + +OUString SAL_CALL VCLXAccessibleComponent::getTitledBorderText( ) +{ + OExternalLockGuard aGuard( this ); + + OUString sRet; + if ( GetWindow() ) + sRet = GetWindow()->GetText(); + + return sRet; +} + +OUString SAL_CALL VCLXAccessibleComponent::getToolTipText( ) +{ + OExternalLockGuard aGuard( this ); + + OUString sRet; + if ( GetWindow() ) + sRet = GetWindow()->GetQuickHelpText(); + + return sRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxbitmap.cxx b/toolkit/source/awt/vclxbitmap.cxx new file mode 100644 index 000000000..17111311d --- /dev/null +++ b/toolkit/source/awt/vclxbitmap.cxx @@ -0,0 +1,63 @@ +/* -*- 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 <awt/vclxbitmap.hxx> +#include <tools/stream.hxx> +#include <vcl/dibtools.hxx> +#include <vcl/BitmapTools.hxx> + + + + +// css::lang::XUnoTunnel +UNO3_GETIMPLEMENTATION_IMPL( VCLXBitmap ); + +// css::awt::XBitmap +css::awt::Size VCLXBitmap::getSize() +{ + std::scoped_lock aGuard( GetMutex() ); + + css::awt::Size aSize( maBitmap.GetSizePixel().Width(), maBitmap.GetSizePixel().Height() ); + return aSize; +} + +css::uno::Sequence< sal_Int8 > VCLXBitmap::getDIB() +{ + std::scoped_lock aGuard( GetMutex() ); + + SvMemoryStream aMem; + WriteDIB(maBitmap.GetBitmap(), aMem, false, true); + return css::uno::Sequence<sal_Int8>( static_cast<sal_Int8 const *>(aMem.GetData()), aMem.Tell() ); +} + +css::uno::Sequence< sal_Int8 > VCLXBitmap::getMaskDIB() +{ + std::scoped_lock aGuard( GetMutex() ); + + return vcl::bitmap::GetMaskDIB(maBitmap); +} + +sal_Int64 SAL_CALL VCLXBitmap::estimateUsage() +{ + std::scoped_lock aGuard( GetMutex() ); + + return maBitmap.GetSizeBytes(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxcontainer.cxx b/toolkit/source/awt/vclxcontainer.cxx new file mode 100644 index 000000000..05e321d1b --- /dev/null +++ b/toolkit/source/awt/vclxcontainer.cxx @@ -0,0 +1,290 @@ +/* -*- 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 <awt/vclxcontainer.hxx> +#include <toolkit/helper/macros.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <comphelper/interfacecontainer3.hxx> + +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <vcl/tabpage.hxx> +#include <tools/debug.hxx> +#include <helper/scrollabledialog.hxx> +#include <toolkit/helper/property.hxx> + +void VCLXContainer::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + VCLXWindow::ImplGetPropertyIds( rIds ); +} + +VCLXContainer::VCLXContainer() +{ +} + +VCLXContainer::~VCLXContainer() +{ +} + +// css::uno::XInterface +css::uno::Any VCLXContainer::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XVclContainer* >(this), + static_cast< css::awt::XVclContainerPeer* >(this) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXContainer ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXContainer::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XVclContainer>::get(), + cppu::UnoType<css::awt::XVclContainerPeer>::get(), + VCLXWindow::getTypes() + ); + return aTypeList.getTypes(); +} + + +// css::awt::XVclContainer +void VCLXContainer::addVclContainerListener( const css::uno::Reference< css::awt::XVclContainerListener >& rxListener ) +{ + SolarMutexGuard aGuard; + + if (!IsDisposed()) + GetContainerListeners().addInterface( rxListener ); +} + +void VCLXContainer::removeVclContainerListener( const css::uno::Reference< css::awt::XVclContainerListener >& rxListener ) +{ + SolarMutexGuard aGuard; + + if (!IsDisposed()) + GetContainerListeners().removeInterface( rxListener ); +} + +css::uno::Sequence< css::uno::Reference< css::awt::XWindow > > VCLXContainer::getWindows( ) +{ + SolarMutexGuard aGuard; + + // Request container interface from all children + css::uno::Sequence< css::uno::Reference< css::awt::XWindow > > aSeq; + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + sal_uInt16 nChildren = pWindow->GetChildCount(); + if ( nChildren ) + { + aSeq = css::uno::Sequence< css::uno::Reference< css::awt::XWindow > >( nChildren ); + css::uno::Reference< css::awt::XWindow > * pChildRefs = aSeq.getArray(); + for ( sal_uInt16 n = 0; n < nChildren; n++ ) + { + vcl::Window* pChild = pWindow->GetChild( n ); + css::uno::Reference< css::awt::XWindowPeer > xWP = pChild->GetComponentInterface(); + css::uno::Reference< css::awt::XWindow > xW( xWP, css::uno::UNO_QUERY ); + pChildRefs[n] = xW; + } + } + } + return aSeq; +} + + +// css::awt::XVclContainerPeer +void VCLXContainer::enableDialogControl( sal_Bool bEnable ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + WinBits nStyle = pWindow->GetStyle(); + if ( bEnable ) + nStyle |= WB_DIALOGCONTROL; + else + nStyle &= (~WB_DIALOGCONTROL); + pWindow->SetStyle( nStyle ); + } +} + +void VCLXContainer::setTabOrder( const css::uno::Sequence< css::uno::Reference< css::awt::XWindow > >& Components, const css::uno::Sequence< css::uno::Any >& Tabs, sal_Bool bGroupControl ) +{ + SolarMutexGuard aGuard; + + sal_uInt32 nCount = Components.getLength(); + DBG_ASSERT( nCount == static_cast<sal_uInt32>(Tabs.getLength()), "setTabOrder: TabCount != ComponentCount" ); + const css::uno::Reference< css::awt::XWindow > * pComps = Components.getConstArray(); + const css::uno::Any* pTabs = Tabs.getConstArray(); + + vcl::Window* pPrevWin = nullptr; + for ( sal_uInt32 n = 0; n < nCount; n++ ) + { + // css::style::TabStop + VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( pComps[n] ); + // May be NULL if a css::uno::Sequence is originated from TabController and is missing a peer! + if ( pWin ) + { + // Order windows before manipulating their style, because elements such as the + // RadioButton considers the PREV-window in StateChanged. + if ( pPrevWin ) + pWin->SetZOrder( pPrevWin, ZOrderFlags::Behind ); + + WinBits nStyle = pWin->GetStyle(); + nStyle &= ~(WB_TABSTOP|WB_NOTABSTOP|WB_GROUP); + if ( pTabs[n].getValueType().getTypeClass() == css::uno::TypeClass_BOOLEAN ) + { + bool bTab = false; + pTabs[n] >>= bTab; + nStyle |= ( bTab ? WB_TABSTOP : WB_NOTABSTOP ); + } + pWin->SetStyle( nStyle ); + + if ( bGroupControl ) + { + if ( n == 0 ) + pWin->SetDialogControlStart( true ); + else + pWin->SetDialogControlStart( false ); + } + + pPrevWin = pWin; + } + } +} + +void VCLXContainer::setGroup( const css::uno::Sequence< css::uno::Reference< css::awt::XWindow > >& Components ) +{ + SolarMutexGuard aGuard; + + sal_uInt32 nCount = Components.getLength(); + const css::uno::Reference< css::awt::XWindow > * pComps = Components.getConstArray(); + + vcl::Window* pPrevWin = nullptr; + vcl::Window* pPrevRadio = nullptr; + for ( sal_uInt32 n = 0; n < nCount; n++ ) + { + VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( pComps[n] ); + if ( pWin ) + { + vcl::Window* pSortBehind = pPrevWin; + // #57096# Sort all radios consecutively + bool bNewPrevWin = true; + if ( pWin->GetType() == WindowType::RADIOBUTTON ) + { + if ( pPrevRadio ) + { + // This RadioButton was sorted before PrevWin + bNewPrevWin = ( pPrevWin == pPrevRadio ); + pSortBehind = pPrevRadio; + } + pPrevRadio = pWin; + } + + // Z-Order + if ( pSortBehind ) + pWin->SetZOrder( pSortBehind, ZOrderFlags::Behind ); + + WinBits nStyle = pWin->GetStyle(); + if ( n == 0 ) + nStyle |= WB_GROUP; + else + nStyle &= (~WB_GROUP); + pWin->SetStyle( nStyle ); + + // Add WB_GROUP after the last group + if ( n == ( nCount - 1 ) ) + { + vcl::Window* pBehindLast = pWin->GetWindow( GetWindowType::Next ); + if ( pBehindLast ) + { + WinBits nLastStyle = pBehindLast->GetStyle(); + nLastStyle |= WB_GROUP; + pBehindLast->SetStyle( nLastStyle ); + } + } + + if ( bNewPrevWin ) + pPrevWin = pWin; + } + } +} + +void SAL_CALL VCLXContainer::setProperty( + const OUString& PropertyName, + const css::uno::Any& Value ) +{ + SolarMutexGuard aGuard; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_SCROLLHEIGHT: + case BASEPROPERTY_SCROLLWIDTH: + case BASEPROPERTY_SCROLLTOP: + case BASEPROPERTY_SCROLLLEFT: + { + sal_Int32 nVal =0; + Value >>= nVal; + Size aSize( nVal, nVal ); + VclPtr<vcl::Window> pWindow = GetWindow(); + MapMode aMode( MapUnit::MapAppFont ); + toolkit::ScrollableDialog* pScrollable = dynamic_cast< toolkit::ScrollableDialog* >( pWindow.get() ); + TabPage* pScrollTabPage = dynamic_cast< TabPage* >( pWindow.get() ); + if ( pWindow && (pScrollable || pScrollTabPage) ) + { + aSize = pWindow->LogicToPixel( aSize, aMode ); + switch ( nPropType ) + { + case BASEPROPERTY_SCROLLHEIGHT: + pScrollable ? pScrollable->SetScrollHeight( aSize.Height() ) : (void)0; + pScrollTabPage ? pScrollTabPage->SetScrollHeight( aSize.Height() ) : (void)0; + break; + case BASEPROPERTY_SCROLLWIDTH: + pScrollable ? pScrollable->SetScrollWidth( aSize.Width() ) : (void)0; + pScrollTabPage ? pScrollTabPage->SetScrollWidth( aSize.Width() ) : (void)0; + break; + case BASEPROPERTY_SCROLLTOP: + pScrollable ? pScrollable->SetScrollTop( aSize.Height() ) : (void)0; + pScrollTabPage ? pScrollTabPage->SetScrollTop( aSize.Height() ) : (void)0; + break; + case BASEPROPERTY_SCROLLLEFT: + pScrollable ? pScrollable->SetScrollLeft( aSize.Width() ) : (void)0; + pScrollTabPage ? pScrollTabPage->SetScrollLeft( aSize.Width() ) : (void)0; + break; + default: + break; + } + break; + } + break; + } + + default: + { + VCLXWindow::setProperty( PropertyName, Value ); + } + } +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxdevice.cxx b/toolkit/source/awt/vclxdevice.cxx new file mode 100644 index 000000000..5b83b9e62 --- /dev/null +++ b/toolkit/source/awt/vclxdevice.cxx @@ -0,0 +1,254 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <com/sun/star/util/MeasureUnit.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +#include <toolkit/awt/vclxdevice.hxx> +#include <toolkit/awt/vclxfont.hxx> +#include <awt/vclxbitmap.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +#include <vcl/svapp.hxx> +#include <vcl/outdev.hxx> +#include <vcl/virdev.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/metric.hxx> + + +VCLXDevice::VCLXDevice() +{ +} + +VCLXDevice::~VCLXDevice() +{ + //TODO: why was this empty, and everything done in ~VCLXVirtualDevice? + SolarMutexGuard g; + mpOutputDevice.reset(); +} + +// css::lang::XUnoTunnel +UNO3_GETIMPLEMENTATION_IMPL( VCLXDevice ); + +// css::awt::XDevice, +css::uno::Reference< css::awt::XGraphics > VCLXDevice::createGraphics( ) +{ + SolarMutexGuard aGuard; + + css::uno::Reference< css::awt::XGraphics > xRef; + + if ( mpOutputDevice ) + xRef = mpOutputDevice->CreateUnoGraphics(); + + return xRef; +} + +css::uno::Reference< css::awt::XDevice > VCLXDevice::createDevice( sal_Int32 nWidth, sal_Int32 nHeight ) +{ + SolarMutexGuard aGuard; + + css::uno::Reference< css::awt::XDevice > xRef; + if ( GetOutputDevice() ) + { + rtl::Reference<VCLXVirtualDevice> pVDev = new VCLXVirtualDevice; + VclPtrInstance<VirtualDevice> pVclVDev( *GetOutputDevice() ); + pVclVDev->SetOutputSizePixel( Size( nWidth, nHeight ) ); + pVDev->SetVirtualDevice( pVclVDev ); + xRef = pVDev; + } + return xRef; +} + +css::awt::DeviceInfo VCLXDevice::getInfo() +{ + SolarMutexGuard aGuard; + + css::awt::DeviceInfo aInfo; + + if (mpOutputDevice) + aInfo = mpOutputDevice->GetDeviceInfo(); + + return aInfo; +} + +css::uno::Sequence< css::awt::FontDescriptor > VCLXDevice::getFontDescriptors( ) +{ + SolarMutexGuard aGuard; + + css::uno::Sequence< css::awt::FontDescriptor> aFonts; + if( mpOutputDevice ) + { + int nFonts = mpOutputDevice->GetFontFaceCollectionCount(); + if ( nFonts ) + { + aFonts = css::uno::Sequence< css::awt::FontDescriptor>( nFonts ); + css::awt::FontDescriptor* pFonts = aFonts.getArray(); + for ( int n = 0; n < nFonts; n++ ) + pFonts[n] = VCLUnoHelper::CreateFontDescriptor( mpOutputDevice->GetFontMetricFromCollection( n ) ); + } + } + return aFonts; +} + +css::uno::Reference< css::awt::XFont > VCLXDevice::getFont( const css::awt::FontDescriptor& rDescriptor ) +{ + SolarMutexGuard aGuard; + + css::uno::Reference< css::awt::XFont > xRef; + if( mpOutputDevice ) + { + rtl::Reference<VCLXFont> pMetric = new VCLXFont; + pMetric->Init( *this, VCLUnoHelper::CreateFont( rDescriptor, mpOutputDevice->GetFont() ) ); + xRef = pMetric; + } + return xRef; +} + +css::uno::Reference< css::awt::XBitmap > VCLXDevice::createBitmap( sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight ) +{ + SolarMutexGuard aGuard; + + css::uno::Reference< css::awt::XBitmap > xBmp; + if( mpOutputDevice ) + { + BitmapEx aBmp = mpOutputDevice->GetBitmapEx( Point( nX, nY ), Size( nWidth, nHeight ) ); + + rtl::Reference<VCLXBitmap> pBmp = new VCLXBitmap; + pBmp->SetBitmap( aBmp ); + xBmp = pBmp; + } + return xBmp; +} + +css::uno::Reference< css::awt::XDisplayBitmap > VCLXDevice::createDisplayBitmap( const css::uno::Reference< css::awt::XBitmap >& rxBitmap ) +{ + SolarMutexGuard aGuard; + + BitmapEx aBmp = VCLUnoHelper::GetBitmap( rxBitmap ); + rtl::Reference<VCLXBitmap> pBmp = new VCLXBitmap; + pBmp->SetBitmap( aBmp ); + return pBmp; +} + +VCLXVirtualDevice::~VCLXVirtualDevice() +{ + SolarMutexGuard aGuard; + + mpOutputDevice.disposeAndClear(); +} + +// Interface implementation of css::awt::XUnitConversion + +css::awt::Point SAL_CALL VCLXDevice::convertPointToLogic( const css::awt::Point& aPoint, ::sal_Int16 TargetUnit ) +{ + SolarMutexGuard aGuard; + if (TargetUnit == css::util::MeasureUnit::PERCENT ) + { + // percentage not allowed here + throw css::lang::IllegalArgumentException(); + } + + css::awt::Point aAWTPoint(0,0); + // X,Y + + if( mpOutputDevice ) + { + MapMode aMode(VCLUnoHelper::ConvertToMapModeUnit(TargetUnit)); + ::Point aVCLPoint = VCLUnoHelper::ConvertToVCLPoint(aPoint); + ::Point aDevPoint = mpOutputDevice->PixelToLogic(aVCLPoint, aMode ); + aAWTPoint = VCLUnoHelper::ConvertToAWTPoint(aDevPoint); + } + + return aAWTPoint; +} + + +css::awt::Point SAL_CALL VCLXDevice::convertPointToPixel( const css::awt::Point& aPoint, ::sal_Int16 SourceUnit ) +{ + SolarMutexGuard aGuard; + if (SourceUnit == css::util::MeasureUnit::PERCENT || + SourceUnit == css::util::MeasureUnit::PIXEL ) + { + // pixel or percentage not allowed here + throw css::lang::IllegalArgumentException(); + } + + css::awt::Point aAWTPoint(0,0); + + if( mpOutputDevice ) + { + MapMode aMode(VCLUnoHelper::ConvertToMapModeUnit(SourceUnit)); + ::Point aVCLPoint = VCLUnoHelper::ConvertToVCLPoint(aPoint); + ::Point aDevPoint = mpOutputDevice->LogicToPixel(aVCLPoint, aMode ); + aAWTPoint = VCLUnoHelper::ConvertToAWTPoint(aDevPoint); + } + + return aAWTPoint; +} + +css::awt::Size SAL_CALL VCLXDevice::convertSizeToLogic( const css::awt::Size& aSize, ::sal_Int16 TargetUnit ) +{ + SolarMutexGuard aGuard; + if (TargetUnit == css::util::MeasureUnit::PERCENT) + { + // percentage not allowed here + throw css::lang::IllegalArgumentException(); + } + + css::awt::Size aAWTSize(0,0); + // Width, Height + + + if( mpOutputDevice ) + { + MapMode aMode(VCLUnoHelper::ConvertToMapModeUnit(TargetUnit)); + ::Size aVCLSize = VCLUnoHelper::ConvertToVCLSize(aSize); + ::Size aDevSz = mpOutputDevice->PixelToLogic(aVCLSize, aMode ); + aAWTSize = VCLUnoHelper::ConvertToAWTSize(aDevSz); + } + + return aAWTSize; +} + +css::awt::Size SAL_CALL VCLXDevice::convertSizeToPixel( const css::awt::Size& aSize, ::sal_Int16 SourceUnit ) +{ + SolarMutexGuard aGuard; + if (SourceUnit == css::util::MeasureUnit::PERCENT || + SourceUnit == css::util::MeasureUnit::PIXEL) + { + // pixel or percentage not allowed here + throw css::lang::IllegalArgumentException(); + } + + css::awt::Size aAWTSize(0,0); + // Width, Height + if( mpOutputDevice ) + { + MapMode aMode(VCLUnoHelper::ConvertToMapModeUnit(SourceUnit)); + ::Size aVCLSize = VCLUnoHelper::ConvertToVCLSize(aSize); + ::Size aDevSz = mpOutputDevice->LogicToPixel(aVCLSize, aMode ); + aAWTSize = VCLUnoHelper::ConvertToAWTSize(aDevSz); + } + + return aAWTSize; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxfont.cxx b/toolkit/source/awt/vclxfont.cxx new file mode 100644 index 000000000..e84fe338c --- /dev/null +++ b/toolkit/source/awt/vclxfont.cxx @@ -0,0 +1,191 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <memory> + +#include <com/sun/star/awt/XDevice.hpp> + +#include <comphelper/sequence.hxx> +#include <toolkit/awt/vclxfont.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +#include <vcl/metric.hxx> +#include <vcl/outdev.hxx> +#include <vcl/svapp.hxx> + + + +VCLXFont::VCLXFont() +{ + mpFontMetric = nullptr; +} + +VCLXFont::~VCLXFont() +{ +} + +void VCLXFont::Init( css::awt::XDevice& rxDev, const vcl::Font& rFont ) +{ + mxDevice = &rxDev; + + mpFontMetric.reset(); + + maFont = rFont; +} + +bool VCLXFont::ImplAssertValidFontMetric() +{ + if ( !mpFontMetric && mxDevice.is() ) + { + OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); + if ( pOutDev ) + { + vcl::Font aOldFont = pOutDev->GetFont(); + pOutDev->SetFont( maFont ); + mpFontMetric.reset( new FontMetric( pOutDev->GetFontMetric() ) ); + pOutDev->SetFont( aOldFont ); + } + } + return mpFontMetric != nullptr; +} + +// css::lang::XUnoTunnel +UNO3_GETIMPLEMENTATION_IMPL( VCLXFont ); + +css::awt::FontDescriptor VCLXFont::getFontDescriptor( ) +{ + std::unique_lock aGuard( maMutex ); + + return VCLUnoHelper::CreateFontDescriptor( maFont ); + +} + +css::awt::SimpleFontMetric VCLXFont::getFontMetric( ) +{ + std::unique_lock aGuard( maMutex ); + + css::awt::SimpleFontMetric aFM; + if ( ImplAssertValidFontMetric() ) + aFM = VCLUnoHelper::CreateFontMetric( *mpFontMetric ); + return aFM; +} + +sal_Int16 VCLXFont::getCharWidth( sal_Unicode c ) +{ + std::unique_lock aGuard( maMutex ); + + sal_Int16 nRet = -1; + OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); + if ( pOutDev ) + { + vcl::Font aOldFont = pOutDev->GetFont(); + pOutDev->SetFont( maFont ); + + nRet = sal::static_int_cast< sal_Int16 >( + pOutDev->GetTextWidth( OUString(c) )); + + pOutDev->SetFont( aOldFont ); + } + return nRet; +} + +css::uno::Sequence< sal_Int16 > VCLXFont::getCharWidths( sal_Unicode nFirst, sal_Unicode nLast ) +{ + std::unique_lock aGuard( maMutex ); + + css::uno::Sequence<sal_Int16> aSeq; + OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); + if ( pOutDev ) + { + vcl::Font aOldFont = pOutDev->GetFont(); + pOutDev->SetFont( maFont ); + + sal_Int16 nCount = nLast-nFirst + 1; + aSeq = css::uno::Sequence<sal_Int16>( nCount ); + for ( sal_uInt16 n = 0; n < nCount; n++ ) + { + aSeq.getArray()[n] = sal::static_int_cast< sal_Int16 >( + pOutDev->GetTextWidth( + OUString(static_cast< sal_Unicode >(nFirst+n)) )); + } + + pOutDev->SetFont( aOldFont ); + } + return aSeq; +} + +sal_Int32 VCLXFont::getStringWidth( const OUString& str ) +{ + std::unique_lock aGuard( maMutex ); + + sal_Int32 nRet = -1; + OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); + if ( pOutDev ) + { + vcl::Font aOldFont = pOutDev->GetFont(); + pOutDev->SetFont( maFont ); + nRet = pOutDev->GetTextWidth( str ); + pOutDev->SetFont( aOldFont ); + } + return nRet; +} + +sal_Int32 VCLXFont::getStringWidthArray( const OUString& str, css::uno::Sequence< sal_Int32 >& rDXArray ) +{ + std::unique_lock aGuard( maMutex ); + + sal_Int32 nRet = -1; + OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); + if ( pOutDev ) + { + vcl::Font aOldFont = pOutDev->GetFont(); + pOutDev->SetFont( maFont ); + std::vector<sal_Int32> aDXA; + nRet = pOutDev->GetTextArray( str, &aDXA ); + // I don't know if size of aDXA is guaranteed same as length of str, so use arrayToSequence + rDXArray = comphelper::arrayToSequence<sal_Int32>(aDXA.data(), str.getLength()); + pOutDev->SetFont( aOldFont ); + } + return nRet; +} + +void VCLXFont::getKernPairs( css::uno::Sequence< sal_Unicode >& /*rnChars1*/, css::uno::Sequence< sal_Unicode >& /*rnChars2*/, css::uno::Sequence< sal_Int16 >& /*rnKerns*/ ) +{ + // NOTE: this empty method is just used for keeping the related UNO-API stable +} + +// css::awt::XFont2 +sal_Bool VCLXFont::hasGlyphs( const OUString& aText ) +{ + std::unique_lock aGuard( maMutex ); + SolarMutexGuard aSolarGuard; + + OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); + if ( pOutDev ) + { + if ( pOutDev->HasGlyphs( maFont, aText ) == -1 ) + { + return true; + } + } + + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxgraphics.cxx b/toolkit/source/awt/vclxgraphics.cxx new file mode 100644 index 000000000..a8409a5cf --- /dev/null +++ b/toolkit/source/awt/vclxgraphics.cxx @@ -0,0 +1,490 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <memory> +#include <awt/vclxgraphics.hxx> +#include <toolkit/awt/vclxdevice.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +#include <vcl/svapp.hxx> +#include <vcl/outdev.hxx> +#include <vcl/image.hxx> +#include <vcl/gradient.hxx> +#include <vcl/metric.hxx> +#include <tools/debug.hxx> + +using namespace com::sun::star; + + + +// lang::XUnoTunnel +UNO3_GETIMPLEMENTATION_IMPL( VCLXGraphics ); + +VCLXGraphics::VCLXGraphics() + : mpOutputDevice(nullptr) + , meRasterOp(RasterOp::OverPaint) +{ +} + +VCLXGraphics::~VCLXGraphics() +{ + std::vector< VCLXGraphics* > *pLst = mpOutputDevice ? mpOutputDevice->GetUnoGraphicsList() : nullptr; + if ( pLst ) + { + auto it = std::find(pLst->begin(), pLst->end(), this); + if (it != pLst->end()) + pLst->erase( it ); + } + + mpClipRegion.reset(); + + SolarMutexGuard g; + mpOutputDevice.reset(); +} + +void VCLXGraphics::SetOutputDevice( OutputDevice* pOutDev ) +{ + mpOutputDevice = pOutDev; + mxDevice = nullptr; + initAttrs(); +} + +void VCLXGraphics::Init( OutputDevice* pOutDev ) +{ + DBG_ASSERT( !mpOutputDevice, "VCLXGraphics::Init already has pOutDev !" ); + mpOutputDevice = pOutDev; + + initAttrs(); + mpClipRegion = nullptr; + + // Register at OutputDevice + std::vector< VCLXGraphics* > *pLst = mpOutputDevice->GetUnoGraphicsList(); + if ( !pLst ) + pLst = mpOutputDevice->CreateUnoGraphicsList(); + pLst->push_back( this ); +} + +void VCLXGraphics::initAttrs() +{ + if ( !mpOutputDevice ) + return; + + maFont = mpOutputDevice->GetFont(); + maTextColor = mpOutputDevice->GetTextColor(); /* COL_BLACK */ + maTextFillColor = mpOutputDevice->GetTextFillColor(); /* COL_TRANSPARENT */ + maLineColor = mpOutputDevice->GetLineColor(); /* COL_BLACK */ + maFillColor = mpOutputDevice->GetFillColor(); /* COL_WHITE */ + meRasterOp = mpOutputDevice->GetRasterOp(); /* RasterOp::OverPaint */ +} + +void VCLXGraphics::InitOutputDevice( InitOutDevFlags nFlags ) +{ + if(!mpOutputDevice) + return; + + SolarMutexGuard aVclGuard; + + if ( nFlags & InitOutDevFlags::FONT ) + { + mpOutputDevice->SetFont( maFont ); + mpOutputDevice->SetTextColor( maTextColor ); + mpOutputDevice->SetTextFillColor( maTextFillColor ); + } + + if ( nFlags & InitOutDevFlags::COLORS ) + { + mpOutputDevice->SetLineColor( maLineColor ); + mpOutputDevice->SetFillColor( maFillColor ); + } + + mpOutputDevice->SetRasterOp( meRasterOp ); + + if( mpClipRegion ) + mpOutputDevice->SetClipRegion( *mpClipRegion ); + else + mpOutputDevice->SetClipRegion(); +} + +uno::Reference< awt::XDevice > VCLXGraphics::getDevice() +{ + SolarMutexGuard aGuard; + + if( !mxDevice.is() && mpOutputDevice ) + { + rtl::Reference<VCLXDevice> pDev = new VCLXDevice; + pDev->SetOutputDevice( mpOutputDevice ); + mxDevice = pDev; + } + return mxDevice; +} + +awt::SimpleFontMetric VCLXGraphics::getFontMetric() +{ + SolarMutexGuard aGuard; + + awt::SimpleFontMetric aM; + if( mpOutputDevice ) + { + mpOutputDevice->SetFont( maFont ); + aM = VCLUnoHelper::CreateFontMetric( mpOutputDevice->GetFontMetric() ); + } + return aM; +} + +void VCLXGraphics::setFont( const uno::Reference< awt::XFont >& rxFont ) +{ + SolarMutexGuard aGuard; + + maFont = VCLUnoHelper::CreateFont( rxFont ); +} + +void VCLXGraphics::selectFont( const awt::FontDescriptor& rDescription ) +{ + SolarMutexGuard aGuard; + + maFont = VCLUnoHelper::CreateFont( rDescription, vcl::Font() ); +} + +void VCLXGraphics::setTextColor( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + maTextColor = Color( ColorTransparency, nColor ); +} + +void VCLXGraphics::setTextFillColor( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + maTextFillColor = Color( ColorTransparency, nColor ); +} + +void VCLXGraphics::setLineColor( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + maLineColor = Color( ColorTransparency, nColor ); +} + +void VCLXGraphics::setFillColor( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + maFillColor = Color( ColorTransparency, nColor ); +} + +void VCLXGraphics::setRasterOp( awt::RasterOperation eROP ) +{ + SolarMutexGuard aGuard; + + meRasterOp = static_cast<RasterOp>(eROP); +} + +void VCLXGraphics::setClipRegion( const uno::Reference< awt::XRegion >& rxRegion ) +{ + SolarMutexGuard aGuard; + + if ( rxRegion.is() ) + mpClipRegion.reset( new vcl::Region( VCLUnoHelper::GetRegion( rxRegion ) ) ); + else + mpClipRegion.reset(); +} + +void VCLXGraphics::intersectClipRegion( const uno::Reference< awt::XRegion >& rxRegion ) +{ + SolarMutexGuard aGuard; + + if ( rxRegion.is() ) + { + vcl::Region aRegion( VCLUnoHelper::GetRegion( rxRegion ) ); + if ( !mpClipRegion ) + mpClipRegion.reset( new vcl::Region( aRegion ) ); + else + mpClipRegion->Intersect( aRegion ); + } +} + +void VCLXGraphics::push( ) +{ + SolarMutexGuard aGuard; + + + if( mpOutputDevice ) + mpOutputDevice->Push(); +} + +void VCLXGraphics::pop( ) +{ + SolarMutexGuard aGuard; + + + if( mpOutputDevice ) + mpOutputDevice->Pop(); +} + +void VCLXGraphics::clear( + const awt::Rectangle& aRect ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + const ::tools::Rectangle aVCLRect = VCLUnoHelper::ConvertToVCLRect( aRect ); + mpOutputDevice->Erase( aVCLRect ); + } +} + +void VCLXGraphics::copy( const uno::Reference< awt::XDevice >& rxSource, sal_Int32 nSourceX, sal_Int32 nSourceY, sal_Int32 nSourceWidth, sal_Int32 nSourceHeight, sal_Int32 nDestX, sal_Int32 nDestY, sal_Int32 nDestWidth, sal_Int32 nDestHeight ) +{ + SolarMutexGuard aGuard; + + if ( mpOutputDevice ) + { + VCLXDevice* pFromDev = comphelper::getFromUnoTunnel<VCLXDevice>( rxSource ); + DBG_ASSERT( pFromDev, "VCLXGraphics::copy - invalid device" ); + if ( pFromDev ) + { + InitOutputDevice( InitOutDevFlags::NONE ); + mpOutputDevice->DrawOutDev( Point( nDestX, nDestY ), Size( nDestWidth, nDestHeight ), + Point( nSourceX, nSourceY ), Size( nSourceWidth, nSourceHeight ), *pFromDev->GetOutputDevice() ); + } + } +} + +void VCLXGraphics::draw( const uno::Reference< awt::XDisplayBitmap >& rxBitmapHandle, sal_Int32 nSourceX, sal_Int32 nSourceY, sal_Int32 nSourceWidth, sal_Int32 nSourceHeight, sal_Int32 nDestX, sal_Int32 nDestY, sal_Int32 nDestWidth, sal_Int32 nDestHeight ) +{ + SolarMutexGuard aGuard; + + if( !mpOutputDevice ) + return; + + InitOutputDevice( InitOutDevFlags::NONE); + uno::Reference< awt::XBitmap > xBitmap( rxBitmapHandle, uno::UNO_QUERY ); + BitmapEx aBmpEx = VCLUnoHelper::GetBitmap( xBitmap ); + + Point aPos(nDestX - nSourceX, nDestY - nSourceY); + Size aSz = aBmpEx.GetSizePixel(); + + if(nDestWidth != nSourceWidth) + { + float zoomX = static_cast<float>(nDestWidth) / static_cast<float>(nSourceWidth); + aSz.setWidth( static_cast<tools::Long>(static_cast<float>(aSz.Width()) * zoomX) ); + } + + if(nDestHeight != nSourceHeight) + { + float zoomY = static_cast<float>(nDestHeight) / static_cast<float>(nSourceHeight); + aSz.setHeight( static_cast<tools::Long>(static_cast<float>(aSz.Height()) * zoomY) ); + } + + if(nSourceX || nSourceY || aSz.Width() != nSourceWidth || aSz.Height() != nSourceHeight) + mpOutputDevice->IntersectClipRegion(vcl::Region(tools::Rectangle(nDestX, nDestY, nDestX + nDestWidth - 1, nDestY + nDestHeight - 1))); + + mpOutputDevice->DrawBitmapEx( aPos, aSz, aBmpEx ); +} + +void VCLXGraphics::drawPixel( sal_Int32 x, sal_Int32 y ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawPixel( Point( x, y ) ); + } +} + +void VCLXGraphics::drawLine( sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawLine( Point( x1, y1 ), Point( x2, y2 ) ); + } +} + +void VCLXGraphics::drawRect( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawRect( tools::Rectangle( Point( x, y ), Size( width, height ) ) ); + } +} + +void VCLXGraphics::drawRoundedRect( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 nHorzRound, sal_Int32 nVertRound ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawRect( tools::Rectangle( Point( x, y ), Size( width, height ) ), nHorzRound, nVertRound ); + } +} + +void VCLXGraphics::drawPolyLine( const uno::Sequence< sal_Int32 >& DataX, const uno::Sequence< sal_Int32 >& DataY ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawPolyLine( VCLUnoHelper::CreatePolygon( DataX, DataY ) ); + } +} + +void VCLXGraphics::drawPolygon( const uno::Sequence< sal_Int32 >& DataX, const uno::Sequence< sal_Int32 >& DataY ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawPolygon( VCLUnoHelper::CreatePolygon( DataX, DataY ) ); + } +} + +void VCLXGraphics::drawPolyPolygon( const uno::Sequence< uno::Sequence< sal_Int32 > >& DataX, const uno::Sequence< uno::Sequence< sal_Int32 > >& DataY ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + sal_uInt16 nPolys = static_cast<sal_uInt16>(DataX.getLength()); + tools::PolyPolygon aPolyPoly( nPolys ); + for ( sal_uInt16 n = 0; n < nPolys; n++ ) + aPolyPoly[n] = VCLUnoHelper::CreatePolygon( DataX.getConstArray()[n], DataY.getConstArray()[n] ); + + mpOutputDevice->DrawPolyPolygon( aPolyPoly ); + } +} + +void VCLXGraphics::drawEllipse( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawEllipse( tools::Rectangle( Point( x, y ), Size( width, height ) ) ); + } +} + +void VCLXGraphics::drawArc( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawArc( tools::Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) ); + } +} + +void VCLXGraphics::drawPie( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawPie( tools::Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) ); + } +} + +void VCLXGraphics::drawChord( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawChord( tools::Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) ); + } +} + +void VCLXGraphics::drawGradient( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, const awt::Gradient& rGradient ) +{ + SolarMutexGuard aGuard; + + if( !mpOutputDevice ) + return; + + InitOutputDevice( InitOutDevFlags::COLORS ); + Gradient aGradient(static_cast<GradientStyle>(rGradient.Style), Color(ColorTransparency, rGradient.StartColor), Color(ColorTransparency, rGradient.EndColor)); + aGradient.SetAngle(Degree10(rGradient.Angle)); + aGradient.SetBorder(rGradient.Border); + aGradient.SetOfsX(rGradient.XOffset); + aGradient.SetOfsY(rGradient.YOffset); + aGradient.SetStartIntensity(rGradient.StartIntensity); + aGradient.SetEndIntensity(rGradient.EndIntensity); + aGradient.SetSteps(rGradient.StepCount); + mpOutputDevice->DrawGradient( tools::Rectangle( Point( x, y ), Size( width, height ) ), aGradient ); +} + +void VCLXGraphics::drawText( sal_Int32 x, sal_Int32 y, const OUString& rText ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS |InitOutDevFlags::FONT); + mpOutputDevice->DrawText( Point( x, y ), rText ); + } +} + +void VCLXGraphics::drawTextArray( sal_Int32 x, sal_Int32 y, const OUString& rText, const uno::Sequence< sal_Int32 >& rLongs ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS|InitOutDevFlags::FONT ); + std::vector<sal_Int32> aDXA(rText.getLength()); + for(int i = 0; i < rText.getLength(); i++) + { + aDXA[i] = rLongs[i]; + } + mpOutputDevice->DrawTextArray( Point( x, y ), rText, aDXA ); + } +} + + +void VCLXGraphics::drawImage( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int16 nStyle, const uno::Reference< graphic::XGraphic >& xGraphic ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice && xGraphic.is() ) + { + Image aImage( xGraphic ); + if ( !!aImage ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawImage( Point( x, y ), Size( width, height ), aImage, static_cast<DrawImageFlags>(nStyle) ); + } + } +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxmenu.cxx b/toolkit/source/awt/vclxmenu.cxx new file mode 100644 index 000000000..b17f32c2a --- /dev/null +++ b/toolkit/source/awt/vclxmenu.cxx @@ -0,0 +1,872 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <toolkit/awt/vclxmenu.hxx> +#include <toolkit/helper/convert.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <tools/debug.hxx> +#include <vcl/dialoghelper.hxx> +#include <vcl/graph.hxx> +#include <vcl/menu.hxx> +#include <vcl/keycod.hxx> +#include <vcl/image.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> + +#include <com/sun/star/awt/KeyModifier.hpp> + +VCLXMenu::VCLXMenu() + : maMenuListeners( *this ) + , mnDefaultItem(0) +{ + mpMenu = nullptr; +} + +VCLXMenu::VCLXMenu( Menu* pMenu ) + : maMenuListeners( *this ) + , mnDefaultItem(0) +{ + mpMenu = pMenu; +} + +VCLXMenu::~VCLXMenu() +{ + maPopupMenuRefs.clear(); + if ( mpMenu ) + { + SolarMutexGuard g; + mpMenu->RemoveEventListener( LINK( this, VCLXMenu, MenuEventListener ) ); + mpMenu.disposeAndClear(); + } +} + +bool VCLXMenu::IsPopupMenu() const +{ + return (mpMenu && ! mpMenu->IsMenuBar()); +} + +void VCLXMenu::ImplCreateMenu( bool bPopup ) +{ + DBG_ASSERT( !mpMenu, "CreateMenu: Menu exists!" ); + + if ( bPopup ) + mpMenu = VclPtr<PopupMenu>::Create(); + else + mpMenu = VclPtr<MenuBar>::Create(); + + mpMenu->AddEventListener( LINK( this, VCLXMenu, MenuEventListener ) ); +} + +void VCLXMenu::ImplAddListener() +{ + assert(mpMenu); + mpMenu->AddEventListener( LINK( this, VCLXMenu, MenuEventListener ) ); +} + +IMPL_LINK( VCLXMenu, MenuEventListener, VclMenuEvent&, rMenuEvent, void ) +{ + DBG_ASSERT( rMenuEvent.GetMenu() && mpMenu, "Menu???" ); + + if ( rMenuEvent.GetMenu() != mpMenu ) // Also called for the root menu + return; + + switch ( rMenuEvent.GetId() ) + { + case VclEventId::MenuSelect: + { + if ( maMenuListeners.getLength() ) + { + css::awt::MenuEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.MenuId = mpMenu->GetCurItemId(); + maMenuListeners.itemSelected( aEvent ); + } + } + break; + case VclEventId::ObjectDying: + { + mpMenu = nullptr; + } + break; + case VclEventId::MenuHighlight: + { + if ( maMenuListeners.getLength() ) + { + css::awt::MenuEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.MenuId = mpMenu->GetCurItemId(); + maMenuListeners.itemHighlighted( aEvent ); + } + } + break; + case VclEventId::MenuActivate: + { + if ( maMenuListeners.getLength() ) + { + css::awt::MenuEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.MenuId = mpMenu->GetCurItemId(); + maMenuListeners.itemActivated( aEvent ); + } + } + break; + case VclEventId::MenuDeactivate: + { + if ( maMenuListeners.getLength() ) + { + css::awt::MenuEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.MenuId = mpMenu->GetCurItemId(); + maMenuListeners.itemDeactivated( aEvent ); + } + } + break; + + // ignore accessibility events + case VclEventId::MenuEnable: + case VclEventId::MenuInsertItem: + case VclEventId::MenuRemoveItem: + case VclEventId::MenuSubmenuActivate: + case VclEventId::MenuSubmenuDeactivate: + case VclEventId::MenuSubmenuChanged: + case VclEventId::MenuDehighlight: + case VclEventId::MenuDisable: + case VclEventId::MenuItemTextChanged: + case VclEventId::MenuItemChecked: + case VclEventId::MenuItemUnchecked: + case VclEventId::MenuShow: + case VclEventId::MenuHide: + break; + + default: OSL_FAIL( "MenuEventListener - Unknown event!" ); + } +} + + +OUString SAL_CALL VCLXMenu::getImplementationName( ) +{ + std::unique_lock aGuard( maMutex ); + const bool bIsPopupMenu = IsPopupMenu(); + aGuard.unlock(); + + OUString implName( "stardiv.Toolkit." ); + if ( bIsPopupMenu ) + implName += "VCLXPopupMenu"; + else + implName += "VCLXMenuBar"; + + return implName; +} + +css::uno::Sequence< OUString > SAL_CALL VCLXMenu::getSupportedServiceNames( ) +{ + std::unique_lock aGuard( maMutex ); + const bool bIsPopupMenu = IsPopupMenu(); + aGuard.unlock(); + + if ( bIsPopupMenu ) + return css::uno::Sequence<OUString>{ + "com.sun.star.awt.PopupMenu", + "stardiv.vcl.PopupMenu"}; + else + return css::uno::Sequence<OUString>{ + "com.sun.star.awt.MenuBar", + "stardiv.vcl.MenuBar"}; +} + +sal_Bool SAL_CALL VCLXMenu::supportsService(const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Any VCLXMenu::queryInterface( + const css::uno::Type & rType ) +{ + std::unique_lock aGuard( maMutex ); + const bool bIsPopupMenu = IsPopupMenu(); + aGuard.unlock(); + + css::uno::Any aRet; + + if ( bIsPopupMenu ) + aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XMenu* >(static_cast<css::awt::XMenuBar*>(this)), + static_cast< css::awt::XPopupMenu* >(this), + static_cast< css::lang::XTypeProvider* >(this), + static_cast< css::lang::XServiceInfo* >(this), + static_cast< css::lang::XUnoTunnel* >(this) ); + else + aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XMenu* >(static_cast<css::awt::XMenuBar*>(this)), + static_cast< css::awt::XMenuBar* >(this), + static_cast< css::lang::XTypeProvider* >(this), + static_cast< css::lang::XServiceInfo* >(this), + static_cast< css::lang::XUnoTunnel* >(this) ); + + return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); +} + + +UNO3_GETIMPLEMENTATION_IMPL( VCLXMenu ); + +css::uno::Sequence< css::uno::Type > VCLXMenu::getTypes() +{ + std::unique_lock aGuard( maMutex ); + const bool bIsPopupMenu = IsPopupMenu(); + aGuard.unlock(); + + if ( bIsPopupMenu ) + { + static cppu::OTypeCollection collectionPopupMenu( + cppu::UnoType<css::lang::XTypeProvider>::get(), cppu::UnoType<css::awt::XMenu>::get(), + cppu::UnoType<css::awt::XPopupMenu>::get(), + cppu::UnoType<css::lang::XServiceInfo>::get()); + return collectionPopupMenu.getTypes(); + } + else + { + static cppu::OTypeCollection collectionMenuBar( + cppu::UnoType<css::lang::XTypeProvider>::get(), cppu::UnoType<css::awt::XMenu>::get(), + cppu::UnoType<css::awt::XMenuBar>::get(), + cppu::UnoType<css::lang::XServiceInfo>::get()); + return collectionMenuBar.getTypes(); + } +} + + +css::uno::Sequence< sal_Int8 > VCLXMenu::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +void VCLXMenu::addMenuListener( + const css::uno::Reference< css::awt::XMenuListener >& rxListener ) +{ + std::unique_lock aGuard( maMutex ); + + maMenuListeners.addInterface( rxListener ); +} + +void VCLXMenu::removeMenuListener( + const css::uno::Reference< css::awt::XMenuListener >& rxListener ) +{ + std::unique_lock aGuard( maMutex ); + + maMenuListeners.removeInterface( rxListener ); +} + +void VCLXMenu::insertItem( + sal_Int16 nItemId, + const OUString& aText, + sal_Int16 nItemStyle, + sal_Int16 nPos ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu ) + mpMenu->InsertItem(nItemId, aText, static_cast<MenuItemBits>(nItemStyle), OString(), nPos); +} + +void VCLXMenu::removeItem( + sal_Int16 nPos, + sal_Int16 nCount ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if (!mpMenu) + return; + + sal_Int32 nItemCount = static_cast<sal_Int32>(mpMenu->GetItemCount()); + if ((nCount > 0) && (nPos >= 0) && (nPos < nItemCount)) + { + sal_Int16 nP = sal::static_int_cast< sal_Int16 >( + std::min( static_cast<int>(nPos+nCount), static_cast<int>(nItemCount) )); + while( nP-nPos > 0 ) + mpMenu->RemoveItem( --nP ); + } +} + +sal_Int16 VCLXMenu::getItemCount( ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + return mpMenu ? mpMenu->GetItemCount() : 0; +} + +sal_Int16 VCLXMenu::getItemId( + sal_Int16 nPos ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + return mpMenu ? mpMenu->GetItemId( nPos ) : 0; +} + +sal_Int16 VCLXMenu::getItemPos( + sal_Int16 nId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + return mpMenu ? mpMenu->GetItemPos( nId ) : 0; +} + +void VCLXMenu::enableItem( + sal_Int16 nItemId, + sal_Bool bEnable ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu ) + mpMenu->EnableItem( nItemId, bEnable ); +} + +sal_Bool VCLXMenu::isItemEnabled( + sal_Int16 nItemId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + return mpMenu && mpMenu->IsItemEnabled( nItemId ); +} + +void VCLXMenu::setItemText( + sal_Int16 nItemId, + const OUString& aText ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu ) + mpMenu->SetItemText( nItemId, aText ); +} + +OUString VCLXMenu::getItemText( + sal_Int16 nItemId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + OUString aItemText; + if ( mpMenu ) + aItemText = mpMenu->GetItemText( nItemId ); + return aItemText; +} + +void VCLXMenu::setPopupMenu( + sal_Int16 nItemId, + const css::uno::Reference< css::awt::XPopupMenu >& rxPopupMenu ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + VCLXMenu* pVCLMenu = comphelper::getFromUnoTunnel<VCLXMenu>( rxPopupMenu ); + DBG_ASSERT( pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu(), "setPopupMenu: Invalid Menu!" ); + + if ( mpMenu && pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu() ) + { + maPopupMenuRefs.push_back( rxPopupMenu ); + + mpMenu->SetPopupMenu( nItemId, static_cast<PopupMenu*>( pVCLMenu->GetMenu() ) ); + } +} + +css::uno::Reference< css::awt::XPopupMenu > VCLXMenu::getPopupMenu( + sal_Int16 nItemId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + css::uno::Reference< css::awt::XPopupMenu > aRef; + Menu* pMenu = mpMenu ? mpMenu->GetPopupMenu( nItemId ) : nullptr; + if ( pMenu ) + { + for ( size_t n = maPopupMenuRefs.size(); n; ) + { + css::uno::Reference< css::awt::XPopupMenu >& rRef = maPopupMenuRefs[ --n ]; + Menu* pM = static_cast<VCLXMenu*>(rRef.get())->GetMenu(); + if ( pM == pMenu ) + { + aRef = rRef; + break; + } + } + // it seems the popup menu is not insert into maPopupMenuRefs + // if the popup men is not created by stardiv.Toolkit.VCLXPopupMenu + if( !aRef.is() ) + { + aRef = new VCLXPopupMenu( static_cast<PopupMenu*>(pMenu) ); + } + } + return aRef; +} + +// css::awt::XPopupMenu +void VCLXMenu::insertSeparator( + sal_Int16 nPos ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu ) + mpMenu->InsertSeparator(OString(), nPos); +} + +void VCLXMenu::setDefaultItem( + sal_Int16 nItemId ) +{ + std::unique_lock aGuard( maMutex ); + + mnDefaultItem = nItemId; +} + +sal_Int16 VCLXMenu::getDefaultItem( ) +{ + std::unique_lock aGuard( maMutex ); + + return mnDefaultItem; +} + +void VCLXMenu::checkItem( + sal_Int16 nItemId, + sal_Bool bCheck ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu ) + mpMenu->CheckItem( nItemId, bCheck ); +} + +sal_Bool VCLXMenu::isItemChecked( + sal_Int16 nItemId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + return mpMenu && mpMenu->IsItemChecked( nItemId ); +} + +sal_Int16 VCLXMenu::execute( + const css::uno::Reference< css::awt::XWindowPeer >& rxWindowPeer, + const css::awt::Rectangle& rPos, + sal_Int16 nFlags ) +{ + SolarMutexGuard aSolarGuard; + auto pMenu = mpMenu; + { + std::unique_lock aGuard( maMutex ); + if ( !mpMenu || !IsPopupMenu() ) + return 0; + } + // cannot call this with mutex locked because it will call back into us + return static_cast<PopupMenu*>(pMenu.get())->Execute( + VCLUnoHelper::GetWindow( rxWindowPeer ), + VCLRectangle( rPos ), + static_cast<PopupMenuFlags>(nFlags) | PopupMenuFlags::NoMouseUpClose ); +} + + +void SAL_CALL VCLXMenu::setCommand( + sal_Int16 nItemId, + const OUString& aCommand ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu ) + mpMenu->SetItemCommand( nItemId, aCommand ); +} + +OUString SAL_CALL VCLXMenu::getCommand( + sal_Int16 nItemId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + OUString aItemCommand; + if ( mpMenu ) + aItemCommand = mpMenu->GetItemCommand( nItemId ); + return aItemCommand; +} + +void SAL_CALL VCLXMenu::setHelpCommand( + sal_Int16 nItemId, + const OUString& aHelp ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu ) + mpMenu->SetHelpCommand( nItemId, aHelp ); +} + +OUString SAL_CALL VCLXMenu::getHelpCommand( + sal_Int16 nItemId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + OUString aHelpCommand; + if ( mpMenu ) + aHelpCommand = mpMenu->GetHelpCommand( nItemId ); + return aHelpCommand; +} + + +namespace +{ + Image lcl_XGraphic2VCLImage( + const css::uno::Reference< css::graphic::XGraphic >& xGraphic, + bool bResize ) + { + Image aImage; + if ( !xGraphic.is() ) + return aImage; + + aImage = Image( xGraphic ); + const ::Size aCurSize = aImage.GetSizePixel(); + const sal_Int32 nCurWidth = aCurSize.Width(); + const sal_Int32 nCurHeight = aCurSize.Height(); + constexpr sal_Int32 nIdeal( 16 ); + + if ( nCurWidth > 0 && nCurHeight > 0 ) + { + if ( bResize && ( nCurWidth > nIdeal || nCurHeight > nIdeal ) ) + { + sal_Int32 nIdealWidth = std::min(nCurWidth, nIdeal); + sal_Int32 nIdealHeight = std::min(nCurHeight, nIdeal); + + ::Size aNewSize( nIdealWidth, nIdealHeight ); + + bool bModified( false ); + BitmapEx aBitmapEx = aImage.GetBitmapEx(); + bModified = aBitmapEx.Scale( aNewSize, BmpScaleFlag::BestQuality ); + + if ( bModified ) + aImage = Image( aBitmapEx ); + } + } + return aImage; + } + + /** Copied from include/svtools/acceleratorexecute.hxx */ + css::awt::KeyEvent lcl_VCLKey2AWTKey( + const vcl::KeyCode& aVCLKey) + { + css::awt::KeyEvent aAWTKey; + aAWTKey.Modifiers = 0; + aAWTKey.KeyCode = static_cast<sal_Int16>(aVCLKey.GetCode()); + + if (aVCLKey.IsShift()) + aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT; + if (aVCLKey.IsMod1()) + aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1; + if (aVCLKey.IsMod2()) + aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2; + if (aVCLKey.IsMod3()) + aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3; + + return aAWTKey; + } + + vcl::KeyCode lcl_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey) + { + bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT ); + bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 ); + bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 ); + bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 ); + sal_uInt16 nKey = static_cast<sal_uInt16>(aAWTKey.KeyCode); + + return vcl::KeyCode(nKey, bShift, bMod1, bMod2, bMod3); + } + +} + + +sal_Bool SAL_CALL VCLXMenu::isPopupMenu( ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + return IsPopupMenu(); +} + +void SAL_CALL VCLXMenu::clear( ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + if ( mpMenu ) + mpMenu->Clear(); +} + + +css::awt::MenuItemType SAL_CALL VCLXMenu::getItemType( + ::sal_Int16 nItemPos ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + css::awt::MenuItemType aMenuItemType = + css::awt::MenuItemType_DONTKNOW; + if ( mpMenu ) + { + aMenuItemType = static_cast<css::awt::MenuItemType>(mpMenu->GetItemType( nItemPos )); + } + + return aMenuItemType; +} + +void SAL_CALL VCLXMenu::hideDisabledEntries( + sal_Bool bHide ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + if ( mpMenu ) + { + if ( bHide ) + mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MenuFlags::HideDisabledEntries ); + else + mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MenuFlags::HideDisabledEntries ); + } +} + + +sal_Bool SAL_CALL VCLXMenu::isInExecute( ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu && IsPopupMenu() ) + return vcl::IsInPopupMenuExecute(); + else + return false; +} + + +void SAL_CALL VCLXMenu::endExecute() +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu && IsPopupMenu() ) + static_cast<PopupMenu*>( mpMenu.get() )->EndExecute(); +} + + +void SAL_CALL VCLXMenu::enableAutoMnemonics( + sal_Bool bEnable ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + if ( mpMenu ) + { + if ( !bEnable ) + mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MenuFlags::NoAutoMnemonics ); + else + mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MenuFlags::NoAutoMnemonics ); + } +} + + +void SAL_CALL VCLXMenu::setAcceleratorKeyEvent( + ::sal_Int16 nItemId, + const css::awt::KeyEvent& aKeyEvent ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) + { + vcl::KeyCode aVCLKeyCode = lcl_AWTKey2VCLKey( aKeyEvent ); + mpMenu->SetAccelKey( nItemId, aVCLKeyCode ); + } +} + + +css::awt::KeyEvent SAL_CALL VCLXMenu::getAcceleratorKeyEvent( + ::sal_Int16 nItemId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + css::awt::KeyEvent aKeyEvent; + if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) + { + vcl::KeyCode nKeyCode = mpMenu->GetAccelKey( nItemId ); + aKeyEvent = lcl_VCLKey2AWTKey( nKeyCode ); + } + + return aKeyEvent; +} + + +void SAL_CALL VCLXMenu::setHelpText( + ::sal_Int16 nItemId, + const OUString& sHelpText ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) + { + mpMenu->SetHelpText( nItemId, sHelpText ); + } +} + + +OUString SAL_CALL VCLXMenu::getHelpText( + ::sal_Int16 nItemId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + OUString sHelpText; + if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) + { + sHelpText = mpMenu->GetHelpText( nItemId ); + } + + return sHelpText; +} + + +void SAL_CALL VCLXMenu::setTipHelpText( + ::sal_Int16 nItemId, + const OUString& sTipHelpText ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) + { + mpMenu->SetTipHelpText( nItemId, sTipHelpText ); + } +} + + +OUString SAL_CALL VCLXMenu::getTipHelpText( + ::sal_Int16 nItemId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + OUString sTipHelpText; + if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) + { + sTipHelpText = mpMenu->GetTipHelpText( nItemId ); + } + return sTipHelpText; +} + + +void SAL_CALL VCLXMenu::setItemImage( + ::sal_Int16 nItemId, + const css::uno::Reference< css::graphic::XGraphic >& xGraphic, + sal_Bool bScale ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) + { + Image aImage = lcl_XGraphic2VCLImage( xGraphic, bScale ); + mpMenu->SetItemImage( nItemId, aImage ); + } +} + + +css::uno::Reference< css::graphic::XGraphic > SAL_CALL +VCLXMenu::getItemImage( + ::sal_Int16 nItemId ) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + css::uno::Reference< css::graphic::XGraphic > rxGraphic; + + if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) + { + Image aImage = mpMenu->GetItemImage( nItemId ); + if ( !!aImage ) + rxGraphic = Graphic(aImage.GetBitmapEx()).GetXGraphic(); + } + return rxGraphic; +} + +void VCLXMenu::setUserValue(sal_uInt16 nItemId, void* nUserValue, MenuUserDataReleaseFunction aFunc) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard(maMutex); + + mpMenu->SetUserValue(nItemId, nUserValue, aFunc); +} + +void* VCLXMenu::getUserValue(sal_uInt16 nItemId) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard(maMutex); + + return mpMenu->GetUserValue(nItemId); +} + +VCLXMenuBar::VCLXMenuBar() +{ + ImplCreateMenu( false ); +} + +VCLXMenuBar::VCLXMenuBar( MenuBar* pMenuBar ) : VCLXMenu( static_cast<Menu *>(pMenuBar) ) +{ +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +stardiv_Toolkit_VCLXMenuBar_get_implementation( + css::uno::XComponentContext *, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new VCLXMenuBar()); +} + +VCLXPopupMenu::VCLXPopupMenu() +{ + ImplCreateMenu( true ); +} + +VCLXPopupMenu::VCLXPopupMenu( PopupMenu* pPopMenu ) : VCLXMenu( static_cast<Menu *>(pPopMenu) ) +{ + ImplAddListener(); +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +stardiv_Toolkit_VCLXPopupMenu_get_implementation( + css::uno::XComponentContext *, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new VCLXPopupMenu()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxpointer.cxx b/toolkit/source/awt/vclxpointer.cxx new file mode 100644 index 000000000..89828e48a --- /dev/null +++ b/toolkit/source/awt/vclxpointer.cxx @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <awt/vclxpointer.hxx> +#include <cppuhelper/supportsservice.hxx> + +VCLXPointer::VCLXPointer() : maPointer(PointerStyle::Arrow) +{ +} + +VCLXPointer::~VCLXPointer() +{ +} + +// css::lang::XUnoTunnel +UNO3_GETIMPLEMENTATION_IMPL( VCLXPointer ); + +void VCLXPointer::setType( sal_Int32 nType ) +{ + std::scoped_lock aGuard( maMutex ); + + maPointer = static_cast<PointerStyle>(nType); +} + +sal_Int32 VCLXPointer::getType() +{ + std::scoped_lock aGuard( maMutex ); + + return static_cast<sal_Int32>(maPointer); +} + +OUString VCLXPointer::getImplementationName() +{ + return "stardiv.Toolkit.VCLXPointer"; +} + +sal_Bool VCLXPointer::supportsService(OUString const & ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +css::uno::Sequence<OUString> VCLXPointer::getSupportedServiceNames() +{ + return css::uno::Sequence<OUString>{ + "com.sun.star.awt.Pointer", "stardiv.vcl.Pointer"}; +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +stardiv_Toolkit_VCLXPointer_get_implementation( + css::uno::XComponentContext *, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new VCLXPointer()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxprinter.cxx b/toolkit/source/awt/vclxprinter.cxx new file mode 100644 index 000000000..c0db73db4 --- /dev/null +++ b/toolkit/source/awt/vclxprinter.cxx @@ -0,0 +1,379 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <awt/vclxprinter.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/string.hxx> + +#include <vcl/print.hxx> +#include <vcl/jobset.hxx> +#include <vcl/oldprintadaptor.hxx> +#include <vcl/svapp.hxx> + +#include <tools/debug.hxx> +#include <tools/stream.hxx> +#include <o3tl/string_view.hxx> + +#include <toolkit/awt/vclxdevice.hxx> + + +#define BINARYSETUPMARKER 0x23864691 + +#define PROPERTY_Orientation 0 +#define PROPERTY_Horizontal 1 + +// ---------------------------------------------------- +// class VCLXPrinterPropertySet +// ---------------------------------------------------- + +IMPLEMENT_FORWARD_XINTERFACE2( VCLXPrinterPropertySet, VCLXPrinterPropertySet_Base, OPropertySetHelper ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXPrinterPropertySet, VCLXPrinterPropertySet_Base, ::cppu::OPropertySetHelper ) + +VCLXPrinterPropertySet::VCLXPrinterPropertySet( const OUString& rPrinterName ) + : OPropertySetHelper( BrdcstHelper ) + , mxPrinter(VclPtrInstance< Printer >(rPrinterName)) +{ + SolarMutexGuard aSolarGuard; + + mnOrientation = 0; + mbHorizontal = false; +} + +VCLXPrinterPropertySet::~VCLXPrinterPropertySet() +{ + SolarMutexGuard aSolarGuard; + mxPrinter.reset(); +} + +css::uno::Reference< css::awt::XDevice > const & VCLXPrinterPropertySet::GetDevice() +{ + if ( !mxPrnDevice.is() ) + { + rtl::Reference<VCLXDevice> pDev = new VCLXDevice; + pDev->SetOutputDevice( GetPrinter() ); + mxPrnDevice = pDev; + } + return mxPrnDevice; +} + +css::uno::Reference< css::beans::XPropertySetInfo > VCLXPrinterPropertySet::getPropertySetInfo( ) +{ + static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +::cppu::IPropertyArrayHelper& VCLXPrinterPropertySet::getInfoHelper() +{ + static ::cppu::OPropertyArrayHelper s_PropertyArrayHelper( + css::uno::Sequence<css::beans::Property>{ + css::beans::Property( "Orientation", PROPERTY_Orientation, cppu::UnoType<sal_Int16>::get(), 0 ), + css::beans::Property( "Horizontal", PROPERTY_Horizontal, cppu::UnoType<bool>::get(), 0 )}, + false); + + return s_PropertyArrayHelper; +} + +sal_Bool VCLXPrinterPropertySet::convertFastPropertyValue( css::uno::Any & rConvertedValue, css::uno::Any & rOldValue, sal_Int32 nHandle, const css::uno::Any& rValue ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + bool bDifferent = false; + switch ( nHandle ) + { + case PROPERTY_Orientation: + { + sal_Int16 n; + if( ( rValue >>= n ) && ( n != mnOrientation ) ) + { + rConvertedValue <<= n; + rOldValue <<= mnOrientation; + bDifferent = true; + } + } + break; + case PROPERTY_Horizontal: + { + bool b; + if( ( rValue >>= b ) && ( b != mbHorizontal ) ) + { + rConvertedValue <<= b; + rOldValue <<= mbHorizontal; + bDifferent = true; + } + } + break; + default: + { + OSL_FAIL( "VCLXPrinterPropertySet_Impl::convertFastPropertyValue - invalid Handle" ); + } + } + return bDifferent; +} + +void VCLXPrinterPropertySet::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + switch( nHandle ) + { + case PROPERTY_Orientation: + { + rValue >>= mnOrientation; + } + break; + case PROPERTY_Horizontal: + { + rValue >>= mbHorizontal; + } + break; + default: + { + OSL_FAIL( "VCLXPrinterPropertySet_Impl::convertFastPropertyValue - invalid Handle" ); + } + } +} + +void VCLXPrinterPropertySet::getFastPropertyValue( css::uno::Any& rValue, sal_Int32 nHandle ) const +{ + ::osl::MutexGuard aGuard( const_cast<VCLXPrinterPropertySet*>(this)->Mutex ); + + switch( nHandle ) + { + case PROPERTY_Orientation: + rValue <<= mnOrientation; + break; + case PROPERTY_Horizontal: + rValue <<= mbHorizontal; + break; + default: + { + OSL_FAIL( "VCLXPrinterPropertySet_Impl::convertFastPropertyValue - invalid Handle" ); + } + } +} + +// css::awt::XPrinterPropertySet +void VCLXPrinterPropertySet::setHorizontal( sal_Bool bHorizontal ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + css::uno::Any aValue; + aValue <<= bHorizontal; + setFastPropertyValue( PROPERTY_Horizontal, aValue ); +} + +css::uno::Sequence< OUString > VCLXPrinterPropertySet::getFormDescriptions( ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + const sal_uInt16 nPaperBinCount = GetPrinter()->GetPaperBinCount(); + css::uno::Sequence< OUString > aDescriptions( nPaperBinCount ); + for ( sal_uInt16 n = 0; n < nPaperBinCount; n++ ) + { + // Format: <DisplayFormName;FormNameId;DisplayPaperBinName;PaperBinNameId;DisplayPaperName;PaperNameId> + OUString aDescr = "*;*;" + GetPrinter()->GetPaperBinName( n ) + ";" + + OUString::number(n) + ";*;*"; + + aDescriptions.getArray()[n] = aDescr; + } + return aDescriptions; +} + +void VCLXPrinterPropertySet::selectForm( const OUString& rFormDescription ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + sal_uInt16 nPaperBin = sal::static_int_cast< sal_uInt16 >( + o3tl::toInt32(o3tl::getToken(rFormDescription, 3, ';' ))); + GetPrinter()->SetPaperBin( nPaperBin ); +} + +css::uno::Sequence< sal_Int8 > VCLXPrinterPropertySet::getBinarySetup( ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + SvMemoryStream aMem; + aMem.WriteUInt32( BINARYSETUPMARKER ); + WriteJobSetup( aMem, GetPrinter()->GetJobSetup() ); + return css::uno::Sequence<sal_Int8>( static_cast<sal_Int8 const *>(aMem.GetData()), aMem.Tell() ); +} + +void VCLXPrinterPropertySet::setBinarySetup( const css::uno::Sequence< sal_Int8 >& data ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + SvMemoryStream aMem( const_cast<signed char*>(data.getConstArray()), data.getLength(), StreamMode::READ ); + sal_uInt32 nMarker; + aMem.ReadUInt32( nMarker ); + DBG_ASSERT( nMarker == BINARYSETUPMARKER, "setBinarySetup - invalid!" ); + if ( nMarker == BINARYSETUPMARKER ) + { + JobSetup aSetup; + ReadJobSetup( aMem, aSetup ); + GetPrinter()->SetJobSetup( aSetup ); + } +} + + +// ---------------------------------------------------- +// class VCLXPrinter +// ---------------------------------------------------- +VCLXPrinter::VCLXPrinter( const OUString& rPrinterName ) + : VCLXPrinter_Base( rPrinterName ) +{ +} + +VCLXPrinter::~VCLXPrinter() +{ +} + +sal_Bool VCLXPrinter::start( const OUString& /*rJobName*/, sal_Int16 /*nCopies*/, sal_Bool /*bCollate*/ ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + if (mxPrinter) + { + maInitJobSetup = mxPrinter->GetJobSetup(); + mxListener = std::make_shared<vcl::OldStylePrintAdaptor>(mxPrinter, nullptr); + } + + return true; +} + +void VCLXPrinter::end( ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + if (mxListener) + { + Printer::PrintJob(mxListener, maInitJobSetup); + mxListener.reset(); + } +} + +void VCLXPrinter::terminate( ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + mxListener.reset(); +} + +css::uno::Reference< css::awt::XDevice > VCLXPrinter::startPage( ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + if (mxListener) + { + mxListener->StartPage(); + } + return GetDevice(); +} + +void VCLXPrinter::endPage( ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + if (mxListener) + { + mxListener->EndPage(); + } +} + + +// ---------------------------------------------------- +// class VCLXInfoPrinter +// ---------------------------------------------------- + +VCLXInfoPrinter::VCLXInfoPrinter( const OUString& rPrinterName ) + : VCLXInfoPrinter_Base( rPrinterName ) +{ +} + +VCLXInfoPrinter::~VCLXInfoPrinter() +{ +} + +// css::awt::XInfoPrinter +css::uno::Reference< css::awt::XDevice > VCLXInfoPrinter::createDevice( ) +{ + ::osl::MutexGuard aGuard( Mutex ); + + return GetDevice(); +} + +// ---------------------------------------------------- +// class VCLXPrinterServer +// ---------------------------------------------------- + +// css::awt::XPrinterServer2 +css::uno::Sequence< OUString > VCLXPrinterServer::getPrinterNames( ) +{ + const std::vector<OUString>& rQueues = Printer::GetPrinterQueues(); + sal_uInt32 nPrinters = rQueues.size(); + + css::uno::Sequence< OUString > aNames( nPrinters ); + for ( sal_uInt32 n = 0; n < nPrinters; n++ ) + aNames.getArray()[n] = rQueues[n]; + + return aNames; +} + +OUString VCLXPrinterServer::getDefaultPrinterName() +{ + return Printer::GetDefaultPrinterName(); +} + +css::uno::Reference< css::awt::XPrinter > VCLXPrinterServer::createPrinter( const OUString& rPrinterName ) +{ + css::uno::Reference< css::awt::XPrinter > xP = new VCLXPrinter( rPrinterName ); + return xP; +} + +css::uno::Reference< css::awt::XInfoPrinter > VCLXPrinterServer::createInfoPrinter( const OUString& rPrinterName ) +{ + css::uno::Reference< css::awt::XInfoPrinter > xP = new VCLXInfoPrinter( rPrinterName ); + return xP; +} + +OUString VCLXPrinterServer::getImplementationName() +{ + return "stardiv.Toolkit.VCLXPrinterServer"; +} + +sal_Bool VCLXPrinterServer::supportsService(OUString const & ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +css::uno::Sequence<OUString> VCLXPrinterServer::getSupportedServiceNames() +{ + return css::uno::Sequence<OUString>{ + "com.sun.star.awt.PrinterServer", "stardiv.vcl.PrinterServer"}; +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +stardiv_Toolkit_VCLXPrinterServer_get_implementation( + css::uno::XComponentContext *, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new VCLXPrinterServer); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxregion.cxx b/toolkit/source/awt/vclxregion.cxx new file mode 100644 index 000000000..d9abedecf --- /dev/null +++ b/toolkit/source/awt/vclxregion.cxx @@ -0,0 +1,145 @@ +/* -*- 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 <awt/vclxregion.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <toolkit/helper/convert.hxx> + + + +VCLXRegion::VCLXRegion() +{ +} + +VCLXRegion::~VCLXRegion() +{ +} + +// css::lang::XUnoTunnel +UNO3_GETIMPLEMENTATION_IMPL( VCLXRegion ); + +css::awt::Rectangle VCLXRegion::getBounds() +{ + std::scoped_lock aGuard( maMutex ); + + return AWTRectangle( maRegion.GetBoundRect() ); +} + +void VCLXRegion::clear() +{ + std::scoped_lock aGuard( maMutex ); + + maRegion.SetEmpty(); +} + +void VCLXRegion::move( sal_Int32 nHorzMove, sal_Int32 nVertMove ) +{ + std::scoped_lock aGuard( maMutex ); + + maRegion.Move( nHorzMove, nVertMove ); +} + +void VCLXRegion::unionRectangle( const css::awt::Rectangle& rRect ) +{ + std::scoped_lock aGuard( maMutex ); + + maRegion.Union( VCLRectangle( rRect ) ); +} + +void VCLXRegion::intersectRectangle( const css::awt::Rectangle& rRect ) +{ + std::scoped_lock aGuard( maMutex ); + + maRegion.Intersect( VCLRectangle( rRect ) ); +} + +void VCLXRegion::excludeRectangle( const css::awt::Rectangle& rRect ) +{ + std::scoped_lock aGuard( maMutex ); + + maRegion.Exclude( VCLRectangle( rRect ) ); +} + +void VCLXRegion::xOrRectangle( const css::awt::Rectangle& rRect ) +{ + std::scoped_lock aGuard( maMutex ); + + maRegion.XOr( VCLRectangle( rRect ) ); +} + +void VCLXRegion::unionRegion( const css::uno::Reference< css::awt::XRegion >& rxRegion ) +{ + std::scoped_lock aGuard( maMutex ); + + if ( rxRegion.is() ) + maRegion.Union( VCLUnoHelper::GetRegion( rxRegion ) ); +} + +void VCLXRegion::intersectRegion( const css::uno::Reference< css::awt::XRegion >& rxRegion ) +{ + std::scoped_lock aGuard( maMutex ); + + if ( rxRegion.is() ) + maRegion.Intersect( VCLUnoHelper::GetRegion( rxRegion ) ); +} + +void VCLXRegion::excludeRegion( const css::uno::Reference< css::awt::XRegion >& rxRegion ) +{ + std::scoped_lock aGuard( maMutex ); + + if ( rxRegion.is() ) + maRegion.Exclude( VCLUnoHelper::GetRegion( rxRegion ) ); +} + +void VCLXRegion::xOrRegion( const css::uno::Reference< css::awt::XRegion >& rxRegion ) +{ + std::scoped_lock aGuard( maMutex ); + + if ( rxRegion.is() ) + maRegion.XOr( VCLUnoHelper::GetRegion( rxRegion ) ); +} + +css::uno::Sequence< css::awt::Rectangle > VCLXRegion::getRectangles() +{ + std::scoped_lock aGuard( maMutex ); + + RectangleVector aRectangles; + maRegion.GetRegionRectangles(aRectangles); + +// sal_uLong nRects = maRegion.GetRectCount(); + css::uno::Sequence< css::awt::Rectangle > aRects(aRectangles.size()); + sal_uInt32 a(0); + + for(const auto& rRect : aRectangles) + { + aRects.getArray()[a++] = AWTRectangle(rRect); + } + + //Rectangle aRect; + //sal_uInt32 nR = 0; + //RegionHandle h = maRegion.BeginEnumRects(); + //while ( maRegion.GetEnumRects( h, aRect ) ) + // aRects.getArray()[nR++] = AWTRectangle( aRect ); + //maRegion.EndEnumRects( h ); + + return aRects; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxspinbutton.cxx b/toolkit/source/awt/vclxspinbutton.cxx new file mode 100644 index 000000000..db5d1f1b0 --- /dev/null +++ b/toolkit/source/awt/vclxspinbutton.cxx @@ -0,0 +1,331 @@ +/* -*- 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 <awt/vclxspinbutton.hxx> +#include <toolkit/helper/property.hxx> +#include <com/sun/star/awt/ScrollBarOrientation.hpp> + +#include <vcl/toolkit/spin.hxx> +#include <vcl/svapp.hxx> +#include "vclxwindows_internal.hxx" + +namespace toolkit +{ + + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::beans; + + + namespace + { + void lcl_modifyStyle( vcl::Window* _pWindow, WinBits _nStyleBits, bool _bShouldBePresent ) + { + WinBits nStyle = _pWindow->GetStyle(); + if ( _bShouldBePresent ) + nStyle |= _nStyleBits; + else + nStyle &= ~_nStyleBits; + _pWindow->SetStyle( nStyle ); + } + } + + VCLXSpinButton::VCLXSpinButton() + :maAdjustmentListeners( *this ) + { + } + + + VCLXSpinButton::~VCLXSpinButton() + { + } + + + IMPLEMENT_FORWARD_XINTERFACE2( VCLXSpinButton, VCLXWindow, VCLXSpinButton_Base ) + + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXSpinButton, VCLXWindow, VCLXSpinButton_Base ) + + + void SAL_CALL VCLXSpinButton::dispose( ) + { + { + SolarMutexGuard aGuard; + + EventObject aDisposeEvent; + aDisposeEvent.Source = *this; + maAdjustmentListeners.disposeAndClear( aDisposeEvent ); + } + + VCLXWindow::dispose(); + } + + + void SAL_CALL VCLXSpinButton::addAdjustmentListener( const Reference< XAdjustmentListener >& listener ) + { + if ( listener.is() ) + maAdjustmentListeners.addInterface( listener ); + } + + + void SAL_CALL VCLXSpinButton::removeAdjustmentListener( const Reference< XAdjustmentListener >& listener ) + { + if ( listener.is() ) + maAdjustmentListeners.removeInterface( listener ); + } + + namespace + { + typedef void (SpinButton::*SetSpinButtonValue) (tools::Long); + typedef tools::Long (SpinButton::*GetSpinButtonValue) () const; + + + void lcl_setSpinButtonValue(vcl::Window* _pWindow, SetSpinButtonValue _pSetter, sal_Int32 _nValue ) + { + SolarMutexGuard aGuard; + SpinButton* pSpinButton = static_cast< SpinButton* >( _pWindow ); + if ( pSpinButton ) + (pSpinButton->*_pSetter)( _nValue ); + } + + + sal_Int32 lcl_getSpinButtonValue(const vcl::Window* _pWindow, GetSpinButtonValue _pGetter ) + { + SolarMutexGuard aGuard; + + sal_Int32 nValue = 0; + + const SpinButton* pSpinButton = static_cast< const SpinButton* >( _pWindow ); + if ( pSpinButton ) + nValue = (pSpinButton->*_pGetter)( ); + return nValue; + } + } + + + void SAL_CALL VCLXSpinButton::setValue( sal_Int32 n ) + { + lcl_setSpinButtonValue( GetWindow(), &SpinButton::SetValue, n ); + } + + + void SAL_CALL VCLXSpinButton::setValues( sal_Int32 minValue, sal_Int32 maxValue, sal_Int32 currentValue ) + { + SolarMutexGuard aGuard; + + setMinimum( minValue ); + setMaximum( maxValue ); + setValue( currentValue ); + } + + + sal_Int32 SAL_CALL VCLXSpinButton::getValue( ) + { + return lcl_getSpinButtonValue( GetWindow(), &SpinButton::GetValue ); + } + + + void SAL_CALL VCLXSpinButton::setMinimum( sal_Int32 minValue ) + { + lcl_setSpinButtonValue( GetWindow(), &SpinButton::SetRangeMin, minValue ); + } + + + void SAL_CALL VCLXSpinButton::setMaximum( sal_Int32 maxValue ) + { + lcl_setSpinButtonValue( GetWindow(), &SpinButton::SetRangeMax, maxValue ); + } + + + sal_Int32 SAL_CALL VCLXSpinButton::getMinimum( ) + { + return lcl_getSpinButtonValue( GetWindow(), &SpinButton::GetRangeMin ); + } + + + sal_Int32 SAL_CALL VCLXSpinButton::getMaximum( ) + { + return lcl_getSpinButtonValue( GetWindow(), &SpinButton::GetRangeMax ); + } + + + void SAL_CALL VCLXSpinButton::setSpinIncrement( sal_Int32 spinIncrement ) + { + lcl_setSpinButtonValue( GetWindow(), &SpinButton::SetValueStep, spinIncrement ); + } + + + sal_Int32 SAL_CALL VCLXSpinButton::getSpinIncrement( ) + { + return lcl_getSpinButtonValue( GetWindow(), &SpinButton::GetValueStep ); + } + + + void SAL_CALL VCLXSpinButton::setOrientation( sal_Int32 orientation ) + { + SolarMutexGuard aGuard; + + lcl_modifyStyle( GetWindow(), WB_HSCROLL, orientation == ScrollBarOrientation::HORIZONTAL ); + } + + + sal_Int32 SAL_CALL VCLXSpinButton::getOrientation( ) + { + return ( 0 != ( GetWindow()->GetStyle() & WB_HSCROLL ) ) + ? ScrollBarOrientation::HORIZONTAL + : ScrollBarOrientation::VERTICAL; + } + + + void VCLXSpinButton::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent ) + { + SolarMutexClearableGuard aGuard; + Reference< XSpinValue > xKeepAlive( this ); + VclPtr<SpinButton> pSpinButton = GetAs<SpinButton>(); + if ( !pSpinButton ) + return; + + switch ( _rVclWindowEvent.GetId() ) + { + case VclEventId::SpinbuttonUp: + case VclEventId::SpinbuttonDown: + if ( maAdjustmentListeners.getLength() ) + { + AdjustmentEvent aEvent; + aEvent.Source = *this; + aEvent.Value = pSpinButton->GetValue(); + + aGuard.clear(); + maAdjustmentListeners.adjustmentValueChanged( aEvent ); + } + break; + + default: + xKeepAlive.clear(); + aGuard.clear(); + VCLXWindow::ProcessWindowEvent( _rVclWindowEvent ); + break; + } + } + + + void SAL_CALL VCLXSpinButton::setProperty( const OUString& PropertyName, const Any& Value ) + { + SolarMutexGuard aGuard; + + sal_Int32 nValue = 0; + bool bIsLongValue = ( Value >>= nValue ); + + if ( !GetWindow() ) + return; + + sal_uInt16 nPropertyId = GetPropertyId( PropertyName ); + switch ( nPropertyId ) + { + case BASEPROPERTY_BACKGROUNDCOLOR: + // the default implementation of the base class doesn't work here, since our + // interpretation for this property is slightly different + setButtonLikeFaceColor( GetWindow(), Value); + break; + + case BASEPROPERTY_SPINVALUE: + if ( bIsLongValue ) + setValue( nValue ); + break; + + case BASEPROPERTY_SPINVALUE_MIN: + if ( bIsLongValue ) + setMinimum( nValue ); + break; + + case BASEPROPERTY_SPINVALUE_MAX: + if ( bIsLongValue ) + setMaximum( nValue ); + break; + + case BASEPROPERTY_SPININCREMENT: + if ( bIsLongValue ) + setSpinIncrement( nValue ); + break; + + case BASEPROPERTY_ORIENTATION: + if ( bIsLongValue ) + lcl_modifyStyle( GetWindow(), WB_HSCROLL, nValue == ScrollBarOrientation::HORIZONTAL ); + break; + + default: + VCLXWindow::setProperty( PropertyName, Value ); + } + } + + + Any SAL_CALL VCLXSpinButton::getProperty( const OUString& PropertyName ) + { + SolarMutexGuard aGuard; + + Any aReturn; + + if ( GetWindow() ) + { + sal_uInt16 nPropertyId = GetPropertyId( PropertyName ); + switch ( nPropertyId ) + { + case BASEPROPERTY_BACKGROUNDCOLOR: + // the default implementation of the base class doesn't work here, since our + // interpretation for this property is slightly different + aReturn = getButtonLikeFaceColor( GetWindow() ); + break; + + case BASEPROPERTY_SPINVALUE: + aReturn <<= getValue( ); + break; + + case BASEPROPERTY_SPINVALUE_MIN: + aReturn <<= getMinimum( ); + break; + + case BASEPROPERTY_SPINVALUE_MAX: + aReturn <<= getMaximum( ); + break; + + case BASEPROPERTY_SPININCREMENT: + aReturn <<= getSpinIncrement( ); + break; + + case BASEPROPERTY_ORIENTATION: + aReturn <<= static_cast<sal_Int32>( ( 0 != ( GetWindow()->GetStyle() & WB_HSCROLL ) ) + ? ScrollBarOrientation::HORIZONTAL + : ScrollBarOrientation::VERTICAL + ); + break; + + default: + aReturn = VCLXWindow::getProperty( PropertyName ); + } + } + return aReturn; + } + + +} // namespace toolkit + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxsystemdependentwindow.cxx b/toolkit/source/awt/vclxsystemdependentwindow.cxx new file mode 100644 index 000000000..37d7f86d9 --- /dev/null +++ b/toolkit/source/awt/vclxsystemdependentwindow.cxx @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/lang/SystemDependent.hpp> + +#if defined UNX && ! defined MACOSX +#include <com/sun/star/awt/SystemDependentXWindow.hpp> +#endif + +#include <awt/vclxsystemdependentwindow.hxx> +#include <toolkit/helper/macros.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/queryinterface.hxx> + +#ifdef MACOSX +#include <premac.h> +#include <Cocoa/Cocoa.h> +#include <postmac.h> +#endif + +#include <vcl/svapp.hxx> +#include <vcl/syschild.hxx> +#include <vcl/sysdata.hxx> + + + +VCLXSystemDependentWindow::VCLXSystemDependentWindow() +{ +} + +VCLXSystemDependentWindow::~VCLXSystemDependentWindow() +{ +} + +// css::uno::XInterface +css::uno::Any VCLXSystemDependentWindow::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XSystemDependentWindowPeer* >(this) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXSystemDependentWindow ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXSystemDependentWindow::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XSystemDependentWindowPeer>::get(), + VCLXWindow::getTypes() + ); + return aTypeList.getTypes(); +} + +css::uno::Any VCLXSystemDependentWindow::getWindowHandle( const css::uno::Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 SystemType ) +{ + SolarMutexGuard aGuard; + + // TODO, check the process id + css::uno::Any aRet; + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + const SystemEnvData* pSysData = static_cast<SystemChildWindow *>(pWindow.get())->GetSystemData(); + if( pSysData ) + { +#if defined(_WIN32) + if( SystemType == css::lang::SystemDependent::SYSTEM_WIN32 ) + { + aRet <<= reinterpret_cast<sal_IntPtr>(pSysData->hWnd); + } +#elif defined(MACOSX) + if( SystemType == css::lang::SystemDependent::SYSTEM_MAC ) + { + aRet <<= reinterpret_cast<sal_IntPtr>(pSysData->mpNSView); + } +#elif defined(ANDROID) + // Nothing + (void) SystemType; +#elif defined(IOS) + // Nothing + (void) SystemType; +#elif defined(UNX) + if( SystemType == css::lang::SystemDependent::SYSTEM_XWINDOW ) + { + css::awt::SystemDependentXWindow aSD; + aSD.DisplayPointer = sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_IntPtr >(pSysData->pDisplay)); + aSD.WindowHandle = pSysData->GetWindowHandle(pWindow->ImplGetFrame()); + aRet <<= aSD; + } +#endif + } + } + return aRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxtabpagecontainer.cxx b/toolkit/source/awt/vclxtabpagecontainer.cxx new file mode 100644 index 000000000..80124c9de --- /dev/null +++ b/toolkit/source/awt/vclxtabpagecontainer.cxx @@ -0,0 +1,231 @@ +/* -*- 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 <awt/vclxtabpagecontainer.hxx> +#include <com/sun/star/awt/tab/XTabPageModel.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <o3tl/safeint.hxx> +#include <sal/log.hxx> +#include <toolkit/helper/property.hxx> +#include <vcl/image.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/svapp.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +#include <helper/tkresmgr.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::view; + + +void VCLXTabPageContainer::GetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + VCLXWindow::ImplGetPropertyIds( rIds ); +} + +VCLXTabPageContainer::VCLXTabPageContainer() : + m_aTabPageListeners( *this ) +{ +} + +VCLXTabPageContainer::~VCLXTabPageContainer() +{ + SAL_INFO("toolkit", __FUNCTION__); +} + +void SAL_CALL VCLXTabPageContainer::draw( sal_Int32 nX, sal_Int32 nY ) +{ + SolarMutexGuard aGuard; + VclPtr<TabControl> pTabControl = GetAs<TabControl>(); + if ( pTabControl ) + { + TabPage *pTabPage = pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >( pTabControl->GetCurPageId( ) ) ); + OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() ); + if (pTabPage && pDev) + { + ::Point aPos( nX, nY ); + aPos = pDev->PixelToLogic( aPos ); + pTabPage->Draw( pDev, aPos, SystemTextColorFlags::NONE ); + } + } + + VCLXWindow::draw( nX, nY ); +} + +void SAL_CALL VCLXTabPageContainer::setProperty(const OUString& PropertyName, const Any& Value ) +{ + SolarMutexGuard aGuard; + VclPtr<TabControl> pTabPage = GetAs<TabControl>(); + if ( pTabPage ) + VCLXWindow::setProperty( PropertyName, Value ); +} + +::sal_Int16 SAL_CALL VCLXTabPageContainer::getActiveTabPageID() +{ + VclPtr<TabControl> pTabCtrl = GetAs<TabControl>(); + return pTabCtrl ? pTabCtrl->GetCurPageId( ) : 0; +} + +void SAL_CALL VCLXTabPageContainer::setActiveTabPageID( ::sal_Int16 _activetabpageid ) +{ + VclPtr<TabControl> pTabCtrl = GetAs<TabControl>(); + if ( pTabCtrl ) + pTabCtrl->SelectTabPage(_activetabpageid); +} + +::sal_Int16 SAL_CALL VCLXTabPageContainer::getTabPageCount( ) +{ + VclPtr<TabControl> pTabCtrl = GetAs<TabControl>(); + return pTabCtrl ? pTabCtrl->GetPageCount() : 0; +} + +sal_Bool SAL_CALL VCLXTabPageContainer::isTabPageActive( ::sal_Int16 tabPageIndex ) +{ + return (getActiveTabPageID() == tabPageIndex); +} + +Reference< css::awt::tab::XTabPage > SAL_CALL VCLXTabPageContainer::getTabPage( ::sal_Int16 tabPageIndex ) +{ + return (tabPageIndex >= 0 && o3tl::make_unsigned(tabPageIndex) < m_aTabPages.size()) ? m_aTabPages[tabPageIndex] : nullptr; +} + +Reference< css::awt::tab::XTabPage > SAL_CALL VCLXTabPageContainer::getTabPageByID( ::sal_Int16 tabPageID ) +{ + SolarMutexGuard aGuard; + Reference< css::awt::tab::XTabPage > xTabPage; + for(const auto& rTabPage : m_aTabPages) + { + Reference< awt::XControl > xControl(rTabPage,UNO_QUERY ); + Reference< awt::tab::XTabPageModel > xP( xControl->getModel(), UNO_QUERY ); + if ( tabPageID == xP->getTabPageID() ) + { + xTabPage = rTabPage; + break; + } + } + return xTabPage; +} + +void SAL_CALL VCLXTabPageContainer::addTabPageContainerListener( const Reference< css::awt::tab::XTabPageContainerListener >& listener ) +{ + m_aTabPageListeners.addInterface( listener ); +} + +void SAL_CALL VCLXTabPageContainer::removeTabPageContainerListener( const Reference< css::awt::tab::XTabPageContainerListener >& listener ) +{ + m_aTabPageListeners.removeInterface( listener ); +} + +void VCLXTabPageContainer::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent ) +{ + SolarMutexClearableGuard aGuard; + VclPtr<TabControl> pTabControl = GetAs<TabControl>(); + if ( !pTabControl ) + return; + + switch ( _rVclWindowEvent.GetId() ) + { + case VclEventId::TabpageActivate: + { + sal_uLong page = reinterpret_cast<sal_uLong>(_rVclWindowEvent.GetData()); + awt::tab::TabPageActivatedEvent aEvent(nullptr,page); + m_aTabPageListeners.tabPageActivated(aEvent); + break; + } + default: + aGuard.clear(); + VCLXWindow::ProcessWindowEvent( _rVclWindowEvent ); + break; + } +} +void SAL_CALL VCLXTabPageContainer::disposing( const css::lang::EventObject& /*Source*/ ) +{ +} +void SAL_CALL VCLXTabPageContainer::elementInserted( const css::container::ContainerEvent& Event ) +{ + SolarMutexGuard aGuard; + VclPtr<TabControl> pTabCtrl = GetAs<TabControl>(); + Reference< css::awt::tab::XTabPage > xTabPage(Event.Element,uno::UNO_QUERY); + if ( !pTabCtrl || !xTabPage.is() ) + return; + + Reference< awt::XControl > xControl(xTabPage,UNO_QUERY ); + Reference< awt::tab::XTabPageModel > xP( xControl->getModel(), UNO_QUERY ); + sal_Int16 nPageID = xP->getTabPageID(); + + if (!xControl->getPeer().is()) + throw RuntimeException("No peer for tabpage container!"); + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xControl->getPeer()); + TabPage* pPage = static_cast<TabPage*>(pWindow.get()); + pTabCtrl->InsertPage(nPageID,pPage->GetText()); + + pPage->Hide(); + pTabCtrl->SetTabPage(nPageID,pPage); + pTabCtrl->SetHelpText(nPageID,xP->getToolTip()); + pTabCtrl->SetPageImage(nPageID,TkResMgr::getImageFromURL(xP->getImageURL())); + pTabCtrl->SelectTabPage(nPageID); + pTabCtrl->SetPageEnabled(nPageID,xP->getEnabled()); + m_aTabPages.push_back(xTabPage); + +} +void SAL_CALL VCLXTabPageContainer::elementRemoved( const css::container::ContainerEvent& Event ) +{ + SolarMutexGuard aGuard; + VclPtr<TabControl> pTabCtrl = GetAs<TabControl>(); + Reference< css::awt::tab::XTabPage > xTabPage(Event.Element,uno::UNO_QUERY); + if ( pTabCtrl && xTabPage.is() ) + { + Reference< awt::XControl > xControl(xTabPage,UNO_QUERY ); + Reference< awt::tab::XTabPageModel > xP( xControl->getModel(), UNO_QUERY ); + pTabCtrl->RemovePage(xP->getTabPageID()); + m_aTabPages.erase(::std::remove(m_aTabPages.begin(),m_aTabPages.end(),xTabPage)); + } +} +void SAL_CALL VCLXTabPageContainer::elementReplaced( const css::container::ContainerEvent& /*Event*/ ) +{ +} + +void VCLXTabPageContainer::propertiesChange(const::css::uno::Sequence<PropertyChangeEvent>& rEvents) +{ + SolarMutexGuard aGuard; + VclPtr<TabControl> pTabCtrl = GetAs<TabControl>(); + if (!pTabCtrl) + return; + + for (const beans::PropertyChangeEvent& rEvent : rEvents) { + // handle property changes for tab pages + Reference< css::awt::tab::XTabPageModel > xTabPageModel(rEvent.Source, uno::UNO_QUERY); + if (!xTabPageModel.is()) + continue; + + const sal_Int16 nId = xTabPageModel->getTabPageID(); + if (rEvent.PropertyName == GetPropertyName(BASEPROPERTY_ENABLED)) { + pTabCtrl->SetPageEnabled(nId, xTabPageModel->getEnabled()); + } else if (rEvent.PropertyName == GetPropertyName(BASEPROPERTY_TITLE)) { + pTabCtrl->SetPageText(nId, xTabPageModel->getTitle()); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxtoolkit.cxx b/toolkit/source/awt/vclxtoolkit.cxx new file mode 100644 index 000000000..e73511960 --- /dev/null +++ b/toolkit/source/awt/vclxtoolkit.cxx @@ -0,0 +1,2668 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <string_view> + +#ifdef _WIN32 +#include <prewin.h> +#include <postwin.h> +#endif +#include <config_features.h> +#include <com/sun/star/awt/WindowAttribute.hpp> +#include <com/sun/star/awt/VclWindowPeerAttribute.hpp> +#include <com/sun/star/awt/WindowClass.hpp> +#include <com/sun/star/awt/MessageBoxButtons.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/SystemDependent.hpp> +#include <com/sun/star/awt/FocusEvent.hpp> +#include <com/sun/star/awt/KeyEvent.hpp> +#include <com/sun/star/awt/KeyModifier.hpp> +#include <com/sun/star/lang/EventObject.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/awt/XToolkitExperimental.hpp> +#include <com/sun/star/awt/XToolkitRobot.hpp> + +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/bootstrap.hxx> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <o3tl/safeint.hxx> +#include <osl/conditn.hxx> +#include <osl/module.h> +#include <osl/thread.hxx> +#include <osl/mutex.hxx> +#include <rtl/ref.hxx> +#include <rtl/process.h> +#include <sal/log.hxx> +#include <tools/link.hxx> +#include <tools/wintypes.hxx> + +#ifdef MACOSX +#include <premac.h> +#include <Cocoa/Cocoa.h> +#include <postmac.h> +#endif + +#include <vcl/sysdata.hxx> +#include <vcl/textrectinfo.hxx> +#include <vcl/toolkit/vclmedit.hxx> + +#include <toolkit/awt/vclxwindows.hxx> +#include <awt/vclxwindows.hxx> +#include <awt/vclxsystemdependentwindow.hxx> +#include <awt/vclxregion.hxx> +#include <awt/vclxtabpagecontainer.hxx> +#include <awt/vclxtopwindow.hxx> + +#include <awt/animatedimagespeer.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <toolkit/helper/property.hxx> + +#include <toolkit/helper/convert.hxx> +#include <controls/filectrl.hxx> +#include <controls/svmedit.hxx> +#include <controls/treecontrolpeer.hxx> +#include <vcl/toolkit/button.hxx> +#include <vcl/toolkit/calendar.hxx> +#include <vcl/toolkit/combobox.hxx> +#include <vcl/ctrl.hxx> +#include <vcl/toolkit/dialog.hxx> +#include <vcl/dockingarea.hxx> +#include <vcl/dockwin.hxx> +#include <vcl/toolkit/edit.hxx> +#include <vcl/event.hxx> +#include <vcl/toolkit/field.hxx> +#include <vcl/toolkit/fixed.hxx> +#include <vcl/toolkit/fixedhyper.hxx> +#include <vcl/toolkit/floatwin.hxx> +#include <vcl/toolkit/fmtfield.hxx> +#include <vcl/toolkit/prgsbar.hxx> +#include <vcl/scheduler.hxx> +#include <vcl/toolkit/lstbox.hxx> +#include <vcl/toolkit/longcurr.hxx> +#include <vcl/toolkit/menubtn.hxx> +#include <vcl/stdtext.hxx> +#include <vcl/scrbar.hxx> +#include <vcl/split.hxx> +#include <vcl/splitwin.hxx> +#include <vcl/status.hxx> +#include <vcl/svapp.hxx> +#include <vcl/syschild.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/toolbox.hxx> +#include <vcl/virdev.hxx> +#include <vcl/window.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/toolkit/group.hxx> +#include <vcl/toolkit/imgctrl.hxx> +#include <vcl/toolkit/morebtn.hxx> +#include <vcl/toolkit/roadmap.hxx> +#include <vcl/toolkit/spin.hxx> +#include <vcl/toolkit/tabdlg.hxx> +#include <vcl/toolkit/throbber.hxx> +#if HAVE_FEATURE_OPENGL +#include <vcl/opengl/OpenGLWrapper.hxx> +#endif +#include <awt/vclxspinbutton.hxx> +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> +#include <comphelper/interfacecontainer3.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/profilezone.hxx> + +#include <helper/msgbox.hxx> +#include <helper/scrollabledialog.hxx> +#include <helper/unowrapper.hxx> + +#if defined(_WIN32) +#define SYSTEM_DEPENDENT_TYPE css::lang::SystemDependent::SYSTEM_WIN32 +#elif defined(MACOSX) +#define SYSTEM_DEPENDENT_TYPE css::lang::SystemDependent::SYSTEM_MAC +#elif defined(UNX) +#define SYSTEM_DEPENDENT_TYPE css::lang::SystemDependent::SYSTEM_XWINDOW +#endif + +void MessBox::ImplInitButtons() +{ + ButtonDialogFlags nOKFlags = ButtonDialogFlags::OK; + ButtonDialogFlags nCancelFlags = ButtonDialogFlags::Cancel; + ButtonDialogFlags nRetryFlags = ButtonDialogFlags::NONE; + ButtonDialogFlags nYesFlags = ButtonDialogFlags::NONE; + ButtonDialogFlags nNoFlags = ButtonDialogFlags::NONE; + + if ( mnMessBoxStyle & MessBoxStyle::OkCancel ) + { + if ( mnMessBoxStyle & MessBoxStyle::DefaultCancel ) + nCancelFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + else // MessBoxStyle::DefaultOk + nOKFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + + AddButton( StandardButtonType::OK, RET_OK, nOKFlags ); + AddButton( StandardButtonType::Cancel, RET_CANCEL, nCancelFlags ); + } + else if ( mnMessBoxStyle & MessBoxStyle::YesNo ) + { + if ( mnMessBoxStyle & MessBoxStyle::DefaultYes ) + nYesFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + else // MessBoxStyle::DefaultNo + nNoFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + nNoFlags |= ButtonDialogFlags::Cancel; + + AddButton( StandardButtonType::Yes, RET_YES, nYesFlags ); + AddButton( StandardButtonType::No, RET_NO, nNoFlags ); + } + else if ( mnMessBoxStyle & MessBoxStyle::YesNoCancel ) + { + if ( mnMessBoxStyle & MessBoxStyle::DefaultYes ) + nYesFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + else if ( mnMessBoxStyle & MessBoxStyle::DefaultNo ) + nNoFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + else + nCancelFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + + AddButton( StandardButtonType::Yes, RET_YES, nYesFlags ); + AddButton( StandardButtonType::No, RET_NO, nNoFlags ); + AddButton( StandardButtonType::Cancel, RET_CANCEL, nCancelFlags ); + } + else if ( mnMessBoxStyle & MessBoxStyle::RetryCancel ) + { + if ( mnMessBoxStyle & MessBoxStyle::DefaultCancel ) + nCancelFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + else // MessBoxStyle::DefaultRetry + nRetryFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + + AddButton( StandardButtonType::Retry, RET_RETRY, nRetryFlags ); + AddButton( StandardButtonType::Cancel, RET_CANCEL, nCancelFlags ); + } + else if ( mnMessBoxStyle & MessBoxStyle::AbortRetryIgnore ) + { + ButtonDialogFlags nAbortFlags = ButtonDialogFlags::NONE; + ButtonDialogFlags nIgnoreFlags = ButtonDialogFlags::NONE; + + if ( mnMessBoxStyle & MessBoxStyle::DefaultCancel ) + nAbortFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + else if ( mnMessBoxStyle & MessBoxStyle::DefaultRetry ) + nRetryFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + else if ( mnMessBoxStyle & MessBoxStyle::DefaultIgnore ) + nIgnoreFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + + AddButton( StandardButtonType::Abort, RET_CANCEL, nAbortFlags ); + AddButton( StandardButtonType::Retry, RET_RETRY, nRetryFlags ); + AddButton( StandardButtonType::Ignore, RET_IGNORE, nIgnoreFlags ); + } + else if ( mnMessBoxStyle & MessBoxStyle::Ok ) + { + nOKFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus; + + AddButton( StandardButtonType::OK, RET_OK, nOKFlags ); + } +} + +MessBox::MessBox(vcl::Window* pParent, MessBoxStyle nMessBoxStyle, WinBits nWinBits, + const OUString& rTitle, const OUString& rMessage) : + ButtonDialog( WindowType::MESSBOX ), + mbHelpBtn( false ), + mnMessBoxStyle( nMessBoxStyle ), + maMessText( rMessage ) +{ + ImplLOKNotifier(pParent); + ImplInitDialog(pParent, nWinBits | WB_MOVEABLE | WB_HORZ | WB_CENTER); + ImplInitButtons(); + + if ( !rTitle.isEmpty() ) + SetText( rTitle ); +} + +MessBox::~MessBox() +{ + disposeOnce(); +} + +void MessBox::dispose() +{ + mpVCLMultiLineEdit.disposeAndClear(); + mpFixedImage.disposeAndClear(); + ButtonDialog::dispose(); +} + +void MessBox::ImplPosControls() +{ + if ( !GetHelpId().isEmpty() ) + { + if ( !mbHelpBtn ) + { + AddButton( StandardButtonType::Help, RET_HELP, ButtonDialogFlags::Help, 3 ); + mbHelpBtn = true; + } + } + else + { + if ( mbHelpBtn ) + { + RemoveButton( RET_HELP ); + mbHelpBtn = false; + } + } + + TextRectInfo aTextInfo; + tools::Rectangle aRect( 0, 0, 30000, 30000 ); + tools::Rectangle aFormatRect; + Point aTextPos( IMPL_DIALOG_OFFSET, IMPL_DIALOG_OFFSET+IMPL_MSGBOX_OFFSET_EXTRA_Y ); + Size aImageSize; + Size aPageSize; + Size aMEditSize; + tools::Long nTitleWidth; + tools::Long nButtonSize = ImplGetButtonSize(); + tools::Long nMaxLineWidth; + tools::Long nWidth; + WinBits nWinStyle = WB_LEFT | WB_NOLABEL; + DrawTextFlags nTextStyle = DrawTextFlags::MultiLine | DrawTextFlags::Top | DrawTextFlags::Left; + + mpVCLMultiLineEdit.disposeAndClear(); + mpFixedImage.disposeAndClear(); + + // Clean up message text with tabs + OUString aMessText(maMessText.replaceAll("\t", " ")); + + //If window too small, we make dialog box be wider + tools::Long nMaxWidth = 630 * GetDPIScaleFactor(); + + // MessagBox should be at least as wide as to see the title + // Extra-Width for Close button, because Close button is set after this call + nTitleWidth = CalcTitleWidth(); + + nMaxWidth -= (IMPL_DIALOG_OFFSET*2)+(IMPL_MSGBOX_OFFSET_EXTRA_X*2); + + // for an image, get its size, create a suitable control and position it + aImageSize = maImage.GetSizePixel(); + if ( aImageSize.Width() ) + { + aImageSize.AdjustWidth(4 ); + aImageSize.AdjustHeight(4 ); + aTextPos.AdjustX(aImageSize.Width()+IMPL_SEP_MSGBOX_IMAGE ); + mpFixedImage = VclPtr<FixedImage>::Create( this ); + mpFixedImage->SetPosSizePixel( Point( IMPL_DIALOG_OFFSET-2+IMPL_MSGBOX_OFFSET_EXTRA_X, + IMPL_DIALOG_OFFSET-2+IMPL_MSGBOX_OFFSET_EXTRA_Y ), + aImageSize ); + mpFixedImage->SetImage( maImage ); + mpFixedImage->Show(); + nMaxWidth -= aImageSize.Width()+IMPL_SEP_MSGBOX_IMAGE; + } + else + aTextPos.AdjustX(IMPL_MSGBOX_OFFSET_EXTRA_X ); + + // Determine maximum line length without wordbreak + aFormatRect = GetTextRect( aRect, aMessText, nTextStyle, &aTextInfo ); + nMaxLineWidth = aFormatRect.GetWidth(); + nTextStyle |= DrawTextFlags::WordBreak; + + // Determine the width for text formatting + if ( nMaxLineWidth > 450 ) + nWidth = 450; + else if ( nMaxLineWidth > 300 ) + nWidth = nMaxLineWidth+5; + else + nWidth = 300; + + nWidth *= GetDPIScaleFactor(); + + if ( nButtonSize > nWidth ) + nWidth = nButtonSize-(aTextPos.X()-IMPL_DIALOG_OFFSET); + if ( nWidth > nMaxWidth ) + nWidth = nMaxWidth; + + aRect.SetRight( nWidth ); + aFormatRect = GetTextRect( aRect, aMessText, nTextStyle, &aTextInfo ); + if ( aTextInfo.GetMaxLineWidth() > nWidth ) + { + nWidth = aTextInfo.GetMaxLineWidth()+8; + aRect.SetRight( nWidth ); + aFormatRect = GetTextRect( aRect, aMessText, nTextStyle, &aTextInfo ); + } + + // get Style for VCLMultiLineEdit + aMEditSize.setWidth( aTextInfo.GetMaxLineWidth()+1 ); + aMEditSize.setHeight( aFormatRect.GetHeight() ); + aPageSize.setWidth( aImageSize.Width() ); + if ( aMEditSize.Height() < aImageSize.Height() ) + { + nWinStyle |= WB_VCENTER; + aPageSize.setHeight( aImageSize.Height() ); + aMEditSize.setHeight( aImageSize.Height() ); + } + else + { + nWinStyle |= WB_TOP; + aPageSize.setHeight( aMEditSize.Height() ); + } + if ( aImageSize.Width() ) + aPageSize.AdjustWidth(IMPL_SEP_MSGBOX_IMAGE ); + aPageSize.AdjustWidth((IMPL_DIALOG_OFFSET*2)+(IMPL_MSGBOX_OFFSET_EXTRA_X*2) ); + aPageSize.AdjustWidth(aMEditSize.Width()+1 ); + aPageSize.AdjustHeight((IMPL_DIALOG_OFFSET*2)+(IMPL_MSGBOX_OFFSET_EXTRA_Y*2) ); + + if ( aPageSize.Width() < IMPL_MINSIZE_MSGBOX_WIDTH ) + aPageSize.setWidth( IMPL_MINSIZE_MSGBOX_WIDTH ); + if ( aPageSize.Width() < nTitleWidth ) + aPageSize.setWidth( nTitleWidth ); + + mpVCLMultiLineEdit = VclPtr<VclMultiLineEdit>::Create( this, nWinStyle ); + mpVCLMultiLineEdit->SetText( aMessText ); + mpVCLMultiLineEdit->SetPosSizePixel( aTextPos, aMEditSize ); + mpVCLMultiLineEdit->Show(); + mpVCLMultiLineEdit->SetPaintTransparent(true); + mpVCLMultiLineEdit->EnableCursor(false); + SetPageSizePixel( aPageSize ); +} + +void MessBox::StateChanged( StateChangedType nType ) +{ + if ( nType == StateChangedType::InitShow ) + { + ImplPosControls(); + } + ButtonDialog::StateChanged( nType ); +} + +Size MessBox::GetOptimalSize() const +{ + // FIXME: base me on the font size ? + return Size( 250, 100 ); +} + + +namespace { + +extern "C" typedef vcl::Window* (*FN_SvtCreateWindow)( + rtl::Reference<VCLXWindow>* ppNewComp, + const css::awt::WindowDescriptor* pDescriptor, + vcl::Window* pParent, + WinBits nWinBits ); + +class Pause : public Idle +{ +public: + explicit Pause(sal_Int32 nPauseMilliseconds) : + Idle("pause"), + m_nPauseMilliseconds(nPauseMilliseconds) + { + SetPriority(TaskPriority::HIGHEST); + Start(); + } + + virtual void Invoke() override + { + SolarMutexGuard aSolarGuard; + osl::Thread::wait(std::chrono::milliseconds(m_nPauseMilliseconds)); + Stop(); + delete this; + } + + sal_Int32 m_nPauseMilliseconds; +}; + +class VCLXToolkit : public cppu::BaseMutex, + public cppu::WeakComponentImplHelper< + css::awt::XToolkitExperimental, + css::awt::XToolkitRobot, + css::lang::XServiceInfo > +{ + css::uno::Reference< css::datatransfer::clipboard::XClipboard > mxClipboard; + css::uno::Reference< css::datatransfer::clipboard::XClipboard > mxSelection; + + oslModule hSvToolsLib; + FN_SvtCreateWindow fnSvtCreateWindow; + + ::comphelper::OInterfaceContainerHelper3<css::awt::XTopWindowListener> m_aTopWindowListeners; + ::comphelper::OInterfaceContainerHelper3<css::awt::XKeyHandler> m_aKeyHandlers; + ::comphelper::OInterfaceContainerHelper3<css::awt::XFocusListener> m_aFocusListeners; + ::Link<VclSimpleEvent&,void> m_aEventListenerLink; + ::Link<VclWindowEvent&,bool> m_aKeyListenerLink; + bool m_bEventListener; + bool m_bKeyListener; + + DECL_LINK(eventListenerHandler, ::VclSimpleEvent&, void); + + DECL_LINK(keyListenerHandler, ::VclWindowEvent&, bool); + + void callTopWindowListeners( + ::VclSimpleEvent const * pEvent, + void (SAL_CALL css::awt::XTopWindowListener::* pFn)( + css::lang::EventObject const &)); + + bool callKeyHandlers(::VclSimpleEvent const * pEvent, bool bPressed); + + void callFocusListeners(::VclSimpleEvent const * pEvent, bool bGained); + +protected: + ::osl::Mutex& GetMutex() { return m_aMutex; } + + virtual void SAL_CALL disposing() override; + + static vcl::Window* ImplCreateWindow( rtl::Reference<VCLXWindow>* ppNewComp, const css::awt::WindowDescriptor& rDescriptor, vcl::Window* pParent, + WinBits nWinBits, MessBoxStyle nMessBoxStyle ); + css::uno::Reference< css::awt::XWindowPeer > ImplCreateWindow( const css::awt::WindowDescriptor& Descriptor, + MessBoxStyle nForceMessBoxStyle ); + +public: + + VCLXToolkit(); + + // css::awt::XToolkitExperimental + virtual void SAL_CALL processEventsToIdle() override; + + virtual sal_Int64 SAL_CALL getOpenGLBufferSwapCounter() override; + + virtual void SAL_CALL setDeterministicScheduling(sal_Bool bDeterministicMode) override; + + virtual void SAL_CALL pause(sal_Int32 nMilliseconds) override; + + virtual void SAL_CALL startRecording() override; + + virtual void SAL_CALL stopRecording() override; + + css::uno::Sequence< OUString > SAL_CALL getRecordingAndClear() override; + + // css::awt::XToolkit + css::uno::Reference< css::awt::XWindowPeer > SAL_CALL getDesktopWindow( ) override; + css::awt::Rectangle SAL_CALL getWorkArea( ) override; + css::uno::Reference< css::awt::XWindowPeer > SAL_CALL createWindow( const css::awt::WindowDescriptor& Descriptor ) override; + css::uno::Sequence< css::uno::Reference< css::awt::XWindowPeer > > SAL_CALL createWindows( const css::uno::Sequence< css::awt::WindowDescriptor >& Descriptors ) override; + css::uno::Reference< css::awt::XDevice > SAL_CALL createScreenCompatibleDevice( sal_Int32 Width, sal_Int32 Height ) override; + css::uno::Reference< css::awt::XRegion > SAL_CALL createRegion( ) override; + + // css::awt::XSystemChildFactory + css::uno::Reference< css::awt::XWindowPeer > SAL_CALL createSystemChild( const css::uno::Any& Parent, const css::uno::Sequence< sal_Int8 >& ProcessId, sal_Int16 SystemType ) override; + + // css::awt::XMessageBoxFactory + virtual css::uno::Reference< css::awt::XMessageBox > SAL_CALL createMessageBox( const css::uno::Reference< css::awt::XWindowPeer >& aParent, css::awt::MessageBoxType eType, ::sal_Int32 aButtons, const OUString& aTitle, const OUString& aMessage ) override; + + // css::awt::XDataTransfer + css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > SAL_CALL getDragGestureRecognizer( const css::uno::Reference< css::awt::XWindow >& window ) override; + css::uno::Reference< css::datatransfer::dnd::XDragSource > SAL_CALL getDragSource( const css::uno::Reference< css::awt::XWindow >& window ) override; + css::uno::Reference< css::datatransfer::dnd::XDropTarget > SAL_CALL getDropTarget( const css::uno::Reference< css::awt::XWindow >& window ) override; + css::uno::Reference< css::datatransfer::clipboard::XClipboard > SAL_CALL getClipboard( const OUString& clipboardName ) override; + + // css::lang::XServiceInfo + OUString SAL_CALL getImplementationName( ) override; + sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + // css::awt::XExtendedToolkit: + + virtual ::sal_Int32 SAL_CALL getTopWindowCount() override; + + virtual css::uno::Reference< css::awt::XTopWindow > + SAL_CALL getTopWindow(::sal_Int32 nIndex) override; + + virtual css::uno::Reference< css::awt::XTopWindow > + SAL_CALL getActiveTopWindow() override; + + virtual void SAL_CALL addTopWindowListener( + css::uno::Reference< + css::awt::XTopWindowListener > const & rListener) override; + + virtual void SAL_CALL removeTopWindowListener( + css::uno::Reference< + css::awt::XTopWindowListener > const & rListener) override; + + virtual void SAL_CALL addKeyHandler( + css::uno::Reference< + css::awt::XKeyHandler > const & rHandler) override; + + virtual void SAL_CALL removeKeyHandler( + css::uno::Reference< + css::awt::XKeyHandler > const & rHandler) override; + + virtual void SAL_CALL addFocusListener( + css::uno::Reference< + css::awt::XFocusListener > const & rListener) override; + + virtual void SAL_CALL removeFocusListener( + css::uno::Reference< + css::awt::XFocusListener > const & rListener) override; + + virtual void SAL_CALL fireFocusGained( + css::uno::Reference< + css::uno::XInterface > const & source) override; + + virtual void SAL_CALL fireFocusLost( + css::uno::Reference< + css::uno::XInterface > const & source) override; + + // css::awt::XReschedule: + virtual void SAL_CALL reschedule() override; + + // css::awt::XFontMappingUse: + virtual void SAL_CALL startTrackingFontMappingUse() override; + + virtual css::uno::Sequence<css::awt::XFontMappingUseItem> SAL_CALL finishTrackingFontMappingUse() override; + + // css:awt:XToolkitRobot + virtual void SAL_CALL keyPress( const css::awt::KeyEvent & aKeyEvent ) override; + + virtual void SAL_CALL keyRelease( const css::awt::KeyEvent & aKeyEvent ) override; + + virtual void SAL_CALL mousePress( const css::awt::MouseEvent & aMouseEvent ) override; + + virtual void SAL_CALL mouseRelease( const css::awt::MouseEvent & aMouseEvent ) override; + + virtual void SAL_CALL mouseMove( const css::awt::MouseEvent & aMouseEvent ) override; + +}; + +std::pair<WinBits,MessBoxStyle> ImplGetWinBits( sal_uInt32 nComponentAttribs, WindowType nCompType ) +{ + WinBits nWinBits = 0; + MessBoxStyle nStyle = MessBoxStyle::NONE; + + bool bMessBox = false; + if ( ( nCompType == WindowType::INFOBOX ) || + ( nCompType == WindowType::MESSBOX ) || + ( nCompType == WindowType::QUERYBOX ) || + ( nCompType == WindowType::WARNINGBOX ) || + ( nCompType == WindowType::ERRORBOX ) ) + { + bMessBox = true; + } + + bool bDecoratedWindow = false; + if ( bMessBox + || ( nCompType == WindowType::DIALOG ) + || ( nCompType == WindowType::MODELESSDIALOG ) + || ( nCompType == WindowType::DOCKINGWINDOW ) + || ( nCompType == WindowType::TABDIALOG ) + || ( nCompType == WindowType::BUTTONDIALOG ) + || ( nCompType == WindowType::SYSTEMCHILDWINDOW ) + ) + { + bDecoratedWindow = true; + } + + if( nComponentAttribs & css::awt::WindowAttribute::BORDER ) + nWinBits |= WB_BORDER; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::NOBORDER ) + nWinBits |= WB_NOBORDER; + if( nComponentAttribs & css::awt::WindowAttribute::SIZEABLE ) + nWinBits |= WB_SIZEABLE; + if( nComponentAttribs & css::awt::WindowAttribute::MOVEABLE ) + nWinBits |= WB_MOVEABLE; + if( nComponentAttribs & css::awt::WindowAttribute::CLOSEABLE ) + nWinBits |= WB_CLOSEABLE; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::HSCROLL ) + nWinBits |= WB_HSCROLL; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::VSCROLL ) + nWinBits |= WB_VSCROLL; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::LEFT ) + nWinBits |= WB_LEFT; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::CENTER ) + nWinBits |= WB_CENTER; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::RIGHT ) + nWinBits |= WB_RIGHT; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::SPIN ) + nWinBits |= WB_SPIN; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::SORT ) + nWinBits |= WB_SORT; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DROPDOWN ) + nWinBits |= WB_DROPDOWN; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEFBUTTON ) + nWinBits |= WB_DEFBUTTON; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::READONLY ) + nWinBits |= WB_READONLY; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::CLIPCHILDREN ) + nWinBits |= WB_CLIPCHILDREN; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::GROUP ) + nWinBits |= WB_GROUP; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::NOLABEL ) //added for issue79712 + nWinBits |= WB_NOLABEL; + + // These bits are not unique + if ( bMessBox ) + { + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::OK ) + nStyle |= MessBoxStyle::Ok; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::OK_CANCEL ) + nStyle |= MessBoxStyle::OkCancel; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::YES_NO ) + nStyle |= MessBoxStyle::YesNo; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::YES_NO_CANCEL ) + nStyle |= MessBoxStyle::YesNoCancel; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::RETRY_CANCEL ) + nStyle |= MessBoxStyle::RetryCancel; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_OK ) + nStyle |= MessBoxStyle::DefaultOk; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_CANCEL ) + nStyle |= MessBoxStyle::DefaultCancel; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_RETRY ) + nStyle |= MessBoxStyle::DefaultRetry; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_YES ) + nStyle |= MessBoxStyle::DefaultYes; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_NO ) + nStyle |= MessBoxStyle::DefaultNo; + } + if ( nCompType == WindowType::MULTILINEEDIT || nCompType == WindowType::DIALOG + || nCompType == WindowType::GROUPBOX || nCompType == WindowType::TABPAGE ) + { + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::AUTOHSCROLL ) + nWinBits |= WB_AUTOHSCROLL; + if( nComponentAttribs & css::awt::VclWindowPeerAttribute::AUTOVSCROLL ) + nWinBits |= WB_AUTOVSCROLL; + } + + + if ( bDecoratedWindow ) + { + if( nComponentAttribs & css::awt::WindowAttribute::NODECORATION ) + { + // No decoration removes several window attributes and must + // set WB_NOBORDER! + nWinBits &= ~WB_BORDER; + nWinBits &= ~WB_SIZEABLE; + nWinBits &= ~WB_MOVEABLE; + nWinBits &= ~WB_CLOSEABLE; + nWinBits |= WB_NOBORDER; + } + } + + return { nWinBits, nStyle }; +} + +struct ComponentInfo +{ + std::u16string_view sName; + WindowType nWinType; +}; + +ComponentInfo const aComponentInfos [] = +{ + { std::u16string_view(u"animatedimages"), WindowType::CONTROL }, + { std::u16string_view(u"buttondialog"), WindowType::BUTTONDIALOG }, + { std::u16string_view(u"cancelbutton"), WindowType::CANCELBUTTON }, + { std::u16string_view(u"checkbox"), WindowType::CHECKBOX }, + { std::u16string_view(u"combobox"), WindowType::COMBOBOX }, + { std::u16string_view(u"control"), WindowType::CONTROL }, + { std::u16string_view(u"currencybox"), WindowType::CURRENCYBOX }, + { std::u16string_view(u"currencyfield"), WindowType::CURRENCYFIELD }, + { std::u16string_view(u"datebox"), WindowType::DATEBOX }, + { std::u16string_view(u"datefield"), WindowType::CONTROL }, + { std::u16string_view(u"dialog"), WindowType::DIALOG }, + { std::u16string_view(u"dockingarea"), WindowType::DOCKINGAREA }, + { std::u16string_view(u"dockingwindow"), WindowType::DOCKINGWINDOW }, + { std::u16string_view(u"edit"), WindowType::EDIT }, + { std::u16string_view(u"errorbox"), WindowType::ERRORBOX }, + { std::u16string_view(u"filecontrol"), WindowType::CONTROL }, + { std::u16string_view(u"fixedbitmap"), WindowType::FIXEDBITMAP }, + { std::u16string_view(u"fixedhyperlink"), WindowType::CONTROL }, + { std::u16string_view(u"fixedimage"), WindowType::FIXEDIMAGE }, + { std::u16string_view(u"fixedline"), WindowType::FIXEDLINE }, + { std::u16string_view(u"fixedtext"), WindowType::FIXEDTEXT }, + { std::u16string_view(u"floatingwindow"), WindowType::FLOATINGWINDOW }, + { std::u16string_view(u"formattedfield"), WindowType::CONTROL }, + { std::u16string_view(u"frame"), WindowType::GROUPBOX }, + { std::u16string_view(u"framewindow"), WindowType::TOOLKIT_FRAMEWINDOW }, + { std::u16string_view(u"groupbox"), WindowType::GROUPBOX }, + { std::u16string_view(u"helpbutton"), WindowType::HELPBUTTON }, + { std::u16string_view(u"imagebutton"), WindowType::IMAGEBUTTON }, + { std::u16string_view(u"infobox"), WindowType::INFOBOX }, + { std::u16string_view(u"listbox"), WindowType::LISTBOX }, + { std::u16string_view(u"longcurrencybox"), WindowType::LONGCURRENCYBOX }, + { std::u16string_view(u"longcurrencyfield"), WindowType::CONTROL }, + { std::u16string_view(u"menubutton"), WindowType::MENUBUTTON }, + { std::u16string_view(u"messbox"), WindowType::MESSBOX }, + { std::u16string_view(u"metricbox"), WindowType::METRICBOX }, + { std::u16string_view(u"metricfield"), WindowType::METRICFIELD }, + { std::u16string_view(u"modelessdialog"), WindowType::MODELESSDIALOG }, + { std::u16string_view(u"morebutton"), WindowType::MOREBUTTON }, + { std::u16string_view(u"multilineedit"), WindowType::MULTILINEEDIT }, + { std::u16string_view(u"multilistbox"), WindowType::MULTILISTBOX }, + { std::u16string_view(u"numericbox"), WindowType::NUMERICBOX }, + { std::u16string_view(u"numericfield"), WindowType::CONTROL }, + { std::u16string_view(u"okbutton"), WindowType::OKBUTTON }, + { std::u16string_view(u"patternbox"), WindowType::PATTERNBOX }, + { std::u16string_view(u"patternfield"), WindowType::PATTERNFIELD }, + { std::u16string_view(u"progressbar"), WindowType::CONTROL }, + { std::u16string_view(u"pushbutton"), WindowType::PUSHBUTTON }, + { std::u16string_view(u"querybox"), WindowType::QUERYBOX }, + { std::u16string_view(u"radiobutton"), WindowType::RADIOBUTTON }, + { std::u16string_view(u"roadmap"), WindowType::CONTROL }, + { std::u16string_view(u"scrollbar"), WindowType::SCROLLBAR }, + { std::u16string_view(u"scrollbarbox"), WindowType::SCROLLBARBOX }, + { std::u16string_view(u"spinbutton"), WindowType::SPINBUTTON }, + { std::u16string_view(u"spinfield"), WindowType::SPINFIELD }, + { std::u16string_view(u"splitter"), WindowType::SPLITTER }, + { std::u16string_view(u"splitwindow"), WindowType::SPLITWINDOW }, + { std::u16string_view(u"statusbar"), WindowType::STATUSBAR }, + { std::u16string_view(u"systemchildwindow"), WindowType::TOOLKIT_SYSTEMCHILDWINDOW }, + { std::u16string_view(u"tabcontrol"), WindowType::TABCONTROL }, + { std::u16string_view(u"tabdialog"), WindowType::TABDIALOG }, + { std::u16string_view(u"tabpage"), WindowType::TABPAGE }, + { std::u16string_view(u"tabpagecontainer"), WindowType::CONTROL }, + { std::u16string_view(u"tabpagemodel"), WindowType::TABPAGE }, + { std::u16string_view(u"timebox"), WindowType::TIMEBOX }, + { std::u16string_view(u"timefield"), WindowType::TIMEFIELD }, + { std::u16string_view(u"toolbox"), WindowType::TOOLBOX }, + { std::u16string_view(u"tree"), WindowType::CONTROL }, + { std::u16string_view(u"tristatebox"), WindowType::TRISTATEBOX }, + { std::u16string_view(u"warningbox"), WindowType::WARNINGBOX }, + { std::u16string_view(u"window"), WindowType::WINDOW }, + { std::u16string_view(u"workwindow"), WindowType::WORKWINDOW } +}; + +bool ComponentInfoFindCompare( const ComponentInfo & lhs, const OUString & s) +{ + return rtl_ustr_compareIgnoreAsciiCase_WithLength(s.pData->buffer, s.pData->length, + lhs.sName.data(), lhs.sName.size()) > 0; +} + +WindowType ImplGetComponentType( const OUString& rServiceName ) +{ + static bool bSorted = false; + if( !bSorted ) + { + assert( std::is_sorted( std::begin(aComponentInfos), std::end(aComponentInfos), + [](const ComponentInfo & lhs, const ComponentInfo & rhs) { + return + rtl_ustr_compare_WithLength( + lhs.sName.data(), lhs.sName.size(), rhs.sName.data(), + rhs.sName.size()) + < 0; + } ) ); + bSorted = true; + } + + OUString sSearch; + if ( !rServiceName.isEmpty() ) + sSearch = rServiceName; + else + sSearch = "window"; + + auto it = std::lower_bound( std::begin(aComponentInfos), std::end(aComponentInfos), sSearch, + ComponentInfoFindCompare ); + if (it != std::end(aComponentInfos) && + rtl_ustr_compareIgnoreAsciiCase_WithLength(sSearch.pData->buffer, sSearch.pData->length, it->sName.data(), it->sName.size()) == 0) + return it->nWinType; + return WindowType::NONE; +} + +struct MessageBoxTypeInfo +{ + css::awt::MessageBoxType eType; + const char *pName; + sal_Int32 nLen; +}; + +const MessageBoxTypeInfo aMessageBoxTypeInfo[] = +{ + { css::awt::MessageBoxType_MESSAGEBOX, RTL_CONSTASCII_STRINGPARAM("messbox") }, + { css::awt::MessageBoxType_INFOBOX, RTL_CONSTASCII_STRINGPARAM("infobox") }, + { css::awt::MessageBoxType_WARNINGBOX, RTL_CONSTASCII_STRINGPARAM("warningbox") }, + { css::awt::MessageBoxType_ERRORBOX, RTL_CONSTASCII_STRINGPARAM("errorbox") }, + { css::awt::MessageBoxType_QUERYBOX, RTL_CONSTASCII_STRINGPARAM("querybox") }, + { css::awt::MessageBoxType::MessageBoxType_MAKE_FIXED_SIZE, nullptr, 0 } +}; + +bool lcl_convertMessageBoxType( + OUString &sType, + css::awt::MessageBoxType eType ) +{ + const MessageBoxTypeInfo *pMap = aMessageBoxTypeInfo; + css::awt::MessageBoxType eVal = css::awt::MessageBoxType::MessageBoxType_MAKE_FIXED_SIZE; + + while ( pMap->pName ) + { + if ( pMap->eType == eType ) + { + eVal = eType; + sType = OUString( pMap->pName, pMap->nLen, RTL_TEXTENCODING_ASCII_US ); + break; + } + pMap++; + } + + return ( eVal != css::awt::MessageBoxType::MessageBoxType_MAKE_FIXED_SIZE ); +} + +#ifndef IOS + +sal_Int32 nVCLToolkitInstanceCount = 0; +bool bInitedByVCLToolkit = false; + +osl::Mutex & getInitMutex() +{ + static osl::Mutex aMutex; + return aMutex; +} + +osl::Condition & getInitCondition() +{ + static osl::Condition aCondition; + return aCondition; +} + +extern "C" +{ +static void ToolkitWorkerFunction( void* pArgs ) +{ + osl_setThreadName("VCLXToolkit VCL main thread"); + + css::uno::Reference<css::lang::XMultiServiceFactory> xServiceManager; + try + { + xServiceManager = ::comphelper::getProcessServiceFactory(); + } + catch (const css::uno::DeploymentException&) + { + } + if (!xServiceManager.is()) + { + css::uno::Reference<css::uno::XComponentContext> xContext = + ::cppu::defaultBootstrap_InitialComponentContext(); + + xServiceManager.set( xContext->getServiceManager(), css::uno::UNO_QUERY_THROW ); + // set global process service factory used by unotools config helpers + ::comphelper::setProcessServiceFactory( xServiceManager ); + } + + VCLXToolkit * pTk = static_cast<VCLXToolkit *>(pArgs); + bInitedByVCLToolkit = !IsVCLInit() && InitVCL(); + if( bInitedByVCLToolkit ) + { + UnoWrapper* pUnoWrapper = new UnoWrapper( pTk ); + UnoWrapperBase::SetUnoWrapper( pUnoWrapper ); + } + getInitCondition().set(); + if( bInitedByVCLToolkit ) + { + { + SolarMutexGuard aGuard; + Application::Execute(); + } + try + { + pTk->dispose(); + } + catch( css::uno::Exception & ) + { + } + DeInitVCL(); + } + else + { + // having the thread join itself is pretty stupid. + // but we can't get the osl_Thread to destroy here so just leak it. + } +} +} + +#endif + +// constructor, which might initialize VCL +VCLXToolkit::VCLXToolkit(): + cppu::WeakComponentImplHelper< + css::awt::XToolkitExperimental, + css::awt::XToolkitRobot, + css::lang::XServiceInfo>( GetMutex() ), + m_aTopWindowListeners(rBHelper.rMutex), + m_aKeyHandlers(rBHelper.rMutex), + m_aFocusListeners(rBHelper.rMutex), + m_aEventListenerLink(LINK(this, VCLXToolkit, eventListenerHandler)), + m_aKeyListenerLink(LINK(this, VCLXToolkit, keyListenerHandler)), + m_bEventListener(false), + m_bKeyListener(false) +{ + hSvToolsLib = nullptr; + fnSvtCreateWindow = nullptr; + +#ifndef IOS + osl::Guard< osl::Mutex > aGuard( getInitMutex() ); + nVCLToolkitInstanceCount++; + if( ( nVCLToolkitInstanceCount == 1 ) && ( !Application::IsInMain() ) ) + { + // setup execute thread + CreateMainLoopThread( ToolkitWorkerFunction, this ); + getInitCondition().wait(); + } +#endif +} + +void SAL_CALL VCLXToolkit::disposing() +{ +#ifndef DISABLE_DYNLOADING + if ( hSvToolsLib ) + { + osl_unloadModule( hSvToolsLib ); + hSvToolsLib = nullptr; + fnSvtCreateWindow = nullptr; + } +#endif + +#ifndef IOS + { + osl::Guard< osl::Mutex > aGuard( getInitMutex() ); + if( --nVCLToolkitInstanceCount == 0 ) + { + if( bInitedByVCLToolkit ) + { + Application::Quit(); + JoinMainLoopThread(); + bInitedByVCLToolkit = false; + } + } + } +#endif + if (m_bEventListener) + { + ::Application::RemoveEventListener(m_aEventListenerLink); + m_bEventListener = false; + } + if (m_bKeyListener) + { + ::Application::RemoveKeyListener(m_aKeyListenerLink); + m_bKeyListener = false; + } + css::lang::EventObject aEvent( + static_cast< ::cppu::OWeakObject * >(this)); + m_aTopWindowListeners.disposeAndClear(aEvent); + m_aKeyHandlers.disposeAndClear(aEvent); + m_aFocusListeners.disposeAndClear(aEvent); +} + + +css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::getDesktopWindow( ) +{ + css::uno::Reference< css::awt::XWindowPeer > xRef; + // 07/00: AppWindow doesn't exist anymore... + return xRef; +} + +css::awt::Rectangle VCLXToolkit::getWorkArea( ) +{ + sal_Int32 nDisplay = Application::GetDisplayBuiltInScreen(); + tools::Rectangle aWorkRect = Application::GetScreenPosSizePixel( nDisplay ); + css::awt::Rectangle aNotherRect; + aNotherRect.X = aWorkRect.Left(); + aNotherRect.Y = aWorkRect.Top(); + aNotherRect.Width = aWorkRect.getWidth(); + aNotherRect.Height = aWorkRect.getHeight(); + return aNotherRect; +} + +css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::createWindow( const css::awt::WindowDescriptor& rDescriptor ) +{ + return ImplCreateWindow( rDescriptor, MessBoxStyle::NONE ); +} + +css::uno::Reference< css::awt::XDevice > VCLXToolkit::createScreenCompatibleDevice( sal_Int32 Width, sal_Int32 Height ) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + rtl::Reference<VCLXVirtualDevice> pVDev = new VCLXVirtualDevice; + + SolarMutexGuard aSolarGuard; + + VclPtrInstance<VirtualDevice> pV; + pV->SetOutputSizePixel( Size( Width, Height ) ); + pVDev->SetVirtualDevice( pV ); + + return pVDev; +} + +css::uno::Reference< css::awt::XRegion > VCLXToolkit::createRegion( ) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + css::uno::Reference< css::awt::XRegion > xRef = new VCLXRegion; + return xRef; +} + +class InfoBox : public MessBox +{ +public: + InfoBox(vcl::Window* pParent, const OUString& rMessage) + : MessBox(pParent, MessBoxStyle::Ok | MessBoxStyle::DefaultOk, 0, OUString(), rMessage) + { + // Default Text is the display title from the application + if (GetText().isEmpty()) + SetText(GetStandardInfoBoxText()); + SetImage(GetStandardInfoBoxImage()); + } +}; + +class ErrorBox : public MessBox +{ +public: + ErrorBox(vcl::Window* pParent, MessBoxStyle nStyle, WinBits nWinBits, const OUString& rMessage) + : MessBox(pParent, nStyle, nWinBits, OUString(), rMessage) + { + // Default Text is the display title from the application + if (GetText().isEmpty()) + SetText(GetStandardErrorBoxText()); + SetImage(GetStandardErrorBoxImage()); + } +}; + +class QueryBox : public MessBox +{ +public: + QueryBox(vcl::Window* pParent, MessBoxStyle nStyle, WinBits nWinBits, const OUString& rMessage) + : MessBox(pParent, nStyle, nWinBits, OUString(), rMessage) + { + // Default Text is the display title from the application + if (GetText().isEmpty()) + SetText(GetStandardQueryBoxText()); + SetImage(GetStandardQueryBoxImage()); + } +}; + +class WarningBox : public MessBox +{ +public: + WarningBox(vcl::Window* pParent, MessBoxStyle nStyle, WinBits nWinBits, const OUString& rMessage) + : MessBox(pParent, nStyle, nWinBits, OUString(), rMessage) + { + // Default Text is the display title from the application + if (GetText().isEmpty()) + SetText(GetStandardWarningBoxText()); + SetImage(GetStandardWarningBoxImage()); + } +}; + + +struct RMItemData +{ + bool b_Enabled; + sal_Int32 n_ID; + OUString Label; +}; + +typedef ::cppu::ImplInheritanceHelper < VCLXGraphicControl + , css::container::XContainerListener + , css::beans::XPropertyChangeListener + , css::awt::XItemEventBroadcaster + > SVTXRoadmap_Base; +class SVTXRoadmap final : public SVTXRoadmap_Base +{ +public: + SVTXRoadmap(); + + void SAL_CALL disposing( const css::lang::EventObject& Source ) override { VCLXWindow::disposing( Source ); } + + // css::awt::XVclWindowPeer + void SAL_CALL setProperty( const OUString& PropertyName, const css::uno::Any& Value ) override; + + css::uno::Any SAL_CALL getProperty( const OUString& PropertyName ) override; + + // XContainerListener + void SAL_CALL elementInserted( const css::container::ContainerEvent& rEvent ) override; + void SAL_CALL elementRemoved( const css::container::ContainerEvent& rEvent ) override; + void SAL_CALL elementReplaced( const css::container::ContainerEvent& rEvent ) override; + + // XItemEventBroadcaster + virtual void SAL_CALL addItemListener( const css::uno::Reference< css::awt::XItemListener >& l ) override; + virtual void SAL_CALL removeItemListener( const css::uno::Reference< css::awt::XItemListener >& l ) override; + + // XPropertyChangeListener + virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) override; + +private: + + // VCLXGraphicControl overridables + virtual void ImplSetNewImage() override; + + static void ImplGetPropertyIds( std::vector< sal_uInt16 > &aIds ); + virtual void GetPropertyIds( std::vector< sal_uInt16 > &aIds ) override { return ImplGetPropertyIds( aIds ); } + + static RMItemData GetRMItemData( const css::container::ContainerEvent& _rEvent ); + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + + virtual ~SVTXRoadmap() override; + + ItemListenerMultiplexer maItemListeners; +}; + + + + +SVTXRoadmap::SVTXRoadmap() : maItemListeners( *this ) +{ +} + +SVTXRoadmap::~SVTXRoadmap() +{ +} + +void SVTXRoadmap::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::RoadmapItemSelected: + { + SolarMutexGuard aGuard; + VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::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<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >(); + if ( !pField ) + return; + + css::uno::Reference< css::uno::XInterface > 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<vcl::RoadmapTypes::ItemId>(nID) , bEnable ); + } + else if ( sPropertyName == "Label" ) + { + OUString sLabel; + evt.NewValue >>= sLabel; + pField->ChangeRoadmapItemLabel( static_cast<vcl::RoadmapTypes::ItemId>(nID) , sLabel ); + } + else if ( sPropertyName == "ID" ) + { + sal_Int32 nNewID = 0; + evt.NewValue >>= nNewID; + evt.OldValue >>= nID; + pField->ChangeRoadmapItemID( static_cast<vcl::RoadmapTypes::ItemId>(nID), static_cast<vcl::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<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >(); + if ( pField ) + { + RMItemData CurItemData = GetRMItemData( _rEvent ); + sal_Int32 InsertIndex = 0; + _rEvent.Accessor >>= InsertIndex; + pField->InsertRoadmapItem( InsertIndex, CurItemData.Label, static_cast<vcl::RoadmapTypes::ItemId>(CurItemData.n_ID), CurItemData.b_Enabled ); + } +} + +void SVTXRoadmap::elementRemoved( const css::container::ContainerEvent& _rEvent ) +{ + SolarMutexGuard aGuard; + VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >(); + if ( pField ) + { + sal_Int32 DelIndex = 0; + _rEvent.Accessor >>= DelIndex; + pField->DeleteRoadmapItem(DelIndex); + } +} + +void SVTXRoadmap::elementReplaced( const css::container::ContainerEvent& _rEvent ) +{ + SolarMutexGuard aGuard; + VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >(); + if ( pField ) + { + RMItemData CurItemData = GetRMItemData( _rEvent ); + sal_Int32 ReplaceIndex = 0; + _rEvent.Accessor >>= ReplaceIndex; + pField->ReplaceRoadmapItem( ReplaceIndex, CurItemData.Label, static_cast<vcl::RoadmapTypes::ItemId>(CurItemData.n_ID), CurItemData.b_Enabled ); + } +} + +void SVTXRoadmap::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::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<vcl::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<::vcl::ORoadmap> pField = GetAs< vcl::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< ::vcl::ORoadmap > pButton = GetAs< ::vcl::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 ); +} + +vcl::Window* VCLXToolkit::ImplCreateWindow( rtl::Reference<VCLXWindow>* ppNewComp, + const css::awt::WindowDescriptor& rDescriptor, + vcl::Window* pParent, WinBits nWinBits, MessBoxStyle nMessBoxStyle ) +{ + OUString aServiceName = rDescriptor.WindowServiceName.toAsciiLowerCase(); + + VclPtr<vcl::Window> pNewWindow; + WindowType nType = ImplGetComponentType( aServiceName ); + bool bFrameControl = false; + if ( aServiceName == "frame" ) + bFrameControl = true; + if ( aServiceName == "tabcontrolnotabs" ) + { + nWinBits |= WB_NOBORDER; + nType = ImplGetComponentType( "tabcontrol" ); + } + if ( !pParent ) + { + // If the component needs a parent, then return NULL, + // some time later css::uno::Exception... + bool bException = true; + if ( ( nType == WindowType::DIALOG ) + || ( nType == WindowType::MODELESSDIALOG ) + || ( nType == WindowType::MESSBOX ) + || ( nType == WindowType::INFOBOX ) + || ( nType == WindowType::WARNINGBOX ) + || ( nType == WindowType::ERRORBOX ) + || ( nType == WindowType::QUERYBOX ) + ) + bException = false; + else if ( ( nType == WindowType::WINDOW ) || + ( nType == WindowType::WORKWINDOW ) || + ( nType == WindowType::TOOLKIT_FRAMEWINDOW ) ) + { + if ( rDescriptor.Type == css::awt::WindowClass_TOP ) + bException = false; + } + + if ( bException ) + { + *ppNewComp = nullptr; + return nullptr; + } + } + + if ( nType != WindowType::NONE ) + { + SolarMutexGuard aVclGuard; + switch ( nType ) + { + case WindowType::CANCELBUTTON: + pNewWindow = VclPtr<CancelButton>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXButton; + break; + case WindowType::CHECKBOX: + pNewWindow = VclPtr<CheckBox>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXCheckBox; + break; + case WindowType::COMBOBOX: + pNewWindow = VclPtr<ComboBox>::Create( pParent, nWinBits|WB_AUTOHSCROLL ); + static_cast<ComboBox*>(pNewWindow.get())->EnableAutoSize( false ); + *ppNewComp = new VCLXComboBox; + break; + case WindowType::CURRENCYBOX: + pNewWindow = VclPtr<CurrencyBox>::Create( pParent, nWinBits ); + break; + case WindowType::CURRENCYFIELD: + pNewWindow = VclPtr<CurrencyField>::Create( pParent, nWinBits ); + static_cast<CurrencyField*>(pNewWindow.get())->EnableEmptyFieldValue( true ); + *ppNewComp = new VCLXNumericField; + static_cast<VCLXFormattedSpinField*>((*ppNewComp).get())->SetFormatter( static_cast<FormatterBase*>(static_cast<CurrencyField*>(pNewWindow.get())) ); + break; + case WindowType::DATEBOX: + pNewWindow = VclPtr<DateBox>::Create( pParent, nWinBits ); + break; + case WindowType::DOCKINGAREA: + pNewWindow = VclPtr<DockingAreaWindow>::Create( pParent ); + break; + case WindowType::MULTILINEEDIT: + pNewWindow = VclPtr<MultiLineEdit>::Create(pParent, nWinBits|WB_IGNORETAB); + static_cast<MultiLineEdit*>(pNewWindow.get())->DisableSelectionOnFocus(); + *ppNewComp = new VCLXMultiLineEdit; + break; + case WindowType::EDIT: + pNewWindow = VclPtr<Edit>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXEdit; + break; + case WindowType::ERRORBOX: + pNewWindow = VclPtr<ErrorBox>::Create( pParent, nMessBoxStyle, nWinBits, OUString() ); + *ppNewComp = new VCLXMessageBox; + break; + case WindowType::FIXEDBITMAP: + pNewWindow = VclPtr<FixedBitmap>::Create( pParent, nWinBits ); + break; + case WindowType::FIXEDIMAGE: + pNewWindow = VclPtr<ImageControl>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXImageControl; + break; + case WindowType::FIXEDLINE: + pNewWindow = VclPtr<FixedLine>::Create( pParent, nWinBits ); + break; + case WindowType::FIXEDTEXT: + pNewWindow = VclPtr<FixedText>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXFixedText; + break; + case WindowType::FLOATINGWINDOW: + pNewWindow = VclPtr<FloatingWindow>::Create( pParent, nWinBits ); + break; + case WindowType::GROUPBOX: + pNewWindow = VclPtr<GroupBox>::Create( pParent, nWinBits ); + if ( bFrameControl ) + { + GroupBox* pGroupBox = static_cast< GroupBox* >( pNewWindow.get() ); + *ppNewComp = new VCLXFrame; + // Frame control needs to receive + // Mouse events + pGroupBox->SetMouseTransparent( false ); + } + break; + case WindowType::HELPBUTTON: + pNewWindow = VclPtr<HelpButton>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXButton; + break; + case WindowType::IMAGEBUTTON: + pNewWindow = VclPtr<ImageButton>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXButton; + break; + case WindowType::INFOBOX: + pNewWindow = VclPtr<InfoBox>::Create( pParent, OUString() ); + *ppNewComp = new VCLXMessageBox; + break; + case WindowType::LISTBOX: + pNewWindow = VclPtr<ListBox>::Create( pParent, nWinBits|WB_SIMPLEMODE|WB_AUTOHSCROLL ); + static_cast<ListBox*>(pNewWindow.get())->EnableAutoSize( false ); + *ppNewComp = new VCLXListBox; + break; + case WindowType::LONGCURRENCYBOX: + pNewWindow = VclPtr<LongCurrencyBox>::Create( pParent, nWinBits ); + break; + case WindowType::MENUBUTTON: + pNewWindow = VclPtr<MenuButton>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXButton; + break; + case WindowType::MESSBOX: + pNewWindow = VclPtr<MessBox>::Create( pParent, nMessBoxStyle, nWinBits, OUString(), OUString() ); + *ppNewComp = new VCLXMessageBox; + break; + case WindowType::METRICBOX: + pNewWindow = VclPtr<MetricBox>::Create( pParent, nWinBits ); + break; + case WindowType::METRICFIELD: + pNewWindow = VclPtr<MetricField>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXMetricField; + static_cast<VCLXFormattedSpinField*>((*ppNewComp).get())->SetFormatter( static_cast<FormatterBase*>(static_cast<MetricField*>(pNewWindow.get())) ); + break; + case WindowType::DIALOG: + case WindowType::MODELESSDIALOG: + { + // Modal/Modeless only via Show/Execute + if ( (pParent == nullptr ) && ( rDescriptor.ParentIndex == -1 ) ) + pNewWindow = VclPtr<toolkit::ScrollableDialog>::Create( nullptr, nWinBits, Dialog::InitFlag::NoParent ); + else + pNewWindow = VclPtr<toolkit::ScrollableDialog>::Create( pParent, nWinBits ); + // #i70217# Don't always create a new component object. It's possible that VCL has called + // GetComponentInterface( sal_True ) in the Dialog ctor itself (see Window::IsTopWindow() ) + // which creates a component object. + css::uno::Reference< css::awt::XWindowPeer > xWinPeer = pNewWindow->GetComponentInterface( false ); + if ( xWinPeer.is() ) + *ppNewComp = dynamic_cast< VCLXDialog* >( xWinPeer.get() ); + else + *ppNewComp = new VCLXDialog; + } + break; + case WindowType::MOREBUTTON: + pNewWindow = VclPtr<MoreButton>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXButton; + break; + case WindowType::MULTILISTBOX: + pNewWindow = VclPtr<MultiListBox>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXListBox; + break; + case WindowType::NUMERICBOX: + pNewWindow = VclPtr<NumericBox>::Create( pParent, nWinBits ); + break; + case WindowType::OKBUTTON: + pNewWindow = VclPtr<OKButton>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXButton; + break; + case WindowType::PATTERNBOX: + pNewWindow = VclPtr<PatternBox>::Create( pParent, nWinBits ); + break; + case WindowType::PATTERNFIELD: + pNewWindow = VclPtr<PatternField>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXPatternField; + static_cast<VCLXFormattedSpinField*>((*ppNewComp).get())->SetFormatter( static_cast<FormatterBase*>(static_cast<PatternField*>(pNewWindow.get())) ); + break; + case WindowType::PUSHBUTTON: + pNewWindow = VclPtr<PushButton>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXButton; + break; + case WindowType::QUERYBOX: + pNewWindow = VclPtr<QueryBox>::Create( pParent, nMessBoxStyle, nWinBits, OUString() ); + *ppNewComp = new VCLXMessageBox; + break; + case WindowType::RADIOBUTTON: + pNewWindow = VclPtr<RadioButton>::Create(pParent, false, nWinBits); + *ppNewComp = new VCLXRadioButton; + + // by default, disable RadioCheck + // Since the VCLXRadioButton really cares for its RadioCheck settings, this is important: + // if we enable it, the VCLXRadioButton will use RadioButton::Check instead of RadioButton::SetState + // This leads to a strange behaviour if the control is newly created: when settings the initial + // state to "checked", the RadioButton::Check (called because RadioCheck=sal_True) will uncheck + // _all_other_ radio buttons in the same group. However, at this moment the grouping of the controls + // is not really valid: the controls are grouped after they have been created, but we're still in + // the creation process, so the RadioButton::Check relies on invalid grouping information. + // 07.08.2001 - #87254# - frank.schoenheit@sun.com + static_cast<RadioButton*>(pNewWindow.get())->EnableRadioCheck( false ); + break; + case WindowType::SCROLLBAR: + pNewWindow = VclPtr<ScrollBar>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXScrollBar; + break; + case WindowType::SCROLLBARBOX: + pNewWindow = VclPtr<ScrollBarBox>::Create( pParent, nWinBits ); + break; + case WindowType::SPINBUTTON: + pNewWindow = VclPtr<SpinButton>::Create( pParent, nWinBits ); + *ppNewComp = new ::toolkit::VCLXSpinButton; + break; + case WindowType::SPINFIELD: + pNewWindow = VclPtr<SpinField>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXNumericField; + break; + case WindowType::SPLITTER: + pNewWindow = VclPtr<Splitter>::Create( pParent, nWinBits ); + break; + case WindowType::SPLITWINDOW: + pNewWindow = VclPtr<SplitWindow>::Create( pParent, nWinBits ); + break; + case WindowType::STATUSBAR: + pNewWindow = VclPtr<StatusBar>::Create( pParent, nWinBits ); + break; + case WindowType::TOOLKIT_SYSTEMCHILDWINDOW: + pNewWindow = VclPtr<SystemChildWindow>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXSystemDependentWindow(); + break; + case WindowType::TABCONTROL: + pNewWindow = VclPtr<TabControl>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXMultiPage; + break; + case WindowType::TABDIALOG: + pNewWindow = VclPtr<TabDialog>::Create( pParent, nWinBits ); + break; + case WindowType::TABPAGE: + { + pNewWindow = VclPtr<TabPage>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXTabPage; + } + break; + case WindowType::TIMEBOX: + pNewWindow = VclPtr<TimeBox>::Create( pParent, nWinBits ); + break; + case WindowType::TIMEFIELD: + pNewWindow = VclPtr<TimeField>::Create( pParent, nWinBits ); + static_cast<TimeField*>(pNewWindow.get())->EnableEmptyFieldValue( true ); + *ppNewComp = new VCLXTimeField; + static_cast<VCLXFormattedSpinField*>((*ppNewComp).get())->SetFormatter( static_cast<FormatterBase*>(static_cast<TimeField*>(pNewWindow.get())) ); + break; + case WindowType::TOOLBOX: + pNewWindow = VclPtr<ToolBox>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXToolBox; + break; + case WindowType::TRISTATEBOX: + pNewWindow = VclPtr<CheckBox>::Create( pParent, nWinBits ); + static_cast<CheckBox*>(pNewWindow.get())->EnableTriState(true); + break; + case WindowType::WARNINGBOX: + pNewWindow = VclPtr<WarningBox>::Create( pParent, nMessBoxStyle, nWinBits, OUString() ); + *ppNewComp = new VCLXMessageBox; + break; + case WindowType::WORKWINDOW: + case WindowType::WINDOW: + case WindowType::TOOLKIT_FRAMEWINDOW: + case WindowType::DOCKINGWINDOW: + if ( rDescriptor.Type == css::awt::WindowClass_TOP ) + { + if (nType == WindowType::DOCKINGWINDOW ) + pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits ); + else + { + if ((pParent == nullptr) && rDescriptor.Parent.is()) + { + // try to get a system dependent window handle + css::uno::Reference< css::awt::XSystemDependentWindowPeer > xSystemDepParent(rDescriptor.Parent, css::uno::UNO_QUERY); + + if (xSystemDepParent.is()) + { + sal_Int8 processID[16]; + + rtl_getGlobalProcessId( reinterpret_cast<sal_uInt8*>(processID) ); + + // coverity[overrun-buffer-arg : FALSE] - coverity has difficulty with css::uno::Sequence + css::uno::Sequence<sal_Int8> processIdSeq(processID, 16); + + css::uno::Any anyHandle = xSystemDepParent->getWindowHandle(processIdSeq, SYSTEM_DEPENDENT_TYPE); + + // use sal_Int64 here to accommodate all int types + // uno::Any shift operator will upcast if necessary + sal_Int64 nWindowHandle = 0; + bool bXEmbed = false; + + bool bUseParentData = true; + if( ! (anyHandle >>= nWindowHandle) ) + { + css::uno::Sequence< css::beans::NamedValue > aProps; + if( anyHandle >>= aProps ) + { + for( const css::beans::NamedValue& rProp : std::as_const(aProps) ) + { + if ( rProp.Name == "WINDOW" ) + rProp.Value >>= nWindowHandle; + else if ( rProp.Name == "XEMBED" ) + rProp.Value >>= bXEmbed; + } + } + else + bUseParentData = false; + } + + if( bUseParentData ) + { + SystemParentData aParentData; + aParentData.nSize = sizeof( aParentData ); + #if defined MACOSX + aParentData.pView = reinterpret_cast<NSView*>(nWindowHandle); + #elif defined ANDROID + // Nothing + #elif defined IOS + // Nothing + #elif defined UNX + aParentData.aWindow = nWindowHandle; + aParentData.bXEmbedSupport = bXEmbed; + #elif defined _WIN32 + aParentData.hWnd = reinterpret_cast<HWND>(nWindowHandle); + #endif + pNewWindow = VclPtr<WorkWindow>::Create( &aParentData ); + } + } + } + + if (!pNewWindow) + pNewWindow = VclPtr<WorkWindow>::Create( pParent, nWinBits ); + } + + *ppNewComp = new VCLXTopWindow(); + } + else if ( rDescriptor.Type == css::awt::WindowClass_CONTAINER ) + { + if (nType == WindowType::DOCKINGWINDOW ) + pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits ); + else + pNewWindow = VclPtr<vcl::Window>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXContainer; + } + else + { + if (nType == WindowType::DOCKINGWINDOW ) + pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits ); + else + pNewWindow = VclPtr<vcl::Window>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXWindow; + } + break; + case WindowType::CONTROL: + if ( aServiceName == "tabpagecontainer" ) + { + // TabControl has a special case for tabs without border: they are displayed + // in a different way, so we need to ensure that this style is not set, so + // we can guarantee normal tab behavior + pNewWindow = VclPtr<TabControl>::Create( pParent, nWinBits & (~WB_NOBORDER)); + *ppNewComp = new VCLXTabPageContainer; + } + else if ( aServiceName == "animatedimages" ) + { + pNewWindow = VclPtr<Throbber>::Create( pParent, nWinBits ); + *ppNewComp = new ::toolkit::AnimatedImagesPeer; + } + else if (aServiceName == "roadmap") + { + pNewWindow = VclPtr<::vcl::ORoadmap>::Create( pParent, WB_TABSTOP ); + *ppNewComp = new SVTXRoadmap; + } + else if (aServiceName == "fixedhyperlink") + { + pNewWindow = VclPtr<FixedHyperlink>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXFixedHyperlink; + } + else if (aServiceName == "progressbar") + { + pNewWindow = VclPtr<ProgressBar>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXProgressBar; + } + else if (aServiceName == "filecontrol") + { + pNewWindow = VclPtr<FileControl>::Create( pParent, nWinBits ); + *ppNewComp = new VCLXFileControl; + } + else if (aServiceName == "tree") + { + rtl::Reference<TreeControlPeer> pPeer = new TreeControlPeer; + *ppNewComp = pPeer; + pNewWindow = pPeer->createVclControl( pParent, nWinBits ); + } + else if (aServiceName == "formattedfield") + { + pNewWindow = VclPtr<FormattedField>::Create( pParent, nWinBits ); + *ppNewComp = new SVTXFormattedField; + } + else if (aServiceName == "numericfield") + { + pNewWindow = VclPtr<DoubleNumericField>::Create( pParent, nWinBits ); + *ppNewComp = new SVTXNumericField; + } + else if (aServiceName == "longcurrencyfield") + { + pNewWindow = VclPtr<DoubleCurrencyField>::Create( pParent, nWinBits ); + *ppNewComp = new SVTXCurrencyField; + } + else if (aServiceName == "datefield") + { + pNewWindow = VclPtr<CalendarField>::Create(pParent, nWinBits); + static_cast<CalendarField*>(pNewWindow.get())->EnableToday(); + static_cast<CalendarField*>(pNewWindow.get())->EnableNone(); + static_cast<CalendarField*>(pNewWindow.get())->EnableEmptyFieldValue( true ); + rtl::Reference<SVTXDateField> newComp = new SVTXDateField; + *ppNewComp = newComp; + newComp->SetFormatter( static_cast<FormatterBase*>(static_cast<DateField*>(pNewWindow.get())) ); + } + break; + default: + OSL_ENSURE( false, "VCLXToolkit::ImplCreateWindow: unknown window type!" ); + break; + } + } + + // tdf#126717 default that formcontrols show accelerators + if (Control* pControl = dynamic_cast<Control*>(pNewWindow.get())) + pControl->SetShowAccelerator(true); + return pNewWindow; +} + +#ifndef DISABLE_DYNLOADING + +extern "C" { static void thisModule() {} } + +#else + +extern "C" vcl::Window* SAL_CALL CreateWindow( rtl::Reference<VCLXWindow>* ppNewComp, const css::awt::WindowDescriptor* pDescriptor, vcl::Window* pParent, WinBits nWinBits ); + +#endif + +css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::ImplCreateWindow( + const css::awt::WindowDescriptor& rDescriptor, + MessBoxStyle nForceMessBoxStyle ) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + SolarMutexGuard aSolarGuard; + + css::uno::Reference< css::awt::XWindowPeer > xRef; + + VclPtr<vcl::Window> pParent; + if ( rDescriptor.Parent.is() ) + { + VCLXWindow* pParentComponent = comphelper::getFromUnoTunnel<VCLXWindow>( rDescriptor.Parent ); + + // #103939# Don't throw assertion, may be it's a system dependent window, used in ImplCreateWindow. + // DBG_ASSERT( pParentComponent, "ParentComponent not valid" ); + + if ( pParentComponent ) + pParent = pParentComponent->GetWindow(); + } + std::pair<WinBits, MessBoxStyle> aPair = ImplGetWinBits( rDescriptor.WindowAttributes, + ImplGetComponentType( rDescriptor.WindowServiceName ) ); + WinBits nWinBits = aPair.first; + aPair.second |= nForceMessBoxStyle; + + rtl::Reference<VCLXWindow> pNewComp; + + vcl::Window* pNewWindow = nullptr; + // Try to create the window with SvTools + // (do this _before_ creating it on our own: The old mechanism (extended toolkit in SvTools) did it this way, + // and we need to stay compatible) + // try to load the lib + if ( !fnSvtCreateWindow +#ifndef DISABLE_DYNLOADING + && !hSvToolsLib +#endif + ) + { +#ifndef DISABLE_DYNLOADING + OUString aLibName(SVT_DLL_NAME); + hSvToolsLib = osl_loadModuleRelative( + &thisModule, aLibName.pData, SAL_LOADMODULE_DEFAULT ); + if ( hSvToolsLib ) + { + OUString aFunctionName( "CreateWindow" ); + fnSvtCreateWindow = reinterpret_cast<FN_SvtCreateWindow>(osl_getFunctionSymbol( hSvToolsLib, aFunctionName.pData )); + } +#else + fnSvtCreateWindow = CreateWindow; +#endif + } + // ask the SvTool creation function + if ( fnSvtCreateWindow ) + pNewWindow = fnSvtCreateWindow( &pNewComp, &rDescriptor, pParent, nWinBits ); + + // if SvTools could not provide a window, create it ourself + if ( !pNewWindow ) + pNewWindow = ImplCreateWindow( &pNewComp, rDescriptor, pParent, nWinBits, aPair.second ); + + DBG_ASSERT( pNewWindow, "createWindow: Unknown Component!" ); + SAL_INFO_IF( !pNewComp, "toolkit", "createWindow: No special Interface!" ); + + if ( pNewWindow ) + { + pNewWindow->SetCreatedWithToolkit( true ); + //pNewWindow->SetPosPixel( Point() ); // do not force (0,0) position, keep default pos instead + + if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::MINSIZE ) + { + pNewWindow->SetSizePixel( Size() ); + } + else if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::FULLSIZE ) + { + if ( pParent ) + pNewWindow->SetSizePixel( pParent->GetOutputSizePixel() ); + } + else if ( !VCLUnoHelper::IsZero( rDescriptor.Bounds ) ) + { + tools::Rectangle aRect = VCLRectangle( rDescriptor.Bounds ); + pNewWindow->SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() ); + } + + if ( !pNewComp ) + { + // Default-Interface + xRef = pNewWindow->GetComponentInterface(); + } + else + { + xRef = pNewComp; + pNewWindow->SetComponentInterface( xRef ); + } + DBG_ASSERT( pNewWindow->GetComponentInterface( false ) == xRef, + "VCLXToolkit::createWindow: did #133706# resurge?" ); + + if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::SHOW ) + pNewWindow->Show(); + } + + return xRef; +} + +css::uno::Sequence< css::uno::Reference< css::awt::XWindowPeer > > VCLXToolkit::createWindows( const css::uno::Sequence< css::awt::WindowDescriptor >& rDescriptors ) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + sal_uInt32 nComponents = rDescriptors.getLength(); + css::uno::Sequence< css::uno::Reference< css::awt::XWindowPeer > > aSeq( nComponents ); + for ( sal_uInt32 n = 0; n < nComponents; n++ ) + { + css::awt::WindowDescriptor aDescr = rDescriptors.getConstArray()[n]; + + if ( aDescr.ParentIndex == -1 ) + aDescr.Parent = nullptr; + else if ( ( aDescr.ParentIndex >= 0 ) && ( o3tl::make_unsigned(aDescr.ParentIndex) < n ) ) + aDescr.Parent = aSeq.getConstArray()[aDescr.ParentIndex]; + aSeq.getArray()[n] = createWindow( aDescr ); + } + return aSeq; +} + +// css::awt::XSystemChildFactory +css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::createSystemChild( const css::uno::Any& Parent, const css::uno::Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 nSystemType ) +{ + VclPtr<vcl::Window> pChildWindow; + if ( nSystemType == SYSTEM_DEPENDENT_TYPE ) + { + // use sal_Int64 here to accommodate all int types + // uno::Any shift operator will upcast if necessary + sal_Int64 nWindowHandle = 0; + bool bXEmbed = false; + + bool bUseParentData = true; + if( ! (Parent >>= nWindowHandle) ) + { + css::uno::Sequence< css::beans::NamedValue > aProps; + if( Parent >>= aProps ) + { + for( const css::beans::NamedValue& rProp : std::as_const(aProps) ) + { + if ( rProp.Name == "WINDOW" ) + rProp.Value >>= nWindowHandle; + else if ( rProp.Name == "XEMBED" ) + rProp.Value >>= bXEmbed; + } + } + else + bUseParentData = false; + } + + if( bUseParentData ) + { + SystemParentData aParentData; + aParentData.nSize = sizeof( aParentData ); + #if defined MACOSX + aParentData.pView = reinterpret_cast<NSView*>(nWindowHandle); + #elif defined ANDROID + // Nothing + #elif defined IOS + // Nothing + #elif defined UNX + aParentData.aWindow = nWindowHandle; + aParentData.bXEmbedSupport = bXEmbed; + #elif defined _WIN32 + aParentData.hWnd = reinterpret_cast<HWND>(nWindowHandle); + #endif + SolarMutexGuard aGuard; + try + { + pChildWindow.reset( VclPtr<WorkWindow>::Create( &aParentData ) ); + } + catch ( const css::uno::RuntimeException & ) + { + // system child window could not be created + DBG_UNHANDLED_EXCEPTION("toolkit"); + pChildWindow.clear(); + } + } + } + else if (nSystemType == css::lang::SystemDependent::SYSTEM_JAVA) + { + SolarMutexGuard aGuard; + pChildWindow.reset(VclPtr<WorkWindow>::Create(nullptr, Parent)); + } + + css::uno::Reference< css::awt::XWindowPeer > xPeer; + if ( pChildWindow ) + { + rtl::Reference<VCLXTopWindow> pPeer = new VCLXTopWindow; + SolarMutexGuard aGuard; + pPeer->SetWindow( pChildWindow ); + xPeer = pPeer; + pChildWindow->SetWindowPeer(xPeer, pPeer.get()); + } + + return xPeer; +} + +// css::awt::XMessageBoxFactory +css::uno::Reference< css::awt::XMessageBox > SAL_CALL VCLXToolkit::createMessageBox( + const css::uno::Reference< css::awt::XWindowPeer >& aParent, + css::awt::MessageBoxType eType, + ::sal_Int32 aButtons, + const OUString& aTitle, + const OUString& aMessage ) +{ + css::awt::WindowDescriptor aDescriptor; + + sal_Int32 nWindowAttributes = css::awt::WindowAttribute::BORDER|css::awt::WindowAttribute::MOVEABLE|css::awt::WindowAttribute::CLOSEABLE; + + // Map button definitions to window attributes + if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_OK ) + nWindowAttributes |= css::awt::VclWindowPeerAttribute::OK; + else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_OK_CANCEL ) + nWindowAttributes |= css::awt::VclWindowPeerAttribute::OK_CANCEL; + else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_YES_NO ) + nWindowAttributes |= css::awt::VclWindowPeerAttribute::YES_NO; + else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_YES_NO_CANCEL ) + nWindowAttributes |= css::awt::VclWindowPeerAttribute::YES_NO_CANCEL; + else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_RETRY_CANCEL ) + nWindowAttributes |= css::awt::VclWindowPeerAttribute::RETRY_CANCEL; + + // Map default button definitions to window attributes + if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_OK ) + nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_OK; + else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_CANCEL ) + nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_CANCEL; + else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_YES ) + nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_YES; + else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_NO ) + nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_NO; + else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_RETRY ) + nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_RETRY; + + // No more bits for VclWindowPeerAttribute possible. Mapping must be + // done explicitly using VCL methods + MessBoxStyle nAddWinBits = MessBoxStyle::NONE; + if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_ABORT_IGNORE_RETRY ) + nAddWinBits |= MessBoxStyle::AbortRetryIgnore; + if ( sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_IGNORE ) + nAddWinBits |= MessBoxStyle::DefaultIgnore; + + OUString aType; + lcl_convertMessageBoxType( aType, eType ); + + aDescriptor.Type = css::awt::WindowClass_MODALTOP; + aDescriptor.WindowServiceName = aType; + aDescriptor.ParentIndex = -1; + aDescriptor.Parent = aParent; + aDescriptor.WindowAttributes = nWindowAttributes; + css::uno::Reference< css::awt::XMessageBox > xMsgBox( + ImplCreateWindow( aDescriptor, nAddWinBits ), css::uno::UNO_QUERY ); + css::uno::Reference< css::awt::XWindow > xWindow( xMsgBox, css::uno::UNO_QUERY ); + if ( xMsgBox.is() && xWindow.is() ) + { + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + SolarMutexGuard aGuard; + xMsgBox->setCaptionText( aTitle ); + xMsgBox->setMessageText( aMessage ); + } + } + + return xMsgBox; +} + +css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > SAL_CALL VCLXToolkit::getDragGestureRecognizer( const css::uno::Reference< css::awt::XWindow >& window ) +{ + SolarMutexGuard g; + + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( window ); + + if( pWindow ) + return pWindow->GetDragGestureRecognizer(); + + return css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer >(); +} + +css::uno::Reference< css::datatransfer::dnd::XDragSource > SAL_CALL VCLXToolkit::getDragSource( const css::uno::Reference< css::awt::XWindow >& window ) +{ + SolarMutexGuard g; + + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( window ); + + if( pWindow ) + return pWindow->GetDragSource(); + + return css::uno::Reference< css::datatransfer::dnd::XDragSource >(); +} + +css::uno::Reference< css::datatransfer::dnd::XDropTarget > SAL_CALL VCLXToolkit::getDropTarget( const css::uno::Reference< css::awt::XWindow >& window ) +{ + SolarMutexGuard g; + + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( window ); + + if( pWindow ) + return pWindow->GetDropTarget(); + + return css::uno::Reference< css::datatransfer::dnd::XDropTarget >(); +} + +css::uno::Reference< css::datatransfer::clipboard::XClipboard > SAL_CALL VCLXToolkit::getClipboard( const OUString& clipboardName ) +{ + if( clipboardName.isEmpty() ) + { + if( !mxClipboard.is() ) + { + // remember clipboard here + mxClipboard = css::datatransfer::clipboard::SystemClipboard::create( + comphelper::getProcessComponentContext()); + } + + return mxClipboard; + } + + else if( clipboardName == "Selection" ) + { + return mxSelection; + } + + return css::uno::Reference< css::datatransfer::clipboard::XClipboard >(); +} + +// XServiceInfo +OUString VCLXToolkit::getImplementationName() +{ + return "stardiv.Toolkit.VCLXToolkit"; +} + +sal_Bool VCLXToolkit::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > VCLXToolkit::getSupportedServiceNames() +{ + return css::uno::Sequence<OUString>{ + "com.sun.star.awt.Toolkit", "stardiv.vcl.VclToolkit"}; +} + +// css::awt::XExtendedToolkit: + +// virtual +::sal_Int32 SAL_CALL VCLXToolkit::getTopWindowCount() +{ + return static_cast< ::sal_Int32 >(::Application::GetTopWindowCount()); + // XXX numeric overflow +} + +// virtual +css::uno::Reference< css::awt::XTopWindow > SAL_CALL +VCLXToolkit::getTopWindow(::sal_Int32 nIndex) +{ + vcl::Window * p = ::Application::GetTopWindow(static_cast< tools::Long >(nIndex)); + // XXX numeric overflow + return css::uno::Reference< css::awt::XTopWindow >( + p == nullptr ? nullptr : static_cast< css::awt::XWindow * >(p->GetWindowPeer()), + css::uno::UNO_QUERY); +} + +// virtual +css::uno::Reference< css::awt::XTopWindow > SAL_CALL +VCLXToolkit::getActiveTopWindow() +{ + vcl::Window * p = ::Application::GetActiveTopWindow(); + return css::uno::Reference< css::awt::XTopWindow >( + p == nullptr ? nullptr : static_cast< css::awt::XWindow * >(p->GetWindowPeer()), + css::uno::UNO_QUERY); +} + +// virtual +void SAL_CALL VCLXToolkit::addTopWindowListener( + css::uno::Reference< css::awt::XTopWindowListener > const & rListener) +{ + OSL_ENSURE(rListener.is(), "Null rListener"); + ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex); + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + aGuard.clear(); + rListener->disposing( + css::lang::EventObject( + static_cast< ::cppu::OWeakObject * >(this))); + } + else if (m_aTopWindowListeners.addInterface(rListener) == 1 + && !m_bEventListener) + { + m_bEventListener = true; + ::Application::AddEventListener(m_aEventListenerLink); + } +} + +// virtual +void SAL_CALL VCLXToolkit::removeTopWindowListener( + css::uno::Reference< css::awt::XTopWindowListener > const & rListener) +{ + ::osl::MutexGuard aGuard(rBHelper.rMutex); + if (!(rBHelper.bDisposed || rBHelper.bInDispose) + && m_aTopWindowListeners.removeInterface(rListener) == 0 + && m_aFocusListeners.getLength() == 0 && m_bEventListener) + { + ::Application::RemoveEventListener(m_aEventListenerLink); + m_bEventListener = false; + } +} + +// virtual +void SAL_CALL VCLXToolkit::addKeyHandler( + css::uno::Reference< css::awt::XKeyHandler > const & rHandler) +{ + OSL_ENSURE(rHandler.is(), "Null rHandler"); + ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex); + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + aGuard.clear(); + rHandler->disposing( + css::lang::EventObject( + static_cast< ::cppu::OWeakObject * >(this))); + } + else if (m_aKeyHandlers.addInterface(rHandler) == 1 && !m_bKeyListener) + { + m_bKeyListener = true; + ::Application::AddKeyListener(m_aKeyListenerLink); + } +} + +// virtual +void SAL_CALL VCLXToolkit::removeKeyHandler( + css::uno::Reference< css::awt::XKeyHandler > const & rHandler) +{ + ::osl::MutexGuard aGuard(rBHelper.rMutex); + if (!(rBHelper.bDisposed || rBHelper.bInDispose) + && m_aKeyHandlers.removeInterface(rHandler) == 0 && m_bKeyListener) + { + ::Application::RemoveKeyListener(m_aKeyListenerLink); + m_bKeyListener = false; + } +} + +// virtual +void SAL_CALL VCLXToolkit::addFocusListener( + css::uno::Reference< css::awt::XFocusListener > const & rListener) +{ + OSL_ENSURE(rListener.is(), "Null rListener"); + ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex); + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + aGuard.clear(); + rListener->disposing( + css::lang::EventObject( + static_cast< ::cppu::OWeakObject * >(this))); + } + else if (m_aFocusListeners.addInterface(rListener) == 1 + && !m_bEventListener) + { + m_bEventListener = true; + ::Application::AddEventListener(m_aEventListenerLink); + } +} + +// virtual +void SAL_CALL VCLXToolkit::removeFocusListener( + css::uno::Reference< css::awt::XFocusListener > const & rListener) +{ + ::osl::MutexGuard aGuard(rBHelper.rMutex); + if (!(rBHelper.bDisposed || rBHelper.bInDispose) + && m_aFocusListeners.removeInterface(rListener) == 0 + && m_aTopWindowListeners.getLength() == 0 && m_bEventListener) + { + ::Application::RemoveEventListener(m_aEventListenerLink); + m_bEventListener = false; + } +} + +// virtual +void SAL_CALL VCLXToolkit::fireFocusGained( + css::uno::Reference< + css::uno::XInterface > const &) +{ +} + +// virtual +void SAL_CALL VCLXToolkit::fireFocusLost( + css::uno::Reference< + css::uno::XInterface > const &) +{ +} + + +IMPL_LINK(VCLXToolkit, eventListenerHandler, ::VclSimpleEvent&, rEvent, void) +{ + switch (rEvent.GetId()) + { + case VclEventId::WindowShow: + callTopWindowListeners( + &rEvent, &css::awt::XTopWindowListener::windowOpened); + break; + case VclEventId::WindowHide: + callTopWindowListeners( + &rEvent, &css::awt::XTopWindowListener::windowClosed); + break; + case VclEventId::WindowActivate: + callTopWindowListeners( + &rEvent, &css::awt::XTopWindowListener::windowActivated); + break; + case VclEventId::WindowDeactivate: + callTopWindowListeners( + &rEvent, &css::awt::XTopWindowListener::windowDeactivated); + break; + case VclEventId::WindowClose: + callTopWindowListeners( + &rEvent, &css::awt::XTopWindowListener::windowClosing); + break; + case VclEventId::WindowGetFocus: + callFocusListeners(&rEvent, true); + break; + case VclEventId::WindowLoseFocus: + callFocusListeners(&rEvent, false); + break; + case VclEventId::WindowMinimize: + callTopWindowListeners( + &rEvent, &css::awt::XTopWindowListener::windowMinimized); + break; + case VclEventId::WindowNormalize: + callTopWindowListeners( + &rEvent, &css::awt::XTopWindowListener::windowNormalized); + break; + default: break; + } +} + +IMPL_LINK(VCLXToolkit, keyListenerHandler, ::VclWindowEvent&, rEvent, bool) +{ + switch (rEvent.GetId()) + { + case VclEventId::WindowKeyInput: + return callKeyHandlers(&rEvent, true); + case VclEventId::WindowKeyUp: + return callKeyHandlers(&rEvent, false); + default: break; + } + return false; +} + +void VCLXToolkit::callTopWindowListeners( + ::VclSimpleEvent const * pEvent, + void (SAL_CALL css::awt::XTopWindowListener::* pFn)( + css::lang::EventObject const &)) +{ + vcl::Window * pWindow + = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow(); + if (!pWindow->IsTopWindow()) + return; + + std::vector< css::uno::Reference< css::awt::XTopWindowListener > > + aListeners(m_aTopWindowListeners.getElements()); + if (aListeners.empty()) + return; + + css::lang::EventObject aAwtEvent( + static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer())); + for (const css::uno::Reference<css::awt::XTopWindowListener> & xListener : aListeners) + { + try + { + (xListener.get()->*pFn)(aAwtEvent); + } + catch (const css::uno::RuntimeException &) + { + DBG_UNHANDLED_EXCEPTION("toolkit"); + } + } +} + +bool VCLXToolkit::callKeyHandlers(::VclSimpleEvent const * pEvent, + bool bPressed) +{ + std::vector< css::uno::Reference< css::awt::XKeyHandler > > + aHandlers(m_aKeyHandlers.getElements()); + + if (!aHandlers.empty()) + { + vcl::Window * pWindow = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow(); + + // See implementation in vclxwindow.cxx for mapping between VCL and UNO AWT event + ::KeyEvent * pKeyEvent = static_cast< ::KeyEvent * >( + static_cast< ::VclWindowEvent const * >(pEvent)->GetData()); + css::awt::KeyEvent aAwtEvent( + static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()), + (pKeyEvent->GetKeyCode().IsShift() + ? css::awt::KeyModifier::SHIFT : 0) + | (pKeyEvent->GetKeyCode().IsMod1() + ? css::awt::KeyModifier::MOD1 : 0) + | (pKeyEvent->GetKeyCode().IsMod2() + ? css::awt::KeyModifier::MOD2 : 0) + | (pKeyEvent->GetKeyCode().IsMod3() + ? css::awt::KeyModifier::MOD3 : 0), + pKeyEvent->GetKeyCode().GetCode(), pKeyEvent->GetCharCode(), + sal::static_int_cast< sal_Int16 >( + pKeyEvent->GetKeyCode().GetFunction())); + for (const css::uno::Reference<css::awt::XKeyHandler> & xHandler : aHandlers) + { + try + { + if (bPressed ? xHandler->keyPressed(aAwtEvent) + : xHandler->keyReleased(aAwtEvent)) + return true; + } + catch (const css::uno::RuntimeException &) + { + DBG_UNHANDLED_EXCEPTION("toolkit"); + } + } + } + return false; +} + +void VCLXToolkit::callFocusListeners(::VclSimpleEvent const * pEvent, + bool bGained) +{ + vcl::Window * pWindow + = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow(); + if (!pWindow->IsTopWindow()) + return; + + std::vector< css::uno::Reference< css::awt::XFocusListener > > + aListeners(m_aFocusListeners.getElements()); + if (aListeners.empty()) + return; + + // Ignore the interior of compound controls when determining the + // window that gets the focus next (see implementation in + // vclxwindow.cxx for mapping between VCL and UNO AWT event): + css::uno::Reference< css::uno::XInterface > xNext; + vcl::Window * pFocus = ::Application::GetFocusWindow(); + for (vcl::Window * p = pFocus; p != nullptr; p = p->GetParent()) + if (!p->IsCompoundControl()) + { + pFocus = p; + break; + } + if (pFocus != nullptr) + xNext = pFocus->GetComponentInterface(); + css::awt::FocusEvent aAwtEvent( + static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()), + static_cast<sal_Int16>(pWindow->GetGetFocusFlags()), + xNext, false); + for (const css::uno::Reference<css::awt::XFocusListener> & xListener : aListeners) + { + try + { + bGained ? xListener->focusGained(aAwtEvent) + : xListener->focusLost(aAwtEvent); + } + catch (const css::uno::RuntimeException &) + { + DBG_UNHANDLED_EXCEPTION("toolkit"); + } + } +} + +// css::awt::XReschedule: + +void SAL_CALL VCLXToolkit::reschedule() +{ + SolarMutexGuard aSolarGuard; + Application::Reschedule(true); +} + +// css::awt::XFontMappingUse: +void SAL_CALL VCLXToolkit::startTrackingFontMappingUse() +{ + SolarMutexGuard aSolarGuard; + OutputDevice::StartTrackingFontMappingUse(); +} + +css::uno::Sequence<css::awt::XFontMappingUseItem> +SAL_CALL VCLXToolkit::finishTrackingFontMappingUse() +{ + SolarMutexGuard aSolarGuard; + OutputDevice::FontMappingUseData data = OutputDevice::FinishTrackingFontMappingUse(); + css::uno::Sequence<css::awt::XFontMappingUseItem> ret( data.size()); + css::awt::XFontMappingUseItem* retData = ret.getArray(); + for( size_t i = 0; i < data.size(); ++i ) + { + retData[ i ].originalFont = data[ i ].mOriginalFont; + retData[ i ].usedFonts = comphelper::arrayToSequence<OUString,OUString> + (data[ i ].mUsedFonts.data(), data[ i ].mUsedFonts.size()); + retData[ i ].count = data[ i ].mCount; + } + return ret; +} + +// css::awt::XToolkitExperimental + +void SAL_CALL VCLXToolkit::processEventsToIdle() +{ + SolarMutexGuard aSolarGuard; + comphelper::ProfileZone aZone("processEvents"); + Scheduler::ProcessEventsToIdle(); +} + +sal_Int64 SAL_CALL VCLXToolkit::getOpenGLBufferSwapCounter() +{ +#if HAVE_FEATURE_OPENGL + return OpenGLWrapper::getBufferSwapCounter(); +#else + return 0; +#endif +} + +void SAL_CALL VCLXToolkit::setDeterministicScheduling(sal_Bool bDeterministicMode) +{ + SolarMutexGuard aSolarGuard; + Scheduler::SetDeterministicMode(bDeterministicMode); +} + +void SAL_CALL VCLXToolkit::pause(sal_Int32 nMilliseconds) +{ + new Pause(nMilliseconds); +} + +void SAL_CALL VCLXToolkit::startRecording() +{ + comphelper::TraceEvent::startRecording(); +} + +void SAL_CALL VCLXToolkit::stopRecording() +{ + comphelper::TraceEvent::stopRecording(); +} + +css::uno::Sequence< OUString > VCLXToolkit::getRecordingAndClear() +{ + return comphelper::ProfileZone::getRecordingAndClear(); +} + +// css:awt:XToolkitRobot + +void SAL_CALL VCLXToolkit::keyPress( const css::awt::KeyEvent & aKeyEvent ) +{ + css::uno::Reference<css::awt::XWindow> xWindow ( aKeyEvent.Source, css::uno::UNO_QUERY_THROW ); + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); + if( !pWindow ) + throw css::uno::RuntimeException( "invalid event source" ); + + ::KeyEvent aVCLKeyEvent = VCLUnoHelper::createVCLKeyEvent( aKeyEvent ); + ::Application::PostKeyEvent( VclEventId::WindowKeyInput, pWindow, &aVCLKeyEvent ); +} + +void SAL_CALL VCLXToolkit::keyRelease( const css::awt::KeyEvent & aKeyEvent ) +{ + css::uno::Reference<css::awt::XWindow> xWindow ( aKeyEvent.Source, css::uno::UNO_QUERY_THROW ); + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); + if( !pWindow ) + throw css::uno::RuntimeException( "invalid event source" ); + + ::KeyEvent aVCLKeyEvent = VCLUnoHelper::createVCLKeyEvent( aKeyEvent ); + ::Application::PostKeyEvent( VclEventId::WindowKeyUp, pWindow, &aVCLKeyEvent ); +} + + +void SAL_CALL VCLXToolkit::mousePress( const css::awt::MouseEvent & aMouseEvent ) +{ + css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY_THROW ); + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); + if( !pWindow ) + throw css::uno::RuntimeException( "invalid event source" ); + + ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent ); + ::Application::PostMouseEvent( VclEventId::WindowMouseButtonDown, pWindow, &aVCLMouseEvent ); +} + +void SAL_CALL VCLXToolkit::mouseRelease( const css::awt::MouseEvent & aMouseEvent ) +{ + css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY_THROW ); + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); + if( !pWindow ) + throw css::uno::RuntimeException( "invalid event source" ); + + ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent ); + ::Application::PostMouseEvent( VclEventId::WindowMouseButtonUp, pWindow, &aVCLMouseEvent ); +} + +void SAL_CALL VCLXToolkit::mouseMove( const css::awt::MouseEvent & aMouseEvent ) +{ + css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY_THROW ); + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); + if( !pWindow ) + throw css::uno::RuntimeException( "invalid event source" ); + + ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent ); + ::Application::PostMouseEvent( VclEventId::WindowMouseMove, pWindow, &aVCLMouseEvent ); +} + + +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +stardiv_Toolkit_VCLXToolkit_get_implementation( + css::uno::XComponentContext *, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new VCLXToolkit()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxtopwindow.cxx b/toolkit/source/awt/vclxtopwindow.cxx new file mode 100644 index 000000000..db42fa802 --- /dev/null +++ b/toolkit/source/awt/vclxtopwindow.cxx @@ -0,0 +1,254 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/lang/SystemDependent.hpp> +#include <com/sun/star/awt/SystemDependentXWindow.hpp> + +#if defined ( MACOSX ) +#include <premac.h> +#include <Cocoa/Cocoa.h> +#include <postmac.h> +#endif + +#include <vcl/sysdata.hxx> +#include <comphelper/sequence.hxx> +#include <o3tl/safeint.hxx> + +#include <awt/vclxtopwindow.hxx> +#include <toolkit/awt/vclxmenu.hxx> + +#include <vcl/wrkwin.hxx> +#include <vcl/syswin.hxx> +#include <vcl/menu.hxx> +#include <vcl/svapp.hxx> + +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Type; +using ::com::sun::star::uno::Any; +using ::com::sun::star::lang::IndexOutOfBoundsException; + + +css::uno::Any VCLXTopWindow::getWindowHandle( const css::uno::Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 SystemType ) +{ + SolarMutexGuard aGuard; + + // TODO, check the process id + css::uno::Any aRet; + vcl::Window* pWindow = VCLXContainer::GetWindow(); + if ( pWindow ) + { + const SystemEnvData* pSysData = static_cast<SystemWindow *>(pWindow)->GetSystemData(); + if( pSysData ) + { +#if defined (_WIN32) + if( SystemType == css::lang::SystemDependent::SYSTEM_WIN32 ) + { + aRet <<= reinterpret_cast<sal_IntPtr>(pSysData->hWnd); + } +#elif defined(MACOSX) + if( SystemType == css::lang::SystemDependent::SYSTEM_MAC ) + { + aRet <<= reinterpret_cast<sal_IntPtr>(pSysData->mpNSView); + } +#elif defined(ANDROID) + // Nothing + (void) SystemType; +#elif defined(IOS) + // Nothing + (void) SystemType; +#elif defined(UNX) + if( SystemType == css::lang::SystemDependent::SYSTEM_XWINDOW ) + { + css::awt::SystemDependentXWindow aSD; + aSD.DisplayPointer = sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_IntPtr >(pSysData->pDisplay)); + aSD.WindowHandle = pSysData->GetWindowHandle(pWindow->ImplGetFrame()); + aRet <<= aSD; + } +#endif + } + } + return aRet; +} + +void VCLXTopWindow::addTopWindowListener( const css::uno::Reference< css::awt::XTopWindowListener >& rxListener ) +{ + SolarMutexGuard aGuard; + + if (!IsDisposed()) + GetTopWindowListeners().addInterface( rxListener ); +} + +void VCLXTopWindow::removeTopWindowListener( const css::uno::Reference< css::awt::XTopWindowListener >& rxListener ) +{ + SolarMutexGuard aGuard; + + if (!IsDisposed()) + GetTopWindowListeners().removeInterface( rxListener ); +} + +void VCLXTopWindow::toFront( ) +{ + SolarMutexGuard aGuard; + + vcl::Window* pWindow = VCLXContainer::GetWindow(); + if (pWindow) + pWindow->ToTop( ToTopFlags::RestoreWhenMin ); +} + +void VCLXTopWindow::toBack( ) +{ +} + +void VCLXTopWindow::setMenuBar( const css::uno::Reference< css::awt::XMenuBar >& rxMenu ) +{ + SolarMutexGuard aGuard; + + vcl::Window* pWindow = VCLXContainer::GetWindow(); + if ( pWindow ) + { + SystemWindow* pSystemWindow = static_cast<SystemWindow*>( pWindow ); + pSystemWindow->SetMenuBar( nullptr ); + if ( rxMenu.is() ) + { + VCLXMenu* pMenu = comphelper::getFromUnoTunnel<VCLXMenu>( rxMenu ); + if ( pMenu && !pMenu->IsPopupMenu() ) + pSystemWindow->SetMenuBar( static_cast<MenuBar*>( pMenu->GetMenu() )); + } + } +} + + +sal_Bool SAL_CALL VCLXTopWindow::getIsMaximized() +{ + SolarMutexGuard aGuard; + + const WorkWindow* pWindow = VCLXContainer::GetAsDynamic<WorkWindow>(); + if ( !pWindow ) + return false; + + return pWindow->IsMaximized(); +} + + +void SAL_CALL VCLXTopWindow::setIsMaximized( sal_Bool _ismaximized ) +{ + SolarMutexGuard aGuard; + + WorkWindow* pWindow = VCLXContainer::GetAsDynamic<WorkWindow>(); + if ( !pWindow ) + return; + + pWindow->Maximize( _ismaximized ); +} + + +sal_Bool SAL_CALL VCLXTopWindow::getIsMinimized() +{ + SolarMutexGuard aGuard; + + const WorkWindow* pWindow = VCLXContainer::GetAsDynamic<WorkWindow>(); + if ( !pWindow ) + return false; + + return pWindow->IsMinimized(); +} + + +void SAL_CALL VCLXTopWindow::setIsMinimized( sal_Bool _isMinimized ) +{ + SolarMutexGuard aGuard; + + WorkWindow* pWindow = VCLXContainer::GetAsDynamic<WorkWindow>(); + if ( !pWindow ) + return; + + _isMinimized ? pWindow->Minimize() : pWindow->Restore(); +} + + +::sal_Int32 SAL_CALL VCLXTopWindow::getDisplay() +{ + SolarMutexGuard aGuard; + + const SystemWindow* pWindow = VCLXContainer::GetAsDynamic<SystemWindow>(); + if ( !pWindow ) + return 0; + + return pWindow->GetScreenNumber(); +} + + +void SAL_CALL VCLXTopWindow::setDisplay( ::sal_Int32 _display ) +{ + SolarMutexGuard aGuard; + + if ( ( _display < 0 ) || ( o3tl::make_unsigned(_display) >= Application::GetScreenCount() ) ) + throw IndexOutOfBoundsException(); + + SystemWindow* pWindow = VCLXContainer::GetAsDynamic<SystemWindow>(); + if ( !pWindow ) + return; + + pWindow->SetScreenNumber( _display ); +} + + + + +void VCLXTopWindow::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + VCLXContainer::ImplGetPropertyIds( rIds ); +} + +VCLXTopWindow::VCLXTopWindow() +{ +} + +VCLXTopWindow::~VCLXTopWindow() +{ +} + +// css::uno::XInterface +css::uno::Any VCLXTopWindow::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet( VCLXTopWindow_XBase::queryInterface( rType ) ); + + if (!aRet.hasValue()) + aRet = VCLXTopWindow_XBase::queryInterface( rType ); + if ( !aRet.hasValue() ) + aRet = VCLXContainer::queryInterface( rType ); + + return aRet; +} + +css::uno::Sequence< sal_Int8 > VCLXTopWindow::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +css::uno::Sequence< css::uno::Type > VCLXTopWindow::getTypes() +{ + return ::comphelper::concatSequences( VCLXTopWindow_XBase::getTypes(), VCLXContainer::getTypes() ); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxwindow.cxx b/toolkit/source/awt/vclxwindow.cxx new file mode 100644 index 000000000..d3252dd7a --- /dev/null +++ b/toolkit/source/awt/vclxwindow.cxx @@ -0,0 +1,2557 @@ +/* -*- 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 <stdarg.h> +#include <memory> +#include <com/sun/star/awt/WindowEvent.hpp> +#include <com/sun/star/awt/KeyEvent.hpp> +#include <com/sun/star/awt/MouseEvent.hpp> +#include <com/sun/star/awt/MouseWheelBehavior.hpp> +#include <com/sun/star/awt/Style.hpp> +#include <com/sun/star/awt/DockingEvent.hpp> +#include <com/sun/star/awt/EndDockingEvent.hpp> +#include <com/sun/star/awt/EndPopupModeEvent.hpp> +#include <com/sun/star/awt/XWindowListener2.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/text/WritingMode2.hpp> +#include <toolkit/awt/vclxwindow.hxx> +#include <awt/vclxpointer.hxx> +#include <toolkit/awt/vclxwindows.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <toolkit/helper/convert.hxx> +#include <toolkit/helper/property.hxx> +#include <rtl/math.hxx> +#include <sal/log.hxx> +#include <vcl/toolkit/floatwin.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <tools/color.hxx> +#include <tools/fract.hxx> +#include <tools/debug.hxx> +#include <vcl/event.hxx> +#include <vcl/dockwin.hxx> +#include <vcl/pdfextoutdevdata.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/ctrl.hxx> +#include <vcl/settings.hxx> +#include <vcl/commandevent.hxx> +#include <comphelper/flagguard.hxx> +#include <comphelper/interfacecontainer3.hxx> +#include <comphelper/profilezone.hxx> +#include "stylesettings.hxx" +#include <tools/urlobj.hxx> + +#include <helper/accessibilityclient.hxx> +#include <helper/unopropertyarrayhelper.hxx> + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::lang::EventObject; +using ::com::sun::star::awt::XWindowListener2; +using ::com::sun::star::awt::XDockableWindowListener; +using ::com::sun::star::awt::XDevice; +using ::com::sun::star::awt::XStyleSettings; +using ::com::sun::star::lang::DisposedException; +using ::com::sun::star::style::VerticalAlignment; +using ::com::sun::star::style::VerticalAlignment_TOP; +using ::com::sun::star::style::VerticalAlignment_MIDDLE; +using ::com::sun::star::style::VerticalAlignment_BOTTOM; + +namespace WritingMode2 = ::com::sun::star::text::WritingMode2; + + +//= VCLXWindowImpl + +class VCLXWindowImpl +{ +private: + typedef ::std::vector< VCLXWindow::Callback > CallbackArray; + +private: + VCLXWindow& mrAntiImpl; + ::toolkit::AccessibilityClient maAccFactory; + bool mbDisposed; + bool mbDrawingOntoParent; // no bit mask, is passed around by reference + bool mbEnableVisible; + bool mbDirectVisible; + + ::osl::Mutex maListenerContainerMutex; + ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2> maWindow2Listeners; + ::comphelper::OInterfaceContainerHelper3<XDockableWindowListener> maDockableWindowListeners; + EventListenerMultiplexer maEventListeners; + FocusListenerMultiplexer maFocusListeners; + WindowListenerMultiplexer maWindowListeners; + KeyListenerMultiplexer maKeyListeners; + MouseListenerMultiplexer maMouseListeners; + MouseMotionListenerMultiplexer maMouseMotionListeners; + PaintListenerMultiplexer maPaintListeners; + VclContainerListenerMultiplexer maContainerListeners; + TopWindowListenerMultiplexer maTopWindowListeners; + + CallbackArray maCallbackEvents; + ImplSVEvent * mnCallbackEventId; + +public: + bool mbDisposing : 1; + bool mbDesignMode : 1; + bool mbSynthesizingVCLEvent : 1; + bool mbWithDefaultProps : 1; + + sal_uLong mnListenerLockLevel; + sal_Int16 mnWritingMode; + sal_Int16 mnContextWritingMode; + + std::unique_ptr<UnoPropertyArrayHelper> + mpPropHelper; + + css::uno::Reference< css::accessibility::XAccessibleContext > + mxAccessibleContext; + css::uno::Reference< css::awt::XGraphics > + mxViewGraphics; + css::uno::Reference< css::awt::XStyleSettings > + mxWindowStyleSettings; + +public: + bool& getDrawingOntoParent_ref() { return mbDrawingOntoParent; } + +public: + /** ctor + @param _pAntiImpl + the <type>VCLXWindow</type> instance which the object belongs to. Must + live longer then the object just being constructed. + */ + VCLXWindowImpl( VCLXWindow& _rAntiImpl, bool _bWithDefaultProps ); + + VCLXWindowImpl( const VCLXWindowImpl& ) = delete; + const VCLXWindowImpl& operator=(const VCLXWindowImpl&) = delete; + + /** synchronously mbEnableVisible + */ + void setEnableVisible( bool bEnableVisible ) { mbEnableVisible = bEnableVisible; } + bool isEnableVisible() const { return mbEnableVisible; } + /** synchronously mbDirectVisible; + */ + void setDirectVisible( bool bDirectVisible ) { mbDirectVisible = bDirectVisible; } + bool isDirectVisible() const { return mbDirectVisible; } + + /** impl-version of VCLXWindow::ImplExecuteAsyncWithoutSolarLock + */ + void callBackAsync( const VCLXWindow::Callback& i_callback ); + + /** notifies the object that its VCLXWindow is being disposed + */ + void disposing(); + + ::toolkit::AccessibilityClient& getAccessibleFactory() + { + return maAccFactory; + } + + Reference< XStyleSettings > getStyleSettings(); + + /** returns the container of registered XWindowListener2 listeners + */ + ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2>& getWindow2Listeners() { return maWindow2Listeners; } + ::comphelper::OInterfaceContainerHelper3<XDockableWindowListener>& getDockableWindowListeners() { return maDockableWindowListeners; } + EventListenerMultiplexer& getEventListeners() { return maEventListeners; } + FocusListenerMultiplexer& getFocusListeners() { return maFocusListeners; } + WindowListenerMultiplexer& getWindowListeners() { return maWindowListeners; } + KeyListenerMultiplexer& getKeyListeners() { return maKeyListeners; } + MouseListenerMultiplexer& getMouseListeners() { return maMouseListeners; } + MouseMotionListenerMultiplexer& getMouseMotionListeners() { return maMouseMotionListeners; } + PaintListenerMultiplexer& getPaintListeners() { return maPaintListeners; } + VclContainerListenerMultiplexer& getContainerListeners() { return maContainerListeners; } + TopWindowListenerMultiplexer& getTopWindowListeners() { return maTopWindowListeners; } + +private: + DECL_LINK( OnProcessCallbacks, void*, void ); +}; + + +VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, bool _bWithDefaultProps ) + :mrAntiImpl( _rAntiImpl ) + ,mbDisposed( false ) + ,mbDrawingOntoParent( false ) + ,mbEnableVisible(true) + ,mbDirectVisible(true) + ,maWindow2Listeners( maListenerContainerMutex ) + ,maDockableWindowListeners( maListenerContainerMutex ) + ,maEventListeners( _rAntiImpl ) + ,maFocusListeners( _rAntiImpl ) + ,maWindowListeners( _rAntiImpl ) + ,maKeyListeners( _rAntiImpl ) + ,maMouseListeners( _rAntiImpl ) + ,maMouseMotionListeners( _rAntiImpl ) + ,maPaintListeners( _rAntiImpl ) + ,maContainerListeners( _rAntiImpl ) + ,maTopWindowListeners( _rAntiImpl ) + ,mnCallbackEventId( nullptr ) + ,mbDisposing( false ) + ,mbDesignMode( false ) + ,mbSynthesizingVCLEvent( false ) + ,mbWithDefaultProps( _bWithDefaultProps ) + ,mnListenerLockLevel( 0 ) + ,mnWritingMode( WritingMode2::CONTEXT ) + ,mnContextWritingMode( WritingMode2::CONTEXT ) +{ +} + +void VCLXWindowImpl::disposing() +{ + SolarMutexGuard aGuard; + + assert(!mbDisposed); + + mbDisposed = true; + + if ( mnCallbackEventId ) + { + Application::RemoveUserEvent( mnCallbackEventId ); + mnCallbackEventId = nullptr; + // we acquired our VCLXWindow once before posting the event, release this one ref now + mrAntiImpl.release(); + } + maCallbackEvents.clear(); + + css::lang::EventObject aEvent; + aEvent.Source = mrAntiImpl; + + maDockableWindowListeners.disposeAndClear( aEvent ); + maEventListeners.disposeAndClear( aEvent ); + maFocusListeners.disposeAndClear( aEvent ); + maWindowListeners.disposeAndClear( aEvent ); + maKeyListeners.disposeAndClear( aEvent ); + maMouseListeners.disposeAndClear( aEvent ); + maMouseMotionListeners.disposeAndClear( aEvent ); + maPaintListeners.disposeAndClear( aEvent ); + maContainerListeners.disposeAndClear( aEvent ); + maTopWindowListeners.disposeAndClear( aEvent ); + maWindow2Listeners.disposeAndClear( aEvent ); + + ::toolkit::WindowStyleSettings* pStyleSettings = static_cast< ::toolkit::WindowStyleSettings* >( mxWindowStyleSettings.get() ); + if ( pStyleSettings != nullptr ) + pStyleSettings->dispose(); + mxWindowStyleSettings.clear(); +} + + +void VCLXWindowImpl::callBackAsync( const VCLXWindow::Callback& i_callback ) +{ + DBG_TESTSOLARMUTEX(); + maCallbackEvents.push_back( i_callback ); + if ( !mnCallbackEventId ) + { + // ensure our VCLXWindow is not destroyed while the event is underway + mrAntiImpl.acquire(); + mnCallbackEventId = Application::PostUserEvent( LINK( this, VCLXWindowImpl, OnProcessCallbacks ) ); + } +} + + +IMPL_LINK_NOARG(VCLXWindowImpl, OnProcessCallbacks, void*, void) +{ + const Reference< uno::XInterface > xKeepAlive( mrAntiImpl ); + + SAL_INFO("toolkit.controls", "OnProcessCallbacks grabbing solarmutex"); + + // work on a copy of the callback array + CallbackArray aCallbacksCopy; + { + SolarMutexGuard aGuard; + aCallbacksCopy.swap(maCallbackEvents); + + // we acquired our VCLXWindow once before posting the event, release this one ref now + mrAntiImpl.release(); + + assert( mnCallbackEventId && "should not be possible to call us if the event was removed"); + + mnCallbackEventId = nullptr; + } + + { + SAL_INFO("toolkit.controls", "OnProcessCallbacks relinquished solarmutex"); + SolarMutexReleaser aReleaseSolar; + for (const auto& rCallback : aCallbacksCopy) + { + rCallback(); + } + } +} + +Reference< XStyleSettings > VCLXWindowImpl::getStyleSettings() +{ + SolarMutexGuard aGuard; + if ( mbDisposed ) + throw DisposedException( OUString(), mrAntiImpl ); + if ( !mxWindowStyleSettings.is() ) + mxWindowStyleSettings = new ::toolkit::WindowStyleSettings( maListenerContainerMutex, mrAntiImpl ); + return mxWindowStyleSettings; +} + + +// Uses an out-parameter instead of return value, due to the object reference + +static void ImplInitWindowEvent( css::awt::WindowEvent& rEvent, vcl::Window const * pWindow ) +{ + Point aPos = pWindow->GetPosPixel(); + Size aSz = pWindow->GetSizePixel(); + + rEvent.X = aPos.X(); + rEvent.Y = aPos.Y(); + + rEvent.Width = aSz.Width(); + rEvent.Height = aSz.Height(); + + pWindow->GetBorder( rEvent.LeftInset, rEvent.TopInset, rEvent.RightInset, rEvent.BottomInset ); +} + +VCLXWindow::VCLXWindow( bool _bWithDefaultProps ) +{ + mpImpl.reset( new VCLXWindowImpl( *this, _bWithDefaultProps ) ); +} + +VCLXWindow::~VCLXWindow() +{ + assert(mpImpl->mbDisposing && "forgot to call dispose()"); +} + + +void VCLXWindow::ImplExecuteAsyncWithoutSolarLock( const Callback& i_callback ) +{ + if (mpImpl->mbDisposing) + return; + mpImpl->callBackAsync( i_callback ); +} + + +::toolkit::IAccessibleFactory& VCLXWindow::getAccessibleFactory() +{ + return mpImpl->getAccessibleFactory().getFactory(); +} + +void VCLXWindow::SetWindow( const VclPtr<vcl::Window> &pWindow ) +{ + assert(!mpImpl->mbDisposing || !pWindow); + + if ( GetWindow() ) + { + GetWindow()->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) ); +// GetWindow()->DbgAssertNoEventListeners(); + } + + SetOutputDevice( pWindow ? pWindow->GetOutDev() : nullptr ); + + if ( GetWindow() ) + { + GetWindow()->AddEventListener( LINK( this, VCLXWindow, WindowEventListener ) ); + bool bDirectVisible = pWindow && pWindow->IsVisible(); + mpImpl->setDirectVisible( bDirectVisible ); + } +} + +void VCLXWindow::suspendVclEventListening( ) +{ + ++mpImpl->mnListenerLockLevel; +} + +void VCLXWindow::resumeVclEventListening( ) +{ + DBG_ASSERT( mpImpl->mnListenerLockLevel, "VCLXWindow::resumeVclEventListening: not suspended!" ); + --mpImpl->mnListenerLockLevel; +} + +void VCLXWindow::notifyWindowRemoved( vcl::Window const & _rWindow ) +{ + if ( mpImpl->getContainerListeners().getLength() ) + { + awt::VclContainerEvent aEvent; + aEvent.Source = *this; + aEvent.Child = static_cast< XWindow* >( _rWindow.GetWindowPeer() ); + mpImpl->getContainerListeners().windowRemoved( aEvent ); + } +} + +IMPL_LINK( VCLXWindow, WindowEventListener, VclWindowEvent&, rEvent, void ) +{ + if ( mpImpl->mbDisposing || mpImpl->mnListenerLockLevel ) + return; + + DBG_ASSERT( rEvent.GetWindow() && GetWindow(), "Window???" ); + ProcessWindowEvent( rEvent ); +} + +namespace +{ + struct CallWindow2Listener + { + CallWindow2Listener( ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2>& i_rWindow2Listeners, const bool i_bEnabled, const EventObject& i_rEvent ) + :m_rWindow2Listeners( i_rWindow2Listeners ) + ,m_bEnabled( i_bEnabled ) + ,m_aEvent( i_rEvent ) + { + } + + void operator()() + { + m_rWindow2Listeners.notifyEach( m_bEnabled ? &XWindowListener2::windowEnabled : &XWindowListener2::windowDisabled, m_aEvent ); + } + + ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2>& m_rWindow2Listeners; + const bool m_bEnabled; + const EventObject m_aEvent; + }; +} + +void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + if (mpImpl->mbDisposing) + return; + css::uno::Reference< css::uno::XInterface > xThis( static_cast<cppu::OWeakObject*>(this) ); + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::WindowEnabled: + case VclEventId::WindowDisabled: + { + Callback aCallback = CallWindow2Listener( + mpImpl->getWindow2Listeners(), + ( VclEventId::WindowEnabled == rVclWindowEvent.GetId() ), + EventObject( *this ) + ); + ImplExecuteAsyncWithoutSolarLock( aCallback ); + } + break; + + case VclEventId::WindowPaint: + { + if ( mpImpl->getPaintListeners().getLength() ) + { + css::awt::PaintEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.UpdateRect = AWTRectangle( *static_cast<tools::Rectangle*>(rVclWindowEvent.GetData()) ); + aEvent.Count = 0; + mpImpl->getPaintListeners().windowPaint( aEvent ); + } + } + break; + case VclEventId::WindowMove: + { + if ( mpImpl->getWindowListeners().getLength() ) + { + css::awt::WindowEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() ); + mpImpl->getWindowListeners().windowMoved( aEvent ); + } + } + break; + case VclEventId::WindowResize: + { + if ( mpImpl->getWindowListeners().getLength() ) + { + css::awt::WindowEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() ); + mpImpl->getWindowListeners().windowResized( aEvent ); + } + } + break; + case VclEventId::WindowShow: + { + if ( mpImpl->getWindowListeners().getLength() ) + { + css::awt::WindowEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() ); + mpImpl->getWindowListeners().windowShown( aEvent ); + } + + // For TopWindows this means opened... + if ( mpImpl->getTopWindowListeners().getLength() ) + { + css::lang::EventObject aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + mpImpl->getTopWindowListeners().windowOpened( aEvent ); + } + } + break; + case VclEventId::WindowHide: + { + if ( mpImpl->getWindowListeners().getLength() ) + { + css::awt::WindowEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() ); + mpImpl->getWindowListeners().windowHidden( aEvent ); + } + + // For TopWindows this means closed... + if ( mpImpl->getTopWindowListeners().getLength() ) + { + css::lang::EventObject aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + mpImpl->getTopWindowListeners().windowClosed( aEvent ); + } + } + break; + case VclEventId::WindowActivate: + case VclEventId::WindowDeactivate: + { + if (!mpImpl->getTopWindowListeners().getLength()) + return; + + // Suppress events which are unlikely to be interesting to our listeners. + vcl::Window* pWin = static_cast<vcl::Window*>(rVclWindowEvent.GetData()); + bool bSuppress = false; + + while (pWin) + { + // Either the event came from the same window, from its + // child, or from a child of its border window (e.g. + // menubar or notebookbar). + if (pWin->GetWindow(GetWindowType::Client) == GetWindow()) + return; + + if (pWin->IsMenuFloatingWindow()) + bSuppress = true; + + if (pWin->GetType() == WindowType::FLOATINGWINDOW && + static_cast<FloatingWindow*>(pWin)->IsInPopupMode()) + bSuppress = true; + + // Otherwise, don't suppress if the event came from a different frame. + if (!bSuppress && pWin->GetWindow(GetWindowType::Frame) == pWin) + break; + + pWin = pWin->GetWindow(GetWindowType::RealParent); + } + + css::lang::EventObject aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + if (rVclWindowEvent.GetId() == VclEventId::WindowActivate) + mpImpl->getTopWindowListeners().windowActivated( aEvent ); + else + mpImpl->getTopWindowListeners().windowDeactivated( aEvent ); + } + break; + case VclEventId::WindowClose: + { + if ( mpImpl->getDockableWindowListeners().getLength() ) + { + css::lang::EventObject aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::closed, aEvent ); + } + if ( mpImpl->getTopWindowListeners().getLength() ) + { + css::lang::EventObject aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + mpImpl->getTopWindowListeners().windowClosing( aEvent ); + } + } + break; + case VclEventId::ControlGetFocus: + case VclEventId::WindowGetFocus: + { + if ( ( rVclWindowEvent.GetWindow()->IsCompoundControl() + && rVclWindowEvent.GetId() == VclEventId::ControlGetFocus + ) + || ( !rVclWindowEvent.GetWindow()->IsCompoundControl() + && rVclWindowEvent.GetId() == VclEventId::WindowGetFocus + ) + ) + { + if ( mpImpl->getFocusListeners().getLength() ) + { + css::awt::FocusEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.FocusFlags = static_cast<sal_Int16>(rVclWindowEvent.GetWindow()->GetGetFocusFlags()); + aEvent.Temporary = false; + mpImpl->getFocusListeners().focusGained( aEvent ); + } + } + } + break; + case VclEventId::ControlLoseFocus: + case VclEventId::WindowLoseFocus: + { + if ( ( rVclWindowEvent.GetWindow()->IsCompoundControl() + && rVclWindowEvent.GetId() == VclEventId::ControlLoseFocus + ) + || ( !rVclWindowEvent.GetWindow()->IsCompoundControl() + && rVclWindowEvent.GetId() == VclEventId::WindowLoseFocus + ) + ) + { + if ( mpImpl->getFocusListeners().getLength() ) + { + css::awt::FocusEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.FocusFlags = static_cast<sal_Int16>(rVclWindowEvent.GetWindow()->GetGetFocusFlags()); + aEvent.Temporary = false; + + vcl::Window* pNext = Application::GetFocusWindow(); + if ( pNext ) + { + // Don't care about internals if this control is compound + vcl::Window* pNextC = pNext; + while ( pNextC && !pNextC->IsCompoundControl() ) + pNextC = pNextC->GetParent(); + if ( pNextC ) + pNext = pNextC; + + pNext->GetComponentInterface(); + aEvent.NextFocus = static_cast<cppu::OWeakObject*>(pNext->GetWindowPeer()); + } + mpImpl->getFocusListeners().focusLost( aEvent ); + } + } + } + break; + case VclEventId::WindowMinimize: + { + if ( mpImpl->getTopWindowListeners().getLength() ) + { + css::lang::EventObject aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + mpImpl->getTopWindowListeners().windowMinimized( aEvent ); + } + } + break; + case VclEventId::WindowNormalize: + { + if ( mpImpl->getTopWindowListeners().getLength() ) + { + css::lang::EventObject aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + mpImpl->getTopWindowListeners().windowNormalized( aEvent ); + } + } + break; + case VclEventId::WindowKeyInput: + { + if ( mpImpl->getKeyListeners().getLength() ) + { + css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent( + *static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this + ) ); + mpImpl->getKeyListeners().keyPressed( aEvent ); + } + } + break; + case VclEventId::WindowKeyUp: + { + if ( mpImpl->getKeyListeners().getLength() ) + { + css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent( + *static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this + ) ); + mpImpl->getKeyListeners().keyReleased( aEvent ); + } + } + break; + case VclEventId::WindowCommand: + { + CommandEvent* pCmdEvt = static_cast<CommandEvent*>(rVclWindowEvent.GetData()); + if ( mpImpl->getMouseListeners().getLength() && ( pCmdEvt->GetCommand() == CommandEventId::ContextMenu ) ) + { + // CommandEventId::ContextMenu: send as mousePressed with PopupTrigger = true ... + Point aWhere = static_cast< CommandEvent* >( rVclWindowEvent.GetData() )->GetMousePosPixel(); + if ( !pCmdEvt->IsMouseEvent() ) + { // for keyboard events, we set the coordinates to -1,-1. This is a slight HACK, but the current API + // handles a context menu command as special case of a mouse event, which is simply wrong. + // Without extending the API, we would not have another chance to notify listeners of a + // keyboard-triggered context menu request + aWhere = Point( -1, -1 ); + } + + MouseEvent aMEvt( aWhere, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT, 0 ); + awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( aMEvt, *this ) ); + aEvent.PopupTrigger = true; + + Callback aCallback = [ this, aEvent ]() + { this->mpImpl->getMouseListeners().mousePressed( aEvent ); }; + + ImplExecuteAsyncWithoutSolarLock( aCallback ); + } + } + break; + case VclEventId::WindowMouseMove: + { + MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rVclWindowEvent.GetData()); + if ( mpImpl->getMouseListeners().getLength() && ( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) ) + { + awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) ); + bool const isEnter(pMouseEvt->IsEnterWindow()); + Callback aCallback = [ this, isEnter, aEvent ]() + { MouseListenerMultiplexer& rMouseListeners = this->mpImpl->getMouseListeners(); + isEnter + ? rMouseListeners.mouseEntered(aEvent) + : rMouseListeners.mouseExited(aEvent); }; + + ImplExecuteAsyncWithoutSolarLock( aCallback ); + } + + if ( mpImpl->getMouseMotionListeners().getLength() && !pMouseEvt->IsEnterWindow() && !pMouseEvt->IsLeaveWindow() ) + { + awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) ); + aEvent.ClickCount = 0; + if ( pMouseEvt->GetMode() & MouseEventModifiers::SIMPLEMOVE ) + mpImpl->getMouseMotionListeners().mouseMoved( aEvent ); + else + mpImpl->getMouseMotionListeners().mouseDragged( aEvent ); + } + } + break; + case VclEventId::WindowMouseButtonDown: + { + if ( mpImpl->getMouseListeners().getLength() ) + { + awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) ); + Callback aCallback = [ this, aEvent ]() + { this->mpImpl->getMouseListeners().mousePressed( aEvent ); }; + ImplExecuteAsyncWithoutSolarLock( aCallback ); + } + } + break; + case VclEventId::WindowMouseButtonUp: + { + if ( mpImpl->getMouseListeners().getLength() ) + { + awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) ); + + Callback aCallback = [ this, aEvent ]() + { this->mpImpl->getMouseListeners().mouseReleased( aEvent ); }; + ImplExecuteAsyncWithoutSolarLock( aCallback ); + } + } + break; + case VclEventId::WindowStartDocking: + { + if ( mpImpl->getDockableWindowListeners().getLength() ) + { + DockingData *pData = static_cast<DockingData*>(rVclWindowEvent.GetData()); + + if( pData ) + { + css::awt::DockingEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.TrackingRectangle = AWTRectangle( pData->maTrackRect ); + aEvent.MousePos.X = pData->maMousePos.X(); + aEvent.MousePos.Y = pData->maMousePos.Y(); + aEvent.bLiveMode = false; + aEvent.bInteractive = true; + + mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::startDocking, aEvent ); + } + } + } + break; + case VclEventId::WindowDocking: + { + if ( mpImpl->getDockableWindowListeners().getLength() ) + { + DockingData *pData = static_cast<DockingData*>(rVclWindowEvent.GetData()); + + if( pData ) + { + css::awt::DockingEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.TrackingRectangle = AWTRectangle( pData->maTrackRect ); + aEvent.MousePos.X = pData->maMousePos.X(); + aEvent.MousePos.Y = pData->maMousePos.Y(); + aEvent.bLiveMode = false; + aEvent.bInteractive = true; + + Reference< XDockableWindowListener > xFirstListener; + ::comphelper::OInterfaceIteratorHelper3 aIter( mpImpl->getDockableWindowListeners() ); + while ( aIter.hasMoreElements() && !xFirstListener.is() ) + { + xFirstListener = aIter.next(); + } + + css::awt::DockingData aDockingData = + xFirstListener->docking( aEvent ); + pData->maTrackRect = VCLRectangle( aDockingData.TrackingRectangle ); + pData->mbFloating = aDockingData.bFloating; + } + } + } + break; + case VclEventId::WindowEndDocking: + { + if ( mpImpl->getDockableWindowListeners().getLength() ) + { + EndDockingData *pData = static_cast<EndDockingData*>(rVclWindowEvent.GetData()); + + if( pData ) + { + css::awt::EndDockingEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.WindowRectangle = AWTRectangle( pData->maWindowRect ); + aEvent.bFloating = pData->mbFloating; + aEvent.bCancelled = pData->mbCancelled; + mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endDocking, aEvent ); + } + } + } + break; + case VclEventId::WindowPrepareToggleFloating: + { + if ( mpImpl->getDockableWindowListeners().getLength() ) + { + sal_Bool *p_bFloating = static_cast<sal_Bool*>(rVclWindowEvent.GetData()); + + css::lang::EventObject aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + + Reference< XDockableWindowListener > xFirstListener; + ::comphelper::OInterfaceIteratorHelper3 aIter( mpImpl->getDockableWindowListeners() ); + while ( aIter.hasMoreElements() && !xFirstListener.is() ) + { + xFirstListener = aIter.next(); + } + + *p_bFloating = xFirstListener->prepareToggleFloatingMode( aEvent ); + } + } + break; + case VclEventId::WindowToggleFloating: + { + if ( mpImpl->getDockableWindowListeners().getLength() ) + { + css::lang::EventObject aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::toggleFloatingMode, aEvent ); + } + } + break; + case VclEventId::WindowEndPopupMode: + { + if ( mpImpl->getDockableWindowListeners().getLength() ) + { + EndPopupModeData *pData = static_cast<EndPopupModeData*>(rVclWindowEvent.GetData()); + + if( pData ) + { + css::awt::EndPopupModeEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.FloatingPosition.X = pData->maFloatingPos.X(); + aEvent.FloatingPosition.Y = pData->maFloatingPos.Y(); + aEvent.bTearoff = pData->mbTearoff; + mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endPopupMode, aEvent ); + } + } + } + break; + default: break; + } +} + +uno::Reference< accessibility::XAccessibleContext > VCLXWindow::CreateAccessibleContext() +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return nullptr; + return getAccessibleFactory().createAccessibleContext( this ); +} + +void VCLXWindow::SetSynthesizingVCLEvent( bool _b ) +{ + mpImpl->mbSynthesizingVCLEvent = _b; +} + +bool VCLXWindow::IsSynthesizingVCLEvent() const +{ + return mpImpl->mbSynthesizingVCLEvent; +} + +Size VCLXWindow::ImplCalcWindowSize( const Size& rOutSz ) const +{ + Size aSz = rOutSz; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + sal_Int32 nLeft, nTop, nRight, nBottom; + pWindow->GetBorder( nLeft, nTop, nRight, nBottom ); + aSz.AdjustWidth(nLeft+nRight ); + aSz.AdjustHeight(nTop+nBottom ); + } + return aSz; +} + + +// css::lang::XUnoTunnel +UNO3_GETIMPLEMENTATION2_IMPL(VCLXWindow, VCLXDevice); + + +// css::lang::Component +void VCLXWindow::dispose( ) +{ + SolarMutexGuard aGuard; + + if ( mpImpl->mbDisposing ) + return; + + mpImpl->mbDisposing = true; + + mpImpl->mxViewGraphics = nullptr; + + mpImpl->disposing(); + + if ( VclPtr<vcl::Window> pWindow = GetWindow() ) + { + pWindow->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) ); + pWindow->SetWindowPeer( nullptr, nullptr ); + pWindow->SetAccessible( nullptr ); + + SetOutputDevice( nullptr ); + pWindow.disposeAndClear(); + } + + // #i14103# dispose the accessible context after the window has been destroyed, + // otherwise the old value in the child event fired in VCLXAccessibleComponent::ProcessWindowEvent() + // for VclEventId::WindowChildDestroyed contains a reference to an already disposed accessible object + try + { + css::uno::Reference< css::lang::XComponent > xComponent( mpImpl->mxAccessibleContext, css::uno::UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + } + catch ( const css::uno::Exception& ) + { + OSL_FAIL( "VCLXWindow::dispose: could not dispose the accessible context!" ); + } + mpImpl->mxAccessibleContext.clear(); +} + +void VCLXWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) // called during dispose by accessibility stuff + return; + mpImpl->getEventListeners().addInterface( rxListener ); +} + +void VCLXWindow::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getEventListeners().removeInterface( rxListener ); +} + + +// css::awt::XWindow +void VCLXWindow::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags ) +{ + SolarMutexGuard aGuard; + comphelper::ProfileZone aZone("setPosSize"); + + if ( GetWindow() ) + { + if( vcl::Window::GetDockingManager()->IsDockable( GetWindow() ) ) + vcl::Window::GetDockingManager()->SetPosSizePixel( GetWindow() , X, Y, Width, Height, static_cast<PosSizeFlags>(Flags) ); + else + GetWindow()->setPosSizePixel( X, Y, Width, Height, static_cast<PosSizeFlags>(Flags) ); + } +} + +css::awt::Rectangle VCLXWindow::getPosSize( ) +{ + SolarMutexGuard aGuard; + + css::awt::Rectangle aBounds; + if ( GetWindow() ) + { + if( vcl::Window::GetDockingManager()->IsDockable( GetWindow() ) ) + aBounds = AWTRectangle( vcl::Window::GetDockingManager()->GetPosSizePixel( GetWindow() ) ); + else + aBounds = AWTRectangle( tools::Rectangle( GetWindow()->GetPosPixel(), GetWindow()->GetSizePixel() ) ); + } + + return aBounds; +} + +void VCLXWindow::setVisible( sal_Bool bVisible ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + mpImpl->setDirectVisible( bVisible ); + pWindow->Show( bVisible && mpImpl->isEnableVisible() ); + } +} + +void VCLXWindow::setEnable( sal_Bool bEnable ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + pWindow->Enable( bEnable, false ); // #95824# without children! + pWindow->EnableInput( bEnable ); + } +} + +void VCLXWindow::setFocus( ) +{ + SolarMutexGuard aGuard; + + if ( GetWindow() ) + GetWindow()->GrabFocus(); +} + +void VCLXWindow::addWindowListener( const css::uno::Reference< css::awt::XWindowListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + + mpImpl->getWindowListeners().addInterface( rxListener ); + + Reference< XWindowListener2 > xListener2( rxListener, UNO_QUERY ); + if ( xListener2.is() ) + mpImpl->getWindow2Listeners().addInterface( xListener2 ); + + // #100119# Get all resize events, even if height or width 0, or invisible + if ( GetWindow() ) + GetWindow()->EnableAllResize(); +} + +void VCLXWindow::removeWindowListener( const css::uno::Reference< css::awt::XWindowListener >& rxListener ) +{ + SolarMutexGuard aGuard; + + if (mpImpl->mbDisposing) + return; + + Reference< XWindowListener2 > xListener2( rxListener, UNO_QUERY ); + if ( xListener2.is() ) + mpImpl->getWindow2Listeners().removeInterface( xListener2 ); + + mpImpl->getWindowListeners().removeInterface( rxListener ); +} + +void VCLXWindow::addFocusListener( const css::uno::Reference< css::awt::XFocusListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getFocusListeners().addInterface( rxListener ); +} + +void VCLXWindow::removeFocusListener( const css::uno::Reference< css::awt::XFocusListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getFocusListeners().removeInterface( rxListener ); +} + +void VCLXWindow::addKeyListener( const css::uno::Reference< css::awt::XKeyListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getKeyListeners().addInterface( rxListener ); +} + +void VCLXWindow::removeKeyListener( const css::uno::Reference< css::awt::XKeyListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getKeyListeners().removeInterface( rxListener ); +} + +void VCLXWindow::addMouseListener( const css::uno::Reference< css::awt::XMouseListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getMouseListeners().addInterface( rxListener ); +} + +void VCLXWindow::removeMouseListener( const css::uno::Reference< css::awt::XMouseListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getMouseListeners().removeInterface( rxListener ); +} + +void VCLXWindow::addMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getMouseMotionListeners().addInterface( rxListener ); +} + +void VCLXWindow::removeMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getMouseMotionListeners().removeInterface( rxListener ); +} + +void VCLXWindow::addPaintListener( const css::uno::Reference< css::awt::XPaintListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getPaintListeners().addInterface( rxListener ); +} + +void VCLXWindow::removePaintListener( const css::uno::Reference< css::awt::XPaintListener >& rxListener ) +{ + SolarMutexGuard aGuard; + if (mpImpl->mbDisposing) + return; + mpImpl->getPaintListeners().removeInterface( rxListener ); +} + +// css::awt::XWindowPeer +css::uno::Reference< css::awt::XToolkit > VCLXWindow::getToolkit( ) +{ + // no guard. nothing to guard here. + // 82463 - 12/21/00 - fs + return Application::GetVCLToolkit(); +} + +void VCLXWindow::setPointer( const css::uno::Reference< css::awt::XPointer >& rxPointer ) +{ + SolarMutexGuard aGuard; + + VCLXPointer* pPointer = comphelper::getFromUnoTunnel<VCLXPointer>( rxPointer ); + if ( pPointer && GetWindow() ) + GetWindow()->SetPointer( pPointer->GetPointer() ); +} + +void VCLXWindow::setBackground( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + if ( !GetWindow() ) + return; + + Color aColor(ColorTransparency, nColor); + GetWindow()->SetBackground( aColor ); + GetWindow()->SetControlBackground( aColor ); + + WindowType eWinType = GetWindow()->GetType(); + if ( ( eWinType == WindowType::WINDOW ) || + ( eWinType == WindowType::WORKWINDOW ) || + ( eWinType == WindowType::FLOATINGWINDOW ) ) + { + GetWindow()->Invalidate(); + } +} + +void VCLXWindow::invalidate( sal_Int16 nInvalidateFlags ) +{ + SolarMutexGuard aGuard; + + if ( GetWindow() ) + GetWindow()->Invalidate( static_cast<InvalidateFlags>(nInvalidateFlags) ); +} + +void VCLXWindow::invalidateRect( const css::awt::Rectangle& rRect, sal_Int16 nInvalidateFlags ) +{ + SolarMutexGuard aGuard; + + if ( GetWindow() ) + GetWindow()->Invalidate( VCLRectangle(rRect), static_cast<InvalidateFlags>(nInvalidateFlags) ); +} + + +// css::awt::XVclWindowPeer +sal_Bool VCLXWindow::isChild( const css::uno::Reference< css::awt::XWindowPeer >& rxPeer ) +{ + SolarMutexGuard aGuard; + + bool bIsChild = false; + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + VclPtr<vcl::Window> pPeerWindow = VCLUnoHelper::GetWindow( rxPeer ); + bIsChild = pPeerWindow && pWindow->IsChild( pPeerWindow ); + } + + return bIsChild; +} + +void VCLXWindow::setDesignMode( sal_Bool bOn ) +{ + SolarMutexGuard aGuard; + + mpImpl->mbDesignMode = bOn; +} + +sal_Bool VCLXWindow::isDesignMode( ) +{ + SolarMutexGuard aGuard; + return mpImpl->mbDesignMode; +} + +void VCLXWindow::enableClipSiblings( sal_Bool bClip ) +{ + SolarMutexGuard aGuard; + + if ( GetWindow() ) + GetWindow()->EnableClipSiblings( bClip ); +} + +void VCLXWindow::setForeground( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + if ( GetWindow() ) + { + GetWindow()->SetControlForeground( Color(ColorTransparency, nColor) ); + } +} + +void VCLXWindow::setControlFont( const css::awt::FontDescriptor& rFont ) +{ + SolarMutexGuard aGuard; + + if ( GetWindow() ) + GetWindow()->SetControlFont( VCLUnoHelper::CreateFont( rFont, GetWindow()->GetControlFont() ) ); +} + +void VCLXWindow::getStyles( sal_Int16 nType, css::awt::FontDescriptor& Font, sal_Int32& ForegroundColor, sal_Int32& BackgroundColor ) +{ + SolarMutexGuard aGuard; + + if ( !GetWindow() ) + return; + + const StyleSettings& rStyleSettings = GetWindow()->GetSettings().GetStyleSettings(); + + switch ( nType ) + { + case css::awt::Style::FRAME: + { + Font = VCLUnoHelper::CreateFontDescriptor( rStyleSettings.GetAppFont() ); + ForegroundColor = sal_Int32(rStyleSettings.GetWindowTextColor()); + BackgroundColor = sal_Int32(rStyleSettings.GetWindowColor()); + } + break; + case css::awt::Style::DIALOG: + { + Font = VCLUnoHelper::CreateFontDescriptor( rStyleSettings.GetAppFont() ); + ForegroundColor = sal_Int32(rStyleSettings.GetDialogTextColor()); + BackgroundColor = sal_Int32(rStyleSettings.GetDialogColor()); + } + break; + default: OSL_FAIL( "VCLWindow::getStyles() - unknown Type" ); + } +} + +namespace toolkit +{ + static void setColorSettings( vcl::Window* _pWindow, const css::uno::Any& _rValue, + void (StyleSettings::*pSetter)( const Color& ), const Color& (StyleSettings::*pGetter)( ) const ) + { + sal_Int32 nColor = 0; + if ( !( _rValue >>= nColor ) ) + nColor = sal_Int32((Application::GetSettings().GetStyleSettings().*pGetter)()); + + AllSettings aSettings = _pWindow->GetSettings(); + StyleSettings aStyleSettings = aSettings.GetStyleSettings(); + + (aStyleSettings.*pSetter)( Color( ColorTransparency, nColor ) ); + + aSettings.SetStyleSettings( aStyleSettings ); + _pWindow->SetSettings( aSettings, true ); + } +} + +// Terminated by BASEPROPERTY_NOTFOUND (or 0) +void VCLXWindow::PushPropertyIds( std::vector< sal_uInt16 > &rIds, + int nFirstId, ...) +{ + va_list pVarArgs; + va_start( pVarArgs, nFirstId ); + + for ( int nId = nFirstId; nId != BASEPROPERTY_NOTFOUND; + nId = va_arg( pVarArgs, int ) ) + rIds.push_back( static_cast<sal_uInt16>(nId) ); + + va_end( pVarArgs ); +} + +void VCLXWindow::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds, bool bWithDefaults ) +{ + // These are common across ~all VCLXWindow derived classes + if( bWithDefaults ) + PushPropertyIds( rIds, + BASEPROPERTY_ALIGN, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_TEXT, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_ENABLEVISIBLE, // for visibility + BASEPROPERTY_TABSTOP, + 0); + + // lovely hack from: + // void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId ) + if( std::find(rIds.begin(), rIds.end(), BASEPROPERTY_FONTDESCRIPTOR) != rIds.end() ) + { + // some properties are not included in the FontDescriptor, but every time + // when we have a FontDescriptor we want to have these properties too. + // => Easier to register the here, instead everywhere where I register the FontDescriptor... + + rIds.push_back( BASEPROPERTY_TEXTCOLOR ); + rIds.push_back( BASEPROPERTY_TEXTLINECOLOR ); + rIds.push_back( BASEPROPERTY_FONTRELIEF ); + rIds.push_back( BASEPROPERTY_FONTEMPHASISMARK ); + } +} + +void VCLXWindow::GetPropertyIds( std::vector< sal_uInt16 >& _out_rIds ) +{ + return ImplGetPropertyIds( _out_rIds, mpImpl->mbWithDefaultProps ); +} + +::comphelper::OInterfaceContainerHelper3<css::awt::XVclContainerListener>& VCLXWindow::GetContainerListeners() +{ + return mpImpl->getContainerListeners(); +} + +::comphelper::OInterfaceContainerHelper3<css::awt::XTopWindowListener>& VCLXWindow::GetTopWindowListeners() +{ + return mpImpl->getTopWindowListeners(); +} + +namespace +{ + void lcl_updateWritingMode( vcl::Window& _rWindow, const sal_Int16 _nWritingMode, const sal_Int16 _nContextWritingMode ) + { + bool bEnableRTL = false; + switch ( _nWritingMode ) + { + case WritingMode2::LR_TB: bEnableRTL = false; break; + case WritingMode2::RL_TB: bEnableRTL = true; break; + case WritingMode2::CONTEXT: + { + // consult our ContextWritingMode. If it has an explicit RTL/LTR value, then use + // it. If it doesn't (but is CONTEXT itself), then just ask the parent window of our + // own window for its RTL mode + switch ( _nContextWritingMode ) + { + case WritingMode2::LR_TB: bEnableRTL = false; break; + case WritingMode2::RL_TB: bEnableRTL = true; break; + case WritingMode2::CONTEXT: + { + const vcl::Window* pParent = _rWindow.GetParent(); + OSL_ENSURE( pParent, "lcl_updateWritingMode: cannot determine context's writing mode!" ); + if ( pParent ) + bEnableRTL = pParent->IsRTLEnabled(); + } + break; + } + } + break; + default: + OSL_FAIL( "lcl_updateWritingMode: unsupported WritingMode!" ); + } // switch ( nWritingMode ) + + _rWindow.EnableRTL( bEnableRTL ); + } +} + +void VCLXWindow::setProperty( const OUString& PropertyName, const css::uno::Any& Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( !pWindow ) + return; + + bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID; + + WindowType eWinType = pWindow->GetType(); + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_REFERENCE_DEVICE: + { + Control* pControl = dynamic_cast< Control* >( pWindow.get() ); + OSL_ENSURE( pControl, "VCLXWindow::setProperty( RefDevice ): need a Control for this!" ); + if ( !pControl ) + break; + Reference< XDevice > xDevice( Value, UNO_QUERY ); + OutputDevice* pDevice = VCLUnoHelper::GetOutputDevice( xDevice ); + pControl->SetReferenceDevice( pDevice ); + } + break; + + case BASEPROPERTY_CONTEXT_WRITING_MODE: + { + OSL_VERIFY( Value >>= mpImpl->mnContextWritingMode ); + if ( mpImpl->mnWritingMode == WritingMode2::CONTEXT ) + lcl_updateWritingMode( *pWindow, mpImpl->mnWritingMode, mpImpl->mnContextWritingMode ); + } + break; + + case BASEPROPERTY_WRITING_MODE: + { + bool bProperType = ( Value >>= mpImpl->mnWritingMode ); + OSL_ENSURE( bProperType, "VCLXWindow::setProperty( 'WritingMode' ): illegal value type!" ); + if ( bProperType ) + lcl_updateWritingMode( *pWindow, mpImpl->mnWritingMode, mpImpl->mnContextWritingMode ); + } + break; + + case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR: + { + sal_uInt16 nWheelBehavior( css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY ); + OSL_VERIFY( Value >>= nWheelBehavior ); + + AllSettings aSettings = pWindow->GetSettings(); + MouseSettings aMouseSettings = aSettings.GetMouseSettings(); + + MouseWheelBehaviour nVclBehavior( MouseWheelBehaviour::FocusOnly ); + switch ( nWheelBehavior ) + { + case css::awt::MouseWheelBehavior::SCROLL_DISABLED: nVclBehavior = MouseWheelBehaviour::Disable; break; + case css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclBehavior = MouseWheelBehaviour::FocusOnly; break; + case css::awt::MouseWheelBehavior::SCROLL_ALWAYS: nVclBehavior = MouseWheelBehaviour::ALWAYS; break; + default: + OSL_FAIL( "VCLXWindow::setProperty( 'MouseWheelBehavior' ): illegal property value!" ); + } + + aMouseSettings.SetWheelBehavior( nVclBehavior ); + aSettings.SetMouseSettings( aMouseSettings ); + pWindow->SetSettings( aSettings, true ); + } + break; + + case BASEPROPERTY_NATIVE_WIDGET_LOOK: + { + bool bEnable( true ); + OSL_VERIFY( Value >>= bEnable ); + pWindow->EnableNativeWidget( bEnable ); + } + break; + + case BASEPROPERTY_PLUGINPARENT: + { + // set parent handle + SetSystemParent_Impl( Value ); + } + break; + + case BASEPROPERTY_ENABLED: + { + bool b = bool(); + if ( Value >>= b ) + setEnable( b ); + } + break; + case BASEPROPERTY_ENABLEVISIBLE: + { + bool b = false; + if ( Value >>= b ) + { + if( b != mpImpl->isEnableVisible() ) + { + mpImpl->setEnableVisible( b ); + pWindow->Show( b && mpImpl->isDirectVisible() ); + } + } + } + break; + case BASEPROPERTY_TEXT: + case BASEPROPERTY_LABEL: + case BASEPROPERTY_TITLE: + { + OUString aText; + if ( Value >>= aText ) + { + switch (eWinType) + { + case WindowType::OKBUTTON: + case WindowType::CANCELBUTTON: + case WindowType::HELPBUTTON: + // Standard Button: overwrite only if not empty. + if (!aText.isEmpty()) + pWindow->SetText( aText ); + break; + + default: + pWindow->SetText( aText ); + break; + } + } + } + break; + case BASEPROPERTY_ACCESSIBLENAME: + { + OUString aText; + if ( Value >>= aText ) + pWindow->SetAccessibleName( aText ); + } + break; + case BASEPROPERTY_HELPURL: + { + OUString aURL; + if ( Value >>= aURL ) + { + INetURLObject aHelpURL( aURL ); + if ( aHelpURL.GetProtocol() == INetProtocol::Hid ) + pWindow->SetHelpId( OUStringToOString( aHelpURL.GetURLPath(), RTL_TEXTENCODING_UTF8 ) ); + else + pWindow->SetHelpId( OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ) ); + } + } + break; + case BASEPROPERTY_HELPTEXT: + { + OUString aHelpText; + if ( Value >>= aHelpText ) + { + pWindow->SetQuickHelpText( aHelpText ); + } + } + break; + case BASEPROPERTY_FONTDESCRIPTOR: + { + if ( bVoid ) + pWindow->SetControlFont( vcl::Font() ); + else + { + css::awt::FontDescriptor aFont; + if ( Value >>= aFont ) + pWindow->SetControlFont( VCLUnoHelper::CreateFont( aFont, pWindow->GetControlFont() ) ); + } + } + break; + case BASEPROPERTY_FONTRELIEF: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + { + vcl::Font aFont = pWindow->GetControlFont(); + aFont.SetRelief( static_cast<FontRelief>(n) ); + pWindow->SetControlFont( aFont ); + } + } + break; + case BASEPROPERTY_FONTEMPHASISMARK: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + { + vcl::Font aFont = pWindow->GetControlFont(); + aFont.SetEmphasisMark( static_cast<FontEmphasisMark>(n) ); + pWindow->SetControlFont( aFont ); + } + } + break; + case BASEPROPERTY_BACKGROUNDCOLOR: + if ( bVoid ) + { + switch ( eWinType ) + { + // set dialog color for default + case WindowType::DIALOG: + case WindowType::MESSBOX: + case WindowType::INFOBOX: + case WindowType::WARNINGBOX: + case WindowType::ERRORBOX: + case WindowType::QUERYBOX: + case WindowType::TABPAGE: + { + Color aColor = pWindow->GetSettings().GetStyleSettings().GetDialogColor(); + pWindow->SetBackground( aColor ); + pWindow->SetControlBackground( aColor ); + break; + } + + case WindowType::FIXEDTEXT: + case WindowType::CHECKBOX: + case WindowType::RADIOBUTTON: + case WindowType::GROUPBOX: + case WindowType::FIXEDLINE: + { + // support transparency only for special controls + pWindow->SetBackground(); + pWindow->SetControlBackground(); + pWindow->SetPaintTransparent( true ); + break; + } + + default: + { + // default code which enables transparency for + // compound controls. It's not real transparency + // as most of these controls repaint their client + // area completely new. + if ( pWindow->IsCompoundControl() ) + pWindow->SetBackground(); + pWindow->SetControlBackground(); + break; + } + } + } + else + { + Color aColor; + if ( Value >>= aColor ) + { + pWindow->SetControlBackground( aColor ); + pWindow->SetBackground( aColor ); + switch ( eWinType ) + { + // reset paint transparent mode + case WindowType::FIXEDTEXT: + case WindowType::CHECKBOX: + case WindowType::RADIOBUTTON: + case WindowType::GROUPBOX: + case WindowType::FIXEDLINE: + pWindow->SetPaintTransparent( false ); + break; + default: + break; + } + pWindow->Invalidate(); // Invalidate if control does not respond to it + } + } + break; + case BASEPROPERTY_TEXTCOLOR: + if ( bVoid ) + { + pWindow->SetControlForeground(); + } + else + { + Color nColor ; + if ( Value >>= nColor ) + { + pWindow->SetTextColor( nColor ); + pWindow->SetControlForeground( nColor ); + } + } + break; + case BASEPROPERTY_TEXTLINECOLOR: + if ( bVoid ) + { + pWindow->SetTextLineColor(); + } + else + { + Color nColor; + if ( Value >>= nColor ) + pWindow->SetTextLineColor( nColor ); + } + break; + case BASEPROPERTY_FILLCOLOR: + if ( bVoid ) + pWindow->GetOutDev()->SetFillColor(); + else + { + Color nColor; + if ( Value >>= nColor ) + pWindow->GetOutDev()->SetFillColor( nColor ); + } + break; + case BASEPROPERTY_LINECOLOR: + if ( bVoid ) + pWindow->GetOutDev()->SetLineColor(); + else + { + Color nColor; + if ( Value >>= nColor ) + pWindow->GetOutDev()->SetLineColor( nColor ); + } + break; + case BASEPROPERTY_BORDER: + { + WinBits nStyle = pWindow->GetStyle(); + sal_uInt16 nTmp = 0; + Value >>= nTmp; + // clear any dodgy bits passed in, can come from dodgy extensions + nTmp &= o3tl::typed_flags<WindowBorderStyle>::mask; + WindowBorderStyle nBorder = static_cast<WindowBorderStyle>(nTmp); + if ( !bool(nBorder) ) + { + pWindow->SetStyle( nStyle & ~WB_BORDER ); + } + else + { + pWindow->SetStyle( nStyle | WB_BORDER ); + pWindow->SetBorderStyle( nBorder ); + } + } + break; + case BASEPROPERTY_TABSTOP: + { + WinBits nStyle = pWindow->GetStyle() & ~WB_TABSTOP; + if ( !bVoid ) + { + bool bTab = false; + Value >>= bTab; + if ( bTab ) + nStyle |= WB_TABSTOP; + else + nStyle |= WB_NOTABSTOP; + } + pWindow->SetStyle( nStyle ); + } + break; + case BASEPROPERTY_VERTICALALIGN: + { + VerticalAlignment eAlign = css::style::VerticalAlignment::VerticalAlignment_MAKE_FIXED_SIZE; + WinBits nStyle = pWindow->GetStyle(); + nStyle &= ~(WB_TOP|WB_VCENTER|WB_BOTTOM); + if ( !bVoid ) + Value >>= eAlign; + switch ( eAlign ) + { + case VerticalAlignment_TOP: + nStyle |= WB_TOP; + break; + case VerticalAlignment_MIDDLE: + nStyle |= WB_VCENTER; + break; + case VerticalAlignment_BOTTOM: + nStyle |= WB_BOTTOM; + break; + default: ; // for warning free code, MAKE_FIXED_SIZE + } + pWindow->SetStyle( nStyle ); + } + break; + case BASEPROPERTY_ALIGN: + { + sal_Int16 nAlign = PROPERTY_ALIGN_LEFT; + switch ( eWinType ) + { + case WindowType::COMBOBOX: + case WindowType::PUSHBUTTON: + case WindowType::OKBUTTON: + case WindowType::CANCELBUTTON: + case WindowType::HELPBUTTON: + nAlign = PROPERTY_ALIGN_CENTER; + [[fallthrough]]; + case WindowType::FIXEDTEXT: + case WindowType::EDIT: + case WindowType::MULTILINEEDIT: + case WindowType::CHECKBOX: + case WindowType::RADIOBUTTON: + case WindowType::LISTBOX: + { + WinBits nStyle = pWindow->GetStyle(); + nStyle &= ~(WB_LEFT|WB_CENTER|WB_RIGHT); + if ( !bVoid ) + Value >>= nAlign; + if ( nAlign == PROPERTY_ALIGN_LEFT ) + nStyle |= WB_LEFT; + else if ( nAlign == PROPERTY_ALIGN_CENTER ) + nStyle |= WB_CENTER; + else + nStyle |= WB_RIGHT; + pWindow->SetStyle( nStyle ); + } + break; + default: break; + } + } + break; + case BASEPROPERTY_MULTILINE: + { + if ( ( eWinType == WindowType::FIXEDTEXT ) + || ( eWinType == WindowType::CHECKBOX ) + || ( eWinType == WindowType::RADIOBUTTON ) + || ( eWinType == WindowType::PUSHBUTTON ) + || ( eWinType == WindowType::OKBUTTON ) + || ( eWinType == WindowType::CANCELBUTTON ) + || ( eWinType == WindowType::HELPBUTTON ) + ) + { + WinBits nStyle = pWindow->GetStyle(); + bool bMulti = false; + Value >>= bMulti; + if ( bMulti ) + nStyle |= WB_WORDBREAK; + else + nStyle &= ~WB_WORDBREAK; + pWindow->SetStyle( nStyle ); + } + } + break; + case BASEPROPERTY_ORIENTATION: + { + if ( eWinType == WindowType::FIXEDLINE) + { + sal_Int32 nOrientation = 0; + if ( Value >>= nOrientation ) + { + WinBits nStyle = pWindow->GetStyle(); + nStyle &= ~(WB_HORZ|WB_VERT); + if ( nOrientation == 0 ) + nStyle |= WB_HORZ; + else + nStyle |= WB_VERT; + + pWindow->SetStyle( nStyle ); + } + } + } + break; + case BASEPROPERTY_AUTOMNEMONICS: + { + bool bAutoMnemonics = false; + Value >>= bAutoMnemonics; + AllSettings aSettings = pWindow->GetSettings(); + StyleSettings aStyleSettings = aSettings.GetStyleSettings(); + if ( aStyleSettings.GetAutoMnemonic() != bAutoMnemonics ) + { + aStyleSettings.SetAutoMnemonic( bAutoMnemonics ); + aSettings.SetStyleSettings( aStyleSettings ); + pWindow->SetSettings( aSettings ); + } + } + break; + case BASEPROPERTY_MOUSETRANSPARENT: + { + bool bMouseTransparent = false; + Value >>= bMouseTransparent; + pWindow->SetMouseTransparent( bMouseTransparent ); + } + break; + case BASEPROPERTY_PAINTTRANSPARENT: + { + bool bPaintTransparent = false; + Value >>= bPaintTransparent; + pWindow->SetPaintTransparent( bPaintTransparent ); +// pWindow->SetBackground(); + } + break; + + case BASEPROPERTY_REPEAT: + { + bool bRepeat( false ); + Value >>= bRepeat; + + WinBits nStyle = pWindow->GetStyle(); + if ( bRepeat ) + nStyle |= WB_REPEAT; + else + nStyle &= ~WB_REPEAT; + pWindow->SetStyle( nStyle ); + } + break; + + case BASEPROPERTY_REPEAT_DELAY: + { + sal_Int32 nRepeatDelay = 0; + if ( Value >>= nRepeatDelay ) + { + AllSettings aSettings = pWindow->GetSettings(); + MouseSettings aMouseSettings = aSettings.GetMouseSettings(); + + aMouseSettings.SetButtonRepeat( nRepeatDelay ); + aSettings.SetMouseSettings( aMouseSettings ); + + pWindow->SetSettings( aSettings, true ); + } + } + break; + + case BASEPROPERTY_SYMBOL_COLOR: + ::toolkit::setColorSettings( pWindow, Value, &StyleSettings::SetButtonTextColor, &StyleSettings::GetButtonTextColor ); + break; + + case BASEPROPERTY_BORDERCOLOR: + ::toolkit::setColorSettings( pWindow, Value, &StyleSettings::SetMonoColor, &StyleSettings::GetMonoColor); + break; + } +} + +css::uno::Any VCLXWindow::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + if ( GetWindow() ) + { + WindowType eWinType = GetWindow()->GetType(); + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_REFERENCE_DEVICE: + { + VclPtr<Control> pControl = GetAsDynamic<Control >(); + OSL_ENSURE( pControl, "VCLXWindow::setProperty( RefDevice ): need a Control for this!" ); + if ( !pControl ) + break; + + rtl::Reference<VCLXDevice> pDevice = new VCLXDevice; + pDevice->SetOutputDevice( pControl->GetReferenceDevice() ); + aProp <<= Reference< XDevice >( pDevice ); + } + break; + + case BASEPROPERTY_CONTEXT_WRITING_MODE: + aProp <<= mpImpl->mnContextWritingMode; + break; + + case BASEPROPERTY_WRITING_MODE: + aProp <<= mpImpl->mnWritingMode; + break; + + case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR: + { + MouseWheelBehaviour nVclBehavior = GetWindow()->GetSettings().GetMouseSettings().GetWheelBehavior(); + sal_uInt16 nBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY; + switch ( nVclBehavior ) + { + case MouseWheelBehaviour::Disable: nBehavior = css::awt::MouseWheelBehavior::SCROLL_DISABLED; break; + case MouseWheelBehaviour::FocusOnly: nBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY; break; + case MouseWheelBehaviour::ALWAYS: nBehavior = css::awt::MouseWheelBehavior::SCROLL_ALWAYS; break; + default: + OSL_FAIL( "VCLXWindow::getProperty( 'MouseWheelBehavior' ): illegal VCL value!" ); + } + aProp <<= nBehavior; + } + break; + + case BASEPROPERTY_NATIVE_WIDGET_LOOK: + aProp <<= GetWindow()->IsNativeWidgetEnabled(); + break; + + case BASEPROPERTY_ENABLED: + aProp <<= GetWindow()->IsEnabled(); + break; + + case BASEPROPERTY_ENABLEVISIBLE: + aProp <<= mpImpl->isEnableVisible(); + break; + + case BASEPROPERTY_HIGHCONTRASTMODE: + aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetHighContrastMode(); + break; + + case BASEPROPERTY_TEXT: + case BASEPROPERTY_LABEL: + case BASEPROPERTY_TITLE: + { + OUString aText = GetWindow()->GetText(); + aProp <<= aText; + } + break; + case BASEPROPERTY_ACCESSIBLENAME: + { + OUString aText = GetWindow()->GetAccessibleName(); + aProp <<= aText; + } + break; + case BASEPROPERTY_HELPTEXT: + { + OUString aText = GetWindow()->GetQuickHelpText(); + aProp <<= aText; + } + break; + case BASEPROPERTY_HELPURL: + { + OUString aHelpId( OStringToOUString( GetWindow()->GetHelpId(), RTL_TEXTENCODING_UTF8 ) ); + aProp <<= aHelpId; + } + break; + case BASEPROPERTY_FONTDESCRIPTOR: + { + vcl::Font aFont = GetWindow()->GetControlFont(); + css::awt::FontDescriptor aFD = VCLUnoHelper::CreateFontDescriptor( aFont ); + aProp <<= aFD; + } + break; + case BASEPROPERTY_BACKGROUNDCOLOR: + aProp <<= GetWindow()->GetControlBackground(); + break; + case BASEPROPERTY_DISPLAYBACKGROUNDCOLOR: + aProp <<= GetWindow()->GetBackgroundColor(); + break; + case BASEPROPERTY_FONTRELIEF: + aProp <<= static_cast<sal_Int16>(GetWindow()->GetControlFont().GetRelief()); + break; + case BASEPROPERTY_FONTEMPHASISMARK: + aProp <<= static_cast<sal_Int16>(GetWindow()->GetControlFont().GetEmphasisMark()); + break; + case BASEPROPERTY_TEXTCOLOR: + aProp <<= GetWindow()->GetControlForeground(); + break; + case BASEPROPERTY_TEXTLINECOLOR: + aProp <<= GetWindow()->GetTextLineColor(); + break; + case BASEPROPERTY_FILLCOLOR: + aProp <<= GetWindow()->GetOutDev()->GetFillColor(); + break; + case BASEPROPERTY_LINECOLOR: + aProp <<= GetWindow()->GetOutDev()->GetLineColor(); + break; + case BASEPROPERTY_BORDER: + { + WindowBorderStyle nBorder = WindowBorderStyle::NONE; + if ( GetWindow()->GetStyle() & WB_BORDER ) + nBorder = GetWindow()->GetBorderStyle(); + aProp <<= static_cast<sal_uInt16>(nBorder); + } + break; + case BASEPROPERTY_TABSTOP: + aProp <<= ( GetWindow()->GetStyle() & WB_TABSTOP ) != 0; + break; + case BASEPROPERTY_VERTICALALIGN: + { + WinBits nStyle = GetWindow()->GetStyle(); + if ( nStyle & WB_TOP ) + aProp <<= VerticalAlignment_TOP; + else if ( nStyle & WB_VCENTER ) + aProp <<= VerticalAlignment_MIDDLE; + else if ( nStyle & WB_BOTTOM ) + aProp <<= VerticalAlignment_BOTTOM; + } + break; + case BASEPROPERTY_ALIGN: + { + switch ( eWinType ) + { + case WindowType::FIXEDTEXT: + case WindowType::EDIT: + case WindowType::MULTILINEEDIT: + case WindowType::CHECKBOX: + case WindowType::RADIOBUTTON: + case WindowType::LISTBOX: + case WindowType::COMBOBOX: + case WindowType::PUSHBUTTON: + case WindowType::OKBUTTON: + case WindowType::CANCELBUTTON: + case WindowType::HELPBUTTON: + { + WinBits nStyle = GetWindow()->GetStyle(); + if ( nStyle & WB_LEFT ) + aProp <<= sal_Int16(PROPERTY_ALIGN_LEFT); + else if ( nStyle & WB_CENTER ) + aProp <<= sal_Int16(PROPERTY_ALIGN_CENTER); + else if ( nStyle & WB_RIGHT ) + aProp <<= sal_Int16(PROPERTY_ALIGN_RIGHT); + } + break; + default: break; + } + } + break; + case BASEPROPERTY_MULTILINE: + { + if ( ( eWinType == WindowType::FIXEDTEXT ) + || ( eWinType == WindowType::CHECKBOX ) + || ( eWinType == WindowType::RADIOBUTTON ) + || ( eWinType == WindowType::PUSHBUTTON ) + || ( eWinType == WindowType::OKBUTTON ) + || ( eWinType == WindowType::CANCELBUTTON ) + || ( eWinType == WindowType::HELPBUTTON ) + ) + aProp <<= ( GetWindow()->GetStyle() & WB_WORDBREAK ) != 0; + } + break; + case BASEPROPERTY_AUTOMNEMONICS: + { + bool bAutoMnemonics = GetWindow()->GetSettings().GetStyleSettings().GetAutoMnemonic(); + aProp <<= bAutoMnemonics; + } + break; + case BASEPROPERTY_MOUSETRANSPARENT: + { + bool bMouseTransparent = GetWindow()->IsMouseTransparent(); + aProp <<= bMouseTransparent; + } + break; + case BASEPROPERTY_PAINTTRANSPARENT: + { + bool bPaintTransparent = GetWindow()->IsPaintTransparent(); + aProp <<= bPaintTransparent; + } + break; + + case BASEPROPERTY_REPEAT: + aProp <<= ( 0 != ( GetWindow()->GetStyle() & WB_REPEAT ) ); + break; + + case BASEPROPERTY_REPEAT_DELAY: + { + sal_Int32 nButtonRepeat = GetWindow()->GetSettings().GetMouseSettings().GetButtonRepeat(); + aProp <<= nButtonRepeat; + } + break; + + case BASEPROPERTY_SYMBOL_COLOR: + aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetButtonTextColor(); + break; + + case BASEPROPERTY_BORDERCOLOR: + aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetMonoColor(); + break; + } + } + return aProp; +} + + +// css::awt::XLayoutConstrains +css::awt::Size VCLXWindow::getMinimumSize( ) +{ + SolarMutexGuard aGuard; + + // Use this method only for those components which can be created through + // css::awt::Toolkit , but do not have an interface + + Size aSz; + if ( GetWindow() ) + { + WindowType nWinType = GetWindow()->GetType(); + switch ( nWinType ) + { + case WindowType::CONTROL: + aSz.setWidth( GetWindow()->GetTextWidth( GetWindow()->GetText() )+2*12 ); + aSz.setHeight( GetWindow()->GetTextHeight()+2*6 ); + break; + + case WindowType::PATTERNBOX: + case WindowType::NUMERICBOX: + case WindowType::METRICBOX: + case WindowType::CURRENCYBOX: + case WindowType::DATEBOX: + case WindowType::TIMEBOX: + case WindowType::LONGCURRENCYBOX: + aSz.setWidth( GetWindow()->GetTextWidth( GetWindow()->GetText() )+2*2 ); + aSz.setHeight( GetWindow()->GetTextHeight()+2*2 ); + break; + case WindowType::SCROLLBARBOX: + return VCLXScrollBar::implGetMinimumSize( GetWindow() ); + default: + aSz = GetWindow()->get_preferred_size(); + } + } + + return css::awt::Size( aSz.Width(), aSz.Height() ); +} + +css::awt::Size VCLXWindow::getPreferredSize( ) +{ + return getMinimumSize(); +} + +css::awt::Size VCLXWindow::calcAdjustedSize( const css::awt::Size& rNewSize ) +{ + SolarMutexGuard aGuard; + + css::awt::Size aNewSize( rNewSize ); + css::awt::Size aMinSize = getMinimumSize(); + + if ( aNewSize.Width < aMinSize.Width ) + aNewSize.Width = aMinSize.Width; + if ( aNewSize.Height < aMinSize.Height ) + aNewSize.Height = aMinSize.Height; + + return aNewSize; +} + + +// css::awt::XView +sal_Bool VCLXWindow::setGraphics( const css::uno::Reference< css::awt::XGraphics >& rxDevice ) +{ + SolarMutexGuard aGuard; + + if ( VCLUnoHelper::GetOutputDevice( rxDevice ) ) + mpImpl->mxViewGraphics = rxDevice; + else + mpImpl->mxViewGraphics = nullptr; + + return mpImpl->mxViewGraphics.is(); +} + +css::uno::Reference< css::awt::XGraphics > VCLXWindow::getGraphics( ) +{ + SolarMutexGuard aGuard; + + return mpImpl->mxViewGraphics; +} + +css::awt::Size VCLXWindow::getSize( ) +{ + SolarMutexGuard aGuard; + + Size aSz; + if ( GetWindow() ) + aSz = GetWindow()->GetSizePixel(); + return css::awt::Size( aSz.Width(), aSz.Height() ); +} + +void VCLXWindow::draw( sal_Int32 nX, sal_Int32 nY ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( !pWindow ) + return; + + if ( !(isDesignMode() || mpImpl->isEnableVisible()) ) + return; + + OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( mpImpl->mxViewGraphics ); + if (!pDev) + pDev = pWindow->GetParent()->GetOutDev(); + TabPage* pTabPage = dynamic_cast< TabPage* >( pWindow.get() ); + if ( pTabPage ) + { + Point aPos( nX, nY ); + aPos = pDev->PixelToLogic( aPos ); + pTabPage->Draw( pDev, aPos, SystemTextColorFlags::NONE ); + return; + } + + Point aPos( nX, nY ); + + if ( pWindow->GetParent() && !pWindow->IsSystemWindow() && ( pWindow->GetParent()->GetOutDev() == pDev ) ) + { + // #i40647# don't draw here if this is a recursive call + // sometimes this is called recursively, because the Update call on the parent + // (strangely) triggers another paint. Prevent a stack overflow here + // Yes, this is only fixing symptoms for the moment... + // #i40647# / 2005-01-18 / frank.schoenheit@sun.com + if ( !mpImpl->getDrawingOntoParent_ref() ) + { + ::comphelper::FlagGuard aDrawingflagGuard( mpImpl->getDrawingOntoParent_ref() ); + + bool bWasVisible = pWindow->IsVisible(); + Point aOldPos( pWindow->GetPosPixel() ); + + if ( bWasVisible && aOldPos == aPos ) + { + pWindow->PaintImmediately(); + return; + } + + pWindow->SetPosPixel( aPos ); + + // Update parent first to avoid painting the parent upon the update + // of this window, as it may otherwise cause the parent + // to hide this window again + if( pWindow->GetParent() ) + pWindow->GetParent()->PaintImmediately(); + + pWindow->Show(); + pWindow->PaintImmediately(); + pWindow->SetParentUpdateMode( false ); + pWindow->Hide(); + pWindow->SetParentUpdateMode( true ); + + pWindow->SetPosPixel( aOldPos ); + if ( bWasVisible ) + pWindow->Show(); + } + } + else if ( pDev ) + { + Point aP = pDev->PixelToLogic( aPos ); + + vcl::PDFExtOutDevData* pPDFExport = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData()); + bool bDrawSimple = ( pDev->GetOutDevType() == OUTDEV_PRINTER ) + || ( pDev->GetOutDevViewType() == OutDevViewType::PrintPreview ) + || ( pPDFExport != nullptr ); + if ( bDrawSimple ) + { + pWindow->Draw( pDev, aP, SystemTextColorFlags::NoControls ); + } + else + { + bool bOldNW =pWindow->IsNativeWidgetEnabled(); + if( bOldNW ) + pWindow->EnableNativeWidget(false); + pWindow->PaintToDevice( pDev, aP ); + if( bOldNW ) + pWindow->EnableNativeWidget(); + } + } +} + +void VCLXWindow::setZoom( float fZoomX, float /*fZoomY*/ ) +{ + SolarMutexGuard aGuard; + + if ( GetWindow() ) + { + // Fraction::Fraction takes a double, but we have a float only. + // The implicit conversion from float to double can result in a precision loss, i.e. 1.2 is converted to + // 1.200000000047something. To prevent this, we convert explicitly to double, and round it. + double nZoom( fZoomX ); + Fraction aZoom(::rtl::math::round(nZoom, 4)); + aZoom.ReduceInaccurate(10); // to avoid runovers and BigInt mapping + GetWindow()->SetZoom(aZoom); + } +} + +// css::lang::XEventListener +void SAL_CALL VCLXWindow::disposing( const css::lang::EventObject& _rSource ) +{ + SolarMutexGuard aGuard; + + if (mpImpl->mbDisposing) + return; + + // check if it comes from our AccessibleContext + uno::Reference< uno::XInterface > aAC( mpImpl->mxAccessibleContext, uno::UNO_QUERY ); + uno::Reference< uno::XInterface > xSource( _rSource.Source, uno::UNO_QUERY ); + + if ( aAC.get() == xSource.get() ) + { // yep, it does + mpImpl->mxAccessibleContext.clear(); + } +} + +// css::accessibility::XAccessible +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXWindow::getAccessibleContext( ) +{ + SolarMutexGuard aGuard; + + // already disposed + if (mpImpl->mbDisposing) + return uno::Reference< accessibility::XAccessibleContext >(); + + if ( !mpImpl->mxAccessibleContext.is() && GetWindow() ) + { + mpImpl->mxAccessibleContext = CreateAccessibleContext(); + + // add as event listener to this component + // in case somebody disposes it, we do not want to have a (though weak) reference to a dead + // object + uno::Reference< lang::XComponent > xComp( mpImpl->mxAccessibleContext, uno::UNO_QUERY ); + if ( xComp.is() ) + xComp->addEventListener( this ); + } + + return mpImpl->mxAccessibleContext; +} + +// css::awt::XDockable +void SAL_CALL VCLXWindow::addDockableWindowListener( const css::uno::Reference< css::awt::XDockableWindowListener >& xListener ) +{ + SolarMutexGuard aGuard; + + if (!mpImpl->mbDisposing && xListener.is() ) + mpImpl->getDockableWindowListeners().addInterface( xListener ); + +} + +void SAL_CALL VCLXWindow::removeDockableWindowListener( const css::uno::Reference< css::awt::XDockableWindowListener >& xListener ) +{ + SolarMutexGuard aGuard; + + if (!mpImpl->mbDisposing) + mpImpl->getDockableWindowListeners().removeInterface( xListener ); +} + +void SAL_CALL VCLXWindow::enableDocking( sal_Bool bEnable ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + pWindow->EnableDocking( bEnable ); +} + +sal_Bool SAL_CALL VCLXWindow::isFloating( ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if( pWindow ) + return vcl::Window::GetDockingManager()->IsFloating( pWindow ); + else + return false; +} + +void SAL_CALL VCLXWindow::setFloatingMode( sal_Bool bFloating ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if( pWindow ) + vcl::Window::GetDockingManager()->SetFloatingMode( pWindow, bFloating ); +} + +sal_Bool SAL_CALL VCLXWindow::isLocked( ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if( pWindow ) + return vcl::Window::GetDockingManager()->IsLocked( pWindow ); + else + return false; +} + +void SAL_CALL VCLXWindow::lock( ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if( pWindow && !vcl::Window::GetDockingManager()->IsFloating( pWindow ) ) + vcl::Window::GetDockingManager()->Lock( pWindow ); +} + +void SAL_CALL VCLXWindow::unlock( ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if( pWindow && !vcl::Window::GetDockingManager()->IsFloating( pWindow ) ) + vcl::Window::GetDockingManager()->Unlock( pWindow ); +} + +void SAL_CALL VCLXWindow::startPopupMode( const css::awt::Rectangle& ) +{ + // deprecated +} + +sal_Bool SAL_CALL VCLXWindow::isInPopupMode( ) +{ + // deprecated + return false; +} + + +// css::awt::XWindow2 + +void SAL_CALL VCLXWindow::setOutputSize( const css::awt::Size& aSize ) +{ + SolarMutexGuard aGuard; + if( VclPtr<vcl::Window> pWindow = GetWindow() ) + pWindow->SetOutputSizePixel( VCLSize( aSize ) ); +} + +css::awt::Size SAL_CALL VCLXWindow::getOutputSize( ) +{ + SolarMutexGuard aGuard; + if( VclPtr<vcl::Window> pWindow = GetWindow() ) + return AWTSize( pWindow->GetOutputSizePixel() ); + else + return css::awt::Size(); +} + +sal_Bool SAL_CALL VCLXWindow::isVisible( ) +{ + SolarMutexGuard aGuard; + if( GetWindow() ) + return GetWindow()->IsVisible(); + else + return false; +} + +sal_Bool SAL_CALL VCLXWindow::isActive( ) +{ + SolarMutexGuard aGuard; + if( GetWindow() ) + return GetWindow()->IsActive(); + else + return false; + +} + +sal_Bool SAL_CALL VCLXWindow::isEnabled( ) +{ + SolarMutexGuard aGuard; + if( GetWindow() ) + return GetWindow()->IsEnabled(); + else + return false; +} + +sal_Bool SAL_CALL VCLXWindow::hasFocus( ) +{ + SolarMutexGuard aGuard; + if( GetWindow() ) + return GetWindow()->HasFocus(); + else + return false; +} + +// css::beans::XPropertySetInfo + +UnoPropertyArrayHelper * +VCLXWindow::GetPropHelper() +{ + SolarMutexGuard aGuard; + if ( mpImpl->mpPropHelper == nullptr ) + { + std::vector< sal_uInt16 > aIDs; + GetPropertyIds( aIDs ); + mpImpl->mpPropHelper.reset( new UnoPropertyArrayHelper( aIDs ) ); + } + return mpImpl->mpPropHelper.get(); +} + +css::uno::Sequence< css::beans::Property > SAL_CALL +VCLXWindow::getProperties() +{ + return GetPropHelper()->getProperties(); +} +css::beans::Property SAL_CALL +VCLXWindow::getPropertyByName( const OUString& rName ) +{ + return GetPropHelper()->getPropertyByName( rName ); +} + +sal_Bool SAL_CALL +VCLXWindow::hasPropertyByName( const OUString& rName ) +{ + return GetPropHelper()->hasPropertyByName( rName ); +} + +Reference< XStyleSettings > SAL_CALL VCLXWindow::getStyleSettings() +{ + return mpImpl->getStyleSettings(); +} + +bool VCLXWindow::IsDisposed() const +{ + return mpImpl->mbDisposing; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxwindow1.cxx b/toolkit/source/awt/vclxwindow1.cxx new file mode 100644 index 000000000..7b7b7192f --- /dev/null +++ b/toolkit/source/awt/vclxwindow1.cxx @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <toolkit/awt/vclxwindow.hxx> +#include <com/sun/star/beans/NamedValue.hpp> +#include <vcl/wrkwin.hxx> +#include <vcl/window.hxx> + +#ifdef _WIN32 +#include <prewin.h> +#include <postwin.h> +#elif defined(MACOSX) +#include <premac.h> +#include <Cocoa/Cocoa.h> +#include <postmac.h> +#endif +#include <vcl/sysdata.hxx> + +/// helper method to set a window handle into a SystemParentData struct +void VCLXWindow::SetSystemParent_Impl(const css::uno::Any& rHandle) +{ + // does only work for WorkWindows + VclPtr<vcl::Window> pWindow = GetWindow(); + if (pWindow->GetType() != WindowType::WORKWINDOW) + { + css::uno::RuntimeException aException; + aException.Message = "not a work window"; + throw aException; + } + + // use sal_Int64 here to accommodate all int types + // uno::Any shift operator will upcast if necessary + sal_Int64 nHandle = 0; + bool bXEmbed = false; + bool bThrow = false; + if (!(rHandle >>= nHandle)) + { + css::uno::Sequence<css::beans::NamedValue> aProps; + if (rHandle >>= aProps) + { + for (const css::beans::NamedValue& rProp : std::as_const(aProps)) + { + if (rProp.Name == "WINDOW") + rProp.Value >>= nHandle; + else if (rProp.Name == "XEMBED") + rProp.Value >>= bXEmbed; + } + } + else + bThrow = true; + } + if (bThrow) + { + css::uno::RuntimeException aException; + aException.Message = "incorrect window handle type"; + throw aException; + } + // create system parent data + SystemParentData aSysParentData; + aSysParentData.nSize = sizeof(SystemParentData); +#if defined(_WIN32) + aSysParentData.hWnd = reinterpret_cast<HWND>(nHandle); +#elif defined(MACOSX) + aSysParentData.pView = reinterpret_cast<NSView*>(nHandle); +#elif defined(ANDROID) + // Nothing +#elif defined(IOS) + // Nothing +#elif defined(UNX) + aSysParentData.aWindow = nHandle; + aSysParentData.bXEmbedSupport = bXEmbed; +#endif + + // set system parent + static_cast<WorkWindow*>(pWindow.get())->SetPluginParent(&aSysParentData); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxwindows.cxx b/toolkit/source/awt/vclxwindows.cxx new file mode 100644 index 000000000..e444d6d3a --- /dev/null +++ b/toolkit/source/awt/vclxwindows.cxx @@ -0,0 +1,8220 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <toolkit/awt/vclxwindows.hxx> +#include <toolkit/helper/accessiblefactory.hxx> +#include <com/sun/star/awt/LineEndFormat.hpp> +#include <com/sun/star/awt/ScrollBarOrientation.hpp> +#include <com/sun/star/graphic/GraphicProvider.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <toolkit/helper/vclunohelper.hxx> +#include <toolkit/helper/macros.hxx> +#include <toolkit/helper/property.hxx> +#include <toolkit/helper/convert.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <com/sun/star/awt/VisualEffect.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/resource/XStringResourceResolver.hpp> +#include <com/sun/star/awt/ImageScaleMode.hpp> +#include <com/sun/star/awt/XItemList.hpp> +#include <com/sun/star/awt/TextAlign.hpp> +#include <comphelper/namedvaluecollection.hxx> +#include <comphelper/processfactory.hxx> +#include <sal/log.hxx> + +#include <awt/vclxwindows.hxx> +#include <controls/filectrl.hxx> +#include <controls/svmedit.hxx> +#include <vcl/toolkit/button.hxx> +#include <vcl/toolkit/fmtfield.hxx> +#include <vcl/graph.hxx> +#include <vcl/toolkit/lstbox.hxx> +#include <vcl/toolkit/combobox.hxx> +#include <vcl/toolkit/field.hxx> +#include <vcl/toolkit/fixedhyper.hxx> +#include <vcl/toolkit/imgctrl.hxx> +#include <vcl/toolkit/dialog.hxx> +#include <vcl/toolkit/prgsbar.hxx> +#include <vcl/scrbar.hxx> +#include <vcl/svapp.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/settings.hxx> +#include <tools/diagnose_ex.h> +#include <tools/debug.hxx> + +#include <helper/imagealign.hxx> +#include <helper/msgbox.hxx> +#include <helper/tkresmgr.hxx> +#include "vclxwindows_internal.hxx" +#include <svl/numformat.hxx> + +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::lang::EventObject; +using ::com::sun::star::awt::ItemListEvent; +using ::com::sun::star::awt::XItemList; +using ::com::sun::star::graphic::XGraphic; +using ::com::sun::star::graphic::XGraphicProvider; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::awt::VisualEffect; +namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode; + +static double ImplCalcLongValue( double nValue, sal_uInt16 nDigits ) +{ + double n = nValue; + for ( sal_uInt16 d = 0; d < nDigits; d++ ) + n *= 10; + return n; +} + +static double ImplCalcDoubleValue( double nValue, sal_uInt16 nDigits ) +{ + double n = nValue; + for ( sal_uInt16 d = 0; d < nDigits; d++ ) + n /= 10; + return n; +} + +namespace toolkit +{ + /** sets the "face color" for button like controls (scroll bar, spin button) + */ + void setButtonLikeFaceColor( vcl::Window* _pWindow, const css::uno::Any& _rColorValue ) + { + AllSettings aSettings = _pWindow->GetSettings(); + StyleSettings aStyleSettings = aSettings.GetStyleSettings(); + + if ( !_rColorValue.hasValue() ) + { + const StyleSettings& aAppStyle = Application::GetSettings().GetStyleSettings(); + aStyleSettings.SetFaceColor( aAppStyle.GetFaceColor( ) ); + aStyleSettings.SetCheckedColor( aAppStyle.GetCheckedColor( ) ); + aStyleSettings.SetLightBorderColor( aAppStyle.GetLightBorderColor() ); + aStyleSettings.SetLightColor( aAppStyle.GetLightColor() ); + aStyleSettings.SetShadowColor( aAppStyle.GetShadowColor() ); + aStyleSettings.SetDarkShadowColor( aAppStyle.GetDarkShadowColor() ); + } + else + { + Color nBackgroundColor; + _rColorValue >>= nBackgroundColor; + aStyleSettings.SetFaceColor( nBackgroundColor ); + + // for the real background (everything except the buttons and the thumb), + // use an average between the desired color and "white" + Color aWhite( COL_WHITE ); + Color aCheckedBackground( nBackgroundColor ); + aCheckedBackground.SetRed( ( aCheckedBackground.GetRed() + aWhite.GetRed() ) / 2 ); + aCheckedBackground.SetGreen( ( aCheckedBackground.GetGreen() + aWhite.GetGreen() ) / 2 ); + aCheckedBackground.SetBlue( ( aCheckedBackground.GetBlue() + aWhite.GetBlue() ) / 2 ); + aStyleSettings.SetCheckedColor( aCheckedBackground ); + + sal_Int32 nBackgroundLuminance = nBackgroundColor.GetLuminance(); + sal_Int32 nWhiteLuminance = COL_WHITE.GetLuminance(); + + Color aLightShadow( nBackgroundColor ); + aLightShadow.IncreaseLuminance( static_cast<sal_uInt8>( ( nWhiteLuminance - nBackgroundLuminance ) * 2 / 3 ) ); + aStyleSettings.SetLightBorderColor( aLightShadow ); + + Color aLight( nBackgroundColor ); + aLight.IncreaseLuminance( static_cast<sal_uInt8>( ( nWhiteLuminance - nBackgroundLuminance ) * 1 / 3 ) ); + aStyleSettings.SetLightColor( aLight ); + + Color aShadow( nBackgroundColor ); + aShadow.DecreaseLuminance( static_cast<sal_uInt8>( nBackgroundLuminance * 1 / 3 ) ); + aStyleSettings.SetShadowColor( aShadow ); + + Color aDarkShadow( nBackgroundColor ); + aDarkShadow.DecreaseLuminance( static_cast<sal_uInt8>( nBackgroundLuminance * 2 / 3 ) ); + aStyleSettings.SetDarkShadowColor( aDarkShadow ); + } + + aSettings.SetStyleSettings( aStyleSettings ); + _pWindow->SetSettings( aSettings, true ); + } + + Any getButtonLikeFaceColor( const vcl::Window* _pWindow ) + { + Color nBackgroundColor = _pWindow->GetSettings().GetStyleSettings().GetFaceColor(); + return Any( sal_Int32(nBackgroundColor) ); + } + + static void adjustBooleanWindowStyle( const Any& _rValue, vcl::Window* _pWindow, WinBits _nBits, bool _bInverseSemantics ) + { + WinBits nStyle = _pWindow->GetStyle(); + bool bValue( false ); + OSL_VERIFY( _rValue >>= bValue ); + if ( bValue != _bInverseSemantics ) + nStyle |= _nBits; + else + nStyle &= ~_nBits; + _pWindow->SetStyle( nStyle ); + } + + static void setVisualEffect( const Any& _rValue, vcl::Window* _pWindow ) + { + AllSettings aSettings = _pWindow->GetSettings(); + StyleSettings aStyleSettings = aSettings.GetStyleSettings(); + + sal_Int16 nStyle = LOOK3D; + OSL_VERIFY( _rValue >>= nStyle ); + switch ( nStyle ) + { + case FLAT: + aStyleSettings.SetOptions( aStyleSettings.GetOptions() | StyleSettingsOptions::Mono ); + break; + case LOOK3D: + default: + aStyleSettings.SetOptions( aStyleSettings.GetOptions() & ~StyleSettingsOptions::Mono ); + } + aSettings.SetStyleSettings( aStyleSettings ); + _pWindow->SetSettings( aSettings ); + } + + static Any getVisualEffect( vcl::Window const * _pWindow ) + { + Any aEffect; + + StyleSettings aStyleSettings = _pWindow->GetSettings().GetStyleSettings(); + if ( aStyleSettings.GetOptions() & StyleSettingsOptions::Mono ) + aEffect <<= sal_Int16(FLAT); + else + aEffect <<= sal_Int16(LOOK3D); + return aEffect; + } +} + + + + +void VCLXGraphicControl::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + VCLXWindow::ImplGetPropertyIds( rIds ); +} + +void VCLXGraphicControl::ImplSetNewImage() +{ + OSL_PRECOND( GetWindow(), "VCLXGraphicControl::ImplSetNewImage: window is required to be not-NULL!" ); + VclPtr< Button > pButton = GetAsDynamic< Button >(); + pButton->SetModeImage( GetImage() ); +} + +void VCLXGraphicControl::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags ) +{ + SolarMutexGuard aGuard; + + if ( GetWindow() ) + { + Size aOldSize = GetWindow()->GetSizePixel(); + VCLXWindow::setPosSize( X, Y, Width, Height, Flags ); + if ( ( aOldSize.Width() != Width ) || ( aOldSize.Height() != Height ) ) + ImplSetNewImage(); + } +} + +void VCLXGraphicControl::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + if ( !GetWindow() ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_GRAPHIC: + { + Reference< XGraphic > xGraphic; + OSL_VERIFY( Value >>= xGraphic ); + maImage = Image( xGraphic ); + ImplSetNewImage(); + } + break; + + case BASEPROPERTY_IMAGEALIGN: + { + WindowType eType = GetWindow()->GetType(); + if ( ( eType == WindowType::PUSHBUTTON ) + || ( eType == WindowType::RADIOBUTTON ) + || ( eType == WindowType::CHECKBOX ) + ) + { + sal_Int16 nAlignment = sal_Int16(); + if ( Value >>= nAlignment ) + GetAs< Button >()->SetImageAlign( static_cast< ImageAlign >( nAlignment ) ); + } + } + break; + case BASEPROPERTY_IMAGEPOSITION: + { + WindowType eType = GetWindow()->GetType(); + if ( ( eType == WindowType::PUSHBUTTON ) + || ( eType == WindowType::RADIOBUTTON ) + || ( eType == WindowType::CHECKBOX ) + ) + { + sal_Int16 nImagePosition = 2; + OSL_VERIFY( Value >>= nImagePosition ); + GetAs<Button>()->SetImageAlign( ::toolkit::translateImagePosition( nImagePosition ) ); + } + } + break; + default: + VCLXWindow::setProperty( PropertyName, Value ); + break; + } +} + +css::uno::Any VCLXGraphicControl::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + if ( !GetWindow() ) + return aProp; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_GRAPHIC: + aProp <<= Graphic(maImage.GetBitmapEx()).GetXGraphic(); + break; + case BASEPROPERTY_IMAGEALIGN: + { + WindowType eType = GetWindow()->GetType(); + if ( ( eType == WindowType::PUSHBUTTON ) + || ( eType == WindowType::RADIOBUTTON ) + || ( eType == WindowType::CHECKBOX ) + ) + { + aProp <<= ::toolkit::getCompatibleImageAlign( + GetAs<Button>()->GetImageAlign() ); + } + } + break; + case BASEPROPERTY_IMAGEPOSITION: + { + WindowType eType = GetWindow()->GetType(); + if ( ( eType == WindowType::PUSHBUTTON ) + || ( eType == WindowType::RADIOBUTTON ) + || ( eType == WindowType::CHECKBOX ) + ) + { + aProp <<= ::toolkit::translateImagePosition( + GetAs< Button >()->GetImageAlign() ); + } + } + break; + default: + { + aProp = VCLXWindow::getProperty( PropertyName ); + } + break; + } + return aProp; +} + + + + +void VCLXButton::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_DEFAULTBUTTON, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_GRAPHIC, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_IMAGEALIGN, + BASEPROPERTY_IMAGEPOSITION, + BASEPROPERTY_IMAGEURL, + BASEPROPERTY_LABEL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_PUSHBUTTONTYPE, + BASEPROPERTY_REPEAT, + BASEPROPERTY_REPEAT_DELAY, + BASEPROPERTY_STATE, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_TOGGLE, + BASEPROPERTY_FOCUSONCLICK, + BASEPROPERTY_MULTILINE, + BASEPROPERTY_ALIGN, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_REFERENCE_DEVICE, + 0); + VCLXGraphicControl::ImplGetPropertyIds( rIds ); +} + +VCLXButton::VCLXButton() + :maActionListeners( *this ) + ,maItemListeners( *this ) +{ +} + +VCLXButton::~VCLXButton() +{ +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXButton::CreateAccessibleContext() +{ + return getAccessibleFactory().createAccessibleContext( this ); +} + +void VCLXButton::dispose() +{ + SolarMutexGuard aGuard; + + css::lang::EventObject aObj; + aObj.Source = static_cast<cppu::OWeakObject*>(this); + maActionListeners.disposeAndClear( aObj ); + maItemListeners.disposeAndClear( aObj ); + VCLXGraphicControl::dispose(); +} + +void VCLXButton::addActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.addInterface( l ); +} + +void VCLXButton::removeActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.removeInterface( l ); +} + +void VCLXButton::addItemListener( const css::uno::Reference< css::awt::XItemListener > & l ) +{ + SolarMutexGuard aGuard; + maItemListeners.addInterface( l ); +} + +void VCLXButton::removeItemListener( const css::uno::Reference< css::awt::XItemListener > & l ) +{ + SolarMutexGuard aGuard; + maItemListeners.removeInterface( l ); +} + +void VCLXButton::setLabel( const OUString& rLabel ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + pWindow->SetText( rLabel ); +} + +void VCLXButton::setActionCommand( const OUString& rCommand ) +{ + SolarMutexGuard aGuard; + + maActionCommand = rCommand; +} + +css::awt::Size VCLXButton::getMinimumSize( ) +{ + SolarMutexGuard aGuard; + + Size aSz; + VclPtr< PushButton > pButton = GetAs< PushButton >(); + if ( pButton ) + aSz = pButton->CalcMinimumSize(); + return AWTSize(aSz); +} + +css::awt::Size VCLXButton::getPreferredSize( ) +{ + css::awt::Size aSz = getMinimumSize(); + aSz.Width += 16; + aSz.Height += 10; + return aSz; +} + +css::awt::Size VCLXButton::calcAdjustedSize( const css::awt::Size& rNewSize ) +{ + SolarMutexGuard aGuard; + + Size aSz = VCLSize(rNewSize); + VclPtr< PushButton > pButton = GetAs< PushButton >(); + if ( pButton ) + { + Size aMinSz = pButton->CalcMinimumSize(); + // no text, thus image + if ( pButton->GetText().isEmpty() ) + { + if ( aSz.Width() < aMinSz.Width() ) + aSz.setWidth( aMinSz.Width() ); + if ( aSz.Height() < aMinSz.Height() ) + aSz.setHeight( aMinSz.Height() ); + } + else + { + if ( ( aSz.Width() > aMinSz.Width() ) && ( aSz.Height() < aMinSz.Height() ) ) + aSz.setHeight( aMinSz.Height() ); + else + aSz = aMinSz; + } + } + return AWTSize(aSz); +} + +void VCLXButton::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + VclPtr< Button > pButton = GetAs< Button >(); + if ( !pButton ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_FOCUSONCLICK: + ::toolkit::adjustBooleanWindowStyle( Value, pButton, WB_NOPOINTERFOCUS, true ); + break; + + case BASEPROPERTY_TOGGLE: + ::toolkit::adjustBooleanWindowStyle( Value, pButton, WB_TOGGLE, false ); + break; + + case BASEPROPERTY_DEFAULTBUTTON: + { + WinBits nStyle = pButton->GetStyle() | WB_DEFBUTTON; + bool b = bool(); + if ( ( Value >>= b ) && !b ) + nStyle &= ~WB_DEFBUTTON; + pButton->SetStyle( nStyle ); + } + break; + case BASEPROPERTY_STATE: + { + if ( GetWindow()->GetType() == WindowType::PUSHBUTTON ) + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + static_cast<PushButton*>(pButton.get())->SetState( static_cast<TriState>(n) ); + } + } + break; + default: + { + VCLXGraphicControl::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXButton::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + VclPtr< Button > pButton = GetAs< Button >(); + if ( pButton ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_FOCUSONCLICK: + aProp <<= ( ( pButton->GetStyle() & WB_NOPOINTERFOCUS ) == 0 ); + break; + + case BASEPROPERTY_TOGGLE: + aProp <<= ( ( pButton->GetStyle() & WB_TOGGLE ) != 0 ); + break; + + case BASEPROPERTY_DEFAULTBUTTON: + { + aProp <<= ( pButton->GetStyle() & WB_DEFBUTTON ) != 0; + } + break; + case BASEPROPERTY_STATE: + { + if ( GetWindow()->GetType() == WindowType::PUSHBUTTON ) + { + aProp <<= static_cast<sal_Int16>(static_cast<PushButton*>(pButton.get())->GetState()); + } + } + break; + default: + { + aProp = VCLXGraphicControl::getProperty( PropertyName ); + } + } + } + return aProp; +} + +void VCLXButton::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::ButtonClick: + { + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + // since we call listeners below, there is a potential that we will be destroyed + // during the listener call. To prevent the resulting crashes, we keep us + // alive as long as we're here + + if ( maActionListeners.getLength() ) + { + css::awt::ActionEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.ActionCommand = maActionCommand; + + Callback aCallback = [ this, aEvent ]() + { this->maActionListeners.actionPerformed( aEvent ); }; + + ImplExecuteAsyncWithoutSolarLock( aCallback ); + } + } + break; + + case VclEventId::PushbuttonToggle: + { + PushButton& rButton = dynamic_cast< PushButton& >( *rVclWindowEvent.GetWindow() ); + + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + if ( maItemListeners.getLength() ) + { + css::awt::ItemEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.Selected = ( rButton.GetState() == TRISTATE_TRUE ) ? 1 : 0; + maItemListeners.itemStateChanged( aEvent ); + } + } + break; + + default: + VCLXGraphicControl::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + + + + +void VCLXImageControl::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_GRAPHIC, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_IMAGEURL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_SCALEIMAGE, + BASEPROPERTY_IMAGE_SCALE_MODE, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + 0); + VCLXGraphicControl::ImplGetPropertyIds( rIds ); +} + +VCLXImageControl::VCLXImageControl() +{ +} + +VCLXImageControl::~VCLXImageControl() +{ +} + +void VCLXImageControl::ImplSetNewImage() +{ + OSL_PRECOND( GetWindow(), "VCLXImageControl::ImplSetNewImage: window is required to be not-NULL!" ); + VclPtr<ImageControl> pControl = GetAs< ImageControl >(); + pControl->SetImage( GetImage() ); +} + +css::awt::Size VCLXImageControl::getMinimumSize( ) +{ + SolarMutexGuard aGuard; + + Size aSz = GetImage().GetSizePixel(); + aSz = ImplCalcWindowSize( aSz ); + + return AWTSize(aSz); +} + +css::awt::Size VCLXImageControl::getPreferredSize( ) +{ + return getMinimumSize(); +} + +css::awt::Size VCLXImageControl::calcAdjustedSize( const css::awt::Size& rNewSize ) +{ + SolarMutexGuard aGuard; + + css::awt::Size aSz = rNewSize; + css::awt::Size aMinSz = getMinimumSize(); + if ( aSz.Width < aMinSz.Width ) + aSz.Width = aMinSz.Width; + if ( aSz.Height < aMinSz.Height ) + aSz.Height = aMinSz.Height; + return aSz; +} + +void VCLXImageControl::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + VclPtr< ImageControl > pImageControl = GetAs< ImageControl >(); + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_IMAGE_SCALE_MODE: + { + sal_Int16 nScaleMode( ImageScaleMode::ANISOTROPIC ); + if ( pImageControl && ( Value >>= nScaleMode ) ) + { + pImageControl->SetScaleMode( nScaleMode ); + } + } + break; + + case BASEPROPERTY_SCALEIMAGE: + { + // this is for compatibility only, nowadays, the ImageScaleMode property should be used + bool bScaleImage = false; + if ( pImageControl && ( Value >>= bScaleImage ) ) + { + pImageControl->SetScaleMode( bScaleImage ? ImageScaleMode::ANISOTROPIC : ImageScaleMode::NONE ); + } + } + break; + + default: + VCLXGraphicControl::setProperty( PropertyName, Value ); + break; + } +} + +css::uno::Any VCLXImageControl::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + VclPtr< ImageControl > pImageControl = GetAs< ImageControl >(); + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + + switch ( nPropType ) + { + case BASEPROPERTY_IMAGE_SCALE_MODE: + aProp <<= ( pImageControl ? pImageControl->GetScaleMode() : ImageScaleMode::ANISOTROPIC ); + break; + + case BASEPROPERTY_SCALEIMAGE: + aProp <<= ( pImageControl && pImageControl->GetScaleMode() != ImageScaleMode::NONE ); + break; + + default: + aProp = VCLXGraphicControl::getProperty( PropertyName ); + break; + } + return aProp; +} + + + + +void VCLXCheckBox::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_GRAPHIC, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_IMAGEPOSITION, + BASEPROPERTY_IMAGEURL, + BASEPROPERTY_LABEL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_STATE, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_TRISTATE, + BASEPROPERTY_VISUALEFFECT, + BASEPROPERTY_MULTILINE, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_ALIGN, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_REFERENCE_DEVICE, + 0); + VCLXGraphicControl::ImplGetPropertyIds( rIds ); +} + +VCLXCheckBox::VCLXCheckBox() : maActionListeners( *this ), maItemListeners( *this ) +{ +} + +// css::uno::XInterface +css::uno::Any VCLXCheckBox::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XButton* >(this), + static_cast< css::awt::XCheckBox* >(this) ); + return (aRet.hasValue() ? aRet : VCLXGraphicControl::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXCheckBox ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXCheckBox::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XButton>::get(), + cppu::UnoType<css::awt::XCheckBox>::get(), + VCLXGraphicControl::getTypes() + ); + return aTypeList.getTypes(); +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXCheckBox::CreateAccessibleContext() +{ + return getAccessibleFactory().createAccessibleContext( this ); +} + +void VCLXCheckBox::dispose() +{ + SolarMutexGuard aGuard; + + css::lang::EventObject aObj; + aObj.Source = static_cast<cppu::OWeakObject*>(this); + maItemListeners.disposeAndClear( aObj ); + VCLXGraphicControl::dispose(); +} + +void VCLXCheckBox::addItemListener( const css::uno::Reference< css::awt::XItemListener > & l ) +{ + SolarMutexGuard aGuard; + maItemListeners.addInterface( l ); +} + +void VCLXCheckBox::removeItemListener( const css::uno::Reference< css::awt::XItemListener > & l ) +{ + SolarMutexGuard aGuard; + maItemListeners.removeInterface( l ); +} + +void VCLXCheckBox::addActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.addInterface( l ); +} + +void VCLXCheckBox::removeActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.removeInterface( l ); +} + +void VCLXCheckBox::setActionCommand( const OUString& rCommand ) +{ + SolarMutexGuard aGuard; + maActionCommand = rCommand; +} + +void VCLXCheckBox::setLabel( const OUString& rLabel ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + pWindow->SetText( rLabel ); +} + +void VCLXCheckBox::setState( sal_Int16 n ) +{ + SolarMutexGuard aGuard; + + VclPtr< CheckBox> pCheckBox = GetAs< CheckBox >(); + if ( !pCheckBox) + return; + + TriState eState; + switch ( n ) + { + case 0: eState = TRISTATE_FALSE; break; + case 1: eState = TRISTATE_TRUE; break; + case 2: eState = TRISTATE_INDET; break; + default: eState = TRISTATE_FALSE; + } + pCheckBox->SetState( eState ); + + // #105198# call C++ click listeners (needed for accessibility) + // pCheckBox->GetClickHdl().Call( pCheckBox ); + + // #107218# Call same virtual methods and listeners like VCL would do after user interaction + SetSynthesizingVCLEvent( true ); + pCheckBox->Toggle(); + pCheckBox->Click(); + SetSynthesizingVCLEvent( false ); +} + +sal_Int16 VCLXCheckBox::getState() +{ + SolarMutexGuard aGuard; + + sal_Int16 nState = -1; + VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >(); + if ( pCheckBox ) + { + switch ( pCheckBox->GetState() ) + { + case TRISTATE_FALSE: nState = 0; break; + case TRISTATE_TRUE: nState = 1; break; + case TRISTATE_INDET: nState = 2; break; + default: OSL_FAIL( "VCLXCheckBox::getState(): unknown TriState!" ); + } + } + + return nState; +} + +void VCLXCheckBox::enableTriState( sal_Bool b ) +{ + SolarMutexGuard aGuard; + + VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >(); + if ( pCheckBox) + pCheckBox->EnableTriState( b ); +} + +css::awt::Size VCLXCheckBox::getMinimumSize() +{ + SolarMutexGuard aGuard; + + Size aSz; + VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >(); + if ( pCheckBox ) + aSz = pCheckBox->CalcMinimumSize(); + return AWTSize(aSz); +} + +css::awt::Size VCLXCheckBox::getPreferredSize() +{ + return getMinimumSize(); +} + +css::awt::Size VCLXCheckBox::calcAdjustedSize( const css::awt::Size& rNewSize ) +{ + SolarMutexGuard aGuard; + + Size aSz = VCLSize(rNewSize); + VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >(); + if ( pCheckBox ) + { + Size aMinSz = pCheckBox->CalcMinimumSize(rNewSize.Width); + if ( ( aSz.Width() > aMinSz.Width() ) && ( aSz.Height() < aMinSz.Height() ) ) + aSz.setHeight( aMinSz.Height() ); + else + aSz = aMinSz; + } + return AWTSize(aSz); +} + +void VCLXCheckBox::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >(); + if ( !pCheckBox ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_VISUALEFFECT: + ::toolkit::setVisualEffect( Value, pCheckBox ); + break; + + case BASEPROPERTY_TRISTATE: + { + bool b = bool(); + if ( Value >>= b ) + pCheckBox->EnableTriState( b ); + } + break; + case BASEPROPERTY_STATE: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + setState( n ); + } + break; + default: + { + VCLXGraphicControl::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXCheckBox::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >(); + if ( pCheckBox ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_VISUALEFFECT: + aProp = ::toolkit::getVisualEffect( pCheckBox ); + break; + case BASEPROPERTY_TRISTATE: + aProp <<= pCheckBox->IsTriStateEnabled(); + break; + case BASEPROPERTY_STATE: + aProp <<= static_cast<sal_Int16>(pCheckBox->GetState()); + break; + default: + { + aProp = VCLXGraphicControl::getProperty( PropertyName ); + } + } + } + return aProp; +} + +void VCLXCheckBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::CheckboxToggle: + { + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + // since we call listeners below, there is a potential that we will be destroyed + // in during the listener call. To prevent the resulting crashes, we keep us + // alive as long as we're here + + VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >(); + if ( pCheckBox ) + { + if ( maItemListeners.getLength() ) + { + css::awt::ItemEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.Highlighted = 0; + aEvent.Selected = pCheckBox->GetState(); + maItemListeners.itemStateChanged( aEvent ); + } + if ( !IsSynthesizingVCLEvent() && maActionListeners.getLength() ) + { + css::awt::ActionEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.ActionCommand = maActionCommand; + maActionListeners.actionPerformed( aEvent ); + } + } + } + break; + + default: + VCLXGraphicControl::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + + + +void VCLXRadioButton::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_GRAPHIC, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_IMAGEPOSITION, + BASEPROPERTY_IMAGEURL, + BASEPROPERTY_LABEL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_STATE, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_VISUALEFFECT, + BASEPROPERTY_MULTILINE, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_ALIGN, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_REFERENCE_DEVICE, + BASEPROPERTY_GROUPNAME, + 0); + VCLXGraphicControl::ImplGetPropertyIds( rIds ); +} + + +VCLXRadioButton::VCLXRadioButton() : maItemListeners( *this ), maActionListeners( *this ) +{ +} + +// css::uno::XInterface +css::uno::Any VCLXRadioButton::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XRadioButton* >(this), + static_cast< css::awt::XButton* >(this) ); + return (aRet.hasValue() ? aRet : VCLXGraphicControl::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXRadioButton ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXRadioButton::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XRadioButton>::get(), + cppu::UnoType<css::awt::XButton>::get(), + VCLXGraphicControl::getTypes() + ); + return aTypeList.getTypes(); +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXRadioButton::CreateAccessibleContext() +{ + return getAccessibleFactory().createAccessibleContext( this ); +} + +void VCLXRadioButton::dispose() +{ + SolarMutexGuard aGuard; + + css::lang::EventObject aObj; + aObj.Source = static_cast<cppu::OWeakObject*>(this); + maItemListeners.disposeAndClear( aObj ); + VCLXGraphicControl::dispose(); +} + +void VCLXRadioButton::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + VclPtr< RadioButton > pButton = GetAs< RadioButton >(); + if ( !pButton ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_VISUALEFFECT: + ::toolkit::setVisualEffect( Value, pButton ); + break; + + case BASEPROPERTY_STATE: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + { + bool b = n != 0; + if ( pButton->IsRadioCheckEnabled() ) + pButton->Check( b ); + else + pButton->SetState( b ); + } + } + break; + case BASEPROPERTY_AUTOTOGGLE: + { + bool b = bool(); + if ( Value >>= b ) + pButton->EnableRadioCheck( b ); + } + break; + default: + { + VCLXGraphicControl::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXRadioButton::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + VclPtr< RadioButton > pButton = GetAs< RadioButton >(); + if ( pButton ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_VISUALEFFECT: + aProp = ::toolkit::getVisualEffect( pButton ); + break; + case BASEPROPERTY_STATE: + aProp <<= static_cast<sal_Int16>( pButton->IsChecked() ? 1 : 0 ); + break; + case BASEPROPERTY_AUTOTOGGLE: + aProp <<= pButton->IsRadioCheckEnabled(); + break; + default: + { + aProp = VCLXGraphicControl::getProperty( PropertyName ); + } + } + } + return aProp; +} + +void VCLXRadioButton::addItemListener( const css::uno::Reference< css::awt::XItemListener > & l ) +{ + SolarMutexGuard aGuard; + maItemListeners.addInterface( l ); +} + +void VCLXRadioButton::removeItemListener( const css::uno::Reference< css::awt::XItemListener > & l ) +{ + SolarMutexGuard aGuard; + maItemListeners.removeInterface( l ); +} + +void VCLXRadioButton::addActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.addInterface( l ); +} + +void VCLXRadioButton::removeActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.removeInterface( l ); +} + +void VCLXRadioButton::setLabel( const OUString& rLabel ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + pWindow->SetText( rLabel ); +} + +void VCLXRadioButton::setActionCommand( const OUString& rCommand ) +{ + SolarMutexGuard aGuard; + maActionCommand = rCommand; +} + +void VCLXRadioButton::setState( sal_Bool b ) +{ + SolarMutexGuard aGuard; + + VclPtr< RadioButton > pRadioButton = GetAs< RadioButton >(); + if ( pRadioButton) + { + pRadioButton->Check( b ); + // #102717# item listeners are called, but not C++ click listeners in StarOffice code => call click hdl + // But this is needed in old code because Accessibility API uses it. + // pRadioButton->GetClickHdl().Call( pRadioButton ); + + // #107218# Call same virtual methods and listeners like VCL would do after user interaction + SetSynthesizingVCLEvent( true ); + pRadioButton->Click(); + SetSynthesizingVCLEvent( false ); + } +} + +sal_Bool VCLXRadioButton::getState() +{ + SolarMutexGuard aGuard; + + VclPtr< RadioButton > pRadioButton = GetAs< RadioButton >(); + return pRadioButton && pRadioButton->IsChecked(); +} + +css::awt::Size VCLXRadioButton::getMinimumSize( ) +{ + SolarMutexGuard aGuard; + + Size aSz; + VclPtr< RadioButton > pRadioButton = GetAs< RadioButton >(); + if ( pRadioButton ) + aSz = pRadioButton->CalcMinimumSize(); + return AWTSize(aSz); +} + +css::awt::Size VCLXRadioButton::getPreferredSize( ) +{ + return getMinimumSize(); +} + +css::awt::Size VCLXRadioButton::calcAdjustedSize( const css::awt::Size& rNewSize ) +{ + SolarMutexGuard aGuard; + + Size aSz = VCLSize(rNewSize); + VclPtr< RadioButton > pRadioButton = GetAs< RadioButton >(); + if ( pRadioButton ) + { + Size aMinSz = pRadioButton->CalcMinimumSize(rNewSize.Width); + if ( ( aSz.Width() > aMinSz.Width() ) && ( aSz.Height() < aMinSz.Height() ) ) + aSz.setHeight( aMinSz.Height() ); + else + aSz = aMinSz; + } + return AWTSize(aSz); +} + +void VCLXRadioButton::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + // since we call listeners below, there is a potential that we will be destroyed + // in during the listener call. To prevent the resulting crashes, we keep us + // alive as long as we're here + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::ButtonClick: + if ( !IsSynthesizingVCLEvent() && maActionListeners.getLength() ) + { + css::awt::ActionEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.ActionCommand = maActionCommand; + maActionListeners.actionPerformed( aEvent ); + } + ImplClickedOrToggled( false ); + break; + + case VclEventId::RadiobuttonToggle: + ImplClickedOrToggled( true ); + break; + + default: + VCLXGraphicControl::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + +void VCLXRadioButton::ImplClickedOrToggled( bool bToggled ) +{ + // In the forms, RadioChecked is not enabled, call itemStateChanged only for click + // In the dialog editor, RadioChecked is enabled, call itemStateChanged only for bToggled + VclPtr< RadioButton > pRadioButton = GetAs< RadioButton >(); + if ( pRadioButton && ( pRadioButton->IsRadioCheckEnabled() == bToggled ) && ( bToggled || pRadioButton->IsStateChanged() ) && maItemListeners.getLength() ) + { + css::awt::ItemEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.Highlighted = 0; + aEvent.Selected = pRadioButton->IsChecked() ? 1 : 0; + maItemListeners.itemStateChanged( aEvent ); + } +} + + + +void VCLXSpinField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, + 0 ); + VCLXEdit::ImplGetPropertyIds( rIds ); +} + +VCLXSpinField::VCLXSpinField() : maSpinListeners( *this ) +{ +} + +// css::uno::XInterface +css::uno::Any VCLXSpinField::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XSpinField* >(this) ); + return (aRet.hasValue() ? aRet : VCLXEdit::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXSpinField ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXSpinField::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XSpinField>::get(), + VCLXEdit::getTypes() + ); + return aTypeList.getTypes(); +} + +void VCLXSpinField::addSpinListener( const css::uno::Reference< css::awt::XSpinListener > & l ) +{ + SolarMutexGuard aGuard; + maSpinListeners.addInterface( l ); +} + +void VCLXSpinField::removeSpinListener( const css::uno::Reference< css::awt::XSpinListener > & l ) +{ + SolarMutexGuard aGuard; + maSpinListeners.removeInterface( l ); +} + +void VCLXSpinField::up() +{ + SolarMutexGuard aGuard; + + VclPtr< SpinField > pSpinField = GetAs< SpinField >(); + if ( pSpinField ) + pSpinField->Up(); +} + +void VCLXSpinField::down() +{ + SolarMutexGuard aGuard; + + VclPtr< SpinField > pSpinField = GetAs< SpinField >(); + if ( pSpinField ) + pSpinField->Down(); +} + +void VCLXSpinField::first() +{ + SolarMutexGuard aGuard; + + VclPtr< SpinField > pSpinField = GetAs< SpinField >(); + if ( pSpinField ) + pSpinField->First(); +} + +void VCLXSpinField::last() +{ + SolarMutexGuard aGuard; + + VclPtr< SpinField > pSpinField = GetAs< SpinField >(); + if ( pSpinField ) + pSpinField->Last(); +} + +void VCLXSpinField::enableRepeat( sal_Bool bRepeat ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + WinBits nStyle = pWindow->GetStyle(); + if ( bRepeat ) + nStyle |= WB_REPEAT; + else + nStyle &= ~WB_REPEAT; + pWindow->SetStyle( nStyle ); + } +} + +void VCLXSpinField::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::SpinfieldUp: + case VclEventId::SpinfieldDown: + case VclEventId::SpinfieldFirst: + case VclEventId::SpinfieldLast: + { + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + // since we call listeners below, there is a potential that we will be destroyed + // in during the listener call. To prevent the resulting crashes, we keep us + // alive as long as we're here + + if ( maSpinListeners.getLength() ) + { + css::awt::SpinEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::SpinfieldUp: maSpinListeners.up( aEvent ); + break; + case VclEventId::SpinfieldDown: maSpinListeners.down( aEvent ); + break; + case VclEventId::SpinfieldFirst: maSpinListeners.first( aEvent ); + break; + case VclEventId::SpinfieldLast: maSpinListeners.last( aEvent ); + break; + default: break; + } + + } + } + break; + + default: + VCLXEdit::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + + + +void VCLXListBox::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_DROPDOWN, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_LINECOUNT, + BASEPROPERTY_MULTISELECTION, + BASEPROPERTY_MULTISELECTION_SIMPLEMODE, + BASEPROPERTY_ITEM_SEPARATOR_POS, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_SELECTEDITEMS, + BASEPROPERTY_STRINGITEMLIST, + BASEPROPERTY_TYPEDITEMLIST, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_READONLY, + BASEPROPERTY_ALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_REFERENCE_DEVICE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, + 0); + VCLXWindow::ImplGetPropertyIds( rIds ); +} + + +VCLXListBox::VCLXListBox() + : maActionListeners( *this ), + maItemListeners( *this ) +{ +} + +void VCLXListBox::dispose() +{ + SolarMutexGuard aGuard; + + css::lang::EventObject aObj; + aObj.Source = static_cast<cppu::OWeakObject*>(this); + maItemListeners.disposeAndClear( aObj ); + maActionListeners.disposeAndClear( aObj ); + VCLXWindow::dispose(); +} + +void VCLXListBox::addItemListener( const css::uno::Reference< css::awt::XItemListener > & l ) +{ + SolarMutexGuard aGuard; + maItemListeners.addInterface( l ); +} + +void VCLXListBox::removeItemListener( const css::uno::Reference< css::awt::XItemListener > & l ) +{ + SolarMutexGuard aGuard; + maItemListeners.removeInterface( l ); +} + +void VCLXListBox::addActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.addInterface( l ); +} + +void VCLXListBox::removeActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.removeInterface( l ); +} + +void VCLXListBox::addItem( const OUString& aItem, sal_Int16 nPos ) +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + pBox->InsertEntry( aItem, nPos ); +} + +void VCLXListBox::addItems( const css::uno::Sequence< OUString>& aItems, sal_Int16 nPos ) +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( !pBox ) + return; + + sal_uInt16 nP = nPos; + for ( auto const & item : aItems ) + { + if ( nP == 0xFFFF ) + { + OSL_FAIL( "VCLXListBox::addItems: too many entries!" ); + // skip remaining entries, list cannot hold them, anyway + break; + } + + pBox->InsertEntry( item, nP++ ); + } +} + +void VCLXListBox::removeItems( sal_Int16 nPos, sal_Int16 nCount ) +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + { + for ( sal_Int16 n = nCount; n; ) + pBox->RemoveEntry( nPos + (--n) ); + } +} + +sal_Int16 VCLXListBox::getItemCount() +{ + SolarMutexGuard aGuard; + + VclPtr< ListBox > pBox = GetAs< ListBox >(); + return pBox ? pBox->GetEntryCount() : 0; +} + +OUString VCLXListBox::getItem( sal_Int16 nPos ) +{ + SolarMutexGuard aGuard; + + OUString aItem; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + aItem = pBox->GetEntry( nPos ); + return aItem; +} + +css::uno::Sequence< OUString> VCLXListBox::getItems() +{ + SolarMutexGuard aGuard; + + css::uno::Sequence< OUString> aSeq; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + { + auto n = pBox->GetEntryCount(); + aSeq = css::uno::Sequence< OUString>( n ); + while (n) + { + --n; + aSeq.getArray()[n] = pBox->GetEntry( n ); + } + } + return aSeq; +} + +sal_Int16 VCLXListBox::getSelectedItemPos() +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + return pBox ? pBox->GetSelectedEntryPos() : 0; +} + +css::uno::Sequence<sal_Int16> VCLXListBox::getSelectedItemsPos() +{ + SolarMutexGuard aGuard; + + css::uno::Sequence<sal_Int16> aSeq; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + { + const sal_Int32 nSelEntries = pBox->GetSelectedEntryCount(); + aSeq = css::uno::Sequence<sal_Int16>( nSelEntries ); + for ( sal_Int32 n = 0; n < nSelEntries; ++n ) + aSeq.getArray()[n] = pBox->GetSelectedEntryPos( n ); + } + return aSeq; +} + +OUString VCLXListBox::getSelectedItem() +{ + SolarMutexGuard aGuard; + + OUString aItem; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + aItem = pBox->GetSelectedEntry(); + return aItem; +} + +css::uno::Sequence< OUString> VCLXListBox::getSelectedItems() +{ + SolarMutexGuard aGuard; + + css::uno::Sequence< OUString> aSeq; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + { + const sal_Int32 nSelEntries = pBox->GetSelectedEntryCount(); + aSeq = css::uno::Sequence< OUString>( nSelEntries ); + for ( sal_Int32 n = 0; n < nSelEntries; ++n ) + aSeq.getArray()[n] = pBox->GetSelectedEntry( n ); + } + return aSeq; +} + +void VCLXListBox::selectItemPos( sal_Int16 nPos, sal_Bool bSelect ) +{ + SolarMutexGuard aGuard; + + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox && ( pBox->IsEntryPosSelected( nPos ) != bool(bSelect) ) ) + { + pBox->SelectEntryPos( nPos, bSelect ); + + // VCL doesn't call select handler after API call. + // ImplCallItemListeners(); + + // #107218# Call same listeners like VCL would do after user interaction + SetSynthesizingVCLEvent( true ); + pBox->Select(); + SetSynthesizingVCLEvent( false ); + } +} + +void VCLXListBox::selectItemsPos( const css::uno::Sequence<sal_Int16>& aPositions, sal_Bool bSelect ) +{ + SolarMutexGuard aGuard; + + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( !pBox ) + return; + + std::vector<sal_Int32> aPositionVec; + aPositionVec.reserve(aPositions.getLength()); + + bool bChanged = false; + for ( auto n = aPositions.getLength(); n; ) + { + const auto nPos = aPositions.getConstArray()[--n]; + if ( pBox->IsEntryPosSelected( nPos ) != bool(bSelect) ) + { + aPositionVec.push_back(nPos); + bChanged = true; + } + } + + if ( !bChanged ) + return; + + bool bOrigUpdateMode = pBox->IsUpdateMode(); + pBox->SetUpdateMode(false); + + pBox->SelectEntriesPos(aPositionVec, bSelect); + + pBox->SetUpdateMode(bOrigUpdateMode); + + // VCL doesn't call select handler after API call. + // ImplCallItemListeners(); + + // #107218# Call same listeners like VCL would do after user interaction + SetSynthesizingVCLEvent( true ); + pBox->Select(); + SetSynthesizingVCLEvent( false ); +} + +void VCLXListBox::selectItem( const OUString& rItemText, sal_Bool bSelect ) +{ + SolarMutexGuard aGuard; + + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + { + selectItemPos( pBox->GetEntryPos( rItemText ), bSelect ); + } +} + +void VCLXListBox::setDropDownLineCount( sal_Int16 nLines ) +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + pBox->SetDropDownLineCount( nLines ); +} + +sal_Int16 VCLXListBox::getDropDownLineCount() +{ + SolarMutexGuard aGuard; + + sal_Int16 nLines = 0; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + nLines = pBox->GetDropDownLineCount(); + return nLines; +} + +sal_Bool VCLXListBox::isMutipleMode() +{ + SolarMutexGuard aGuard; + bool bMulti = false; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + bMulti = pBox->IsMultiSelectionEnabled(); + return bMulti; +} + +void VCLXListBox::setMultipleMode( sal_Bool bMulti ) +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + pBox->EnableMultiSelection( bMulti ); +} + +void VCLXListBox::makeVisible( sal_Int16 nEntry ) +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + pBox->SetTopEntry( nEntry ); +} + +void VCLXListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + // since we call listeners below, there is a potential that we will be destroyed + // in during the listener call. To prevent the resulting crashes, we keep us + // alive as long as we're here + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::ListboxSelect: + { + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if( pListBox ) + { + bool bDropDown = ( pListBox->GetStyle() & WB_DROPDOWN ) != 0; + if ( bDropDown && !IsSynthesizingVCLEvent() && maActionListeners.getLength() ) + { + // Call ActionListener on DropDown event + css::awt::ActionEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.ActionCommand = pListBox->GetSelectedEntry(); + maActionListeners.actionPerformed( aEvent ); + } + + if ( maItemListeners.getLength() ) + { + ImplCallItemListeners(); + } + } + } + break; + + case VclEventId::ListboxDoubleClick: + if ( GetWindow() && maActionListeners.getLength() ) + { + css::awt::ActionEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.ActionCommand = GetAs<ListBox>()->GetSelectedEntry(); + maActionListeners.actionPerformed( aEvent ); + } + break; + + default: + VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXListBox::CreateAccessibleContext() +{ + SolarMutexGuard aGuard; + + return getAccessibleFactory().createAccessibleContext( this ); +} + +void VCLXListBox::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if ( !pListBox ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_ITEM_SEPARATOR_POS: + { + sal_Int16 nSeparatorPos(0); + if ( Value >>= nSeparatorPos ) + pListBox->SetSeparatorPos( nSeparatorPos ); + } + break; + case BASEPROPERTY_READONLY: + { + bool b = false; + if ( Value >>= b ) + pListBox->SetReadOnly( b); + } + break; + case BASEPROPERTY_MULTISELECTION: + { + bool b = false; + if ( Value >>= b ) + pListBox->EnableMultiSelection( b ); + } + break; + case BASEPROPERTY_MULTISELECTION_SIMPLEMODE: + ::toolkit::adjustBooleanWindowStyle( Value, pListBox, WB_SIMPLEMODE, false ); + break; + case BASEPROPERTY_LINECOUNT: + { + sal_Int16 n = 0; + if ( Value >>= n ) + pListBox->SetDropDownLineCount( n ); + } + break; + case BASEPROPERTY_STRINGITEMLIST: + { + css::uno::Sequence< OUString> aItems; + if ( Value >>= aItems ) + { + pListBox->Clear(); + addItems( aItems, 0 ); + } + } + break; + case BASEPROPERTY_SELECTEDITEMS: + { + css::uno::Sequence<sal_Int16> aItems; + if ( Value >>= aItems ) + { + for ( auto n = pListBox->GetEntryCount(); n; ) + pListBox->SelectEntryPos( --n, false ); + + if ( aItems.hasElements() ) + selectItemsPos( aItems, true ); + else + pListBox->SetNoSelection(); + + if ( !pListBox->GetSelectedEntryCount() ) + pListBox->SetTopEntry( 0 ); + } + } + break; + default: + { + VCLXWindow::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXListBox::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + css::uno::Any aProp; + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if ( pListBox ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_ITEM_SEPARATOR_POS: + aProp <<= sal_Int16( pListBox->GetSeparatorPos() ); + break; + case BASEPROPERTY_READONLY: + { + aProp <<= pListBox->IsReadOnly(); + } + break; + case BASEPROPERTY_MULTISELECTION: + { + aProp <<= pListBox->IsMultiSelectionEnabled(); + } + break; + case BASEPROPERTY_MULTISELECTION_SIMPLEMODE: + { + aProp <<= ( ( pListBox->GetStyle() & WB_SIMPLEMODE ) == 0 ); + } + break; + case BASEPROPERTY_LINECOUNT: + { + aProp <<= static_cast<sal_Int16>(pListBox->GetDropDownLineCount()); + } + break; + case BASEPROPERTY_STRINGITEMLIST: + { + const sal_Int32 nItems = pListBox->GetEntryCount(); + css::uno::Sequence< OUString> aSeq( nItems ); + OUString* pStrings = aSeq.getArray(); + for ( sal_Int32 n = 0; n < nItems; ++n ) + pStrings[n] = pListBox->GetEntry( n ); + aProp <<= aSeq; + + } + break; + default: + { + aProp = VCLXWindow::getProperty( PropertyName ); + } + } + } + return aProp; +} + +css::awt::Size VCLXListBox::getMinimumSize( ) +{ + SolarMutexGuard aGuard; + Size aSz; + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if ( pListBox ) + aSz = pListBox->CalcMinimumSize(); + return AWTSize(aSz); +} + +css::awt::Size VCLXListBox::getPreferredSize( ) +{ + SolarMutexGuard aGuard; + Size aSz; + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if ( pListBox ) + { + aSz = pListBox->CalcMinimumSize(); + if ( pListBox->GetStyle() & WB_DROPDOWN ) + aSz.AdjustHeight(4 ); + } + return AWTSize(aSz); +} + +css::awt::Size VCLXListBox::calcAdjustedSize( const css::awt::Size& rNewSize ) +{ + SolarMutexGuard aGuard; + Size aSz = VCLSize(rNewSize); + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if ( pListBox ) + aSz = pListBox->CalcAdjustedSize( aSz ); + return AWTSize(aSz); +} + +css::awt::Size VCLXListBox::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) +{ + SolarMutexGuard aGuard; + Size aSz; + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if ( pListBox ) + aSz = pListBox->CalcBlockSize( nCols, nLines ); + return AWTSize(aSz); +} + +void VCLXListBox::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) +{ + SolarMutexGuard aGuard; + nCols = nLines = 0; + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if ( pListBox ) + { + sal_uInt16 nC, nL; + pListBox->GetMaxVisColumnsAndLines( nC, nL ); + nCols = nC; + nLines = nL; + } +} + +void VCLXListBox::ImplCallItemListeners() +{ + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if ( pListBox && maItemListeners.getLength() ) + { + css::awt::ItemEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.Highlighted = 0; + + // Set to 0xFFFF on multiple selection, selected entry ID otherwise + aEvent.Selected = (pListBox->GetSelectedEntryCount() == 1 ) ? pListBox->GetSelectedEntryPos() : 0xFFFF; + + maItemListeners.itemStateChanged( aEvent ); + } +} +namespace +{ + Image lcl_getImageFromURL( const OUString& i_rImageURL ) + { + if ( i_rImageURL.isEmpty() ) + return Image(); + + try + { + Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); + Reference< XGraphicProvider > xProvider(graphic::GraphicProvider::create(xContext)); + ::comphelper::NamedValueCollection aMediaProperties; + aMediaProperties.put( "URL", i_rImageURL ); + Reference< XGraphic > xGraphic = xProvider->queryGraphic( aMediaProperties.getPropertyValues() ); + return Image( xGraphic ); + } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("toolkit"); + } + return Image(); + } +} +void SAL_CALL VCLXListBox::listItemInserted( const ItemListEvent& i_rEvent ) +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + + ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemInserted: no ListBox?!" ); + ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition <= pListBox->GetEntryCount() ), + "VCLXListBox::listItemInserted: illegal (inconsistent) item position!" ); + pListBox->InsertEntry( + i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : OUString(), + i_rEvent.ItemImageURL.IsPresent ? TkResMgr::getImageFromURL( i_rEvent.ItemImageURL.Value ) : Image(), + i_rEvent.ItemPosition ); +} + +void SAL_CALL VCLXListBox::listItemRemoved( const ItemListEvent& i_rEvent ) +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + + ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemRemoved: no ListBox?!" ); + ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < pListBox->GetEntryCount() ), + "VCLXListBox::listItemRemoved: illegal (inconsistent) item position!" ); + + pListBox->RemoveEntry( i_rEvent.ItemPosition ); +} + +void SAL_CALL VCLXListBox::listItemModified( const ItemListEvent& i_rEvent ) +{ + SolarMutexGuard aGuard; + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + + ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemModified: no ListBox?!" ); + ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < pListBox->GetEntryCount() ), + "VCLXListBox::listItemModified: illegal (inconsistent) item position!" ); + + // VCL's ListBox does not support changing an entry's text or image, so remove and re-insert + + const OUString sNewText = i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : pListBox->GetEntry( i_rEvent.ItemPosition ); + const Image aNewImage( i_rEvent.ItemImageURL.IsPresent ? TkResMgr::getImageFromURL( i_rEvent.ItemImageURL.Value ) : pListBox->GetEntryImage( i_rEvent.ItemPosition ) ); + + pListBox->RemoveEntry( i_rEvent.ItemPosition ); + pListBox->InsertEntry( sNewText, aNewImage, i_rEvent.ItemPosition ); +} + +void SAL_CALL VCLXListBox::allItemsRemoved( const EventObject& ) +{ + SolarMutexGuard aGuard; + + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemModified: no ListBox?!" ); + + pListBox->Clear(); +} + +void SAL_CALL VCLXListBox::itemListChanged( const EventObject& i_rEvent ) +{ + SolarMutexGuard aGuard; + + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemModified: no ListBox?!" ); + + pListBox->Clear(); + + uno::Reference< beans::XPropertySet > xPropSet( i_rEvent.Source, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySetInfo > xPSI( xPropSet->getPropertySetInfo(), uno::UNO_SET_THROW ); + uno::Reference< resource::XStringResourceResolver > xStringResourceResolver; + if ( xPSI->hasPropertyByName("ResourceResolver") ) + { + xStringResourceResolver.set( + xPropSet->getPropertyValue("ResourceResolver"), + uno::UNO_QUERY + ); + } + + + Reference< XItemList > xItemList( i_rEvent.Source, uno::UNO_QUERY_THROW ); + const uno::Sequence< beans::Pair< OUString, OUString > > aItems = xItemList->getAllItems(); + for ( const auto& rItem : aItems ) + { + OUString aLocalizationKey( rItem.First ); + if ( xStringResourceResolver.is() && aLocalizationKey.startsWith("&") ) + { + aLocalizationKey = xStringResourceResolver->resolveString(aLocalizationKey.copy( 1 )); + } + pListBox->InsertEntry( aLocalizationKey, lcl_getImageFromURL( rItem.Second ) ); + } +} + +void SAL_CALL VCLXListBox::disposing( const EventObject& i_rEvent ) +{ + // just disambiguate + VCLXWindow::disposing( i_rEvent ); +} + + + + +void VCLXMessageBox::GetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + VCLXTopWindow::ImplGetPropertyIds( rIds ); +} + +VCLXMessageBox::VCLXMessageBox() +{ +} + +VCLXMessageBox::~VCLXMessageBox() +{ +} + +// css::uno::XInterface +css::uno::Any VCLXMessageBox::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XMessageBox* >(this) ); + return (aRet.hasValue() ? aRet : VCLXTopWindow::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXMessageBox ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXMessageBox::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XMessageBox>::get(), + VCLXTopWindow::getTypes() + ); + return aTypeList.getTypes(); +} + +void VCLXMessageBox::setCaptionText( const OUString& rText ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + pWindow->SetText( rText ); +} + +OUString VCLXMessageBox::getCaptionText() +{ + SolarMutexGuard aGuard; + + OUString aText; + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + aText = pWindow->GetText(); + return aText; +} + +void VCLXMessageBox::setMessageText( const OUString& rText ) +{ + SolarMutexGuard aGuard; + VclPtr< MessBox > pBox = GetAs< MessBox >(); + if ( pBox ) + pBox->SetMessText( rText ); +} + +OUString VCLXMessageBox::getMessageText() +{ + SolarMutexGuard aGuard; + OUString aText; + VclPtr< MessBox > pBox = GetAs< MessBox >(); + if ( pBox ) + aText = pBox->GetMessText(); + return aText; +} + +sal_Int16 VCLXMessageBox::execute() +{ + SolarMutexGuard aGuard; + VclPtr< MessBox > pBox = GetAs< MessBox >(); + return pBox ? pBox->Execute() : 0; +} + +css::awt::Size SAL_CALL VCLXMessageBox::getMinimumSize() +{ + return css::awt::Size( 250, 100 ); +} + + + +void VCLXDialog::GetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + VCLXTopWindow::ImplGetPropertyIds( rIds ); +} + +VCLXDialog::VCLXDialog() +{ + SAL_INFO("toolkit", "XDialog created"); +} + +VCLXDialog::~VCLXDialog() +{ + SAL_INFO("toolkit", __FUNCTION__); +} + +// css::uno::XInterface +css::uno::Any VCLXDialog::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XDialog2* >(this), + static_cast< css::awt::XDialog* >(this) ); + return (aRet.hasValue() ? aRet : VCLXTopWindow::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXDialog ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXDialog::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XDialog2>::get(), + cppu::UnoType<css::awt::XDialog>::get(), + VCLXTopWindow::getTypes() + ); + return aTypeList.getTypes(); +} + +void SAL_CALL VCLXDialog::endDialog( ::sal_Int32 i_result ) +{ + SolarMutexGuard aGuard; + VclPtr<Dialog> pDialog = GetAsDynamic< Dialog >(); + if ( pDialog ) + pDialog->EndDialog( i_result ); +} + +void SAL_CALL VCLXDialog::setHelpId( const OUString& rId ) +{ + SolarMutexGuard aGuard; + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + pWindow->SetHelpId( OUStringToOString( rId, RTL_TEXTENCODING_UTF8 ) ); +} + +void VCLXDialog::setTitle( const OUString& Title ) +{ + SolarMutexGuard aGuard; + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + pWindow->SetText( Title ); +} + +OUString VCLXDialog::getTitle() +{ + SolarMutexGuard aGuard; + + OUString aTitle; + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + aTitle = pWindow->GetText(); + return aTitle; +} + +sal_Int16 VCLXDialog::execute() +{ + SolarMutexGuard aGuard; + + sal_Int16 nRet = 0; + if ( GetWindow() ) + { + VclPtr< Dialog > pDlg = GetAs< Dialog >(); + vcl::Window* pParent = pDlg->GetWindow( GetWindowType::ParentOverlap ); + vcl::Window* pOldParent = nullptr; + vcl::Window* pSetParent = nullptr; + if ( pParent && !pParent->IsReallyVisible() ) + { + pOldParent = pDlg->GetParent(); + vcl::Window* pFrame = pDlg->GetWindow( GetWindowType::Frame ); + if( pFrame != pDlg ) + { + pDlg->SetParent( pFrame ); + pSetParent = pFrame; + } + } + + nRet = pDlg->Execute(); + + // set the parent back only in case no new parent was set from outside + // in other words, revert only own changes + if ( pOldParent && pDlg->GetParent() == pSetParent ) + pDlg->SetParent( pOldParent ); + } + return nRet; +} + +void VCLXDialog::endExecute() +{ + endDialog(0); +} + +void SAL_CALL VCLXDialog::draw( sal_Int32 nX, sal_Int32 nY ) +{ + SolarMutexGuard aGuard; + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + { + OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() ); + if ( !pDev ) + pDev = pWindow->GetParent()->GetOutDev(); + + Point aPos = pDev->PixelToLogic( Point( nX, nY ) ); + pWindow->Draw( pDev, aPos, SystemTextColorFlags::NoControls ); + } +} + +css::awt::DeviceInfo VCLXDialog::getInfo() +{ + css::awt::DeviceInfo aInfo = VCLXDevice::getInfo(); + + SolarMutexGuard aGuard; + VclPtr< Dialog > pDlg = GetAs< Dialog >(); + if ( pDlg ) + pDlg->GetDrawWindowBorder( aInfo.LeftInset, aInfo.TopInset, aInfo.RightInset, aInfo.BottomInset ); + + return aInfo; +} + +void SAL_CALL VCLXDialog::setProperty( + const OUString& PropertyName, + const css::uno::Any& Value ) +{ + SolarMutexGuard aGuard; + VclPtr< Dialog > pDialog = GetAs< Dialog >(); + if ( !pDialog ) + return; + + bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_GRAPHIC: + { + Reference< XGraphic > xGraphic; + if (( Value >>= xGraphic ) && xGraphic.is() ) + { + Graphic aImage(xGraphic); + + Wallpaper aWallpaper(aImage.GetBitmapEx()); + aWallpaper.SetStyle( WallpaperStyle::Scale ); + pDialog->SetBackground( aWallpaper ); + } + else if ( bVoid || !xGraphic.is() ) + { + Color aColor = pDialog->GetControlBackground(); + if ( aColor == COL_AUTO ) + aColor = pDialog->GetSettings().GetStyleSettings().GetDialogColor(); + + Wallpaper aWallpaper( aColor ); + pDialog->SetBackground( aWallpaper ); + } + } + break; + + default: + { + VCLXContainer::setProperty( PropertyName, Value ); + } + } +} + + + +VCLXMultiPage::VCLXMultiPage() : maTabListeners( *this ), mTabId( 1 ) +{ + SAL_INFO("toolkit", "VCLXMultiPage::VCLXMultiPage()" ); +} + +void VCLXMultiPage::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_MULTIPAGEVALUE, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_GRAPHIC, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_IMAGEALIGN, + BASEPROPERTY_IMAGEPOSITION, + BASEPROPERTY_IMAGEURL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_FOCUSONCLICK, + 0); + VCLXContainer::ImplGetPropertyIds( rIds ); +} + +VCLXMultiPage::~VCLXMultiPage() +{ +} +void SAL_CALL VCLXMultiPage::dispose() +{ + SolarMutexGuard aGuard; + + css::lang::EventObject aObj; + aObj.Source = static_cast<cppu::OWeakObject*>(this); + maTabListeners.disposeAndClear( aObj ); + VCLXContainer::dispose(); +} +css::uno::Any SAL_CALL VCLXMultiPage::queryInterface(const css::uno::Type & rType ) +{ + uno::Any aRet = ::cppu::queryInterface( rType, static_cast< awt::XSimpleTabController*>( this ) ); + + return ( aRet.hasValue() ? aRet : VCLXContainer::queryInterface( rType ) ); +} +IMPL_IMPLEMENTATION_ID( VCLXMultiPage ) +// css::awt::XView +void SAL_CALL VCLXMultiPage::draw( sal_Int32 nX, sal_Int32 nY ) +{ + SolarMutexGuard aGuard; + VclPtr< vcl::Window > pWindow = GetWindow(); + + if ( pWindow ) + { + OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() ); + if ( !pDev ) + pDev = pWindow->GetParent()->GetOutDev(); + + Point aPos = pDev->PixelToLogic( Point( nX, nY ) ); + pWindow->Draw( pDev, aPos, SystemTextColorFlags::NoControls ); + } +} + +uno::Any SAL_CALL VCLXMultiPage::getProperty( const OUString& PropertyName ) +{ + SAL_INFO("toolkit", " **** VCLXMultiPage::getProperty " << PropertyName ); + SolarMutexGuard aGuard; + css::uno::Any aProp; + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + + case BASEPROPERTY_MULTIPAGEVALUE: + { + aProp <<= getActiveTabID(); + } + break; + default: + aProp = VCLXContainer::getProperty( PropertyName ); + } + return aProp; +} + +void SAL_CALL VCLXMultiPage::setProperty( + const OUString& PropertyName, + const css::uno::Any& Value ) +{ + SAL_INFO("toolkit", " **** VCLXMultiPage::setProperty " << PropertyName ); + SolarMutexGuard aGuard; + + VclPtr< TabControl > pTabControl = GetAs< TabControl >(); + if ( !pTabControl ) + return; + + bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_MULTIPAGEVALUE: + { + SAL_INFO("toolkit", "***MULTIPAGE VALUE"); + sal_Int32 nId(0); + Value >>= nId; + // when the multipage is created we attempt to set the activepage + // but no pages created + if ( nId && nId <= getWindows().getLength() ) + activateTab( nId ); + break; + } + case BASEPROPERTY_GRAPHIC: + { + Reference< XGraphic > xGraphic; + if (( Value >>= xGraphic ) && xGraphic.is() ) + { + Graphic aImage(xGraphic); + + Wallpaper aWallpaper(aImage.GetBitmapEx()); + aWallpaper.SetStyle( WallpaperStyle::Scale ); + pTabControl->SetBackground( aWallpaper ); + } + else if ( bVoid || !xGraphic.is() ) + { + Color aColor = pTabControl->GetControlBackground(); + if ( aColor == COL_AUTO ) + aColor = pTabControl->GetSettings().GetStyleSettings().GetDialogColor(); + + Wallpaper aWallpaper( aColor ); + pTabControl->SetBackground( aWallpaper ); + } + } + break; + + default: + { + VCLXContainer::setProperty( PropertyName, Value ); + } + } +} + +TabControl *VCLXMultiPage::getTabControl() const +{ + VclPtr<TabControl> pTabControl = GetAsDynamic< TabControl >(); + if ( pTabControl ) + return pTabControl; + throw uno::RuntimeException(); +} +sal_Int32 SAL_CALL VCLXMultiPage::insertTab() +{ + TabControl *pTabControl = getTabControl(); + VclPtrInstance<TabPage> pTab( pTabControl ); + return static_cast< sal_Int32 >( insertTab( pTab, OUString() ) ); +} + +sal_uInt16 VCLXMultiPage::insertTab( TabPage* pPage, OUString const & sTitle ) +{ + TabControl *pTabControl = getTabControl(); + sal_uInt16 id = sal::static_int_cast< sal_uInt16 >( mTabId++ ); + pTabControl->InsertPage( id, sTitle ); + pTabControl->SetTabPage( id, pPage ); + return id; +} + +void SAL_CALL VCLXMultiPage::removeTab( sal_Int32 ID ) +{ + TabControl *pTabControl = getTabControl(); + if ( pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >( ID ) ) == nullptr ) + throw lang::IndexOutOfBoundsException(); + pTabControl->RemovePage( sal::static_int_cast< sal_uInt16 >( ID ) ); +} + +void SAL_CALL VCLXMultiPage::activateTab( sal_Int32 ID ) +{ + TabControl *pTabControl = getTabControl(); + SAL_INFO( + "toolkit", + "Attempting to activate tab " << ID << ", active tab is " + << getActiveTabID() << ", numtabs is " << getWindows().getLength()); + if ( pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >( ID ) ) == nullptr ) + throw lang::IndexOutOfBoundsException(); + pTabControl->SelectTabPage( sal::static_int_cast< sal_uInt16 >( ID ) ); +} + +sal_Int32 SAL_CALL VCLXMultiPage::getActiveTabID() +{ + return getTabControl()->GetCurPageId( ); +} + +void SAL_CALL VCLXMultiPage::addTabListener( const uno::Reference< awt::XTabListener >& xListener ) +{ + SolarMutexGuard aGuard; + maTabListeners.addInterface( xListener ); +} + +void SAL_CALL VCLXMultiPage::removeTabListener( const uno::Reference< awt::XTabListener >& xListener ) +{ + SolarMutexGuard aGuard; + maTabListeners.addInterface( xListener ); +} + +void SAL_CALL VCLXMultiPage::setTabProps( sal_Int32 ID, const uno::Sequence< beans::NamedValue >& Properties ) +{ + SolarMutexGuard aGuard; + TabControl *pTabControl = getTabControl(); + if ( pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >( ID ) ) == nullptr ) + throw lang::IndexOutOfBoundsException(); + + for (const auto& rProp : Properties) + { + const OUString &name = rProp.Name; + const uno::Any &value = rProp.Value; + + if (name == "Title") + { + OUString title = value.get<OUString>(); + pTabControl->SetPageText( sal::static_int_cast< sal_uInt16 >( ID ), title ); + } + } +} + +uno::Sequence< beans::NamedValue > SAL_CALL VCLXMultiPage::getTabProps( sal_Int32 ID ) +{ + SolarMutexGuard aGuard; + TabControl *pTabControl = getTabControl(); + if ( pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >( ID ) ) == nullptr ) + throw lang::IndexOutOfBoundsException(); + + uno::Sequence< beans::NamedValue > props + { + { "Title", css::uno::Any(pTabControl->GetPageText( sal::static_int_cast< sal_uInt16 >( ID ) )) }, + { "Position", css::uno::Any(pTabControl->GetPagePos( sal::static_int_cast< sal_uInt16 >( ID ) )) } + }; + return props; +} +void VCLXMultiPage::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::TabpageDeactivate: + { + sal_uLong nPageID = reinterpret_cast<sal_uLong>( rVclWindowEvent.GetData() ); + maTabListeners.deactivated( nPageID ); + break; + + } + case VclEventId::TabpageActivate: + { + sal_uLong nPageID = reinterpret_cast<sal_uLong>( rVclWindowEvent.GetData() ); + maTabListeners.activated( nPageID ); + break; + } + default: + VCLXContainer::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + + + +VCLXTabPage::VCLXTabPage() +{ +} + +void VCLXTabPage::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_GRAPHIC, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_IMAGEALIGN, + BASEPROPERTY_IMAGEPOSITION, + BASEPROPERTY_IMAGEURL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_FOCUSONCLICK, + 0); + VCLXContainer::ImplGetPropertyIds( rIds ); +} + +VCLXTabPage::~VCLXTabPage() +{ +} + +IMPL_IMPLEMENTATION_ID( VCLXTabPage ) + +// css::awt::XView +void SAL_CALL VCLXTabPage::draw( sal_Int32 nX, sal_Int32 nY ) +{ + SolarMutexGuard aGuard; + VclPtr< vcl::Window > pWindow = GetWindow(); + + if ( pWindow ) + { + OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() ); + if ( !pDev ) + pDev = pWindow->GetParent()->GetOutDev(); + + Point aPos = pDev->PixelToLogic( Point( nX, nY ) ); + pWindow->Draw( pDev, aPos, SystemTextColorFlags::NoControls ); + } +} + +void SAL_CALL VCLXTabPage::setProperty( + const OUString& PropertyName, + const css::uno::Any& Value ) +{ + SolarMutexGuard aGuard; + VclPtr< TabPage > pTabPage = GetAs< TabPage >(); + if ( !pTabPage ) + return; + + bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_GRAPHIC: + { + Reference< XGraphic > xGraphic; + if (( Value >>= xGraphic ) && xGraphic.is() ) + { + Graphic aImage(xGraphic); + + Wallpaper aWallpaper(aImage.GetBitmapEx()); + aWallpaper.SetStyle( WallpaperStyle::Scale ); + pTabPage->SetBackground( aWallpaper ); + } + else if ( bVoid || !xGraphic.is() ) + { + Color aColor = pTabPage->GetControlBackground(); + if ( aColor == COL_AUTO ) + aColor = pTabPage->GetSettings().GetStyleSettings().GetDialogColor(); + + Wallpaper aWallpaper( aColor ); + pTabPage->SetBackground( aWallpaper ); + } + } + break; + case BASEPROPERTY_TITLE: + { + OUString sTitle; + if ( Value >>= sTitle ) + { + pTabPage->SetText(sTitle); + } + } + break; + + default: + { + VCLXContainer::setProperty( PropertyName, Value ); + } + } +} + +TabPage *VCLXTabPage::getTabPage() const +{ + VclPtr< TabPage > pTabPage = GetAsDynamic< TabPage >(); + if ( pTabPage ) + return pTabPage; + throw uno::RuntimeException(); +} + + + + +VCLXFixedHyperlink::VCLXFixedHyperlink() : + + maActionListeners( *this ) + +{ +} + +VCLXFixedHyperlink::~VCLXFixedHyperlink() +{ +} + +// css::uno::XInterface +css::uno::Any VCLXFixedHyperlink::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XFixedHyperlink* >(this) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +void VCLXFixedHyperlink::dispose() +{ + SolarMutexGuard aGuard; + + css::lang::EventObject aObj; + aObj.Source = static_cast<cppu::OWeakObject*>(this); + maActionListeners.disposeAndClear( aObj ); + VCLXWindow::dispose(); +} + +IMPL_IMPLEMENTATION_ID( VCLXFixedHyperlink ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXFixedHyperlink::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XFixedHyperlink>::get(), + VCLXWindow::getTypes() + ); + return aTypeList.getTypes(); +} + +void VCLXFixedHyperlink::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::ButtonClick: + { + if ( maActionListeners.getLength() ) + { + css::awt::ActionEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + maActionListeners.actionPerformed( aEvent ); + } + [[fallthrough]]; + } + default: + VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXFixedHyperlink::CreateAccessibleContext() +{ + return getAccessibleFactory().createAccessibleContext( this ); +} + +void VCLXFixedHyperlink::setText( const OUString& Text ) +{ + SolarMutexGuard aGuard; + VclPtr< FixedHyperlink > pBase = GetAs< FixedHyperlink >(); + if (pBase) + pBase->SetText(Text); +} + +OUString VCLXFixedHyperlink::getText() +{ + SolarMutexGuard aGuard; + + OUString aText; + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + aText = pWindow->GetText(); + return aText; +} + +void VCLXFixedHyperlink::setURL( const OUString& URL ) +{ + SolarMutexGuard aGuard; + VclPtr< FixedHyperlink > pBase = GetAs< FixedHyperlink >(); + if ( pBase ) + pBase->SetURL( URL ); +} + +OUString VCLXFixedHyperlink::getURL( ) +{ + SolarMutexGuard aGuard; + + OUString aText; + VclPtr< FixedHyperlink > pBase = GetAs< FixedHyperlink >(); + if ( pBase ) + aText = pBase->GetURL(); + return aText; +} + +void VCLXFixedHyperlink::setAlignment( sal_Int16 nAlign ) +{ + SolarMutexGuard aGuard; + + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( !pWindow ) + return; + + WinBits nNewBits = 0; + if ( nAlign == css::awt::TextAlign::LEFT ) + nNewBits = WB_LEFT; + else if ( nAlign == css::awt::TextAlign::CENTER ) + nNewBits = WB_CENTER; + else + nNewBits = WB_RIGHT; + + WinBits nStyle = pWindow->GetStyle(); + nStyle &= ~(WB_LEFT|WB_CENTER|WB_RIGHT); + pWindow->SetStyle( nStyle | nNewBits ); +} + +sal_Int16 VCLXFixedHyperlink::getAlignment() +{ + SolarMutexGuard aGuard; + + sal_Int16 nAlign = 0; + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + { + WinBits nStyle = pWindow->GetStyle(); + if ( nStyle & WB_LEFT ) + nAlign = css::awt::TextAlign::LEFT; + else if ( nStyle & WB_CENTER ) + nAlign = css::awt::TextAlign::CENTER; + else + nAlign = css::awt::TextAlign::RIGHT; + } + return nAlign; +} + +void VCLXFixedHyperlink::addActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.addInterface( l ); +} + +void VCLXFixedHyperlink::removeActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.removeInterface( l ); +} + +css::awt::Size VCLXFixedHyperlink::getMinimumSize( ) +{ + SolarMutexGuard aGuard; + Size aSz; + VclPtr< FixedText > pFixedText = GetAs< FixedText >(); + if ( pFixedText ) + aSz = pFixedText->CalcMinimumSize(); + return AWTSize(aSz); +} + +css::awt::Size VCLXFixedHyperlink::getPreferredSize( ) +{ + return getMinimumSize(); +} + +css::awt::Size VCLXFixedHyperlink::calcAdjustedSize( const css::awt::Size& rNewSize ) +{ + SolarMutexGuard aGuard; + Size aSz( VCLUnoHelper::ConvertToVCLSize( rNewSize )); + VclPtr< FixedText > pFixedText = GetAs< FixedText >(); + if (pFixedText) + { + Size aMinSz = pFixedText->CalcMinimumSize(rNewSize.Width); + if ( ( aSz.Width() > aMinSz.Width() ) && ( aSz.Height() < aMinSz.Height() ) ) + aSz.setHeight( aMinSz.Height() ); + else + aSz = aMinSz; + } + + return VCLUnoHelper::ConvertToAWTSize(aSz); +} + +void VCLXFixedHyperlink::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + VclPtr< FixedHyperlink > pBase = GetAs< FixedHyperlink >(); + if ( !pBase ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_LABEL: + { + OUString sNewLabel; + if ( Value >>= sNewLabel ) + pBase->SetText(sNewLabel); + break; + } + + case BASEPROPERTY_URL: + { + OUString sNewURL; + if ( Value >>= sNewURL ) + pBase->SetURL( sNewURL ); + break; + } + + default: + { + VCLXWindow::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXFixedHyperlink::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + VclPtr< FixedHyperlink > pBase = GetAs< FixedHyperlink >(); + if ( pBase ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_URL: + { + aProp <<= pBase->GetURL(); + break; + } + + default: + { + aProp = VCLXWindow::getProperty( PropertyName ); + } + } + } + return aProp; +} + +void VCLXFixedHyperlink::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_ALIGN, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_LABEL, + BASEPROPERTY_MULTILINE, + BASEPROPERTY_NOLABEL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_URL, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + 0); + VCLXWindow::ImplGetPropertyIds( rIds ); +} + + + +void VCLXFixedText::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_ALIGN, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_LABEL, + BASEPROPERTY_MULTILINE, + BASEPROPERTY_NOLABEL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_REFERENCE_DEVICE, + 0); + VCLXWindow::ImplGetPropertyIds( rIds ); +} + +VCLXFixedText::VCLXFixedText() +{ +} + +VCLXFixedText::~VCLXFixedText() +{ +} + +// css::uno::XInterface +css::uno::Any VCLXFixedText::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XFixedText* >(this) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXFixedText ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXFixedText::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XFixedText>::get(), + VCLXWindow::getTypes() + ); + return aTypeList.getTypes(); +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXFixedText::CreateAccessibleContext() +{ + return getAccessibleFactory().createAccessibleContext( this ); +} + +void VCLXFixedText::setText( const OUString& Text ) +{ + SolarMutexGuard aGuard; + + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + pWindow->SetText( Text ); +} + +OUString VCLXFixedText::getText() +{ + SolarMutexGuard aGuard; + + OUString aText; + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + aText = pWindow->GetText(); + return aText; +} + +void VCLXFixedText::setAlignment( sal_Int16 nAlign ) +{ + SolarMutexGuard aGuard; + + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( !pWindow ) + return; + + WinBits nNewBits = 0; + if ( nAlign == css::awt::TextAlign::LEFT ) + nNewBits = WB_LEFT; + else if ( nAlign == css::awt::TextAlign::CENTER ) + nNewBits = WB_CENTER; + else + nNewBits = WB_RIGHT; + + WinBits nStyle = pWindow->GetStyle(); + nStyle &= ~(WB_LEFT|WB_CENTER|WB_RIGHT); + pWindow->SetStyle( nStyle | nNewBits ); +} + +sal_Int16 VCLXFixedText::getAlignment() +{ + SolarMutexGuard aGuard; + + sal_Int16 nAlign = 0; + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + { + WinBits nStyle = pWindow->GetStyle(); + if ( nStyle & WB_LEFT ) + nAlign = css::awt::TextAlign::LEFT; + else if ( nStyle & WB_CENTER ) + nAlign = css::awt::TextAlign::CENTER; + else + nAlign = css::awt::TextAlign::RIGHT; + } + return nAlign; +} + +css::awt::Size VCLXFixedText::getMinimumSize( ) +{ + SolarMutexGuard aGuard; + + Size aSz; + VclPtr< FixedText > pFixedText = GetAs< FixedText >(); + if ( pFixedText ) + aSz = pFixedText->CalcMinimumSize(); + return AWTSize(aSz); +} + +css::awt::Size VCLXFixedText::getPreferredSize( ) +{ + return getMinimumSize(); +} + +css::awt::Size VCLXFixedText::calcAdjustedSize( const css::awt::Size& rMaxSize ) +{ + SolarMutexGuard aGuard; + + Size aAdjustedSize( VCLUnoHelper::ConvertToVCLSize( rMaxSize ) ); + VclPtr< FixedText > pFixedText = GetAs< FixedText >(); + if ( pFixedText ) + aAdjustedSize = pFixedText->CalcMinimumSize( rMaxSize.Width ); + return VCLUnoHelper::ConvertToAWTSize( aAdjustedSize ); +} + + + +void VCLXScrollBar::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BLOCKINCREMENT, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_LINEINCREMENT, + BASEPROPERTY_LIVE_SCROLL, + BASEPROPERTY_ORIENTATION, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_REPEAT_DELAY, + BASEPROPERTY_SCROLLVALUE, + BASEPROPERTY_SCROLLVALUE_MAX, + BASEPROPERTY_SCROLLVALUE_MIN, + BASEPROPERTY_SYMBOL_COLOR, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_VISIBLESIZE, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + 0); + VCLXWindow::ImplGetPropertyIds( rIds ); +} + +VCLXScrollBar::VCLXScrollBar() : maAdjustmentListeners( *this ) +{ +} + +// css::uno::XInterface +css::uno::Any VCLXScrollBar::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XScrollBar* >(this) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXScrollBar ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXScrollBar::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XScrollBar>::get(), + VCLXWindow::getTypes() + ); + return aTypeList.getTypes(); +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXScrollBar::CreateAccessibleContext() +{ + return getAccessibleFactory().createAccessibleContext( this ); +} + +// css::lang::XComponent +void VCLXScrollBar::dispose() +{ + SolarMutexGuard aGuard; + + css::lang::EventObject aObj; + aObj.Source = static_cast<cppu::OWeakObject*>(this); + maAdjustmentListeners.disposeAndClear( aObj ); + VCLXWindow::dispose(); +} + +// css::awt::XScrollbar +void VCLXScrollBar::addAdjustmentListener( const css::uno::Reference< css::awt::XAdjustmentListener > & l ) +{ + SolarMutexGuard aGuard; + maAdjustmentListeners.addInterface( l ); +} + +void VCLXScrollBar::removeAdjustmentListener( const css::uno::Reference< css::awt::XAdjustmentListener > & l ) +{ + SolarMutexGuard aGuard; + maAdjustmentListeners.removeInterface( l ); +} + +void VCLXScrollBar::setValue( sal_Int32 n ) +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + if ( pScrollBar ) + pScrollBar->DoScroll( n ); +} + +void VCLXScrollBar::setValues( sal_Int32 nValue, sal_Int32 nVisible, sal_Int32 nMax ) +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + if ( pScrollBar ) + { + pScrollBar->SetVisibleSize( nVisible ); + pScrollBar->SetRangeMax( nMax ); + pScrollBar->DoScroll( nValue ); + } +} + +sal_Int32 VCLXScrollBar::getValue() +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + return pScrollBar ? pScrollBar->GetThumbPos() : 0; +} + +void VCLXScrollBar::setMaximum( sal_Int32 n ) +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + if ( pScrollBar ) + pScrollBar->SetRangeMax( n ); +} + +sal_Int32 VCLXScrollBar::getMaximum() +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + return pScrollBar ? pScrollBar->GetRangeMax() : 0; +} + +void VCLXScrollBar::setMinimum( sal_Int32 n ) +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + if ( pScrollBar ) + pScrollBar->SetRangeMin( n ); +} + +sal_Int32 VCLXScrollBar::getMinimum() const +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + return pScrollBar ? pScrollBar->GetRangeMin() : 0; +} + +void VCLXScrollBar::setLineIncrement( sal_Int32 n ) +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + if ( pScrollBar ) + pScrollBar->SetLineSize( n ); +} + +sal_Int32 VCLXScrollBar::getLineIncrement() +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + return pScrollBar ? pScrollBar->GetLineSize() : 0; +} + +void VCLXScrollBar::setBlockIncrement( sal_Int32 n ) +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + if ( pScrollBar ) + pScrollBar->SetPageSize( n ); +} + +sal_Int32 VCLXScrollBar::getBlockIncrement() +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + return pScrollBar ? pScrollBar->GetPageSize() : 0; +} + +void VCLXScrollBar::setVisibleSize( sal_Int32 n ) +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + if ( pScrollBar ) + pScrollBar->SetVisibleSize( n ); +} + +sal_Int32 VCLXScrollBar::getVisibleSize() +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + return pScrollBar ? pScrollBar->GetVisibleSize() : 0; +} + +void VCLXScrollBar::setOrientation( sal_Int32 n ) +{ + SolarMutexGuard aGuard; + + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + { + WinBits nStyle = pWindow->GetStyle(); + nStyle &= ~(WB_HORZ|WB_VERT); + if ( n == css::awt::ScrollBarOrientation::HORIZONTAL ) + nStyle |= WB_HORZ; + else + nStyle |= WB_VERT; + + pWindow->SetStyle( nStyle ); + pWindow->Resize(); + } +} + +sal_Int32 VCLXScrollBar::getOrientation() +{ + SolarMutexGuard aGuard; + + sal_Int32 n = 0; + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + { + WinBits nStyle = pWindow->GetStyle(); + if ( nStyle & WB_HORZ ) + n = css::awt::ScrollBarOrientation::HORIZONTAL; + else + n = css::awt::ScrollBarOrientation::VERTICAL; + } + return n; + +} + +// css::awt::VclWindowPeer +void VCLXScrollBar::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + if ( !pScrollBar ) + return; + + bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_LIVE_SCROLL: + { + bool bDo = false; + if ( !bVoid ) + { + OSL_VERIFY( Value >>= bDo ); + } + AllSettings aSettings( pScrollBar->GetSettings() ); + StyleSettings aStyle( aSettings.GetStyleSettings() ); + DragFullOptions nDragOptions = aStyle.GetDragFullOptions(); + if ( bDo ) + nDragOptions |= DragFullOptions::Scroll; + else + nDragOptions &= ~DragFullOptions::Scroll; + aStyle.SetDragFullOptions( nDragOptions ); + aSettings.SetStyleSettings( aStyle ); + pScrollBar->SetSettings( aSettings ); + } + break; + + case BASEPROPERTY_SCROLLVALUE: + { + if ( !bVoid ) + { + sal_Int32 n = 0; + if ( Value >>= n ) + setValue( n ); + } + } + break; + case BASEPROPERTY_SCROLLVALUE_MAX: + case BASEPROPERTY_SCROLLVALUE_MIN: + { + if ( !bVoid ) + { + sal_Int32 n = 0; + if ( Value >>= n ) + { + if ( nPropType == BASEPROPERTY_SCROLLVALUE_MAX ) + setMaximum( n ); + else + setMinimum( n ); + } + } + } + break; + case BASEPROPERTY_LINEINCREMENT: + { + if ( !bVoid ) + { + sal_Int32 n = 0; + if ( Value >>= n ) + setLineIncrement( n ); + } + } + break; + case BASEPROPERTY_BLOCKINCREMENT: + { + if ( !bVoid ) + { + sal_Int32 n = 0; + if ( Value >>= n ) + setBlockIncrement( n ); + } + } + break; + case BASEPROPERTY_VISIBLESIZE: + { + if ( !bVoid ) + { + sal_Int32 n = 0; + if ( Value >>= n ) + setVisibleSize( n ); + } + } + break; + case BASEPROPERTY_ORIENTATION: + { + if ( !bVoid ) + { + sal_Int32 n = 0; + if ( Value >>= n ) + setOrientation( n ); + } + } + break; + + case BASEPROPERTY_BACKGROUNDCOLOR: + { + // the default implementation of the base class doesn't work here, since our + // interpretation for this property is slightly different + ::toolkit::setButtonLikeFaceColor( pScrollBar, Value); + } + break; + + default: + { + VCLXWindow::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXScrollBar::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + if ( pScrollBar ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + + switch ( nPropType ) + { + case BASEPROPERTY_LIVE_SCROLL: + { + aProp <<= bool( pScrollBar->GetSettings().GetStyleSettings().GetDragFullOptions() & DragFullOptions::Scroll ); + } + break; + case BASEPROPERTY_SCROLLVALUE: + { + aProp <<= getValue(); + } + break; + case BASEPROPERTY_SCROLLVALUE_MAX: + { + aProp <<= getMaximum(); + } + break; + case BASEPROPERTY_SCROLLVALUE_MIN: + { + aProp <<= getMinimum(); + } + break; + case BASEPROPERTY_LINEINCREMENT: + { + aProp <<= getLineIncrement(); + } + break; + case BASEPROPERTY_BLOCKINCREMENT: + { + aProp <<= getBlockIncrement(); + } + break; + case BASEPROPERTY_VISIBLESIZE: + { + aProp <<= getVisibleSize(); + } + break; + case BASEPROPERTY_ORIENTATION: + { + aProp <<= getOrientation(); + } + break; + case BASEPROPERTY_BACKGROUNDCOLOR: + { + // the default implementation of the base class doesn't work here, since our + // interpretation for this property is slightly different + aProp = ::toolkit::getButtonLikeFaceColor( pScrollBar ); + } + break; + + default: + { + aProp = VCLXWindow::getProperty( PropertyName ); + } + } + } + return aProp; +} + +void VCLXScrollBar::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::ScrollbarScroll: + { + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + // since we call listeners below, there is a potential that we will be destroyed + // in during the listener call. To prevent the resulting crashes, we keep us + // alive as long as we're here + + if ( maAdjustmentListeners.getLength() ) + { + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + + if( pScrollBar ) + { + css::awt::AdjustmentEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.Value = pScrollBar->GetThumbPos(); + + // set adjustment type + ScrollType aType = pScrollBar->GetType(); + if ( aType == ScrollType::LineUp || aType == ScrollType::LineDown ) + { + aEvent.Type = css::awt::AdjustmentType_ADJUST_LINE; + } + else if ( aType == ScrollType::PageUp || aType == ScrollType::PageDown ) + { + aEvent.Type = css::awt::AdjustmentType_ADJUST_PAGE; + } + else if ( aType == ScrollType::Drag ) + { + aEvent.Type = css::awt::AdjustmentType_ADJUST_ABS; + } + + maAdjustmentListeners.adjustmentValueChanged( aEvent ); + } + } + } + break; + + default: + VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + +css::awt::Size VCLXScrollBar::implGetMinimumSize( vcl::Window const * p ) +{ + tools::Long n = p->GetSettings().GetStyleSettings().GetScrollBarSize(); + return css::awt::Size( n, n ); +} + +css::awt::Size SAL_CALL VCLXScrollBar::getMinimumSize() +{ + SolarMutexGuard aGuard; + return implGetMinimumSize( GetWindow() ); +} + + + + +void VCLXEdit::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_ALIGN, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ECHOCHAR, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HARDLINEBREAKS, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_HSCROLL, + BASEPROPERTY_LINE_END_FORMAT, + BASEPROPERTY_MAXTEXTLEN, + BASEPROPERTY_MULTILINE, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_READONLY, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_TEXT, + BASEPROPERTY_VSCROLL, + BASEPROPERTY_HIDEINACTIVESELECTION, + BASEPROPERTY_PAINTTRANSPARENT, + BASEPROPERTY_AUTOHSCROLL, + BASEPROPERTY_AUTOVSCROLL, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + 0); + VCLXWindow::ImplGetPropertyIds( rIds ); +} + +VCLXEdit::VCLXEdit() : maTextListeners( *this ) +{ +} + +// css::uno::XInterface +css::uno::Any VCLXEdit::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XTextComponent* >(this), + static_cast< css::awt::XTextEditField* >(this), + static_cast< css::awt::XTextLayoutConstrains* >(this) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXEdit ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXEdit::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XTextComponent>::get(), + cppu::UnoType<css::awt::XTextEditField>::get(), + cppu::UnoType<css::awt::XTextLayoutConstrains>::get(), + VCLXWindow::getTypes() + ); + return aTypeList.getTypes(); +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXEdit::CreateAccessibleContext() +{ + return getAccessibleFactory().createAccessibleContext( this ); +} + +void VCLXEdit::dispose() +{ + SolarMutexGuard aGuard; + + css::lang::EventObject aObj; + aObj.Source = static_cast<cppu::OWeakObject*>(this); + maTextListeners.disposeAndClear( aObj ); + VCLXWindow::dispose(); +} + +void VCLXEdit::addTextListener( const css::uno::Reference< css::awt::XTextListener > & l ) +{ + SolarMutexGuard aGuard; + GetTextListeners().addInterface( l ); +} + +void VCLXEdit::removeTextListener( const css::uno::Reference< css::awt::XTextListener > & l ) +{ + SolarMutexGuard aGuard; + GetTextListeners().removeInterface( l ); +} + +void VCLXEdit::setText( const OUString& aText ) +{ + SolarMutexGuard aGuard; + + VclPtr< Edit > pEdit = GetAs< Edit >(); + 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 VCLXEdit::insertText( const css::awt::Selection& rSel, const OUString& aText ) +{ + SolarMutexGuard aGuard; + + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + { + pEdit->SetSelection( Selection( rSel.Min, rSel.Max ) ); + pEdit->ReplaceSelected( aText ); + + // #107218# Call same listeners like VCL would do after user interaction + SetSynthesizingVCLEvent( true ); + pEdit->SetModifyFlag(); + pEdit->Modify(); + SetSynthesizingVCLEvent( false ); + } +} + +OUString VCLXEdit::getText() +{ + SolarMutexGuard aGuard; + + OUString aText; + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + aText = pWindow->GetText(); + return aText; +} + +OUString VCLXEdit::getSelectedText() +{ + SolarMutexGuard aGuard; + + OUString aText; + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit) + aText = pEdit->GetSelected(); + return aText; + +} + +void VCLXEdit::setSelection( const css::awt::Selection& aSelection ) +{ + SolarMutexGuard aGuard; + + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + pEdit->SetSelection( Selection( aSelection.Min, aSelection.Max ) ); +} + +css::awt::Selection VCLXEdit::getSelection() +{ + SolarMutexGuard aGuard; + + Selection aSel; + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + aSel = pEdit->GetSelection(); + return css::awt::Selection( aSel.Min(), aSel.Max() ); +} + +sal_Bool VCLXEdit::isEditable() +{ + SolarMutexGuard aGuard; + + VclPtr< Edit > pEdit = GetAs< Edit >(); + return pEdit && !pEdit->IsReadOnly() && pEdit->IsEnabled(); +} + +void VCLXEdit::setEditable( sal_Bool bEditable ) +{ + SolarMutexGuard aGuard; + + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + pEdit->SetReadOnly( !bEditable ); +} + + +void VCLXEdit::setMaxTextLen( sal_Int16 nLen ) +{ + SolarMutexGuard aGuard; + + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + pEdit->SetMaxTextLen( nLen ); +} + +sal_Int16 VCLXEdit::getMaxTextLen() +{ + SolarMutexGuard aGuard; + + VclPtr< Edit > pEdit = GetAs< Edit >(); + return pEdit ? pEdit->GetMaxTextLen() : 0; +} + +void VCLXEdit::setEchoChar( sal_Unicode cEcho ) +{ + SolarMutexGuard aGuard; + + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + pEdit->SetEchoChar( cEcho ); +} + +void VCLXEdit::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( !pEdit ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_HIDEINACTIVESELECTION: + ::toolkit::adjustBooleanWindowStyle( Value, pEdit, WB_NOHIDESELECTION, true ); + if ( pEdit->GetSubEdit() ) + ::toolkit::adjustBooleanWindowStyle( Value, pEdit->GetSubEdit(), WB_NOHIDESELECTION, true ); + break; + + case BASEPROPERTY_READONLY: + { + bool b = bool(); + if ( Value >>= b ) + pEdit->SetReadOnly( b ); + } + break; + case BASEPROPERTY_ECHOCHAR: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + pEdit->SetEchoChar( n ); + } + break; + case BASEPROPERTY_MAXTEXTLEN: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + pEdit->SetMaxTextLen( n ); + } + break; + default: + { + VCLXWindow::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXEdit::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_HIDEINACTIVESELECTION: + aProp <<= ( ( pEdit->GetStyle() & WB_NOHIDESELECTION ) == 0 ); + break; + case BASEPROPERTY_READONLY: + aProp <<= pEdit->IsReadOnly(); + break; + case BASEPROPERTY_ECHOCHAR: + aProp <<= static_cast<sal_Int16>(pEdit->GetEchoChar()); + break; + case BASEPROPERTY_MAXTEXTLEN: + aProp <<= static_cast<sal_Int16>(pEdit->GetMaxTextLen()); + break; + default: + { + aProp = VCLXWindow::getProperty( PropertyName ); + } + } + } + return aProp; +} + +css::awt::Size VCLXEdit::getMinimumSize( ) +{ + SolarMutexGuard aGuard; + + Size aSz; + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + aSz = pEdit->CalcMinimumSize(); + return AWTSize(aSz); +} + +css::awt::Size VCLXEdit::getPreferredSize( ) +{ + SolarMutexGuard aGuard; + + Size aSz; + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + { + aSz = pEdit->CalcMinimumSize(); + aSz.AdjustHeight(4 ); + } + return AWTSize(aSz); +} + +css::awt::Size VCLXEdit::calcAdjustedSize( const css::awt::Size& rNewSize ) +{ + SolarMutexGuard aGuard; + + css::awt::Size aSz = rNewSize; + css::awt::Size aMinSz = getMinimumSize(); + if ( aSz.Height != aMinSz.Height ) + aSz.Height = aMinSz.Height; + + return aSz; +} + +css::awt::Size VCLXEdit::getMinimumSize( sal_Int16 nCols, sal_Int16 ) +{ + SolarMutexGuard aGuard; + + Size aSz; + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + { + if ( nCols ) + aSz = pEdit->CalcSize( nCols ); + else + aSz = pEdit->CalcMinimumSize(); + } + return AWTSize(aSz); +} + +void VCLXEdit::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) +{ + SolarMutexGuard aGuard; + + nLines = 1; + nCols = 0; + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + nCols = pEdit->GetMaxVisChars(); +} + +void VCLXEdit::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::EditModify: + { + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + // since we call listeners below, there is a potential that we will be destroyed + // during the listener call. To prevent the resulting crashes, we keep us + // alive as long as we're here + + if ( GetTextListeners().getLength() ) + { + css::awt::TextEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + GetTextListeners().textChanged( aEvent ); + } + } + break; + + default: + VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + + + + +void VCLXComboBox::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_AUTOCOMPLETE, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_DROPDOWN, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_LINECOUNT, + BASEPROPERTY_MAXTEXTLEN, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_READONLY, + BASEPROPERTY_STRINGITEMLIST, + BASEPROPERTY_TYPEDITEMLIST, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_TEXT, + BASEPROPERTY_HIDEINACTIVESELECTION, + BASEPROPERTY_ALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_REFERENCE_DEVICE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, + 0); + // no, don't call VCLXEdit here - it has properties which we do *not* want to have at combo box + // #i92690# / 2008-08-12 / frank.schoenheit@sun.com + // VCLXEdit::ImplGetPropertyIds( rIds ); + VCLXWindow::ImplGetPropertyIds( rIds ); +} + +VCLXComboBox::VCLXComboBox() + : maActionListeners( *this ), maItemListeners( *this ) +{ +} + +VCLXComboBox::~VCLXComboBox() +{ + SAL_INFO("toolkit", __FUNCTION__); +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXComboBox::CreateAccessibleContext() +{ + SolarMutexGuard aGuard; + + return getAccessibleFactory().createAccessibleContext( this ); +} + +void VCLXComboBox::dispose() +{ + SolarMutexGuard aGuard; + + css::lang::EventObject aObj; + aObj.Source = static_cast<cppu::OWeakObject*>(this); + maItemListeners.disposeAndClear( aObj ); + maActionListeners.disposeAndClear( aObj ); + VCLXEdit::dispose(); +} + + +void VCLXComboBox::addItemListener( const css::uno::Reference< css::awt::XItemListener > & l ) +{ + SolarMutexGuard aGuard; + maItemListeners.addInterface( l ); +} + +void VCLXComboBox::removeItemListener( const css::uno::Reference< css::awt::XItemListener > & l ) +{ + SolarMutexGuard aGuard; + maItemListeners.removeInterface( l ); +} + +void VCLXComboBox::addActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.addInterface( l ); +} + +void VCLXComboBox::removeActionListener( const css::uno::Reference< css::awt::XActionListener > & l ) +{ + SolarMutexGuard aGuard; + maActionListeners.removeInterface( l ); +} + +void VCLXComboBox::addItem( const OUString& aItem, sal_Int16 nPos ) +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( pBox ) + pBox->InsertEntry( aItem, nPos ); +} + +void VCLXComboBox::addItems( const css::uno::Sequence< OUString>& aItems, sal_Int16 nPos ) +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( !pBox ) + return; + + sal_uInt16 nP = nPos; + for ( const auto& rItem : aItems ) + { + pBox->InsertEntry( rItem, nP ); + if ( nP == 0xFFFF ) + { + OSL_FAIL( "VCLXComboBox::addItems: too many entries!" ); + // skip remaining entries, list cannot hold them, anyway + break; + } + } +} + +void VCLXComboBox::removeItems( sal_Int16 nPos, sal_Int16 nCount ) +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( pBox ) + { + for ( sal_uInt16 n = nCount; n; ) + pBox->RemoveEntryAt( nPos + (--n) ); + } +} + +sal_Int16 VCLXComboBox::getItemCount() +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + return pBox ? pBox->GetEntryCount() : 0; +} + +OUString VCLXComboBox::getItem( sal_Int16 nPos ) +{ + SolarMutexGuard aGuard; + + OUString aItem; + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( pBox ) + aItem = pBox->GetEntry( nPos ); + return aItem; +} + +css::uno::Sequence< OUString> VCLXComboBox::getItems() +{ + SolarMutexGuard aGuard; + + css::uno::Sequence< OUString> aSeq; + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( pBox ) + { + auto n = pBox->GetEntryCount(); + aSeq = css::uno::Sequence< OUString>( n ); + while ( n ) + { + --n; + aSeq.getArray()[n] = pBox->GetEntry( n ); + } + } + return aSeq; +} + +void VCLXComboBox::setDropDownLineCount( sal_Int16 nLines ) +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( pBox ) + pBox->SetDropDownLineCount( nLines ); +} + +sal_Int16 VCLXComboBox::getDropDownLineCount() +{ + SolarMutexGuard aGuard; + + sal_Int16 nLines = 0; + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( pBox ) + nLines = pBox->GetDropDownLineCount(); + return nLines; +} + +void VCLXComboBox::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if ( !pComboBox ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_LINECOUNT: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + pComboBox->SetDropDownLineCount( n ); + } + break; + case BASEPROPERTY_AUTOCOMPLETE: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + pComboBox->EnableAutocomplete( n != 0 ); + else + { + bool b = bool(); + if ( Value >>= b ) + pComboBox->EnableAutocomplete( b ); + } + } + break; + case BASEPROPERTY_STRINGITEMLIST: + { + css::uno::Sequence< OUString> aItems; + if ( Value >>= aItems ) + { + pComboBox->Clear(); + addItems( aItems, 0 ); + } + } + break; + default: + { + VCLXEdit::setProperty( PropertyName, Value ); + + // #109385# SetBorderStyle is not virtual + if ( nPropType == BASEPROPERTY_BORDER ) + { + sal_uInt16 nBorder = sal_uInt16(); + if ( (Value >>= nBorder) && nBorder != 0 ) + pComboBox->SetBorderStyle( static_cast<WindowBorderStyle>(nBorder) ); + } + } + } +} + +css::uno::Any VCLXComboBox::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if ( pComboBox ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_LINECOUNT: + { + aProp <<= static_cast<sal_Int16>(pComboBox->GetDropDownLineCount()); + } + break; + case BASEPROPERTY_AUTOCOMPLETE: + { + aProp <<= pComboBox->IsAutocompleteEnabled(); + } + break; + case BASEPROPERTY_STRINGITEMLIST: + { + const sal_Int32 nItems = pComboBox->GetEntryCount(); + css::uno::Sequence< OUString> aSeq( nItems ); + OUString* pStrings = aSeq.getArray(); + for ( sal_Int32 n = 0; n < nItems; ++n ) + pStrings[n] = pComboBox->GetEntry( n ); + aProp <<= aSeq; + + } + break; + default: + { + aProp = VCLXEdit::getProperty( PropertyName ); + } + } + } + return aProp; +} + +void VCLXComboBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + // since we call listeners below, there is a potential that we will be destroyed + // during the listener call. To prevent the resulting crashes, we keep us + // alive as long as we're here + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::ComboboxSelect: + if ( maItemListeners.getLength() ) + { + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if( pComboBox ) + { + if ( !pComboBox->IsTravelSelect() ) + { + css::awt::ItemEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); + aEvent.Highlighted = 0; + + // Set to 0xFFFF on multiple selection, selected entry ID otherwise + aEvent.Selected = pComboBox->GetEntryPos( pComboBox->GetText() ); + + maItemListeners.itemStateChanged( aEvent ); + } + } + } + break; + + case VclEventId::ComboboxDoubleClick: + if ( maActionListeners.getLength() ) + { + css::awt::ActionEvent aEvent; + aEvent.Source = static_cast<cppu::OWeakObject*>(this); +// aEvent.ActionCommand = ...; + maActionListeners.actionPerformed( aEvent ); + } + break; + + default: + VCLXEdit::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + +css::awt::Size VCLXComboBox::getMinimumSize( ) +{ + SolarMutexGuard aGuard; + + Size aSz; + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if ( pComboBox ) + aSz = pComboBox->CalcMinimumSize(); + return AWTSize(aSz); +} + +css::awt::Size VCLXComboBox::getPreferredSize( ) +{ + SolarMutexGuard aGuard; + + Size aSz; + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if ( pComboBox ) + { + aSz = pComboBox->CalcMinimumSize(); + if ( pComboBox->GetStyle() & WB_DROPDOWN ) + aSz.AdjustHeight(4 ); + } + return AWTSize(aSz); +} + +css::awt::Size VCLXComboBox::calcAdjustedSize( const css::awt::Size& rNewSize ) +{ + SolarMutexGuard aGuard; + + Size aSz = VCLSize(rNewSize); + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if ( pComboBox ) + aSz = pComboBox->CalcAdjustedSize( aSz ); + return AWTSize(aSz); +} + +css::awt::Size VCLXComboBox::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) +{ + SolarMutexGuard aGuard; + + Size aSz; + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if ( pComboBox ) + aSz = pComboBox->CalcBlockSize( nCols, nLines ); + return AWTSize(aSz); +} + +void VCLXComboBox::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) +{ + SolarMutexGuard aGuard; + + nCols = nLines = 0; + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if ( pComboBox ) + { + sal_uInt16 nC, nL; + pComboBox->GetMaxVisColumnsAndLines( nC, nL ); + nCols = nC; + nLines = nL; + } +} +void SAL_CALL VCLXComboBox::listItemInserted( const ItemListEvent& i_rEvent ) +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pComboBox = GetAsDynamic< ComboBox >(); + + ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemInserted: no ComboBox?!" ); + ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition <= pComboBox->GetEntryCount() ), + "VCLXComboBox::listItemInserted: illegal (inconsistent) item position!" ); + pComboBox->InsertEntryWithImage( + i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : OUString(), + i_rEvent.ItemImageURL.IsPresent ? lcl_getImageFromURL( i_rEvent.ItemImageURL.Value ) : Image(), + i_rEvent.ItemPosition ); +} + +void SAL_CALL VCLXComboBox::listItemRemoved( const ItemListEvent& i_rEvent ) +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pComboBox = GetAsDynamic< ComboBox >(); + + ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemRemoved: no ComboBox?!" ); + ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < pComboBox->GetEntryCount() ), + "VCLXComboBox::listItemRemoved: illegal (inconsistent) item position!" ); + + pComboBox->RemoveEntryAt( i_rEvent.ItemPosition ); +} + +void SAL_CALL VCLXComboBox::listItemModified( const ItemListEvent& i_rEvent ) +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pComboBox = GetAsDynamic< ComboBox >(); + + ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemModified: no ComboBox?!" ); + ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < pComboBox->GetEntryCount() ), + "VCLXComboBox::listItemModified: illegal (inconsistent) item position!" ); + + // VCL's ComboBox does not support changing an entry's text or image, so remove and re-insert + + const OUString sNewText = i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : pComboBox->GetEntry( i_rEvent.ItemPosition ); + const Image aNewImage( i_rEvent.ItemImageURL.IsPresent ? lcl_getImageFromURL( i_rEvent.ItemImageURL.Value ) : pComboBox->GetEntryImage( i_rEvent.ItemPosition ) ); + + pComboBox->RemoveEntryAt( i_rEvent.ItemPosition ); + pComboBox->InsertEntryWithImage(sNewText, aNewImage, i_rEvent.ItemPosition); +} + +void SAL_CALL VCLXComboBox::allItemsRemoved( const EventObject& ) +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pComboBox = GetAsDynamic< ComboBox >(); + ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemModified: no ComboBox?!" ); + + pComboBox->Clear(); +} + +void SAL_CALL VCLXComboBox::itemListChanged( const EventObject& i_rEvent ) +{ + SolarMutexGuard aGuard; + + VclPtr< ComboBox > pComboBox = GetAsDynamic< ComboBox >(); + ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemModified: no ComboBox?!" ); + + pComboBox->Clear(); + + uno::Reference< beans::XPropertySet > xPropSet( i_rEvent.Source, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySetInfo > xPSI( xPropSet->getPropertySetInfo(), uno::UNO_SET_THROW ); + // bool localize = xPSI->hasPropertyByName("ResourceResolver"); + uno::Reference< resource::XStringResourceResolver > xStringResourceResolver; + if ( xPSI->hasPropertyByName("ResourceResolver") ) + { + xStringResourceResolver.set( + xPropSet->getPropertyValue("ResourceResolver"), + uno::UNO_QUERY + ); + } + + + Reference< XItemList > xItemList( i_rEvent.Source, uno::UNO_QUERY_THROW ); + const uno::Sequence< beans::Pair< OUString, OUString > > aItems = xItemList->getAllItems(); + for ( const auto& rItem : aItems ) + { + OUString aLocalizationKey( rItem.First ); + if ( xStringResourceResolver.is() && !aLocalizationKey.isEmpty() && aLocalizationKey[0] == '&' ) + { + aLocalizationKey = xStringResourceResolver->resolveString(aLocalizationKey.copy( 1 )); + } + pComboBox->InsertEntryWithImage(aLocalizationKey, + lcl_getImageFromURL(rItem.Second)); + } +} +void SAL_CALL VCLXComboBox::disposing( const EventObject& i_rEvent ) +{ + // just disambiguate + VCLXEdit::disposing( i_rEvent ); +} + + + +void VCLXFormattedSpinField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + // Interestingly in the UnoControl API this is + // - not derived from XEdit ultimately, (correct ?) - so cut this here ... +// VCLXSpinField::ImplGetPropertyIds( rIds ); + VCLXWindow::ImplGetPropertyIds( rIds ); +} + +VCLXFormattedSpinField::VCLXFormattedSpinField() + : mpFormatter(nullptr) +{ +} + +VCLXFormattedSpinField::~VCLXFormattedSpinField() +{ +} + +void VCLXFormattedSpinField::setStrictFormat( bool bStrict ) +{ + SolarMutexGuard aGuard; + + FormatterBase* pFormatter = GetFormatter(); + if ( pFormatter ) + pFormatter->SetStrictFormat( bStrict ); +} + +bool VCLXFormattedSpinField::isStrictFormat() const +{ + FormatterBase* pFormatter = GetFormatter(); + return pFormatter && pFormatter->IsStrictFormat(); +} + + +void VCLXFormattedSpinField::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + FormatterBase* pFormatter = GetFormatter(); + if ( !pFormatter ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_SPIN: + { + bool b = bool(); + if ( Value >>= b ) + { + WinBits nStyle = GetWindow()->GetStyle() | WB_SPIN; + if ( !b ) + nStyle &= ~WB_SPIN; + GetWindow()->SetStyle( nStyle ); + } + } + break; + case BASEPROPERTY_STRICTFORMAT: + { + bool b = bool(); + if ( Value >>= b ) + { + pFormatter->SetStrictFormat( b ); + } + } + break; + default: + { + VCLXSpinField::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXFormattedSpinField::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + FormatterBase* pFormatter = GetFormatter(); + if ( pFormatter ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_TABSTOP: + { + aProp <<= ( GetWindow()->GetStyle() & WB_SPIN ) != 0; + } + break; + case BASEPROPERTY_STRICTFORMAT: + { + aProp <<= pFormatter->IsStrictFormat(); + } + break; + default: + { + aProp = VCLXSpinField::getProperty( PropertyName ); + } + } + } + return aProp; +} + + + + +void VCLXDateField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_ALIGN, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DATE, + BASEPROPERTY_DATEMAX, + BASEPROPERTY_DATEMIN, + BASEPROPERTY_DATESHOWCENTURY, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_DROPDOWN, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_EXTDATEFORMAT, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_READONLY, + BASEPROPERTY_REPEAT, + BASEPROPERTY_REPEAT_DELAY, + BASEPROPERTY_SPIN, + BASEPROPERTY_STRICTFORMAT, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_ENFORCE_FORMAT, + BASEPROPERTY_TEXT, + BASEPROPERTY_HIDEINACTIVESELECTION, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, + 0); + VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); +} + +VCLXDateField::VCLXDateField() +{ +} + +VCLXDateField::~VCLXDateField() +{ +} + +//change the window type here to match the role +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXDateField::CreateAccessibleContext() +{ + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + { + pWindow->SetType( WindowType::DATEFIELD ); + } + return getAccessibleFactory().createAccessibleContext( this ); +} + +// css::uno::XInterface +css::uno::Any VCLXDateField::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XDateField* >(this) ); + return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXDateField ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXDateField::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XDateField>::get(), + VCLXFormattedSpinField::getTypes() + ); + return aTypeList.getTypes(); +} + +void VCLXDateField::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + if ( !(GetWindow()) ) + return; + + bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_DATE: + { + if ( bVoid ) + { + GetAs< DateField >()->EnableEmptyFieldValue( true ); + GetAs< DateField >()->SetEmptyFieldValue(); + } + else + { + util::Date d; + if ( Value >>= d ) + setDate( d ); + } + } + break; + case BASEPROPERTY_DATEMIN: + { + util::Date d; + if ( Value >>= d ) + setMin( d ); + } + break; + case BASEPROPERTY_DATEMAX: + { + util::Date d; + if ( Value >>= d ) + setMax( d ); + } + break; + case BASEPROPERTY_EXTDATEFORMAT: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + GetAs< DateField >()->SetExtDateFormat( static_cast<ExtDateFieldFormat>(n) ); + } + break; + case BASEPROPERTY_DATESHOWCENTURY: + { + bool b = bool(); + if ( Value >>= b ) + GetAs< DateField >()->SetShowDateCentury( b ); + } + break; + case BASEPROPERTY_ENFORCE_FORMAT: + { + bool bEnforce( true ); + OSL_VERIFY( Value >>= bEnforce ); + GetAs< DateField >()->EnforceValidValue( bEnforce ); + } + break; + default: + { + VCLXFormattedSpinField::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXDateField::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + FormatterBase* pFormatter = GetFormatter(); + if ( pFormatter ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_DATE: + { + aProp <<= getDate(); + } + break; + case BASEPROPERTY_DATEMIN: + { + aProp <<= getMin(); + } + break; + case BASEPROPERTY_DATEMAX: + { + aProp <<= getMax(); + } + break; + case BASEPROPERTY_DATESHOWCENTURY: + { + aProp <<= GetAs< DateField >()->IsShowDateCentury(); + } + break; + case BASEPROPERTY_ENFORCE_FORMAT: + { + aProp <<= GetAs< DateField >()->IsEnforceValidValue( ); + } + break; + default: + { + aProp = VCLXFormattedSpinField::getProperty( PropertyName ); + } + } + } + return aProp; +} + + +void VCLXDateField::setDate( const util::Date& aDate ) +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + { + pDateField->SetDate( aDate ); + + // #107218# Call same listeners like VCL would do after user interaction + SetSynthesizingVCLEvent( true ); + pDateField->SetModifyFlag(); + pDateField->Modify(); + SetSynthesizingVCLEvent( false ); + } +} + +util::Date VCLXDateField::getDate() +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + return pDateField->GetDate().GetUNODate(); + else + return util::Date(); +} + +void VCLXDateField::setMin( const util::Date& aDate ) +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + pDateField->SetMin( aDate ); +} + +util::Date VCLXDateField::getMin() +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + return pDateField->GetMin().GetUNODate(); + else + return util::Date(); +} + +void VCLXDateField::setMax( const util::Date& aDate ) +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + pDateField->SetMax( aDate ); +} + +util::Date VCLXDateField::getMax() +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + return pDateField->GetMax().GetUNODate(); + else + return util::Date(); +} + +void VCLXDateField::setFirst( const util::Date& aDate ) +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + pDateField->SetFirst( aDate ); +} + +util::Date VCLXDateField::getFirst() +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + return pDateField->GetFirst().GetUNODate(); + else + return util::Date(); +} + +void VCLXDateField::setLast( const util::Date& aDate ) +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + pDateField->SetLast( aDate ); +} + +util::Date VCLXDateField::getLast() +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + return pDateField->GetLast().GetUNODate(); + else + return util::Date(); +} + +void VCLXDateField::setLongFormat( sal_Bool bLong ) +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + pDateField->SetLongFormat( bLong ); +} + +sal_Bool VCLXDateField::isLongFormat() +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + return pDateField && pDateField->IsLongFormat(); +} + +void VCLXDateField::setEmpty() +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + if ( pDateField ) + { + pDateField->SetEmptyDate(); + + // #107218# Call same listeners like VCL would do after user interaction + SetSynthesizingVCLEvent( true ); + pDateField->SetModifyFlag(); + pDateField->Modify(); + SetSynthesizingVCLEvent( false ); + } +} + +sal_Bool VCLXDateField::isEmpty() +{ + SolarMutexGuard aGuard; + + VclPtr< DateField > pDateField = GetAs< DateField >(); + return pDateField && pDateField->IsEmptyDate(); +} + +void VCLXDateField::setStrictFormat( sal_Bool bStrict ) +{ + VCLXFormattedSpinField::setStrictFormat( bStrict ); +} + +sal_Bool VCLXDateField::isStrictFormat() +{ + return VCLXFormattedSpinField::isStrictFormat(); +} + + + + +void VCLXTimeField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_ALIGN, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_EXTTIMEFORMAT, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_READONLY, + BASEPROPERTY_REPEAT, + BASEPROPERTY_REPEAT_DELAY, + BASEPROPERTY_SPIN, + BASEPROPERTY_STRICTFORMAT, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_TIME, + BASEPROPERTY_TIMEMAX, + BASEPROPERTY_TIMEMIN, + BASEPROPERTY_ENFORCE_FORMAT, + BASEPROPERTY_TEXT, + BASEPROPERTY_HIDEINACTIVESELECTION, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, + 0); + VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); +} + +VCLXTimeField::VCLXTimeField() +{ +} + +VCLXTimeField::~VCLXTimeField() +{ +} + +//change the window type here to match the role +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXTimeField::CreateAccessibleContext() +{ + VclPtr< vcl::Window > pWindow = GetWindow(); + if ( pWindow ) + { + pWindow->SetType( WindowType::TIMEFIELD ); + } + return getAccessibleFactory().createAccessibleContext( this ); +} + +// css::uno::XInterface +css::uno::Any VCLXTimeField::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XTimeField* >(this) ); + return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXTimeField ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXTimeField::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XTimeField>::get(), + VCLXFormattedSpinField::getTypes() + ); + return aTypeList.getTypes(); +} + +void VCLXTimeField::setTime( const util::Time& aTime ) +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + { + pTimeField->SetTime( aTime ); + + // #107218# Call same listeners like VCL would do after user interaction + SetSynthesizingVCLEvent( true ); + pTimeField->SetModifyFlag(); + pTimeField->Modify(); + SetSynthesizingVCLEvent( false ); + } +} + +util::Time VCLXTimeField::getTime() +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + return pTimeField->GetTime().GetUNOTime(); + else + return util::Time(); +} + +void VCLXTimeField::setMin( const util::Time& aTime ) +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + pTimeField->SetMin( aTime ); +} + +util::Time VCLXTimeField::getMin() +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + return pTimeField->GetMin().GetUNOTime(); + else + return util::Time(); +} + +void VCLXTimeField::setMax( const util::Time& aTime ) +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + pTimeField->SetMax( aTime ); +} + +util::Time VCLXTimeField::getMax() +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + return pTimeField->GetMax().GetUNOTime(); + else + return util::Time(); +} + +void VCLXTimeField::setFirst( const util::Time& aTime ) +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + pTimeField->SetFirst( aTime ); +} + +util::Time VCLXTimeField::getFirst() +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + return pTimeField->GetFirst().GetUNOTime(); + else + return util::Time(); +} + +void VCLXTimeField::setLast( const util::Time& aTime ) +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + pTimeField->SetLast( aTime ); +} + +util::Time VCLXTimeField::getLast() +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + return pTimeField->GetLast().GetUNOTime(); + else + return util::Time(); +} + +void VCLXTimeField::setEmpty() +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + if ( pTimeField ) + pTimeField->SetEmptyTime(); +} + +sal_Bool VCLXTimeField::isEmpty() +{ + SolarMutexGuard aGuard; + + VclPtr< TimeField > pTimeField = GetAs< TimeField >(); + return pTimeField && pTimeField->IsEmptyTime(); +} + +void VCLXTimeField::setStrictFormat( sal_Bool bStrict ) +{ + VCLXFormattedSpinField::setStrictFormat( bStrict ); +} + +sal_Bool VCLXTimeField::isStrictFormat() +{ + return VCLXFormattedSpinField::isStrictFormat(); +} + + +void VCLXTimeField::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + if ( !(GetWindow()) ) + return; + + bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_TIME: + { + if ( bVoid ) + { + GetAs< TimeField >()->EnableEmptyFieldValue( true ); + GetAs< TimeField >()->SetEmptyFieldValue(); + } + else + { + util::Time t; + if ( Value >>= t ) + setTime( t ); + } + } + break; + case BASEPROPERTY_TIMEMIN: + { + util::Time t; + if ( Value >>= t ) + setMin( t ); + } + break; + case BASEPROPERTY_TIMEMAX: + { + util::Time t; + if ( Value >>= t ) + setMax( t ); + } + break; + case BASEPROPERTY_EXTTIMEFORMAT: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + GetAs< TimeField >()->SetExtFormat( static_cast<ExtTimeFieldFormat>(n) ); + } + break; + case BASEPROPERTY_ENFORCE_FORMAT: + { + bool bEnforce( true ); + OSL_VERIFY( Value >>= bEnforce ); + GetAs< TimeField >()->EnforceValidValue( bEnforce ); + } + break; + default: + { + VCLXFormattedSpinField::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXTimeField::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + if ( GetWindow() ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_TIME: + { + aProp <<= getTime(); + } + break; + case BASEPROPERTY_TIMEMIN: + { + aProp <<= getMin(); + } + break; + case BASEPROPERTY_TIMEMAX: + { + aProp <<= getMax(); + } + break; + case BASEPROPERTY_ENFORCE_FORMAT: + { + aProp <<= GetAs< TimeField >()->IsEnforceValidValue( ); + } + break; + default: + { + aProp = VCLXFormattedSpinField::getProperty( PropertyName ); + } + } + } + return aProp; +} + + + + +void VCLXNumericField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_ALIGN, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DECIMALACCURACY, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_NUMSHOWTHOUSANDSEP, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_READONLY, + BASEPROPERTY_REPEAT, + BASEPROPERTY_REPEAT_DELAY, + BASEPROPERTY_SPIN, + BASEPROPERTY_STRICTFORMAT, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_VALUEMAX_DOUBLE, + BASEPROPERTY_VALUEMIN_DOUBLE, + BASEPROPERTY_VALUESTEP_DOUBLE, + BASEPROPERTY_VALUE_DOUBLE, + BASEPROPERTY_ENFORCE_FORMAT, + BASEPROPERTY_HIDEINACTIVESELECTION, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, + 0); + VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); +} + +VCLXNumericField::VCLXNumericField() +{ +} + +VCLXNumericField::~VCLXNumericField() +{ +} + +// css::uno::XInterface +css::uno::Any VCLXNumericField::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XNumericField* >(this) ); + return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXNumericField ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXNumericField::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XNumericField>::get(), + VCLXFormattedSpinField::getTypes() + ); + return aTypeList.getTypes(); +} + +void VCLXNumericField::setValue( double Value ) +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + if ( !pNumericFormatter ) + return; + + // shift long value using decimal digits + // (e.g., input 105 using 2 digits returns 1,05) + // Thus, to set a value of 1,05, insert 105 and 2 digits + pNumericFormatter->SetValue( + static_cast<tools::Long>(ImplCalcLongValue( Value, pNumericFormatter->GetDecimalDigits() )) ); + + // #107218# Call same listeners like VCL would do after user interaction + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + { + SetSynthesizingVCLEvent( true ); + pEdit->SetModifyFlag(); + pEdit->Modify(); + SetSynthesizingVCLEvent( false ); + } +} + +double VCLXNumericField::getValue() +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + return pNumericFormatter + ? ImplCalcDoubleValue( static_cast<double>(pNumericFormatter->GetValue()), pNumericFormatter->GetDecimalDigits() ) + : 0; +} + +void VCLXNumericField::setMin( double Value ) +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + if ( pNumericFormatter ) + pNumericFormatter->SetMin( + static_cast<tools::Long>(ImplCalcLongValue( Value, pNumericFormatter->GetDecimalDigits() )) ); +} + +double VCLXNumericField::getMin() +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + return pNumericFormatter + ? ImplCalcDoubleValue( static_cast<double>(pNumericFormatter->GetMin()), pNumericFormatter->GetDecimalDigits() ) + : 0; +} + +void VCLXNumericField::setMax( double Value ) +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + if ( pNumericFormatter ) + pNumericFormatter->SetMax( + static_cast<tools::Long>(ImplCalcLongValue( Value, pNumericFormatter->GetDecimalDigits() )) ); +} + +double VCLXNumericField::getMax() +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + return pNumericFormatter + ? ImplCalcDoubleValue( static_cast<double>(pNumericFormatter->GetMax()), pNumericFormatter->GetDecimalDigits() ) + : 0; +} + +void VCLXNumericField::setFirst( double Value ) +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + if ( pNumericFormatter ) + pNumericFormatter->SetFirst( + static_cast<tools::Long>(ImplCalcLongValue( Value, pNumericFormatter->GetDecimalDigits() )) ); +} + +double VCLXNumericField::getFirst() +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + return pNumericFormatter + ? ImplCalcDoubleValue( static_cast<double>(pNumericFormatter->GetFirst()), pNumericFormatter->GetDecimalDigits() ) + : 0; +} + +void VCLXNumericField::setLast( double Value ) +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + if ( pNumericFormatter ) + pNumericFormatter->SetLast( + static_cast<tools::Long>(ImplCalcLongValue( Value, pNumericFormatter->GetDecimalDigits() )) ); +} + +double VCLXNumericField::getLast() +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + return pNumericFormatter + ? ImplCalcDoubleValue( static_cast<double>(pNumericFormatter->GetLast()), pNumericFormatter->GetDecimalDigits() ) + : 0; +} + +void VCLXNumericField::setStrictFormat( sal_Bool bStrict ) +{ + VCLXFormattedSpinField::setStrictFormat( bStrict ); +} + +sal_Bool VCLXNumericField::isStrictFormat() +{ + return VCLXFormattedSpinField::isStrictFormat(); +} + +void VCLXNumericField::setSpinSize( double Value ) +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + if ( pNumericFormatter ) + pNumericFormatter->SetSpinSize( + static_cast<tools::Long>(ImplCalcLongValue( Value, pNumericFormatter->GetDecimalDigits() )) ); +} + +double VCLXNumericField::getSpinSize() +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + return pNumericFormatter + ? ImplCalcDoubleValue( static_cast<double>(pNumericFormatter->GetSpinSize()), pNumericFormatter->GetDecimalDigits() ) + : 0; +} + +void VCLXNumericField::setDecimalDigits( sal_Int16 Value ) +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + if ( pNumericFormatter ) + { + double n = getValue(); + pNumericFormatter->SetDecimalDigits( Value ); + setValue( n ); + } +} + +sal_Int16 VCLXNumericField::getDecimalDigits() +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + return pNumericFormatter ? pNumericFormatter->GetDecimalDigits() : 0; +} + +void VCLXNumericField::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + if ( !(GetWindow()) ) + return; + + bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_VALUE_DOUBLE: + { + if ( bVoid ) + { + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + if (!pNumericFormatter) + return; + pNumericFormatter->EnableEmptyFieldValue( true ); + pNumericFormatter->SetEmptyFieldValue(); + } + else + { + double d = 0; + if ( Value >>= d ) + setValue( d ); + } + } + break; + case BASEPROPERTY_VALUEMIN_DOUBLE: + { + double d = 0; + if ( Value >>= d ) + setMin( d ); + } + break; + case BASEPROPERTY_VALUEMAX_DOUBLE: + { + double d = 0; + if ( Value >>= d ) + setMax( d ); + } + break; + case BASEPROPERTY_VALUESTEP_DOUBLE: + { + double d = 0; + if ( Value >>= d ) + setSpinSize( d ); + } + break; + case BASEPROPERTY_DECIMALACCURACY: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + setDecimalDigits( n ); + } + break; + case BASEPROPERTY_NUMSHOWTHOUSANDSEP: + { + bool b = bool(); + if ( Value >>= b ) + { + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + if (!pNumericFormatter) + return; + pNumericFormatter->SetUseThousandSep( b ); + } + } + break; + default: + { + VCLXFormattedSpinField::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXNumericField::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + FormatterBase* pFormatter = GetFormatter(); + if ( pFormatter ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_VALUE_DOUBLE: + { + aProp <<= getValue(); + } + break; + case BASEPROPERTY_VALUEMIN_DOUBLE: + { + aProp <<= getMin(); + } + break; + case BASEPROPERTY_VALUEMAX_DOUBLE: + { + aProp <<= getMax(); + } + break; + case BASEPROPERTY_VALUESTEP_DOUBLE: + { + aProp <<= getSpinSize(); + } + break; + case BASEPROPERTY_NUMSHOWTHOUSANDSEP: + { + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(pFormatter); + aProp <<= pNumericFormatter->IsUseThousandSep(); + } + break; + default: + { + aProp = VCLXFormattedSpinField::getProperty( PropertyName ); + } + } + } + return aProp; +} + + +// ---------------------------------------------------- +// ---------------------------------------------------- + +void VCLXMetricField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_ALIGN, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DECIMALACCURACY, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_NUMSHOWTHOUSANDSEP, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_READONLY, + BASEPROPERTY_REPEAT, + BASEPROPERTY_REPEAT_DELAY, + BASEPROPERTY_SPIN, + BASEPROPERTY_STRICTFORMAT, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_ENFORCE_FORMAT, + BASEPROPERTY_HIDEINACTIVESELECTION, + BASEPROPERTY_UNIT, + BASEPROPERTY_CUSTOMUNITTEXT, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, + 0); + VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); +} + +VCLXMetricField::VCLXMetricField() +{ +} + +VCLXMetricField::~VCLXMetricField() +{ +} + +MetricFormatter *VCLXMetricField::GetMetricFormatter() +{ + MetricFormatter *pFormatter = static_cast<MetricFormatter *>(GetFormatter()); + if (!pFormatter) + throw css::uno::RuntimeException(); + return pFormatter; +} + +MetricField *VCLXMetricField::GetMetricField() +{ + VclPtr< MetricField > pField = GetAs< MetricField >(); + if (!pField) + throw css::uno::RuntimeException(); + return pField; +} + +// css::uno::XInterface +css::uno::Any VCLXMetricField::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, static_cast< css::awt::XMetricField* >(this) ); + return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXMetricField ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXMetricField::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XMetricField>::get(), + VCLXFormattedSpinField::getTypes() + ); + return aTypeList.getTypes(); +} + +// FIXME: later ... +#define MetricUnitUnoToVcl(a) (static_cast<FieldUnit>(a)) + +#define METRIC_MAP_PAIR(method,parent) \ + sal_Int64 VCLXMetricField::get##method( sal_Int16 nUnit ) \ + { \ + SolarMutexGuard aGuard; \ + return GetMetric##parent()->Get##method( MetricUnitUnoToVcl( nUnit ) ); \ + } \ + void VCLXMetricField::set##method( sal_Int64 nValue, sal_Int16 nUnit ) \ + { \ + SolarMutexGuard aGuard; \ + GetMetric##parent()->Set##method( nValue, MetricUnitUnoToVcl( nUnit ) ); \ + } + +METRIC_MAP_PAIR(Min, Formatter) +METRIC_MAP_PAIR(Max, Formatter) +METRIC_MAP_PAIR(First, Field) +METRIC_MAP_PAIR(Last, Field) + +#undef METRIC_MAP_PAIR + +::sal_Int64 VCLXMetricField::getValue( ::sal_Int16 nUnit ) +{ + SolarMutexGuard aGuard; + return GetMetricFormatter()->GetValue( MetricUnitUnoToVcl( nUnit ) ); +} + +::sal_Int64 VCLXMetricField::getCorrectedValue( ::sal_Int16 nUnit ) +{ + SolarMutexGuard aGuard; + return GetMetricFormatter()->GetCorrectedValue( MetricUnitUnoToVcl( nUnit ) ); +} + +// FIXME: acute cut/paste evilness - move this to the parent Edit class ? +void VCLXMetricField::CallListeners() +{ + // #107218# Call same listeners like VCL would do after user interaction + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + { + SetSynthesizingVCLEvent( true ); + pEdit->SetModifyFlag(); + pEdit->Modify(); + SetSynthesizingVCLEvent( false ); + } +} + +void VCLXMetricField::setValue( ::sal_Int64 Value, ::sal_Int16 Unit ) +{ + SolarMutexGuard aGuard; + GetMetricFormatter()->SetValue( Value, MetricUnitUnoToVcl( Unit ) ); + CallListeners(); +} + +void VCLXMetricField::setUserValue( ::sal_Int64 Value, ::sal_Int16 Unit ) +{ + SolarMutexGuard aGuard; + GetMetricFormatter()->SetUserValue( Value, MetricUnitUnoToVcl( Unit ) ); + CallListeners(); +} + +void VCLXMetricField::setStrictFormat( sal_Bool bStrict ) +{ + VCLXFormattedSpinField::setStrictFormat( bStrict ); +} + +sal_Bool VCLXMetricField::isStrictFormat() +{ + return VCLXFormattedSpinField::isStrictFormat(); +} + +void VCLXMetricField::setSpinSize( sal_Int64 Value ) +{ + SolarMutexGuard aGuard; + GetMetricField()->SetSpinSize( Value ); +} + +sal_Int64 VCLXMetricField::getSpinSize() +{ + SolarMutexGuard aGuard; + return GetMetricField()->GetSpinSize(); +} + +void VCLXMetricField::setDecimalDigits( sal_Int16 Value ) +{ + SolarMutexGuard aGuard; + GetMetricFormatter()->SetDecimalDigits( Value ); +} + +sal_Int16 VCLXMetricField::getDecimalDigits() +{ + SolarMutexGuard aGuard; + + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + return pNumericFormatter ? pNumericFormatter->GetDecimalDigits() : 0; +} + +void VCLXMetricField::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + if ( !(GetWindow()) ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_DECIMALACCURACY: + { + sal_Int16 n = 0; + if ( Value >>= n ) + setDecimalDigits( n ); + break; + } + case BASEPROPERTY_NUMSHOWTHOUSANDSEP: + { + bool b = false; + if ( Value >>= b ) + { + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(GetFormatter()); + if (!pNumericFormatter) + return; + pNumericFormatter->SetUseThousandSep( b ); + } + } + break; + case BASEPROPERTY_UNIT: + { + sal_uInt16 nVal = 0; + if ( Value >>= nVal ) + GetAs< MetricField >()->SetUnit( static_cast<FieldUnit>(nVal) ); + break; + } + case BASEPROPERTY_CUSTOMUNITTEXT: + { + OUString aStr; + if ( Value >>= aStr ) + GetAs< MetricField >()->SetCustomUnitText( aStr ); + break; + } + default: + { + VCLXFormattedSpinField::setProperty( PropertyName, Value ); + break; + } + } +} + +css::uno::Any VCLXMetricField::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + FormatterBase* pFormatter = GetFormatter(); + if ( pFormatter ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_NUMSHOWTHOUSANDSEP: + { + NumericFormatter* pNumericFormatter = static_cast<NumericFormatter*>(pFormatter); + aProp <<= pNumericFormatter->IsUseThousandSep(); + break; + } + case BASEPROPERTY_UNIT: + aProp <<= static_cast<sal_uInt16>(GetAs< MetricField >()->GetUnit()); + break; + case BASEPROPERTY_CUSTOMUNITTEXT: + aProp <<= GetAs< MetricField >()->GetCustomUnitText(); + break; + default: + { + aProp = VCLXFormattedSpinField::getProperty( PropertyName ); + break; + } + } + } + return aProp; +} + +void VCLXPatternField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_ALIGN, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_EDITMASK, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_LITERALMASK, + BASEPROPERTY_MAXTEXTLEN, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_READONLY, + BASEPROPERTY_STRICTFORMAT, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_TEXT, + BASEPROPERTY_HIDEINACTIVESELECTION, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, + 0); + VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); +} + +VCLXPatternField::VCLXPatternField() +{ +} + +VCLXPatternField::~VCLXPatternField() +{ +} + +// css::uno::XInterface +css::uno::Any VCLXPatternField::queryInterface( const css::uno::Type & rType ) +{ + css::uno::Any aRet = ::cppu::queryInterface( rType, + static_cast< css::awt::XPatternField* >(this) ); + return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType )); +} + +IMPL_IMPLEMENTATION_ID( VCLXPatternField ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXPatternField::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XPatternField>::get(), + VCLXFormattedSpinField::getTypes() + ); + return aTypeList.getTypes(); +} + +void VCLXPatternField::setMasks( const OUString& EditMask, const OUString& LiteralMask ) +{ + SolarMutexGuard aGuard; + + VclPtr< PatternField > pPatternField = GetAs< PatternField >(); + if ( pPatternField ) + { + pPatternField->SetMask( OUStringToOString(EditMask, RTL_TEXTENCODING_ASCII_US), LiteralMask ); + } +} + +void VCLXPatternField::getMasks( OUString& EditMask, OUString& LiteralMask ) +{ + SolarMutexGuard aGuard; + + VclPtr< PatternField > pPatternField = GetAs< PatternField >(); + if ( pPatternField ) + { + EditMask = OStringToOUString(pPatternField->GetEditMask(), RTL_TEXTENCODING_ASCII_US); + LiteralMask = pPatternField->GetLiteralMask(); + } +} + +void VCLXPatternField::setString( const OUString& Str ) +{ + SolarMutexGuard aGuard; + VclPtr< PatternField > pPatternField = GetAs< PatternField >(); + if ( pPatternField ) + pPatternField->SetString( Str ); +} + +OUString VCLXPatternField::getString() +{ + SolarMutexGuard aGuard; + + OUString aString; + VclPtr< PatternField > pPatternField = GetAs< PatternField >(); + if ( pPatternField ) + aString = pPatternField->GetString(); + return aString; +} + +void VCLXPatternField::setStrictFormat( sal_Bool bStrict ) +{ + VCLXFormattedSpinField::setStrictFormat( bStrict ); +} + +sal_Bool VCLXPatternField::isStrictFormat() +{ + return VCLXFormattedSpinField::isStrictFormat(); +} + +void VCLXPatternField::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + if ( !(GetWindow()) ) + return; + + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_EDITMASK: + case BASEPROPERTY_LITERALMASK: + { + OUString aString; + if ( Value >>= aString ) + { + OUString aEditMask, aLiteralMask; + getMasks( aEditMask, aLiteralMask ); + if ( nPropType == BASEPROPERTY_EDITMASK ) + aEditMask = aString; + else + aLiteralMask = aString; + setMasks( aEditMask, aLiteralMask ); + } + } + break; + default: + { + VCLXFormattedSpinField::setProperty( PropertyName, Value ); + } + } +} + +css::uno::Any VCLXPatternField::getProperty( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + css::uno::Any aProp; + if ( GetWindow() ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_EDITMASK: + case BASEPROPERTY_LITERALMASK: + { + OUString aEditMask, aLiteralMask; + getMasks( aEditMask, aLiteralMask ); + if ( nPropType == BASEPROPERTY_EDITMASK ) + aProp <<= aEditMask; + else + aProp <<= aLiteralMask; + } + break; + default: + { + aProp = VCLXFormattedSpinField::getProperty( PropertyName ); + } + } + } + return aProp; +} + + + +VCLXToolBox::VCLXToolBox() +{ +} + +VCLXToolBox::~VCLXToolBox() +{ +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXToolBox::CreateAccessibleContext() +{ + return getAccessibleFactory().createAccessibleContext( this ); +} + +VCLXHeaderBar::VCLXHeaderBar() +{ +} + +VCLXHeaderBar::~VCLXHeaderBar() +{ +} + +css::uno::Reference< css::accessibility::XAccessibleContext > VCLXHeaderBar::CreateAccessibleContext() +{ + return getAccessibleFactory().createAccessibleContext( this ); +} + + +VCLXFrame::VCLXFrame() +{ +} + +void VCLXFrame::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_GRAPHIC, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_LABEL, + 0); + VCLXContainer::ImplGetPropertyIds( rIds ); +} + +VCLXFrame::~VCLXFrame() +{ +} + +IMPL_IMPLEMENTATION_ID( VCLXFrame ) + +// css::awt::XView +void SAL_CALL VCLXFrame::draw( sal_Int32 nX, sal_Int32 nY ) +{ + SolarMutexGuard aGuard; + VclPtr< vcl::Window > pWindow = GetWindow(); + + if ( pWindow ) + { + OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() ); + if ( !pDev ) + pDev = pWindow->GetParent()->GetOutDev(); + + Point aPos = pDev->PixelToLogic( Point( nX, nY ) ); + pWindow->Draw( pDev, aPos, SystemTextColorFlags::NoControls ); + } +} + +void SAL_CALL VCLXFrame::setProperty( + const OUString& PropertyName, + const css::uno::Any& Value ) +{ + SolarMutexGuard aGuard; + + VCLXContainer::setProperty( PropertyName, Value ); +} + +void VCLXFrame::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + css::uno::Reference< css::awt::XWindow > xKeepAlive( this ); + VCLXContainer::ProcessWindowEvent( rVclWindowEvent ); +} + +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 )); +} + +IMPL_IMPLEMENTATION_ID( VCLXProgressBar ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXProgressBar::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XProgressBar>::get(), + VCLXWindow::getTypes() + ); + return aTypeList.getTypes(); +} + +// css::awt::XProgressBar +void VCLXProgressBar::setForegroundColor( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + pWindow->SetControlForeground( Color(ColorTransparency, nColor) ); + } +} + +void VCLXProgressBar::setBackgroundColor( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + Color aColor( ColorTransparency, 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 + { + Color nColor; + if ( Value >>= nColor ) + pWindow->SetControlForeground( nColor ); + } + } + } + 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 ); +} + +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 )); +} + +IMPL_IMPLEMENTATION_ID( VCLXFileControl ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXFileControl::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XTextComponent>::get(), + cppu::UnoType<css::awt::XTextLayoutConstrains>::get(), + VCLXWindow::getTypes() + ); + return aTypeList.getTypes(); +} + +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 ); + } +} + +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 ); +} + +SVTXFormattedField::SVTXFormattedField() + :bIsStandardSupplier(true) + ,nKeyToSetDelayed(-1) +{ +} + +SVTXFormattedField::~SVTXFormattedField() +{ +} + +void SVTXFormattedField::SetWindow( const VclPtr< vcl::Window > &_pWindow ) +{ + VCLXSpinField::SetWindow(_pWindow); + if (GetAs< FormattedField >()) + GetAs< FormattedField >()->GetFormatter().SetAutoColor(true); +} + +void SVTXFormattedField::setProperty( const OUString& PropertyName, const css::uno::Any& Value) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + { + Formatter& rFormatter = pField->GetFormatter(); + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch (nPropType) + { + case BASEPROPERTY_ENFORCE_FORMAT: + { + bool bEnable( true ); + if ( Value >>= bEnable ) + rFormatter.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::Any(static_cast<double>(nValue))); + break; + } + + SetValue(Value); + } + break; + case BASEPROPERTY_VALUESTEP_DOUBLE: + { + double d = 0.0; + if ( Value >>= d ) + rFormatter.SetSpinSize( d ); + else + { + sal_Int32 n = 0; + if ( Value >>= n ) + rFormatter.SetSpinSize( n ); + } + } + break; + case BASEPROPERTY_DECIMALACCURACY: + { + sal_Int32 n = 0; + if ( Value >>= n ) + rFormatter.SetDecimalDigits( static_cast<sal_uInt16>(n) ); + } + break; + case BASEPROPERTY_NUMSHOWTHOUSANDSEP: + { + bool b; + if ( Value >>= b ) + rFormatter.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 + rFormatter.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 ) + { + Formatter& rFormatter = pField->GetFormatter(); + 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 <<= rFormatter.GetSpinSize(); + break; + + case BASEPROPERTY_DECIMALACCURACY: + aReturn <<= rFormatter.GetDecimalDigits(); + break; + + case BASEPROPERTY_FORMATSSUPPLIER: + { + if (!bIsStandardSupplier) + { // ansonsten void + css::uno::Reference< css::util::XNumberFormatsSupplier > xSupplier = m_xCurrentSupplier; + 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) const +{ + css::uno::Any aReturn; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if (!pField) + return aReturn; + + Formatter& rFieldFormatter = pField->GetFormatter(); + switch (rValue.getValueType().getTypeClass()) + { + case css::uno::TypeClass_DOUBLE: + if (rFieldFormatter.TreatingAsNumber()) + { + double d = 0.0; + rValue >>= d; + aReturn <<= d; + } + else + { + SvNumberFormatter* pFormatter = rFieldFormatter.GetFormatter(); + if (!pFormatter) + pFormatter = rFieldFormatter.StandardFormatter(); + // should never fail + + const 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 (rFieldFormatter.TreatingAsNumber()) + { + SvNumberFormatter* pFormatter = rFieldFormatter.GetFormatter(); + if (!pFormatter) + pFormatter = rFieldFormatter.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; + + Formatter& rFormatter = pField->GetFormatter(); + switch (rValue.getValueType().getTypeClass()) + + { + case css::uno::TypeClass_DOUBLE: + { + double d = 0.0; + rValue >>= d; + rFormatter.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(); + } + rFormatter.ClearMinValue(); + break; + } +} + +css::uno::Any SVTXFormattedField::GetMinValue() const +{ + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if (!pField) + return css::uno::Any(); + Formatter& rFormatter = pField->GetFormatter(); + if (!rFormatter.HasMinValue()) + return css::uno::Any(); + + css::uno::Any aReturn; + aReturn <<= rFormatter.GetMinValue(); + return aReturn; +} + +void SVTXFormattedField::SetMaxValue(const css::uno::Any& rValue) +{ + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if (!pField) + return; + + Formatter& rFormatter = pField->GetFormatter(); + switch (rValue.getValueType().getTypeClass()) + { + case css::uno::TypeClass_DOUBLE: + { + double d = 0.0; + rValue >>= d; + rFormatter.SetMaxValue(d); + break; + } + default: + if (rValue.getValueType().getTypeClass() != css::uno::TypeClass_VOID) + + { + throw css::lang::IllegalArgumentException(); + } + rFormatter.ClearMaxValue(); + break; + } +} + +css::uno::Any SVTXFormattedField::GetMaxValue() const +{ + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if (!pField) + return css::uno::Any(); + Formatter& rFormatter = pField->GetFormatter(); + if (!rFormatter.HasMaxValue()) + return css::uno::Any(); + + css::uno::Any aReturn; + aReturn <<= rFormatter.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); + + Formatter& rFormatter = pField->GetFormatter(); + switch (aConverted.getValueType().getTypeClass()) + { + case css::uno::TypeClass_DOUBLE: + { + double d = 0.0; + aConverted >>= d; + rFormatter.SetDefaultValue(d); + } + break; + case css::uno::TypeClass_STRING: + { + OUString aStr; + aConverted >>= aStr; + rFormatter.SetDefaultText( aStr ); + } + break; + default: + rFormatter.EnableEmptyField(true); + // only void accepted + break; + } +} + +css::uno::Any SVTXFormattedField::GetDefaultValue() const +{ + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if (!pField) + return css::uno::Any(); + Formatter& rFormatter = pField->GetFormatter(); + if (rFormatter.IsEmptyFieldEnabled()) + return css::uno::Any(); + + css::uno::Any aReturn; + if (rFormatter.TreatingAsNumber()) + aReturn <<= rFormatter.GetDefaultValue(); + else + aReturn <<= rFormatter.GetDefaultText(); + return aReturn; +} + +bool SVTXFormattedField::GetTreatAsNumber() const +{ + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if (pField) + return pField->GetFormatter().TreatingAsNumber(); + + return true; +} + +void SVTXFormattedField::SetTreatAsNumber(bool bSet) +{ + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if (pField) + pField->GetFormatter().TreatAsNumber(bSet); +} + +css::uno::Any SVTXFormattedField::GetValue() const +{ + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if (!pField) + return css::uno::Any(); + + Formatter& rFormatter = pField->GetFormatter(); + css::uno::Any aReturn; + if (!rFormatter.TreatingAsNumber()) + { + OUString sText = rFormatter.GetTextValue(); + aReturn <<= sText; + } + else + { + if (!pField->GetText().isEmpty()) // empty is returned as void by default + aReturn <<= rFormatter.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 + { + Formatter& rFormatter = pField->GetFormatter(); + if (rValue.getValueType().getTypeClass() == css::uno::TypeClass_DOUBLE ) + { + double d = 0.0; + rValue >>= d; + rFormatter.SetValue(d); + } + else + { + DBG_ASSERT(rValue.getValueType().getTypeClass() == css::uno::TypeClass_STRING, "SVTXFormattedField::SetValue : invalid argument !"); + + OUString sText; + rValue >>= sText; + if (!rFormatter.TreatingAsNumber()) + rFormatter.SetTextFormatted(sText); + else + rFormatter.SetTextValue(sText); + } + } +// NotifyTextListeners(); +} + +void SVTXFormattedField::setFormatsSupplier(const css::uno::Reference< css::util::XNumberFormatsSupplier > & xSupplier) +{ + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + + rtl::Reference<SvNumberFormatsSupplierObj> pNew; + if (!xSupplier.is()) + { + if (pField) + { + Formatter& rFormatter = pField->GetFormatter(); + pNew = new SvNumberFormatsSupplierObj(rFormatter.StandardFormatter()); + bIsStandardSupplier = true; + } + } + else + { + pNew = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(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(); + Formatter& rFormatter = pField->GetFormatter(); + rFormatter.SetFormatter(m_xCurrentSupplier->GetNumberFormatter(), false); + if (nKeyToSetDelayed != -1) + { + rFormatter.SetFormatKey(nKeyToSetDelayed); + nKeyToSetDelayed = -1; + } + SetValue(aCurrent); + NotifyTextListeners(); +} + +sal_Int32 SVTXFormattedField::getFormatKey() const +{ + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetFormatKey() : 0; +} + +void SVTXFormattedField::setFormatKey(sal_Int32 nKey) +{ + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if (!pField) + return; + + Formatter& rFormatter = pField->GetFormatter(); + if (rFormatter.GetFormatter()) + rFormatter.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 ); +} + +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 )); +} + +IMPL_IMPLEMENTATION_ID( SVTXCurrencyField ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > SVTXCurrencyField::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XCurrencyField>::get(), + SVTXFormattedField::getTypes() + ); + return aTypeList.getTypes(); +} + +void SVTXCurrencyField::setValue( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetValue( Value ); +} + +double SVTXCurrencyField::getValue() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetValue() : 0; +} + +void SVTXCurrencyField::setMin( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetMinValue( Value ); +} + +double SVTXCurrencyField::getMin() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetMinValue() : 0; +} + +void SVTXCurrencyField::setMax( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetMaxValue( Value ); +} + +double SVTXCurrencyField::getMax() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetMaxValue() : 0; +} + +void SVTXCurrencyField::setFirst( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetSpinFirst( Value ); +} + +double SVTXCurrencyField::getFirst() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetSpinFirst() : 0; +} + +void SVTXCurrencyField::setLast( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetSpinLast( Value ); +} + +double SVTXCurrencyField::getLast() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetSpinLast() : 0; +} + +void SVTXCurrencyField::setSpinSize( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetSpinSize( Value ); +} + +double SVTXCurrencyField::getSpinSize() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetSpinSize() : 0; +} + +void SVTXCurrencyField::setDecimalDigits( sal_Int16 Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetDecimalDigits( Value ); +} + +sal_Int16 SVTXCurrencyField::getDecimalDigits() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetDecimalDigits() : 0; +} + +void SVTXCurrencyField::setStrictFormat( sal_Bool bStrict ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetStrictFormat( bStrict ); +} + +sal_Bool SVTXCurrencyField::isStrictFormat() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField && pField->GetFormatter().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_ALIGN, + BASEPROPERTY_BACKGROUNDCOLOR, + BASEPROPERTY_BORDER, + BASEPROPERTY_BORDERCOLOR, + BASEPROPERTY_CURRENCYSYMBOL, + BASEPROPERTY_CURSYM_POSITION, + BASEPROPERTY_DECIMALACCURACY, + BASEPROPERTY_DEFAULTCONTROL, + BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, + BASEPROPERTY_FONTDESCRIPTOR, + BASEPROPERTY_HELPTEXT, + BASEPROPERTY_HELPURL, + BASEPROPERTY_NUMSHOWTHOUSANDSEP, + BASEPROPERTY_PRINTABLE, + BASEPROPERTY_READONLY, + BASEPROPERTY_REPEAT, + BASEPROPERTY_REPEAT_DELAY, + BASEPROPERTY_SPIN, + BASEPROPERTY_STRICTFORMAT, + BASEPROPERTY_TABSTOP, + BASEPROPERTY_VALUEMAX_DOUBLE, + BASEPROPERTY_VALUEMIN_DOUBLE, + BASEPROPERTY_VALUESTEP_DOUBLE, + BASEPROPERTY_VALUE_DOUBLE, + BASEPROPERTY_ENFORCE_FORMAT, + BASEPROPERTY_HIDEINACTIVESELECTION, + BASEPROPERTY_VERTICALALIGN, + BASEPROPERTY_WRITING_MODE, + BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, + 0); + VCLXWindow::ImplGetPropertyIds( rIds ); +} + +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 )); +} + +IMPL_IMPLEMENTATION_ID( SVTXNumericField ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > SVTXNumericField::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XNumericField>::get(), + SVTXFormattedField::getTypes() + ); + return aTypeList.getTypes(); +} + + +css::uno::Reference<accessibility::XAccessibleContext> SVTXNumericField::CreateAccessibleContext() +{ + return getAccessibleFactory().createAccessibleContext(this); +} + + +void SVTXNumericField::setValue( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetValue( Value ); +} + +double SVTXNumericField::getValue() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetValue() : 0; +} + +void SVTXNumericField::setMin( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetMinValue( Value ); +} + +double SVTXNumericField::getMin() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetMinValue() : 0; +} + +void SVTXNumericField::setMax( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetMaxValue( Value ); +} + +double SVTXNumericField::getMax() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetMaxValue() : 0; +} + +void SVTXNumericField::setFirst( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetSpinFirst( Value ); +} + +double SVTXNumericField::getFirst() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetSpinFirst() : 0; +} + +void SVTXNumericField::setLast( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetSpinLast( Value ); +} + +double SVTXNumericField::getLast() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetSpinLast() : 0; +} + +void SVTXNumericField::setSpinSize( double Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetSpinSize( Value ); +} + +double SVTXNumericField::getSpinSize() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetSpinSize() : 0; +} + +void SVTXNumericField::setDecimalDigits( sal_Int16 Value ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetDecimalDigits( Value ); +} + +sal_Int16 SVTXNumericField::getDecimalDigits() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField ? pField->GetFormatter().GetDecimalDigits() : 0; +} + +void SVTXNumericField::setStrictFormat( sal_Bool bStrict ) +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + if ( pField ) + pField->GetFormatter().SetStrictFormat( bStrict ); +} + +sal_Bool SVTXNumericField::isStrictFormat() +{ + SolarMutexGuard aGuard; + + VclPtr<FormattedField> pField = GetAs< FormattedField >(); + return pField && pField->GetFormatter().IsStrictFormat(); +} + +void SVTXNumericField::GetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + SVTXFormattedField::ImplGetPropertyIds( rIds ); +} + +SVTXDateField::SVTXDateField() +{ +} + +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() ? GetAs<Edit>()->GetSubEdit() : nullptr; + if ( !pSubEdit ) + return; + + switch ( GetPropertyId( PropertyName ) ) + { + case BASEPROPERTY_TEXTLINECOLOR: + if ( !Value.hasValue() ) + pSubEdit->SetTextLineColor(); + else + { + Color nColor; + if ( Value >>= nColor ) + pSubEdit->SetTextLineColor( nColor ); + } + break; + } +} + +void SVTXDateField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_TEXTLINECOLOR, + 0); + VCLXDateField::ImplGetPropertyIds( rIds ); +} + +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 )); +} + +IMPL_IMPLEMENTATION_ID( VCLXMultiLineEdit ) + +// css::lang::XTypeProvider +css::uno::Sequence< css::uno::Type > VCLXMultiLineEdit::getTypes() +{ + static const ::cppu::OTypeCollection aTypeList( + cppu::UnoType<css::lang::XTypeProvider>::get(), + cppu::UnoType<css::awt::XTextComponent>::get(), + cppu::UnoType<css::awt::XTextArea>::get(), + cppu::UnoType<css::awt::XTextLayoutConstrains>::get(), + VCLXWindow::getTypes() + ); + return aTypeList.getTypes(); +} + +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 ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/awt/vclxwindows_internal.hxx b/toolkit/source/awt/vclxwindows_internal.hxx new file mode 100644 index 000000000..042522586 --- /dev/null +++ b/toolkit/source/awt/vclxwindows_internal.hxx @@ -0,0 +1,33 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_TOOLKIT_SOURCE_AWT_VCLXWINDOWS_INTERNAL_HXX +#define INCLUDED_TOOLKIT_SOURCE_AWT_VCLXWINDOWS_INTERNAL_HXX + +#include <vcl/window.hxx> + +namespace toolkit +{ +void setButtonLikeFaceColor(vcl::Window* _pWindow, const css::uno::Any& _rColorValue); +css::uno::Any getButtonLikeFaceColor(const vcl::Window* _pWindow); +} + +#endif // INCLUDED_TOOLKIT_SOURCE_AWT_VCLXWINDOWS_INTERNAL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |