summaryrefslogtreecommitdiffstats
path: root/svtools/source/hatchwindow
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /svtools/source/hatchwindow
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svtools/source/hatchwindow')
-rw-r--r--svtools/source/hatchwindow/documentcloser.cxx234
-rw-r--r--svtools/source/hatchwindow/hatchwindow.cxx201
-rw-r--r--svtools/source/hatchwindow/hatchwindowfactory.cxx89
-rw-r--r--svtools/source/hatchwindow/ipwin.cxx623
-rw-r--r--svtools/source/hatchwindow/ipwin.hxx92
5 files changed, 1239 insertions, 0 deletions
diff --git a/svtools/source/hatchwindow/documentcloser.cxx b/svtools/source/hatchwindow/documentcloser.cxx
new file mode 100644
index 000000000..6e014dd7e
--- /dev/null
+++ b/svtools/source/hatchwindow/documentcloser.cxx
@@ -0,0 +1,234 @@
+/* -*- 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 <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <comphelper/interfacecontainer2.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/dialoghelper.hxx>
+#include <vcl/window.hxx>
+#include <tools/link.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+// the service is implemented as a wrapper to be able to die by refcount
+// the disposing mechanics is required for java related scenarios
+class ODocumentCloser : public ::cppu::WeakImplHelper< css::lang::XComponent,
+ css::lang::XServiceInfo >
+{
+ ::osl::Mutex m_aMutex;
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+ std::unique_ptr<::comphelper::OInterfaceContainerHelper2> m_pListenersContainer; // list of listeners
+
+ bool m_bDisposed;
+
+public:
+ explicit ODocumentCloser(const css::uno::Sequence< css::uno::Any >& aArguments);
+
+// XComponent
+ virtual void SAL_CALL dispose() override;
+ virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) override;
+ virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) override;
+
+// 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;
+};
+
+class MainThreadFrameCloserRequest
+{
+ uno::Reference< frame::XFrame > m_xFrame;
+
+ public:
+ explicit MainThreadFrameCloserRequest( const uno::Reference< frame::XFrame >& xFrame )
+ : m_xFrame( xFrame )
+ {}
+
+ DECL_STATIC_LINK( MainThreadFrameCloserRequest, worker, void*, void );
+
+ static void Start( MainThreadFrameCloserRequest* pRequest );
+};
+
+
+void MainThreadFrameCloserRequest::Start( MainThreadFrameCloserRequest* pMTRequest )
+{
+ if ( pMTRequest )
+ {
+ if ( Application::IsMainThread() )
+ {
+ // this is the main thread
+ worker( nullptr, pMTRequest );
+ }
+ else
+ Application::PostUserEvent( LINK( nullptr, MainThreadFrameCloserRequest, worker ), pMTRequest );
+ }
+}
+
+
+IMPL_STATIC_LINK( MainThreadFrameCloserRequest, worker, void*, p, void )
+{
+ MainThreadFrameCloserRequest* pMTRequest = static_cast<MainThreadFrameCloserRequest*>(p);
+ if ( !pMTRequest )
+ return;
+
+ if ( pMTRequest->m_xFrame.is() )
+ {
+ // this is the main thread, the solar mutex must be locked
+ SolarMutexGuard aGuard;
+
+ try
+ {
+ uno::Reference< awt::XWindow > xWindow = pMTRequest->m_xFrame->getContainerWindow();
+ uno::Reference< awt::XVclWindowPeer > xWinPeer( xWindow, uno::UNO_QUERY_THROW );
+
+ xWindow->setVisible( false );
+
+ // reparent the window
+ xWinPeer->setProperty( "PluginParent", uno::makeAny( sal_Int64(0) ) );
+
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if (pWindow)
+ vcl::EndAllDialogs(pWindow);
+ }
+ catch( uno::Exception& )
+ {
+ // ignore all the errors
+ }
+
+ try
+ {
+ uno::Reference< util::XCloseable > xCloseable( pMTRequest->m_xFrame, uno::UNO_QUERY_THROW );
+ xCloseable->close( true );
+ }
+ catch( uno::Exception& )
+ {
+ // ignore all the errors
+ }
+ }
+
+ delete pMTRequest;
+}
+
+ODocumentCloser::ODocumentCloser(const css::uno::Sequence< css::uno::Any >& aArguments)
+: m_bDisposed( false )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_refCount )
+ throw uno::RuntimeException(); // the object must be refcounted already!
+
+ sal_Int32 nLen = aArguments.getLength();
+ if ( nLen != 1 )
+ throw lang::IllegalArgumentException(
+ "Wrong count of parameters!",
+ uno::Reference< uno::XInterface >(),
+ 0 );
+
+ if ( !( aArguments[0] >>= m_xFrame ) || !m_xFrame.is() )
+ throw lang::IllegalArgumentException(
+ "Nonempty reference is expected as the first argument!",
+ uno::Reference< uno::XInterface >(),
+ 0 );
+}
+
+
+// XComponent
+
+void SAL_CALL ODocumentCloser::dispose()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
+ if ( m_pListenersContainer )
+ m_pListenersContainer->disposeAndClear( aSource );
+
+ // TODO: trigger a main thread execution to close the frame
+ if ( m_xFrame.is() )
+ {
+ // the created object will be deleted after thread execution
+ MainThreadFrameCloserRequest* pCloser = new MainThreadFrameCloserRequest( m_xFrame );
+ MainThreadFrameCloserRequest::Start( pCloser );
+ }
+
+ m_bDisposed = true;
+}
+
+
+void SAL_CALL ODocumentCloser::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_bDisposed )
+ throw lang::DisposedException(); // TODO
+
+ if ( !m_pListenersContainer )
+ m_pListenersContainer.reset( new ::comphelper::OInterfaceContainerHelper2( m_aMutex ) );
+
+ m_pListenersContainer->addInterface( xListener );
+}
+
+
+void SAL_CALL ODocumentCloser::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_pListenersContainer )
+ m_pListenersContainer->removeInterface( xListener );
+}
+
+// XServiceInfo
+OUString SAL_CALL ODocumentCloser::getImplementationName( )
+{
+ return "com.sun.star.comp.embed.DocumentCloser";
+}
+
+sal_Bool SAL_CALL ODocumentCloser::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL ODocumentCloser::getSupportedServiceNames()
+{
+ return { "com.sun.star.embed.DocumentCloser" };
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_embed_DocumentCloser_get_implementation(
+ SAL_UNUSED_PARAMETER css::uno::XComponentContext *,
+ css::uno::Sequence<css::uno::Any> const &arguments)
+{
+ return cppu::acquire(new ODocumentCloser(arguments));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/hatchwindow/hatchwindow.cxx b/svtools/source/hatchwindow/hatchwindow.cxx
new file mode 100644
index 000000000..1402fde5a
--- /dev/null
+++ b/svtools/source/hatchwindow/hatchwindow.cxx
@@ -0,0 +1,201 @@
+/* -*- 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/embed/XHatchWindowController.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include <hatchwindow.hxx>
+#include "ipwin.hxx"
+
+#include <toolkit/helper/convert.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <osl/diagnose.h>
+#include <vcl/svapp.hxx>
+
+using namespace ::com::sun::star;
+
+VCLXHatchWindow::VCLXHatchWindow()
+: VCLXWindow()
+, pHatchWindow(nullptr)
+{
+}
+
+VCLXHatchWindow::~VCLXHatchWindow()
+{
+}
+
+void VCLXHatchWindow::initializeWindow( const uno::Reference< awt::XWindowPeer >& xParent,
+ const awt::Rectangle& aBounds,
+ const awt::Size& aSize )
+{
+ SolarMutexGuard aGuard;
+
+ VclPtr<vcl::Window> pParent;
+ VCLXWindow* pParentComponent = comphelper::getUnoTunnelImplementation<VCLXWindow>( xParent );
+
+ if ( pParentComponent )
+ pParent = pParentComponent->GetWindow();
+
+ OSL_ENSURE( pParent, "No parent window is provided!" );
+ if ( !pParent )
+ throw lang::IllegalArgumentException(); // TODO
+
+ pHatchWindow = VclPtr<SvResizeWindow>::Create( pParent, this );
+ pHatchWindow->setPosSizePixel( aBounds.X, aBounds.Y, aBounds.Width, aBounds.Height );
+ aHatchBorderSize = aSize;
+ pHatchWindow->SetHatchBorderPixel( Size( aSize.Width, aSize.Height ) );
+
+ SetWindow( pHatchWindow );
+ pHatchWindow->SetComponentInterface( this );
+
+ //pHatchWindow->Show();
+}
+
+void VCLXHatchWindow::QueryObjAreaPixel( tools::Rectangle & aRect )
+{
+ if ( !m_xController.is() )
+ return;
+
+ awt::Rectangle aUnoRequestRect = AWTRectangle( aRect );
+
+ try {
+ awt::Rectangle aUnoResultRect = m_xController->calcAdjustedRectangle( aUnoRequestRect );
+ aRect = VCLRectangle( aUnoResultRect );
+ }
+ catch( uno::Exception& )
+ {
+ OSL_FAIL( "Can't adjust rectangle size!" );
+ }
+}
+
+void VCLXHatchWindow::RequestObjAreaPixel( const tools::Rectangle & aRect )
+{
+ if ( m_xController.is() )
+ {
+ awt::Rectangle aUnoRequestRect = AWTRectangle( aRect );
+
+ try {
+ m_xController->requestPositioning( aUnoRequestRect );
+ }
+ catch( uno::Exception& )
+ {
+ OSL_FAIL( "Can't request resizing!" );
+ }
+ }
+}
+
+void VCLXHatchWindow::InplaceDeactivate()
+{
+ if ( m_xController.is() )
+ {
+ // TODO: communicate with controller
+ }
+}
+
+
+uno::Any SAL_CALL VCLXHatchWindow::queryInterface( const uno::Type & rType )
+{
+ // Attention:
+ // Don't use mutex or guard in this method!!! Is a method of XInterface.
+
+ uno::Any aReturn( ::cppu::queryInterface( rType,
+ static_cast< embed::XHatchWindow* >( this ) ) );
+
+ if ( aReturn.hasValue() )
+ {
+ return aReturn ;
+ }
+
+ return VCLXWindow::queryInterface( rType ) ;
+}
+
+void SAL_CALL VCLXHatchWindow::acquire()
+ throw()
+{
+ VCLXWindow::acquire();
+}
+
+void SAL_CALL VCLXHatchWindow::release()
+ throw()
+{
+ VCLXWindow::release();
+}
+
+uno::Sequence< uno::Type > SAL_CALL VCLXHatchWindow::getTypes()
+{
+ static cppu::OTypeCollection aTypeCollection(cppu::UnoType<embed::XHatchWindow>::get(),
+ VCLXWindow::getTypes());
+
+ return aTypeCollection.getTypes();
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL VCLXHatchWindow::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+css::awt::Size SAL_CALL VCLXHatchWindow::getHatchBorderSize()
+{
+ return aHatchBorderSize;
+}
+
+void SAL_CALL VCLXHatchWindow::setHatchBorderSize( const css::awt::Size& _hatchbordersize )
+{
+ if ( pHatchWindow )
+ {
+ aHatchBorderSize = _hatchbordersize;
+ pHatchWindow->SetHatchBorderPixel( Size( aHatchBorderSize.Width, aHatchBorderSize.Height ) );
+ }
+}
+
+void SAL_CALL VCLXHatchWindow::setController( const uno::Reference< embed::XHatchWindowController >& xController )
+{
+ m_xController = xController;
+}
+
+void SAL_CALL VCLXHatchWindow::dispose()
+{
+ pHatchWindow.clear();
+ VCLXWindow::dispose();
+}
+
+void SAL_CALL VCLXHatchWindow::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+{
+ VCLXWindow::addEventListener( xListener );
+}
+
+void SAL_CALL VCLXHatchWindow::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
+{
+ VCLXWindow::removeEventListener( xListener );
+}
+
+void VCLXHatchWindow::Activated()
+{
+ if ( m_xController.is() )
+ m_xController->activated();
+}
+
+void VCLXHatchWindow::Deactivated()
+{
+ if ( m_xController.is() )
+ m_xController->deactivated();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/hatchwindow/hatchwindowfactory.cxx b/svtools/source/hatchwindow/hatchwindowfactory.cxx
new file mode 100644
index 000000000..520cc1a25
--- /dev/null
+++ b/svtools/source/hatchwindow/hatchwindowfactory.cxx
@@ -0,0 +1,89 @@
+/* -*- 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/embed/XHatchWindowFactory.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <vcl/svapp.hxx>
+
+#include <hatchwindow.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+class OHatchWindowFactory : public ::cppu::WeakImplHelper<
+ embed::XHatchWindowFactory,
+ lang::XServiceInfo >
+{
+public:
+ OHatchWindowFactory() {}
+
+ // XHatchWindowFactory
+ virtual uno::Reference< embed::XHatchWindow > SAL_CALL createHatchWindowInstance( const uno::Reference< awt::XWindowPeer >& xParent, const awt::Rectangle& aBounds, const awt::Size& aSize ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+};
+
+uno::Reference< embed::XHatchWindow > SAL_CALL OHatchWindowFactory::createHatchWindowInstance(
+ const uno::Reference< awt::XWindowPeer >& xParent,
+ const awt::Rectangle& aBounds,
+ const awt::Size& aHandlerSize )
+{
+ if ( !xParent.is() )
+ throw lang::IllegalArgumentException(); // TODO
+
+ SolarMutexGuard aGuard;
+ VCLXHatchWindow* pResult = new VCLXHatchWindow();
+ pResult->initializeWindow( xParent, aBounds, aHandlerSize );
+ return uno::Reference< embed::XHatchWindow >( static_cast< embed::XHatchWindow* >( pResult ) );
+}
+
+OUString SAL_CALL OHatchWindowFactory::getImplementationName()
+{
+ return "com.sun.star.comp.embed.HatchWindowFactory";
+}
+
+sal_Bool SAL_CALL OHatchWindowFactory::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL OHatchWindowFactory::getSupportedServiceNames()
+{
+ return { "com.sun.star.embed.HatchWindowFactory", "com.sun.star.comp.embed.HatchWindowFactory" };
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_embed_HatchWindowFactory_get_implementation(
+ css::uno::XComponentContext *,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new OHatchWindowFactory);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/hatchwindow/ipwin.cxx b/svtools/source/hatchwindow/ipwin.cxx
new file mode 100644
index 000000000..751f3efa5
--- /dev/null
+++ b/svtools/source/hatchwindow/ipwin.cxx
@@ -0,0 +1,623 @@
+/* -*- 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 <osl/diagnose.h>
+#include <vcl/event.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/ptrstyle.hxx>
+
+#include "ipwin.hxx"
+#include <hatchwindow.hxx>
+
+/************************************************************************/
+/*************************************************************************
+|* SvResizeHelper::SvResizeHelper()
+|*
+|* Description
+*************************************************************************/
+SvResizeHelper::SvResizeHelper()
+ : aBorder( 5, 5 )
+ , nGrab( -1 )
+{
+}
+
+/*************************************************************************
+|* SvResizeHelper::FillHandleRects()
+|*
+|* Description: the eight handles to magnify
+*************************************************************************/
+std::array<tools::Rectangle,8> SvResizeHelper::FillHandleRectsPixel() const
+{
+ std::array<tools::Rectangle,8> aRects;
+
+ // only because of EMPTY_RECT
+ Point aBottomRight = aOuter.BottomRight();
+
+ // upper left
+ aRects[ 0 ] = tools::Rectangle( aOuter.TopLeft(), aBorder );
+ // upper middle
+ aRects[ 1 ] = tools::Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2,
+ aOuter.Top() ),
+ aBorder );
+ // upper right
+ aRects[ 2 ] = tools::Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
+ aOuter.Top() ),
+ aBorder );
+ // middle right
+ aRects[ 3 ] = tools::Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
+ aOuter.Center().Y() - aBorder.Height() / 2 ),
+ aBorder );
+ // lower right
+ aRects[ 4 ] = tools::Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
+ aBottomRight.Y() - aBorder.Height() +1 ),
+ aBorder );
+ // lower middle
+ aRects[ 5 ] = tools::Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2,
+ aBottomRight.Y() - aBorder.Height() +1),
+ aBorder );
+ // lower left
+ aRects[ 6 ] = tools::Rectangle( Point( aOuter.Left(),
+ aBottomRight.Y() - aBorder.Height() +1),
+ aBorder );
+ // middle left
+ aRects[ 7 ] = tools::Rectangle( Point( aOuter.Left(),
+ aOuter.Center().Y() - aBorder.Height() / 2 ),
+ aBorder );
+ return aRects;
+}
+
+/*************************************************************************
+|* SvResizeHelper::FillMoveRectsPixel()
+|*
+|* Description: the four edges are calculated
+*************************************************************************/
+std::array<tools::Rectangle,4> SvResizeHelper::FillMoveRectsPixel() const
+{
+ std::array<tools::Rectangle,4> aRects;
+
+ // upper
+ aRects[ 0 ] = aOuter;
+ aRects[ 0 ].SetBottom( aRects[ 0 ].Top() + aBorder.Height() -1 );
+ // right
+ aRects[ 1 ] = aOuter;
+ if (!aOuter.IsWidthEmpty())
+ aRects[ 1 ].SetLeft( aRects[ 1 ].Right() - aBorder.Width() -1 );
+ // lower
+ aRects[ 2 ] = aOuter;
+ if (!aOuter.IsHeightEmpty())
+ aRects[ 2 ].SetTop( aRects[ 2 ].Bottom() - aBorder.Height() -1 );
+ // left
+ aRects[ 3 ] = aOuter;
+ aRects[ 3 ].SetRight( aRects[ 3 ].Left() + aBorder.Width() -1 );
+
+ return aRects;
+}
+
+/*************************************************************************
+|* SvResizeHelper::Draw()
+|*
+|* Description
+*************************************************************************/
+void SvResizeHelper::Draw(vcl::RenderContext& rRenderContext)
+{
+ rRenderContext.Push();
+ rRenderContext.SetMapMode( MapMode() );
+
+ rRenderContext.SetFillColor( COL_LIGHTGRAY );
+ rRenderContext.SetLineColor();
+
+ std::array<tools::Rectangle,4> aMoveRects = FillMoveRectsPixel();
+ sal_uInt16 i;
+ for (i = 0; i < 4; i++)
+ rRenderContext.DrawRect(aMoveRects[i]);
+ // draw handles
+ rRenderContext.SetFillColor(Color()); // black
+ std::array<tools::Rectangle,8> aRects = FillHandleRectsPixel();
+ for (i = 0; i < 8; i++)
+ rRenderContext.DrawRect( aRects[ i ] );
+ rRenderContext.Pop();
+}
+
+/*************************************************************************
+|* SvResizeHelper::InvalidateBorder()
+|*
+|* Description
+*************************************************************************/
+void SvResizeHelper::InvalidateBorder( vcl::Window * pWin )
+{
+ std::array<tools::Rectangle,4> aMoveRects = FillMoveRectsPixel();
+ for(const auto & rMoveRect : aMoveRects)
+ pWin->Invalidate( rMoveRect );
+}
+
+/*************************************************************************
+|* SvResizeHelper::SelectBegin()
+|*
+|* Description
+*************************************************************************/
+bool SvResizeHelper::SelectBegin( vcl::Window * pWin, const Point & rPos )
+{
+ if( -1 == nGrab )
+ {
+ nGrab = SelectMove( pWin, rPos );
+ if( -1 != nGrab )
+ {
+ aSelPos = rPos; // store start position
+ pWin->CaptureMouse();
+ return true;
+ }
+ }
+ return false;
+}
+
+/*************************************************************************
+|* SvResizeHelper::SelectMove()
+|*
+|* Description
+*************************************************************************/
+short SvResizeHelper::SelectMove( vcl::Window * pWin, const Point & rPos )
+{
+ if( -1 == nGrab )
+ {
+ std::array<tools::Rectangle,8> aRects = FillHandleRectsPixel();
+ for( sal_uInt16 i = 0; i < 8; i++ )
+ if( aRects[ i ].IsInside( rPos ) )
+ return i;
+ // Move-Rect overlaps Handles
+ std::array<tools::Rectangle,4> aMoveRects = FillMoveRectsPixel();
+ for(const auto & rMoveRect : aMoveRects)
+ if( rMoveRect.IsInside( rPos ) )
+ return 8;
+ }
+ else
+ {
+ tools::Rectangle aRect( GetTrackRectPixel( rPos ) );
+ aRect.SetSize( pWin->PixelToLogic( aRect.GetSize() ) );
+ aRect.SetPos( pWin->PixelToLogic( aRect.TopLeft() ) );
+ pWin->ShowTracking( aRect );
+ }
+ return nGrab;
+}
+
+Point SvResizeHelper::GetTrackPosPixel( const tools::Rectangle & rRect ) const
+{
+ // not important how the rectangle is returned, it is important
+ // which handle has been touched
+ Point aPos;
+ tools::Rectangle aRect( rRect );
+ aRect.Justify();
+ // only because of EMPTY_RECT
+ Point aBR = aOuter.BottomRight();
+ Point aTR = aOuter.TopRight();
+ Point aBL = aOuter.BottomLeft();
+ bool bRTL = AllSettings::GetLayoutRTL();
+ switch( nGrab )
+ {
+ case 0:
+ // FIXME: disable it for RTL because it's wrong calculations
+ if( bRTL )
+ break;
+ aPos = aRect.TopLeft() - aOuter.TopLeft();
+ break;
+ case 1:
+ aPos.setY( aRect.Top() - aOuter.Top() );
+ break;
+ case 2:
+ // FIXME: disable it for RTL because it's wrong calculations
+ if( bRTL )
+ break;
+ aPos = aRect.TopRight() - aTR;
+ break;
+ case 3:
+ if( bRTL )
+ aPos.setX( aRect.Left() - aTR.X() );
+ else
+ aPos.setX( aRect.Right() - aTR.X() );
+ break;
+ case 4:
+ // FIXME: disable it for RTL because it's wrong calculations
+ if( bRTL )
+ break;
+ aPos = aRect.BottomRight() - aBR;
+ break;
+ case 5:
+ aPos.setY( aRect.Bottom() - aBR.Y() );
+ break;
+ case 6:
+ // FIXME: disable it for RTL because it's wrong calculations
+ if( bRTL )
+ break;
+ aPos = aRect.BottomLeft() - aBL;
+ break;
+ case 7:
+ if( bRTL )
+ aPos.setX( aRect.Right() + aOuter.Right() - aOuter.TopRight().X() );
+ else
+ aPos.setX( aRect.Left() - aOuter.Left() );
+ break;
+ case 8:
+ aPos = aRect.TopLeft() - aOuter.TopLeft();
+ break;
+ }
+ return aPos + aSelPos;
+}
+
+/*************************************************************************
+|* SvResizeHelper::GetTrackRectPixel()
+|*
+|* Description
+*************************************************************************/
+tools::Rectangle SvResizeHelper::GetTrackRectPixel( const Point & rTrackPos ) const
+{
+ tools::Rectangle aTrackRect;
+ if( -1 != nGrab )
+ {
+ Point aDiff = rTrackPos - aSelPos;
+ aTrackRect = aOuter;
+ Point aBR = aOuter.BottomRight();
+ bool bRTL = AllSettings::GetLayoutRTL();
+ switch( nGrab )
+ {
+ case 0:
+ aTrackRect.AdjustTop(aDiff.Y() );
+ // ugly solution for resizing OLE objects in RTL
+ if( bRTL )
+ aTrackRect.SetRight( aBR.X() - aDiff.X() );
+ else
+ aTrackRect.AdjustLeft(aDiff.X() );
+ break;
+ case 1:
+ aTrackRect.AdjustTop(aDiff.Y() );
+ break;
+ case 2:
+ aTrackRect.AdjustTop(aDiff.Y() );
+ // ugly solution for resizing OLE objects in RTL
+ if( bRTL )
+ aTrackRect.AdjustLeft( -(aDiff.X()) );
+ else
+ aTrackRect.SetRight( aBR.X() + aDiff.X() );
+ break;
+ case 3:
+ // ugly solution for resizing OLE objects in RTL
+ if( bRTL )
+ aTrackRect.AdjustLeft( -(aDiff.X()) );
+ else
+ aTrackRect.SetRight( aBR.X() + aDiff.X() );
+ break;
+ case 4:
+ aTrackRect.SetBottom( aBR.Y() + aDiff.Y() );
+ // ugly solution for resizing OLE objects in RTL
+ if( bRTL )
+ aTrackRect.AdjustLeft( -(aDiff.X()) );
+ else
+ aTrackRect.SetRight( aBR.X() + aDiff.X() );
+ break;
+ case 5:
+ aTrackRect.SetBottom( aBR.Y() + aDiff.Y() );
+ break;
+ case 6:
+ aTrackRect.SetBottom( aBR.Y() + aDiff.Y() );
+ // ugly solution for resizing OLE objects in RTL
+ if( bRTL )
+ aTrackRect.SetRight( aBR.X() - aDiff.X() );
+ else
+ aTrackRect.AdjustLeft(aDiff.X() );
+ break;
+ case 7:
+ // ugly solution for resizing OLE objects in RTL
+ if( bRTL )
+ aTrackRect.SetRight( aBR.X() - aDiff.X() );
+ else
+ aTrackRect.AdjustLeft(aDiff.X() );
+ break;
+ case 8:
+ if( bRTL )
+ aDiff.setX( -aDiff.X() ); // workaround for move in RTL mode
+ aTrackRect.SetPos( aTrackRect.TopLeft() + aDiff );
+ break;
+ }
+ }
+ return aTrackRect;
+}
+
+void SvResizeHelper::ValidateRect( tools::Rectangle & rValidate ) const
+{
+ switch( nGrab )
+ {
+ case 0:
+ if( rValidate.Top() > rValidate.Bottom() )
+ rValidate.SetTop( rValidate.Bottom() );
+ if( rValidate.Left() > rValidate.Right() )
+ rValidate.SetLeft( rValidate.Right() );
+ break;
+ case 1:
+ if( rValidate.Top() > rValidate.Bottom() )
+ rValidate.SetTop( rValidate.Bottom() );
+ break;
+ case 2:
+ if( rValidate.Top() > rValidate.Bottom() )
+ rValidate.SetTop( rValidate.Bottom() );
+ if( rValidate.Left() > rValidate.Right() )
+ rValidate.SetRight( rValidate.Left() );
+ break;
+ case 3:
+ if( rValidate.Left() > rValidate.Right() )
+ rValidate.SetRight( rValidate.Left() );
+ break;
+ case 4:
+ if( rValidate.Top() > rValidate.Bottom() )
+ rValidate.SetBottom( rValidate.Top() );
+ if( rValidate.Left() > rValidate.Right() )
+ rValidate.SetRight( rValidate.Left() );
+ break;
+ case 5:
+ if( rValidate.Top() > rValidate.Bottom() )
+ rValidate.SetBottom( rValidate.Top() );
+ break;
+ case 6:
+ if( rValidate.Top() > rValidate.Bottom() )
+ rValidate.SetBottom( rValidate.Top() );
+ if( rValidate.Left() > rValidate.Right() )
+ rValidate.SetLeft( rValidate.Right() );
+ break;
+ case 7:
+ if( rValidate.Left() > rValidate.Right() )
+ rValidate.SetLeft( rValidate.Right() );
+ break;
+ }
+
+ // Mindestgr"osse 5 x 5
+ if( rValidate.Left() + 5 > rValidate.Right() )
+ rValidate.SetRight( rValidate.Left() + 5 );
+ if( rValidate.Top() + 5 > rValidate.Bottom() )
+ rValidate.SetBottom( rValidate.Top() + 5 );
+}
+
+/*************************************************************************
+|* SvResizeHelper::SelectRelease()
+|*
+|* Description
+*************************************************************************/
+bool SvResizeHelper::SelectRelease( vcl::Window * pWin, const Point & rPos,
+ tools::Rectangle & rOutPosSize )
+{
+ if( -1 != nGrab )
+ {
+ rOutPosSize = GetTrackRectPixel( rPos );
+ rOutPosSize.Justify();
+ nGrab = -1;
+ pWin->ReleaseMouse();
+ pWin->HideTracking();
+ return true;
+ }
+ return false;
+}
+
+/*************************************************************************
+|* SvResizeHelper::Release()
+|*
+|* Description
+*************************************************************************/
+void SvResizeHelper::Release( vcl::Window * pWin )
+{
+ if( nGrab != -1 )
+ {
+ pWin->ReleaseMouse();
+ pWin->HideTracking();
+ nGrab = -1;
+ }
+}
+
+/*************************************************************************
+|* SvResizeWindow::SvResizeWindow()
+|*
+|* Description
+*************************************************************************/
+SvResizeWindow::SvResizeWindow
+(
+ vcl::Window * pParent,
+ VCLXHatchWindow* pWrapper
+)
+ : Window( pParent, WB_CLIPCHILDREN )
+ , m_aOldPointer(PointerStyle::Arrow)
+ , m_nMoveGrab( -1 )
+ , m_bActive( false )
+ , m_pWrapper( pWrapper )
+{
+ OSL_ENSURE( pParent != nullptr && pWrapper != nullptr, "Wrong initialization of hatch window!" );
+ SetBackground();
+ SetAccessibleRole( css::accessibility::AccessibleRole::EMBEDDED_OBJECT );
+ m_aResizer.SetOuterRectPixel( tools::Rectangle( Point(), GetOutputSizePixel() ) );
+}
+
+/*************************************************************************
+|* SvResizeWindow::SetHatchBorderPixel()
+|*
+|* Description
+*************************************************************************/
+void SvResizeWindow::SetHatchBorderPixel( const Size & rSize )
+{
+ m_aResizer.SetBorderPixel( rSize );
+}
+
+/*************************************************************************
+|* SvResizeWindow::SelectMouse()
+|*
+|* Description
+*************************************************************************/
+void SvResizeWindow::SelectMouse( const Point & rPos )
+{
+ short nGrab = m_aResizer.SelectMove( this, rPos );
+ if( nGrab >= 4 )
+ nGrab -= 4;
+ if( m_nMoveGrab == nGrab )
+ return;
+
+ // Pointer did change
+ if( -1 == nGrab )
+ SetPointer( m_aOldPointer );
+ else
+ {
+ PointerStyle aStyle = PointerStyle::Move;
+ if( nGrab == 3 )
+ aStyle = PointerStyle::ESize;
+ else if( nGrab == 2 )
+ aStyle = PointerStyle::NESize;
+ else if( nGrab == 1 )
+ aStyle = PointerStyle::SSize;
+ else if( nGrab == 0 )
+ aStyle = PointerStyle::SESize;
+ if( m_nMoveGrab == -1 ) // the first time
+ {
+ m_aOldPointer = GetPointer();
+ SetPointer( aStyle );
+ }
+ else
+ SetPointer( aStyle );
+ }
+ m_nMoveGrab = nGrab;
+}
+
+/*************************************************************************
+|* SvResizeWindow::MouseButtonDown()
+|*
+|* Description
+*************************************************************************/
+void SvResizeWindow::MouseButtonDown( const MouseEvent & rEvt )
+{
+ if( m_aResizer.SelectBegin( this, rEvt.GetPosPixel() ) )
+ SelectMouse( rEvt.GetPosPixel() );
+}
+
+/*************************************************************************
+|* SvResizeWindow::MouseMove()
+|*
+|* Description
+*************************************************************************/
+void SvResizeWindow::MouseMove( const MouseEvent & rEvt )
+{
+ if( m_aResizer.GetGrab() == -1 )
+ SelectMouse( rEvt.GetPosPixel() );
+ else
+ {
+ tools::Rectangle aRect( m_aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) );
+ Point aDiff = GetPosPixel();
+ aRect.SetPos( aRect.TopLeft() + aDiff );
+ m_aResizer.ValidateRect( aRect );
+
+ m_pWrapper->QueryObjAreaPixel( aRect );
+ aRect.SetPos( aRect.TopLeft() - aDiff );
+ Point aPos = m_aResizer.GetTrackPosPixel( aRect );
+
+ SelectMouse( aPos );
+ }
+}
+
+/*************************************************************************
+|* SvResizeWindow::MouseButtonUp()
+|*
+|* Description
+*************************************************************************/
+void SvResizeWindow::MouseButtonUp( const MouseEvent & rEvt )
+{
+ if( m_aResizer.GetGrab() == -1 )
+ return;
+
+ tools::Rectangle aRect( m_aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) );
+ Point aDiff = GetPosPixel();
+ aRect.SetPos( aRect.TopLeft() + aDiff );
+ // aRect -= GetAllBorderPixel();
+ m_aResizer.ValidateRect( aRect );
+
+ m_pWrapper->QueryObjAreaPixel( aRect );
+
+ tools::Rectangle aOutRect;
+ if( m_aResizer.SelectRelease( this, rEvt.GetPosPixel(), aOutRect ) )
+ {
+ m_nMoveGrab = -1;
+ SetPointer( m_aOldPointer );
+ m_pWrapper->RequestObjAreaPixel( aRect );
+ }
+}
+
+/*************************************************************************
+|* SvResizeWindow::KeyEvent()
+|*
+|* Description
+*************************************************************************/
+void SvResizeWindow::KeyInput( const KeyEvent & rEvt )
+{
+ if( rEvt.GetKeyCode().GetCode() == KEY_ESCAPE )
+ {
+ m_aResizer.Release( this );
+ m_pWrapper->InplaceDeactivate();
+ }
+}
+
+/*************************************************************************
+|* SvResizeWindow::Resize()
+|*
+|* Description
+*************************************************************************/
+void SvResizeWindow::Resize()
+{
+ m_aResizer.InvalidateBorder( this ); // old area
+ m_aResizer.SetOuterRectPixel( tools::Rectangle( Point(), GetOutputSizePixel() ) );
+ m_aResizer.InvalidateBorder( this ); // new area
+}
+
+/*************************************************************************
+|* SvResizeWindow::Paint()
+|*
+|* Description
+*************************************************************************/
+void SvResizeWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle & /*rRect*/ )
+{
+ m_aResizer.Draw(rRenderContext);
+}
+
+bool SvResizeWindow::PreNotify( NotifyEvent& rEvt )
+{
+ if ( rEvt.GetType() == MouseNotifyEvent::GETFOCUS && !m_bActive )
+ {
+ m_bActive = true;
+ m_pWrapper->Activated();
+ }
+
+ return Window::PreNotify(rEvt);
+}
+
+bool SvResizeWindow::EventNotify( NotifyEvent& rEvt )
+{
+ if ( rEvt.GetType() == MouseNotifyEvent::LOSEFOCUS && m_bActive )
+ {
+ bool bHasFocus = HasChildPathFocus(true);
+ if ( !bHasFocus )
+ {
+ m_bActive = false;
+ m_pWrapper->Deactivated();
+ }
+ }
+
+ return Window::EventNotify(rEvt);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/hatchwindow/ipwin.hxx b/svtools/source/hatchwindow/ipwin.hxx
new file mode 100644
index 000000000..72567ce26
--- /dev/null
+++ b/svtools/source/hatchwindow/ipwin.hxx
@@ -0,0 +1,92 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <tools/gen.hxx>
+#include <vcl/window.hxx>
+#include <array>
+
+/********************** SvResizeHelper ***********************************
+*************************************************************************/
+class SvResizeHelper
+{
+ Size aBorder;
+ tools::Rectangle aOuter;
+ short nGrab; // -1 no Grab, 0 - 7, 8 = Move, see FillHandle...
+ Point aSelPos;
+public:
+ SvResizeHelper();
+
+ short GetGrab() const
+ {
+ return nGrab;
+ }
+ void SetBorderPixel(const Size & rBorderP)
+ {
+ aBorder = rBorderP;
+ }
+ void SetOuterRectPixel(const tools::Rectangle& rRect)
+ {
+ aOuter = rRect;
+ }
+ // Clockwise, start at upper left
+
+ std::array<tools::Rectangle,8> FillHandleRectsPixel() const;
+ std::array<tools::Rectangle,4> FillMoveRectsPixel() const;
+ void Draw(vcl::RenderContext& rRenderContext);
+ void InvalidateBorder( vcl::Window * );
+ bool SelectBegin( vcl::Window *, const Point & rPos );
+ short SelectMove( vcl::Window * pWin, const Point & rPos );
+ Point GetTrackPosPixel( const tools::Rectangle & rRect ) const;
+ tools::Rectangle GetTrackRectPixel( const Point & rTrackPos ) const;
+ void ValidateRect( tools::Rectangle & rValidate ) const;
+ bool SelectRelease( vcl::Window *, const Point & rPos, tools::Rectangle & rOutPosSize );
+ void Release( vcl::Window * pWin );
+};
+
+/********************** SvResizeWindow ***********************************
+*************************************************************************/
+class VCLXHatchWindow;
+class SvResizeWindow : public vcl::Window
+{
+ PointerStyle m_aOldPointer;
+ short m_nMoveGrab; // last pointer type
+ SvResizeHelper m_aResizer;
+ bool m_bActive;
+
+ VCLXHatchWindow* m_pWrapper;
+public:
+ SvResizeWindow( vcl::Window* pParent, VCLXHatchWindow* pWrapper );
+
+ void SetHatchBorderPixel( const Size & rSize );
+
+ void SelectMouse( const Point & rPos );
+ virtual void MouseButtonUp( const MouseEvent & rEvt ) override;
+ virtual void MouseMove( const MouseEvent & rEvt ) override;
+ virtual void MouseButtonDown( const MouseEvent & rEvt ) override;
+ virtual void KeyInput( const KeyEvent & rEvt ) override;
+ virtual void Resize() override;
+ virtual void Paint( vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle & ) override;
+ virtual bool EventNotify( NotifyEvent& rNEvt ) override;
+ virtual bool PreNotify( NotifyEvent& rNEvt ) override;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */