1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "vbalistbox.hxx" 29 #include "vbanewfont.hxx" 30 #include <comphelper/anytostring.hxx> 31 #include <com/sun/star/script/ArrayWrapper.hpp> 32 #include <com/sun/star/form/validation/XValidatableFormComponent.hpp> 33 34 using namespace com::sun::star; 35 using namespace ooo::vba; 36 37 const static rtl::OUString TEXT( RTL_CONSTASCII_USTRINGPARAM("Text") ); 38 const static rtl::OUString SELECTEDITEMS( RTL_CONSTASCII_USTRINGPARAM("SelectedItems") ); 39 const static rtl::OUString ITEMS( RTL_CONSTASCII_USTRINGPARAM("StringItemList") ); 40 41 42 ScVbaListBox::ScVbaListBox( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< css::uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, AbstractGeometryAttributes* pGeomHelper ) : ListBoxImpl_BASE( xParent, xContext, xControl, xModel, pGeomHelper ) 43 { 44 mpListHelper.reset( new ListControlHelper( m_xProps ) ); 45 } 46 47 // Attributes 48 void SAL_CALL 49 ScVbaListBox::setListIndex( const uno::Any& _value ) throw (uno::RuntimeException) 50 { 51 sal_Int32 nIndex = 0; 52 _value >>= nIndex; 53 uno::Reference< XPropValue > xPropVal( Selected( nIndex ), uno::UNO_QUERY_THROW ); 54 xPropVal->setValue( uno::makeAny( sal_True ) ); 55 } 56 57 uno::Any SAL_CALL 58 ScVbaListBox::getListIndex() throw (uno::RuntimeException) 59 { 60 uno::Sequence< sal_Int16 > sSelection; 61 m_xProps->getPropertyValue( SELECTEDITEMS ) >>= sSelection; 62 if ( sSelection.getLength() == 0 ) 63 return uno::Any( sal_Int32( -1 ) ); 64 return uno::Any( sSelection[ 0 ] ); 65 } 66 67 uno::Any SAL_CALL 68 ScVbaListBox::getValue() throw (uno::RuntimeException) 69 { 70 uno::Sequence< sal_Int16 > sSelection; 71 uno::Sequence< rtl::OUString > sItems; 72 m_xProps->getPropertyValue( SELECTEDITEMS ) >>= sSelection; 73 m_xProps->getPropertyValue( ITEMS ) >>= sItems; 74 if( getMultiSelect() ) 75 throw uno::RuntimeException( rtl::OUString::createFromAscii( 76 "Attribute use invalid." ), uno::Reference< uno::XInterface >() ); 77 uno::Any aRet; 78 if ( sSelection.getLength() ) 79 aRet = uno::makeAny( sItems[ sSelection[ 0 ] ] ); 80 return aRet; 81 } 82 83 void SAL_CALL 84 ScVbaListBox::setValue( const uno::Any& _value ) throw (uno::RuntimeException) 85 { 86 if( getMultiSelect() ) 87 { 88 throw uno::RuntimeException( rtl::OUString::createFromAscii( 89 "Attribute use invalid." ), uno::Reference< uno::XInterface >() ); 90 } 91 rtl::OUString sValue = getAnyAsString( _value ); 92 uno::Sequence< rtl::OUString > sList; 93 m_xProps->getPropertyValue( ITEMS ) >>= sList; 94 uno::Sequence< sal_Int16 > nList; 95 sal_Int16 nLength = static_cast<sal_Int16>( sList.getLength() ); 96 sal_Int16 nValue = -1; 97 sal_Int16 i = 0; 98 for( i = 0; i < nLength; i++ ) 99 { 100 if( sList[i].equals( sValue ) ) 101 { 102 nValue = i; 103 break; 104 } 105 } 106 if( nValue == -1 ) 107 throw uno::RuntimeException( rtl::OUString::createFromAscii( 108 "Attribute use invalid." ), uno::Reference< uno::XInterface >() ); 109 110 uno::Sequence< sal_Int16 > nSelectedIndices(1); 111 nSelectedIndices[ 0 ] = nValue; 112 m_xProps->setPropertyValue( SELECTEDITEMS, uno::makeAny( nSelectedIndices ) ); 113 m_xProps->setPropertyValue( TEXT, uno::makeAny( sValue ) ); 114 } 115 116 ::rtl::OUString SAL_CALL 117 ScVbaListBox::getText() throw (uno::RuntimeException) 118 { 119 rtl::OUString result; 120 getValue() >>= result; 121 return result; 122 } 123 124 void SAL_CALL 125 ScVbaListBox::setText( const ::rtl::OUString& _text ) throw (uno::RuntimeException) 126 { 127 setValue( uno::makeAny( _text ) ); // seems the same 128 } 129 130 sal_Bool SAL_CALL 131 ScVbaListBox::getMultiSelect() throw (css::uno::RuntimeException) 132 { 133 sal_Bool bMultiSelect = sal_False; 134 m_xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiSelection" ) ) ) >>= bMultiSelect; 135 return bMultiSelect; 136 } 137 138 void SAL_CALL 139 ScVbaListBox::setMultiSelect( sal_Bool _multiselect ) throw (css::uno::RuntimeException) 140 { 141 m_xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiSelection" ) ), uno::makeAny( _multiselect ) ); 142 } 143 144 css::uno::Any SAL_CALL 145 ScVbaListBox::Selected( sal_Int32 index ) throw (css::uno::RuntimeException) 146 { 147 uno::Sequence< rtl::OUString > sList; 148 m_xProps->getPropertyValue( ITEMS ) >>= sList; 149 sal_Int16 nLength = static_cast< sal_Int16 >( sList.getLength() ); 150 // no choice but to do a horror cast as internally 151 // the indices are but sal_Int16 152 sal_Int16 nIndex = static_cast< sal_Int16 >( index ); 153 if( nIndex < 0 || nIndex >= nLength ) 154 throw uno::RuntimeException( rtl::OUString::createFromAscii( 155 "Error Number." ), uno::Reference< uno::XInterface >() ); 156 m_nIndex = nIndex; 157 return uno::makeAny( uno::Reference< XPropValue > ( new ScVbaPropValue( this ) ) ); 158 } 159 160 // Methods 161 void SAL_CALL 162 ScVbaListBox::AddItem( const uno::Any& pvargItem, const uno::Any& pvargIndex ) throw (uno::RuntimeException) 163 { 164 mpListHelper->AddItem( pvargItem, pvargIndex ); 165 } 166 167 void SAL_CALL 168 ScVbaListBox::removeItem( const uno::Any& index ) throw (uno::RuntimeException) 169 { 170 mpListHelper->removeItem( index ); 171 } 172 173 void SAL_CALL 174 ScVbaListBox::Clear( ) throw (uno::RuntimeException) 175 { 176 mpListHelper->Clear(); 177 } 178 179 // this is called when something like the following vba code is used 180 // to set the selected state of particular entries in the Listbox 181 // ListBox1.Selected( 3 ) = false 182 //PropListener 183 void 184 ScVbaListBox::setValueEvent( const uno::Any& value ) 185 { 186 sal_Bool bValue = sal_False; 187 if( !(value >>= bValue) ) 188 throw uno::RuntimeException( rtl::OUString::createFromAscii( 189 "Invalid type\n. need boolean." ), uno::Reference< uno::XInterface >() ); 190 uno::Sequence< sal_Int16 > nList; 191 m_xProps->getPropertyValue( SELECTEDITEMS ) >>= nList; 192 sal_Int16 nLength = static_cast<sal_Int16>( nList.getLength() ); 193 sal_Int16 nIndex = m_nIndex; 194 for( sal_Int16 i = 0; i < nLength; i++ ) 195 { 196 if( nList[i] == nIndex ) 197 { 198 if( bValue ) 199 return; 200 else 201 { 202 for( ; i < nLength - 1; i++ ) 203 { 204 nList[i] = nList[i + 1]; 205 } 206 nList.realloc( nLength - 1 ); 207 //m_xProps->setPropertyValue( sSourceName, uno::makeAny( nList ) ); 208 m_xProps->setPropertyValue( SELECTEDITEMS, uno::makeAny( nList ) ); 209 return; 210 } 211 } 212 } 213 if( bValue ) 214 { 215 if( getMultiSelect() ) 216 { 217 nList.realloc( nLength + 1 ); 218 nList[nLength] = nIndex; 219 } 220 else 221 { 222 nList.realloc( 1 ); 223 nList[0] = nIndex; 224 } 225 //m_xProps->setPropertyValue( sSourceName, uno::makeAny( nList ) ); 226 m_xProps->setPropertyValue( SELECTEDITEMS, uno::makeAny( nList ) ); 227 } 228 } 229 230 // this is called when something like the following vba code is used 231 // to determine the selected state of particular entries in the Listbox 232 // msgbox ListBox1.Selected( 3 ) 233 234 css::uno::Any 235 ScVbaListBox::getValueEvent() 236 { 237 uno::Sequence< sal_Int16 > nList; 238 m_xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectedItems" ) ) ) >>= nList; 239 sal_Int32 nLength = nList.getLength(); 240 sal_Int32 nIndex = m_nIndex; 241 242 for( sal_Int32 i = 0; i < nLength; i++ ) 243 { 244 if( nList[i] == nIndex ) 245 return uno::makeAny( sal_True ); 246 } 247 248 return uno::makeAny( sal_False ); 249 } 250 251 void SAL_CALL 252 ScVbaListBox::setRowSource( const rtl::OUString& _rowsource ) throw (uno::RuntimeException) 253 { 254 ScVbaControl::setRowSource( _rowsource ); 255 mpListHelper->setRowSource( _rowsource ); 256 } 257 258 sal_Int32 SAL_CALL 259 ScVbaListBox::getListCount() throw (uno::RuntimeException) 260 { 261 return mpListHelper->getListCount(); 262 } 263 264 uno::Any SAL_CALL 265 ScVbaListBox::List( const ::uno::Any& pvargIndex, const uno::Any& pvarColumn ) throw (uno::RuntimeException) 266 { 267 return mpListHelper->List( pvargIndex, pvarColumn ); 268 } 269 270 uno::Reference< msforms::XNewFont > SAL_CALL ScVbaListBox::getFont() throw (uno::RuntimeException) 271 { 272 return new VbaNewFont( this, mxContext, m_xProps ); 273 } 274 275 rtl::OUString& 276 ScVbaListBox::getServiceImplName() 277 { 278 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaListBox") ); 279 return sImplName; 280 } 281 282 uno::Sequence< rtl::OUString > 283 ScVbaListBox::getServiceNames() 284 { 285 static uno::Sequence< rtl::OUString > aServiceNames; 286 if ( aServiceNames.getLength() == 0 ) 287 { 288 aServiceNames.realloc( 1 ); 289 aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.msforms.ScVbaListBox" ) ); 290 } 291 return aServiceNames; 292 } 293