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 #include <vbalistcontrolhelper.hxx>
23 #include <vector>
24
25 using namespace com::sun::star;
26 using namespace ooo::vba;
27
28 const static rtl::OUString ITEMS( RTL_CONSTASCII_USTRINGPARAM("StringItemList") );
29
30 void SAL_CALL
AddItem(const uno::Any & pvargItem,const uno::Any & pvargIndex)31 ListControlHelper::AddItem( const uno::Any& pvargItem, const uno::Any& pvargIndex ) throw (uno::RuntimeException)
32 {
33 if ( pvargItem.hasValue() )
34 {
35 uno::Sequence< rtl::OUString > sList;
36 m_xProps->getPropertyValue( ITEMS ) >>= sList;
37
38 sal_Int32 nIndex = sList.getLength();
39
40 if ( pvargIndex.hasValue() )
41 pvargIndex >>= nIndex;
42
43 rtl::OUString sString = getAnyAsString( pvargItem );
44
45 // if no index specified or item is to be appended to end of
46 // list just realloc the array and set the last item
47 if ( nIndex == sList.getLength() )
48 {
49 sal_Int32 nOldSize = sList.getLength();
50 sList.realloc( nOldSize + 1 );
51 sList[ nOldSize ] = sString;
52 }
53 else
54 {
55 // just copy those elements above the one to be inserted
56 std::vector< rtl::OUString > sVec;
57 // reserve just the amount we need to copy
58 sVec.reserve( sList.getLength() - nIndex );
59
60 // point at first element to copy
61 rtl::OUString* pString = sList.getArray() + nIndex;
62 const rtl::OUString* pEndString = sList.getArray() + sList.getLength();
63 // insert the new element
64 sVec.push_back( sString );
65 // copy elements
66 for ( ; pString != pEndString; ++pString )
67 sVec.push_back( *pString );
68
69 sList.realloc( sList.getLength() + 1 );
70
71 // point at first element to be overwritten
72 pString = sList.getArray() + nIndex;
73 pEndString = sList.getArray() + sList.getLength();
74 std::vector< rtl::OUString >::iterator it = sVec.begin();
75 for ( ; pString != pEndString; ++pString, ++it)
76 *pString = *it;
77 //
78 }
79
80 m_xProps->setPropertyValue( ITEMS, uno::makeAny( sList ) );
81
82 }
83 }
84
85 void SAL_CALL
removeItem(const uno::Any & index)86 ListControlHelper::removeItem( const uno::Any& index ) throw (uno::RuntimeException)
87 {
88 sal_Int32 nIndex = 0;
89 // for int index
90 if ( index >>= nIndex )
91 {
92 uno::Sequence< rtl::OUString > sList;
93 m_xProps->getPropertyValue( ITEMS ) >>= sList;
94 if( nIndex < 0 || nIndex > ( sList.getLength() - 1 ) )
95 throw uno::RuntimeException( rtl::OUString::createFromAscii( "Invalid index" ), uno::Reference< uno::XInterface > () );
96 if( sList.hasElements() )
97 {
98 if( sList.getLength() == 1 )
99 {
100 Clear();
101 return;
102 }
103 for( sal_Int32 i = nIndex; i < ( sList.getLength()-1 ); i++ )
104 {
105 sList[i] = sList[i+1];
106 }
107 sList.realloc( sList.getLength() - 1 );
108 }
109
110 m_xProps->setPropertyValue( ITEMS, uno::makeAny( sList ) );
111 }
112 }
113
114 void SAL_CALL
Clear()115 ListControlHelper::Clear( ) throw (uno::RuntimeException)
116 {
117 // urk, setValue doesn't seem to work !!
118 //setValue( uno::makeAny( sal_Int16() ) );
119 m_xProps->setPropertyValue( ITEMS, uno::makeAny( uno::Sequence< rtl::OUString >() ) );
120 }
121
122 void SAL_CALL
setRowSource(const rtl::OUString & _rowsource)123 ListControlHelper::setRowSource( const rtl::OUString& _rowsource ) throw (uno::RuntimeException)
124 {
125 if ( _rowsource.getLength() == 0 )
126 Clear();
127 }
128
129 sal_Int32 SAL_CALL
getListCount()130 ListControlHelper::getListCount() throw (uno::RuntimeException)
131 {
132 uno::Sequence< rtl::OUString > sList;
133 m_xProps->getPropertyValue( ITEMS ) >>= sList;
134 return sList.getLength();
135 }
136
137 uno::Any SAL_CALL
List(const::uno::Any & pvargIndex,const uno::Any & pvarColumn)138 ListControlHelper::List( const ::uno::Any& pvargIndex, const uno::Any& pvarColumn ) throw (uno::RuntimeException)
139 {
140 uno::Sequence< rtl::OUString > sList;
141 m_xProps->getPropertyValue( ITEMS ) >>= sList;
142 sal_Int16 nLength = static_cast< sal_Int16 >( sList.getLength() );
143 uno::Any aRet;
144 if ( pvargIndex.hasValue() )
145 {
146 sal_Int16 nIndex = -1;
147 pvargIndex >>= nIndex;
148 if( nIndex < 0 || nIndex >= nLength )
149 throw uno::RuntimeException( rtl::OUString::createFromAscii(
150 "Bad row Index" ), uno::Reference< uno::XInterface >() );
151 aRet <<= sList[ nIndex ];
152 }
153 else if ( pvarColumn.hasValue() ) // pvarColumn on its own would be bad
154 throw uno::RuntimeException( rtl::OUString::createFromAscii(
155 "Bad column Index" ), uno::Reference< uno::XInterface >() );
156 else // List() ( e.g. no args )
157 {
158 uno::Sequence< uno::Sequence< rtl::OUString > > sReturnArray( nLength );
159 for ( sal_Int32 i = 0; i < nLength; ++i )
160 {
161 sReturnArray[ i ].realloc( 10 );
162 sReturnArray[ i ][ 0 ] = sList[ i ];
163 }
164 aRet = uno::makeAny( sReturnArray );
165 }
166 return aRet;
167 }
168