summaryrefslogtreecommitdiffstats
path: root/basctl/source/dlged
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /basctl/source/dlged
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.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 'basctl/source/dlged')
-rw-r--r--basctl/source/dlged/dlged.cxx1242
-rw-r--r--basctl/source/dlged/dlgedclip.cxx109
-rw-r--r--basctl/source/dlged/dlgedfac.cxx232
-rw-r--r--basctl/source/dlged/dlgedfunc.cxx548
-rw-r--r--basctl/source/dlged/dlgedlist.cxx80
-rw-r--r--basctl/source/dlged/dlgedmod.cxx36
-rw-r--r--basctl/source/dlged/dlgedobj.cxx1703
-rw-r--r--basctl/source/dlged/dlgedpage.cxx66
-rw-r--r--basctl/source/dlged/dlgedview.cxx184
-rw-r--r--basctl/source/dlged/managelang.cxx318
-rw-r--r--basctl/source/dlged/propbrw.cxx506
11 files changed, 5024 insertions, 0 deletions
diff --git a/basctl/source/dlged/dlged.cxx b/basctl/source/dlged/dlged.cxx
new file mode 100644
index 000000000..81fa3f14e
--- /dev/null
+++ b/basctl/source/dlged/dlged.cxx
@@ -0,0 +1,1242 @@
+/* -*- 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 <dlged.hxx>
+#include <dlgedclip.hxx>
+#include <dlgeddef.hxx>
+#include <dlgedfac.hxx>
+#include <dlgedfunc.hxx>
+#include <dlgedmod.hxx>
+#include <dlgedobj.hxx>
+#include <dlgedpage.hxx>
+#include <dlgedview.hxx>
+#include <localizationmgr.hxx>
+#include <baside3.hxx>
+
+#include <com/sun/star/awt/Toolkit.hpp>
+#include <com/sun/star/awt/UnoControlDialog.hpp>
+#include <com/sun/star/resource/StringResource.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/util/NumberFormatsSupplier.hpp>
+#include <comphelper/types.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/debug.hxx>
+#include <svl/itempool.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <svx/svdpagv.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/print.hxx>
+#include <vcl/scrbar.hxx>
+#include <vcl/svapp.hxx>
+#include <xmlscript/xml_helper.hxx>
+#include <xmlscript/xmldlg_imexp.hxx>
+#include <osl/diagnose.h>
+
+namespace basctl
+{
+
+using namespace comphelper;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+
+constexpr OUStringLiteral aResourceResolverPropName = u"ResourceResolver";
+constexpr OUStringLiteral aDecorationPropName = u"Decoration";
+
+
+// DlgEdHint
+
+
+DlgEdHint::DlgEdHint(Kind eHint)
+ : eKind(eHint)
+ , pDlgEdObj(nullptr)
+{
+}
+
+DlgEdHint::DlgEdHint(Kind eHint, DlgEdObj* pObj)
+ : eKind(eHint)
+ , pDlgEdObj(pObj)
+{
+}
+
+DlgEdHint::~DlgEdHint()
+{
+}
+
+
+// DlgEditor
+
+
+void DlgEditor::ShowDialog()
+{
+ uno::Reference< uno::XComponentContext > xContext = getProcessComponentContext();
+
+ // create a dialog
+ uno::Reference< awt::XUnoControlDialog > xDlg = awt::UnoControlDialog::create( xContext );
+
+ // clone the dialog model
+ uno::Reference< util::XCloneable > xC( m_xUnoControlDialogModel, uno::UNO_QUERY );
+ uno::Reference< util::XCloneable > xNew = xC->createClone();
+ uno::Reference< awt::XControlModel > xDlgMod( xNew, uno::UNO_QUERY );
+
+ uno::Reference< beans::XPropertySet > xSrcDlgModPropSet( m_xUnoControlDialogModel, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySet > xNewDlgModPropSet( xDlgMod, uno::UNO_QUERY );
+ if( xNewDlgModPropSet.is() )
+ {
+ if( xSrcDlgModPropSet.is() )
+ {
+ try
+ {
+ Any aResourceResolver = xSrcDlgModPropSet->getPropertyValue( aResourceResolverPropName );
+ xNewDlgModPropSet->setPropertyValue( aResourceResolverPropName, aResourceResolver );
+ }
+ catch(const UnknownPropertyException& )
+ {
+ OSL_FAIL( "DlgEditor::ShowDialog(): No ResourceResolver property" );
+ }
+ }
+
+ // Disable decoration
+ try
+ {
+ bool bDecoration = true;
+
+ Any aDecorationAny = xSrcDlgModPropSet->getPropertyValue( aDecorationPropName );
+ aDecorationAny >>= bDecoration;
+ if( !bDecoration )
+ {
+ xNewDlgModPropSet->setPropertyValue( aDecorationPropName, Any( true ) );
+ xNewDlgModPropSet->setPropertyValue( "Title", Any( OUString() ) );
+ }
+ }
+ catch(const UnknownPropertyException& )
+ {}
+ }
+
+ // set the model
+ xDlg->setModel( xDlgMod );
+
+ // create a peer
+ uno::Reference< awt::XToolkit> xToolkit = awt::Toolkit::create( xContext );
+ xDlg->createPeer( xToolkit, rWindow.GetComponentInterface() );
+
+ xDlg->execute();
+
+ // need to cast because of multiple inheritance
+ Reference<awt::XControl>(xDlg)->dispose();
+}
+
+
+bool DlgEditor::UnmarkDialog()
+{
+ SdrObject* pDlgObj = pDlgEdModel->GetPage(0)->GetObj(0);
+ SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
+
+ bool bWasMarked = pDlgEdView->IsObjMarked( pDlgObj );
+
+ if( bWasMarked )
+ pDlgEdView->MarkObj( pDlgObj, pPgView, true );
+
+ return bWasMarked;
+}
+
+
+bool DlgEditor::RemarkDialog()
+{
+ SdrObject* pDlgObj = pDlgEdModel->GetPage(0)->GetObj(0);
+ SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
+
+ bool bWasMarked = pDlgEdView->IsObjMarked( pDlgObj );
+
+ if( !bWasMarked )
+ pDlgEdView->MarkObj( pDlgObj, pPgView );
+
+ return bWasMarked;
+}
+
+
+DlgEditor::DlgEditor (
+ vcl::Window& rWindow_, DialogWindowLayout& rLayout_,
+ css::uno::Reference<css::frame::XModel> const& xModel,
+ css::uno::Reference<css::container::XNameContainer> const & xDialogModel
+)
+ :pHScroll(nullptr)
+ ,pVScroll(nullptr)
+ ,pDlgEdModel(new DlgEdModel())
+ ,pDlgEdPage(new DlgEdPage(*pDlgEdModel))
+ // set clipboard data flavors
+ ,m_ClipboardDataFlavors{ { /* MimeType */ "application/vnd.sun.xml.dialog",
+ /* HumanPresentableName */ "Dialog 6.0",
+ /* DataType */ cppu::UnoType<Sequence< sal_Int8 >>::get() } }
+ ,m_ClipboardDataFlavorsResource{ m_ClipboardDataFlavors[0],
+ { /* MimeType */ "application/vnd.sun.xml.dialogwithresource",
+ /* HumanPresentableName */ "Dialog 8.0",
+ /* DataType */ cppu::UnoType<Sequence< sal_Int8 >>::get() } }
+ ,pObjFac(new DlgEdFactory(xModel))
+ ,rWindow(rWindow_)
+ ,pFunc(new DlgEdFuncSelect(*this))
+ ,rLayout(rLayout_)
+ ,eMode( DlgEditor::SELECT )
+ ,eActObj( SdrObjKind::BasicDialogPushButton )
+ ,bFirstDraw(false)
+ ,bCreateOK(true)
+ ,bDialogModelChanged(false)
+ ,aMarkIdle("basctl DlgEditor Mark")
+ ,mnPaintGuard(0)
+ ,m_xDocument( xModel )
+{
+ pDlgEdModel->GetItemPool().FreezeIdRanges();
+ pDlgEdView.reset(new DlgEdView(*pDlgEdModel, *rWindow_.GetOutDev(), *this));
+ pDlgEdModel->SetScaleUnit( MapUnit::Map100thMM );
+
+ SdrLayerAdmin& rAdmin = pDlgEdModel->GetLayerAdmin();
+ rAdmin.NewLayer( rAdmin.GetControlLayerName() );
+ rAdmin.NewLayer( "HiddenLayer" );
+
+ pDlgEdModel->InsertPage(pDlgEdPage);
+
+ aMarkIdle.SetInvokeHandler( LINK( this, DlgEditor, MarkTimeout ) );
+
+ rWindow.SetMapMode( MapMode( MapUnit::Map100thMM ) );
+ pDlgEdPage->SetSize( rWindow.PixelToLogic( Size(DLGED_PAGE_WIDTH_MIN, DLGED_PAGE_HEIGHT_MIN) ) );
+
+ pDlgEdView->ShowSdrPage(pDlgEdView->GetModel()->GetPage(0));
+ pDlgEdView->SetLayerVisible( "HiddenLayer", false );
+ pDlgEdView->SetMoveSnapOnlyTopLeft(true);
+ pDlgEdView->SetWorkArea( tools::Rectangle( Point( 0, 0 ), pDlgEdPage->GetSize() ) );
+
+ Size aGridSize( 100, 100 ); // 100TH_MM
+ pDlgEdView->SetGridCoarse( aGridSize );
+ pDlgEdView->SetSnapGridWidth(Fraction(aGridSize.Width(), 1), Fraction(aGridSize.Height(), 1));
+ pDlgEdView->SetGridSnap( true );
+ pDlgEdView->SetGridVisible( false );
+ pDlgEdView->SetDragStripes(false);
+
+ pDlgEdView->SetDesignMode();
+
+ ::comphelper::disposeComponent( m_xControlContainer );
+
+ SetDialog(xDialogModel);
+}
+
+
+DlgEditor::~DlgEditor()
+{
+ aMarkIdle.Stop();
+
+ ::comphelper::disposeComponent( m_xControlContainer );
+}
+
+
+Reference< awt::XControlContainer > const & DlgEditor::GetWindowControlContainer()
+{
+ if (!m_xControlContainer.is())
+ m_xControlContainer = VCLUnoHelper::CreateControlContainer(&rWindow);
+ return m_xControlContainer;
+}
+
+
+void DlgEditor::SetScrollBars( ScrollBar* pHS, ScrollBar* pVS )
+{
+ pHScroll = pHS;
+ pVScroll = pVS;
+
+ InitScrollBars();
+}
+
+
+void DlgEditor::InitScrollBars()
+{
+ DBG_ASSERT( pHScroll, "DlgEditor::InitScrollBars: no horizontal scroll bar!" );
+ DBG_ASSERT( pVScroll, "DlgEditor::InitScrollBars: no vertical scroll bar!" );
+ if ( !pHScroll || !pVScroll )
+ return;
+
+ Size aOutSize = rWindow.GetOutDev()->GetOutputSize();
+ Size aPgSize = pDlgEdPage->GetSize();
+
+ pHScroll->SetRange( Range( 0, aPgSize.Width() ));
+ pVScroll->SetRange( Range( 0, aPgSize.Height() ));
+ pHScroll->SetVisibleSize( aOutSize.Width() );
+ pVScroll->SetVisibleSize( aOutSize.Height() );
+
+ pHScroll->SetLineSize( aOutSize.Width() / 10 );
+ pVScroll->SetLineSize( aOutSize.Height() / 10 );
+ pHScroll->SetPageSize( aOutSize.Width() / 2 );
+ pVScroll->SetPageSize( aOutSize.Height() / 2 );
+
+ DoScroll();
+}
+
+
+void DlgEditor::DoScroll()
+{
+ if( !pHScroll || !pVScroll )
+ return;
+
+ MapMode aMap = rWindow.GetMapMode();
+ Point aOrg = aMap.GetOrigin();
+
+ Size aScrollPos( pHScroll->GetThumbPos(), pVScroll->GetThumbPos() );
+ aScrollPos = rWindow.LogicToPixel( aScrollPos );
+ aScrollPos = rWindow.PixelToLogic( aScrollPos );
+
+ tools::Long nX = aScrollPos.Width() + aOrg.X();
+ tools::Long nY = aScrollPos.Height() + aOrg.Y();
+
+ if( !nX && !nY )
+ return;
+
+ rWindow.PaintImmediately();
+
+ // #i31562#
+ // When scrolling, someone was rescuing the Wallpaper and forced the window scroll to
+ // be done without background refresh. I do not know why, but that causes the repaint
+ // problems. Taking that out.
+ // Wallpaper aOldBackground = rWindow.GetBackground();
+ // rWindow.SetBackground();
+
+ // #i74769# children should be scrolled
+ rWindow.Scroll( -nX, -nY, ScrollFlags::Children);
+ aMap.SetOrigin( Point( -aScrollPos.Width(), -aScrollPos.Height() ) );
+ rWindow.SetMapMode( aMap );
+ rWindow.PaintImmediately();
+
+ DlgEdHint aHint( DlgEdHint::WINDOWSCROLLED );
+ Broadcast( aHint );
+}
+
+
+void DlgEditor::UpdateScrollBars()
+{
+ MapMode aMap = rWindow.GetMapMode();
+ Point aOrg = aMap.GetOrigin();
+
+ if ( pHScroll )
+ pHScroll->SetThumbPos( -aOrg.X() );
+
+ if ( pVScroll )
+ pVScroll->SetThumbPos( -aOrg.Y() );
+}
+
+
+void DlgEditor::SetDialog( const uno::Reference< container::XNameContainer >& xUnoControlDialogModel )
+{
+ // set dialog model
+ m_xUnoControlDialogModel = xUnoControlDialogModel;
+
+ // create dialog form
+ pDlgEdForm = new DlgEdForm(*pDlgEdModel, *this);
+ uno::Reference< awt::XControlModel > xDlgMod( m_xUnoControlDialogModel , uno::UNO_QUERY );
+ pDlgEdForm->SetUnoControlModel(xDlgMod);
+ static_cast<DlgEdPage*>(pDlgEdModel->GetPage(0))->SetDlgEdForm( pDlgEdForm );
+ pDlgEdModel->GetPage(0)->InsertObject( pDlgEdForm );
+ AdjustPageSize();
+ pDlgEdForm->SetRectFromProps();
+ pDlgEdForm->UpdateTabIndices(); // for backward compatibility
+ pDlgEdForm->StartListening();
+
+ // create controls
+ if ( m_xUnoControlDialogModel.is() )
+ {
+ // get sequence of control names
+ Sequence< OUString > aNames = m_xUnoControlDialogModel->getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 nCtrls = aNames.getLength();
+
+ // create a map of tab indices and control names, sorted by tab index
+ IndexToNameMap aIndexToNameMap;
+ for ( sal_Int32 i = 0; i < nCtrls; ++i )
+ {
+ // get name
+ OUString aName( pNames[i] );
+
+ // get tab index
+ sal_Int16 nTabIndex = -1;
+ Any aCtrl = m_xUnoControlDialogModel->getByName( aName );
+ Reference< css::beans::XPropertySet > xPSet;
+ aCtrl >>= xPSet;
+ if ( xPSet.is() )
+ xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
+
+ // insert into map
+ aIndexToNameMap.emplace( nTabIndex, aName );
+ }
+
+ // create controls and insert them into drawing page
+ for (auto const& indexToName : aIndexToNameMap)
+ {
+ Any aCtrl = m_xUnoControlDialogModel->getByName( indexToName.second );
+ Reference< css::awt::XControlModel > xCtrlModel;
+ aCtrl >>= xCtrlModel;
+ DlgEdObj* pCtrlObj = new DlgEdObj(*pDlgEdModel);
+ pCtrlObj->SetUnoControlModel( xCtrlModel );
+ pCtrlObj->SetDlgEdForm( pDlgEdForm );
+ pDlgEdForm->AddChild( pCtrlObj );
+ pDlgEdModel->GetPage(0)->InsertObject( pCtrlObj );
+ pCtrlObj->SetRectFromProps();
+ pCtrlObj->UpdateStep();
+ pCtrlObj->StartListening();
+ }
+ }
+
+ bFirstDraw = true;
+
+ pDlgEdModel->SetChanged(false);
+}
+
+void DlgEditor::ResetDialog ()
+{
+ DlgEdForm* pOldDlgEdForm = pDlgEdForm;
+ DlgEdPage* pPage = static_cast<DlgEdPage*>(pDlgEdModel->GetPage(0));
+ SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
+ bool bWasMarked = pDlgEdView->IsObjMarked( pOldDlgEdForm );
+ pDlgEdView->UnmarkAll();
+
+ // clear SdrObjects with broadcasting
+ pPage->ClearSdrObjList();
+
+ pPage->SetDlgEdForm( nullptr );
+ SetDialog( m_xUnoControlDialogModel );
+ if( bWasMarked )
+ pDlgEdView->MarkObj( pDlgEdForm, pPgView );
+}
+
+
+Reference< util::XNumberFormatsSupplier > const & DlgEditor::GetNumberFormatsSupplier()
+{
+ if ( !m_xSupplier.is() )
+ {
+ Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< util::XNumberFormatsSupplier > xSupplier( util::NumberFormatsSupplier::createWithDefaultLocale(xContext) );
+
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !m_xSupplier.is() )
+ {
+ m_xSupplier = xSupplier;
+ }
+ }
+ return m_xSupplier;
+}
+
+
+void DlgEditor::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ rWindow.GrabFocus();
+ pFunc->MouseButtonDown( rMEvt );
+}
+
+
+void DlgEditor::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ bool bRet = pFunc->MouseButtonUp( rMEvt );
+
+ if( eMode == DlgEditor::INSERT )
+ bCreateOK = bRet;
+}
+
+
+void DlgEditor::MouseMove( const MouseEvent& rMEvt )
+{
+ pFunc->MouseMove( rMEvt );
+}
+
+
+bool DlgEditor::KeyInput( const KeyEvent& rKEvt )
+{
+ return pFunc->KeyInput( rKEvt );
+}
+
+
+void DlgEditor::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
+{
+ aPaintRect = rRect;
+ mnPaintGuard++;
+
+ if (bFirstDraw && rWindow.IsVisible() && (rRenderContext.GetOutputSize() != Size()))
+ {
+ bFirstDraw = false;
+
+ // get property set
+ css::uno::Reference<css::beans::XPropertySet> xPSet(pDlgEdForm->GetUnoControlModel(), css::uno::UNO_QUERY);
+
+ if (xPSet.is())
+ {
+ // get dialog size from properties
+ sal_Int32 nWidth = 0, nHeight = 0;
+ xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
+ xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
+
+ if (nWidth == 0 && nHeight == 0)
+ {
+ Size aSize = rRenderContext.PixelToLogic( Size( 400, 300 ) );
+
+ // align with grid
+ Size aGridSize_(tools::Long(pDlgEdView->GetSnapGridWidthX()), tools::Long(pDlgEdView->GetSnapGridWidthY()));
+ aSize.AdjustWidth( -(aSize.Width() % aGridSize_.Width()) );
+ aSize.AdjustHeight( -(aSize.Height() % aGridSize_.Height()) );
+
+ Point aPos;
+ Size aOutSize = rRenderContext.GetOutputSize();
+ aPos.setX( (aOutSize.Width()>>1) - (aSize.Width()>>1) );
+ aPos.setY( (aOutSize.Height()>>1) - (aSize.Height()>>1) );
+
+ // align with grid
+ aPos.AdjustX( -(aPos.X() % aGridSize_.Width()) );
+ aPos.AdjustY( -(aPos.Y() % aGridSize_.Height()) );
+
+ // don't put in the corner
+ Point aMinPos = rRenderContext.PixelToLogic( Point( 30, 20 ) );
+ if( (aPos.X() < aMinPos.X()) || (aPos.Y() < aMinPos.Y()) )
+ {
+ aPos = aMinPos;
+ aPos.AdjustX( -(aPos.X() % aGridSize_.Width()) );
+ aPos.AdjustY( -(aPos.Y() % aGridSize_.Height()) );
+ }
+
+ // set dialog position and size
+ pDlgEdForm->SetSnapRect( tools::Rectangle( aPos, aSize ) );
+ pDlgEdForm->EndListening(false);
+ pDlgEdForm->SetPropsFromRect();
+ pDlgEdForm->GetDlgEditor().SetDialogModelChanged();
+ pDlgEdForm->StartListening();
+
+ // set position and size of controls
+ if (const size_t nObjCount = pDlgEdPage->GetObjCount())
+ {
+ for (size_t i = 0 ; i < nObjCount ; ++i)
+ {
+ if (DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pDlgEdPage->GetObj(i)))
+ {
+ if (!dynamic_cast<DlgEdForm*>(pDlgEdObj))
+ {
+ pDlgEdObj->SetRectFromProps();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // repaint, get PageView and prepare Region
+ SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
+ const vcl::Region aPaintRectRegion(aPaintRect);
+
+ // #i74769#
+ SdrPaintWindow* pTargetPaintWindow = nullptr;
+
+ // mark repaint start
+ if (pPgView)
+ {
+ pTargetPaintWindow = pPgView->GetView().BeginDrawLayers(&rRenderContext, aPaintRectRegion);
+ OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
+ }
+
+ // draw background self using wallpaper
+ // #i79128# ...and use correct OutDev for that
+ if (pTargetPaintWindow)
+ {
+ OutputDevice& rTargetOutDev = pTargetPaintWindow->GetTargetOutputDevice();
+ rTargetOutDev.DrawWallpaper(aPaintRect, Wallpaper(COL_WHITE));
+ }
+
+ // do paint (unbuffered) and mark repaint end
+ if (pPgView)
+ {
+ // paint of control layer is done in EndDrawLayers anyway...
+ pPgView->GetView().EndDrawLayers(*pTargetPaintWindow, true);
+ }
+
+ mnPaintGuard--;
+}
+
+
+IMPL_LINK_NOARG(DlgEditor, MarkTimeout, Timer *, void)
+{
+ rLayout.UpdatePropertyBrowser();
+}
+
+
+void DlgEditor::SetMode (Mode eNewMode )
+{
+ if ( eNewMode != eMode )
+ {
+ if ( eNewMode == INSERT )
+ pFunc.reset(new DlgEdFuncInsert(*this));
+ else
+ pFunc.reset(new DlgEdFuncSelect(*this));
+
+ if ( eNewMode == READONLY )
+ pDlgEdModel->SetReadOnly( true );
+ else
+ pDlgEdModel->SetReadOnly( false );
+ }
+
+ if ( eNewMode == TEST )
+ ShowDialog();
+
+ eMode = eNewMode;
+}
+
+
+void DlgEditor::SetInsertObj(SdrObjKind eObj)
+{
+ eActObj = eObj;
+
+ pDlgEdView->SetCurrentObj( eActObj, SdrInventor::BasicDialog );
+}
+
+void DlgEditor::CreateDefaultObject()
+{
+ // create object by factory
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(
+ *pDlgEdModel,
+ pDlgEdView->GetCurrentObjInventor(),
+ pDlgEdView->GetCurrentObjIdentifier());
+
+ DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pObj);
+ if (!pDlgEdObj)
+ return;
+
+ // set position and size
+ Size aSize = rWindow.PixelToLogic( Size( 96, 24 ) );
+ Point aPoint = pDlgEdForm->GetSnapRect().Center();
+ aPoint.AdjustX( -(aSize.Width() / 2) );
+ aPoint.AdjustY( -(aSize.Height() / 2) );
+ pDlgEdObj->SetSnapRect( tools::Rectangle( aPoint, aSize ) );
+
+ // set default property values
+ pDlgEdObj->SetDefaults();
+
+ // insert object into drawing page
+ SdrPageView* pPageView = pDlgEdView->GetSdrPageView();
+ if (pDlgEdView->InsertObjectAtView(pDlgEdObj, *pPageView))
+ {
+ // start listening
+ pDlgEdObj->StartListening();
+ }
+}
+
+void DlgEditor::Cut()
+{
+ Copy();
+ Delete();
+}
+
+static void implCopyStreamToByteSequence( const Reference< XInputStream >& xStream,
+ Sequence< sal_Int8 >& bytes )
+{
+ xStream->readBytes( bytes, xStream->available() );
+ for (;;)
+ {
+ Sequence< sal_Int8 > readBytes;
+ sal_Int32 nRead = xStream->readBytes( readBytes, 1024 );
+ if (! nRead)
+ break;
+
+ sal_Int32 nPos = bytes.getLength();
+ bytes.realloc( nPos + nRead );
+ memcpy( bytes.getArray() + nPos, readBytes.getConstArray(), static_cast<sal_uInt32>(nRead) );
+ }
+}
+
+void DlgEditor::Copy()
+{
+ if( !pDlgEdView->AreObjectsMarked() )
+ return;
+
+ // stop all drawing actions
+ pDlgEdView->BrkAction();
+
+ // create an empty clipboard dialog model
+ Reference< util::XCloneable > xClone( m_xUnoControlDialogModel, UNO_QUERY );
+ Reference< util::XCloneable > xNewClone = xClone->createClone();
+ Reference< container::XNameContainer > xClipDialogModel( xNewClone, UNO_QUERY );
+
+ if ( xClipDialogModel.is() )
+ {
+ Sequence< OUString > aNames = xClipDialogModel->getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_uInt32 nCtrls = aNames.getLength();
+
+ for ( sal_uInt32 n = 0; n < nCtrls; n++ )
+ {
+ xClipDialogModel->removeByName( pNames[n] );
+ }
+ }
+
+ // insert control models of marked objects into clipboard dialog model
+ const size_t nMark = pDlgEdView->GetMarkedObjectList().GetMarkCount();
+ for( size_t i = 0; i < nMark; ++i )
+ {
+ SdrObject* pObj = pDlgEdView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj();
+ DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pObj);
+
+ if (pDlgEdObj && !dynamic_cast<DlgEdForm*>(pDlgEdObj))
+ {
+ OUString aName;
+ Reference< beans::XPropertySet > xMarkPSet(pDlgEdObj->GetUnoControlModel(), uno::UNO_QUERY);
+ if (xMarkPSet.is())
+ {
+ xMarkPSet->getPropertyValue( DLGED_PROP_NAME ) >>= aName;
+ }
+
+ if ( m_xUnoControlDialogModel.is() && m_xUnoControlDialogModel->hasByName(aName) )
+ {
+ Any aCtrl = m_xUnoControlDialogModel->getByName( aName );
+
+ // clone control model
+ Reference< util::XCloneable > xCtrl;
+ aCtrl >>= xCtrl;
+ Reference< util::XCloneable > xNewCtrl = xCtrl->createClone();
+ Any aNewCtrl;
+ aNewCtrl <<= xNewCtrl;
+
+ if (xClipDialogModel.is())
+ xClipDialogModel->insertByName( aName , aNewCtrl );
+ }
+ }
+ }
+
+ // export clipboard dialog model to xml
+ Reference< XComponentContext > xContext(
+ comphelper::getProcessComponentContext() );
+ Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xClipDialogModel, xContext, m_xDocument );
+ Reference< XInputStream > xStream( xISP->createInputStream() );
+ Sequence< sal_Int8 > DialogModelBytes;
+ implCopyStreamToByteSequence( xStream, DialogModelBytes );
+ xStream->closeInput();
+
+ // set clipboard content
+ Reference< datatransfer::clipboard::XClipboard > xClipboard = GetWindow().GetClipboard();
+ if ( !xClipboard.is() )
+ return;
+
+ // With resource?
+ uno::Reference< beans::XPropertySet > xDialogModelPropSet( m_xUnoControlDialogModel, uno::UNO_QUERY );
+ uno::Reference< resource::XStringResourcePersistence > xStringResourcePersistence;
+ if( xDialogModelPropSet.is() )
+ {
+ try
+ {
+ Any aResourceResolver = xDialogModelPropSet->getPropertyValue( aResourceResolverPropName );
+ aResourceResolver >>= xStringResourcePersistence;
+ }
+ catch(const UnknownPropertyException& )
+ {}
+ }
+
+ rtl::Reference<DlgEdTransferableImpl> pTrans;
+ if( xStringResourcePersistence.is() )
+ {
+ // With resource, support old and new format
+
+ // Export xClipDialogModel another time with ids replaced by current language string
+ LocalizationMgr::resetResourceForDialog( xClipDialogModel, xStringResourcePersistence );
+ Reference< XInputStreamProvider > xISP2 = ::xmlscript::exportDialogModel( xClipDialogModel, xContext, m_xDocument );
+ Reference< XInputStream > xStream2( xISP2->createInputStream() );
+ Sequence< sal_Int8 > NoResourceDialogModelBytes;
+ implCopyStreamToByteSequence( xStream2, NoResourceDialogModelBytes );
+ xStream2->closeInput();
+
+ // Old format contains dialog with replaced ids
+ Any aNoResourceDialogModelBytesAny;
+ aNoResourceDialogModelBytesAny <<= NoResourceDialogModelBytes;
+
+ // New format contains dialog and resource
+ Sequence< sal_Int8 > aResData = xStringResourcePersistence->exportBinary();
+
+ // Create sequence for combined dialog and resource
+ sal_Int32 nDialogDataLen = DialogModelBytes.getLength();
+ sal_Int32 nResDataLen = aResData.getLength();
+
+ // Combined data = 4 Bytes 32Bit Offset to begin of resource data, lowest byte first
+ // + nDialogDataLen bytes dialog data + nResDataLen resource data
+ sal_Int32 nTotalLen = 4 + nDialogDataLen + nResDataLen;
+ sal_Int32 nResOffset = 4 + nDialogDataLen;
+ Sequence< sal_Int8 > aCombinedData( nTotalLen );
+ sal_Int8* pCombinedData = aCombinedData.getArray();
+
+ // Write offset
+ sal_Int32 n = nResOffset;
+ for( sal_Int16 i = 0 ; i < 4 ; i++ )
+ {
+ pCombinedData[i] = sal_Int8( n & 0xff );
+ n >>= 8;
+ }
+ memcpy( pCombinedData + 4, DialogModelBytes.getConstArray(), nDialogDataLen );
+ memcpy( pCombinedData + nResOffset, aResData.getConstArray(), nResDataLen );
+
+ Sequence< Any > aSeqData
+ {
+ aNoResourceDialogModelBytesAny,
+ Any(aCombinedData)
+ };
+
+ pTrans = new DlgEdTransferableImpl( m_ClipboardDataFlavorsResource, aSeqData );
+ }
+ else
+ {
+ // No resource, support only old format
+ pTrans = new DlgEdTransferableImpl( m_ClipboardDataFlavors , { Any(DialogModelBytes) } );
+ }
+ SolarMutexReleaser aReleaser;
+ xClipboard->setContents( pTrans , pTrans );
+}
+
+
+void DlgEditor::Paste()
+{
+ // stop all drawing actions
+ pDlgEdView->BrkAction();
+
+ // unmark all objects
+ pDlgEdView->UnmarkAll();
+
+ // get clipboard
+ Reference< datatransfer::clipboard::XClipboard > xClipboard = GetWindow().GetClipboard();
+ if ( !xClipboard.is() )
+ return;
+
+ Reference< datatransfer::XTransferable > xTransf;
+ {
+ SolarMutexReleaser aReleaser;
+ // get clipboard content
+ xTransf = xClipboard->getContents();
+ }
+ if ( !xTransf.is() )
+ return;
+
+ // Is target dialog (library) localized?
+ uno::Reference< beans::XPropertySet > xDialogModelPropSet( m_xUnoControlDialogModel, uno::UNO_QUERY );
+ uno::Reference< resource::XStringResourceManager > xStringResourceManager;
+ if( xDialogModelPropSet.is() )
+ {
+ try
+ {
+ Any aResourceResolver = xDialogModelPropSet->getPropertyValue( aResourceResolverPropName );
+ aResourceResolver >>= xStringResourceManager;
+ }
+ catch(const UnknownPropertyException& )
+ {}
+ }
+ bool bLocalized = false;
+ if( xStringResourceManager.is() )
+ bLocalized = xStringResourceManager->getLocales().hasElements();
+
+ if ( !xTransf->isDataFlavorSupported( m_ClipboardDataFlavors[0] ) )
+ return;
+
+ // create clipboard dialog model from xml
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ Reference< container::XNameContainer > xClipDialogModel( xContext->getServiceManager()->createInstanceWithContext(
+ "com.sun.star.awt.UnoControlDialogModel", xContext ), uno::UNO_QUERY );
+
+ bool bSourceIsLocalized = false;
+ Sequence< sal_Int8 > DialogModelBytes;
+ Sequence< sal_Int8 > aResData;
+ if( bLocalized && xTransf->isDataFlavorSupported( m_ClipboardDataFlavorsResource[1] ) )
+ {
+ bSourceIsLocalized = true;
+
+ Any aCombinedDataAny = xTransf->getTransferData( m_ClipboardDataFlavorsResource[1] );
+ Sequence< sal_Int8 > aCombinedData;
+ aCombinedDataAny >>= aCombinedData;
+ const sal_Int8* pCombinedData = aCombinedData.getConstArray();
+
+ sal_Int32 nTotalLen = aCombinedData.getLength();
+
+ // Reading offset
+ sal_Int32 nResOffset = 0;
+ sal_Int32 nFactor = 1;
+ for( sal_Int16 i = 0; i < 4; i++ )
+ {
+ nResOffset += nFactor * sal_uInt8( pCombinedData[i] );
+ nFactor *= 256;
+ }
+
+ sal_Int32 nResDataLen = nTotalLen - nResOffset;
+ sal_Int32 nDialogDataLen = nTotalLen - nResDataLen - 4;
+
+ DialogModelBytes.realloc( nDialogDataLen );
+ memcpy( DialogModelBytes.getArray(), pCombinedData + 4, nDialogDataLen );
+
+ aResData.realloc( nResDataLen );
+ memcpy( aResData.getArray(), pCombinedData + nResOffset, nResDataLen );
+ }
+ else
+ {
+ Any aAny = xTransf->getTransferData( m_ClipboardDataFlavors[0] );
+ aAny >>= DialogModelBytes;
+ }
+
+ if ( xClipDialogModel.is() )
+ {
+ Reference<XInputStream> xIn = ::xmlscript::createInputStream( DialogModelBytes.getConstArray(), DialogModelBytes.getLength() );
+ ::xmlscript::importDialogModel( xIn , xClipDialogModel, xContext, m_xDocument );
+ }
+
+ // get control models from clipboard dialog model
+ if ( !xClipDialogModel.is() )
+ return;
+
+ Sequence< OUString > aNames = xClipDialogModel->getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_uInt32 nCtrls = aNames.getLength();
+
+ Reference< resource::XStringResourcePersistence > xStringResourcePersistence;
+ if( nCtrls > 0 && bSourceIsLocalized )
+ {
+ xStringResourcePersistence = css::resource::StringResource::create( getProcessComponentContext() );
+ xStringResourcePersistence->importBinary( aResData );
+ }
+ for( sal_uInt32 n = 0; n < nCtrls; n++ )
+ {
+ Any aA = xClipDialogModel->getByName( pNames[n] );
+ Reference< css::awt::XControlModel > xCM;
+ aA >>= xCM;
+
+ // clone the control model
+ Reference< util::XCloneable > xClone( xCM, uno::UNO_QUERY );
+ Reference< awt::XControlModel > xCtrlModel( xClone->createClone(), uno::UNO_QUERY );
+
+ DlgEdObj* pCtrlObj = new DlgEdObj(*pDlgEdModel);
+ pCtrlObj->SetDlgEdForm(pDlgEdForm); // set parent form
+ pDlgEdForm->AddChild(pCtrlObj); // add child to parent form
+ pCtrlObj->SetUnoControlModel( xCtrlModel ); // set control model
+
+ // set new name
+ OUString aOUniqueName( pCtrlObj->GetUniqueName() );
+ Reference< beans::XPropertySet > xPSet( xCtrlModel , UNO_QUERY );
+ xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOUniqueName) );
+
+ // set tabindex
+ Sequence< OUString > aNames_ = m_xUnoControlDialogModel->getElementNames();
+ xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(aNames_.getLength())) );
+
+ if( bLocalized )
+ {
+ Any aControlAny;
+ aControlAny <<= xCtrlModel;
+ if( bSourceIsLocalized && xStringResourcePersistence.is() )
+ {
+ LocalizationMgr::copyResourcesForPastedEditorObject( this,
+ aControlAny, aOUniqueName, xStringResourcePersistence );
+ }
+ else
+ {
+ LocalizationMgr::setControlResourceIDsForNewEditorObject
+ ( this, aControlAny, aOUniqueName );
+ }
+ }
+
+ // insert control model in editor dialog model
+ Any aCtrlModel;
+ aCtrlModel <<= xCtrlModel;
+ m_xUnoControlDialogModel->insertByName( aOUniqueName , aCtrlModel );
+
+ // insert object into drawing page
+ pDlgEdModel->GetPage(0)->InsertObject( pCtrlObj );
+ pCtrlObj->SetRectFromProps();
+ pCtrlObj->UpdateStep();
+ pDlgEdForm->UpdateTabOrderAndGroups();
+ pCtrlObj->StartListening(); // start listening
+
+ // mark object
+ SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
+ pDlgEdView->MarkObj( pCtrlObj, pPgView, false, true);
+ }
+
+ // center marked objects in dialog editor form
+ Point aMarkCenter = pDlgEdView->GetMarkedObjRect().Center();
+ Point aFormCenter = pDlgEdForm->GetSnapRect().Center();
+ Point aPoint = aFormCenter - aMarkCenter;
+ Size aSize( aPoint.X() , aPoint.Y() );
+ pDlgEdView->MoveMarkedObj( aSize ); // update of control model properties (position + size) in NbcMove
+ pDlgEdView->MarkListHasChanged();
+
+ // dialog model changed
+ SetDialogModelChanged();
+}
+
+
+void DlgEditor::Delete()
+{
+ if( !pDlgEdView->AreObjectsMarked() )
+ return;
+
+ // remove control models of marked objects from dialog model
+ const size_t nMark = pDlgEdView->GetMarkedObjectList().GetMarkCount();
+
+ for( size_t i = 0; i < nMark; ++i )
+ {
+ SdrObject* pObj = pDlgEdView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj();
+ DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pObj);
+
+ if ( pDlgEdObj && !dynamic_cast<DlgEdForm*>(pDlgEdObj) )
+ {
+ // get name from property
+ OUString aName;
+ uno::Reference< beans::XPropertySet > xPSet(pDlgEdObj->GetUnoControlModel(), uno::UNO_QUERY);
+ if (xPSet.is())
+ {
+ xPSet->getPropertyValue( DLGED_PROP_NAME ) >>= aName;
+ }
+
+ // remove control from dialog model
+ Reference< css::container::XNameAccess > xNameAcc(pDlgEdObj->GetDlgEdForm()->GetUnoControlModel(), UNO_QUERY );
+ if ( xNameAcc.is() && xNameAcc->hasByName(aName) )
+ {
+ Reference< css::container::XNameContainer > xCont(xNameAcc, UNO_QUERY );
+ if ( xCont.is() )
+ {
+ if( xCont->hasByName( aName ) )
+ {
+ Any aAny = xCont->getByName( aName );
+ LocalizationMgr::deleteControlResourceIDsForDeletedEditorObject( this, aAny, aName );
+ }
+ xCont->removeByName( aName );
+ }
+ }
+
+ // remove child from parent form
+ pDlgEdForm->RemoveChild( pDlgEdObj );
+ }
+ }
+
+ // update tab indices
+ pDlgEdForm->UpdateTabIndices();
+
+ pDlgEdView->BrkAction();
+
+ bool const bDlgMarked = UnmarkDialog();
+ pDlgEdView->DeleteMarked();
+ if( bDlgMarked )
+ RemarkDialog();
+}
+
+
+bool DlgEditor::IsPasteAllowed()
+{
+ // get clipboard
+ Reference< datatransfer::clipboard::XClipboard > xClipboard = GetWindow().GetClipboard();
+ if ( xClipboard.is() )
+ {
+ Reference< datatransfer::XTransferable > xTransf;
+ {
+ SolarMutexReleaser aReleaser;
+ // get clipboard content
+ xTransf = xClipboard->getContents();
+ }
+ if (xTransf.is())
+ return xTransf->isDataFlavorSupported(m_ClipboardDataFlavors[0]);
+ }
+ return false;
+}
+
+
+void DlgEditor::ShowProperties()
+{
+ rLayout.ShowPropertyBrowser();
+}
+
+
+void DlgEditor::UpdatePropertyBrowserDelayed()
+{
+ aMarkIdle.Start();
+}
+
+
+bool DlgEditor::IsModified() const
+{
+ return pDlgEdModel->IsChanged() || bDialogModelChanged;
+}
+
+
+void DlgEditor::ClearModifyFlag()
+{
+ pDlgEdModel->SetChanged(false);
+ bDialogModelChanged = false;
+}
+
+
+namespace Print
+{
+ tools::Long const nLeftMargin = 1700;
+ tools::Long const nRightMargin = 900;
+ tools::Long const nTopMargin = 2000;
+ tools::Long const nBottomMargin = 1000;
+ tools::Long const nBorder = 300;
+}
+
+static void lcl_PrintHeader( Printer* pPrinter, const OUString& rTitle ) // not working yet
+{
+
+ pPrinter->Push();
+
+ Size const aSz = pPrinter->GetOutputSize();
+
+ pPrinter->SetLineColor( COL_BLACK );
+ pPrinter->SetFillColor();
+
+ vcl::Font aFont( pPrinter->GetFont() );
+ aFont.SetWeight( WEIGHT_BOLD );
+ aFont.SetAlignment( ALIGN_BOTTOM );
+ pPrinter->SetFont( aFont );
+
+ tools::Long const nFontHeight = pPrinter->GetTextHeight();
+
+ // 1st border => line, 2+3 border = free space
+ tools::Long const nYTop = Print::nTopMargin - 3*Print::nBorder - nFontHeight;
+
+ tools::Long const nXLeft = Print::nLeftMargin - Print::nBorder;
+ tools::Long const nXRight = aSz.Width() - Print::nRightMargin + Print::nBorder;
+
+ pPrinter->DrawRect(tools::Rectangle(
+ Point(nXLeft, nYTop),
+ Size(nXRight - nXLeft, aSz.Height() - nYTop - Print::nBottomMargin + Print::nBorder)
+ ));
+
+ tools::Long nY = Print::nTopMargin - 2*Print::nBorder;
+ Point aPos(Print::nLeftMargin, nY);
+ pPrinter->DrawText( aPos, rTitle );
+
+ nY = Print::nTopMargin - Print::nBorder;
+ pPrinter->DrawLine( Point( nXLeft, nY ), Point( nXRight, nY ) );
+
+ pPrinter->Pop();
+}
+
+
+void DlgEditor::printPage( sal_Int32 nPage, Printer* pPrinter, const OUString& rTitle )
+{
+ if( nPage == 0 )
+ Print( pPrinter, rTitle );
+}
+
+
+void DlgEditor::Print( Printer* pPrinter, const OUString& rTitle ) // not working yet
+{
+ MapMode aOldMap( pPrinter->GetMapMode());
+ vcl::Font aOldFont( pPrinter->GetFont() );
+
+ MapMode aMap( MapUnit::Map100thMM );
+ pPrinter->SetMapMode( aMap );
+ vcl::Font aFont;
+ aFont.SetAlignment( ALIGN_BOTTOM );
+ aFont.SetFontSize( Size( 0, 360 ));
+ pPrinter->SetFont( aFont );
+
+ Size aPaperSz = pPrinter->GetOutputSize();
+ aPaperSz.AdjustWidth( -(Print::nLeftMargin + Print::nRightMargin) );
+ aPaperSz.AdjustHeight( -(Print::nTopMargin + Print::nBottomMargin) );
+
+ lcl_PrintHeader( pPrinter, rTitle );
+
+ BitmapEx aDlgEx;
+ Size aBmpSz( pPrinter->PixelToLogic( aDlgEx.GetSizePixel() ) );
+ double nPaperSzWidth = aPaperSz.Width();
+ double nPaperSzHeight = aPaperSz.Height();
+ double nBmpSzWidth = aBmpSz.Width();
+ double nBmpSzHeight = aBmpSz.Height();
+ double nScaleX = nPaperSzWidth / nBmpSzWidth;
+ double nScaleY = nPaperSzHeight / nBmpSzHeight;
+
+ Size aOutputSz;
+ if( nBmpSzHeight * nScaleX <= nPaperSzHeight )
+ {
+ aOutputSz.setWidth( static_cast<tools::Long>(nBmpSzWidth * nScaleX) );
+ aOutputSz.setHeight( static_cast<tools::Long>(nBmpSzHeight * nScaleX) );
+ }
+ else
+ {
+ aOutputSz.setWidth( static_cast<tools::Long>(nBmpSzWidth * nScaleY) );
+ aOutputSz.setHeight( static_cast<tools::Long>(nBmpSzHeight * nScaleY) );
+ }
+
+ Point aPosOffs(
+ (aPaperSz.Width() / 2) - (aOutputSz.Width() / 2),
+ (aPaperSz.Height()/ 2) - (aOutputSz.Height() / 2));
+
+ aPosOffs.AdjustX(Print::nLeftMargin );
+ aPosOffs.AdjustY(Print::nTopMargin );
+
+ pPrinter->DrawBitmapEx( aPosOffs, aOutputSz, aDlgEx );
+
+ pPrinter->SetMapMode( aOldMap );
+ pPrinter->SetFont( aOldFont );
+}
+
+
+bool DlgEditor::AdjustPageSize()
+{
+ bool bAdjustedPageSize = false;
+ Reference< beans::XPropertySet > xPSet( m_xUnoControlDialogModel, UNO_QUERY );
+ if ( xPSet.is() )
+ {
+ sal_Int32 nFormXIn = 0, nFormYIn = 0, nFormWidthIn = 0, nFormHeightIn = 0;
+ xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nFormXIn;
+ xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nFormYIn;
+ xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nFormWidthIn;
+ xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nFormHeightIn;
+
+ sal_Int32 nFormX, nFormY, nFormWidth, nFormHeight;
+ if ( pDlgEdForm && pDlgEdForm->TransformFormToSdrCoordinates( nFormXIn, nFormYIn, nFormWidthIn, nFormHeightIn, nFormX, nFormY, nFormWidth, nFormHeight ) )
+ {
+ Size aPageSizeDelta( 400, 300 );
+ aPageSizeDelta = rWindow.PixelToLogic( aPageSizeDelta, MapMode( MapUnit::Map100thMM ) );
+
+ sal_Int32 nNewPageWidth = nFormX + nFormWidth + aPageSizeDelta.Width();
+ sal_Int32 nNewPageHeight = nFormY + nFormHeight + aPageSizeDelta.Height();
+
+ Size aPageSizeMin( DLGED_PAGE_WIDTH_MIN, DLGED_PAGE_HEIGHT_MIN );
+ aPageSizeMin = rWindow.PixelToLogic( aPageSizeMin, MapMode( MapUnit::Map100thMM ) );
+ sal_Int32 nPageWidthMin = aPageSizeMin.Width();
+ sal_Int32 nPageHeightMin = aPageSizeMin.Height();
+
+ if ( nNewPageWidth < nPageWidthMin )
+ nNewPageWidth = nPageWidthMin;
+
+ if ( nNewPageHeight < nPageHeightMin )
+ nNewPageHeight = nPageHeightMin;
+
+ if ( pDlgEdPage )
+ {
+ Size aPageSize = pDlgEdPage->GetSize();
+ if ( nNewPageWidth != aPageSize.Width() || nNewPageHeight != aPageSize.Height() )
+ {
+ Size aNewPageSize( nNewPageWidth, nNewPageHeight );
+ pDlgEdPage->SetSize( aNewPageSize );
+ pDlgEdView->SetWorkArea( tools::Rectangle( Point( 0, 0 ), aNewPageSize ) );
+ bAdjustedPageSize = true;
+ }
+ }
+ }
+ }
+
+ return bAdjustedPageSize;
+}
+
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/dlged/dlgedclip.cxx b/basctl/source/dlged/dlgedclip.cxx
new file mode 100644
index 000000000..931f10afe
--- /dev/null
+++ b/basctl/source/dlged/dlgedclip.cxx
@@ -0,0 +1,109 @@
+/* -*- 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 <dlgedclip.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
+#include <com/sun/star/datatransfer/XMimeContentType.hpp>
+#include <com/sun/star/datatransfer/MimeContentTypeFactory.hpp>
+
+namespace basctl
+{
+
+using namespace comphelper;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::datatransfer;
+using namespace ::com::sun::star::datatransfer::clipboard;
+DlgEdTransferableImpl::DlgEdTransferableImpl( const Sequence< DataFlavor >& aSeqFlavors, const Sequence< Any >& aSeqData )
+{
+ m_SeqFlavors = aSeqFlavors;
+ m_SeqData = aSeqData;
+}
+DlgEdTransferableImpl::~DlgEdTransferableImpl()
+{
+}
+bool DlgEdTransferableImpl::compareDataFlavors( const DataFlavor& lFlavor, const DataFlavor& rFlavor )
+{
+ // compare mime content types
+ Reference< uno::XComponentContext > xContext = getProcessComponentContext();
+ Reference< datatransfer::XMimeContentTypeFactory >
+ xMCntTypeFactory = MimeContentTypeFactory::create(xContext);
+
+ // compare full media types
+ Reference< datatransfer::XMimeContentType > xLType = xMCntTypeFactory->createMimeContentType( lFlavor.MimeType );
+ Reference< datatransfer::XMimeContentType > xRType = xMCntTypeFactory->createMimeContentType( rFlavor.MimeType );
+
+ OUString aLFullMediaType = xLType->getFullMediaType();
+ OUString aRFullMediaType = xRType->getFullMediaType();
+
+ bool bRet = aLFullMediaType.equalsIgnoreAsciiCase( aRFullMediaType );
+
+ return bRet;
+}
+
+// XTransferable
+Any SAL_CALL DlgEdTransferableImpl::getTransferData( const DataFlavor& rFlavor )
+{
+ const SolarMutexGuard aGuard;
+
+ if ( !isDataFlavorSupported( rFlavor ) )
+ throw UnsupportedFlavorException();
+
+ Any aData;
+
+ for ( sal_Int32 i = 0; i < m_SeqFlavors.getLength(); i++ )
+ {
+ if ( compareDataFlavors( m_SeqFlavors[i] , rFlavor ) )
+ {
+ aData = m_SeqData[i];
+ break;
+ }
+ }
+
+ return aData;
+}
+Sequence< DataFlavor > SAL_CALL DlgEdTransferableImpl::getTransferDataFlavors( )
+{
+ const SolarMutexGuard aGuard;
+
+ return m_SeqFlavors;
+}
+sal_Bool SAL_CALL DlgEdTransferableImpl::isDataFlavorSupported( const DataFlavor& rFlavor )
+{
+ const SolarMutexGuard aGuard;
+
+ for ( auto const & i : std::as_const(m_SeqFlavors) )
+ if ( compareDataFlavors( i, rFlavor ) )
+ return true;
+ return false;
+}
+
+// XClipboardOwner
+void SAL_CALL DlgEdTransferableImpl::lostOwnership( const Reference< XClipboard >&, const Reference< XTransferable >& )
+{
+ const SolarMutexGuard aGuard;
+
+ m_SeqFlavors = Sequence< DataFlavor >();
+ m_SeqData = Sequence< Any >();
+}
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/dlged/dlgedfac.cxx b/basctl/source/dlged/dlgedfac.cxx
new file mode 100644
index 000000000..03713c2b9
--- /dev/null
+++ b/basctl/source/dlged/dlgedfac.cxx
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <dlgedfac.hxx>
+#include <dlgedobj.hxx>
+#include <dlgeddef.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/ScrollBarOrientation.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <comphelper/processfactory.hxx>
+#include <utility>
+
+namespace basctl
+{
+
+using namespace ::com::sun::star;
+
+
+DlgEdFactory::DlgEdFactory( css::uno::Reference< css::frame::XModel > xModel ) : mxModel(std::move( xModel ))
+{
+ SdrObjFactory::InsertMakeObjectHdl( LINK(this, DlgEdFactory, MakeObject) );
+}
+
+
+DlgEdFactory::~DlgEdFactory() COVERITY_NOEXCEPT_FALSE
+{
+ SdrObjFactory::RemoveMakeObjectHdl( LINK(this, DlgEdFactory, MakeObject) );
+}
+
+
+IMPL_LINK( DlgEdFactory, MakeObject, SdrObjCreatorParams, aParams, SdrObject* )
+{
+ static const uno::Reference<lang::XMultiServiceFactory> xDialogSFact = [] {
+ uno::Reference<lang::XMultiServiceFactory> xFact;
+ uno::Reference< uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference< container::XNameContainer > xC( xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.awt.UnoControlDialogModel", xContext ), uno::UNO_QUERY );
+ if( xC.is() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xModFact( xC, uno::UNO_QUERY );
+ xFact = xModFact;
+ }
+ return xFact;
+ }();
+
+ SdrObject* pNewObj = nullptr;
+ if( (aParams.nInventor == SdrInventor::BasicDialog) &&
+ (aParams.nObjIdentifier >= SdrObjKind::BasicDialogPushButton) &&
+ (aParams.nObjIdentifier <= SdrObjKind::BasicDialogFormHorizontalScroll) )
+ {
+ switch( aParams.nObjIdentifier )
+ {
+ case SdrObjKind::BasicDialogPushButton:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlButtonModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogRadioButton:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlRadioButtonModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogFormRadio:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.form.component.RadioButton", xDialogSFact );
+ static_cast< DlgEdObj* >( pNewObj )->MakeDataAware( mxModel );
+ break;
+ case SdrObjKind::BasicDialogCheckbox:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlCheckBoxModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogFormCheck:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.form.component.CheckBox", xDialogSFact );
+ static_cast< DlgEdObj* >( pNewObj )->MakeDataAware( mxModel );
+ break;
+ case SdrObjKind::BasicDialogListbox:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlListBoxModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogFormList:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.form.component.ListBox", xDialogSFact );
+ static_cast< DlgEdObj* >( pNewObj )->MakeDataAware( mxModel );
+ break;
+ case SdrObjKind::BasicDialogFormCombo:
+ case SdrObjKind::BasicDialogCombobox:
+ {
+ DlgEdObj* pNew = nullptr;
+ if ( aParams.nObjIdentifier == SdrObjKind::BasicDialogCombobox )
+ pNew = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlComboBoxModel", xDialogSFact );
+ else
+ {
+ pNew = new DlgEdObj(aParams.rSdrModel, "com.sun.star.form.component.ComboBox", xDialogSFact );
+ pNew->MakeDataAware( mxModel );
+ }
+ pNewObj = pNew;
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPSet(pNew->GetUnoControlModel(), uno::UNO_QUERY);
+ if (xPSet.is())
+ {
+ xPSet->setPropertyValue( DLGED_PROP_DROPDOWN, uno::Any(true));
+ }
+ }
+ catch(...)
+ {
+ }
+ }
+ break;
+ case SdrObjKind::BasicDialogGroupBox:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlGroupBoxModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogEdit:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlEditModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogFixedText:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlFixedTextModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogImageControl:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlImageControlModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogProgressbar:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlProgressBarModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogHorizontalScrollbar:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlScrollBarModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogFormHorizontalScroll:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.form.component.ScrollBar", xDialogSFact );
+ static_cast< DlgEdObj* >( pNewObj )->MakeDataAware( mxModel );
+ break;
+ case SdrObjKind::BasicDialogFormVerticalScroll:
+ case SdrObjKind::BasicDialogVerticalScrollbar:
+ {
+ DlgEdObj* pNew = nullptr;
+ if ( aParams.nObjIdentifier == SdrObjKind::BasicDialogVerticalScrollbar )
+ pNew = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlScrollBarModel", xDialogSFact );
+ else
+ {
+ pNew = new DlgEdObj(aParams.rSdrModel, "com.sun.star.form.component.ScrollBar", xDialogSFact );
+ pNew->MakeDataAware( mxModel );
+ }
+ pNewObj = pNew;
+ // set vertical orientation
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPSet(pNew->GetUnoControlModel(), uno::UNO_QUERY);
+ if (xPSet.is())
+ {
+ xPSet->setPropertyValue( DLGED_PROP_ORIENTATION, uno::Any(sal_Int32(css::awt::ScrollBarOrientation::VERTICAL)) );
+ }
+ }
+ catch(...)
+ {
+ }
+ } break;
+ case SdrObjKind::BasicDialogHorizontalFixedLine:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlFixedLineModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogVerticalFixedLine:
+ {
+ DlgEdObj* pNew = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlFixedLineModel", xDialogSFact );
+ pNewObj = pNew;
+ // set vertical orientation
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPSet(pNew->GetUnoControlModel(), uno::UNO_QUERY);
+ if (xPSet.is())
+ {
+ xPSet->setPropertyValue( DLGED_PROP_ORIENTATION, uno::Any(sal_Int32(1)) );
+ }
+ }
+ catch(...)
+ {
+ }
+ } break;
+ case SdrObjKind::BasicDialogDateField:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlDateFieldModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogTimeField:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlTimeFieldModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogNumericField:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlNumericFieldModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogCurencyField:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlCurrencyFieldModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogFormattedField:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlFormattedFieldModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogPatternField:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlPatternFieldModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogFileControl:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlFileControlModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogSpinButton:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlSpinButtonModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogFormSpin:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.form.component.SpinButton", xDialogSFact );
+ static_cast< DlgEdObj* >( pNewObj )->MakeDataAware( mxModel );
+ break;
+ case SdrObjKind::BasicDialogTreeControl:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.tree.TreeControlModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogGridControl:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.grid.UnoControlGridModel", xDialogSFact );
+ break;
+ case SdrObjKind::BasicDialogHyperlinkControl:
+ pNewObj = new DlgEdObj(aParams.rSdrModel, "com.sun.star.awt.UnoControlFixedHyperlinkModel", xDialogSFact );
+ break;
+ default:
+ break;
+
+ }
+ }
+ return pNewObj;
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/dlged/dlgedfunc.cxx b/basctl/source/dlged/dlgedfunc.cxx
new file mode 100644
index 000000000..c43b22c8e
--- /dev/null
+++ b/basctl/source/dlged/dlgedfunc.cxx
@@ -0,0 +1,548 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/scrbar.hxx>
+#include <svx/svdview.hxx>
+#include <dlgedfunc.hxx>
+#include <dlged.hxx>
+#include <dlgedview.hxx>
+#include <vcl/seleng.hxx>
+
+namespace basctl
+{
+
+IMPL_LINK_NOARG( DlgEdFunc, ScrollTimeout, Timer *, void )
+{
+ vcl::Window& rWindow = rParent.GetWindow();
+ Point aPos = rWindow.ScreenToOutputPixel( rWindow.GetPointerPosPixel() );
+ aPos = rWindow.PixelToLogic( aPos );
+ ForceScroll( aPos );
+}
+
+void DlgEdFunc::ForceScroll( const Point& rPos )
+{
+ aScrollTimer.Stop();
+
+ vcl::Window& rWindow = rParent.GetWindow();
+
+ static const Point aDefPoint;
+ tools::Rectangle aOutRect( aDefPoint, rWindow.GetOutputSizePixel() );
+ aOutRect = rWindow.PixelToLogic( aOutRect );
+
+ ScrollBar* pHScroll = rParent.GetHScroll();
+ ScrollBar* pVScroll = rParent.GetVScroll();
+ tools::Long nDeltaX = pHScroll->GetLineSize();
+ tools::Long nDeltaY = pVScroll->GetLineSize();
+
+ if( !aOutRect.Contains( rPos ) )
+ {
+ if( rPos.X() < aOutRect.Left() )
+ nDeltaX = -nDeltaX;
+ else if( rPos.X() <= aOutRect.Right() )
+ nDeltaX = 0;
+
+ if( rPos.Y() < aOutRect.Top() )
+ nDeltaY = -nDeltaY;
+ else if( rPos.Y() <= aOutRect.Bottom() )
+ nDeltaY = 0;
+
+ if( nDeltaX )
+ pHScroll->SetThumbPos( pHScroll->GetThumbPos() + nDeltaX );
+ if( nDeltaY )
+ pVScroll->SetThumbPos( pVScroll->GetThumbPos() + nDeltaY );
+
+ if( nDeltaX )
+ rParent.DoScroll();
+ if( nDeltaY )
+ rParent.DoScroll();
+ }
+
+ aScrollTimer.Start();
+}
+
+DlgEdFunc::DlgEdFunc (DlgEditor& rParent_) :
+ rParent(rParent_), aScrollTimer("basctl DlgEdFunc aScrollTimer")
+{
+ aScrollTimer.SetInvokeHandler( LINK( this, DlgEdFunc, ScrollTimeout ) );
+ aScrollTimer.SetTimeout( SELENG_AUTOREPEAT_INTERVAL );
+}
+
+DlgEdFunc::~DlgEdFunc()
+{
+}
+
+void DlgEdFunc::MouseButtonDown( const MouseEvent& )
+{
+}
+
+bool DlgEdFunc::MouseButtonUp( const MouseEvent& )
+{
+ aScrollTimer.Stop();
+ return true;
+}
+
+void DlgEdFunc::MouseMove( const MouseEvent& )
+{
+}
+
+bool DlgEdFunc::KeyInput( const KeyEvent& rKEvt )
+{
+ bool bReturn = false;
+
+ SdrView& rView = rParent.GetView();
+ vcl::Window& rWindow = rParent.GetWindow();
+
+ vcl::KeyCode aCode = rKEvt.GetKeyCode();
+ sal_uInt16 nCode = aCode.GetCode();
+
+ switch ( nCode )
+ {
+ case KEY_ESCAPE:
+ {
+ if ( rView.IsAction() )
+ {
+ rView.BrkAction();
+ bReturn = true;
+ }
+ else if ( rView.AreObjectsMarked() )
+ {
+ const SdrHdlList& rHdlList = rView.GetHdlList();
+ SdrHdl* pHdl = rHdlList.GetFocusHdl();
+ if ( pHdl )
+ const_cast<SdrHdlList&>(rHdlList).ResetFocusHdl();
+ else
+ rView.UnmarkAll();
+
+ bReturn = true;
+ }
+ }
+ break;
+ case KEY_TAB:
+ {
+ if ( !aCode.IsMod1() && !aCode.IsMod2() )
+ {
+ // mark next object
+ if ( !rView.MarkNextObj( !aCode.IsShift() ) )
+ {
+ // if no next object, mark first/last
+ rView.UnmarkAllObj();
+ rView.MarkNextObj( !aCode.IsShift() );
+ }
+
+ if ( rView.AreObjectsMarked() )
+ rView.MakeVisible( rView.GetAllMarkedRect(), rWindow );
+
+ bReturn = true;
+ }
+ else if ( aCode.IsMod1() )
+ {
+ // selected handle
+ const SdrHdlList& rHdlList = rView.GetHdlList();
+ const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl( !aCode.IsShift() );
+
+ // guarantee visibility of focused handle
+ if (SdrHdl* pHdl = rHdlList.GetFocusHdl())
+ {
+ Point aHdlPosition( pHdl->GetPos() );
+ tools::Rectangle aVisRect( aHdlPosition - Point( 100, 100 ), Size( 200, 200 ) );
+ rView.MakeVisible( aVisRect, rWindow );
+ }
+
+ bReturn = true;
+ }
+ }
+ break;
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ {
+ tools::Long nX = 0;
+ tools::Long nY = 0;
+
+ if ( nCode == KEY_UP )
+ {
+ // scroll up
+ nX = 0;
+ nY = -1;
+ }
+ else if ( nCode == KEY_DOWN )
+ {
+ // scroll down
+ nX = 0;
+ nY = 1;
+ }
+ else if ( nCode == KEY_LEFT )
+ {
+ // scroll left
+ nX = -1;
+ nY = 0;
+ }
+ else if ( nCode == KEY_RIGHT )
+ {
+ // scroll right
+ nX = 1;
+ nY = 0;
+ }
+
+ if ( rView.AreObjectsMarked() && !aCode.IsMod1() )
+ {
+ if ( aCode.IsMod2() )
+ {
+ // move in 1 pixel distance
+ Size aPixelSize = rWindow.PixelToLogic(Size(1, 1));
+ nX *= aPixelSize.Width();
+ nY *= aPixelSize.Height();
+ }
+ else
+ {
+ // move in 1 mm distance
+ nX *= 100;
+ nY *= 100;
+ }
+
+ const SdrHdlList& rHdlList = rView.GetHdlList();
+ SdrHdl* pHdl = rHdlList.GetFocusHdl();
+
+ if ( pHdl == nullptr )
+ {
+ // no handle selected
+ if ( rView.IsMoveAllowed() )
+ {
+ // restrict movement to work area
+ const tools::Rectangle& rWorkArea = rView.GetWorkArea();
+
+ if ( !rWorkArea.IsEmpty() )
+ {
+ tools::Rectangle aMarkRect( rView.GetMarkedObjRect() );
+ aMarkRect.Move( nX, nY );
+
+ if ( !rWorkArea.Contains( aMarkRect ) )
+ {
+ if ( aMarkRect.Left() < rWorkArea.Left() )
+ nX += rWorkArea.Left() - aMarkRect.Left();
+
+ if ( aMarkRect.Right() > rWorkArea.Right() )
+ nX -= aMarkRect.Right() - rWorkArea.Right();
+
+ if ( aMarkRect.Top() < rWorkArea.Top() )
+ nY += rWorkArea.Top() - aMarkRect.Top();
+
+ if ( aMarkRect.Bottom() > rWorkArea.Bottom() )
+ nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
+ }
+ }
+
+ if ( nX != 0 || nY != 0 )
+ {
+ rView.MoveAllMarked( Size( nX, nY ) );
+ rView.MakeVisible( rView.GetAllMarkedRect(), rWindow );
+ }
+ }
+ }
+ else if (nX || nY)
+ {
+ Point aStartPoint(pHdl->GetPos());
+ Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
+ const SdrDragStat& rDragStat = rView.GetDragStat();
+
+ // start dragging
+ rView.BegDragObj(aStartPoint, nullptr, pHdl, 0);
+
+ if (rView.IsDragObj())
+ {
+ bool const bWasNoSnap = rDragStat.IsNoSnap();
+ bool const bWasSnapEnabled = rView.IsSnapEnabled();
+
+ // switch snapping off
+ if (!bWasNoSnap)
+ const_cast<SdrDragStat&>(rDragStat).SetNoSnap();
+ if (bWasSnapEnabled)
+ rView.SetSnapEnabled(false);
+
+ rView.MovAction(aEndPoint);
+ rView.EndDragObj();
+
+ // restore snap
+ if (!bWasNoSnap)
+ const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap);
+ if (bWasSnapEnabled)
+ rView.SetSnapEnabled(bWasSnapEnabled);
+ }
+
+ // make moved handle visible
+ tools::Rectangle aVisRect(aEndPoint - Point(100, 100), Size(200, 200));
+ rView.MakeVisible(aVisRect, rWindow);
+ }
+ }
+ else
+ {
+ // scroll page
+ ScrollBar* pScrollBar = ( nX != 0 ) ? rParent.GetHScroll() : rParent.GetVScroll();
+ if ( pScrollBar )
+ {
+ tools::Long nRangeMin = pScrollBar->GetRangeMin();
+ tools::Long nRangeMax = pScrollBar->GetRangeMax();
+ tools::Long nThumbPos = pScrollBar->GetThumbPos() + ( ( nX != 0 ) ? nX : nY ) * pScrollBar->GetLineSize();
+ if ( nThumbPos < nRangeMin )
+ nThumbPos = nRangeMin;
+ if ( nThumbPos > nRangeMax )
+ nThumbPos = nRangeMax;
+ pScrollBar->SetThumbPos( nThumbPos );
+ rParent.DoScroll();
+ }
+ }
+
+ bReturn = true;
+ }
+ break;
+ default:
+ {
+ }
+ break;
+ }
+
+ if ( bReturn )
+ rWindow.ReleaseMouse();
+
+ return bReturn;
+}
+
+DlgEdFuncInsert::DlgEdFuncInsert (DlgEditor& rParent_) :
+ DlgEdFunc(rParent_)
+{
+ rParent.GetView().SetCreateMode();
+}
+
+DlgEdFuncInsert::~DlgEdFuncInsert()
+{
+ rParent.GetView().SetEditMode();
+}
+
+void DlgEdFuncInsert::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if( !rMEvt.IsLeft() )
+ return;
+
+ SdrView& rView = rParent.GetView();
+ vcl::Window& rWindow = rParent.GetWindow();
+ rView.SetActualWin(rWindow.GetOutDev());
+
+ Point aPos = rWindow.PixelToLogic( rMEvt.GetPosPixel() );
+ sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width());
+ sal_uInt16 nDrgLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width());
+
+ rWindow.CaptureMouse();
+
+ if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 1 )
+ {
+ SdrHdl* pHdl = rView.PickHandle(aPos);
+
+ // if selected object was hit, drag object
+ if ( pHdl!=nullptr || rView.IsMarkedHit(aPos, nHitLog) )
+ rView.BegDragObj(aPos, nullptr, pHdl, nDrgLog);
+ else if ( rView.AreObjectsMarked() )
+ rView.UnmarkAll();
+
+ // if no action, create object
+ if ( !rView.IsAction() )
+ rView.BegCreateObj(aPos);
+ }
+ else if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 2 )
+ {
+ // if object was hit, show property browser
+ if ( rView.IsMarkedHit(aPos, nHitLog) && rParent.GetMode() != DlgEditor::READONLY )
+ rParent.ShowProperties();
+ }
+}
+
+bool DlgEdFuncInsert::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ DlgEdFunc::MouseButtonUp( rMEvt );
+
+ SdrView& rView = rParent.GetView();
+ vcl::Window& rWindow = rParent.GetWindow();
+ rView.SetActualWin(rWindow.GetOutDev());
+
+ rWindow.ReleaseMouse();
+
+ // object creation active?
+ if ( rView.IsCreateObj() )
+ {
+ rView.EndCreateObj(SdrCreateCmd::ForceEnd);
+
+ if ( !rView.AreObjectsMarked() )
+ {
+ sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width());
+ Point aPos( rWindow.PixelToLogic( rMEvt.GetPosPixel() ) );
+ rView.MarkObj(aPos, nHitLog);
+ }
+
+ return rView.AreObjectsMarked();
+ }
+ else
+ {
+ if ( rView.IsDragObj() )
+ rView.EndDragObj( rMEvt.IsMod1() );
+ return true;
+ }
+}
+
+void DlgEdFuncInsert::MouseMove( const MouseEvent& rMEvt )
+{
+ SdrView& rView = rParent.GetView();
+ vcl::Window& rWindow = rParent.GetWindow();
+ rView.SetActualWin(rWindow.GetOutDev());
+
+ Point aPos = rWindow.PixelToLogic(rMEvt.GetPosPixel());
+ sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width());
+
+ if (rView.IsAction())
+ {
+ ForceScroll(aPos);
+ rView.MovAction(aPos);
+ }
+
+ rWindow.SetPointer( rView.GetPreferredPointer( aPos, rWindow.GetOutDev(), nHitLog ) );
+}
+
+DlgEdFuncSelect::DlgEdFuncSelect (DlgEditor& rParent_) :
+ DlgEdFunc(rParent_)
+{
+}
+
+DlgEdFuncSelect::~DlgEdFuncSelect()
+{
+}
+
+void DlgEdFuncSelect::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ // get view from parent
+ SdrView& rView = rParent.GetView();
+ vcl::Window& rWindow = rParent.GetWindow();
+ rView.SetActualWin(rWindow.GetOutDev());
+
+ sal_uInt16 nDrgLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width());
+ sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width());
+ Point aMDPos = rWindow.PixelToLogic(rMEvt.GetPosPixel());
+
+ if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 1 )
+ {
+ SdrHdl* pHdl = rView.PickHandle(aMDPos);
+
+ // hit selected object?
+ if ( pHdl!=nullptr || rView.IsMarkedHit(aMDPos, nHitLog) )
+ {
+ rView.BegDragObj(aMDPos, nullptr, pHdl, nDrgLog);
+ }
+ else
+ {
+ // if not multi selection, unmark all
+ if ( !rMEvt.IsShift() )
+ rView.UnmarkAll();
+ else
+ {
+ SdrPageView* pPV;
+ SdrObject* pObj = rView.PickObj(aMDPos, nHitLog, pPV);
+ if (pObj)
+ {
+ //if (dynamic_cast<DlgEdForm*>(pObj))
+ // rView.UnmarkAll();
+ //else
+ // rParent.UnmarkDialog();
+ }
+ }
+
+ if ( rView.MarkObj(aMDPos, nHitLog) )
+ {
+ // drag object
+ pHdl = rView.PickHandle(aMDPos);
+ rView.BegDragObj(aMDPos, nullptr, pHdl, nDrgLog);
+ }
+ else
+ {
+ // select object
+ rView.BegMarkObj(aMDPos);
+ }
+ }
+ }
+ else if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 2 )
+ {
+ // if object was hit, show property browser
+ if ( rView.IsMarkedHit(aMDPos, nHitLog) && rParent.GetMode() != DlgEditor::READONLY )
+ rParent.ShowProperties();
+ }
+}
+
+bool DlgEdFuncSelect::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ DlgEdFunc::MouseButtonUp( rMEvt );
+
+ // get view from parent
+ SdrView& rView = rParent.GetView();
+ vcl::Window& rWindow = rParent.GetWindow();
+ rView.SetActualWin(rWindow.GetOutDev());
+
+ Point aPnt = rWindow.PixelToLogic(rMEvt.GetPosPixel());
+ sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width());
+
+ if ( rMEvt.IsLeft() )
+ {
+ if (rView.IsDragObj())
+ {
+ // object was dragged
+ rView.EndDragObj( rMEvt.IsMod1() );
+ rView.ForceMarkedToAnotherPage();
+ }
+ else if (rView.IsAction())
+ {
+ rView.EndAction();
+ }
+ }
+
+ rWindow.SetPointer( rView.GetPreferredPointer( aPnt, rWindow.GetOutDev(), nHitLog ) );
+ rWindow.ReleaseMouse();
+
+ return true;
+}
+
+void DlgEdFuncSelect::MouseMove( const MouseEvent& rMEvt )
+{
+ SdrView& rView = rParent.GetView();
+ vcl::Window& rWindow = rParent.GetWindow();
+ rView.SetActualWin(rWindow.GetOutDev());
+
+ Point aPnt = rWindow.PixelToLogic(rMEvt.GetPosPixel());
+ sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width());
+
+ if ( rView.IsAction() )
+ {
+ Point aPix = rMEvt.GetPosPixel();
+ Point aPnt_ = rWindow.PixelToLogic(aPix);
+
+ ForceScroll(aPnt_);
+ rView.MovAction(aPnt_);
+ }
+
+ rWindow.SetPointer( rView.GetPreferredPointer( aPnt, rWindow.GetOutDev(), nHitLog ) );
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/dlged/dlgedlist.cxx b/basctl/source/dlged/dlgedlist.cxx
new file mode 100644
index 000000000..6b9cebfe8
--- /dev/null
+++ b/basctl/source/dlged/dlgedlist.cxx
@@ -0,0 +1,80 @@
+/* -*- 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 <dlgedlist.hxx>
+#include <dlgedobj.hxx>
+
+namespace basctl
+{
+
+// DlgEdPropListenerImpl
+DlgEdPropListenerImpl::DlgEdPropListenerImpl (DlgEdObj& rObj) :
+ rDlgEdObj(rObj)
+{
+}
+
+DlgEdPropListenerImpl::~DlgEdPropListenerImpl()
+{
+}
+
+// XEventListener
+void SAL_CALL DlgEdPropListenerImpl::disposing( const css::lang::EventObject& )
+{
+}
+
+// XPropertyChangeListener
+void SAL_CALL DlgEdPropListenerImpl::propertyChange( const css::beans::PropertyChangeEvent& evt )
+{
+ rDlgEdObj._propertyChange( evt );
+}
+
+// DlgEdEvtContListenerImpl
+DlgEdEvtContListenerImpl::DlgEdEvtContListenerImpl (DlgEdObj& rObj) :
+ rDlgEdObj(rObj)
+{
+}
+
+DlgEdEvtContListenerImpl::~DlgEdEvtContListenerImpl()
+{
+}
+
+// XEventListener
+void SAL_CALL DlgEdEvtContListenerImpl::disposing( const css::lang::EventObject& )
+{
+}
+
+// XContainerListener
+void SAL_CALL DlgEdEvtContListenerImpl::elementInserted(const css::container::ContainerEvent& /*Event*/)
+{
+ rDlgEdObj._elementInserted();
+}
+
+void SAL_CALL DlgEdEvtContListenerImpl::elementReplaced(const css::container::ContainerEvent& /*Event*/)
+{
+ rDlgEdObj._elementReplaced();
+}
+
+void SAL_CALL DlgEdEvtContListenerImpl::elementRemoved(const css::container::ContainerEvent& /*Event*/)
+{
+ rDlgEdObj._elementRemoved();
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/dlged/dlgedmod.cxx b/basctl/source/dlged/dlgedmod.cxx
new file mode 100644
index 000000000..017e4b16c
--- /dev/null
+++ b/basctl/source/dlged/dlgedmod.cxx
@@ -0,0 +1,36 @@
+/* -*- 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 <dlgedmod.hxx>
+#include <dlgedpage.hxx>
+
+namespace basctl
+{
+DlgEdModel::DlgEdModel() {}
+
+DlgEdModel::~DlgEdModel() {}
+
+rtl::Reference<SdrPage> DlgEdModel::AllocPage(bool bMasterPage)
+{
+ return new DlgEdPage(*this, bMasterPage);
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/dlged/dlgedobj.cxx b/basctl/source/dlged/dlgedobj.cxx
new file mode 100644
index 000000000..1d89210b7
--- /dev/null
+++ b/basctl/source/dlged/dlgedobj.cxx
@@ -0,0 +1,1703 @@
+/* -*- 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 <sal/log.hxx>
+
+#include <cassert>
+
+#include <dlged.hxx>
+#include <dlgeddef.hxx>
+#include <dlgedlist.hxx>
+#include <dlgedobj.hxx>
+#include <dlgedpage.hxx>
+#include <dlgedview.hxx>
+#include <localizationmgr.hxx>
+#include <strings.hxx>
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/awt/XUnoControlContainer.hpp>
+#include <com/sun/star/awt/XVclContainerPeer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/script/XScriptEventsSupplier.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <cppuhelper/exc_hlp.hxx>
+#include <o3tl/functional.hxx>
+#include <svx/svdpagv.hxx>
+#include <unotools/sharedunocomponent.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/debug.hxx>
+
+namespace basctl
+{
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::script;
+
+
+DlgEditor& DlgEdObj::GetDialogEditor ()
+{
+ if (DlgEdForm* pFormThis = dynamic_cast<DlgEdForm*>(this))
+ return pFormThis->GetDlgEditor();
+ else
+ return pDlgEdForm->GetDlgEditor();
+}
+
+DlgEdObj::DlgEdObj(SdrModel& rSdrModel)
+: SdrUnoObj(rSdrModel, OUString())
+ ,bIsListening(false)
+ ,pDlgEdForm( nullptr )
+{
+}
+
+DlgEdObj::DlgEdObj(SdrModel& rSdrModel, DlgEdObj const & rSource)
+: SdrUnoObj(rSdrModel, rSource)
+ ,bIsListening(false)
+{
+ // set parent form
+ pDlgEdForm = rSource.pDlgEdForm;
+
+ // add child to parent form
+ pDlgEdForm->AddChild( this );
+
+ Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
+ if ( xPSet.is() )
+ {
+ // set new name
+ OUString aOUniqueName( GetUniqueName() );
+ Any aUniqueName;
+ aUniqueName <<= aOUniqueName;
+ xPSet->setPropertyValue( DLGED_PROP_NAME, aUniqueName );
+
+ Reference< container::XNameContainer > xCont( GetDlgEdForm()->GetUnoControlModel() , UNO_QUERY );
+ if ( xCont.is() )
+ {
+ // set tabindex
+ Sequence< OUString > aNames = xCont->getElementNames();
+ xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(aNames.getLength())) );
+
+ // insert control model in dialog model
+ Reference< awt::XControlModel > xCtrl( xPSet , UNO_QUERY );
+ xCont->insertByName( aOUniqueName, Any(xCtrl) );
+
+ pDlgEdForm->UpdateTabOrderAndGroups();
+ }
+ }
+
+ // start listening
+ StartListening();
+}
+
+DlgEdObj::DlgEdObj(
+ SdrModel& rSdrModel,
+ const OUString& rModelName,
+ const css::uno::Reference< css::lang::XMultiServiceFactory >& rxSFac)
+: SdrUnoObj(rSdrModel, rModelName, rxSFac)
+ ,bIsListening(false)
+ ,pDlgEdForm( nullptr )
+{
+}
+
+DlgEdObj::~DlgEdObj()
+{
+ if ( isListening() )
+ EndListening(true);
+}
+
+namespace
+{
+ /* returns the DlgEdForm which the given DlgEdObj belongs to
+ (which might in fact be the object itself)
+
+ Failure to obtain the form will be reported with an assertion in the non-product
+ version.
+ */
+ bool lcl_getDlgEdForm( DlgEdObj* _pObject, DlgEdForm*& _out_pDlgEdForm )
+ {
+ _out_pDlgEdForm = dynamic_cast< DlgEdForm* >( _pObject );
+ if ( !_out_pDlgEdForm )
+ _out_pDlgEdForm = _pObject->GetDlgEdForm();
+ DBG_ASSERT( _out_pDlgEdForm, "lcl_getDlgEdForm: no form!" );
+ return ( _out_pDlgEdForm != nullptr );
+ }
+}
+
+uno::Reference< awt::XControl > DlgEdObj::GetControl() const
+{
+ uno::Reference< awt::XControl > xControl;
+ if (DlgEdForm const* pForm = GetDlgEdForm())
+ {
+ DlgEditor const& rEditor = pForm->GetDlgEditor();
+ xControl = GetUnoControl(rEditor.GetView(), *rEditor.GetWindow().GetOutDev());
+ }
+ return xControl;
+}
+
+bool DlgEdObj::TransformSdrToControlCoordinates(
+ sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
+ sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
+{
+ // input position and size
+ Size aPos( nXIn, nYIn );
+ Size aSize( nWidthIn, nHeightIn );
+
+ // form position
+ DlgEdForm* pForm = nullptr;
+ if ( !lcl_getDlgEdForm( this, pForm ) )
+ return false;
+ tools::Rectangle aFormRect = pForm->GetSnapRect();
+ Size aFormPos( aFormRect.Left(), aFormRect.Top() );
+
+ // convert 100th_mm to pixel
+ OutputDevice* pDevice = Application::GetDefaultDevice();
+ DBG_ASSERT( pDevice, "DlgEdObj::TransformSdrToControlCoordinates: missing default device!" );
+ if ( !pDevice )
+ return false;
+ aPos = pDevice->LogicToPixel( aPos, MapMode( MapUnit::Map100thMM ) );
+ aSize = pDevice->LogicToPixel( aSize, MapMode( MapUnit::Map100thMM ) );
+ aFormPos = pDevice->LogicToPixel( aFormPos, MapMode( MapUnit::Map100thMM ) );
+
+ // subtract form position
+ aPos.AdjustWidth( -(aFormPos.Width()) );
+ aPos.AdjustHeight( -(aFormPos.Height()) );
+
+ // take window borders into account
+ Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
+ DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
+ if ( !xPSetForm.is() )
+ return false;
+ bool bDecoration = true;
+ xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
+ if( bDecoration )
+ {
+ awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
+ aPos.AdjustWidth( -(aDeviceInfo.LeftInset) );
+ aPos.AdjustHeight( -(aDeviceInfo.TopInset) );
+ }
+
+ // convert pixel to logic units
+ aPos = pDevice->PixelToLogic(aPos, MapMode(MapUnit::MapAppFont));
+ aSize = pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapAppFont));
+
+ // set out parameters
+ nXOut = aPos.Width();
+ nYOut = aPos.Height();
+ nWidthOut = aSize.Width();
+ nHeightOut = aSize.Height();
+
+ return true;
+}
+
+bool DlgEdObj::TransformSdrToFormCoordinates(
+ sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
+ sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
+{
+ // input position and size
+ Size aPos( nXIn, nYIn );
+ Size aSize( nWidthIn, nHeightIn );
+
+ // convert 100th_mm to pixel
+ OutputDevice* pDevice = Application::GetDefaultDevice();
+ DBG_ASSERT( pDevice, "DlgEdObj::TransformSdrToFormCoordinates: missing default device!" );
+ if ( !pDevice )
+ return false;
+ aPos = pDevice->LogicToPixel( aPos, MapMode( MapUnit::Map100thMM ) );
+ aSize = pDevice->LogicToPixel( aSize, MapMode( MapUnit::Map100thMM ) );
+
+ // take window borders into account
+ DlgEdForm* pForm = nullptr;
+ if ( !lcl_getDlgEdForm( this, pForm ) )
+ return false;
+
+ // take window borders into account
+ Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
+ DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
+ if ( !xPSetForm.is() )
+ return false;
+ bool bDecoration = true;
+ xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
+ if( bDecoration )
+ {
+ awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
+ aSize.AdjustWidth( -(aDeviceInfo.LeftInset + aDeviceInfo.RightInset) );
+ aSize.AdjustHeight( -(aDeviceInfo.TopInset + aDeviceInfo.BottomInset) );
+ }
+ // convert pixel to logic units
+ aPos = pDevice->PixelToLogic(aPos, MapMode(MapUnit::MapAppFont));
+ aSize = pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapAppFont));
+
+ // set out parameters
+ nXOut = aPos.Width();
+ nYOut = aPos.Height();
+ nWidthOut = aSize.Width();
+ nHeightOut = aSize.Height();
+
+ return true;
+}
+
+bool DlgEdObj::TransformControlToSdrCoordinates(
+ sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
+ sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
+{
+ // input position and size
+ Size aPos( nXIn, nYIn );
+ Size aSize( nWidthIn, nHeightIn );
+
+ // form position
+ DlgEdForm* pForm = nullptr;
+ if ( !lcl_getDlgEdForm( this, pForm ) )
+ return false;
+
+ Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
+ DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformControlToSdrCoordinates: no form property set!" );
+ if ( !xPSetForm.is() )
+ return false;
+ sal_Int32 nFormX = 0, nFormY = 0;
+ xPSetForm->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nFormX;
+ xPSetForm->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nFormY;
+ Size aFormPos( nFormX, nFormY );
+
+ // convert logic units to pixel
+ OutputDevice* pDevice = Application::GetDefaultDevice();
+ DBG_ASSERT( pDevice, "DlgEdObj::TransformControlToSdrCoordinates: missing default device!" );
+ if ( !pDevice )
+ return false;
+ aPos = pDevice->LogicToPixel(aPos, MapMode(MapUnit::MapAppFont));
+ aSize = pDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
+ aFormPos = pDevice->LogicToPixel(aFormPos, MapMode(MapUnit::MapAppFont));
+
+ // add form position
+ aPos.AdjustWidth(aFormPos.Width() );
+ aPos.AdjustHeight(aFormPos.Height() );
+
+ // take window borders into account
+ bool bDecoration = true;
+ xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
+ if( bDecoration )
+ {
+ awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
+ aPos.AdjustWidth(aDeviceInfo.LeftInset );
+ aPos.AdjustHeight(aDeviceInfo.TopInset );
+ }
+
+ // convert pixel to 100th_mm
+ aPos = pDevice->PixelToLogic( aPos, MapMode( MapUnit::Map100thMM ) );
+ aSize = pDevice->PixelToLogic( aSize, MapMode( MapUnit::Map100thMM ) );
+
+ // set out parameters
+ nXOut = aPos.Width();
+ nYOut = aPos.Height();
+ nWidthOut = aSize.Width();
+ nHeightOut = aSize.Height();
+
+ return true;
+}
+
+bool DlgEdObj::TransformFormToSdrCoordinates(
+ sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
+ sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
+{
+ // input position and size
+ Size aPos( nXIn, nYIn );
+ Size aSize( nWidthIn, nHeightIn );
+
+ // convert logic units to pixel
+ OutputDevice* pDevice = Application::GetDefaultDevice();
+ DBG_ASSERT( pDevice, "DlgEdObj::TransformFormToSdrCoordinates: missing default device!" );
+ if ( !pDevice )
+ return false;
+
+ // take window borders into account
+ DlgEdForm* pForm = nullptr;
+ if ( !lcl_getDlgEdForm( this, pForm ) )
+ return false;
+
+ aPos = pDevice->LogicToPixel(aPos, MapMode(MapUnit::MapAppFont));
+ aSize = pDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
+
+ // take window borders into account
+ Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
+ DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
+ if ( !xPSetForm.is() )
+ return false;
+ bool bDecoration = true;
+ xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
+ if( bDecoration )
+ {
+ awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
+ aSize.AdjustWidth(aDeviceInfo.LeftInset + aDeviceInfo.RightInset );
+ aSize.AdjustHeight(aDeviceInfo.TopInset + aDeviceInfo.BottomInset );
+ }
+
+ // convert pixel to 100th_mm
+ aPos = pDevice->PixelToLogic( aPos, MapMode( MapUnit::Map100thMM ) );
+ aSize = pDevice->PixelToLogic( aSize, MapMode( MapUnit::Map100thMM ) );
+
+ // set out parameters
+ nXOut = aPos.Width();
+ nYOut = aPos.Height();
+ nWidthOut = aSize.Width();
+ nHeightOut = aSize.Height();
+
+ return true;
+}
+
+void DlgEdObj::SetRectFromProps()
+{
+ // get control position and size from properties
+ Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
+ if ( !xPSet.is() )
+ return;
+
+ sal_Int32 nXIn = 0, nYIn = 0, nWidthIn = 0, nHeightIn = 0;
+ xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nXIn;
+ xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nYIn;
+ xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidthIn;
+ xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeightIn;
+
+ // transform coordinates
+ sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
+ if ( TransformControlToSdrCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
+ {
+ // set rectangle position and size
+ Point aPoint( nXOut, nYOut );
+ Size aSize( nWidthOut, nHeightOut );
+ SetSnapRect( tools::Rectangle( aPoint, aSize ) );
+ }
+}
+
+void DlgEdObj::SetPropsFromRect()
+{
+ // get control position and size from rectangle
+ tools::Rectangle aRect_ = GetSnapRect();
+ sal_Int32 nXIn = aRect_.Left();
+ sal_Int32 nYIn = aRect_.Top();
+ sal_Int32 nWidthIn = aRect_.GetWidth();
+ sal_Int32 nHeightIn = aRect_.GetHeight();
+
+ // transform coordinates
+ sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
+ if ( TransformSdrToControlCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
+ {
+ // set properties
+ Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
+ if ( xPSet.is() )
+ {
+ xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nXOut) );
+ xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nYOut) );
+ xPSet->setPropertyValue( DLGED_PROP_WIDTH, Any(nWidthOut) );
+ xPSet->setPropertyValue( DLGED_PROP_HEIGHT, Any(nHeightOut) );
+ }
+ }
+}
+
+void DlgEdObj::PositionAndSizeChange( const beans::PropertyChangeEvent& evt )
+{
+ DBG_ASSERT( pDlgEdForm, "DlgEdObj::PositionAndSizeChange: no form!" );
+ DlgEdPage& rPage = pDlgEdForm->GetDlgEditor().GetPage();
+ {
+ Size aPageSize = rPage.GetSize();
+ sal_Int32 nPageWidthIn = aPageSize.Width();
+ sal_Int32 nPageHeightIn = aPageSize.Height();
+ sal_Int32 nPageX, nPageY, nPageWidth, nPageHeight;
+ if ( TransformSdrToControlCoordinates( 0/*nPageXIn*/, 0/*nPageYIn*/, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
+ {
+ Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
+ if ( xPSet.is() )
+ {
+ sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
+ xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nX;
+ xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nY;
+ xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
+ xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
+
+ sal_Int32 nValue = 0;
+ evt.NewValue >>= nValue;
+ sal_Int32 nNewValue = nValue;
+
+ if ( evt.PropertyName == DLGED_PROP_POSITIONX )
+ {
+ if ( nNewValue + nWidth > nPageX + nPageWidth )
+ nNewValue = nPageX + nPageWidth - nWidth;
+ if ( nNewValue < nPageX )
+ nNewValue = nPageX;
+ }
+ else if ( evt.PropertyName == DLGED_PROP_POSITIONY )
+ {
+ if ( nNewValue + nHeight > nPageY + nPageHeight )
+ nNewValue = nPageY + nPageHeight - nHeight;
+ if ( nNewValue < nPageY )
+ nNewValue = nPageY;
+ }
+ else if ( evt.PropertyName == DLGED_PROP_WIDTH )
+ {
+ if ( nX + nNewValue > nPageX + nPageWidth )
+ nNewValue = nPageX + nPageWidth - nX;
+ if ( nNewValue < 1 )
+ nNewValue = 1;
+ }
+ else if ( evt.PropertyName == DLGED_PROP_HEIGHT )
+ {
+ if ( nY + nNewValue > nPageY + nPageHeight )
+ nNewValue = nPageY + nPageHeight - nY;
+ if ( nNewValue < 1 )
+ nNewValue = 1;
+ }
+
+ if ( nNewValue != nValue )
+ {
+ EndListening( false );
+ xPSet->setPropertyValue( evt.PropertyName, Any(nNewValue) );
+ StartListening();
+ }
+ }
+ }
+ }
+
+ SetRectFromProps();
+}
+
+void DlgEdObj::NameChange( const css::beans::PropertyChangeEvent& evt )
+{
+ // get old name
+ OUString aOldName;
+ evt.OldValue >>= aOldName;
+
+ // get new name
+ OUString aNewName;
+ evt.NewValue >>= aNewName;
+
+ if ( aNewName == aOldName )
+ return;
+
+ Reference< container::XNameAccess > xNameAcc((GetDlgEdForm()->GetUnoControlModel()), UNO_QUERY);
+ if ( !(xNameAcc.is() && xNameAcc->hasByName(aOldName)) )
+ return;
+
+ if (!xNameAcc->hasByName(aNewName) && !aNewName.isEmpty())
+ {
+ // remove the control by the old name and insert the control by the new name in the container
+ Reference< container::XNameContainer > xCont(xNameAcc, UNO_QUERY );
+ if ( xCont.is() )
+ {
+ Reference< awt::XControlModel > xCtrl = GetUnoControlModel();
+ Any aAny;
+ aAny <<= xCtrl;
+ xCont->removeByName( aOldName );
+ xCont->insertByName( aNewName , aAny );
+
+ LocalizationMgr::renameControlResourceIDsForEditorObject(
+ &GetDialogEditor(), aAny, aNewName
+ );
+ }
+ }
+ else
+ {
+ // set old name property
+ EndListening(false);
+ Reference< beans::XPropertySet > xPSet(GetUnoControlModel(), UNO_QUERY);
+ xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOldName) );
+ StartListening();
+ }
+}
+
+sal_Int32 DlgEdObj::GetStep() const
+{
+ // get step property
+ sal_Int32 nStep = 0;
+ uno::Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), uno::UNO_QUERY );
+ if (xPSet.is())
+ {
+ xPSet->getPropertyValue( DLGED_PROP_STEP ) >>= nStep;
+ }
+ return nStep;
+}
+
+void DlgEdObj::UpdateStep()
+{
+ sal_Int32 nCurStep = GetDlgEdForm()->GetStep();
+ sal_Int32 nStep = GetStep();
+
+ SdrLayerAdmin& rLayerAdmin(getSdrModelFromSdrObject().GetLayerAdmin());
+ SdrLayerID nHiddenLayerId = rLayerAdmin.GetLayerID( "HiddenLayer" );
+ SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName() );
+
+ if( nCurStep )
+ {
+ if ( nStep && (nStep != nCurStep) )
+ {
+ SetLayer( nHiddenLayerId );
+ }
+ else
+ {
+ SetLayer( nControlLayerId );
+ }
+ }
+ else
+ {
+ SetLayer( nControlLayerId );
+ }
+}
+
+void DlgEdObj::TabIndexChange( const beans::PropertyChangeEvent& evt )
+{
+ DlgEdForm* pForm = GetDlgEdForm();
+ if ( !pForm )
+ return;
+
+ // stop listening with all children
+ std::vector<DlgEdObj*> aChildList = pForm->GetChildren();
+ for (auto const& child : aChildList)
+ {
+ child->EndListening( false );
+ }
+
+ Reference< container::XNameAccess > xNameAcc( pForm->GetUnoControlModel() , UNO_QUERY );
+ if ( xNameAcc.is() )
+ {
+ // get sequence of control names
+ Sequence< OUString > aNames = xNameAcc->getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 nCtrls = aNames.getLength();
+
+ // create a map of tab indices and control names, sorted by tab index
+ IndexToNameMap aIndexToNameMap;
+ for ( sal_Int32 i = 0; i < nCtrls; ++i )
+ {
+ // get control name
+ OUString aName( pNames[i] );
+
+ // get tab index
+ sal_Int16 nTabIndex = -1;
+ Any aCtrl = xNameAcc->getByName( aName );
+ Reference< beans::XPropertySet > xPSet;
+ aCtrl >>= xPSet;
+ if ( xPSet.is() && xPSet == Reference< beans::XPropertySet >( evt.Source, UNO_QUERY ) )
+ evt.OldValue >>= nTabIndex;
+ else if ( xPSet.is() )
+ xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
+
+ // insert into map
+ aIndexToNameMap.emplace( nTabIndex, aName );
+ }
+
+ // create a helper list of control names, sorted by tab index
+ std::vector< OUString > aNameList( aIndexToNameMap.size() );
+ std::transform(
+ aIndexToNameMap.begin(), aIndexToNameMap.end(),
+ aNameList.begin(),
+ ::o3tl::select2nd< IndexToNameMap::value_type >( )
+ );
+
+ // check tab index
+ sal_Int16 nOldTabIndex = 0;
+ evt.OldValue >>= nOldTabIndex;
+ sal_Int16 nNewTabIndex = 0;
+ evt.NewValue >>= nNewTabIndex;
+ if ( nNewTabIndex < 0 )
+ nNewTabIndex = 0;
+ else if ( nNewTabIndex > nCtrls - 1 )
+ nNewTabIndex = sal::static_int_cast<sal_Int16>( nCtrls - 1 );
+
+ // reorder helper list
+ OUString aCtrlName = aNameList[nOldTabIndex];
+ aNameList.erase( aNameList.begin() + nOldTabIndex );
+ aNameList.insert( aNameList.begin() + nNewTabIndex , aCtrlName );
+
+ // set new tab indices
+ for ( sal_Int32 i = 0; i < nCtrls; ++i )
+ {
+ Any aCtrl = xNameAcc->getByName( aNameList[i] );
+ Reference< beans::XPropertySet > xPSet;
+ aCtrl >>= xPSet;
+ if ( xPSet.is() )
+ {
+ assert(i >= SAL_MIN_INT16);
+ if (i > SAL_MAX_INT16)
+ {
+ SAL_WARN("basctl", "tab " << i << " > SAL_MAX_INT16");
+ continue;
+ }
+ xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(i)) );
+ }
+ }
+
+ // reorder objects in drawing page
+ getSdrModelFromSdrObject().GetPage(0)->SetObjectOrdNum( nOldTabIndex + 1, nNewTabIndex + 1 );
+
+ pForm->UpdateTabOrderAndGroups();
+ }
+
+ // start listening with all children
+ for (auto const& child : aChildList)
+ {
+ child->StartListening();
+ }
+}
+
+bool DlgEdObj::supportsService( OUString const & serviceName ) const
+{
+ bool bSupports = false;
+
+ Reference< lang::XServiceInfo > xServiceInfo( GetUnoControlModel() , UNO_QUERY );
+ // TODO: cache xServiceInfo as member?
+ if ( xServiceInfo.is() )
+ bSupports = xServiceInfo->supportsService( serviceName );
+
+ return bSupports;
+}
+
+OUString DlgEdObj::GetDefaultName() const
+{
+ OUString sResId;
+ OUString aDefaultName;
+ if ( supportsService( "com.sun.star.awt.UnoControlDialogModel" ) )
+ {
+ sResId = RID_STR_CLASS_DIALOG;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ) )
+ {
+ sResId = RID_STR_CLASS_BUTTON;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) )
+ {
+ sResId = RID_STR_CLASS_RADIOBUTTON;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) )
+ {
+ sResId = RID_STR_CLASS_CHECKBOX;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlListBoxModel" ) )
+ {
+ sResId = RID_STR_CLASS_LISTBOX;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ) )
+ {
+ sResId = RID_STR_CLASS_COMBOBOX;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) )
+ {
+ sResId = RID_STR_CLASS_GROUPBOX;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlEditModel" ) )
+ {
+ sResId = RID_STR_CLASS_EDIT;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
+ {
+ sResId = RID_STR_CLASS_FIXEDTEXT;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlImageControlModel" ) )
+ {
+ sResId = RID_STR_CLASS_IMAGECONTROL;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ) )
+ {
+ sResId = RID_STR_CLASS_PROGRESSBAR;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ) )
+ {
+ sResId = RID_STR_CLASS_SCROLLBAR;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ) )
+ {
+ sResId = RID_STR_CLASS_FIXEDLINE;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_DATEFIELD;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_TIMEFIELD;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_NUMERICFIELD;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_CURRENCYFIELD;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_FORMATTEDFIELD;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_PATTERNFIELD;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlFileControlModel" ) )
+ {
+ sResId = RID_STR_CLASS_FILECONTROL;
+ }
+ else if ( supportsService( "com.sun.star.awt.tree.TreeControlModel" ) )
+ {
+ sResId = RID_STR_CLASS_TREECONTROL;
+ }
+ else if ( supportsService( "com.sun.star.awt.grid.UnoControlGridModel" ) )
+ {
+ sResId = RID_STR_CLASS_GRIDCONTROL;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlFixedHyperlinkModel" ) )
+ {
+ sResId = RID_STR_CLASS_HYPERLINKCONTROL;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlSpinButtonModel" ) )
+ {
+ sResId = RID_STR_CLASS_SPINCONTROL;
+ }
+ else
+ {
+ sResId = RID_STR_CLASS_CONTROL;
+ }
+
+ if (!sResId.isEmpty())
+ aDefaultName = sResId;
+
+ return aDefaultName;
+}
+
+OUString DlgEdObj::GetUniqueName() const
+{
+ OUString aUniqueName;
+ uno::Reference< container::XNameAccess > xNameAcc((GetDlgEdForm()->GetUnoControlModel()), uno::UNO_QUERY);
+
+ if ( xNameAcc.is() )
+ {
+ sal_Int32 n = 0;
+ OUString aDefaultName = GetDefaultName();
+
+ do
+ {
+ aUniqueName = aDefaultName + OUString::number(++n);
+ } while (xNameAcc->hasByName(aUniqueName));
+ }
+
+ return aUniqueName;
+}
+
+SdrInventor DlgEdObj::GetObjInventor() const
+{
+ return SdrInventor::BasicDialog;
+}
+
+SdrObjKind DlgEdObj::GetObjIdentifier() const
+{
+ if ( supportsService( "com.sun.star.awt.UnoControlDialogModel" ))
+ {
+ return SdrObjKind::BasicDialogDialog;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ))
+ {
+ return SdrObjKind::BasicDialogPushButton;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ))
+ {
+ return SdrObjKind::BasicDialogRadioButton;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ))
+ {
+ return SdrObjKind::BasicDialogCheckbox;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlListBoxModel" ))
+ {
+ return SdrObjKind::BasicDialogListbox;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ))
+ {
+ return SdrObjKind::BasicDialogCombobox;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ))
+ {
+ return SdrObjKind::BasicDialogGroupBox;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlEditModel" ))
+ {
+ return SdrObjKind::BasicDialogEdit;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ))
+ {
+ return SdrObjKind::BasicDialogFixedText;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlImageControlModel" ))
+ {
+ return SdrObjKind::BasicDialogImageControl;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ))
+ {
+ return SdrObjKind::BasicDialogProgressbar;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ))
+ {
+ return SdrObjKind::BasicDialogHorizontalScrollbar;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ))
+ {
+ return SdrObjKind::BasicDialogHorizontalFixedLine;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ))
+ {
+ return SdrObjKind::BasicDialogDateField;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ))
+ {
+ return SdrObjKind::BasicDialogTimeField;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ))
+ {
+ return SdrObjKind::BasicDialogNumericField;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ))
+ {
+ return SdrObjKind::BasicDialogCurencyField;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ))
+ {
+ return SdrObjKind::BasicDialogFormattedField;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ))
+ {
+ return SdrObjKind::BasicDialogPatternField;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlFileControlModel" ))
+ {
+ return SdrObjKind::BasicDialogFileControl;
+ }
+ else if ( supportsService( "com.sun.star.awt.tree.TreeControlModel" ))
+ {
+ return SdrObjKind::BasicDialogTreeControl;
+ }
+ else if ( supportsService( "com.sun.star.awt.grid.UnoControlGridModel" ))
+ {
+ return SdrObjKind::BasicDialogGridControl;
+ }
+ else if ( supportsService( "com.sun.star.awt.UnoControlFixedHyperlinkModel" ))
+ {
+ return SdrObjKind::BasicDialogHyperlinkControl;
+ }
+ else
+ {
+ return SdrObjKind::BasicDialogControl;
+ }
+}
+
+DlgEdObj* DlgEdObj::CloneSdrObject(SdrModel& rTargetModel) const
+{
+ return new DlgEdObj(rTargetModel, *this);
+}
+
+SdrObjectUniquePtr DlgEdObj::getFullDragClone() const
+{
+ // no need to really add the clone for dragging, it's a temporary
+ // object
+ return SdrObjectUniquePtr(new SdrUnoObj(getSdrModelFromSdrObject(), *this));
+}
+
+void DlgEdObj::NbcMove( const Size& rSize )
+{
+ SdrUnoObj::NbcMove( rSize );
+
+ // stop listening
+ EndListening(false);
+
+ // set geometry properties
+ SetPropsFromRect();
+
+ // start listening
+ StartListening();
+
+ // dialog model changed
+ GetDlgEdForm()->GetDlgEditor().SetDialogModelChanged();
+}
+
+void DlgEdObj::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract)
+{
+ SdrUnoObj::NbcResize( rRef, xFract, yFract );
+
+ // stop listening
+ EndListening(false);
+
+ // set geometry properties
+ SetPropsFromRect();
+
+ // start listening
+ StartListening();
+
+ // dialog model changed
+ GetDlgEdForm()->GetDlgEditor().SetDialogModelChanged();
+}
+
+bool DlgEdObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
+{
+ bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
+
+ // tdf#120674 after interactive creation, the SdrObject (this) has no SdrPage yet
+ // due to not being inserted. Usually this should be handled in a ::handlePageChange
+ // implementation. For historical reasons, the SdrPage (which is the DlgEdPage) was
+ // already set. For now, get it from the SdrDragStat and use it to access and set
+ // the local pDlgEdForm
+ if(nullptr == pDlgEdForm && nullptr != rStat.GetPageView())
+ {
+ const DlgEdPage* pDlgEdPage(dynamic_cast<const DlgEdPage*>(rStat.GetPageView()->GetPage()));
+
+ if(nullptr != pDlgEdPage)
+ {
+ // set parent form
+ pDlgEdForm = pDlgEdPage->GetDlgEdForm();
+ }
+ }
+
+ SetDefaults();
+ StartListening();
+
+ return bResult;
+}
+
+void DlgEdObj::SetDefaults()
+{
+ if ( !pDlgEdForm )
+ return;
+
+ // add child to parent form
+ pDlgEdForm->AddChild( this );
+
+ Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
+ if ( xPSet.is() )
+ {
+ // get unique name
+ OUString aOUniqueName( GetUniqueName() );
+
+ // set name property
+ xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOUniqueName) );
+
+ // set labels
+ if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ) ||
+ supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) ||
+ supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) ||
+ supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) ||
+ supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
+ {
+ xPSet->setPropertyValue( DLGED_PROP_LABEL, Any(aOUniqueName) );
+ }
+
+ // set number formats supplier for formatted field
+ if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) )
+ {
+ Reference< util::XNumberFormatsSupplier > xSupplier = GetDlgEdForm()->GetDlgEditor().GetNumberFormatsSupplier();
+ if ( xSupplier.is() )
+ {
+ xPSet->setPropertyValue( DLGED_PROP_FORMATSSUPPLIER, Any(xSupplier) );
+ }
+ }
+
+ // set geometry properties
+ SetPropsFromRect();
+
+ Reference< container::XNameContainer > xCont( GetDlgEdForm()->GetUnoControlModel() , UNO_QUERY );
+ if ( xCont.is() )
+ {
+ // set tabindex
+ Sequence< OUString > aNames = xCont->getElementNames();
+ uno::Any aTabIndex;
+ aTabIndex <<= static_cast<sal_Int16>(aNames.getLength());
+ xPSet->setPropertyValue( DLGED_PROP_TABINDEX, aTabIndex );
+
+ // set step
+ Reference< beans::XPropertySet > xPSetForm( xCont, UNO_QUERY );
+ if ( xPSetForm.is() )
+ {
+ Any aStep = xPSetForm->getPropertyValue( DLGED_PROP_STEP );
+ xPSet->setPropertyValue( DLGED_PROP_STEP, aStep );
+ }
+
+ // insert control model in dialog model
+ Reference< awt::XControlModel > xCtrl( xPSet , UNO_QUERY );
+ Any aAny;
+ aAny <<= xCtrl;
+ xCont->insertByName( aOUniqueName , aAny );
+
+ LocalizationMgr::setControlResourceIDsForNewEditorObject(
+ &GetDialogEditor(), aAny, aOUniqueName
+ );
+
+ pDlgEdForm->UpdateTabOrderAndGroups();
+ }
+ }
+
+ // dialog model changed
+ pDlgEdForm->GetDlgEditor().SetDialogModelChanged();
+}
+
+void DlgEdObj::StartListening()
+{
+ DBG_ASSERT(!isListening(), "DlgEdObj::StartListening: already listening!");
+
+ if (isListening())
+ return;
+
+ bIsListening = true;
+
+ // XPropertyChangeListener
+ Reference< XPropertySet > xControlModel( GetUnoControlModel() , UNO_QUERY );
+ if (!m_xPropertyChangeListener.is() && xControlModel.is())
+ {
+ // create listener
+ m_xPropertyChangeListener = new DlgEdPropListenerImpl(*this);
+
+ // register listener to properties
+ xControlModel->addPropertyChangeListener( OUString() , m_xPropertyChangeListener );
+ }
+
+ // XContainerListener
+ Reference< XScriptEventsSupplier > xEventsSupplier( GetUnoControlModel() , UNO_QUERY );
+ if( !m_xContainerListener.is() && xEventsSupplier.is() )
+ {
+ // create listener
+ m_xContainerListener = new DlgEdEvtContListenerImpl(*this);
+
+ // register listener to script event container
+ Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
+ DBG_ASSERT(xEventCont.is(), "DlgEdObj::StartListening: control model has no script event container!");
+ Reference< XContainer > xCont( xEventCont , UNO_QUERY );
+ if (xCont.is())
+ xCont->addContainerListener( m_xContainerListener );
+ }
+}
+
+void DlgEdObj::EndListening(bool bRemoveListener)
+{
+ DBG_ASSERT(isListening(), "DlgEdObj::EndListening: not listening currently!");
+
+ if (!isListening())
+ return;
+
+ bIsListening = false;
+
+ if (!bRemoveListener)
+ return;
+
+ // XPropertyChangeListener
+ Reference< XPropertySet > xControlModel(GetUnoControlModel(), UNO_QUERY);
+ if ( m_xPropertyChangeListener.is() && xControlModel.is() )
+ {
+ // remove listener
+ xControlModel->removePropertyChangeListener( OUString() , m_xPropertyChangeListener );
+ }
+ m_xPropertyChangeListener.clear();
+
+ // XContainerListener
+ Reference< XScriptEventsSupplier > xEventsSupplier( GetUnoControlModel() , UNO_QUERY );
+ if( m_xContainerListener.is() && xEventsSupplier.is() )
+ {
+ // remove listener
+ Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
+ DBG_ASSERT(xEventCont.is(), "DlgEdObj::EndListening: control model has no script event container!");
+ Reference< XContainer > xCont( xEventCont , UNO_QUERY );
+ if (xCont.is())
+ xCont->removeContainerListener( m_xContainerListener );
+ }
+ m_xContainerListener.clear();
+}
+
+void DlgEdObj::_propertyChange( const css::beans::PropertyChangeEvent& evt )
+{
+ if (!isListening())
+ return;
+
+ DlgEdForm* pRealDlgEdForm = dynamic_cast<DlgEdForm*>(this);
+ if (!pRealDlgEdForm)
+ pRealDlgEdForm = GetDlgEdForm();
+ if (!pRealDlgEdForm)
+ return;
+ DlgEditor& rDlgEditor = pRealDlgEdForm->GetDlgEditor();
+ if (rDlgEditor.isInPaint())
+ return;
+
+ // dialog model changed
+ rDlgEditor.SetDialogModelChanged();
+
+ // update position and size
+ if ( evt.PropertyName == DLGED_PROP_POSITIONX || evt.PropertyName == DLGED_PROP_POSITIONY ||
+ evt.PropertyName == DLGED_PROP_WIDTH || evt.PropertyName == DLGED_PROP_HEIGHT ||
+ evt.PropertyName == DLGED_PROP_DECORATION )
+ {
+ PositionAndSizeChange( evt );
+
+ if ( evt.PropertyName == DLGED_PROP_DECORATION )
+ GetDialogEditor().ResetDialog();
+ }
+ // change name of control in dialog model
+ else if ( evt.PropertyName == DLGED_PROP_NAME )
+ {
+ if (!dynamic_cast<DlgEdForm*>(this))
+ {
+ try
+ {
+ NameChange(evt);
+ }
+ catch (container::NoSuchElementException const&)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("", nullptr,
+ anyEx);
+ }
+ }
+ }
+ // update step
+ else if ( evt.PropertyName == DLGED_PROP_STEP )
+ {
+ UpdateStep();
+ }
+ // change tabindex
+ else if ( evt.PropertyName == DLGED_PROP_TABINDEX )
+ {
+ if (!dynamic_cast<DlgEdForm*>(this))
+ TabIndexChange(evt);
+ }
+}
+
+void DlgEdObj::_elementInserted()
+{
+ if (isListening())
+ {
+ // dialog model changed
+ GetDialogEditor().SetDialogModelChanged();
+ }
+}
+
+void DlgEdObj::_elementReplaced()
+{
+ if (isListening())
+ {
+ // dialog model changed
+ GetDialogEditor().SetDialogModelChanged();
+ }
+}
+
+void DlgEdObj::_elementRemoved()
+{
+ if (isListening())
+ {
+ // dialog model changed
+ GetDialogEditor().SetDialogModelChanged();
+ }
+}
+
+void DlgEdObj::SetLayer(SdrLayerID nLayer)
+{
+ SdrLayerID nOldLayer = GetLayer();
+
+ if ( nLayer != nOldLayer )
+ {
+ SdrUnoObj::SetLayer( nLayer );
+
+ DlgEdHint aHint( DlgEdHint::LAYERCHANGED, this );
+ GetDlgEdForm()->GetDlgEditor().Broadcast( aHint );
+ }
+}
+
+DlgEdForm::DlgEdForm(
+ SdrModel& rSdrModel,
+ DlgEditor& rDlgEditor_)
+: DlgEdObj(rSdrModel),
+ rDlgEditor(rDlgEditor_)
+{
+}
+
+DlgEdForm::~DlgEdForm()
+{
+}
+
+void DlgEdForm::SetRectFromProps()
+{
+ // get form position and size from properties
+ Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
+ if ( !xPSet.is() )
+ return;
+
+ sal_Int32 nXIn = 0, nYIn = 0, nWidthIn = 0, nHeightIn = 0;
+ xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nXIn;
+ xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nYIn;
+ xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidthIn;
+ xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeightIn;
+
+ // transform coordinates
+ sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
+ if ( TransformFormToSdrCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
+ {
+ // set rectangle position and size
+ Point aPoint( nXOut, nYOut );
+ Size aSize( nWidthOut, nHeightOut );
+ SetSnapRect( tools::Rectangle( aPoint, aSize ) );
+ }
+}
+
+void DlgEdForm::SetPropsFromRect()
+{
+ // get form position and size from rectangle
+ tools::Rectangle aRect_ = GetSnapRect();
+ sal_Int32 nXIn = aRect_.Left();
+ sal_Int32 nYIn = aRect_.Top();
+ sal_Int32 nWidthIn = aRect_.GetWidth();
+ sal_Int32 nHeightIn = aRect_.GetHeight();
+
+ // transform coordinates
+ sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
+ if ( TransformSdrToFormCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
+ {
+ // set properties
+ Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
+ if ( xPSet.is() )
+ {
+ xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nXOut) );
+ xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nYOut) );
+ xPSet->setPropertyValue( DLGED_PROP_WIDTH, Any(nWidthOut) );
+ xPSet->setPropertyValue( DLGED_PROP_HEIGHT, Any(nHeightOut) );
+ }
+ }
+}
+
+void DlgEdForm::AddChild( DlgEdObj* pDlgEdObj )
+{
+ pChildren.push_back( pDlgEdObj );
+}
+
+void DlgEdForm::RemoveChild( DlgEdObj* pDlgEdObj )
+{
+ pChildren.erase( std::remove( pChildren.begin() , pChildren.end() , pDlgEdObj ) );
+}
+
+void DlgEdForm::PositionAndSizeChange( const beans::PropertyChangeEvent& evt )
+{
+ DlgEditor& rEditor = GetDlgEditor();
+ DlgEdPage& rPage = rEditor.GetPage();
+
+ sal_Int32 nPageXIn = 0;
+ sal_Int32 nPageYIn = 0;
+ Size aPageSize = rPage.GetSize();
+ sal_Int32 nPageWidthIn = aPageSize.Width();
+ sal_Int32 nPageHeightIn = aPageSize.Height();
+ sal_Int32 nPageX, nPageY, nPageWidth, nPageHeight;
+ if ( TransformSdrToFormCoordinates( nPageXIn, nPageYIn, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
+ {
+ Reference< beans::XPropertySet > xPSetForm( GetUnoControlModel(), UNO_QUERY );
+ if ( xPSetForm.is() )
+ {
+ sal_Int32 nValue = 0;
+ evt.NewValue >>= nValue;
+ sal_Int32 nNewValue = nValue;
+
+ if ( evt.PropertyName == DLGED_PROP_POSITIONX )
+ {
+ if ( nNewValue < nPageX )
+ nNewValue = nPageX;
+ }
+ else if ( evt.PropertyName == DLGED_PROP_POSITIONY )
+ {
+ if ( nNewValue < nPageY )
+ nNewValue = nPageY;
+ }
+ else if ( evt.PropertyName == DLGED_PROP_WIDTH )
+ {
+ if ( nNewValue < 1 )
+ nNewValue = 1;
+ }
+ else if ( evt.PropertyName == DLGED_PROP_HEIGHT )
+ {
+ if ( nNewValue < 1 )
+ nNewValue = 1;
+ }
+
+ if ( nNewValue != nValue )
+ {
+ EndListening( false );
+ xPSetForm->setPropertyValue( evt.PropertyName, Any(nNewValue) );
+ StartListening();
+ }
+ }
+ }
+
+ bool bAdjustedPageSize = rEditor.AdjustPageSize();
+ SetRectFromProps();
+ std::vector<DlgEdObj*> const& aChildList = GetChildren();
+
+ if ( bAdjustedPageSize )
+ {
+ rEditor.InitScrollBars();
+ aPageSize = rPage.GetSize();
+ nPageWidthIn = aPageSize.Width();
+ nPageHeightIn = aPageSize.Height();
+ if ( TransformSdrToControlCoordinates( nPageXIn, nPageYIn, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
+ {
+ for (auto const& child : aChildList)
+ {
+ Reference< beans::XPropertySet > xPSet( child->GetUnoControlModel(), UNO_QUERY );
+ if ( xPSet.is() )
+ {
+ sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
+ xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nX;
+ xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nY;
+ xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
+ xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
+
+ sal_Int32 nNewX = nX;
+ if ( nX + nWidth > nPageX + nPageWidth )
+ {
+ nNewX = nPageX + nPageWidth - nWidth;
+ if ( nNewX < nPageX )
+ nNewX = nPageX;
+ }
+ if ( nNewX != nX )
+ {
+ EndListening( false );
+ xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nNewX) );
+ StartListening();
+ }
+
+ sal_Int32 nNewY = nY;
+ if ( nY + nHeight > nPageY + nPageHeight )
+ {
+ nNewY = nPageY + nPageHeight - nHeight;
+ if ( nNewY < nPageY )
+ nNewY = nPageY;
+ }
+ if ( nNewY != nY )
+ {
+ EndListening( false );
+ xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nNewY) );
+ StartListening();
+ }
+ }
+ }
+ }
+ }
+
+ for (auto const& child : aChildList)
+ child->SetRectFromProps();
+}
+
+void DlgEdForm::UpdateStep()
+{
+ SdrPage* pSdrPage = getSdrPageFromSdrObject();
+
+ if ( pSdrPage )
+ {
+ const size_t nObjCount = pSdrPage->GetObjCount();
+ for ( size_t i = 0 ; i < nObjCount ; i++ )
+ {
+ DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pSdrPage->GetObj(i));
+ if (pDlgEdObj && !dynamic_cast<DlgEdForm*>(pDlgEdObj))
+ pDlgEdObj->UpdateStep();
+ }
+ }
+}
+
+void DlgEdForm::UpdateTabIndices()
+{
+ // stop listening with all children
+ for (auto const& child : pChildren)
+ {
+ child->EndListening( false );
+ }
+
+ Reference< css::container::XNameAccess > xNameAcc( GetUnoControlModel() , UNO_QUERY );
+ if ( xNameAcc.is() )
+ {
+ // get sequence of control names
+ Sequence< OUString > aNames = xNameAcc->getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 nCtrls = aNames.getLength();
+
+ // create a map of tab indices and control names, sorted by tab index
+ IndexToNameMap aIndexToNameMap;
+ for ( sal_Int32 i = 0; i < nCtrls; ++i )
+ {
+ // get name
+ OUString aName( pNames[i] );
+
+ // get tab index
+ sal_Int16 nTabIndex = -1;
+ Any aCtrl = xNameAcc->getByName( aName );
+ Reference< css::beans::XPropertySet > xPSet;
+ aCtrl >>= xPSet;
+ if ( xPSet.is() )
+ xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
+
+ // insert into map
+ aIndexToNameMap.emplace( nTabIndex, aName );
+ }
+
+ // set new tab indices
+ sal_Int16 nNewTabIndex = 0;
+ for (auto const& indexToName : aIndexToNameMap)
+ {
+ Any aCtrl = xNameAcc->getByName( indexToName.second );
+ Reference< beans::XPropertySet > xPSet;
+ aCtrl >>= xPSet;
+ if ( xPSet.is() )
+ {
+ xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(nNewTabIndex) );
+ nNewTabIndex++;
+ }
+ }
+
+ UpdateTabOrderAndGroups();
+ }
+
+ // start listening with all children
+ for (auto const& child : pChildren)
+ {
+ child->StartListening();
+ }
+}
+
+void DlgEdForm::UpdateTabOrder()
+{
+ // When the tabindex of a control model changes, the dialog control is
+ // notified about those changes. Due to #109067# (bad performance of
+ // dialog editor) the dialog control doesn't activate the tab order
+ // in design mode. When the dialog editor has reordered all
+ // tabindices, this method allows to activate the taborder afterwards.
+
+ Reference< awt::XUnoControlContainer > xCont( GetControl(), UNO_QUERY );
+ if ( xCont.is() )
+ {
+ Sequence< Reference< awt::XTabController > > aSeqTabCtrls = xCont->getTabControllers();
+ const Reference< awt::XTabController >* pTabCtrls = aSeqTabCtrls.getConstArray();
+ sal_Int32 nCount = aSeqTabCtrls.getLength();
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ pTabCtrls[i]->activateTabOrder();
+ }
+}
+
+void DlgEdForm::UpdateGroups()
+{
+ // The grouping of radio buttons in a dialog is done by vcl.
+ // In the dialog editor we have two views (=controls) for one
+ // radio button model. One control is owned by the dialog control,
+ // but not visible in design mode. The other control is owned by
+ // the drawing layer object. Whereas the grouping of the first
+ // control is done by vcl, the grouping of the control in the
+ // drawing layer has to be done here.
+
+ Reference< awt::XTabControllerModel > xTabModel( GetUnoControlModel() , UNO_QUERY );
+ if ( !xTabModel.is() )
+ return;
+
+ // create a global list of controls that belong to the dialog
+ std::vector<DlgEdObj*> aChildList = GetChildren();
+ sal_uInt32 nSize = aChildList.size();
+ Sequence< Reference< awt::XControl > > aSeqControls( nSize );
+ for ( sal_uInt32 i = 0; i < nSize; ++i )
+ aSeqControls.getArray()[i] = aChildList[i]->GetControl();
+
+ sal_Int32 nGroupCount = xTabModel->getGroupCount();
+ for ( sal_Int32 nGroup = 0; nGroup < nGroupCount; ++nGroup )
+ {
+ // get a list of control models that belong to this group
+ OUString aName;
+ Sequence< Reference< awt::XControlModel > > aSeqModels;
+ xTabModel->getGroup( nGroup, aSeqModels, aName );
+ const Reference< awt::XControlModel >* pModels = aSeqModels.getConstArray();
+ sal_Int32 nModelCount = aSeqModels.getLength();
+
+ // create a list of peers that belong to this group
+ Sequence< Reference< awt::XWindow > > aSeqPeers( nModelCount );
+ for ( sal_Int32 nModel = 0; nModel < nModelCount; ++nModel )
+ {
+ // for each control model find the corresponding control in the global list
+ const Reference< awt::XControl >* pControls = aSeqControls.getConstArray();
+ sal_Int32 nControlCount = aSeqControls.getLength();
+ for ( sal_Int32 nControl = 0; nControl < nControlCount; ++nControl )
+ {
+ const Reference< awt::XControl > xCtrl( pControls[nControl] );
+ if ( xCtrl.is() )
+ {
+ Reference< awt::XControlModel > xCtrlModel( xCtrl->getModel() );
+ if ( xCtrlModel.get() == pModels[nModel].get() )
+ {
+ // get the control peer and insert into the list of peers
+ aSeqPeers.getArray()[ nModel ].set( xCtrl->getPeer(), UNO_QUERY );
+ break;
+ }
+ }
+ }
+ }
+
+ // set the group at the dialog peer
+ Reference< awt::XControl > xDlg = GetControl();
+ if ( xDlg.is() )
+ {
+ Reference< awt::XVclContainerPeer > xDlgPeer( xDlg->getPeer(), UNO_QUERY );
+ if ( xDlgPeer.is() )
+ xDlgPeer->setGroup( aSeqPeers );
+ }
+ }
+}
+
+void DlgEdForm::UpdateTabOrderAndGroups()
+{
+ UpdateTabOrder();
+ UpdateGroups();
+}
+
+void DlgEdForm::NbcMove( const Size& rSize )
+{
+ SdrUnoObj::NbcMove( rSize );
+
+ // set geometry properties of form
+ EndListening(false);
+ SetPropsFromRect();
+ StartListening();
+
+ // set geometry properties of all children
+ for (auto const& child : pChildren)
+ {
+ child->EndListening(false);
+ child->SetPropsFromRect();
+ child->StartListening();
+ }
+
+ // dialog model changed
+ GetDlgEditor().SetDialogModelChanged();
+}
+
+void DlgEdForm::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract)
+{
+ SdrUnoObj::NbcResize( rRef, xFract, yFract );
+
+ // set geometry properties of form
+ EndListening(false);
+ SetPropsFromRect();
+ StartListening();
+
+ // set geometry properties of all children
+ for (auto const& child : pChildren)
+ {
+ child->EndListening(false);
+ child->SetPropsFromRect();
+ child->StartListening();
+ }
+
+ // dialog model changed
+ GetDlgEditor().SetDialogModelChanged();
+}
+
+bool DlgEdForm::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
+{
+ bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
+
+ // stop listening
+ EndListening(false);
+
+ // set geometry properties
+ SetPropsFromRect();
+
+ // dialog model changed
+ GetDlgEditor().SetDialogModelChanged();
+
+ // start listening
+ StartListening();
+
+ return bResult;
+}
+
+awt::DeviceInfo DlgEdForm::getDeviceInfo() const
+{
+ awt::DeviceInfo aDeviceInfo;
+
+ DlgEditor& rEditor = GetDlgEditor();
+ vcl::Window& rWindow = rEditor.GetWindow();
+
+ // obtain an XControl
+ ::utl::SharedUNOComponent< awt::XControl > xDialogControl; // ensures auto-disposal, if needed
+ xDialogControl.reset( GetControl(), ::utl::SharedUNOComponent< awt::XControl >::NoTakeOwnership );
+ if ( !xDialogControl.is() )
+ {
+ // don't create a temporary control all the time, this method here is called
+ // way too often. Instead, use a cached DeviceInfo.
+ // #i74065#
+ if ( !!mpDeviceInfo )
+ return *mpDeviceInfo;
+
+ Reference< awt::XControlContainer > xEditorControlContainer( rEditor.GetWindowControlContainer() );
+ xDialogControl.reset(
+ GetTemporaryControlForWindow(rWindow, xEditorControlContainer),
+ utl::SharedUNOComponent< awt::XControl >::TakeOwnership
+ );
+ }
+
+ Reference< awt::XDevice > xDialogDevice;
+ if ( xDialogControl.is() )
+ xDialogDevice.set( xDialogControl->getPeer(), UNO_QUERY );
+ DBG_ASSERT( xDialogDevice.is(), "DlgEdForm::getDeviceInfo: no device!" );
+ if ( xDialogDevice.is() )
+ aDeviceInfo = xDialogDevice->getInfo();
+
+ mpDeviceInfo = aDeviceInfo;
+
+ return aDeviceInfo;
+}
+void DlgEdObj::MakeDataAware( const Reference< frame::XModel >& xModel )
+{
+ // Need to flesh this out, currently we will only support data-aware controls for calc
+ // and only handle a subset of functionality e.g. linked-cell and cell range data source. Of course later
+ // we need to disambiguate for writer ( and others ? ) and also support the generic form (db) bindings
+ // we need some more work in xmlscript to be able to handle that
+ Reference< lang::XMultiServiceFactory > xFac( xModel, UNO_QUERY );
+ Reference< form::binding::XBindableValue > xBindable( GetUnoControlModel(), UNO_QUERY );
+ Reference< form::binding::XListEntrySink > xListEntrySink( GetUnoControlModel(), UNO_QUERY );
+ if ( !xFac.is() )
+ return;
+
+ css::table::CellAddress aApiAddress;
+
+ //tdf#90361 CellValueBinding and CellRangeListSource are unusable
+ //without being initialized, so use createInstanceWithArguments with a
+ //dummy BoundCell instead of createInstance. This at least results in
+ //the dialog editor not falling.
+ css::beans::NamedValue aValue;
+ aValue.Name = "BoundCell";
+ aValue.Value <<= aApiAddress;
+
+ Sequence< Any > aArgs{ Any(aValue) };
+
+ if ( xBindable.is() )
+ {
+ Reference< form::binding::XValueBinding > xBinding( xFac->createInstanceWithArguments( "com.sun.star.table.CellValueBinding", aArgs ), UNO_QUERY );
+ xBindable->setValueBinding( xBinding );
+ }
+ if ( xListEntrySink.is() )
+ {
+ Reference< form::binding::XListEntrySource > xSource( xFac->createInstanceWithArguments( "com.sun.star.table.CellRangeListSource", aArgs ), UNO_QUERY );
+ xListEntrySink->setListEntrySource( xSource );
+ }
+}
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/dlged/dlgedpage.cxx b/basctl/source/dlged/dlgedpage.cxx
new file mode 100644
index 000000000..760f88527
--- /dev/null
+++ b/basctl/source/dlged/dlgedpage.cxx
@@ -0,0 +1,66 @@
+/* -*- 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 <dlgedpage.hxx>
+#include <dlged.hxx>
+#include <dlgedmod.hxx>
+#include <dlgedobj.hxx>
+
+namespace basctl
+{
+
+
+DlgEdPage::DlgEdPage(DlgEdModel& rModel, bool bMasterPage)
+: SdrPage(rModel, bMasterPage)
+ ,pDlgEdForm(nullptr)
+{
+}
+
+DlgEdPage::~DlgEdPage()
+{
+ // clear SdrObjects with broadcasting
+ ClearSdrObjList();
+}
+
+rtl::Reference<SdrPage> DlgEdPage::CloneSdrPage(SdrModel& rTargetModel) const
+{
+ DlgEdModel& rDlgEdModel(static_cast< DlgEdModel& >(rTargetModel));
+ rtl::Reference<DlgEdPage> pClonedDlgEdPage =
+ new DlgEdPage(
+ rDlgEdModel,
+ IsMasterPage());
+ pClonedDlgEdPage->SdrPage::lateInit(*this);
+ return pClonedDlgEdPage;
+}
+
+
+SdrObject* DlgEdPage::SetObjectOrdNum(size_t nOldObjNum, size_t nNewObjNum)
+{
+ SdrObject* pObj = SdrPage::SetObjectOrdNum( nOldObjNum, nNewObjNum );
+
+ DlgEdHint aHint( DlgEdHint::OBJORDERCHANGED );
+ if ( pDlgEdForm )
+ pDlgEdForm->GetDlgEditor().Broadcast( aHint );
+
+ return pObj;
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/dlged/dlgedview.cxx b/basctl/source/dlged/dlgedview.cxx
new file mode 100644
index 000000000..d6c67b7e9
--- /dev/null
+++ b/basctl/source/dlged/dlgedview.cxx
@@ -0,0 +1,184 @@
+/* -*- 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 <dlgedview.hxx>
+#include <dlged.hxx>
+#include <dlgedpage.hxx>
+
+#include <vcl/canvastools.hxx>
+#include <vcl/scrbar.hxx>
+
+#include <dlgedobj.hxx>
+
+namespace basctl
+{
+
+DlgEdView::DlgEdView(
+ SdrModel& rSdrModel,
+ OutputDevice& rOut,
+ DlgEditor& rEditor)
+: SdrView(rSdrModel, &rOut),
+ rDlgEditor(rEditor)
+{
+ SetBufferedOutputAllowed(true);
+ SetBufferedOverlayAllowed(true);
+}
+
+DlgEdView::~DlgEdView()
+{
+}
+
+void DlgEdView::MarkListHasChanged()
+{
+ SdrView::MarkListHasChanged();
+
+ DlgEdHint aHint( DlgEdHint::SELECTIONCHANGED );
+ rDlgEditor.Broadcast( aHint );
+ rDlgEditor.UpdatePropertyBrowserDelayed();
+}
+
+void DlgEdView::MakeVisible( const tools::Rectangle& rRect, vcl::Window& rWin )
+{
+ // visible area
+ MapMode aMap( rWin.GetMapMode() );
+ Point aOrg( aMap.GetOrigin() );
+ Size aVisSize( rWin.GetOutDev()->GetOutputSize() );
+ tools::Rectangle RectTmp( Point(-aOrg.X(),-aOrg.Y()), aVisSize );
+ tools::Rectangle aVisRect( RectTmp );
+
+ // check, if rectangle is inside visible area
+ if ( aVisRect.Contains( rRect ) )
+ return;
+
+ // calculate scroll distance; the rectangle must be inside the visible area
+ sal_Int32 nScrollX = 0, nScrollY = 0;
+
+ sal_Int32 nVisLeft = aVisRect.Left();
+ sal_Int32 nVisRight = aVisRect.Right();
+ sal_Int32 nVisTop = aVisRect.Top();
+ sal_Int32 nVisBottom = aVisRect.Bottom();
+
+ sal_Int32 nDeltaX = rDlgEditor.GetHScroll()->GetLineSize();
+ sal_Int32 nDeltaY = rDlgEditor.GetVScroll()->GetLineSize();
+
+ while ( rRect.Right() > nVisRight + nScrollX )
+ nScrollX += nDeltaX;
+
+ while ( rRect.Left() < nVisLeft + nScrollX )
+ nScrollX -= nDeltaX;
+
+ while ( rRect.Bottom() > nVisBottom + nScrollY )
+ nScrollY += nDeltaY;
+
+ while ( rRect.Top() < nVisTop + nScrollY )
+ nScrollY -= nDeltaY;
+
+ // don't scroll beyond the page size
+ Size aPageSize = rDlgEditor.GetPage().GetSize();
+ sal_Int32 nPageWidth = aPageSize.Width();
+ sal_Int32 nPageHeight = aPageSize.Height();
+
+ if ( nVisRight + nScrollX > nPageWidth )
+ nScrollX = nPageWidth - nVisRight;
+
+ if ( nVisLeft + nScrollX < 0 )
+ nScrollX = -nVisLeft;
+
+ if ( nVisBottom + nScrollY > nPageHeight )
+ nScrollY = nPageHeight - nVisBottom;
+
+ if ( nVisTop + nScrollY < 0 )
+ nScrollY = -nVisTop;
+
+ // scroll window
+ rWin.PaintImmediately();
+ rWin.Scroll( -nScrollX, -nScrollY );
+ aMap.SetOrigin( Point( aOrg.X() - nScrollX, aOrg.Y() - nScrollY ) );
+ rWin.SetMapMode( aMap );
+ rWin.Invalidate();
+
+ // update scroll bars
+ rDlgEditor.UpdateScrollBars();
+
+ DlgEdHint aHint( DlgEdHint::WINDOWSCROLLED );
+ rDlgEditor.Broadcast( aHint );
+}
+
+static SdrObject* impLocalHitCorrection(SdrObject* pRetval, const Point& rPnt, sal_uInt16 nTol)
+{
+ DlgEdObj* pDlgEdObj = dynamic_cast< DlgEdObj* >(pRetval);
+
+ if(pDlgEdObj)
+ {
+ bool bExcludeInner(false);
+
+ if(dynamic_cast< DlgEdForm* >(pRetval) != nullptr)
+ {
+ // from DlgEdForm::CheckHit; exclude inner for DlgEdForm
+ bExcludeInner = true;
+ }
+ else if(pDlgEdObj->supportsService("com.sun.star.awt.UnoControlGroupBoxModel"))
+ {
+ // from DlgEdObj::CheckHit; exclude inner for group shapes
+ bExcludeInner = true;
+ }
+
+ if(bExcludeInner)
+ {
+ // use direct model data; it's a DlgEdObj, so GetLastBoundRect()
+ // will access aOutRect directly
+ const tools::Rectangle aOuterRectangle(pDlgEdObj->GetLastBoundRect());
+
+ if(!aOuterRectangle.IsEmpty())
+ {
+ basegfx::B2DRange aOuterRange = vcl::unotools::b2DRectangleFromRectangle(aOuterRectangle);
+
+ if(nTol)
+ {
+ aOuterRange.grow(-1.0 * nTol);
+ }
+
+ if(aOuterRange.isInside(basegfx::B2DPoint(rPnt.X(), rPnt.Y())))
+ {
+ pRetval = nullptr;
+ }
+ }
+ }
+ }
+
+ return pRetval;
+}
+
+SdrObject* DlgEdView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, SdrSearchOptions nOptions, const SdrLayerIDSet* pMVisLay) const
+{
+ // call parent
+ SdrObject* pRetval = SdrView::CheckSingleSdrObjectHit(rPnt, nTol, pObj, pPV, nOptions, pMVisLay);
+
+ if(pRetval)
+ {
+ // check hit object locally
+ pRetval = impLocalHitCorrection(pRetval, rPnt, nTol);
+ }
+
+ return pRetval;
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/dlged/managelang.cxx b/basctl/source/dlged/managelang.cxx
new file mode 100644
index 000000000..69f366ed6
--- /dev/null
+++ b/basctl/source/dlged/managelang.cxx
@@ -0,0 +1,318 @@
+/* -*- 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 <basidesh.hxx>
+#include <basobj.hxx>
+#include <iderdll.hxx>
+#include <iderid.hxx>
+#include <localizationmgr.hxx>
+#include <managelang.hxx>
+
+#include <strings.hrc>
+
+#include <comphelper/sequence.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svtools/langtab.hxx>
+#include <svx/langbox.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/settings.hxx>
+#include <tools/debug.hxx>
+
+namespace basctl
+{
+
+using namespace ::com::sun::star::i18n;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::resource;
+using namespace ::com::sun::star::uno;
+
+bool localesAreEqual( const Locale& rLocaleLeft, const Locale& rLocaleRight )
+{
+ bool bRet = ( rLocaleLeft.Language == rLocaleRight.Language &&
+ rLocaleLeft.Country == rLocaleRight.Country &&
+ rLocaleLeft.Variant == rLocaleRight.Variant );
+ return bRet;
+}
+
+ManageLanguageDialog::ManageLanguageDialog(weld::Window* pParent, std::shared_ptr<LocalizationMgr> xLMgr)
+ : GenericDialogController(pParent, "modules/BasicIDE/ui/managelanguages.ui", "ManageLanguagesDialog")
+ , m_xLocalizationMgr(std::move(xLMgr))
+ , m_sDefLangStr(IDEResId(RID_STR_DEF_LANG))
+ , m_sCreateLangStr(IDEResId(RID_STR_CREATE_LANG))
+ , m_xLanguageLB(m_xBuilder->weld_tree_view("treeview"))
+ , m_xAddPB(m_xBuilder->weld_button("add"))
+ , m_xDeletePB(m_xBuilder->weld_button("delete"))
+ , m_xMakeDefPB(m_xBuilder->weld_button("default"))
+{
+ m_xLanguageLB->set_size_request(m_xLanguageLB->get_approximate_digit_width() * 42,
+ m_xLanguageLB->get_height_rows(10));
+
+ Init();
+ FillLanguageBox();
+ SelectHdl( *m_xLanguageLB );
+}
+
+ManageLanguageDialog::~ManageLanguageDialog()
+{
+ ClearLanguageBox();
+}
+
+void ManageLanguageDialog::Init()
+{
+ // get current IDE
+ Shell* pShell = GetShell();
+ const OUString& sLibName = pShell->GetCurLibName();
+ // set dialog title with library name
+ OUString sText = m_xDialog->get_title();
+ sText = sText.replaceAll("$1", sLibName);
+ m_xDialog->set_title(sText);
+ // set handler
+ m_xAddPB->connect_clicked( LINK( this, ManageLanguageDialog, AddHdl ) );
+ m_xDeletePB->connect_clicked( LINK( this, ManageLanguageDialog, DeleteHdl ) );
+ m_xMakeDefPB->connect_clicked( LINK( this, ManageLanguageDialog, MakeDefHdl ) );
+ m_xLanguageLB->connect_changed( LINK( this, ManageLanguageDialog, SelectHdl ) );
+
+ m_xLanguageLB->set_selection_mode(SelectionMode::Multiple);
+}
+
+void ManageLanguageDialog::FillLanguageBox()
+{
+ DBG_ASSERT( m_xLocalizationMgr, "ManageLanguageDialog::FillLanguageBox(): no localization manager" );
+
+ if ( m_xLocalizationMgr->isLibraryLocalized() )
+ {
+ Locale aDefaultLocale = m_xLocalizationMgr->getStringResourceManager()->getDefaultLocale();
+ Sequence< Locale > aLocaleSeq = m_xLocalizationMgr->getStringResourceManager()->getLocales();
+ const Locale* pLocale = aLocaleSeq.getConstArray();
+ sal_Int32 i, nCount = aLocaleSeq.getLength();
+ for ( i = 0; i < nCount; ++i )
+ {
+ bool bIsDefault = localesAreEqual( aDefaultLocale, pLocale[i] );
+ LanguageType eLangType = LanguageTag::convertToLanguageType( pLocale[i] );
+ OUString sLanguage = SvtLanguageTable::GetLanguageString( eLangType );
+ if ( bIsDefault )
+ {
+ sLanguage += " " + m_sDefLangStr;
+ }
+ LanguageEntry* pEntry = new LanguageEntry(pLocale[i], bIsDefault);
+ m_xLanguageLB->append(weld::toId(pEntry), sLanguage);
+ }
+ }
+ else
+ m_xLanguageLB->append_text(m_sCreateLangStr);
+}
+
+void ManageLanguageDialog::ClearLanguageBox()
+{
+ const sal_Int32 nCount = m_xLanguageLB->n_children();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ LanguageEntry* pEntry = weld::fromId<LanguageEntry*>(m_xLanguageLB->get_id(i));
+ delete pEntry;
+ }
+ m_xLanguageLB->clear();
+}
+
+IMPL_LINK_NOARG(ManageLanguageDialog, AddHdl, weld::Button&, void)
+{
+ auto xDlg = std::make_shared<SetDefaultLanguageDialog>(m_xDialog.get(), m_xLocalizationMgr);
+ weld::DialogController::runAsync(xDlg, [xDlg,this](sal_Int32 nResult)
+ {
+ if (!nResult )
+ return;
+ // add new locales
+ Sequence< Locale > aLocaleSeq = xDlg->GetLocales();
+ m_xLocalizationMgr->handleAddLocales( aLocaleSeq );
+ // update listbox
+ ClearLanguageBox();
+ FillLanguageBox();
+
+ if (SfxBindings* pBindings = GetBindingsPtr())
+ pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );
+ });
+}
+
+IMPL_LINK_NOARG(ManageLanguageDialog, DeleteHdl, weld::Button&, void)
+{
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), "modules/BasicIDE/ui/deletelangdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQBox(xBuilder->weld_message_dialog("DeleteLangDialog"));
+ if (xQBox->run() != RET_OK)
+ return;
+
+ std::vector<int> aSelection = m_xLanguageLB->get_selected_rows();
+ int nCount = aSelection.size();
+ int nPos = m_xLanguageLB->get_selected_index();
+ // remove locales
+ Sequence< Locale > aLocaleSeq( nCount );
+ auto aLocaleSeqRange = asNonConstRange(aLocaleSeq);
+ for (int i = 0; i < nCount; ++i)
+ {
+ const sal_Int32 nSelPos = aSelection[i];
+ LanguageEntry* pEntry = weld::fromId<LanguageEntry*>(m_xLanguageLB->get_id(nSelPos));
+ if ( pEntry )
+ aLocaleSeqRange[i] = pEntry->m_aLocale;
+ }
+ m_xLocalizationMgr->handleRemoveLocales( aLocaleSeq );
+ // update listbox
+ ClearLanguageBox();
+ FillLanguageBox();
+ // reset selection
+ nCount = m_xLanguageLB->n_children();
+ if (nCount <= nPos)
+ nPos = nCount - 1;
+ m_xLanguageLB->select(nPos);
+ SelectHdl( *m_xLanguageLB );
+}
+
+IMPL_LINK_NOARG(ManageLanguageDialog, MakeDefHdl, weld::Button&, void)
+{
+ const sal_Int32 nPos = m_xLanguageLB->get_selected_index();
+ LanguageEntry* pSelectEntry = weld::fromId<LanguageEntry*>(m_xLanguageLB->get_id(nPos));
+ if (pSelectEntry && !pSelectEntry->m_bIsDefault)
+ {
+ // set new default entry
+ m_xLocalizationMgr->handleSetDefaultLocale( pSelectEntry->m_aLocale );
+ // update Listbox
+ ClearLanguageBox();
+ FillLanguageBox();
+ // reset selection
+ m_xLanguageLB->select(nPos);
+ SelectHdl( *m_xLanguageLB );
+ }
+}
+
+IMPL_LINK_NOARG(ManageLanguageDialog, SelectHdl, weld::TreeView&, void)
+{
+ const sal_Int32 nCount = m_xLanguageLB->n_children();
+ bool bEmpty = ( !nCount ||
+ m_xLanguageLB->find_text(m_sCreateLangStr) != -1 );
+ bool bSelect = ( m_xLanguageLB->get_selected_index() != -1 );
+ bool bEnable = !bEmpty && bSelect;
+
+ m_xDeletePB->set_sensitive(bEnable);
+ m_xMakeDefPB->set_sensitive(bEnable && nCount > 1 && m_xLanguageLB->count_selected_rows() == 1);
+}
+
+// class SetDefaultLanguageDialog -----------------------------------------------
+
+SetDefaultLanguageDialog::SetDefaultLanguageDialog(weld::Window* pParent, std::shared_ptr<LocalizationMgr> xLMgr)
+ : GenericDialogController(pParent, "modules/BasicIDE/ui/defaultlanguage.ui", "DefaultLanguageDialog")
+ , m_xLocalizationMgr(std::move(xLMgr))
+ , m_xLanguageFT(m_xBuilder->weld_label("defaultlabel"))
+ , m_xLanguageLB(m_xBuilder->weld_tree_view("entries"))
+ , m_xCheckLangFT(m_xBuilder->weld_label("checkedlabel"))
+ , m_xCheckLangLB(m_xBuilder->weld_tree_view("checkedentries"))
+ , m_xDefinedFT(m_xBuilder->weld_label("defined"))
+ , m_xAddedFT(m_xBuilder->weld_label("added"))
+ , m_xAltTitle(m_xBuilder->weld_label("alttitle"))
+ , m_xLanguageCB(new SvxLanguageBox(m_xBuilder->weld_combo_box("hidden")))
+{
+ m_xLanguageLB->set_size_request(-1, m_xLanguageLB->get_height_rows(10));
+ m_xCheckLangLB->set_size_request(-1, m_xCheckLangLB->get_height_rows(10));
+ m_xCheckLangLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ if (m_xLocalizationMgr->isLibraryLocalized())
+ {
+ // change to "Add Interface Language" mode
+ m_xLanguageLB->hide();
+ m_xCheckLangLB->show();
+ m_xDialog->set_title(m_xAltTitle->get_label());
+ m_xLanguageFT->hide();
+ m_xCheckLangFT->show();
+ m_xDefinedFT->hide();
+ m_xAddedFT->show();
+ }
+
+ FillLanguageBox();
+}
+
+SetDefaultLanguageDialog::~SetDefaultLanguageDialog()
+{
+}
+
+void SetDefaultLanguageDialog::FillLanguageBox()
+{
+ // fill list with all languages
+ m_xLanguageCB->SetLanguageList(SvxLanguageListFlags::ALL, false);
+
+ if (m_xLocalizationMgr->isLibraryLocalized())
+ {
+ // remove the already localized languages
+ Sequence< Locale > aLocaleSeq = m_xLocalizationMgr->getStringResourceManager()->getLocales();
+ const Locale* pLocale = aLocaleSeq.getConstArray();
+ const sal_Int32 nCountLoc = aLocaleSeq.getLength();
+ for ( sal_Int32 i = 0; i < nCountLoc; ++i )
+ m_xLanguageCB->remove_id(LanguageTag::convertToLanguageType(pLocale[i]));
+
+ // fill checklistbox if not in default mode
+ const sal_Int32 nCountLang = m_xLanguageCB->get_count();
+ for (sal_Int32 j = 0; j < nCountLang; ++j)
+ {
+ LanguageType eLang = m_xLanguageCB->get_id(j);
+ m_xCheckLangLB->append();
+ const int nRow = m_xCheckLangLB->n_children() - 1;
+ m_xCheckLangLB->set_toggle(nRow, TRISTATE_FALSE);
+ m_xCheckLangLB->set_text(nRow, m_xLanguageCB->get_text(j), 0);
+ m_xCheckLangLB->set_id(nRow, OUString::number(eLang.get()));
+ }
+ m_xLanguageCB.reset();
+ m_xLanguageLB.reset();
+ }
+ else
+ {
+ const sal_Int32 nCountLang = m_xLanguageCB->get_count();
+ for (sal_Int32 j = 0; j < nCountLang; ++j)
+ {
+ LanguageType eLang = m_xLanguageCB->get_id(j);
+ m_xLanguageLB->append(OUString::number(eLang.get()), m_xLanguageCB->get_text(j));
+ }
+ m_xLanguageCB.reset();
+
+ // preselect current UI language
+ m_xLanguageLB->select_id(OUString::number(Application::GetSettings().GetUILanguageTag().getLanguageType().get()));
+ }
+}
+
+Sequence< Locale > SetDefaultLanguageDialog::GetLocales() const
+{
+ bool bNotLocalized = !m_xLocalizationMgr->isLibraryLocalized();
+ if (bNotLocalized)
+ {
+ LanguageType eType(m_xLanguageLB->get_selected_id().toUInt32());
+ return {LanguageTag(eType).getLocale()};
+ }
+ std::vector<Locale> aLocaleSeq;
+ const sal_Int32 nCount = m_xCheckLangLB->n_children();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ if (m_xCheckLangLB->get_toggle(i) == TRISTATE_TRUE)
+ {
+ LanguageType eType(m_xCheckLangLB->get_id(i).toUInt32());
+ aLocaleSeq.push_back(LanguageTag::convertToLocale(eType));
+ }
+ }
+ return comphelper::containerToSequence(aLocaleSeq);
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/dlged/propbrw.cxx b/basctl/source/dlged/propbrw.cxx
new file mode 100644
index 000000000..d7ab2ee63
--- /dev/null
+++ b/basctl/source/dlged/propbrw.cxx
@@ -0,0 +1,506 @@
+/* -*- 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 <propbrw.hxx>
+#include <basidesh.hxx>
+#include <dlgedobj.hxx>
+#include <iderid.hxx>
+#include <baside3.hxx>
+#include <strings.hrc>
+
+#include <strings.hxx>
+
+#include <com/sun/star/frame/Frame.hpp>
+#include <com/sun/star/inspection/XObjectInspector.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <comphelper/types.hxx>
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/component_context.hxx>
+#include <tools/debug.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdview.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/layout.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/weld.hxx>
+
+#include <memory>
+
+namespace basctl
+{
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::comphelper;
+
+
+void PropBrw::Update( const SfxViewShell* pShell )
+{
+ Shell const* pIdeShell = dynamic_cast<Shell const*>(pShell);
+ OSL_ENSURE( pIdeShell || !pShell, "PropBrw::Update: invalid shell!" );
+ if (pIdeShell)
+ ImplUpdate(pIdeShell->GetCurrentDocument(), pIdeShell->GetCurDlgView());
+ else if (pShell)
+ ImplUpdate(nullptr, pShell->GetDrawView());
+ else
+ ImplUpdate(nullptr, nullptr);
+}
+
+
+namespace
+{
+
+const tools::Long STD_WIN_SIZE_X = 300;
+const tools::Long STD_WIN_SIZE_Y = 350;
+
+const tools::Long STD_MIN_SIZE_X = 250;
+const tools::Long STD_MIN_SIZE_Y = 250;
+
+const tools::Long WIN_BORDER = 2;
+
+} // namespace
+
+PropBrw::PropBrw (DialogWindowLayout& rLayout_):
+ DockingWindow(&rLayout_),
+ m_xContentArea(VclPtr<VclVBox>::Create(this)),
+ m_bInitialStateChange(true),
+ m_xContextDocument(SfxViewShell::Current() ? SfxViewShell::Current()->GetCurrentDocument() : Reference<XModel>()),
+ pView(nullptr)
+{
+ Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y);
+ SetMinOutputSizePixel(Size(STD_MIN_SIZE_X,STD_MIN_SIZE_Y));
+ SetOutputSizePixel(aPropWinSize);
+
+ // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
+ // transparent children of the widget
+ m_xContentArea->SetControlBackground(m_xContentArea->GetSettings().GetStyleSettings().GetWindowColor());
+ m_xContentArea->SetBackground(m_xContentArea->GetControlBackground());
+ m_xContentArea->SetStyle(m_xContentArea->GetStyle() & ~WB_CLIPCHILDREN);
+ m_xContentArea->Show();
+
+ try
+ {
+ // create a frame wrapper for myself
+ m_xMeAsFrame = frame::Frame::create( comphelper::getProcessComponentContext() );
+ m_xMeAsFrame->initialize(VCLUnoHelper::GetInterface(m_xContentArea));
+ m_xMeAsFrame->setName( "form property browser" ); // change name!
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("PropBrw::PropBrw: could not create/initialize my frame!");
+ m_xMeAsFrame.clear();
+ }
+
+ ImplReCreateController();
+}
+
+
+void PropBrw::ImplReCreateController()
+{
+ OSL_PRECOND( m_xMeAsFrame.is(), "PropBrw::ImplCreateController: no frame for myself!" );
+ if ( !m_xMeAsFrame.is() )
+ return;
+
+ if ( m_xBrowserController.is() )
+ ImplDestroyController();
+
+ try
+ {
+ Reference< XComponentContext > xOwnContext = comphelper::getProcessComponentContext();
+
+ // a ComponentContext for the
+ ::cppu::ContextEntry_Init aHandlerContextInfo[] =
+ {
+ ::cppu::ContextEntry_Init( "DialogParentWindow", Any(VCLUnoHelper::GetInterface(this))),
+ ::cppu::ContextEntry_Init( "ContextDocument", Any( m_xContextDocument ) )
+ };
+ Reference< XComponentContext > xInspectorContext(
+ ::cppu::createComponentContext( aHandlerContextInfo, std::size( aHandlerContextInfo ), xOwnContext ) );
+
+ // create a property browser controller
+ Reference< XMultiComponentFactory > xFactory( xInspectorContext->getServiceManager(), UNO_SET_THROW );
+ static constexpr OUStringLiteral s_sControllerServiceName = u"com.sun.star.awt.PropertyBrowserController";
+ m_xBrowserController.set( xFactory->createInstanceWithContext( s_sControllerServiceName, xInspectorContext ), UNO_QUERY );
+ if ( !m_xBrowserController.is() )
+ {
+ vcl::Window* pWin = GetParent();
+ ShowServiceNotAvailableError(pWin ? pWin->GetFrameWeld() : nullptr, s_sControllerServiceName, true);
+ }
+ else
+ {
+ Reference< XController > xAsXController( m_xBrowserController, UNO_QUERY );
+ DBG_ASSERT(xAsXController.is(), "PropBrw::PropBrw: invalid controller object!");
+ if (!xAsXController.is())
+ {
+ ::comphelper::disposeComponent(m_xBrowserController);
+ m_xBrowserController.clear();
+ }
+ else
+ {
+ xAsXController->attachFrame( Reference<XFrame>(m_xMeAsFrame,UNO_QUERY_THROW) );
+ }
+ }
+
+ Point aPropWinPos( WIN_BORDER, WIN_BORDER );
+ Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y);
+ aPropWinSize.AdjustWidth( -(2*WIN_BORDER) );
+ aPropWinSize.AdjustHeight( -(2*WIN_BORDER) );
+
+ VclContainer::setLayoutAllocation(*m_xContentArea, aPropWinPos, aPropWinSize);
+ m_xContentArea->Show();
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("PropBrw::PropBrw: could not create/initialize the browser controller!");
+ try
+ {
+ ::comphelper::disposeComponent(m_xBrowserController);
+ }
+ catch(const Exception&)
+ {
+ }
+
+ m_xBrowserController.clear();
+ }
+ Resize();
+}
+
+PropBrw::~PropBrw()
+{
+ disposeOnce();
+}
+
+void PropBrw::dispose()
+{
+ if ( m_xBrowserController.is() )
+ ImplDestroyController();
+ m_xContentArea.disposeAndClear();
+ DockingWindow::dispose();
+}
+
+
+void PropBrw::ImplDestroyController()
+{
+ implSetNewObject( Reference< XPropertySet >() );
+
+ if ( m_xMeAsFrame.is() )
+ m_xMeAsFrame->setComponent( nullptr, nullptr );
+
+ Reference< XController > xAsXController( m_xBrowserController, UNO_QUERY );
+ if ( xAsXController.is() )
+ xAsXController->attachFrame( nullptr );
+
+ try
+ {
+ ::comphelper::disposeComponent( m_xBrowserController );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("basctl");
+ }
+
+ m_xBrowserController.clear();
+}
+
+bool PropBrw::Close()
+{
+ ImplDestroyController();
+
+ return DockingWindow::Close();
+}
+
+Sequence< Reference< XInterface > >
+ PropBrw::CreateMultiSelectionSequence( const SdrMarkList& _rMarkList )
+{
+ Sequence< Reference< XInterface > > aSeq;
+ InterfaceArray aInterfaces;
+
+ const size_t nMarkCount = _rMarkList.GetMarkCount();
+ for( size_t i = 0 ; i < nMarkCount ; ++i )
+ {
+ SdrObject* pCurrent = _rMarkList.GetMark(i)->GetMarkedSdrObj();
+
+ std::unique_ptr<SdrObjListIter> pGroupIterator;
+ if (pCurrent->IsGroupObject())
+ {
+ pGroupIterator.reset(new SdrObjListIter(pCurrent->GetSubList()));
+ pCurrent = pGroupIterator->IsMore() ? pGroupIterator->Next() : nullptr;
+ }
+
+ while (pCurrent)
+ {
+ if (DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pCurrent))
+ {
+ Reference< XInterface > xControlInterface(pDlgEdObj->GetUnoControlModel(), UNO_QUERY);
+ if (xControlInterface.is())
+ aInterfaces.push_back(xControlInterface);
+ }
+
+ // next element
+ pCurrent = pGroupIterator && pGroupIterator->IsMore() ? pGroupIterator->Next() : nullptr;
+ }
+ }
+
+ sal_Int32 nCount = aInterfaces.size();
+ aSeq.realloc( nCount );
+ Reference< XInterface >* pInterfaces = aSeq.getArray();
+ for( sal_Int32 i = 0 ; i < nCount ; i++ )
+ pInterfaces[i] = aInterfaces[i];
+
+ return aSeq;
+}
+
+
+void PropBrw::implSetNewObjectSequence
+ ( const Sequence< Reference< XInterface > >& _rObjectSeq )
+{
+ Reference< inspection::XObjectInspector > xObjectInspector(m_xBrowserController, UNO_QUERY);
+ if ( xObjectInspector.is() )
+ {
+ xObjectInspector->inspect( _rObjectSeq );
+
+ OUString aText = IDEResId(RID_STR_BRWTITLE_PROPERTIES)
+ + IDEResId(RID_STR_BRWTITLE_MULTISELECT);
+ SetText( aText );
+ }
+}
+
+
+void PropBrw::implSetNewObject( const Reference< XPropertySet >& _rxObject )
+{
+ if ( m_xBrowserController.is() )
+ {
+ m_xBrowserController->setPropertyValue( "IntrospectedObject",
+ Any( _rxObject )
+ );
+
+ // set the new title according to the selected object
+ SetText( GetHeadlineName( _rxObject ) );
+ }
+}
+
+
+OUString PropBrw::GetHeadlineName( const Reference< XPropertySet >& _rxObject )
+{
+ OUString aName;
+ Reference< lang::XServiceInfo > xServiceInfo( _rxObject, UNO_QUERY );
+
+ if (xServiceInfo.is()) // single selection
+ {
+ OUString sResId;
+ aName = IDEResId(RID_STR_BRWTITLE_PROPERTIES);
+
+ if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlDialogModel" ) )
+ {
+ sResId = RID_STR_CLASS_DIALOG;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlButtonModel" ) )
+ {
+ sResId = RID_STR_CLASS_BUTTON;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) )
+ {
+ sResId = RID_STR_CLASS_RADIOBUTTON;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) )
+ {
+ sResId = RID_STR_CLASS_CHECKBOX;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlListBoxModel" ) )
+ {
+ sResId = RID_STR_CLASS_LISTBOX;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ) )
+ {
+ sResId = RID_STR_CLASS_COMBOBOX;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) )
+ {
+ sResId = RID_STR_CLASS_GROUPBOX;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlEditModel" ) )
+ {
+ sResId = RID_STR_CLASS_EDIT;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
+ {
+ sResId = RID_STR_CLASS_FIXEDTEXT;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlImageControlModel" ) )
+ {
+ sResId = RID_STR_CLASS_IMAGECONTROL;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ) )
+ {
+ sResId = RID_STR_CLASS_PROGRESSBAR;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ) )
+ {
+ sResId = RID_STR_CLASS_SCROLLBAR;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ) )
+ {
+ sResId = RID_STR_CLASS_FIXEDLINE;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_DATEFIELD;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_TIMEFIELD;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_NUMERICFIELD;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_CURRENCYFIELD;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_FORMATTEDFIELD;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ) )
+ {
+ sResId = RID_STR_CLASS_PATTERNFIELD;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFileControlModel" ) )
+ {
+ sResId = RID_STR_CLASS_FILECONTROL;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.tree.TreeControlModel" ) )
+ {
+ sResId = RID_STR_CLASS_TREECONTROL;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.grid.UnoControlGridModel" ) )
+ {
+ sResId = RID_STR_CLASS_GRIDCONTROL;
+ }
+ else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFixedHyperlinkModel" ) )
+ {
+ sResId = RID_STR_CLASS_HYPERLINKCONTROL;
+ }
+ else
+ {
+ sResId = RID_STR_CLASS_CONTROL;
+ }
+
+ if (!sResId.isEmpty())
+ {
+ aName += sResId;
+ }
+ }
+ else if (!_rxObject.is()) // no properties
+ {
+ aName = IDEResId(RID_STR_BRWTITLE_NO_PROPERTIES);
+ }
+
+ return aName;
+}
+
+void PropBrw::ImplUpdate( const Reference< XModel >& _rxContextDocument, SdrView* pNewView )
+{
+ Reference< XModel > xContextDocument( _rxContextDocument );
+
+ // if we should simply "empty" ourself, assume the context document didn't change
+ if ( !pNewView )
+ {
+ OSL_ENSURE( !_rxContextDocument.is(), "PropBrw::ImplUpdate: no view, but a document?!" );
+ xContextDocument = m_xContextDocument;
+ }
+
+ if ( xContextDocument != m_xContextDocument )
+ {
+ m_xContextDocument = xContextDocument;
+ ImplReCreateController();
+ }
+
+ try
+ {
+ if ( pView )
+ {
+ EndListening( *(pView->GetModel()) );
+ pView = nullptr;
+ }
+
+ if ( !pNewView )
+ return;
+
+ pView = pNewView;
+
+ // set focus on initialization
+ if ( m_bInitialStateChange )
+ {
+ m_xContentArea->GrabFocus();
+ m_bInitialStateChange = false;
+ }
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ const size_t nMarkCount = rMarkList.GetMarkCount();
+
+ if ( nMarkCount == 0 )
+ {
+ EndListening( *(pView->GetModel()) );
+ pView = nullptr;
+ implSetNewObject( nullptr );
+ return;
+ }
+
+ Reference< XPropertySet > xNewObject;
+ Sequence< Reference< XInterface > > aNewObjects;
+ if ( nMarkCount == 1 )
+ {
+ if (DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(rMarkList.GetMark(0)->GetMarkedSdrObj()))
+ {
+ if ( pDlgEdObj->IsGroupObject() ) // group object
+ aNewObjects = CreateMultiSelectionSequence( rMarkList );
+ else // single selection
+ xNewObject.set(pDlgEdObj->GetUnoControlModel(), css::uno::UNO_QUERY);
+ }
+ }
+ else if ( nMarkCount > 1 ) // multiple selection
+ {
+ aNewObjects = CreateMultiSelectionSequence( rMarkList );
+ }
+
+ if ( aNewObjects.hasElements() )
+ implSetNewObjectSequence( aNewObjects );
+ else
+ implSetNewObject( xNewObject );
+
+ StartListening( *(pView->GetModel()) );
+ }
+ catch ( const PropertyVetoException& ) { /* silence */ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("basctl");
+ }
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */