xref: /trunk/main/svl/source/items/slstitm.cxx (revision 40df464e)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svl.hxx"
26 
27 #include <svl/slstitm.hxx>
28 #include <svl/poolitem.hxx>
29 #include <com/sun/star/uno/Any.hxx>
30 #include <com/sun/star/uno/Sequence.hxx>
31 #include <tools/stream.hxx>
32 
33 // STATIC DATA -----------------------------------------------------------
34 
35 DBG_NAME(SfxStringListItem)
36 
37 // -----------------------------------------------------------------------
38 
39 TYPEINIT1_AUTOFACTORY(SfxStringListItem, SfxPoolItem);
40 
41 class SfxImpStringList
42 {
43 public:
44 	sal_uInt16	nRefCount;
45 	List	aList;
46 
SfxImpStringList()47 			SfxImpStringList() { nRefCount = 1; }
48 			~SfxImpStringList();
49 	void 	Sort( sal_Bool bAscending, List* );
50 };
51 
52 //------------------------------------------------------------------------
53 
~SfxImpStringList()54 SfxImpStringList::~SfxImpStringList()
55 {
56 	DBG_ASSERT(nRefCount!=0xffff,"ImpList already deleted");
57 	String* pStr = (String*)aList.First();
58 	while( pStr )
59 	{
60 		delete pStr;
61 		pStr = (String*)aList.Next();
62 	}
63 	nRefCount = 0xffff;
64 }
65 
66 //------------------------------------------------------------------------
67 
Sort(sal_Bool bAscending,List * pParallelList)68 void SfxImpStringList::Sort( sal_Bool bAscending, List* pParallelList )
69 {
70 	DBG_ASSERT(!pParallelList || pParallelList->Count() >= aList.Count(),"Sort:ParallelList too small");
71 	sal_uLong nCount = aList.Count();
72 	if( nCount > 1 )
73 	{
74 		nCount -= 2;
75 		// Bubble Dir Einen
76 		sal_Bool bSwapped = sal_True;
77 		while( bSwapped )
78 		{
79 			bSwapped = sal_False;
80 			for( sal_uLong nCur = 0; nCur <= nCount; nCur++ )
81 			{
82 				String* pStr1 = (String*)aList.GetObject( nCur );
83 				String* pStr2 = (String*)aList.GetObject( nCur+1 );
84 				// COMPARE_GREATER => pStr2 ist groesser als pStr1
85 				StringCompare eCompare = pStr1->CompareIgnoreCaseToAscii( *pStr2 ); //@@@
86 				sal_Bool bSwap = sal_False;
87 				if( bAscending )
88 				{
89 					if( eCompare == COMPARE_LESS )
90 						bSwap = sal_True;
91 				}
92 				else if( eCompare == COMPARE_GREATER )
93 					bSwap = sal_True;
94 
95 				if( bSwap )
96 				{
97 					bSwapped = sal_True;
98 					aList.Replace( pStr1, nCur + 1 );
99 					aList.Replace( pStr2, nCur );
100 					if( pParallelList )
101 					{
102 						void* p1 = pParallelList->GetObject( nCur );
103 						void* p2 = pParallelList->GetObject( nCur + 1 );
104 						pParallelList->Replace( p1, nCur + 1 );
105 						pParallelList->Replace( p2, nCur );
106 					}
107 				}
108 			}
109 		}
110 	}
111 }
112 
113 // class SfxStringListItem -----------------------------------------------
114 
SfxStringListItem()115 SfxStringListItem::SfxStringListItem() :
116 	pImp(NULL)
117 {
118 }
119 
120 //------------------------------------------------------------------------
121 
SfxStringListItem(sal_uInt16 which,const List * pList)122 SfxStringListItem::SfxStringListItem( sal_uInt16 which, const List* pList ) :
123 	SfxPoolItem( which ),
124 	pImp(NULL)
125 {
126 	// PB: das Putten einer leeren Liste funktionierte nicht,
127 	// deshalb habe ich hier die Abfrage nach dem Count auskommentiert
128 	if( pList /*!!! && pList->Count() */ )
129 	{
130 		pImp = new SfxImpStringList;
131 
132 		long i, nCount = pList->Count();
133 		String  *pStr1, *pStr2;
134 		for( i=0; i < nCount; i++ )
135 		{
136 			pStr1 = (String*)pList->GetObject(i);
137 			pStr2 = new String( *pStr1 );
138 			pImp->aList.Insert( pStr2, LIST_APPEND );
139 		}
140 	}
141 }
142 
143 //------------------------------------------------------------------------
144 
SfxStringListItem(sal_uInt16 which,SvStream & rStream)145 SfxStringListItem::SfxStringListItem( sal_uInt16 which, SvStream& rStream ) :
146 	SfxPoolItem( which ),
147 	pImp(NULL)
148 {
149 	long nEntryCount;
150 	rStream >> nEntryCount;
151 
152 	if( nEntryCount )
153 		pImp = new SfxImpStringList;
154 
155 	long   i;
156 	String*  pStr;
157 	for( i=0; i < nEntryCount; i++ )
158 	{
159 		pStr = new String;
160 		readByteString(rStream, *pStr);
161 		pImp->aList.Insert( pStr, LIST_APPEND );
162 	}
163 }
164 
165 //------------------------------------------------------------------------
166 
SfxStringListItem(const SfxStringListItem & rItem)167 SfxStringListItem::SfxStringListItem( const SfxStringListItem& rItem ) :
168 	SfxPoolItem( rItem ),
169 	pImp(NULL)
170 {
171 	pImp = rItem.pImp;
172 
173 	if( pImp )
174 	{
175 		DBG_ASSERT(pImp->nRefCount!=0xffff,"ImpList not valid");
176 		pImp->nRefCount++;
177 	}
178 }
179 
180 //------------------------------------------------------------------------
181 
~SfxStringListItem()182 SfxStringListItem::~SfxStringListItem()
183 {
184 	if( pImp )
185 	{
186 		DBG_ASSERT(pImp->nRefCount!=0xffff,"ImpList not valid");
187 		if( pImp->nRefCount > 1 )
188 			pImp->nRefCount--;
189 		else
190 			delete pImp;
191 	}
192 }
193 
194 //------------------------------------------------------------------------
195 
GetList()196 List* SfxStringListItem::GetList()
197 {
198 	if( !pImp )
199 		pImp = new SfxImpStringList;
200 	DBG_ASSERT(pImp->nRefCount!=0xffff,"ImpList not valid");
201 	return &(pImp->aList);
202 }
203 
204 //------------------------------------------------------------------------
205 
operator ==(const SfxPoolItem & rItem) const206 int SfxStringListItem::operator==( const SfxPoolItem& rItem ) const
207 {
208 	DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
209 
210 	SfxStringListItem* pItem = (SfxStringListItem*)&rItem;
211 
212 	if( pImp == pItem->pImp )
213 		return sal_True;
214 	else
215 		return sal_False;
216 }
217 
218 //------------------------------------------------------------------------
219 
GetPresentation(SfxItemPresentation,SfxMapUnit,SfxMapUnit,XubString & rText,const IntlWrapper *) const220 SfxItemPresentation SfxStringListItem::GetPresentation
221 (
222 	SfxItemPresentation 	/*ePresentation*/,
223 	SfxMapUnit				/*eCoreMetric*/,
224 	SfxMapUnit				/*ePresentationMetric*/,
225 	XubString& 				rText,
226     const IntlWrapper *
227 )	const
228 {
229 	rText.AssignAscii(RTL_CONSTASCII_STRINGPARAM("(List)"));
230 	return SFX_ITEM_PRESENTATION_NONE;
231 }
232 
233 //------------------------------------------------------------------------
234 
Clone(SfxItemPool *) const235 SfxPoolItem* SfxStringListItem::Clone( SfxItemPool *) const
236 {
237 	return new SfxStringListItem( *this );
238 	/*
239 	if( pImp )
240 		return new SfxStringListItem( Which(), &(pImp->aList) );
241 	else
242 		return new SfxStringListItem( Which(), NULL );
243 	*/
244 
245 }
246 
247 //------------------------------------------------------------------------
248 
Create(SvStream & rStream,sal_uInt16) const249 SfxPoolItem* SfxStringListItem::Create( SvStream & rStream, sal_uInt16 ) const
250 {
251 	return new SfxStringListItem( Which(), rStream );
252 }
253 
254 //------------------------------------------------------------------------
255 
Store(SvStream & rStream,sal_uInt16) const256 SvStream& SfxStringListItem::Store( SvStream & rStream, sal_uInt16 ) const
257 {
258 	if( !pImp )
259 	{
260 		rStream << 0L;
261 		return rStream;
262 	}
263 
264 	DBG_ASSERT(pImp->nRefCount!=0xffff,"ImpList not valid");
265 
266 	long nCount = pImp->aList.Count();
267 	rStream << nCount;
268 
269 	long i;
270 	String* pStr;
271 	for( i=0; i < nCount; i++ )
272 	{
273 		pStr = (String*)(pImp->aList.GetObject( i ));
274 		writeByteString(rStream, *pStr);
275 	}
276 
277 	return rStream;
278 }
279 
280 //------------------------------------------------------------------------
281 
SetString(const XubString & rStr)282 void SfxStringListItem::SetString( const XubString& rStr )
283 {
284 	DBG_ASSERT(GetRefCount()==0,"SetString:RefCount!=0");
285 
286 	if ( pImp && (pImp->nRefCount == 1) )
287 		delete pImp;
288 	else
289 	if( pImp )
290 		pImp->nRefCount--;
291 	pImp = new SfxImpStringList;
292 
293 	xub_StrLen nStart = 0;
294 	xub_StrLen nDelimPos;
295 	XubString aStr(rStr);
296 	aStr.ConvertLineEnd(LINEEND_CR);
297 	do
298 	{
299 		nDelimPos = aStr.Search( _CR, nStart );
300 		xub_StrLen nLen;
301 		if ( nDelimPos == STRING_NOTFOUND )
302 			nLen = 0xffff;
303 		else
304 			nLen = nDelimPos - nStart;
305 
306 		XubString* pStr = new XubString(aStr.Copy(nStart, nLen));
307 		// String gehoert der Liste
308 		pImp->aList.Insert( pStr, LIST_APPEND );
309 
310 		nStart += nLen + 1 ;	// delimiter ueberspringen
311 	} while( nDelimPos != STRING_NOTFOUND );
312 
313 	// Kein Leerstring am Ende
314 	if( pImp->aList.Last() &&
315 		!((XubString*)pImp->aList.Last())->Len() )
316 		delete (XubString*)pImp->aList.Remove( pImp->aList.Count()-1 );
317 }
318 
319 //------------------------------------------------------------------------
320 
GetString()321 XubString SfxStringListItem::GetString()
322 {
323 	XubString aStr;
324 	if ( pImp )
325 	{
326 		DBG_ASSERT(pImp->nRefCount!=0xffff,"ImpList not valid");
327 		XubString* pStr = (XubString*)(pImp->aList.First());
328 		while( pStr )
329 		{
330 			aStr += *pStr;
331 			pStr = (XubString*)(pImp->aList.Next());
332 			if ( pStr )
333 				aStr += '\r';
334 		}
335 	}
336 	aStr.ConvertLineEnd();
337 	return aStr;
338 }
339 
340 //------------------------------------------------------------------------
341 
342 #ifndef TF_POOLABLE
343 
IsPoolable() const344 int SfxStringListItem::IsPoolable() const
345 {
346 	return sal_False;
347 }
348 
349 #endif
350 
351 //------------------------------------------------------------------------
352 
Sort(sal_Bool bAscending,List * pParallelList)353 void SfxStringListItem::Sort( sal_Bool bAscending, List* pParallelList )
354 {
355 	DBG_ASSERT(GetRefCount()==0,"Sort:RefCount!=0");
356 	if( pImp )
357 		pImp->Sort( bAscending, pParallelList );
358 }
359 
360 //----------------------------------------------------------------------------
SetStringList(const com::sun::star::uno::Sequence<rtl::OUString> & rList)361 void SfxStringListItem::SetStringList( const com::sun::star::uno::Sequence< rtl::OUString >& rList )
362 {
363 	DBG_ASSERT(GetRefCount()==0,"SetString:RefCount!=0");
364 
365 	if ( pImp && (pImp->nRefCount == 1) )
366 		delete pImp;
367 	else
368 	if( pImp )
369 		pImp->nRefCount--;
370 	pImp = new SfxImpStringList;
371 
372     for ( sal_Int32 n = 0; n < rList.getLength(); n++ )
373     {
374 		XubString* pStr = new XubString( rList[n] );
375 		// String gehoert der Liste
376 		pImp->aList.Insert( pStr, LIST_APPEND );
377     }
378 }
379 
380 //----------------------------------------------------------------------------
GetStringList(com::sun::star::uno::Sequence<rtl::OUString> & rList) const381 void SfxStringListItem::GetStringList( com::sun::star::uno::Sequence< rtl::OUString >& rList ) const
382 {
383 	long nCount = pImp->aList.Count();
384 
385     rList.realloc( nCount );
386 	for( long i=0; i < nCount; i++ )
387 		rList[i] = *(String*)(pImp->aList.GetObject( i ));
388 }
389 
390 //----------------------------------------------------------------------------
391 // virtual
PutValue(const com::sun::star::uno::Any & rVal,sal_uInt8)392 sal_Bool SfxStringListItem::PutValue( const com::sun::star::uno::Any& rVal,sal_uInt8 )
393 {
394     com::sun::star::uno::Sequence< rtl::OUString > aValue;
395 	if ( rVal >>= aValue )
396 	{
397 		SetStringList( aValue );
398 		return sal_True;
399 	}
400 
401 	DBG_ERROR( "SfxStringListItem::PutValue - Wrong type!" );
402 	return sal_False;
403 }
404 
405 //----------------------------------------------------------------------------
406 // virtual
QueryValue(com::sun::star::uno::Any & rVal,sal_uInt8) const407 sal_Bool SfxStringListItem::QueryValue( com::sun::star::uno::Any& rVal,sal_uInt8 ) const
408 {
409 	// GetString() is not const!!!
410 	SfxStringListItem* pThis = const_cast< SfxStringListItem * >( this );
411 
412     com::sun::star::uno::Sequence< rtl::OUString > aStringList;
413     pThis->GetStringList( aStringList );
414     rVal = ::com::sun::star::uno::makeAny( aStringList );
415 	return sal_True;
416 }
417 
418 
419