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
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)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
setListIndex(const uno::Any & _value)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
getListIndex()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
getValue()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
setValue(const uno::Any & _value)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
getText()113 ScVbaListBox::getText() throw (uno::RuntimeException)
114 {
115 rtl::OUString result;
116 getValue() >>= result;
117 return result;
118 }
119
120 void SAL_CALL
setText(const::rtl::OUString & _text)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
getMultiSelect()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
setMultiSelect(sal_Bool _multiselect)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
Selected(sal_Int32 index)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
AddItem(const uno::Any & pvargItem,const uno::Any & pvargIndex)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
removeItem(const uno::Any & index)164 ScVbaListBox::removeItem( const uno::Any& index ) throw (uno::RuntimeException)
165 {
166 mpListHelper->removeItem( index );
167 }
168
169 void SAL_CALL
Clear()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
setValueEvent(const uno::Any & value)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
getValueEvent()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
setRowSource(const rtl::OUString & _rowsource)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
getListCount()255 ScVbaListBox::getListCount() throw (uno::RuntimeException)
256 {
257 return mpListHelper->getListCount();
258 }
259
260 uno::Any SAL_CALL
List(const::uno::Any & pvargIndex,const uno::Any & pvarColumn)261 ScVbaListBox::List( const ::uno::Any& pvargIndex, const uno::Any& pvarColumn ) throw (uno::RuntimeException)
262 {
263 return mpListHelper->List( pvargIndex, pvarColumn );
264 }
265
getFont()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&
getServiceImplName()272 ScVbaListBox::getServiceImplName()
273 {
274 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaListBox") );
275 return sImplName;
276 }
277
278 uno::Sequence< rtl::OUString >
getServiceNames()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