1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: collect.cxx,v $
10 * $Revision: 1.14.32.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
37 #include <tools/stream.hxx>
38 #include <unotools/transliterationwrapper.hxx>
40 #include "rechead.hxx"
41 #include "collect.hxx"
42 #include "document.hxx" // fuer TypedStrData Konstruktor
44 // -----------------------------------------------------------------------
46 ScDataObject::~ScDataObject()
50 //------------------------------------------------------------------------
52 //------------------------------------------------------------------------
54 void lcl_DeleteScDataObjects( ScDataObject
** p
, USHORT nCount
)
58 for (USHORT i
= 0; i
< nCount
; i
++) delete p
[i
];
64 ScCollection::ScCollection(USHORT nLim
, USHORT nDel
) :
70 if (nDelta
> MAXDELTA
)
74 if (nLimit
> MAXCOLLECTIONSIZE
)
75 nLimit
= MAXCOLLECTIONSIZE
;
76 else if (nLimit
< nDelta
)
78 pItems
= new ScDataObject
*[nLimit
];
81 ScCollection::ScCollection(const ScCollection
& rCollection
)
91 //------------------------------------------------------------------------
93 ScCollection::~ScCollection()
95 lcl_DeleteScDataObjects( pItems
, nCount
);
98 //------------------------------------------------------------------------
99 USHORT
ScCollection::GetCount() const { return nCount
; }
100 void ScCollection::AtFree(USHORT nIndex
)
102 if ((pItems
) && (nIndex
< nCount
))
104 delete pItems
[nIndex
];
105 --nCount
; // before memmove
106 memmove ( &pItems
[nIndex
], &pItems
[nIndex
+ 1], (nCount
- nIndex
) * sizeof(ScDataObject
*));
107 pItems
[nCount
] = NULL
;
111 //------------------------------------------------------------------------
113 void ScCollection::Free(ScDataObject
* pScDataObject
)
115 AtFree(IndexOf(pScDataObject
));
118 //------------------------------------------------------------------------
120 void ScCollection::FreeAll()
122 lcl_DeleteScDataObjects( pItems
, nCount
);
124 pItems
= new ScDataObject
*[nLimit
];
127 //------------------------------------------------------------------------
129 BOOL
ScCollection::AtInsert(USHORT nIndex
, ScDataObject
* pScDataObject
)
131 if ((nCount
< MAXCOLLECTIONSIZE
) && (nIndex
<= nCount
) && pItems
)
133 if (nCount
== nLimit
)
135 ScDataObject
** pNewItems
= new ScDataObject
*[nLimit
+ nDelta
];
138 nLimit
= sal::static_int_cast
<USHORT
>( nLimit
+ nDelta
);
139 memmove(pNewItems
, pItems
, nCount
* sizeof(ScDataObject
*));
144 memmove(&pItems
[nIndex
+ 1], &pItems
[nIndex
], (nCount
- nIndex
) * sizeof(ScDataObject
*));
145 pItems
[nIndex
] = pScDataObject
;
152 //------------------------------------------------------------------------
154 BOOL
ScCollection::Insert(ScDataObject
* pScDataObject
)
156 return AtInsert(nCount
, pScDataObject
);
159 //------------------------------------------------------------------------
161 ScDataObject
* ScCollection::At(USHORT nIndex
) const
164 return pItems
[nIndex
];
169 //------------------------------------------------------------------------
171 USHORT
ScCollection::IndexOf(ScDataObject
* pScDataObject
) const
173 USHORT nIndex
= 0xffff;
174 for (USHORT i
= 0; ((i
< nCount
) && (nIndex
== 0xffff)); i
++)
176 if (pItems
[i
] == pScDataObject
) nIndex
= i
;
181 //------------------------------------------------------------------------
183 ScCollection
& ScCollection::operator=( const ScCollection
& r
)
185 lcl_DeleteScDataObjects( pItems
, nCount
);
190 pItems
= new ScDataObject
*[nLimit
];
191 for ( USHORT i
=0; i
<nCount
; i
++ )
192 pItems
[i
] = r
.pItems
[i
]->Clone();
197 //------------------------------------------------------------------------
199 ScDataObject
* ScCollection::Clone() const
201 return new ScCollection(*this);
204 //------------------------------------------------------------------------
205 // ScSortedCollection
206 //------------------------------------------------------------------------
208 ScSortedCollection::ScSortedCollection(USHORT nLim
, USHORT nDel
, BOOL bDup
) :
209 ScCollection (nLim
, nDel
),
214 //------------------------------------------------------------------------
216 USHORT
ScSortedCollection::IndexOf(ScDataObject
* pScDataObject
) const
219 if (Search(pScDataObject
, nIndex
))
225 //------------------------------------------------------------------------
227 BOOL
ScSortedCollection::Search(ScDataObject
* pScDataObject
, USHORT
& rIndex
) const
232 short nHi
= nCount
- 1;
237 nIndex
= (nLo
+ nHi
) / 2;
238 nCompare
= Compare(pItems
[nIndex
], pScDataObject
);
255 //------------------------------------------------------------------------
257 BOOL
ScSortedCollection::Insert(ScDataObject
* pScDataObject
)
260 BOOL bFound
= Search(pScDataObject
, nIndex
);
264 return AtInsert(nIndex
, pScDataObject
);
269 return AtInsert(nIndex
, pScDataObject
);
272 //------------------------------------------------------------------------
274 BOOL
ScSortedCollection::InsertPos(ScDataObject
* pScDataObject
, USHORT
& nIndex
)
276 BOOL bFound
= Search(pScDataObject
, nIndex
);
280 return AtInsert(nIndex
, pScDataObject
);
285 return AtInsert(nIndex
, pScDataObject
);
288 //------------------------------------------------------------------------
290 BOOL
ScSortedCollection::operator==(const ScSortedCollection
& rCmp
) const
292 if ( nCount
!= rCmp
.nCount
)
294 for (USHORT i
=0; i
<nCount
; i
++)
295 if ( !IsEqual(pItems
[i
],rCmp
.pItems
[i
]) )
300 //------------------------------------------------------------------------
302 // IsEqual - komplette Inhalte vergleichen
304 BOOL
ScSortedCollection::IsEqual(ScDataObject
* pKey1
, ScDataObject
* pKey2
) const
306 return ( Compare(pKey1
, pKey2
) == 0 ); // Default: nur Index vergleichen
309 //------------------------------------------------------------------------
311 ScDataObject
* StrData::Clone() const
313 return new StrData(*this);
316 //------------------------------------------------------------------------
318 short ScStrCollection::Compare(ScDataObject
* pKey1
, ScDataObject
* pKey2
) const
320 StringCompare eComp
= ((StrData
*)pKey1
)->aStr
.CompareTo(((StrData
*)pKey2
)->aStr
);
321 if (eComp
== COMPARE_EQUAL
)
323 else if (eComp
== COMPARE_LESS
)
329 //------------------------------------------------------------------------
331 ScDataObject
* ScStrCollection::Clone() const
333 return new ScStrCollection(*this);
336 //------------------------------------------------------------------------
337 // TypedScStrCollection
338 //------------------------------------------------------------------------
340 //UNUSED2008-05 TypedStrData::TypedStrData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
341 //UNUSED2008-05 BOOL bAllStrings )
343 //UNUSED2008-05 if ( pDoc->HasValueData( nCol, nRow, nTab ) )
345 //UNUSED2008-05 pDoc->GetValue( nCol, nRow, nTab, nValue );
346 //UNUSED2008-05 if (bAllStrings)
347 //UNUSED2008-05 pDoc->GetString( nCol, nRow, nTab, aStrValue );
348 //UNUSED2008-05 nStrType = 0;
352 //UNUSED2008-05 pDoc->GetString( nCol, nRow, nTab, aStrValue );
353 //UNUSED2008-05 nValue = 0.0;
354 //UNUSED2008-05 nStrType = 1; //! Typ uebergeben ?
358 ScDataObject
* TypedStrData::Clone() const
360 return new TypedStrData(*this);
362 TypedScStrCollection::~TypedScStrCollection()
364 ScDataObject
* TypedScStrCollection::Clone() const
366 return new TypedScStrCollection(*this);
369 short TypedScStrCollection::Compare( ScDataObject
* pKey1
, ScDataObject
* pKey2
) const
373 if ( pKey1
&& pKey2
)
375 TypedStrData
& rData1
= (TypedStrData
&)*pKey1
;
376 TypedStrData
& rData2
= (TypedStrData
&)*pKey2
;
378 if ( rData1
.nStrType
> rData2
.nStrType
)
380 else if ( rData1
.nStrType
< rData2
.nStrType
)
382 else if ( !rData1
.nStrType
/* && !rData2.nStrType */ )
384 //--------------------
385 // Zahlen vergleichen:
386 //--------------------
387 if ( rData1
.nValue
== rData2
.nValue
)
389 else if ( rData1
.nValue
< rData2
.nValue
)
394 else /* if ( rData1.nStrType && rData2.nStrType ) */
396 //---------------------
397 // Strings vergleichen:
398 //---------------------
399 if ( bCaseSensitive
)
400 nResult
= (short) ScGlobal::GetCaseTransliteration()->compareString(
401 rData1
.aStrValue
, rData2
.aStrValue
);
403 nResult
= (short) ScGlobal::GetpTransliteration()->compareString(
404 rData1
.aStrValue
, rData2
.aStrValue
);
411 BOOL
TypedScStrCollection::FindText( const String
& rStart
, String
& rResult
,
412 USHORT
& rPos
, BOOL bBack
) const
414 // Die Collection ist nach String-Vergleichen sortiert, darum muss hier
415 // alles durchsucht werden
420 if ( rPos
!= SCPOS_INVALID
&& rPos
< nCount
)
422 TypedStrData
* pData
= (TypedStrData
*) pItems
[rPos
];
424 aOldResult
= pData
->aStrValue
;
427 if ( bBack
) // rueckwaerts
429 USHORT nStartPos
= nCount
;
430 if ( rPos
!= SCPOS_INVALID
)
431 nStartPos
= rPos
; // weitersuchen...
433 for ( USHORT i
=nStartPos
; i
>0; )
436 TypedStrData
* pData
= (TypedStrData
*) pItems
[i
];
439 if ( ScGlobal::GetpTransliteration()->isMatch( rStart
, pData
->aStrValue
) )
441 // If the collection is case sensitive, it may contain several entries
442 // that are equal when compared case-insensitive. They are skipped here.
443 if ( !bCaseSensitive
|| !aOldResult
.Len() ||
444 !ScGlobal::GetpTransliteration()->isEqual(
445 pData
->aStrValue
, aOldResult
) )
447 rResult
= pData
->aStrValue
;
458 USHORT nStartPos
= 0;
459 if ( rPos
!= SCPOS_INVALID
)
460 nStartPos
= rPos
+ 1; // weitersuchen...
462 for ( USHORT i
=nStartPos
; i
<nCount
; i
++ )
464 TypedStrData
* pData
= (TypedStrData
*) pItems
[i
];
467 if ( ScGlobal::GetpTransliteration()->isMatch( rStart
, pData
->aStrValue
) )
469 // If the collection is case sensitive, it may contain several entries
470 // that are equal when compared case-insensitive. They are skipped here.
471 if ( !bCaseSensitive
|| !aOldResult
.Len() ||
472 !ScGlobal::GetpTransliteration()->isEqual(
473 pData
->aStrValue
, aOldResult
) )
475 rResult
= pData
->aStrValue
;
488 // Gross-/Kleinschreibung anpassen
490 BOOL
TypedScStrCollection::GetExactMatch( String
& rString
) const
492 for (USHORT i
=0; i
<nCount
; i
++)
494 TypedStrData
* pData
= (TypedStrData
*) pItems
[i
];
495 if ( pData
->nStrType
&& ScGlobal::GetpTransliteration()->isEqual(
496 pData
->aStrValue
, rString
) )
498 rString
= pData
->aStrValue
; // String anpassen