tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / vba / vbasheetobject.cxx
blobf5b84bb5a89ab86f466be847fc2abe4d0d8fcd8b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/beans/XPropertySet.hpp>
23 #include <com/sun/star/container/XIndexContainer.hpp>
24 #include <com/sun/star/drawing/XControlShape.hpp>
25 #include <com/sun/star/frame/XModel.hpp>
26 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
27 #include <com/sun/star/script/XEventAttacherManager.hpp>
28 #include <com/sun/star/style/VerticalAlignment.hpp>
29 #include <comphelper/documentinfo.hxx>
30 #include <o3tl/unit_conversion.hxx>
31 #include <ooo/vba/excel/Constants.hpp>
32 #include <ooo/vba/excel/XlOrientation.hpp>
33 #include <ooo/vba/excel/XlPlacement.hpp>
34 #include <filter/msfilter/msvbahelper.hxx>
35 #include "vbafont.hxx"
37 using namespace ::com::sun::star;
38 using namespace ::ooo::vba;
40 constexpr OUString gaListenerType = u"XActionListener"_ustr;
41 constexpr OUString gaEventMethod = u"actionPerformed"_ustr;
43 static double HmmToPoints(double nHmm)
45 return o3tl::convert(nHmm, o3tl::Length::mm100, o3tl::Length::pt);
48 static sal_Int32 PointsToHmm(double fPoints)
50 return std::round(o3tl::convert(fPoints, o3tl::Length::pt, o3tl::Length::mm100));
53 ScVbaButtonCharacters::ScVbaButtonCharacters(
54 const uno::Reference< XHelperInterface >& rxParent,
55 const uno::Reference< uno::XComponentContext >& rxContext,
56 const uno::Reference< beans::XPropertySet >& rxPropSet,
57 const ScVbaPalette& rPalette,
58 const uno::Any& rStart,
59 const uno::Any& rLength ) :
60 ScVbaButtonCharacters_BASE( rxParent, rxContext ),
61 maPalette( rPalette ),
62 mxPropSet( rxPropSet, uno::UNO_SET_THROW )
64 // extract optional start parameter (missing or invalid -> from beginning)
65 if( !(rStart >>= mnStart) || (mnStart < 1) )
66 mnStart = 1;
67 --mnStart; // VBA is 1-based, rtl string is 0-based
69 // extract optional length parameter (missing or invalid -> to end)
70 if( !(rLength >>= mnLength) || (mnLength < 1) )
71 mnLength = SAL_MAX_INT32;
74 ScVbaButtonCharacters::~ScVbaButtonCharacters()
78 // XCharacters attributes
80 OUString SAL_CALL ScVbaButtonCharacters::getCaption()
82 // ignore invalid mnStart and/or mnLength members
83 OUString aString = getFullString();
84 sal_Int32 nStart = ::std::min( mnStart, aString.getLength() );
85 sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart );
86 return aString.copy( nStart, nLength );
89 void SAL_CALL ScVbaButtonCharacters::setCaption( const OUString& rCaption )
91 /* Replace the covered text with the passed text, ignore invalid mnStart
92 and/or mnLength members. This operation does not affect the mnLength
93 parameter. If the inserted text is longer than mnLength, the additional
94 characters are not covered by this object. If the inserted text is
95 shorter than mnLength, other uncovered characters from the original
96 string will be covered now, thus may be changed with subsequent
97 operations. */
98 OUString aString = getFullString();
99 sal_Int32 nStart = ::std::min( mnStart, aString.getLength() );
100 sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart );
101 setFullString( aString.replaceAt( nStart, nLength, rCaption ) );
104 sal_Int32 SAL_CALL ScVbaButtonCharacters::getCount()
106 // always return the total length of the caption
107 return getFullString().getLength();
110 OUString SAL_CALL ScVbaButtonCharacters::getText()
112 // Text attribute same as Caption attribute?
113 return getCaption();
116 void SAL_CALL ScVbaButtonCharacters::setText( const OUString& rText )
118 // Text attribute same as Caption attribute?
119 setCaption( rText );
122 uno::Reference< excel::XFont > SAL_CALL ScVbaButtonCharacters::getFont()
124 return new ScVbaFont( this, mxContext, maPalette, mxPropSet, nullptr, true );
127 void SAL_CALL ScVbaButtonCharacters::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ )
129 // TODO
132 // XCharacters methods
134 void SAL_CALL ScVbaButtonCharacters::Insert( const OUString& rString )
136 /* The Insert() operation is in fact "replace covered characters", at
137 least for buttons... It seems there is no easy way to really insert a
138 substring. This operation does not affect the mnLength parameter. */
139 setCaption( rString );
142 void SAL_CALL ScVbaButtonCharacters::Delete()
144 /* The Delete() operation is nothing else than "replace with empty string".
145 This does not affect the mnLength parameter, multiple calls of Delete()
146 will remove characters as long as there are some more covered by this
147 object. */
148 setCaption( OUString() );
151 // XHelperInterface
153 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtonCharacters, u"ooo.vba.excel.Characters"_ustr )
155 // private
157 OUString ScVbaButtonCharacters::getFullString() const
159 return mxPropSet->getPropertyValue( u"Label"_ustr ).get< OUString >();
162 void ScVbaButtonCharacters::setFullString( const OUString& rString )
164 mxPropSet->setPropertyValue( u"Label"_ustr, uno::Any( rString ) );
167 ScVbaSheetObjectBase::ScVbaSheetObjectBase(
168 const uno::Reference< XHelperInterface >& rxParent,
169 const uno::Reference< uno::XComponentContext >& rxContext,
170 const uno::Reference< frame::XModel >& rxModel,
171 const uno::Reference< drawing::XShape >& rxShape ) :
172 ScVbaSheetObject_BASE( rxParent, rxContext ),
173 maPalette( rxModel ),
174 mxModel( rxModel, uno::UNO_SET_THROW ),
175 mxShape( rxShape, uno::UNO_SET_THROW ),
176 mxShapeProps( rxShape, uno::UNO_QUERY_THROW )
180 // XSheetObject attributes
182 double SAL_CALL ScVbaSheetObjectBase::getLeft()
184 return HmmToPoints( mxShape->getPosition().X );
187 void SAL_CALL ScVbaSheetObjectBase::setLeft( double fLeft )
189 if( fLeft < 0.0 )
190 throw uno::RuntimeException();
191 mxShape->setPosition( awt::Point( PointsToHmm( fLeft ), mxShape->getPosition().Y ) );
194 double SAL_CALL ScVbaSheetObjectBase::getTop()
196 return HmmToPoints( mxShape->getPosition().Y );
199 void SAL_CALL ScVbaSheetObjectBase::setTop( double fTop )
201 if( fTop < 0.0 )
202 throw uno::RuntimeException();
203 mxShape->setPosition( awt::Point( mxShape->getPosition().X, PointsToHmm( fTop ) ) );
206 double SAL_CALL ScVbaSheetObjectBase::getWidth()
208 return HmmToPoints( mxShape->getSize().Width );
211 void SAL_CALL ScVbaSheetObjectBase::setWidth( double fWidth )
213 if( fWidth <= 0.0 )
214 throw uno::RuntimeException();
215 mxShape->setSize( awt::Size( PointsToHmm( fWidth ), mxShape->getSize().Height ) );
218 double SAL_CALL ScVbaSheetObjectBase::getHeight()
220 return HmmToPoints( mxShape->getSize().Height );
223 void SAL_CALL ScVbaSheetObjectBase::setHeight( double fHeight )
225 if( fHeight <= 0.0 )
226 throw uno::RuntimeException();
227 mxShape->setSize( awt::Size( mxShape->getSize().Width, PointsToHmm( fHeight ) ) );
230 OUString SAL_CALL ScVbaSheetObjectBase::getName()
232 return mxShapeProps->getPropertyValue( u"Name"_ustr ).get< OUString >();
235 void SAL_CALL ScVbaSheetObjectBase::setName( const OUString& rName )
237 mxShapeProps->setPropertyValue( u"Name"_ustr, uno::Any( rName ) );
240 sal_Int32 SAL_CALL ScVbaSheetObjectBase::getPlacement()
242 sal_Int32 const nRet = excel::XlPlacement::xlMoveAndSize;
243 #if 0 // TODO: not working at the moment.
244 SvxShape* pShape = SdrObject::getSdrObjectFromXShape( mxShape );
245 if(pShape)
247 SdrObject* pObj = pShape->GetSdrObject();
248 if (pObj)
250 ScAnchorType eType = ScDrawLayer::GetAnchor(pObj);
251 if (eType == SCA_PAGE)
252 nRet = excel::XlPlacement::xlFreeFloating;
255 #endif
256 return nRet;
259 void SAL_CALL ScVbaSheetObjectBase::setPlacement( sal_Int32 /*nPlacement*/ )
261 #if 0 // TODO: not working at the moment.
262 SvxShape* pShape = SdrObject::getSdrObjectFromXShape( mxShape );
263 if(pShape)
265 SdrObject* pObj = pShape->GetSdrObject();
266 if (pObj)
268 ScAnchorType eType = SCA_CELL;
269 if ( nPlacement == excel::XlPlacement::xlFreeFloating )
270 eType = SCA_PAGE;
272 // xlMove is not supported, treated as SCA_CELL (xlMoveAndSize)
274 ScDrawLayer::SetAnchor(pObj, eType);
277 #endif
280 sal_Bool SAL_CALL ScVbaSheetObjectBase::getPrintObject()
282 // not supported
283 return true;
286 void SAL_CALL ScVbaSheetObjectBase::setPrintObject( sal_Bool /*bPrintObject*/ )
288 // not supported
291 // private
293 void ScVbaSheetObjectBase::setDefaultProperties( sal_Int32 nIndex )
295 OUString aName = implGetBaseName() + OUStringChar(' ') + OUString::number( nIndex + 1 );
296 setName( aName );
297 implSetDefaultProperties();
300 void ScVbaSheetObjectBase::implSetDefaultProperties()
304 ScVbaControlObjectBase::ScVbaControlObjectBase(
305 const uno::Reference< XHelperInterface >& rxParent,
306 const uno::Reference< uno::XComponentContext >& rxContext,
307 const uno::Reference< frame::XModel >& rxModel,
308 const uno::Reference< container::XIndexContainer >& rxFormIC,
309 const uno::Reference< drawing::XControlShape >& rxControlShape ) :
310 ScVbaControlObject_BASE( rxParent, rxContext, rxModel, uno::Reference< drawing::XShape >( rxControlShape, uno::UNO_QUERY_THROW ) ),
311 mxFormIC( rxFormIC, uno::UNO_SET_THROW ),
312 mxControlProps( rxControlShape->getControl(), uno::UNO_QUERY_THROW ),
313 mbNotifyMacroEventRead(false)
317 // XSheetObject attributes
319 OUString SAL_CALL ScVbaControlObjectBase::getName()
321 return mxControlProps->getPropertyValue( u"Name"_ustr ).get< OUString >();
324 void SAL_CALL ScVbaControlObjectBase::setName( const OUString& rName )
326 mxControlProps->setPropertyValue( u"Name"_ustr, uno::Any( rName ) );
329 OUString SAL_CALL ScVbaControlObjectBase::getOnAction()
331 uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW );
332 sal_Int32 nIndex = getModelIndexInForm();
333 const uno::Sequence< script::ScriptEventDescriptor > aEvents = xEventMgr->getScriptEvents( nIndex );
334 if( aEvents.hasElements() )
336 const script::ScriptEventDescriptor* pEvent = std::find_if(aEvents.begin(), aEvents.end(),
337 [](const script::ScriptEventDescriptor& rEvent) {
338 return (rEvent.ListenerType == gaListenerType)
339 && (rEvent.EventMethod == gaEventMethod)
340 && (rEvent.ScriptType == "Script");
342 if (pEvent != aEvents.end())
343 return extractMacroName( pEvent->ScriptCode );
345 return OUString();
348 void ScVbaControlObjectBase::NotifyMacroEventRead()
350 if (mbNotifyMacroEventRead)
351 return;
352 comphelper::DocumentInfo::notifyMacroEventRead(mxModel);
353 mbNotifyMacroEventRead = true;
356 void SAL_CALL ScVbaControlObjectBase::setOnAction( const OUString& rMacroName )
358 uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW );
359 sal_Int32 nIndex = getModelIndexInForm();
361 // first, remove a registered event (try/catch just in case implementation throws)
362 try { xEventMgr->revokeScriptEvent( nIndex, gaListenerType, gaEventMethod, OUString() ); } catch( uno::Exception& ) {}
364 // if a macro name has been passed, try to attach it to the event
365 if( rMacroName.isEmpty() )
366 return;
368 MacroResolvedInfo aResolvedMacro = resolveVBAMacro( getSfxObjShell( mxModel ), rMacroName );
369 if( !aResolvedMacro.mbFound )
370 throw uno::RuntimeException();
371 script::ScriptEventDescriptor aDescriptor;
372 aDescriptor.ListenerType = gaListenerType;
373 aDescriptor.EventMethod = gaEventMethod;
374 aDescriptor.ScriptType = "Script";
375 aDescriptor.ScriptCode = makeMacroURL( aResolvedMacro.msResolvedMacro );
376 NotifyMacroEventRead();
377 xEventMgr->registerScriptEvent( nIndex, aDescriptor );
380 sal_Bool SAL_CALL ScVbaControlObjectBase::getPrintObject()
382 return mxControlProps->getPropertyValue( u"Printable"_ustr ).get<bool>();
385 void SAL_CALL ScVbaControlObjectBase::setPrintObject( sal_Bool bPrintObject )
387 mxControlProps->setPropertyValue( u"Printable"_ustr, uno::Any( bPrintObject ) );
390 // XControlObject attributes
392 sal_Bool SAL_CALL ScVbaControlObjectBase::getAutoSize()
394 // not supported
395 return false;
398 void SAL_CALL ScVbaControlObjectBase::setAutoSize( sal_Bool /*bAutoSize*/ )
400 // not supported
403 // private
405 sal_Int32 ScVbaControlObjectBase::getModelIndexInForm() const
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() )
411 return nIndex;
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 ) :
422 ScVbaButton_BASE( rxParent, rxContext, rxModel, rxFormIC, rxControlShape )
426 // XButton attributes
428 OUString SAL_CALL ScVbaButton::getCaption()
430 return mxControlProps->getPropertyValue( u"Label"_ustr ).get< OUString >();
433 void SAL_CALL ScVbaButton::setCaption( const OUString& rCaption )
435 mxControlProps->setPropertyValue( u"Label"_ustr, uno::Any( rCaption ) );
438 uno::Reference< excel::XFont > SAL_CALL ScVbaButton::getFont()
440 return new ScVbaFont( this, mxContext, maPalette, mxControlProps, nullptr, true );
443 void SAL_CALL ScVbaButton::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ )
445 // TODO
448 sal_Int32 SAL_CALL ScVbaButton::getHorizontalAlignment()
450 switch( mxControlProps->getPropertyValue( u"Align"_ustr ).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 )
461 sal_Int32 nAwtAlign = awt::TextAlign::CENTER;
462 switch( nAlign )
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( u"Align"_ustr, uno::Any( static_cast< sal_Int16 >( nAwtAlign ) ) );
472 sal_Int32 SAL_CALL ScVbaButton::getVerticalAlignment()
474 switch( mxControlProps->getPropertyValue( u"VerticalAlign"_ustr ).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;
479 default:;
481 return excel::Constants::xlCenter;
484 void SAL_CALL ScVbaButton::setVerticalAlignment( sal_Int32 nAlign )
486 style::VerticalAlignment eAwtAlign = style::VerticalAlignment_MIDDLE;
487 switch( nAlign )
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( u"VerticalAlign"_ustr, uno::Any( eAwtAlign ) );
496 sal_Int32 SAL_CALL ScVbaButton::getOrientation()
498 // not supported
499 return excel::XlOrientation::xlHorizontal;
502 void SAL_CALL ScVbaButton::setOrientation( sal_Int32 /*nOrientation*/ )
504 // not supported
507 uno::Any SAL_CALL ScVbaButton::getValue()
509 return mxControlProps->getPropertyValue( u"State"_ustr );
512 void SAL_CALL ScVbaButton::setValue( const uno::Any &nValue )
514 return mxControlProps->setPropertyValue( u"State"_ustr, nValue );
517 OUString SAL_CALL ScVbaButton::getText()
519 return mxControlProps->getPropertyValue( u"Label"_ustr ).get< OUString >();
522 void SAL_CALL ScVbaButton::setText( const OUString &aText )
524 return mxControlProps->setPropertyValue( u"Label"_ustr, uno::Any( aText ) );
527 // XButton methods
529 uno::Reference< excel::XCharacters > SAL_CALL ScVbaButton::Characters( const uno::Any& rStart, const uno::Any& rLength )
531 return new ScVbaButtonCharacters( this, mxContext, mxControlProps, maPalette, rStart, rLength );
534 // XHelperInterface
536 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButton, u"ooo.vba.excel.Button"_ustr )
538 // private
540 OUString ScVbaButton::implGetBaseName() const
542 return u"Button"_ustr;
545 void ScVbaButton::implSetDefaultProperties()
547 setCaption( getName() );
550 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */