xref: /trunk/main/sc/source/ui/vba/vbasheetobjects.cxx (revision b3f79822)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "vbasheetobjects.hxx"
25 #include <vector>
26 #include <rtl/math.hxx>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/container/XIndexContainer.hpp>
29 #include <com/sun/star/container/XNamed.hpp>
30 #include <com/sun/star/drawing/XControlShape.hpp>
31 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
32 #include <com/sun/star/drawing/XShapes.hpp>
33 #include <com/sun/star/form/FormComponentType.hpp>
34 #include <com/sun/star/form/XForm.hpp>
35 #include <com/sun/star/form/XFormComponent.hpp>
36 #include <com/sun/star/form/XFormsSupplier.hpp>
37 #include <oox/helper/helper.hxx>
38 #include "vbasheetobject.hxx"
39 
40 using ::rtl::OUString;
41 using namespace ::com::sun::star;
42 using namespace ::ooo::vba;
43 
44 // ============================================================================
45 
46 namespace {
47 
48 template< typename Type >
lclGetProperty(Type & orValue,const uno::Reference<beans::XPropertySet> & rxPropSet,const OUString & rPropName)49 inline bool lclGetProperty( Type& orValue, const uno::Reference< beans::XPropertySet >& rxPropSet, const OUString& rPropName )
50 {
51     try
52     {
53         return rxPropSet->getPropertyValue( rPropName ) >>= orValue;
54     }
55     catch( uno::Exception& )
56     {
57     }
58     return false;
59 }
60 
61 /** Rounds the passed value to a multiple of 0.75 and converts it to 1/100 mm. */
lclPointsToHmm(const uno::Any & rPoints)62 inline double lclPointsToHmm( const uno::Any& rPoints ) throw (uno::RuntimeException)
63 {
64     return PointsToHmm( ::rtl::math::approxFloor( rPoints.get< double >() / 0.75 ) * 0.75 );
65 }
66 
67 } // namespace
68 
69 // ============================================================================
70 // Base implementations
71 // ============================================================================
72 
73 /** Container for a specific type of drawing object in a spreadsheet.
74 
75     Derived classes provide all required functionality specific to the type of
76     shapes covered by the container.
77  */
78 class ScVbaObjectContainer : public ::cppu::WeakImplHelper1< container::XIndexAccess >
79 {
80 public:
81     explicit ScVbaObjectContainer(
82         const uno::Reference< XHelperInterface >& rxParent,
83         const uno::Reference< uno::XComponentContext >& rxContext,
84         const uno::Reference< frame::XModel >& rxModel,
85         const uno::Reference< sheet::XSpreadsheet >& rxSheet,
86         const uno::Type& rVbaType ) throw (uno::RuntimeException);
87 
88     /** Returns the VBA helper interface of the VBA collection object. */
getParent() const89     inline const uno::Reference< XHelperInterface >& getParent() const { return mxParent; }
90     /** Returns the component context of the VBA collection object. */
getContext() const91     inline const uno::Reference< uno::XComponentContext >& getContext() const { return mxContext; }
92     /** Returns the VBA type information of the objects in this container. */
getVbaType() const93     inline const uno::Type& getVbaType() const { return maVbaType; }
94 
95     /** Collects all shapes supported by this instance and inserts them into
96         the internal shape vector. */
97     void collectShapes() throw (uno::RuntimeException);
98     /** Creates and returns a new UNO shape. */
99     uno::Reference< drawing::XShape > createShape( const awt::Point& rPos, const awt::Size& rSize ) throw (uno::RuntimeException);
100     /** Inserts the passed shape into the draw page and into this container, and returns its index in the draw page. */
101     sal_Int32 insertShape( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
102     /** Creates and returns a new VBA implementation object for the passed shape. */
103     ::rtl::Reference< ScVbaSheetObjectBase > createVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
104     /** Creates and returns a new VBA implementation object for the passed shape in an Any. */
105     uno::Any createCollectionObject( const uno::Any& rSource ) throw (uno::RuntimeException);
106     /** Returns the VBA implementation object with the specified name. */
107     uno::Any getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException);
108 
109     // XIndexAccess
110     virtual sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException);
111     virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException);
112 
113     // XElementAccess
114     virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException);
115     virtual sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException);
116 
117 protected:
118     /** Derived classes return true, if the passed shape is supported by the instance. */
119     virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const = 0;
120     /** Derived classes create and return a new VBA implementation object for the passed shape. */
121     virtual ScVbaSheetObjectBase* implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) = 0;
122     /** Derived classes return the service name of the UNO shape. */
123     virtual OUString implGetShapeServiceName() const = 0;
124 
125     /** Returns the shape name via 'Name' property of the UNO shape. May be overwritten. */
126     virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException);
127     /** Is called when a new UNO shape has been created but not yet inserted into the drawing page. */
128     virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
129     /** Is called when a new UNO shape has been inserted into the drawing page. */
130     virtual void implOnShapeInserted( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
131 
132 protected:
133     uno::Reference< XHelperInterface > mxParent;
134     uno::Reference< uno::XComponentContext > mxContext;
135     uno::Reference< frame::XModel > mxModel;
136     uno::Reference< lang::XMultiServiceFactory > mxFactory;
137     uno::Reference< drawing::XShapes > mxShapes;
138 
139 private:
140     typedef ::std::vector< uno::Reference< drawing::XShape > > ShapeVector;
141     const uno::Type maVbaType;
142     ShapeVector maShapes;
143 };
144 
145 // ----------------------------------------------------------------------------
146 
ScVbaObjectContainer(const uno::Reference<XHelperInterface> & rxParent,const uno::Reference<uno::XComponentContext> & rxContext,const uno::Reference<frame::XModel> & rxModel,const uno::Reference<sheet::XSpreadsheet> & rxSheet,const uno::Type & rVbaType)147 ScVbaObjectContainer::ScVbaObjectContainer(
148         const uno::Reference< XHelperInterface >& rxParent,
149         const uno::Reference< uno::XComponentContext >& rxContext,
150         const uno::Reference< frame::XModel >& rxModel,
151         const uno::Reference< sheet::XSpreadsheet >& rxSheet,
152         const uno::Type& rVbaType ) throw (uno::RuntimeException) :
153     mxParent( rxParent ),
154     mxContext( rxContext ),
155     mxModel( rxModel, uno::UNO_SET_THROW ),
156     mxFactory( rxModel, uno::UNO_QUERY_THROW ),
157     maVbaType( rVbaType )
158 {
159     uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( rxSheet, uno::UNO_QUERY_THROW );
160     mxShapes.set( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW );
161 }
162 
collectShapes()163 void ScVbaObjectContainer::collectShapes() throw (uno::RuntimeException)
164 {
165     maShapes.clear();
166     for( sal_Int32 nIndex = 0, nCount = mxShapes->getCount(); nIndex < nCount; ++nIndex )
167     {
168         uno::Reference< drawing::XShape > xShape( mxShapes->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
169         if( implPickShape( xShape ) )
170             maShapes.push_back( xShape );
171     }
172 }
173 
createShape(const awt::Point & rPos,const awt::Size & rSize)174 uno::Reference< drawing::XShape > ScVbaObjectContainer::createShape( const awt::Point& rPos, const awt::Size& rSize ) throw (uno::RuntimeException)
175 {
176     uno::Reference< drawing::XShape > xShape( mxFactory->createInstance( implGetShapeServiceName() ), uno::UNO_QUERY_THROW );
177     xShape->setPosition( rPos );
178     xShape->setSize( rSize );
179     implOnShapeCreated( xShape );
180     return xShape;
181 }
182 
insertShape(const uno::Reference<drawing::XShape> & rxShape)183 sal_Int32 ScVbaObjectContainer::insertShape( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException)
184 {
185     mxShapes->add( rxShape );
186     maShapes.push_back( rxShape );
187     implOnShapeInserted( rxShape );
188     return mxShapes->getCount() - 1;
189 }
190 
createVbaObject(const uno::Reference<drawing::XShape> & rxShape)191 ::rtl::Reference< ScVbaSheetObjectBase > ScVbaObjectContainer::createVbaObject(
192     const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException)
193 {
194     return implCreateVbaObject( rxShape );
195 }
196 
createCollectionObject(const uno::Any & rSource)197 uno::Any ScVbaObjectContainer::createCollectionObject( const uno::Any& rSource ) throw (uno::RuntimeException)
198 {
199     uno::Reference< drawing::XShape > xShape( rSource, uno::UNO_QUERY_THROW );
200     uno::Reference< excel::XSheetObject > xSheetObject( implCreateVbaObject( xShape ) );
201     return uno::Any( xSheetObject );
202 }
203 
getItemByStringIndex(const OUString & rIndex)204 uno::Any ScVbaObjectContainer::getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException)
205 {
206     for( ShapeVector::iterator aIt = maShapes.begin(), aEnd = maShapes.end(); aIt != aEnd; ++aIt )
207         if( rIndex == implGetShapeName( *aIt ) )
208             return createCollectionObject( uno::Any( *aIt ) );
209     throw uno::RuntimeException();
210 }
211 
212 // XIndexAccess
213 
getCount()214 sal_Int32 SAL_CALL ScVbaObjectContainer::getCount() throw (uno::RuntimeException)
215 {
216     return static_cast< sal_Int32 >( maShapes.size() );
217 }
218 
getByIndex(sal_Int32 nIndex)219 uno::Any SAL_CALL ScVbaObjectContainer::getByIndex( sal_Int32 nIndex )
220         throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
221 {
222     if( (0 <= nIndex) && (nIndex < getCount()) )
223         return uno::Any( maShapes[ static_cast< size_t >( nIndex ) ] );
224     throw lang::IndexOutOfBoundsException();
225 }
226 
227 // XElementAccess
228 
getElementType()229 uno::Type SAL_CALL ScVbaObjectContainer::getElementType() throw (uno::RuntimeException)
230 {
231     return drawing::XShape::static_type( 0 );
232 }
233 
hasElements()234 sal_Bool SAL_CALL ScVbaObjectContainer::hasElements() throw (uno::RuntimeException)
235 {
236     return !maShapes.empty();
237 }
238 
239 // private
240 
implGetShapeName(const uno::Reference<drawing::XShape> & rxShape) const241 OUString ScVbaObjectContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException)
242 {
243     uno::Reference< beans::XPropertySet > xPropSet( rxShape, uno::UNO_QUERY_THROW );
244     return xPropSet->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >();
245 }
246 
implOnShapeCreated(const uno::Reference<drawing::XShape> &)247 void ScVbaObjectContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& /*rxShape*/ ) throw (uno::RuntimeException)
248 {
249 }
250 
implOnShapeInserted(const uno::Reference<drawing::XShape> &)251 void ScVbaObjectContainer::implOnShapeInserted( const uno::Reference< drawing::XShape >& /*rxShape*/ ) throw (uno::RuntimeException)
252 {
253 }
254 
255 // ============================================================================
256 
257 class ScVbaObjectEnumeration : public SimpleEnumerationBase
258 {
259 public:
260     explicit ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer );
261     virtual uno::Any createCollectionObject( const uno::Any& rSource );
262 
263 private:
264     ScVbaObjectContainerRef mxContainer;
265 };
266 
267 // ----------------------------------------------------------------------------
268 
ScVbaObjectEnumeration(const ScVbaObjectContainerRef & rxContainer)269 ScVbaObjectEnumeration::ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer ) :
270     SimpleEnumerationBase( rxContainer->getParent(), rxContainer->getContext(), rxContainer.get() ),
271     mxContainer( rxContainer )
272 {
273 }
274 
createCollectionObject(const uno::Any & rSource)275 uno::Any ScVbaObjectEnumeration::createCollectionObject( const uno::Any& rSource )
276 {
277     return mxContainer->createCollectionObject( rSource );
278 }
279 
280 // ============================================================================
281 
ScVbaSheetObjectsBase(const ScVbaObjectContainerRef & rxContainer)282 ScVbaSheetObjectsBase::ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException) :
283     ScVbaSheetObjects_BASE( rxContainer->getParent(), rxContainer->getContext(), rxContainer.get() ),
284     mxContainer( rxContainer )
285 {
286     mxContainer->collectShapes();
287 }
288 
~ScVbaSheetObjectsBase()289 ScVbaSheetObjectsBase::~ScVbaSheetObjectsBase()
290 {
291 }
292 
collectShapes()293 void ScVbaSheetObjectsBase::collectShapes() throw (uno::RuntimeException)
294 {
295     mxContainer->collectShapes();
296 }
297 
298 // XEnumerationAccess
299 
createEnumeration()300 uno::Reference< container::XEnumeration > SAL_CALL ScVbaSheetObjectsBase::createEnumeration() throw (uno::RuntimeException)
301 {
302     return new ScVbaObjectEnumeration( mxContainer );
303 }
304 
305 // XElementAccess
306 
getElementType()307 uno::Type SAL_CALL ScVbaSheetObjectsBase::getElementType() throw (uno::RuntimeException)
308 {
309     return mxContainer->getVbaType();
310 }
311 
312 // ScVbaCollectionBase
313 
createCollectionObject(const uno::Any & rSource)314 uno::Any ScVbaSheetObjectsBase::createCollectionObject( const uno::Any& rSource )
315 {
316     return mxContainer->createCollectionObject( rSource );
317 }
318 
getItemByStringIndex(const OUString & rIndex)319 uno::Any ScVbaSheetObjectsBase::getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException)
320 {
321     return mxContainer->getItemByStringIndex( rIndex );
322 }
323 
324 // ============================================================================
325 // Graphic object containers supporting ooo.vba.excel.XGraphicObject
326 // ============================================================================
327 
ScVbaGraphicObjectsBase(const ScVbaObjectContainerRef & rxContainer)328 ScVbaGraphicObjectsBase::ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (uno::RuntimeException) :
329     ScVbaGraphicObjects_BASE( rxContainer )
330 {
331 }
332 
333 // XGraphicObjects
334 
Add(const uno::Any & rLeft,const uno::Any & rTop,const uno::Any & rWidth,const uno::Any & rHeight)335 uno::Any SAL_CALL ScVbaGraphicObjectsBase::Add( const uno::Any& rLeft, const uno::Any& rTop, const uno::Any& rWidth, const uno::Any& rHeight ) throw (uno::RuntimeException)
336 {
337     /*  Extract double values from passed Anys (the lclPointsToHmm() helper
338         function will throw a RuntimeException on any error), and convert from
339         points to 1/100 mm. */
340     awt::Point aPos( lclPointsToHmm( rLeft ), lclPointsToHmm( rTop ) );
341     awt::Size aSize( lclPointsToHmm( rWidth ), lclPointsToHmm( rHeight ) );
342     // TODO: translate coordinates for RTL sheets
343     if( (aPos.X < 0) || (aPos.Y < 0) || (aSize.Width <= 0) || (aSize.Height <= 0) )
344         throw uno::RuntimeException();
345 
346     // create the UNO shape
347     uno::Reference< drawing::XShape > xShape( mxContainer->createShape( aPos, aSize ), uno::UNO_SET_THROW );
348     sal_Int32 nIndex = mxContainer->insertShape( xShape );
349 
350     // create and return the VBA object
351     ::rtl::Reference< ScVbaSheetObjectBase > xVbaObject = mxContainer->createVbaObject( xShape );
352     xVbaObject->setDefaultProperties( nIndex );
353     return uno::Any( uno::Reference< excel::XSheetObject >( xVbaObject.get() ) );
354 }
355 
356 // ============================================================================
357 // Drawing controls
358 // ============================================================================
359 
360 class ScVbaControlContainer : public ScVbaObjectContainer
361 {
362 public:
363     explicit ScVbaControlContainer(
364         const uno::Reference< XHelperInterface >& rxParent,
365         const uno::Reference< uno::XComponentContext >& rxContext,
366         const uno::Reference< frame::XModel >& rxModel,
367         const uno::Reference< sheet::XSpreadsheet >& rxSheet,
368         const uno::Type& rVbaType,
369         const OUString& rModelServiceName,
370         sal_Int16 nComponentType ) throw (uno::RuntimeException);
371 
372 protected:
373     uno::Reference< container::XIndexContainer > createForm() throw (uno::RuntimeException);
374 
375     virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const;
376     virtual OUString implGetShapeServiceName() const;
377     virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const;
378     virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException);
379     virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
380 
381 protected:
382     uno::Reference< container::XIndexContainer > mxFormIC;
383     OUString maModelServiceName;
384     sal_Int16 mnComponentType;
385 };
386 
387 // ----------------------------------------------------------------------------
388 
ScVbaControlContainer(const uno::Reference<XHelperInterface> & rxParent,const uno::Reference<uno::XComponentContext> & rxContext,const uno::Reference<frame::XModel> & rxModel,const uno::Reference<sheet::XSpreadsheet> & rxSheet,const uno::Type & rVbaType,const OUString & rModelServiceName,sal_Int16 nComponentType)389 ScVbaControlContainer::ScVbaControlContainer(
390         const uno::Reference< XHelperInterface >& rxParent,
391         const uno::Reference< uno::XComponentContext >& rxContext,
392         const uno::Reference< frame::XModel >& rxModel,
393         const uno::Reference< sheet::XSpreadsheet >& rxSheet,
394         const uno::Type& rVbaType,
395         const OUString& rModelServiceName,
396         sal_Int16 nComponentType ) throw (uno::RuntimeException) :
397     ScVbaObjectContainer( rxParent, rxContext, rxModel, rxSheet, rVbaType ),
398     maModelServiceName( rModelServiceName ),
399     mnComponentType( nComponentType )
400 {
401 }
402 
createForm()403 uno::Reference< container::XIndexContainer > ScVbaControlContainer::createForm() throw (uno::RuntimeException)
404 {
405     if( !mxFormIC.is() )
406     {
407         uno::Reference< form::XFormsSupplier > xFormsSupp( mxShapes, uno::UNO_QUERY_THROW );
408         uno::Reference< container::XNameContainer > xFormsNC( xFormsSupp->getForms(), uno::UNO_SET_THROW );
409         OUString aFormName = CREATE_OUSTRING( "Standard" );
410         if( xFormsNC->hasByName( aFormName ) )
411         {
412             mxFormIC.set( xFormsNC->getByName( aFormName ), uno::UNO_QUERY_THROW );
413         }
414         else
415         {
416             uno::Reference< form::XForm > xForm( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), uno::UNO_QUERY_THROW );
417             xFormsNC->insertByName( aFormName, uno::Any( xForm ) );
418             mxFormIC.set( xForm, uno::UNO_QUERY_THROW );
419         }
420     }
421     return mxFormIC;
422 }
423 
implPickShape(const uno::Reference<drawing::XShape> & rxShape) const424 bool ScVbaControlContainer::implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const
425 {
426     try
427     {
428         uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
429         uno::Reference< beans::XPropertySet > xModelProps( xControlShape->getControl(), uno::UNO_QUERY_THROW );
430         sal_Int16 nClassId = -1;
431         return lclGetProperty( nClassId, xModelProps, CREATE_OUSTRING( "ClassId" ) ) &&
432             (nClassId == mnComponentType) && implCheckProperties( xModelProps );
433     }
434     catch( uno::Exception& )
435     {
436     }
437     return false;
438 }
439 
implGetShapeServiceName() const440 OUString ScVbaControlContainer::implGetShapeServiceName() const
441 {
442     return CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" );
443 }
444 
implCheckProperties(const uno::Reference<beans::XPropertySet> &) const445 bool ScVbaControlContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& /*rxModelProps*/ ) const
446 {
447     return true;
448 }
449 
implGetShapeName(const uno::Reference<drawing::XShape> & rxShape) const450 OUString ScVbaControlContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException)
451 {
452     uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
453     return uno::Reference< container::XNamed >( xControlShape->getControl(), uno::UNO_QUERY_THROW )->getName();
454 }
455 
implOnShapeCreated(const uno::Reference<drawing::XShape> & rxShape)456 void ScVbaControlContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException)
457 {
458     // passed shape must be a control shape
459     uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
460 
461     // create the UNO control model
462     uno::Reference< form::XFormComponent > xFormComponent( mxFactory->createInstance( maModelServiceName ), uno::UNO_QUERY_THROW );
463     uno::Reference< awt::XControlModel > xControlModel( xFormComponent, uno::UNO_QUERY_THROW );
464 
465     // insert the control model into the form and the shape
466     createForm();
467     mxFormIC->insertByIndex( mxFormIC->getCount(), uno::Any( xFormComponent ) );
468     xControlShape->setControl( xControlModel );
469 }
470 
471 // ============================================================================
472 // Push button
473 // ============================================================================
474 
475 class ScVbaButtonContainer : public ScVbaControlContainer
476 {
477 public:
478     explicit ScVbaButtonContainer(
479         const uno::Reference< XHelperInterface >& rxParent,
480         const uno::Reference< uno::XComponentContext >& rxContext,
481         const uno::Reference< frame::XModel >& rxModel,
482         const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException);
483 
484 protected:
485     virtual ScVbaSheetObjectBase* implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
486     virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const;
487 };
488 
489 // ----------------------------------------------------------------------------
490 
ScVbaButtonContainer(const uno::Reference<XHelperInterface> & rxParent,const uno::Reference<uno::XComponentContext> & rxContext,const uno::Reference<frame::XModel> & rxModel,const uno::Reference<sheet::XSpreadsheet> & rxSheet)491 ScVbaButtonContainer::ScVbaButtonContainer(
492         const uno::Reference< XHelperInterface >& rxParent,
493         const uno::Reference< uno::XComponentContext >& rxContext,
494         const uno::Reference< frame::XModel >& rxModel,
495         const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException) :
496     ScVbaControlContainer(
497         rxParent, rxContext, rxModel, rxSheet,
498         excel::XButton::static_type( 0 ),
499         CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" ),
500         form::FormComponentType::COMMANDBUTTON )
501 {
502 }
503 
implCreateVbaObject(const uno::Reference<drawing::XShape> & rxShape)504 ScVbaSheetObjectBase* ScVbaButtonContainer::implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException)
505 {
506     uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
507     return new ScVbaButton( mxParent, mxContext, mxModel, createForm(), xControlShape );
508 }
509 
implCheckProperties(const uno::Reference<beans::XPropertySet> & rxModelProps) const510 bool ScVbaButtonContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const
511 {
512     // do not insert toggle buttons into the 'Buttons' collection
513     bool bToggle = false;
514     return lclGetProperty( bToggle, rxModelProps, CREATE_OUSTRING( "Toggle" ) ) && !bToggle;
515 }
516 
517 // ============================================================================
518 
ScVbaButtons(const uno::Reference<XHelperInterface> & rxParent,const uno::Reference<uno::XComponentContext> & rxContext,const uno::Reference<frame::XModel> & rxModel,const uno::Reference<sheet::XSpreadsheet> & rxSheet)519 ScVbaButtons::ScVbaButtons(
520         const uno::Reference< XHelperInterface >& rxParent,
521         const uno::Reference< uno::XComponentContext >& rxContext,
522         const uno::Reference< frame::XModel >& rxModel,
523         const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException) :
524     ScVbaGraphicObjectsBase( new ScVbaButtonContainer( rxParent, rxContext, rxModel, rxSheet ) )
525 {
526 }
527 
528 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtons, "ooo.vba.excel.Buttons" )
529 
530 // ============================================================================
531