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