xref: /trunk/main/svl/source/items/slstitm.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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