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 // ============================================================================
41 ScVbaButtonCharacters::ScVbaButtonCharacters(
42 const uno::Reference
< XHelperInterface
>& rxParent
,
43 const uno::Reference
< uno::XComponentContext
>& rxContext
,
44 const uno::Reference
< beans::XPropertySet
>& rxPropSet
,
45 const ScVbaPalette
& rPalette
,
46 const uno::Any
& rStart
,
47 const uno::Any
& rLength
) throw (uno::RuntimeException
) :
48 ScVbaButtonCharacters_BASE( rxParent
, rxContext
),
49 maPalette( rPalette
),
50 mxPropSet( rxPropSet
, uno::UNO_SET_THROW
)
52 // extract optional start parameter (missing or invalid -> from beginning)
53 if( !(rStart
>>= mnStart
) || (mnStart
< 1) )
55 --mnStart
; // VBA is 1-based, rtl string is 0-based
57 // extract optional length parameter (missing or invalid -> to end)
58 if( !(rLength
>>= mnLength
) || (mnLength
< 1) )
59 mnLength
= SAL_MAX_INT32
;
62 ScVbaButtonCharacters::~ScVbaButtonCharacters()
66 // XCharacters attributes
68 OUString SAL_CALL
ScVbaButtonCharacters::getCaption() throw (uno::RuntimeException
)
70 // ignore invalid mnStart and/or mnLength members
71 OUString aString
= getFullString();
72 sal_Int32 nStart
= ::std::min( mnStart
, aString
.getLength() );
73 sal_Int32 nLength
= ::std::min( mnLength
, aString
.getLength() - nStart
);
74 return aString
.copy( nStart
, nLength
);
77 void SAL_CALL
ScVbaButtonCharacters::setCaption( const OUString
& rCaption
) throw (uno::RuntimeException
)
79 /* Replace the covered text with the passed text, ignore invalid mnStart
80 and/or mnLength members. This operation does not affect the mnLength
81 parameter. If the inserted text is longer than mnLength, the additional
82 characters are not covered by this object. If the inserted text is
83 shorter than mnLength, other uncovered characters from the original
84 string will be covered now, thus may be changed with subsequent
86 OUString aString
= getFullString();
87 sal_Int32 nStart
= ::std::min( mnStart
, aString
.getLength() );
88 sal_Int32 nLength
= ::std::min( mnLength
, aString
.getLength() - nStart
);
89 setFullString( aString
.replaceAt( nStart
, nLength
, rCaption
) );
92 sal_Int32 SAL_CALL
ScVbaButtonCharacters::getCount() throw (uno::RuntimeException
)
94 // always return the total length of the caption
95 return getFullString().getLength();
98 OUString SAL_CALL
ScVbaButtonCharacters::getText() throw (uno::RuntimeException
)
100 // Text attribute same as Caption attribute?
104 void SAL_CALL
ScVbaButtonCharacters::setText( const OUString
& rText
) throw (uno::RuntimeException
)
106 // Text attribute same as Caption attribute?
110 uno::Reference
< excel::XFont
> SAL_CALL
ScVbaButtonCharacters::getFont() throw (uno::RuntimeException
)
112 return new ScVbaFont( this, mxContext
, maPalette
, mxPropSet
, 0, true );
115 void SAL_CALL
ScVbaButtonCharacters::setFont( const uno::Reference
< excel::XFont
>& /*rxFont*/ ) throw (uno::RuntimeException
)
120 // XCharacters methods
122 void SAL_CALL
ScVbaButtonCharacters::Insert( const OUString
& rString
) throw (uno::RuntimeException
)
124 /* The Insert() operation is in fact "replace covered characters", at
125 least for buttons... It seems there is no easy way to really insert a
126 substring. This operation does not affect the mnLength parameter. */
127 setCaption( rString
);
130 void SAL_CALL
ScVbaButtonCharacters::Delete() throw (uno::RuntimeException
)
132 /* The Delete() operation is nothing else than "replace with empty string".
133 This does not affect the mnLength parameter, multiple calls of Delete()
134 will remove characters as long as there are some more covered by this
136 setCaption( OUString() );
141 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtonCharacters
, "ooo.vba.excel.Characters" )
145 OUString
ScVbaButtonCharacters::getFullString() const throw (uno::RuntimeException
)
147 return mxPropSet
->getPropertyValue( "Label" ).get
< OUString
>();
150 void ScVbaButtonCharacters::setFullString( const OUString
& rString
) throw (uno::RuntimeException
)
152 mxPropSet
->setPropertyValue( "Label", uno::Any( rString
) );
155 // ============================================================================
157 ScVbaSheetObjectBase::ScVbaSheetObjectBase(
158 const uno::Reference
< XHelperInterface
>& rxParent
,
159 const uno::Reference
< uno::XComponentContext
>& rxContext
,
160 const uno::Reference
< frame::XModel
>& rxModel
,
161 const uno::Reference
< drawing::XShape
>& rxShape
) throw (uno::RuntimeException
) :
162 ScVbaSheetObject_BASE( rxParent
, rxContext
),
163 maPalette( rxModel
),
164 mxModel( rxModel
, uno::UNO_SET_THROW
),
165 mxShape( rxShape
, uno::UNO_SET_THROW
),
166 mxShapeProps( rxShape
, uno::UNO_QUERY_THROW
)
170 // XSheetObject attributes
172 double SAL_CALL
ScVbaSheetObjectBase::getLeft() throw (uno::RuntimeException
)
174 return HmmToPoints( mxShape
->getPosition().X
);
177 void SAL_CALL
ScVbaSheetObjectBase::setLeft( double fLeft
) throw (uno::RuntimeException
)
180 throw uno::RuntimeException();
181 mxShape
->setPosition( awt::Point( PointsToHmm( fLeft
), mxShape
->getPosition().Y
) );
184 double SAL_CALL
ScVbaSheetObjectBase::getTop() throw (uno::RuntimeException
)
186 return HmmToPoints( mxShape
->getPosition().Y
);
189 void SAL_CALL
ScVbaSheetObjectBase::setTop( double fTop
) throw (uno::RuntimeException
)
192 throw uno::RuntimeException();
193 mxShape
->setPosition( awt::Point( mxShape
->getPosition().X
, PointsToHmm( fTop
) ) );
196 double SAL_CALL
ScVbaSheetObjectBase::getWidth() throw (uno::RuntimeException
)
198 return HmmToPoints( mxShape
->getSize().Width
);
201 void SAL_CALL
ScVbaSheetObjectBase::setWidth( double fWidth
) throw (uno::RuntimeException
)
204 throw uno::RuntimeException();
205 mxShape
->setSize( awt::Size( PointsToHmm( fWidth
), mxShape
->getSize().Height
) );
208 double SAL_CALL
ScVbaSheetObjectBase::getHeight() throw (uno::RuntimeException
)
210 return HmmToPoints( mxShape
->getSize().Height
);
213 void SAL_CALL
ScVbaSheetObjectBase::setHeight( double fHeight
) throw (uno::RuntimeException
)
216 throw uno::RuntimeException();
217 mxShape
->setSize( awt::Size( mxShape
->getSize().Width
, PointsToHmm( fHeight
) ) );
220 OUString SAL_CALL
ScVbaSheetObjectBase::getName() throw (uno::RuntimeException
)
222 return mxShapeProps
->getPropertyValue( "Name" ).get
< OUString
>();
225 void SAL_CALL
ScVbaSheetObjectBase::setName( const OUString
& rName
) throw (uno::RuntimeException
)
227 mxShapeProps
->setPropertyValue( "Name", uno::Any( rName
) );
230 sal_Int32 SAL_CALL
ScVbaSheetObjectBase::getPlacement() throw (uno::RuntimeException
)
232 sal_Int32 nRet
= excel::XlPlacement::xlMoveAndSize
;
233 #if 0 // TODO: not working at the moment.
234 SvxShape
* pShape
= SvxShape::getImplementation( mxShape
);
237 SdrObject
* pObj
= pShape
->GetSdrObject();
240 ScAnchorType eType
= ScDrawLayer::GetAnchor(pObj
);
241 if (eType
== SCA_PAGE
)
242 nRet
= excel::XlPlacement::xlFreeFloating
;
249 void SAL_CALL
ScVbaSheetObjectBase::setPlacement( sal_Int32
/*nPlacement*/ ) throw (uno::RuntimeException
)
251 #if 0 // TODO: not working at the moment.
252 SvxShape
* pShape
= SvxShape::getImplementation( mxShape
);
255 SdrObject
* pObj
= pShape
->GetSdrObject();
258 ScAnchorType eType
= SCA_CELL
;
259 if ( nPlacement
== excel::XlPlacement::xlFreeFloating
)
262 // xlMove is not supported, treated as SCA_CELL (xlMoveAndSize)
264 ScDrawLayer::SetAnchor(pObj
, eType
);
270 sal_Bool SAL_CALL
ScVbaSheetObjectBase::getPrintObject() throw (uno::RuntimeException
)
276 void SAL_CALL
ScVbaSheetObjectBase::setPrintObject( sal_Bool
/*bPrintObject*/ ) throw (uno::RuntimeException
)
283 void ScVbaSheetObjectBase::setDefaultProperties( sal_Int32 nIndex
) throw (uno::RuntimeException
)
285 OUString aName
= OUStringBuffer( implGetBaseName() ).append( sal_Unicode( ' ' ) ).append( nIndex
+ 1 ).makeStringAndClear();
287 implSetDefaultProperties();
290 void ScVbaSheetObjectBase::implSetDefaultProperties() throw (uno::RuntimeException
)
294 // ============================================================================
296 ScVbaControlObjectBase::ScVbaControlObjectBase(
297 const uno::Reference
< XHelperInterface
>& rxParent
,
298 const uno::Reference
< uno::XComponentContext
>& rxContext
,
299 const uno::Reference
< frame::XModel
>& rxModel
,
300 const uno::Reference
< container::XIndexContainer
>& rxFormIC
,
301 const uno::Reference
< drawing::XControlShape
>& rxControlShape
,
302 ListenerType eListenerType
) throw (uno::RuntimeException
) :
303 ScVbaControlObject_BASE( rxParent
, rxContext
, rxModel
, uno::Reference
< drawing::XShape
>( rxControlShape
, uno::UNO_QUERY_THROW
) ),
304 mxFormIC( rxFormIC
, uno::UNO_SET_THROW
),
305 mxControlProps( rxControlShape
->getControl(), uno::UNO_QUERY_THROW
)
307 // set listener and event name to be used for OnAction attribute
308 switch( eListenerType
)
310 case LISTENER_ACTION
:
311 maListenerType
= "XActionListener";
312 maEventMethod
= "actionPerformed";
315 maListenerType
= "XMouseListener";
316 maEventMethod
= "mouseReleased";
319 maListenerType
= "XTextListener";
320 maEventMethod
= "textChanged";
323 maListenerType
= "XAdjustmentListener";
324 maEventMethod
= "adjustmentValueChanged";
326 case LISTENER_CHANGE
:
327 maListenerType
= "XChangeListener";
328 maEventMethod
= "changed";
330 // no default, to let the compiler complain about missing case
334 // XSheetObject attributes
336 OUString SAL_CALL
ScVbaControlObjectBase::getName() throw (uno::RuntimeException
)
338 return mxControlProps
->getPropertyValue( "Name" ).get
< OUString
>();
341 void SAL_CALL
ScVbaControlObjectBase::setName( const OUString
& rName
) throw (uno::RuntimeException
)
343 mxControlProps
->setPropertyValue( "Name", uno::Any( rName
) );
346 OUString SAL_CALL
ScVbaControlObjectBase::getOnAction() throw (uno::RuntimeException
)
348 uno::Reference
< script::XEventAttacherManager
> xEventMgr( mxFormIC
, uno::UNO_QUERY_THROW
);
349 sal_Int32 nIndex
= getModelIndexInForm();
350 uno::Sequence
< script::ScriptEventDescriptor
> aEvents
= xEventMgr
->getScriptEvents( nIndex
);
351 if( aEvents
.hasElements() )
353 const script::ScriptEventDescriptor
* pEvent
= aEvents
.getConstArray();
354 const script::ScriptEventDescriptor
* pEventEnd
= pEvent
+ aEvents
.getLength();
355 const OUString aScriptType
= "Script";
356 for( ; pEvent
< pEventEnd
; ++pEvent
)
357 if( (pEvent
->ListenerType
== maListenerType
) && (pEvent
->EventMethod
== maEventMethod
) && (pEvent
->ScriptType
== aScriptType
) )
358 return extractMacroName( pEvent
->ScriptCode
);
363 void SAL_CALL
ScVbaControlObjectBase::setOnAction( const OUString
& rMacroName
) throw (uno::RuntimeException
)
365 uno::Reference
< script::XEventAttacherManager
> xEventMgr( mxFormIC
, uno::UNO_QUERY_THROW
);
366 sal_Int32 nIndex
= getModelIndexInForm();
368 // first, remove a registered event (try/catch just in case implementation throws)
369 try { xEventMgr
->revokeScriptEvent( nIndex
, maListenerType
, maEventMethod
, OUString() ); } catch( uno::Exception
& ) {}
371 // if a macro name has been passed, try to attach it to the event
372 if( !rMacroName
.isEmpty() )
374 MacroResolvedInfo aResolvedMacro
= resolveVBAMacro( getSfxObjShell( mxModel
), rMacroName
);
375 if( !aResolvedMacro
.mbFound
)
376 throw uno::RuntimeException();
377 script::ScriptEventDescriptor aDescriptor
;
378 aDescriptor
.ListenerType
= maListenerType
;
379 aDescriptor
.EventMethod
= maEventMethod
;
380 aDescriptor
.ScriptType
= "Script";
381 aDescriptor
.ScriptCode
= makeMacroURL( aResolvedMacro
.msResolvedMacro
);
382 xEventMgr
->registerScriptEvent( nIndex
, aDescriptor
);
386 sal_Bool SAL_CALL
ScVbaControlObjectBase::getPrintObject() throw (uno::RuntimeException
)
388 return mxControlProps
->getPropertyValue( "Printable" ).get
< sal_Bool
>();
391 void SAL_CALL
ScVbaControlObjectBase::setPrintObject( sal_Bool bPrintObject
) throw (uno::RuntimeException
)
393 mxControlProps
->setPropertyValue( "Printable", uno::Any( bPrintObject
) );
396 // XControlObject attributes
398 sal_Bool SAL_CALL
ScVbaControlObjectBase::getAutoSize() throw (uno::RuntimeException
)
404 void SAL_CALL
ScVbaControlObjectBase::setAutoSize( sal_Bool
/*bAutoSize*/ ) throw (uno::RuntimeException
)
411 sal_Int32
ScVbaControlObjectBase::getModelIndexInForm() const throw (uno::RuntimeException
)
413 for( sal_Int32 nIndex
= 0, nCount
= mxFormIC
->getCount(); nIndex
< nCount
; ++nIndex
)
415 uno::Reference
< beans::XPropertySet
> xProps( mxFormIC
->getByIndex( nIndex
), uno::UNO_QUERY_THROW
);
416 if( mxControlProps
.get() == xProps
.get() )
419 throw uno::RuntimeException();
422 // ============================================================================
424 ScVbaButton::ScVbaButton(
425 const uno::Reference
< XHelperInterface
>& rxParent
,
426 const uno::Reference
< uno::XComponentContext
>& rxContext
,
427 const uno::Reference
< frame::XModel
>& rxModel
,
428 const uno::Reference
< container::XIndexContainer
>& rxFormIC
,
429 const uno::Reference
< drawing::XControlShape
>& rxControlShape
) throw (uno::RuntimeException
) :
430 ScVbaButton_BASE( rxParent
, rxContext
, rxModel
, rxFormIC
, rxControlShape
, LISTENER_ACTION
)
434 // XButton attributes
436 OUString SAL_CALL
ScVbaButton::getCaption() throw (uno::RuntimeException
)
438 return mxControlProps
->getPropertyValue( "Label" ).get
< OUString
>();
441 void SAL_CALL
ScVbaButton::setCaption( const OUString
& rCaption
) throw (uno::RuntimeException
)
443 mxControlProps
->setPropertyValue( "Label", uno::Any( rCaption
) );
446 uno::Reference
< excel::XFont
> SAL_CALL
ScVbaButton::getFont() throw (uno::RuntimeException
)
448 return new ScVbaFont( this, mxContext
, maPalette
, mxControlProps
, 0, true );
451 void SAL_CALL
ScVbaButton::setFont( const uno::Reference
< excel::XFont
>& /*rxFont*/ ) throw (uno::RuntimeException
)
456 sal_Int32 SAL_CALL
ScVbaButton::getHorizontalAlignment() throw (uno::RuntimeException
)
458 switch( mxControlProps
->getPropertyValue( "Align" ).get
< sal_Int16
>() )
460 case awt::TextAlign::LEFT
: return excel::Constants::xlLeft
;
461 case awt::TextAlign::RIGHT
: return excel::Constants::xlRight
;
462 case awt::TextAlign::CENTER
: return excel::Constants::xlCenter
;
464 return excel::Constants::xlCenter
;
467 void SAL_CALL
ScVbaButton::setHorizontalAlignment( sal_Int32 nAlign
) throw (uno::RuntimeException
)
469 sal_Int32 nAwtAlign
= awt::TextAlign::CENTER
;
472 case excel::Constants::xlLeft
: nAwtAlign
= awt::TextAlign::LEFT
; break;
473 case excel::Constants::xlRight
: nAwtAlign
= awt::TextAlign::RIGHT
; break;
474 case excel::Constants::xlCenter
: nAwtAlign
= awt::TextAlign::CENTER
; break;
476 // form controls expect short value
477 mxControlProps
->setPropertyValue( "Align", uno::Any( static_cast< sal_Int16
>( nAwtAlign
) ) );
480 sal_Int32 SAL_CALL
ScVbaButton::getVerticalAlignment() throw (uno::RuntimeException
)
482 switch( mxControlProps
->getPropertyValue( "VerticalAlign" ).get
< style::VerticalAlignment
>() )
484 case style::VerticalAlignment_TOP
: return excel::Constants::xlTop
;
485 case style::VerticalAlignment_BOTTOM
: return excel::Constants::xlBottom
;
486 case style::VerticalAlignment_MIDDLE
: return excel::Constants::xlCenter
;
489 return excel::Constants::xlCenter
;
492 void SAL_CALL
ScVbaButton::setVerticalAlignment( sal_Int32 nAlign
) throw (uno::RuntimeException
)
494 style::VerticalAlignment eAwtAlign
= style::VerticalAlignment_MIDDLE
;
497 case excel::Constants::xlTop
: eAwtAlign
= style::VerticalAlignment_TOP
; break;
498 case excel::Constants::xlBottom
: eAwtAlign
= style::VerticalAlignment_BOTTOM
; break;
499 case excel::Constants::xlCenter
: eAwtAlign
= style::VerticalAlignment_MIDDLE
; break;
501 mxControlProps
->setPropertyValue( "VerticalAlign", uno::Any( eAwtAlign
) );
504 sal_Int32 SAL_CALL
ScVbaButton::getOrientation() throw (uno::RuntimeException
)
507 return excel::XlOrientation::xlHorizontal
;
510 void SAL_CALL
ScVbaButton::setOrientation( sal_Int32
/*nOrientation*/ ) throw (uno::RuntimeException
)
517 uno::Reference
< excel::XCharacters
> SAL_CALL
ScVbaButton::Characters( const uno::Any
& rStart
, const uno::Any
& rLength
) throw (uno::RuntimeException
)
519 return new ScVbaButtonCharacters( this, mxContext
, mxControlProps
, maPalette
, rStart
, rLength
);
524 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButton
, "ooo.vba.excel.Button" )
528 OUString
ScVbaButton::implGetBaseName() const
530 return OUString( "Button" );
533 void ScVbaButton::implSetDefaultProperties() throw (uno::RuntimeException
)
535 setCaption( getName() );
538 // ============================================================================
540 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */