Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 : #include <com/sun/star/form/FormComponentType.hpp>
20 : #include <com/sun/star/awt/XControlModel.hpp>
21 : #include <com/sun/star/awt/XControl.hpp>
22 : #include <com/sun/star/awt/XWindow2.hpp>
23 : #include <com/sun/star/awt/XActionListener.hpp>
24 : #include <com/sun/star/lang/XEventListener.hpp>
25 : #include <com/sun/star/drawing/XShape.hpp>
26 : #include <com/sun/star/drawing/XControlShape.hpp>
27 : #include <com/sun/star/frame/XModel.hpp>
28 : #include <com/sun/star/view/XControlAccess.hpp>
29 : #include <com/sun/star/container/XChild.hpp>
30 : #include <com/sun/star/form/binding/XBindableValue.hpp>
31 : #include <com/sun/star/form/binding/XListEntrySink.hpp>
32 : #include <com/sun/star/table/CellAddress.hpp>
33 : #include <com/sun/star/table/CellRangeAddress.hpp>
34 : #include <com/sun/star/script/XScriptListener.hpp>
35 : #include <com/sun/star/document/XCodeNameQuery.hpp>
36 : #include <com/sun/star/form/XChangeListener.hpp>
37 : #include <ooo/vba/XControlProvider.hpp>
38 : #include <ooo/vba/msforms/fmMousePointer.hpp>
39 : #include <svtools/bindablecontrolhelper.hxx>
40 : #include "vbacontrol.hxx"
41 : #include "vbacombobox.hxx"
42 : #include "vbabutton.hxx"
43 : #include "vbalabel.hxx"
44 : #include "vbatextbox.hxx"
45 : #include "vbaradiobutton.hxx"
46 : #include "vbalistbox.hxx"
47 : #include "vbatogglebutton.hxx"
48 : #include "vbacheckbox.hxx"
49 : #include "vbaframe.hxx"
50 : #include "vbascrollbar.hxx"
51 : #include "vbaprogressbar.hxx"
52 : #include "vbamultipage.hxx"
53 : #include "vbaspinbutton.hxx"
54 : #include "vbasystemaxcontrol.hxx"
55 : #include "vbaimage.hxx"
56 : #include <vbahelper/helperdecl.hxx>
57 : #include <toolkit/helper/vclunohelper.hxx>
58 : #include <vcl/window.hxx>
59 : #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
60 : #include <com/sun/star/form/XFormsSupplier.hpp>
61 : #include <svx/svdobj.hxx>
62 :
63 : using namespace com::sun::star;
64 : using namespace ooo::vba;
65 :
66 : uno::Reference< css::awt::XWindowPeer >
67 0 : ScVbaControl::getWindowPeer() throw (uno::RuntimeException)
68 : {
69 0 : uno::Reference< drawing::XControlShape > xControlShape( m_xControl, uno::UNO_QUERY );
70 :
71 0 : uno::Reference< awt::XControlModel > xControlModel;
72 0 : uno::Reference< css::awt::XWindowPeer > xWinPeer;
73 0 : if ( !xControlShape.is() )
74 : {
75 : // would seem to be a Userform control
76 0 : uno::Reference< awt::XControl > xControl( m_xControl, uno::UNO_QUERY_THROW );
77 0 : xWinPeer = xControl->getPeer();
78 0 : return xWinPeer;
79 : }
80 : // form control
81 0 : xControlModel.set( xControlShape->getControl(), uno::UNO_QUERY_THROW );
82 :
83 0 : uno::Reference< view::XControlAccess > xControlAccess( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
84 : try
85 : {
86 0 : uno::Reference< awt::XControl > xControl( xControlAccess->getControl( xControlModel ), uno::UNO_QUERY );
87 0 : xWinPeer = xControl->getPeer();
88 : }
89 0 : catch(const uno::Exception&)
90 : {
91 0 : throw uno::RuntimeException( "The Control does not exist" );
92 : }
93 0 : return xWinPeer;
94 : }
95 :
96 : //ScVbaControlListener
97 : class ScVbaControlListener: public cppu::WeakImplHelper1< lang::XEventListener >
98 : {
99 : private:
100 : ScVbaControl *pControl;
101 : public:
102 : ScVbaControlListener( ScVbaControl *pTmpControl );
103 : virtual ~ScVbaControlListener();
104 : virtual void SAL_CALL disposing( const lang::EventObject& rEventObject ) throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
105 : };
106 :
107 228 : ScVbaControlListener::ScVbaControlListener( ScVbaControl *pTmpControl ): pControl( pTmpControl )
108 : {
109 228 : }
110 :
111 456 : ScVbaControlListener::~ScVbaControlListener()
112 : {
113 456 : }
114 :
115 : void SAL_CALL
116 0 : ScVbaControlListener::disposing( const lang::EventObject& ) throw( uno::RuntimeException, std::exception )
117 : {
118 0 : if( pControl )
119 : {
120 0 : pControl->removeResouce();
121 0 : pControl = NULL;
122 : }
123 0 : }
124 :
125 : //ScVbaControl
126 :
127 228 : ScVbaControl::ScVbaControl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< ::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, AbstractGeometryAttributes* pGeomHelper ) : ControlImpl_BASE( xParent, xContext ), bIsDialog(false), m_xControl( xControl ), m_xModel( xModel )
128 : {
129 : //add listener
130 228 : m_xEventListener.set( new ScVbaControlListener( this ) );
131 228 : setGeometryHelper( pGeomHelper );
132 228 : uno::Reference< lang::XComponent > xComponent( m_xControl, uno::UNO_QUERY_THROW );
133 228 : xComponent->addEventListener( m_xEventListener );
134 :
135 : //init m_xProps
136 456 : uno::Reference< drawing::XControlShape > xControlShape( m_xControl, uno::UNO_QUERY ) ;
137 456 : uno::Reference< awt::XControl> xUserFormControl( m_xControl, uno::UNO_QUERY ) ;
138 228 : if ( xControlShape.is() ) // form control
139 : {
140 122 : m_xProps.set( xControlShape->getControl(), uno::UNO_QUERY_THROW );
141 122 : OUString sDefaultControl;
142 122 : m_xProps->getPropertyValue( "DefaultControl" ) >>= sDefaultControl;
143 244 : uno::Reference< lang::XMultiComponentFactory > xMFac( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
144 244 : m_xEmptyFormControl.set( xMFac->createInstanceWithContext( sDefaultControl, mxContext ), uno::UNO_QUERY_THROW );
145 : }
146 106 : else if ( xUserFormControl.is() ) // userform control
147 : {
148 106 : m_xProps.set( xUserFormControl->getModel(), uno::UNO_QUERY_THROW );
149 106 : bIsDialog = true;
150 228 : }
151 228 : }
152 :
153 456 : ScVbaControl::~ScVbaControl()
154 : {
155 228 : if( m_xControl.is() )
156 : {
157 228 : uno::Reference< lang::XComponent > xComponent( m_xControl, uno::UNO_QUERY_THROW );
158 228 : xComponent->removeEventListener( m_xEventListener );
159 : }
160 228 : }
161 :
162 : void
163 232 : ScVbaControl::setGeometryHelper( AbstractGeometryAttributes* pHelper )
164 : {
165 232 : mpGeometryHelper.reset( pHelper );
166 232 : }
167 :
168 0 : void ScVbaControl::removeResouce() throw( uno::RuntimeException )
169 : {
170 0 : uno::Reference< lang::XComponent > xComponent( m_xControl, uno::UNO_QUERY_THROW );
171 0 : xComponent->removeEventListener( m_xEventListener );
172 0 : m_xControl= NULL;
173 0 : m_xProps = NULL;
174 0 : }
175 :
176 : //In design model has different behavior
177 0 : sal_Bool SAL_CALL ScVbaControl::getEnabled() throw (uno::RuntimeException, std::exception)
178 : {
179 0 : uno::Any aValue = m_xProps->getPropertyValue ( "Enabled" );
180 0 : bool bRet = false;
181 0 : aValue >>= bRet;
182 0 : return bRet;
183 : }
184 :
185 0 : void SAL_CALL ScVbaControl::setEnabled( sal_Bool bVisible ) throw (uno::RuntimeException, std::exception)
186 : {
187 0 : uno::Any aValue( bVisible );
188 0 : m_xProps->setPropertyValue( "Enabled" , aValue);
189 :
190 0 : }
191 :
192 0 : sal_Bool SAL_CALL ScVbaControl::getVisible() throw (uno::RuntimeException, std::exception)
193 : {
194 0 : bool bVisible( true );
195 0 : m_xProps->getPropertyValue ( "EnableVisible" ) >>= bVisible;
196 0 : uno::Reference< drawing::XControlShape > xControlShape( m_xControl, uno::UNO_QUERY );
197 0 : if ( xControlShape.is() )
198 : {
199 0 : bool bEnableVisible = bVisible;
200 0 : uno::Reference< beans::XPropertySet > xProps( m_xControl, uno::UNO_QUERY_THROW );
201 0 : xProps->getPropertyValue ( "Visible" ) >>= bVisible;
202 0 : bVisible = bVisible && bEnableVisible;
203 : }
204 : else
205 0 : m_xProps->getPropertyValue ( "EnableVisible" ) >>= bVisible;
206 0 : return bVisible;
207 : }
208 :
209 0 : void SAL_CALL ScVbaControl::setVisible( sal_Bool bVisible ) throw (uno::RuntimeException, std::exception)
210 : {
211 0 : uno::Any aValue( bVisible );
212 0 : m_xProps->setPropertyValue( "EnableVisible" , aValue);
213 0 : uno::Reference< drawing::XControlShape > xControlShape( m_xControl, uno::UNO_QUERY );
214 0 : if ( xControlShape.is() )
215 : {
216 0 : uno::Reference< beans::XPropertySet > xProps( m_xControl, uno::UNO_QUERY_THROW );
217 0 : xProps->setPropertyValue ( "Visible", aValue );
218 0 : }
219 0 : }
220 0 : double SAL_CALL ScVbaControl::getHeight() throw (uno::RuntimeException, std::exception)
221 : {
222 0 : return mpGeometryHelper->getHeight();
223 : }
224 0 : void SAL_CALL ScVbaControl::setHeight( double _height ) throw (uno::RuntimeException, std::exception)
225 : {
226 0 : mpGeometryHelper->setHeight( _height );
227 0 : }
228 :
229 0 : double SAL_CALL ScVbaControl::getWidth() throw (uno::RuntimeException, std::exception)
230 : {
231 0 : return mpGeometryHelper->getWidth();
232 : }
233 0 : void SAL_CALL ScVbaControl::setWidth( double _width ) throw (uno::RuntimeException, std::exception)
234 : {
235 0 : mpGeometryHelper->setWidth( _width );
236 0 : }
237 :
238 : double SAL_CALL
239 0 : ScVbaControl::getLeft() throw (uno::RuntimeException, std::exception)
240 : {
241 0 : return mpGeometryHelper->getLeft();
242 : }
243 :
244 : void SAL_CALL
245 0 : ScVbaControl::setLeft( double _left ) throw (uno::RuntimeException, std::exception)
246 : {
247 0 : mpGeometryHelper->setLeft( _left );
248 0 : }
249 :
250 : double SAL_CALL
251 0 : ScVbaControl::getTop() throw (uno::RuntimeException, std::exception)
252 : {
253 0 : return mpGeometryHelper->getTop();
254 : }
255 :
256 : void SAL_CALL
257 0 : ScVbaControl::setTop( double _top ) throw (uno::RuntimeException, std::exception)
258 : {
259 0 : mpGeometryHelper->setTop( _top );
260 0 : }
261 :
262 : uno::Reference< uno::XInterface > SAL_CALL
263 0 : ScVbaControl::getObject() throw (uno::RuntimeException, std::exception)
264 : {
265 0 : uno::Reference< msforms::XControl > xRet( this );
266 0 : return xRet;
267 : }
268 :
269 0 : void SAL_CALL ScVbaControl::SetFocus() throw (uno::RuntimeException, std::exception)
270 : {
271 0 : uno::Reference< awt::XWindow > xWin( m_xControl, uno::UNO_QUERY_THROW );
272 0 : xWin->setFocus();
273 0 : }
274 :
275 0 : void SAL_CALL ScVbaControl::Move( double Left, double Top, const uno::Any& Width, const uno::Any& Height )
276 : throw ( uno::RuntimeException, std::exception )
277 : {
278 0 : double nWidth = 0.0;
279 0 : double nHeight = 0.0;
280 :
281 0 : setLeft( Left );
282 0 : setTop( Top );
283 :
284 0 : if ( Width >>= nWidth )
285 0 : setWidth( nWidth );
286 :
287 0 : if ( Height >>= nHeight )
288 0 : setHeight( nHeight );
289 0 : }
290 :
291 : OUString SAL_CALL
292 0 : ScVbaControl::getControlSource() throw (uno::RuntimeException, std::exception)
293 : {
294 : // #FIXME I *hate* having these upstream differences
295 : // but this is necessary until I manage to upstream other
296 : // dependent parts
297 0 : OUString sControlSource;
298 0 : uno::Reference< form::binding::XBindableValue > xBindable( m_xProps, uno::UNO_QUERY );
299 0 : if ( xBindable.is() )
300 : {
301 : try
302 : {
303 0 : uno::Reference< lang::XMultiServiceFactory > xFac( m_xModel, uno::UNO_QUERY_THROW );
304 0 : uno::Reference< beans::XPropertySet > xConvertor( xFac->createInstance( "com.sun.star.table.CellAddressConversion" ), uno::UNO_QUERY );
305 0 : uno::Reference< beans::XPropertySet > xProps( xBindable->getValueBinding(), uno::UNO_QUERY_THROW );
306 0 : table::CellAddress aAddress;
307 0 : xProps->getPropertyValue( "BoundCell" ) >>= aAddress;
308 0 : xConvertor->setPropertyValue( "Address" , uno::makeAny( aAddress ) );
309 0 : xConvertor->getPropertyValue( "XLA1Representation" ) >>= sControlSource;
310 : }
311 0 : catch(const uno::Exception&)
312 : {
313 : }
314 : }
315 0 : return sControlSource;
316 : }
317 :
318 : void SAL_CALL
319 0 : ScVbaControl::setControlSource( const OUString& _controlsource ) throw (uno::RuntimeException, std::exception)
320 : {
321 0 : OUString sEmpty;
322 : // afaik this is only relevant for Excel documents ( and we need to set up a
323 : // reference tab in case no Sheet is specified in "_controlsource"
324 : // Can't use the active sheet either, code may of course access
325 0 : uno::Reference< drawing::XDrawPagesSupplier > xSupplier( m_xModel, uno::UNO_QUERY_THROW );
326 0 : uno::Reference< container::XIndexAccess > xIndex( xSupplier->getDrawPages(), uno::UNO_QUERY_THROW );
327 0 : sal_Int32 nLen = xIndex->getCount();
328 0 : bool bMatched = false;
329 0 : sal_Int16 nRefTab = 0;
330 0 : for ( sal_Int32 index = 0; index < nLen; ++index )
331 : {
332 : try
333 : {
334 0 : uno::Reference< form::XFormsSupplier > xFormSupplier( xIndex->getByIndex( index ), uno::UNO_QUERY_THROW );
335 0 : uno::Reference< container::XIndexAccess > xFormIndex( xFormSupplier->getForms(), uno::UNO_QUERY_THROW );
336 : // get the www-standard container
337 0 : uno::Reference< container::XIndexAccess > xFormControls( xFormIndex->getByIndex(0), uno::UNO_QUERY_THROW );
338 0 : sal_Int32 nCntrls = xFormControls->getCount();
339 0 : for( sal_Int32 cIndex = 0; cIndex < nCntrls; ++cIndex )
340 : {
341 0 : uno::Reference< uno::XInterface > xControl( xFormControls->getByIndex( cIndex ), uno::UNO_QUERY_THROW );
342 0 : bMatched = ( m_xProps == xControl );
343 0 : if ( bMatched )
344 : {
345 0 : nRefTab = index;
346 0 : break;
347 : }
348 0 : }
349 : }
350 0 : catch( uno::Exception& ) {}
351 0 : if ( bMatched )
352 0 : break;
353 : }
354 :
355 0 : svt::BindableControlHelper::ApplyListSourceAndBindableData( m_xModel, m_xProps, _controlsource, sEmpty, sal_uInt16( nRefTab ) );
356 0 : }
357 :
358 : OUString SAL_CALL
359 0 : ScVbaControl::getRowSource() throw (uno::RuntimeException, std::exception)
360 : {
361 0 : OUString sRowSource;
362 0 : uno::Reference< form::binding::XListEntrySink > xListSink( m_xProps, uno::UNO_QUERY );
363 0 : if ( xListSink.is() )
364 : {
365 : try
366 : {
367 0 : uno::Reference< lang::XMultiServiceFactory > xFac( m_xModel, uno::UNO_QUERY_THROW );
368 0 : uno::Reference< beans::XPropertySet > xConvertor( xFac->createInstance( "com.sun.star.table.CellRangeAddressConversion" ), uno::UNO_QUERY );
369 :
370 0 : uno::Reference< beans::XPropertySet > xProps( xListSink->getListEntrySource(), uno::UNO_QUERY_THROW );
371 0 : table::CellRangeAddress aAddress;
372 0 : xProps->getPropertyValue( "CellRange" ) >>= aAddress;
373 0 : xConvertor->setPropertyValue( "Address" , uno::makeAny( aAddress ) );
374 0 : xConvertor->getPropertyValue( "XLA1Representation" ) >>= sRowSource;
375 : }
376 0 : catch(const uno::Exception&)
377 : {
378 : }
379 : }
380 0 : return sRowSource;
381 : }
382 :
383 : void SAL_CALL
384 0 : ScVbaControl::setRowSource( const OUString& _rowsource ) throw (uno::RuntimeException, std::exception)
385 : {
386 0 : OUString sEmpty;
387 0 : svt::BindableControlHelper::ApplyListSourceAndBindableData( m_xModel, m_xProps, sEmpty, _rowsource );
388 0 : }
389 :
390 : OUString SAL_CALL
391 102 : ScVbaControl::getName() throw (uno::RuntimeException, std::exception)
392 : {
393 102 : OUString sName;
394 102 : m_xProps->getPropertyValue( "Name" ) >>= sName;
395 102 : return sName;
396 :
397 : }
398 :
399 : void SAL_CALL
400 0 : ScVbaControl::setName( const OUString& _name ) throw (uno::RuntimeException, std::exception)
401 : {
402 0 : m_xProps->setPropertyValue( "Name" , uno::makeAny( _name ) );
403 0 : }
404 :
405 : OUString SAL_CALL
406 0 : ScVbaControl::getControlTipText() throw (css::uno::RuntimeException, std::exception)
407 : {
408 0 : OUString sName;
409 0 : m_xProps->getPropertyValue( "HelpText" ) >>= sName;
410 0 : return sName;
411 : }
412 :
413 : void SAL_CALL
414 0 : ScVbaControl::setControlTipText( const OUString& rsToolTip ) throw (css::uno::RuntimeException, std::exception)
415 : {
416 0 : m_xProps->setPropertyValue( "HelpText" , uno::makeAny( rsToolTip ) );
417 0 : }
418 :
419 0 : OUString SAL_CALL ScVbaControl::getTag()
420 : throw (css::uno::RuntimeException, std::exception)
421 : {
422 0 : return m_aControlTag;
423 : }
424 :
425 0 : void SAL_CALL ScVbaControl::setTag( const OUString& aTag )
426 : throw (css::uno::RuntimeException, std::exception)
427 : {
428 0 : m_aControlTag = aTag;
429 0 : }
430 :
431 0 : ::sal_Int32 SAL_CALL ScVbaControl::getForeColor() throw (::com::sun::star::uno::RuntimeException)
432 : {
433 0 : sal_Int32 nForeColor = -1;
434 0 : m_xProps->getPropertyValue( "TextColor" ) >>= nForeColor;
435 0 : return OORGBToXLRGB( nForeColor );
436 : }
437 :
438 0 : void SAL_CALL ScVbaControl::setForeColor( ::sal_Int32 _forecolor ) throw (::com::sun::star::uno::RuntimeException)
439 : {
440 0 : m_xProps->setPropertyValue( "TextColor" , uno::makeAny( XLRGBToOORGB( _forecolor ) ) );
441 0 : }
442 :
443 : struct PointerStyles
444 : {
445 : long msoPointerStyle;
446 : PointerStyle loPointStyle;
447 : };
448 :
449 : // 1 -> 1 map of styles ( some dubious choices in there though )
450 : PointerStyles styles[] = {
451 : /// assuming pointer default is Arrow
452 : { msforms::fmMousePointer::fmMousePointerDefault, POINTER_ARROW },
453 : { msforms::fmMousePointer::fmMousePointerArrow, POINTER_ARROW },
454 : { msforms::fmMousePointer::fmMousePointerCross, POINTER_CROSS },
455 : { msforms::fmMousePointer::fmMousePointerIBeam, POINTER_TEXT },
456 : { msforms::fmMousePointer::fmMousePointerSizeNESW, POINTER_AUTOSCROLL_NSWE }, // #TODO not correct, need to check, need to find the right one
457 : { msforms::fmMousePointer::fmMousePointerSizeNS, POINTER_AUTOSCROLL_NS },
458 : { msforms::fmMousePointer::fmMousePointerSizeNWSE, POINTER_AUTOSCROLL_NSWE }, // #TODO not correct, need to check, need to find the right one
459 : { msforms::fmMousePointer::fmMousePointerSizeWE, POINTER_AUTOSCROLL_WE },
460 : { msforms::fmMousePointer::fmMousePointerUpArrow, POINTER_WINDOW_NSIZE },
461 : { msforms::fmMousePointer::fmMousePointerHourGlass, POINTER_WAIT },
462 : { msforms::fmMousePointer::fmMousePointerNoDrop, POINTER_NOTALLOWED },
463 : { msforms::fmMousePointer::fmMousePointerAppStarting, POINTER_WAIT },
464 : { msforms::fmMousePointer::fmMousePointerHelp, POINTER_HELP },
465 : { msforms::fmMousePointer::fmMousePointerSizeAll, POINTER_CROSS },
466 : { msforms::fmMousePointer::fmMousePointerCustom, POINTER_ARROW }, // not supported I guess
467 :
468 : };
469 :
470 0 : static long lcl_loPointerToMsoPointer( PointerStyle eType )
471 : {
472 0 : long nRet = msforms::fmMousePointer::fmMousePointerDefault;
473 0 : for ( int i = 0, nElems = SAL_N_ELEMENTS( styles ); i < nElems; ++i )
474 : {
475 0 : if ( styles[ i ].loPointStyle == eType )
476 : {
477 0 : nRet = styles[ i ].msoPointerStyle;
478 0 : break;
479 : }
480 : }
481 0 : return nRet;
482 : }
483 :
484 0 : static Pointer lcl_msoPointerToLOPointer( long msoPointerStyle )
485 : {
486 0 : Pointer aPointer( POINTER_ARROW );
487 0 : for ( int i = 0, nElems = SAL_N_ELEMENTS( styles ); i < nElems; ++i )
488 : {
489 0 : if ( styles[ i ].msoPointerStyle == msoPointerStyle )
490 : {
491 0 : aPointer = Pointer( styles[ i ].loPointStyle );
492 0 : break;
493 : }
494 : }
495 0 : return aPointer;
496 : }
497 :
498 : ::sal_Int32 SAL_CALL
499 0 : ScVbaControl::getMousePointer() throw (::com::sun::star::uno::RuntimeException, std::exception)
500 : {
501 0 : PointerStyle eType = POINTER_ARROW; // default ?
502 0 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( getWindowPeer() );
503 0 : if ( pWindow )
504 : {
505 0 : eType = pWindow->GetPointer().GetStyle();
506 : }
507 0 : return lcl_loPointerToMsoPointer( eType );
508 : }
509 :
510 : void SAL_CALL
511 0 : ScVbaControl::setMousePointer( ::sal_Int32 _mousepointer ) throw (::com::sun::star::uno::RuntimeException, std::exception)
512 : {
513 0 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( getWindowPeer() );
514 0 : if ( pWindow )
515 : {
516 0 : Pointer aPointer( POINTER_ARROW );
517 0 : aPointer = lcl_msoPointerToLOPointer( _mousepointer );
518 0 : pWindow->SetPointer( aPointer );
519 : }
520 0 : }
521 :
522 56 : void SAL_CALL ScVbaControl::fireEvent( const script::ScriptEvent& rEvt ) throw (uno::RuntimeException, std::exception)
523 : {
524 56 : script::ScriptEvent evt( rEvt );
525 112 : uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
526 112 : uno::Reference< script::XScriptListener > xScriptListener( xServiceManager->createInstanceWithContext( "ooo.vba.EventListener" , mxContext ), uno::UNO_QUERY_THROW );
527 :
528 112 : uno::Reference< beans::XPropertySet > xProps( xScriptListener, uno::UNO_QUERY_THROW );
529 56 : xProps->setPropertyValue( "Model" , uno::makeAny( m_xModel ) );
530 :
531 : // handling for sheet control
532 112 : uno::Reference< msforms::XControl > xThisControl( this );
533 : try
534 : {
535 56 : evt.Arguments.realloc( 1 );
536 56 : lang::EventObject aEvt;
537 :
538 112 : uno::Reference< drawing::XControlShape > xControlShape( m_xControl, uno::UNO_QUERY ) ;
539 112 : uno::Reference< awt::XControl > xControl( m_xControl, uno::UNO_QUERY ) ;
540 :
541 56 : if ( xControlShape.is() )
542 : {
543 32 : evt.Source = xControlShape;
544 32 : aEvt.Source = m_xEmptyFormControl;
545 : // Set up proper scriptcode
546 32 : uno::Reference< lang::XMultiServiceFactory > xDocFac( m_xModel, uno::UNO_QUERY_THROW );
547 64 : uno::Reference< document::XCodeNameQuery > xNameQuery( xDocFac->createInstance( "ooo.vba.VBACodeNameProvider" ), uno::UNO_QUERY_THROW );
548 64 : uno::Reference< uno::XInterface > xIf( xControlShape->getControl(), uno::UNO_QUERY_THROW );
549 32 : evt.ScriptCode = xNameQuery->getCodeNameForObject( xIf );
550 : // handle if we passed in our own arguments
551 32 : if ( !rEvt.Arguments.getLength() )
552 30 : evt.Arguments[ 0 ] = uno::makeAny( aEvt );
553 64 : xScriptListener->firing( evt );
554 : }
555 : else
556 : {
557 24 : if ( xControl.is() ) // normal control ( from dialog/userform )
558 : {
559 : // #FIXME We should probably store a reference to the
560 : // parent dialog/userform here ( other wise the name of
561 : // dialog could be changed and we won't be aware of it.
562 : // ( OTOH this is probably an unlikely scenario )
563 24 : evt.Source = xThisControl;
564 24 : aEvt.Source = xControl;
565 24 : evt.ScriptCode = m_sLibraryAndCodeName;
566 24 : evt.Arguments[ 0 ] = uno::makeAny( aEvt );
567 24 : xScriptListener->firing( evt );
568 : }
569 56 : }
570 : }
571 0 : catch(const uno::Exception&)
572 : {
573 56 : }
574 56 : }
575 28 : void ScVbaControl::fireChangeEvent()
576 : {
577 28 : script::ScriptEvent evt;
578 28 : evt.ScriptType = "VBAInterop";
579 28 : evt.ListenerType = cppu::UnoType<form::XChangeListener>::get();
580 28 : evt.MethodName = "changed";
581 28 : fireEvent( evt );
582 28 : }
583 :
584 26 : void ScVbaControl::fireClickEvent()
585 : {
586 26 : script::ScriptEvent evt;
587 26 : evt.ScriptType = "VBAInterop";
588 26 : evt.ListenerType = cppu::UnoType<awt::XActionListener>::get();
589 26 : evt.MethodName = "actionPerformed";
590 26 : fireEvent( evt );
591 26 : }
592 :
593 0 : sal_Int32 SAL_CALL ScVbaControl::getTabIndex() throw (uno::RuntimeException, std::exception)
594 : {
595 0 : return 1;
596 : }
597 :
598 0 : void SAL_CALL ScVbaControl::setTabIndex( sal_Int32 /*nTabIndex*/ ) throw (uno::RuntimeException, std::exception)
599 : {
600 0 : }
601 :
602 : //ScVbaControlFactory
603 :
604 122 : /*static*/ uno::Reference< msforms::XControl > ScVbaControlFactory::createShapeControl(
605 : const uno::Reference< uno::XComponentContext >& xContext,
606 : const uno::Reference< drawing::XControlShape >& xControlShape,
607 : const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException)
608 : {
609 122 : uno::Reference< beans::XPropertySet > xProps( xControlShape->getControl(), uno::UNO_QUERY_THROW );
610 122 : sal_Int32 nClassId = -1;
611 122 : xProps->getPropertyValue( "ClassId" ) >>= nClassId;
612 244 : uno::Reference< XHelperInterface > xVbaParent; // #FIXME - should be worksheet I guess
613 244 : uno::Reference< drawing::XShape > xShape( xControlShape, uno::UNO_QUERY_THROW );
614 244 : ::std::unique_ptr< ConcreteXShapeGeometryAttributes > xGeoHelper( new ConcreteXShapeGeometryAttributes( xContext, xShape ) );
615 122 : switch( nClassId )
616 : {
617 : case form::FormComponentType::COMBOBOX:
618 14 : return new ScVbaComboBox( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
619 : case form::FormComponentType::COMMANDBUTTON:
620 : {
621 16 : bool bToggle = false;
622 16 : xProps->getPropertyValue( "Toggle" ) >>= bToggle;
623 16 : if ( bToggle )
624 16 : return new ScVbaToggleButton( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
625 : else
626 0 : return new VbaButton( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
627 : }
628 : case form::FormComponentType::FIXEDTEXT:
629 2 : return new ScVbaLabel( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
630 : case form::FormComponentType::TEXTFIELD:
631 34 : return new ScVbaTextBox( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
632 : case form::FormComponentType::CHECKBOX:
633 18 : return new ScVbaCheckbox( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
634 : case form::FormComponentType::RADIOBUTTON:
635 16 : return new ScVbaRadioButton( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
636 : case form::FormComponentType::LISTBOX:
637 22 : return new ScVbaListBox( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
638 : case form::FormComponentType::SPINBUTTON:
639 0 : return new ScVbaSpinButton( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
640 : case form::FormComponentType::IMAGECONTROL:
641 0 : return new ScVbaImage( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
642 : case form::FormComponentType::SCROLLBAR:
643 0 : return new ScVbaScrollBar( xVbaParent, xContext, xControlShape, xModel, xGeoHelper.release() );
644 : }
645 122 : throw uno::RuntimeException( "Unsupported control." );
646 : }
647 :
648 102 : /*static*/ uno::Reference< msforms::XControl > ScVbaControlFactory::createUserformControl(
649 : const uno::Reference< uno::XComponentContext >& xContext,
650 : const uno::Reference< awt::XControl >& xControl,
651 : const uno::Reference< awt::XControl >& xDialog,
652 : const uno::Reference< frame::XModel >& xModel,
653 : double fOffsetX, double fOffsetY ) throw (uno::RuntimeException)
654 : {
655 102 : uno::Reference< beans::XPropertySet > xProps( xControl->getModel(), uno::UNO_QUERY_THROW );
656 204 : uno::Reference< lang::XServiceInfo > xServiceInfo( xProps, uno::UNO_QUERY_THROW );
657 102 : uno::Reference< msforms::XControl > xVBAControl;
658 204 : uno::Reference< XHelperInterface > xVbaParent; // #FIXME - should be worksheet I guess
659 204 : ::std::unique_ptr< UserFormGeometryHelper > xGeoHelper( new UserFormGeometryHelper( xContext, xControl, fOffsetX, fOffsetY ) );
660 :
661 102 : if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) )
662 14 : xVBAControl.set( new ScVbaCheckbox( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
663 88 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) )
664 16 : xVBAControl.set( new ScVbaRadioButton( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
665 72 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlEditModel" ) )
666 32 : xVBAControl.set( new ScVbaTextBox( xVbaParent, xContext, xControl, xModel, xGeoHelper.release(), true ) );
667 40 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlButtonModel" ) )
668 : {
669 16 : bool bToggle = false;
670 16 : xProps->getPropertyValue( "Toggle" ) >>= bToggle;
671 16 : if ( bToggle )
672 16 : xVBAControl.set( new ScVbaToggleButton( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
673 : else
674 0 : xVBAControl.set( new VbaButton( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
675 : }
676 24 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ) )
677 0 : xVBAControl.set( new ScVbaComboBox( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
678 24 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlListBoxModel" ) )
679 24 : xVBAControl.set( new ScVbaListBox( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
680 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
681 0 : xVBAControl.set( new ScVbaLabel( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
682 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlImageControlModel" ) )
683 0 : xVBAControl.set( new ScVbaImage( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
684 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ) )
685 0 : xVBAControl.set( new ScVbaProgressBar( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
686 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) )
687 0 : xVBAControl.set( new ScVbaFrame( xVbaParent, xContext, xControl, xModel, xGeoHelper.release(), xDialog ) );
688 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ) )
689 0 : xVBAControl.set( new ScVbaScrollBar( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
690 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoMultiPageModel" ) )
691 0 : xVBAControl.set( new ScVbaMultiPage( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
692 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlSpinButtonModel" ) )
693 0 : xVBAControl.set( new ScVbaSpinButton( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
694 0 : else if ( xServiceInfo->supportsService( "com.sun.star.custom.awt.UnoControlSystemAXContainerModel" ) )
695 0 : xVBAControl.set( new VbaSystemAXControl( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
696 : // #FIXME implement a page control
697 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoPageModel" ) )
698 0 : xVBAControl.set( new ScVbaControl( xVbaParent, xContext, xControl, xModel, xGeoHelper.release() ) );
699 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoFrameModel" ) )
700 0 : xVBAControl.set( new ScVbaFrame( xVbaParent, xContext, xControl, xModel, xGeoHelper.release(), xDialog ) );
701 102 : if( xVBAControl.is() )
702 204 : return xVBAControl;
703 102 : throw uno::RuntimeException( "Unsupported control." );
704 : }
705 :
706 : OUString
707 0 : ScVbaControl::getServiceImplName()
708 : {
709 0 : return OUString("ScVbaControl");
710 : }
711 :
712 : uno::Sequence< OUString >
713 0 : ScVbaControl::getServiceNames()
714 : {
715 0 : static uno::Sequence< OUString > aServiceNames;
716 0 : if ( aServiceNames.getLength() == 0 )
717 : {
718 0 : aServiceNames.realloc( 1 );
719 0 : aServiceNames[ 0 ] = "ooo.vba.excel.Control";
720 : }
721 0 : return aServiceNames;
722 : }
723 :
724 : sal_Int32 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 };
725 :
726 0 : sal_Int32 ScVbaControl::getBackColor() throw (uno::RuntimeException)
727 : {
728 0 : sal_Int32 nBackColor = 0;
729 0 : m_xProps->getPropertyValue( "BackgroundColor" ) >>= nBackColor;
730 0 : return nBackColor;
731 : }
732 :
733 0 : void ScVbaControl::setBackColor( sal_Int32 nBackColor ) throw (uno::RuntimeException)
734 : {
735 0 : if ( ( (sal_uInt32)nBackColor >= (sal_uInt32)0x80000000 ) &&
736 0 : ( (sal_uInt32)nBackColor <= (sal_uInt32)0x80000000 + SAL_N_ELEMENTS(nSysCols) ) )
737 : {
738 0 : nBackColor = nSysCols[ nBackColor & 0x0FF];
739 : }
740 0 : m_xProps->setPropertyValue( "BackgroundColor" , uno::makeAny( XLRGBToOORGB( nBackColor ) ) );
741 0 : }
742 :
743 0 : bool ScVbaControl::getAutoSize() throw (uno::RuntimeException)
744 : {
745 0 : bool bIsResizeEnabled = false;
746 0 : uno::Reference< uno::XInterface > xIf( m_xControl, uno::UNO_QUERY_THROW );
747 0 : SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xIf );
748 0 : if ( pObj )
749 0 : bIsResizeEnabled = !pObj->IsResizeProtect();
750 0 : return bIsResizeEnabled;
751 : }
752 :
753 : // currently no implementation for this
754 0 : void ScVbaControl::setAutoSize( bool bAutoSize ) throw (uno::RuntimeException)
755 : {
756 0 : uno::Reference< uno::XInterface > xIf( m_xControl, uno::UNO_QUERY_THROW );
757 0 : SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xIf );
758 0 : if ( pObj )
759 0 : pObj->SetResizeProtect( !bAutoSize );
760 0 : }
761 :
762 0 : bool ScVbaControl::getLocked() throw (uno::RuntimeException)
763 : {
764 0 : bool bRes( false );
765 0 : m_xProps->getPropertyValue( "ReadOnly" ) >>= bRes;
766 0 : return bRes;
767 : }
768 :
769 0 : void ScVbaControl::setLocked( bool bLocked ) throw (uno::RuntimeException)
770 : {
771 0 : m_xProps->setPropertyValue( "ReadOnly" , uno::makeAny( bLocked ) );
772 0 : }
773 :
774 : typedef cppu::WeakImplHelper1< XControlProvider > ControlProvider_BASE;
775 122 : class ControlProviderImpl : public ControlProvider_BASE
776 : {
777 : uno::Reference< uno::XComponentContext > m_xCtx;
778 : public:
779 122 : ControlProviderImpl( const uno::Reference< uno::XComponentContext >& xCtx ) : m_xCtx( xCtx ) {}
780 : virtual uno::Reference< msforms::XControl > SAL_CALL createControl( const uno::Reference< drawing::XControlShape >& xControl, const uno::Reference< frame::XModel >& xDocOwner ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
781 : };
782 :
783 : uno::Reference< msforms::XControl > SAL_CALL
784 122 : ControlProviderImpl::createControl( const uno::Reference< drawing::XControlShape >& xControlShape, const uno::Reference< frame::XModel >& xDocOwner ) throw (uno::RuntimeException, std::exception)
785 : {
786 122 : uno::Reference< msforms::XControl > xControlToReturn;
787 122 : if ( xControlShape.is() )
788 122 : xControlToReturn = ScVbaControlFactory::createShapeControl( m_xCtx, xControlShape, xDocOwner );
789 122 : return xControlToReturn;
790 :
791 : }
792 :
793 : namespace controlprovider
794 : {
795 : namespace sdecl = comphelper::service_decl;
796 2 : sdecl::class_<ControlProviderImpl, sdecl::with_args<false> > serviceImpl;
797 2 : extern sdecl::ServiceDecl const serviceDecl(
798 : serviceImpl,
799 : "ControlProviderImpl",
800 : "ooo.vba.ControlProvider" );
801 6 : }
802 :
803 :
804 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|