1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/form/FormComponentType.hpp>
21 #include <com/sun/star/awt/XControlModel.hpp>
22 #include <com/sun/star/awt/XControl.hpp>
23 #include <com/sun/star/awt/XActionListener.hpp>
24 #include <com/sun/star/lang/XEventListener.hpp>
25 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
26 #include <com/sun/star/lang/XServiceInfo.hpp>
27 #include <com/sun/star/drawing/XShape.hpp>
28 #include <com/sun/star/drawing/XControlShape.hpp>
29 #include <com/sun/star/frame/XModel.hpp>
30 #include <com/sun/star/view/XControlAccess.hpp>
31 #include <com/sun/star/form/binding/XBindableValue.hpp>
32 #include <com/sun/star/form/binding/XListEntrySink.hpp>
33 #include <com/sun/star/table/CellAddress.hpp>
34 #include <com/sun/star/table/CellRangeAddress.hpp>
35 #include <com/sun/star/script/XScriptListener.hpp>
36 #include <com/sun/star/document/XCodeNameQuery.hpp>
37 #include <com/sun/star/form/XChangeListener.hpp>
38 #include <ooo/vba/XControlProvider.hpp>
39 #include <ooo/vba/msforms/fmMousePointer.hpp>
40 #include <svtools/bindablecontrolhelper.hxx>
41 #include "vbacontrol.hxx"
42 #include "vbacombobox.hxx"
43 #include "vbabutton.hxx"
44 #include "vbalabel.hxx"
45 #include "vbatextbox.hxx"
46 #include "vbaradiobutton.hxx"
47 #include "vbalistbox.hxx"
48 #include "vbatogglebutton.hxx"
49 #include "vbacheckbox.hxx"
50 #include "vbaframe.hxx"
51 #include "vbascrollbar.hxx"
52 #include "vbaprogressbar.hxx"
53 #include "vbamultipage.hxx"
54 #include "vbaspinbutton.hxx"
55 #include "vbasystemaxcontrol.hxx"
56 #include "vbaimage.hxx"
57 #include <toolkit/helper/vclunohelper.hxx>
58 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
59 #include <com/sun/star/form/XFormsSupplier.hpp>
60 #include <svx/svdobj.hxx>
61 #include <cppuhelper/implbase.hxx>
62 #include <cppuhelper/supportsservice.hxx>
65 using namespace com::sun::star
;
66 using namespace ooo::vba
;
68 uno::Reference
< css::awt::XVclWindowPeer
>
69 ScVbaControl::getWindowPeer()
71 uno::Reference
< drawing::XControlShape
> xControlShape( m_xControl
, uno::UNO_QUERY
);
73 uno::Reference
< awt::XControlModel
> xControlModel
;
74 uno::Reference
< css::awt::XWindowPeer
> xWinPeer
;
75 if ( !xControlShape
.is() )
77 // would seem to be a Userform control
78 uno::Reference
< awt::XControl
> xControl( m_xControl
, uno::UNO_QUERY_THROW
);
79 xWinPeer
= xControl
->getPeer();
84 xControlModel
.set( xControlShape
->getControl(), uno::UNO_SET_THROW
);
86 uno::Reference
< view::XControlAccess
> xControlAccess( m_xModel
->getCurrentController(), uno::UNO_QUERY_THROW
);
89 uno::Reference
< awt::XControl
> xControl
= xControlAccess
->getControl( xControlModel
);
90 xWinPeer
= xControl
->getPeer();
92 catch(const uno::Exception
&)
94 throw uno::RuntimeException( "The Control does not exist" );
97 uno::Reference
< css::awt::XVclWindowPeer
> xVclWinPeer(xWinPeer
, uno::UNO_QUERY
);
98 assert(xVclWinPeer
|| !xWinPeer
);
104 //ScVbaControlListener
105 class ScVbaControlListener
: public cppu::WeakImplHelper
< lang::XEventListener
>
108 ScVbaControl
*pControl
;
110 explicit ScVbaControlListener( ScVbaControl
*pTmpControl
);
112 virtual void SAL_CALL
disposing( const lang::EventObject
& rEventObject
) override
;
117 ScVbaControlListener::ScVbaControlListener( ScVbaControl
*pTmpControl
): pControl( pTmpControl
)
122 ScVbaControlListener::disposing( const lang::EventObject
& )
126 pControl
->removeResource();
133 ScVbaControl::ScVbaControl( const uno::Reference
< XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
>& xContext
, uno::Reference
< ::uno::XInterface
> xControl
, css::uno::Reference
< css::frame::XModel
> xModel
, std::unique_ptr
<ov::AbstractGeometryAttributes
> pGeomHelper
)
134 : ControlImpl_BASE( xParent
, xContext
), m_xControl(std::move( xControl
)), m_xModel(std::move( xModel
))
137 m_xEventListener
.set( new ScVbaControlListener( this ) );
138 setGeometryHelper( std::move(pGeomHelper
) );
139 uno::Reference
< lang::XComponent
> xComponent( m_xControl
, uno::UNO_QUERY_THROW
);
140 xComponent
->addEventListener( m_xEventListener
);
143 uno::Reference
< drawing::XControlShape
> xControlShape( m_xControl
, uno::UNO_QUERY
) ;
144 uno::Reference
< awt::XControl
> xUserFormControl( m_xControl
, uno::UNO_QUERY
) ;
145 if ( xControlShape
.is() ) // form control
147 m_xProps
.set( xControlShape
->getControl(), uno::UNO_QUERY_THROW
);
148 OUString sDefaultControl
;
149 m_xProps
->getPropertyValue( "DefaultControl" ) >>= sDefaultControl
;
150 uno::Reference
< lang::XMultiComponentFactory
> xMFac( mxContext
->getServiceManager(), uno::UNO_SET_THROW
);
151 m_xEmptyFormControl
.set( xMFac
->createInstanceWithContext( sDefaultControl
, mxContext
), uno::UNO_QUERY_THROW
);
153 else if ( xUserFormControl
.is() ) // userform control
155 m_xProps
.set( xUserFormControl
->getModel(), uno::UNO_QUERY_THROW
);
159 ScVbaControl::~ScVbaControl()
161 if( m_xControl
.is() )
163 uno::Reference
< lang::XComponent
> xComponent( m_xControl
, uno::UNO_QUERY_THROW
);
164 xComponent
->removeEventListener( m_xEventListener
);
169 ScVbaControl::setGeometryHelper( std::unique_ptr
<AbstractGeometryAttributes
> pHelper
)
171 mpGeometryHelper
= std::move( pHelper
);
174 void ScVbaControl::removeResource()
176 uno::Reference
< lang::XComponent
> xComponent( m_xControl
, uno::UNO_QUERY_THROW
);
177 xComponent
->removeEventListener( m_xEventListener
);
182 //In design model has different behavior
183 sal_Bool SAL_CALL
ScVbaControl::getEnabled()
185 uno::Any aValue
= m_xProps
->getPropertyValue ( "Enabled" );
191 void SAL_CALL
ScVbaControl::setEnabled( sal_Bool bVisible
)
193 uno::Any
aValue( bVisible
);
194 m_xProps
->setPropertyValue( "Enabled" , aValue
);
198 sal_Bool SAL_CALL
ScVbaControl::getVisible()
200 bool bVisible( true );
201 m_xProps
->getPropertyValue ( "EnableVisible" ) >>= bVisible
;
202 uno::Reference
< drawing::XControlShape
> xControlShape( m_xControl
, uno::UNO_QUERY
);
203 if ( xControlShape
.is() )
205 bool bEnableVisible
= bVisible
;
206 uno::Reference
< beans::XPropertySet
> xProps( m_xControl
, uno::UNO_QUERY_THROW
);
207 xProps
->getPropertyValue ( "Visible" ) >>= bVisible
;
208 bVisible
= bVisible
&& bEnableVisible
;
211 m_xProps
->getPropertyValue ( "EnableVisible" ) >>= bVisible
;
215 void SAL_CALL
ScVbaControl::setVisible( sal_Bool bVisible
)
217 uno::Any
aValue( bVisible
);
218 m_xProps
->setPropertyValue( "EnableVisible" , aValue
);
219 uno::Reference
< drawing::XControlShape
> xControlShape( m_xControl
, uno::UNO_QUERY
);
220 if ( xControlShape
.is() )
222 uno::Reference
< beans::XPropertySet
> xProps( m_xControl
, uno::UNO_QUERY_THROW
);
223 xProps
->setPropertyValue ( "Visible", aValue
);
226 double SAL_CALL
ScVbaControl::getHeight()
228 return mpGeometryHelper
->getHeight();
230 void SAL_CALL
ScVbaControl::setHeight( double _height
)
232 mpGeometryHelper
->setHeight( _height
);
235 double SAL_CALL
ScVbaControl::getWidth()
237 return mpGeometryHelper
->getWidth();
239 void SAL_CALL
ScVbaControl::setWidth( double _width
)
241 mpGeometryHelper
->setWidth( _width
);
245 ScVbaControl::getLeft()
247 return mpGeometryHelper
->getLeft();
251 ScVbaControl::setLeft( double _left
)
253 mpGeometryHelper
->setLeft( _left
);
257 ScVbaControl::getTop()
259 return mpGeometryHelper
->getTop();
263 ScVbaControl::setTop( double _top
)
265 mpGeometryHelper
->setTop( _top
);
268 uno::Reference
< uno::XInterface
> SAL_CALL
269 ScVbaControl::getObject()
271 uno::Reference
< msforms::XControl
> xRet( this );
275 void SAL_CALL
ScVbaControl::SetFocus()
277 uno::Reference
< awt::XWindow
> xWin( m_xControl
, uno::UNO_QUERY_THROW
);
281 void SAL_CALL
ScVbaControl::Move( double Left
, double Top
, const uno::Any
& Width
, const uno::Any
& Height
)
284 double nHeight
= 0.0;
289 if ( Width
>>= nWidth
)
292 if ( Height
>>= nHeight
)
293 setHeight( nHeight
);
297 ScVbaControl::getControlSource()
299 // #FIXME I *hate* having these upstream differences
300 // but this is necessary until I manage to upstream other
302 OUString sControlSource
;
303 uno::Reference
< form::binding::XBindableValue
> xBindable( m_xProps
, uno::UNO_QUERY
);
304 if ( xBindable
.is() )
308 uno::Reference
< lang::XMultiServiceFactory
> xFac( m_xModel
, uno::UNO_QUERY_THROW
);
309 uno::Reference
< beans::XPropertySet
> xConvertor( xFac
->createInstance( "com.sun.star.table.CellAddressConversion" ), uno::UNO_QUERY
);
310 uno::Reference
< beans::XPropertySet
> xProps( xBindable
->getValueBinding(), uno::UNO_QUERY_THROW
);
311 table::CellAddress aAddress
;
312 xProps
->getPropertyValue( "BoundCell" ) >>= aAddress
;
313 xConvertor
->setPropertyValue( "Address" , uno::Any( aAddress
) );
314 xConvertor
->getPropertyValue( "XLA1Representation" ) >>= sControlSource
;
316 catch(const uno::Exception
&)
320 return sControlSource
;
324 ScVbaControl::setControlSource( const OUString
& _controlsource
)
326 // afaik this is only relevant for Excel documents ( and we need to set up a
327 // reference tab in case no Sheet is specified in "_controlsource"
328 // Can't use the active sheet either, code may of course access
329 uno::Reference
< drawing::XDrawPagesSupplier
> xSupplier( m_xModel
, uno::UNO_QUERY_THROW
);
330 uno::Reference
< container::XIndexAccess
> xIndex( xSupplier
->getDrawPages(), uno::UNO_QUERY_THROW
);
331 sal_Int32 nLen
= xIndex
->getCount();
332 bool bMatched
= false;
333 sal_Int16 nRefTab
= 0;
334 for ( sal_Int32 index
= 0; index
< nLen
; ++index
)
338 uno::Reference
< form::XFormsSupplier
> xFormSupplier( xIndex
->getByIndex( index
), uno::UNO_QUERY_THROW
);
339 uno::Reference
< container::XIndexAccess
> xFormIndex( xFormSupplier
->getForms(), uno::UNO_QUERY_THROW
);
340 // get the www-standard container
341 uno::Reference
< container::XIndexAccess
> xFormControls( xFormIndex
->getByIndex(0), uno::UNO_QUERY_THROW
);
342 sal_Int32 nCntrls
= xFormControls
->getCount();
343 for( sal_Int32 cIndex
= 0; cIndex
< nCntrls
; ++cIndex
)
345 uno::Reference
< uno::XInterface
> xControl( xFormControls
->getByIndex( cIndex
), uno::UNO_QUERY_THROW
);
346 bMatched
= ( m_xProps
== xControl
);
354 catch( uno::Exception
& ) {}
359 svt::BindableControlHelper::ApplyListSourceAndBindableData( m_xModel
, m_xProps
, _controlsource
, "", sal_uInt16( nRefTab
) );
363 ScVbaControl::getRowSource()
366 uno::Reference
< form::binding::XListEntrySink
> xListSink( m_xProps
, uno::UNO_QUERY
);
367 if ( xListSink
.is() )
371 uno::Reference
< lang::XMultiServiceFactory
> xFac( m_xModel
, uno::UNO_QUERY_THROW
);
372 uno::Reference
< beans::XPropertySet
> xConvertor( xFac
->createInstance( "com.sun.star.table.CellRangeAddressConversion" ), uno::UNO_QUERY
);
374 uno::Reference
< beans::XPropertySet
> xProps( xListSink
->getListEntrySource(), uno::UNO_QUERY_THROW
);
375 table::CellRangeAddress aAddress
;
376 xProps
->getPropertyValue( "CellRange" ) >>= aAddress
;
377 xConvertor
->setPropertyValue( "Address" , uno::Any( aAddress
) );
378 xConvertor
->getPropertyValue( "XLA1Representation" ) >>= sRowSource
;
380 catch(const uno::Exception
&)
388 ScVbaControl::setRowSource( const OUString
& _rowsource
)
390 svt::BindableControlHelper::ApplyListSourceAndBindableData( m_xModel
, m_xProps
, "", _rowsource
);
394 ScVbaControl::getName()
397 m_xProps
->getPropertyValue( "Name" ) >>= sName
;
403 ScVbaControl::setName( const OUString
& _name
)
405 m_xProps
->setPropertyValue( "Name" , uno::Any( _name
) );
409 ScVbaControl::getControlTipText()
412 m_xProps
->getPropertyValue( "HelpText" ) >>= sName
;
417 ScVbaControl::setControlTipText( const OUString
& rsToolTip
)
419 m_xProps
->setPropertyValue( "HelpText" , uno::Any( rsToolTip
) );
422 OUString SAL_CALL
ScVbaControl::getTag()
424 return m_aControlTag
;
427 void SAL_CALL
ScVbaControl::setTag( const OUString
& aTag
)
429 m_aControlTag
= aTag
;
432 ::sal_Int32 SAL_CALL
ScVbaControl::getForeColor()
435 m_xProps
->getPropertyValue( "TextColor" ) >>= nForeColor
;
436 return OORGBToXLRGB( nForeColor
);
443 tools::Long msoPointerStyle
;
444 PointerStyle loPointStyle
;
449 // 1 -> 1 map of styles ( some dubious choices in there though )
450 PointerStyles
const styles
[] = {
451 /// assuming pointer default is Arrow
452 { msforms::fmMousePointer::fmMousePointerDefault
, PointerStyle::Arrow
},
453 { msforms::fmMousePointer::fmMousePointerArrow
, PointerStyle::Arrow
},
454 { msforms::fmMousePointer::fmMousePointerCross
, PointerStyle::Cross
},
455 { msforms::fmMousePointer::fmMousePointerIBeam
, PointerStyle::Text
},
456 { msforms::fmMousePointer::fmMousePointerSizeNESW
, PointerStyle::AutoScrollNSWE
}, // #TODO not correct, need to check, need to find the right one
457 { msforms::fmMousePointer::fmMousePointerSizeNS
, PointerStyle::AutoScrollNS
},
458 { msforms::fmMousePointer::fmMousePointerSizeNWSE
, PointerStyle::AutoScrollNSWE
}, // #TODO not correct, need to check, need to find the right one
459 { msforms::fmMousePointer::fmMousePointerSizeWE
, PointerStyle::AutoScrollWE
},
460 { msforms::fmMousePointer::fmMousePointerUpArrow
, PointerStyle::WindowNSize
},
461 { msforms::fmMousePointer::fmMousePointerHourGlass
, PointerStyle::Wait
},
462 { msforms::fmMousePointer::fmMousePointerNoDrop
, PointerStyle::NotAllowed
},
463 { msforms::fmMousePointer::fmMousePointerAppStarting
, PointerStyle::Wait
},
464 { msforms::fmMousePointer::fmMousePointerHelp
, PointerStyle::Help
},
465 { msforms::fmMousePointer::fmMousePointerSizeAll
, PointerStyle::Cross
},
466 { msforms::fmMousePointer::fmMousePointerCustom
, PointerStyle::Arrow
}, // not supported I guess
470 static tools::Long
lcl_loPointerToMsoPointer( PointerStyle eType
)
472 tools::Long nRet
= msforms::fmMousePointer::fmMousePointerDefault
;
473 for ( auto const & i
: styles
)
475 if ( i
.loPointStyle
== eType
)
477 nRet
= i
.msoPointerStyle
;
484 static PointerStyle
lcl_msoPointerToLOPointer( tools::Long msoPointerStyle
)
486 PointerStyle
aPointer( PointerStyle::Arrow
);
487 for ( auto const & i
: styles
)
489 if ( i
.msoPointerStyle
== msoPointerStyle
)
491 aPointer
= i
.loPointStyle
;
499 ScVbaControl::getMousePointer()
501 return lcl_loPointerToMsoPointer(VCLUnoHelper::getMousePointer(getWindowPeer()));
505 ScVbaControl::setMousePointer( ::sal_Int32 _mousepointer
)
507 VCLUnoHelper::setMousePointer(getWindowPeer(), lcl_msoPointerToLOPointer(_mousepointer
));
510 void SAL_CALL
ScVbaControl::fireEvent( const script::ScriptEvent
& rEvt
)
512 script::ScriptEvent
evt( rEvt
);
513 uno::Reference
<lang::XMultiComponentFactory
> xServiceManager( mxContext
->getServiceManager(), uno::UNO_SET_THROW
);
514 uno::Reference
< script::XScriptListener
> xScriptListener( xServiceManager
->createInstanceWithContext( "ooo.vba.EventListener" , mxContext
), uno::UNO_QUERY_THROW
);
516 uno::Reference
< beans::XPropertySet
> xProps( xScriptListener
, uno::UNO_QUERY_THROW
);
517 xProps
->setPropertyValue( "Model" , uno::Any( m_xModel
) );
519 // handling for sheet control
520 uno::Reference
< msforms::XControl
> xThisControl( this );
523 evt
.Arguments
.realloc( 1 );
524 lang::EventObject aEvt
;
526 uno::Reference
< drawing::XControlShape
> xControlShape( m_xControl
, uno::UNO_QUERY
) ;
527 uno::Reference
< awt::XControl
> xControl( m_xControl
, uno::UNO_QUERY
) ;
529 if ( xControlShape
.is() )
531 evt
.Source
= xControlShape
;
532 aEvt
.Source
= m_xEmptyFormControl
;
533 // Set up proper scriptcode
534 uno::Reference
< lang::XMultiServiceFactory
> xDocFac( m_xModel
, uno::UNO_QUERY_THROW
);
535 uno::Reference
< document::XCodeNameQuery
> xNameQuery( xDocFac
->createInstance( "ooo.vba.VBACodeNameProvider" ), uno::UNO_QUERY_THROW
);
536 uno::Reference
< uno::XInterface
> xIf( xControlShape
->getControl(), uno::UNO_QUERY_THROW
);
537 evt
.ScriptCode
= xNameQuery
->getCodeNameForObject( xIf
);
538 // handle if we passed in our own arguments
539 if ( !rEvt
.Arguments
.hasElements() )
540 evt
.Arguments
.getArray()[ 0 ] <<= aEvt
;
541 xScriptListener
->firing( evt
);
545 if ( xControl
.is() ) // normal control ( from dialog/userform )
547 // #FIXME We should probably store a reference to the
548 // parent dialog/userform here (otherwise the name of
549 // dialog could be changed and we won't be aware of it.
550 // (OTOH this is probably an unlikely scenario)
551 evt
.Source
= xThisControl
;
552 aEvt
.Source
= xControl
;
553 evt
.ScriptCode
= m_sLibraryAndCodeName
;
554 evt
.Arguments
.getArray()[ 0 ] <<= aEvt
;
555 xScriptListener
->firing( evt
);
559 catch(const uno::Exception
&)
563 void ScVbaControl::fireChangeEvent()
565 script::ScriptEvent evt
;
566 evt
.ScriptType
= "VBAInterop";
567 evt
.ListenerType
= cppu::UnoType
<form::XChangeListener
>::get();
568 evt
.MethodName
= "changed";
572 void ScVbaControl::fireClickEvent()
574 script::ScriptEvent evt
;
575 evt
.ScriptType
= "VBAInterop";
576 evt
.ListenerType
= cppu::UnoType
<awt::XActionListener
>::get();
577 evt
.MethodName
= "actionPerformed";
581 sal_Int32 SAL_CALL
ScVbaControl::getTabIndex()
586 void SAL_CALL
ScVbaControl::setTabIndex( sal_Int32
/*nTabIndex*/ )
590 //ScVbaControlFactory
592 /*static*/ uno::Reference
< msforms::XControl
> ScVbaControlFactory::createShapeControl(
593 const uno::Reference
< uno::XComponentContext
>& xContext
,
594 const uno::Reference
< drawing::XControlShape
>& xControlShape
,
595 const uno::Reference
< frame::XModel
>& xModel
)
597 uno::Reference
< beans::XPropertySet
> xProps( xControlShape
->getControl(), uno::UNO_QUERY_THROW
);
598 sal_Int32 nClassId
= -1;
599 xProps
->getPropertyValue( "ClassId" ) >>= nClassId
;
600 uno::Reference
< XHelperInterface
> xVbaParent
; // #FIXME - should be worksheet I guess
601 uno::Reference
< drawing::XShape
> xShape( xControlShape
, uno::UNO_QUERY_THROW
);
602 ::std::unique_ptr
< ConcreteXShapeGeometryAttributes
> xGeoHelper( new ConcreteXShapeGeometryAttributes( xShape
) );
605 case form::FormComponentType::COMBOBOX
:
606 return new ScVbaComboBox( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
607 case form::FormComponentType::COMMANDBUTTON
:
609 bool bToggle
= false;
610 xProps
->getPropertyValue( "Toggle" ) >>= bToggle
;
612 return new ScVbaToggleButton( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
614 return new VbaButton( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
616 case form::FormComponentType::FIXEDTEXT
:
617 return new ScVbaLabel( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
618 case form::FormComponentType::TEXTFIELD
:
619 return new ScVbaTextBox( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
620 case form::FormComponentType::CHECKBOX
:
621 return new ScVbaCheckbox( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
622 case form::FormComponentType::RADIOBUTTON
:
623 return new ScVbaRadioButton( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
624 case form::FormComponentType::LISTBOX
:
625 return new ScVbaListBox( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
626 case form::FormComponentType::SPINBUTTON
:
627 return new ScVbaSpinButton( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
628 case form::FormComponentType::IMAGECONTROL
:
629 return new ScVbaImage( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
630 case form::FormComponentType::SCROLLBAR
:
631 return new ScVbaScrollBar( xVbaParent
, xContext
, xControlShape
, xModel
, std::move(xGeoHelper
) );
633 throw uno::RuntimeException( "Unsupported control." );
636 /*static*/ uno::Reference
< msforms::XControl
> ScVbaControlFactory::createUserformControl(
637 const uno::Reference
< uno::XComponentContext
>& xContext
,
638 const uno::Reference
< awt::XControl
>& xControl
,
639 const uno::Reference
< awt::XControl
>& xDialog
,
640 const uno::Reference
< frame::XModel
>& xModel
,
641 double fOffsetX
, double fOffsetY
)
643 uno::Reference
< beans::XPropertySet
> xProps( xControl
->getModel(), uno::UNO_QUERY_THROW
);
644 uno::Reference
< lang::XServiceInfo
> xServiceInfo( xProps
, uno::UNO_QUERY_THROW
);
645 uno::Reference
< msforms::XControl
> xVBAControl
;
646 uno::Reference
< XHelperInterface
> xVbaParent
; // #FIXME - should be worksheet I guess
647 ::std::unique_ptr
< UserFormGeometryHelper
> xGeoHelper( new UserFormGeometryHelper( xControl
, fOffsetX
, fOffsetY
) );
649 if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) )
650 xVBAControl
.set( new ScVbaCheckbox( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
651 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) )
652 xVBAControl
.set( new ScVbaRadioButton( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
653 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlEditModel" ) )
654 xVBAControl
.set( new ScVbaTextBox( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
), true ) );
655 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlButtonModel" ) )
657 bool bToggle
= false;
658 xProps
->getPropertyValue( "Toggle" ) >>= bToggle
;
660 xVBAControl
.set( new ScVbaToggleButton( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
662 xVBAControl
.set( new VbaButton( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
664 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ) )
665 xVBAControl
.set( new ScVbaComboBox( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
666 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlListBoxModel" ) )
667 xVBAControl
.set( new ScVbaListBox( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
668 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
669 xVBAControl
.set( new ScVbaLabel( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
670 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlImageControlModel" ) )
671 xVBAControl
.set( new ScVbaImage( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
672 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ) )
673 xVBAControl
.set( new ScVbaProgressBar( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
674 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) )
675 xVBAControl
.set( new ScVbaFrame( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
), xDialog
) );
676 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ) )
677 xVBAControl
.set( new ScVbaScrollBar( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
678 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoMultiPageModel" ) )
679 xVBAControl
.set( new ScVbaMultiPage( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
680 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoControlSpinButtonModel" ) )
681 xVBAControl
.set( new ScVbaSpinButton( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
682 else if ( xServiceInfo
->supportsService( "com.sun.star.custom.awt.UnoControlSystemAXContainerModel" ) )
683 xVBAControl
.set( new VbaSystemAXControl( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
684 // #FIXME implement a page control
685 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoPageModel" ) )
686 xVBAControl
.set( new ScVbaControl( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
) ) );
687 else if ( xServiceInfo
->supportsService( "com.sun.star.awt.UnoFrameModel" ) )
688 xVBAControl
.set( new ScVbaFrame( xVbaParent
, xContext
, xControl
, xModel
, std::move(xGeoHelper
), xDialog
) );
689 if( xVBAControl
.is() )
691 throw uno::RuntimeException( "Unsupported control." );
695 ScVbaControl::getServiceImplName()
697 return "ScVbaControl";
700 uno::Sequence
< OUString
>
701 ScVbaControl::getServiceNames()
703 return { "ooo.vba.excel.Control" };
706 sal_Int32
const nSysCols
[] = { 0xC8D0D4, 0x0, 0x6A240A, 0x808080, 0xE4E4E4, 0xFFFFFF, 0x0, 0x0, 0x0, 0xFFFFFF, 0xE4E4E4, 0xE4E4E4, 0x808080, 0x6A240A, 0xFFFFFF, 0xE4E4E4, 0x808080, 0x808080, 0x0, 0xC8D0D4, 0xFFFFFF, 0x404040, 0xE4E4E4, 0x0, 0xE1FFFF };
708 sal_Int32
ScVbaControl::getBackColor()
710 sal_Int32 nBackColor
= 0;
711 m_xProps
->getPropertyValue( "BackgroundColor" ) >>= nBackColor
;
715 void ScVbaControl::setBackColor( sal_Int32 nBackColor
)
717 auto const col
= static_cast<sal_uInt32
>(nBackColor
);
718 if ( ( col
>= sal_uInt32(0x80000000) ) &&
719 ( col
<= sal_uInt32(0x80000000) + SAL_N_ELEMENTS(nSysCols
) ) )
721 nBackColor
= nSysCols
[ col
& 0x0FF];
723 m_xProps
->setPropertyValue( "BackgroundColor" , uno::Any( XLRGBToOORGB( nBackColor
) ) );
726 bool ScVbaControl::getAutoSize() const
728 bool bIsResizeEnabled
= false;
729 uno::Reference
< uno::XInterface
> xIf( m_xControl
, uno::UNO_SET_THROW
);
730 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape( xIf
);
732 bIsResizeEnabled
= !pObj
->IsResizeProtect();
733 return bIsResizeEnabled
;
736 // currently no implementation for this
737 void ScVbaControl::setAutoSize( bool bAutoSize
)
739 uno::Reference
< uno::XInterface
> xIf( m_xControl
, uno::UNO_SET_THROW
);
740 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape( xIf
);
742 pObj
->SetResizeProtect( !bAutoSize
);
745 bool ScVbaControl::getLocked()
748 m_xProps
->getPropertyValue( "ReadOnly" ) >>= bRes
;
752 void ScVbaControl::setLocked( bool bLocked
)
754 m_xProps
->setPropertyValue( "ReadOnly" , uno::Any( bLocked
) );
759 class ControlProviderImpl
: public cppu::WeakImplHelper
< XControlProvider
, css::lang::XServiceInfo
>
761 uno::Reference
< uno::XComponentContext
> m_xCtx
;
763 explicit ControlProviderImpl( uno::Reference
< uno::XComponentContext
> xCtx
) : m_xCtx(std::move( xCtx
)) {}
764 virtual uno::Reference
< msforms::XControl
> SAL_CALL
createControl( const uno::Reference
< drawing::XControlShape
>& xControl
, const uno::Reference
< frame::XModel
>& xDocOwner
) override
;
767 virtual sal_Bool SAL_CALL
supportsService(const OUString
& sServiceName
) override
;
768 virtual OUString SAL_CALL
getImplementationName() override
;
769 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
775 sal_Bool
ControlProviderImpl::supportsService(const OUString
& sServiceName
)
777 return cppu::supportsService(this, sServiceName
);
779 OUString
ControlProviderImpl::getImplementationName()
781 return "ControlProviderImpl";
783 css::uno::Sequence
< OUString
> ControlProviderImpl::getSupportedServiceNames()
785 return { "ooo.vba.ControlProvider" };
788 uno::Reference
< msforms::XControl
> SAL_CALL
789 ControlProviderImpl::createControl( const uno::Reference
< drawing::XControlShape
>& xControlShape
, const uno::Reference
< frame::XModel
>& xDocOwner
)
791 uno::Reference
< msforms::XControl
> xControlToReturn
;
792 if ( xControlShape
.is() )
793 xControlToReturn
= ScVbaControlFactory::createShapeControl( m_xCtx
, xControlShape
, xDocOwner
);
794 return xControlToReturn
;
798 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
799 ControlProviderImpl_get_implementation(
800 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
802 return cppu::acquire(new ControlProviderImpl(context
));
805 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */