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 "vbalistbox.hxx" 25 #include "vbanewfont.hxx" 26 #include <comphelper/anytostring.hxx> 27 #include <com/sun/star/script/ArrayWrapper.hpp> 28 #include <com/sun/star/form/validation/XValidatableFormComponent.hpp> 29 30 using namespace com::sun::star; 31 using namespace ooo::vba; 32 33 const static rtl::OUString TEXT( RTL_CONSTASCII_USTRINGPARAM("Text") ); 34 const static rtl::OUString SELECTEDITEMS( RTL_CONSTASCII_USTRINGPARAM("SelectedItems") ); 35 const static rtl::OUString ITEMS( RTL_CONSTASCII_USTRINGPARAM("StringItemList") ); 36 37 38 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 ) 39 { 40 mpListHelper.reset( new ListControlHelper( m_xProps ) ); 41 } 42 43 // Attributes 44 void SAL_CALL 45 ScVbaListBox::setListIndex( const uno::Any& _value ) throw (uno::RuntimeException) 46 { 47 sal_Int32 nIndex = 0; 48 _value >>= nIndex; 49 uno::Reference< XPropValue > xPropVal( Selected( nIndex ), uno::UNO_QUERY_THROW ); 50 xPropVal->setValue( uno::makeAny( sal_True ) ); 51 } 52 53 uno::Any SAL_CALL 54 ScVbaListBox::getListIndex() throw (uno::RuntimeException) 55 { 56 uno::Sequence< sal_Int16 > sSelection; 57 m_xProps->getPropertyValue( SELECTEDITEMS ) >>= sSelection; 58 if ( sSelection.getLength() == 0 ) 59 return uno::Any( sal_Int32( -1 ) ); 60 return uno::Any( sSelection[ 0 ] ); 61 } 62 63 uno::Any SAL_CALL 64 ScVbaListBox::getValue() throw (uno::RuntimeException) 65 { 66 uno::Sequence< sal_Int16 > sSelection; 67 uno::Sequence< rtl::OUString > sItems; 68 m_xProps->getPropertyValue( SELECTEDITEMS ) >>= sSelection; 69 m_xProps->getPropertyValue( ITEMS ) >>= sItems; 70 if( getMultiSelect() ) 71 throw uno::RuntimeException( rtl::OUString::createFromAscii( 72 "Attribute use invalid." ), uno::Reference< uno::XInterface >() ); 73 uno::Any aRet; 74 if ( sSelection.getLength() ) 75 aRet = uno::makeAny( sItems[ sSelection[ 0 ] ] ); 76 return aRet; 77 } 78 79 void SAL_CALL 80 ScVbaListBox::setValue( const uno::Any& _value ) throw (uno::RuntimeException) 81 { 82 if( getMultiSelect() ) 83 { 84 throw uno::RuntimeException( rtl::OUString::createFromAscii( 85 "Attribute use invalid." ), uno::Reference< uno::XInterface >() ); 86 } 87 rtl::OUString sValue = getAnyAsString( _value ); 88 uno::Sequence< rtl::OUString > sList; 89 m_xProps->getPropertyValue( ITEMS ) >>= sList; 90 uno::Sequence< sal_Int16 > nList; 91 sal_Int16 nLength = static_cast<sal_Int16>( sList.getLength() ); 92 sal_Int16 nValue = -1; 93 sal_Int16 i = 0; 94 for( i = 0; i < nLength; i++ ) 95 { 96 if( sList[i].equals( sValue ) ) 97 { 98 nValue = i; 99 break; 100 } 101 } 102 if( nValue == -1 ) 103 throw uno::RuntimeException( rtl::OUString::createFromAscii( 104 "Attribute use invalid." ), uno::Reference< uno::XInterface >() ); 105 106 uno::Sequence< sal_Int16 > nSelectedIndices(1); 107 nSelectedIndices[ 0 ] = nValue; 108 m_xProps->setPropertyValue( SELECTEDITEMS, uno::makeAny( nSelectedIndices ) ); 109 m_xProps->setPropertyValue( TEXT, uno::makeAny( sValue ) ); 110 } 111 112 ::rtl::OUString SAL_CALL 113 ScVbaListBox::getText() throw (uno::RuntimeException) 114 { 115 rtl::OUString result; 116 getValue() >>= result; 117 return result; 118 } 119 120 void SAL_CALL 121 ScVbaListBox::setText( const ::rtl::OUString& _text ) throw (uno::RuntimeException) 122 { 123 setValue( uno::makeAny( _text ) ); // seems the same 124 } 125 126 sal_Bool SAL_CALL 127 ScVbaListBox::getMultiSelect() throw (css::uno::RuntimeException) 128 { 129 sal_Bool bMultiSelect = sal_False; 130 m_xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiSelection" ) ) ) >>= bMultiSelect; 131 return bMultiSelect; 132 } 133 134 void SAL_CALL 135 ScVbaListBox::setMultiSelect( sal_Bool _multiselect ) throw (css::uno::RuntimeException) 136 { 137 m_xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiSelection" ) ), uno::makeAny( _multiselect ) ); 138 } 139 140 css::uno::Any SAL_CALL 141 ScVbaListBox::Selected( sal_Int32 index ) throw (css::uno::RuntimeException) 142 { 143 uno::Sequence< rtl::OUString > sList; 144 m_xProps->getPropertyValue( ITEMS ) >>= sList; 145 sal_Int16 nLength = static_cast< sal_Int16 >( sList.getLength() ); 146 // no choice but to do a horror cast as internally 147 // the indices are but sal_Int16 148 sal_Int16 nIndex = static_cast< sal_Int16 >( index ); 149 if( nIndex < 0 || nIndex >= nLength ) 150 throw uno::RuntimeException( rtl::OUString::createFromAscii( 151 "Error Number." ), uno::Reference< uno::XInterface >() ); 152 m_nIndex = nIndex; 153 return uno::makeAny( uno::Reference< XPropValue > ( new ScVbaPropValue( this ) ) ); 154 } 155 156 // Methods 157 void SAL_CALL 158 ScVbaListBox::AddItem( const uno::Any& pvargItem, const uno::Any& pvargIndex ) throw (uno::RuntimeException) 159 { 160 mpListHelper->AddItem( pvargItem, pvargIndex ); 161 } 162 163 void SAL_CALL 164 ScVbaListBox::removeItem( const uno::Any& index ) throw (uno::RuntimeException) 165 { 166 mpListHelper->removeItem( index ); 167 } 168 169 void SAL_CALL 170 ScVbaListBox::Clear( ) throw (uno::RuntimeException) 171 { 172 mpListHelper->Clear(); 173 } 174 175 // this is called when something like the following vba code is used 176 // to set the selected state of particular entries in the Listbox 177 // ListBox1.Selected( 3 ) = false 178 //PropListener 179 void 180 ScVbaListBox::setValueEvent( const uno::Any& value ) 181 { 182 sal_Bool bValue = sal_False; 183 if( !(value >>= bValue) ) 184 throw uno::RuntimeException( rtl::OUString::createFromAscii( 185 "Invalid type\n. need boolean." ), uno::Reference< uno::XInterface >() ); 186 uno::Sequence< sal_Int16 > nList; 187 m_xProps->getPropertyValue( SELECTEDITEMS ) >>= nList; 188 sal_Int16 nLength = static_cast<sal_Int16>( nList.getLength() ); 189 sal_Int16 nIndex = m_nIndex; 190 for( sal_Int16 i = 0; i < nLength; i++ ) 191 { 192 if( nList[i] == nIndex ) 193 { 194 if( bValue ) 195 return; 196 else 197 { 198 for( ; i < nLength - 1; i++ ) 199 { 200 nList[i] = nList[i + 1]; 201 } 202 nList.realloc( nLength - 1 ); 203 //m_xProps->setPropertyValue( sSourceName, uno::makeAny( nList ) ); 204 m_xProps->setPropertyValue( SELECTEDITEMS, uno::makeAny( nList ) ); 205 return; 206 } 207 } 208 } 209 if( bValue ) 210 { 211 if( getMultiSelect() ) 212 { 213 nList.realloc( nLength + 1 ); 214 nList[nLength] = nIndex; 215 } 216 else 217 { 218 nList.realloc( 1 ); 219 nList[0] = nIndex; 220 } 221 //m_xProps->setPropertyValue( sSourceName, uno::makeAny( nList ) ); 222 m_xProps->setPropertyValue( SELECTEDITEMS, uno::makeAny( nList ) ); 223 } 224 } 225 226 // this is called when something like the following vba code is used 227 // to determine the selected state of particular entries in the Listbox 228 // msgbox ListBox1.Selected( 3 ) 229 230 css::uno::Any 231 ScVbaListBox::getValueEvent() 232 { 233 uno::Sequence< sal_Int16 > nList; 234 m_xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectedItems" ) ) ) >>= nList; 235 sal_Int32 nLength = nList.getLength(); 236 sal_Int32 nIndex = m_nIndex; 237 238 for( sal_Int32 i = 0; i < nLength; i++ ) 239 { 240 if( nList[i] == nIndex ) 241 return uno::makeAny( sal_True ); 242 } 243 244 return uno::makeAny( sal_False ); 245 } 246 247 void SAL_CALL 248 ScVbaListBox::setRowSource( const rtl::OUString& _rowsource ) throw (uno::RuntimeException) 249 { 250 ScVbaControl::setRowSource( _rowsource ); 251 mpListHelper->setRowSource( _rowsource ); 252 } 253 254 sal_Int32 SAL_CALL 255 ScVbaListBox::getListCount() throw (uno::RuntimeException) 256 { 257 return mpListHelper->getListCount(); 258 } 259 260 uno::Any SAL_CALL 261 ScVbaListBox::List( const ::uno::Any& pvargIndex, const uno::Any& pvarColumn ) throw (uno::RuntimeException) 262 { 263 return mpListHelper->List( pvargIndex, pvarColumn ); 264 } 265 266 uno::Reference< msforms::XNewFont > SAL_CALL ScVbaListBox::getFont() throw (uno::RuntimeException) 267 { 268 return new VbaNewFont( this, mxContext, m_xProps ); 269 } 270 271 rtl::OUString& 272 ScVbaListBox::getServiceImplName() 273 { 274 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaListBox") ); 275 return sImplName; 276 } 277 278 uno::Sequence< rtl::OUString > 279 ScVbaListBox::getServiceNames() 280 { 281 static uno::Sequence< rtl::OUString > aServiceNames; 282 if ( aServiceNames.getLength() == 0 ) 283 { 284 aServiceNames.realloc( 1 ); 285 aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.msforms.ScVbaListBox" ) ); 286 } 287 return aServiceNames; 288 } 289