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