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