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 "vbasheetobject.hxx"
21 #include <com/sun/star/awt/TextAlign.hpp>
22 #include <com/sun/star/container/XIndexContainer.hpp>
23 #include <com/sun/star/drawing/XControlShape.hpp>
24 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
25 #include <com/sun/star/script/XEventAttacherManager.hpp>
26 #include <com/sun/star/style/VerticalAlignment.hpp>
27 #include <ooo/vba/excel/Constants.hpp>
28 #include <ooo/vba/excel/XlOrientation.hpp>
29 #include <ooo/vba/excel/XlPlacement.hpp>
30 #include <rtl/ustrbuf.hxx>
31 #include <filter/msfilter/msvbahelper.hxx>
32 #include <svx/unoshape.hxx>
33 #include "vbafont.hxx"
34 #include "drwlayer.hxx"
36 using namespace ::com::sun::star
;
37 using namespace ::ooo::vba
;
39 ScVbaButtonCharacters::ScVbaButtonCharacters(
40 const uno::Reference
< XHelperInterface
>& rxParent
,
41 const uno::Reference
< uno::XComponentContext
>& rxContext
,
42 const uno::Reference
< beans::XPropertySet
>& rxPropSet
,
43 const ScVbaPalette
& rPalette
,
44 const uno::Any
& rStart
,
45 const uno::Any
& rLength
) throw (uno::RuntimeException
) :
46 ScVbaButtonCharacters_BASE( rxParent
, rxContext
),
47 maPalette( rPalette
),
48 mxPropSet( rxPropSet
, uno::UNO_SET_THROW
)
50 // extract optional start parameter (missing or invalid -> from beginning)
51 if( !(rStart
>>= mnStart
) || (mnStart
< 1) )
53 --mnStart
; // VBA is 1-based, rtl string is 0-based
55 // extract optional length parameter (missing or invalid -> to end)
56 if( !(rLength
>>= mnLength
) || (mnLength
< 1) )
57 mnLength
= SAL_MAX_INT32
;
60 ScVbaButtonCharacters::~ScVbaButtonCharacters()
64 // XCharacters attributes
66 OUString SAL_CALL
ScVbaButtonCharacters::getCaption() throw (uno::RuntimeException
, std::exception
)
68 // ignore invalid mnStart and/or mnLength members
69 OUString aString
= getFullString();
70 sal_Int32 nStart
= ::std::min( mnStart
, aString
.getLength() );
71 sal_Int32 nLength
= ::std::min( mnLength
, aString
.getLength() - nStart
);
72 return aString
.copy( nStart
, nLength
);
75 void SAL_CALL
ScVbaButtonCharacters::setCaption( const OUString
& rCaption
) throw (uno::RuntimeException
, std::exception
)
77 /* Replace the covered text with the passed text, ignore invalid mnStart
78 and/or mnLength members. This operation does not affect the mnLength
79 parameter. If the inserted text is longer than mnLength, the additional
80 characters are not covered by this object. If the inserted text is
81 shorter than mnLength, other uncovered characters from the original
82 string will be covered now, thus may be changed with subsequent
84 OUString aString
= getFullString();
85 sal_Int32 nStart
= ::std::min( mnStart
, aString
.getLength() );
86 sal_Int32 nLength
= ::std::min( mnLength
, aString
.getLength() - nStart
);
87 setFullString( aString
.replaceAt( nStart
, nLength
, rCaption
) );
90 sal_Int32 SAL_CALL
ScVbaButtonCharacters::getCount() throw (uno::RuntimeException
, std::exception
)
92 // always return the total length of the caption
93 return getFullString().getLength();
96 OUString SAL_CALL
ScVbaButtonCharacters::getText() throw (uno::RuntimeException
, std::exception
)
98 // Text attribute same as Caption attribute?
102 void SAL_CALL
ScVbaButtonCharacters::setText( const OUString
& rText
) throw (uno::RuntimeException
, std::exception
)
104 // Text attribute same as Caption attribute?
108 uno::Reference
< excel::XFont
> SAL_CALL
ScVbaButtonCharacters::getFont() throw (uno::RuntimeException
, std::exception
)
110 return new ScVbaFont( this, mxContext
, maPalette
, mxPropSet
, 0, true );
113 void SAL_CALL
ScVbaButtonCharacters::setFont( const uno::Reference
< excel::XFont
>& /*rxFont*/ ) throw (uno::RuntimeException
, std::exception
)
118 // XCharacters methods
120 void SAL_CALL
ScVbaButtonCharacters::Insert( const OUString
& rString
) throw (uno::RuntimeException
, std::exception
)
122 /* The Insert() operation is in fact "replace covered characters", at
123 least for buttons... It seems there is no easy way to really insert a
124 substring. This operation does not affect the mnLength parameter. */
125 setCaption( rString
);
128 void SAL_CALL
ScVbaButtonCharacters::Delete() throw (uno::RuntimeException
, std::exception
)
130 /* The Delete() operation is nothing else than "replace with empty string".
131 This does not affect the mnLength parameter, multiple calls of Delete()
132 will remove characters as long as there are some more covered by this
134 setCaption( OUString() );
139 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtonCharacters
, "ooo.vba.excel.Characters" )
143 OUString
ScVbaButtonCharacters::getFullString() const throw (uno::RuntimeException
)
145 return mxPropSet
->getPropertyValue( "Label" ).get
< OUString
>();
148 void ScVbaButtonCharacters::setFullString( const OUString
& rString
) throw (uno::RuntimeException
)
150 mxPropSet
->setPropertyValue( "Label", uno::Any( rString
) );
153 ScVbaSheetObjectBase::ScVbaSheetObjectBase(
154 const uno::Reference
< XHelperInterface
>& rxParent
,
155 const uno::Reference
< uno::XComponentContext
>& rxContext
,
156 const uno::Reference
< frame::XModel
>& rxModel
,
157 const uno::Reference
< drawing::XShape
>& rxShape
) throw (uno::RuntimeException
) :
158 ScVbaSheetObject_BASE( rxParent
, rxContext
),
159 maPalette( rxModel
),
160 mxModel( rxModel
, uno::UNO_SET_THROW
),
161 mxShape( rxShape
, uno::UNO_SET_THROW
),
162 mxShapeProps( rxShape
, uno::UNO_QUERY_THROW
)
166 // XSheetObject attributes
168 double SAL_CALL
ScVbaSheetObjectBase::getLeft() throw (uno::RuntimeException
, std::exception
)
170 return HmmToPoints( mxShape
->getPosition().X
);
173 void SAL_CALL
ScVbaSheetObjectBase::setLeft( double fLeft
) throw (uno::RuntimeException
, std::exception
)
176 throw uno::RuntimeException();
177 mxShape
->setPosition( awt::Point( PointsToHmm( fLeft
), mxShape
->getPosition().Y
) );
180 double SAL_CALL
ScVbaSheetObjectBase::getTop() throw (uno::RuntimeException
, std::exception
)
182 return HmmToPoints( mxShape
->getPosition().Y
);
185 void SAL_CALL
ScVbaSheetObjectBase::setTop( double fTop
) throw (uno::RuntimeException
, std::exception
)
188 throw uno::RuntimeException();
189 mxShape
->setPosition( awt::Point( mxShape
->getPosition().X
, PointsToHmm( fTop
) ) );
192 double SAL_CALL
ScVbaSheetObjectBase::getWidth() throw (uno::RuntimeException
, std::exception
)
194 return HmmToPoints( mxShape
->getSize().Width
);
197 void SAL_CALL
ScVbaSheetObjectBase::setWidth( double fWidth
) throw (uno::RuntimeException
, std::exception
)
200 throw uno::RuntimeException();
201 mxShape
->setSize( awt::Size( PointsToHmm( fWidth
), mxShape
->getSize().Height
) );
204 double SAL_CALL
ScVbaSheetObjectBase::getHeight() throw (uno::RuntimeException
, std::exception
)
206 return HmmToPoints( mxShape
->getSize().Height
);
209 void SAL_CALL
ScVbaSheetObjectBase::setHeight( double fHeight
) throw (uno::RuntimeException
, std::exception
)
212 throw uno::RuntimeException();
213 mxShape
->setSize( awt::Size( mxShape
->getSize().Width
, PointsToHmm( fHeight
) ) );
216 OUString SAL_CALL
ScVbaSheetObjectBase::getName() throw (uno::RuntimeException
, std::exception
)
218 return mxShapeProps
->getPropertyValue( "Name" ).get
< OUString
>();
221 void SAL_CALL
ScVbaSheetObjectBase::setName( const OUString
& rName
) throw (uno::RuntimeException
, std::exception
)
223 mxShapeProps
->setPropertyValue( "Name", uno::Any( rName
) );
226 sal_Int32 SAL_CALL
ScVbaSheetObjectBase::getPlacement() throw (uno::RuntimeException
, std::exception
)
228 sal_Int32 nRet
= excel::XlPlacement::xlMoveAndSize
;
229 #if 0 // TODO: not working at the moment.
230 SvxShape
* pShape
= SvxShape::getImplementation( mxShape
);
233 SdrObject
* pObj
= pShape
->GetSdrObject();
236 ScAnchorType eType
= ScDrawLayer::GetAnchor(pObj
);
237 if (eType
== SCA_PAGE
)
238 nRet
= excel::XlPlacement::xlFreeFloating
;
245 void SAL_CALL
ScVbaSheetObjectBase::setPlacement( sal_Int32
/*nPlacement*/ ) throw (uno::RuntimeException
, std::exception
)
247 #if 0 // TODO: not working at the moment.
248 SvxShape
* pShape
= SvxShape::getImplementation( mxShape
);
251 SdrObject
* pObj
= pShape
->GetSdrObject();
254 ScAnchorType eType
= SCA_CELL
;
255 if ( nPlacement
== excel::XlPlacement::xlFreeFloating
)
258 // xlMove is not supported, treated as SCA_CELL (xlMoveAndSize)
260 ScDrawLayer::SetAnchor(pObj
, eType
);
266 sal_Bool SAL_CALL
ScVbaSheetObjectBase::getPrintObject() throw (uno::RuntimeException
, std::exception
)
272 void SAL_CALL
ScVbaSheetObjectBase::setPrintObject( sal_Bool
/*bPrintObject*/ ) throw (uno::RuntimeException
, std::exception
)
279 void ScVbaSheetObjectBase::setDefaultProperties( sal_Int32 nIndex
) throw (uno::RuntimeException
)
281 OUString aName
= OUStringBuffer( implGetBaseName() ).append( ' ' ).append( nIndex
+ 1 ).makeStringAndClear();
283 implSetDefaultProperties();
286 void ScVbaSheetObjectBase::implSetDefaultProperties() throw (uno::RuntimeException
)
290 ScVbaControlObjectBase::ScVbaControlObjectBase(
291 const uno::Reference
< XHelperInterface
>& rxParent
,
292 const uno::Reference
< uno::XComponentContext
>& rxContext
,
293 const uno::Reference
< frame::XModel
>& rxModel
,
294 const uno::Reference
< container::XIndexContainer
>& rxFormIC
,
295 const uno::Reference
< drawing::XControlShape
>& rxControlShape
,
296 ListenerType eListenerType
) throw (uno::RuntimeException
) :
297 ScVbaControlObject_BASE( rxParent
, rxContext
, rxModel
, uno::Reference
< drawing::XShape
>( rxControlShape
, uno::UNO_QUERY_THROW
) ),
298 mxFormIC( rxFormIC
, uno::UNO_SET_THROW
),
299 mxControlProps( rxControlShape
->getControl(), uno::UNO_QUERY_THROW
)
301 // set listener and event name to be used for OnAction attribute
302 switch( eListenerType
)
304 case LISTENER_ACTION
:
305 maListenerType
= "XActionListener";
306 maEventMethod
= "actionPerformed";
309 maListenerType
= "XMouseListener";
310 maEventMethod
= "mouseReleased";
313 maListenerType
= "XTextListener";
314 maEventMethod
= "textChanged";
317 maListenerType
= "XAdjustmentListener";
318 maEventMethod
= "adjustmentValueChanged";
320 case LISTENER_CHANGE
:
321 maListenerType
= "XChangeListener";
322 maEventMethod
= "changed";
324 // no default, to let the compiler complain about missing case
328 // XSheetObject attributes
330 OUString SAL_CALL
ScVbaControlObjectBase::getName() throw (uno::RuntimeException
, std::exception
)
332 return mxControlProps
->getPropertyValue( "Name" ).get
< OUString
>();
335 void SAL_CALL
ScVbaControlObjectBase::setName( const OUString
& rName
) throw (uno::RuntimeException
, std::exception
)
337 mxControlProps
->setPropertyValue( "Name", uno::Any( rName
) );
340 OUString SAL_CALL
ScVbaControlObjectBase::getOnAction() throw (uno::RuntimeException
, std::exception
)
342 uno::Reference
< script::XEventAttacherManager
> xEventMgr( mxFormIC
, uno::UNO_QUERY_THROW
);
343 sal_Int32 nIndex
= getModelIndexInForm();
344 uno::Sequence
< script::ScriptEventDescriptor
> aEvents
= xEventMgr
->getScriptEvents( nIndex
);
345 if( aEvents
.hasElements() )
347 const script::ScriptEventDescriptor
* pEvent
= aEvents
.getConstArray();
348 const script::ScriptEventDescriptor
* pEventEnd
= pEvent
+ aEvents
.getLength();
349 const OUString aScriptType
= "Script";
350 for( ; pEvent
< pEventEnd
; ++pEvent
)
351 if( (pEvent
->ListenerType
== maListenerType
) && (pEvent
->EventMethod
== maEventMethod
) && (pEvent
->ScriptType
== aScriptType
) )
352 return extractMacroName( pEvent
->ScriptCode
);
357 void SAL_CALL
ScVbaControlObjectBase::setOnAction( const OUString
& rMacroName
) throw (uno::RuntimeException
, std::exception
)
359 uno::Reference
< script::XEventAttacherManager
> xEventMgr( mxFormIC
, uno::UNO_QUERY_THROW
);
360 sal_Int32 nIndex
= getModelIndexInForm();
362 // first, remove a registered event (try/catch just in case implementation throws)
363 try { xEventMgr
->revokeScriptEvent( nIndex
, maListenerType
, maEventMethod
, OUString() ); } catch( uno::Exception
& ) {}
365 // if a macro name has been passed, try to attach it to the event
366 if( !rMacroName
.isEmpty() )
368 MacroResolvedInfo aResolvedMacro
= resolveVBAMacro( getSfxObjShell( mxModel
), rMacroName
);
369 if( !aResolvedMacro
.mbFound
)
370 throw uno::RuntimeException();
371 script::ScriptEventDescriptor aDescriptor
;
372 aDescriptor
.ListenerType
= maListenerType
;
373 aDescriptor
.EventMethod
= maEventMethod
;
374 aDescriptor
.ScriptType
= "Script";
375 aDescriptor
.ScriptCode
= makeMacroURL( aResolvedMacro
.msResolvedMacro
);
376 xEventMgr
->registerScriptEvent( nIndex
, aDescriptor
);
380 sal_Bool SAL_CALL
ScVbaControlObjectBase::getPrintObject() throw (uno::RuntimeException
, std::exception
)
382 return mxControlProps
->getPropertyValue( "Printable" ).get
< sal_Bool
>();
385 void SAL_CALL
ScVbaControlObjectBase::setPrintObject( sal_Bool bPrintObject
) throw (uno::RuntimeException
, std::exception
)
387 mxControlProps
->setPropertyValue( "Printable", uno::Any( bPrintObject
) );
390 // XControlObject attributes
392 sal_Bool SAL_CALL
ScVbaControlObjectBase::getAutoSize() throw (uno::RuntimeException
, std::exception
)
398 void SAL_CALL
ScVbaControlObjectBase::setAutoSize( sal_Bool
/*bAutoSize*/ ) throw (uno::RuntimeException
, std::exception
)
405 sal_Int32
ScVbaControlObjectBase::getModelIndexInForm() const throw (uno::RuntimeException
)
407 for( sal_Int32 nIndex
= 0, nCount
= mxFormIC
->getCount(); nIndex
< nCount
; ++nIndex
)
409 uno::Reference
< beans::XPropertySet
> xProps( mxFormIC
->getByIndex( nIndex
), uno::UNO_QUERY_THROW
);
410 if( mxControlProps
.get() == xProps
.get() )
413 throw uno::RuntimeException();
416 ScVbaButton::ScVbaButton(
417 const uno::Reference
< XHelperInterface
>& rxParent
,
418 const uno::Reference
< uno::XComponentContext
>& rxContext
,
419 const uno::Reference
< frame::XModel
>& rxModel
,
420 const uno::Reference
< container::XIndexContainer
>& rxFormIC
,
421 const uno::Reference
< drawing::XControlShape
>& rxControlShape
) throw (uno::RuntimeException
) :
422 ScVbaButton_BASE( rxParent
, rxContext
, rxModel
, rxFormIC
, rxControlShape
, LISTENER_ACTION
)
426 // XButton attributes
428 OUString SAL_CALL
ScVbaButton::getCaption() throw (uno::RuntimeException
, std::exception
)
430 return mxControlProps
->getPropertyValue( "Label" ).get
< OUString
>();
433 void SAL_CALL
ScVbaButton::setCaption( const OUString
& rCaption
) throw (uno::RuntimeException
, std::exception
)
435 mxControlProps
->setPropertyValue( "Label", uno::Any( rCaption
) );
438 uno::Reference
< excel::XFont
> SAL_CALL
ScVbaButton::getFont() throw (uno::RuntimeException
, std::exception
)
440 return new ScVbaFont( this, mxContext
, maPalette
, mxControlProps
, 0, true );
443 void SAL_CALL
ScVbaButton::setFont( const uno::Reference
< excel::XFont
>& /*rxFont*/ ) throw (uno::RuntimeException
, std::exception
)
448 sal_Int32 SAL_CALL
ScVbaButton::getHorizontalAlignment() throw (uno::RuntimeException
, std::exception
)
450 switch( mxControlProps
->getPropertyValue( "Align" ).get
< sal_Int16
>() )
452 case awt::TextAlign::LEFT
: return excel::Constants::xlLeft
;
453 case awt::TextAlign::RIGHT
: return excel::Constants::xlRight
;
454 case awt::TextAlign::CENTER
: return excel::Constants::xlCenter
;
456 return excel::Constants::xlCenter
;
459 void SAL_CALL
ScVbaButton::setHorizontalAlignment( sal_Int32 nAlign
) throw (uno::RuntimeException
, std::exception
)
461 sal_Int32 nAwtAlign
= awt::TextAlign::CENTER
;
464 case excel::Constants::xlLeft
: nAwtAlign
= awt::TextAlign::LEFT
; break;
465 case excel::Constants::xlRight
: nAwtAlign
= awt::TextAlign::RIGHT
; break;
466 case excel::Constants::xlCenter
: nAwtAlign
= awt::TextAlign::CENTER
; break;
468 // form controls expect short value
469 mxControlProps
->setPropertyValue( "Align", uno::Any( static_cast< sal_Int16
>( nAwtAlign
) ) );
472 sal_Int32 SAL_CALL
ScVbaButton::getVerticalAlignment() throw (uno::RuntimeException
, std::exception
)
474 switch( mxControlProps
->getPropertyValue( "VerticalAlign" ).get
< style::VerticalAlignment
>() )
476 case style::VerticalAlignment_TOP
: return excel::Constants::xlTop
;
477 case style::VerticalAlignment_BOTTOM
: return excel::Constants::xlBottom
;
478 case style::VerticalAlignment_MIDDLE
: return excel::Constants::xlCenter
;
481 return excel::Constants::xlCenter
;
484 void SAL_CALL
ScVbaButton::setVerticalAlignment( sal_Int32 nAlign
) throw (uno::RuntimeException
, std::exception
)
486 style::VerticalAlignment eAwtAlign
= style::VerticalAlignment_MIDDLE
;
489 case excel::Constants::xlTop
: eAwtAlign
= style::VerticalAlignment_TOP
; break;
490 case excel::Constants::xlBottom
: eAwtAlign
= style::VerticalAlignment_BOTTOM
; break;
491 case excel::Constants::xlCenter
: eAwtAlign
= style::VerticalAlignment_MIDDLE
; break;
493 mxControlProps
->setPropertyValue( "VerticalAlign", uno::Any( eAwtAlign
) );
496 sal_Int32 SAL_CALL
ScVbaButton::getOrientation() throw (uno::RuntimeException
, std::exception
)
499 return excel::XlOrientation::xlHorizontal
;
502 void SAL_CALL
ScVbaButton::setOrientation( sal_Int32
/*nOrientation*/ ) throw (uno::RuntimeException
, std::exception
)
509 uno::Reference
< excel::XCharacters
> SAL_CALL
ScVbaButton::Characters( const uno::Any
& rStart
, const uno::Any
& rLength
) throw (uno::RuntimeException
, std::exception
)
511 return new ScVbaButtonCharacters( this, mxContext
, mxControlProps
, maPalette
, rStart
, rLength
);
516 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButton
, "ooo.vba.excel.Button" )
520 OUString
ScVbaButton::implGetBaseName() const
522 return OUString( "Button" );
525 void ScVbaButton::implSetDefaultProperties() throw (uno::RuntimeException
)
527 setCaption( getName() );
530 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */