update dev300-m58
[ooovba.git] / sc / source / core / tool / collect.cxx
blob78c6b25d97d0be9737b4f4859f9ba34b6211b9ea
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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"
36 #include <string.h>
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 //------------------------------------------------------------------------
51 // Collection
52 //------------------------------------------------------------------------
54 void lcl_DeleteScDataObjects( ScDataObject** p, USHORT nCount )
56 if ( p )
58 for (USHORT i = 0; i < nCount; i++) delete p[i];
59 delete[] p;
60 p = NULL;
64 ScCollection::ScCollection(USHORT nLim, USHORT nDel) :
65 nCount ( 0 ),
66 nLimit ( nLim ),
67 nDelta ( nDel ),
68 pItems ( NULL )
70 if (nDelta > MAXDELTA)
71 nDelta = MAXDELTA;
72 else if (nDelta == 0)
73 nDelta = 1;
74 if (nLimit > MAXCOLLECTIONSIZE)
75 nLimit = MAXCOLLECTIONSIZE;
76 else if (nLimit < nDelta)
77 nLimit = nDelta;
78 pItems = new ScDataObject*[nLimit];
81 ScCollection::ScCollection(const ScCollection& rCollection)
82 : ScDataObject(),
83 nCount ( 0 ),
84 nLimit ( 0 ),
85 nDelta ( 0 ),
86 pItems ( NULL )
88 *this = 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 );
123 nCount = 0;
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];
136 if (!pNewItems)
137 return FALSE;
138 nLimit = sal::static_int_cast<USHORT>( nLimit + nDelta );
139 memmove(pNewItems, pItems, nCount * sizeof(ScDataObject*));
140 delete[] pItems;
141 pItems = pNewItems;
143 if (nCount > nIndex)
144 memmove(&pItems[nIndex + 1], &pItems[nIndex], (nCount - nIndex) * sizeof(ScDataObject*));
145 pItems[nIndex] = pScDataObject;
146 nCount++;
147 return TRUE;
149 return FALSE;
152 //------------------------------------------------------------------------
154 BOOL ScCollection::Insert(ScDataObject* pScDataObject)
156 return AtInsert(nCount, pScDataObject);
159 //------------------------------------------------------------------------
161 ScDataObject* ScCollection::At(USHORT nIndex) const
163 if (nIndex < nCount)
164 return pItems[nIndex];
165 else
166 return NULL;
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;
178 return nIndex;
181 //------------------------------------------------------------------------
183 ScCollection& ScCollection::operator=( const ScCollection& r )
185 lcl_DeleteScDataObjects( pItems, nCount );
187 nCount = r.nCount;
188 nLimit = r.nLimit;
189 nDelta = r.nDelta;
190 pItems = new ScDataObject*[nLimit];
191 for ( USHORT i=0; i<nCount; i++ )
192 pItems[i] = r.pItems[i]->Clone();
194 return *this;
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),
210 bDuplicates ( bDup)
214 //------------------------------------------------------------------------
216 USHORT ScSortedCollection::IndexOf(ScDataObject* pScDataObject) const
218 USHORT nIndex;
219 if (Search(pScDataObject, nIndex))
220 return nIndex;
221 else
222 return 0xffff;
225 //------------------------------------------------------------------------
227 BOOL ScSortedCollection::Search(ScDataObject* pScDataObject, USHORT& rIndex) const
229 rIndex = nCount;
230 BOOL bFound = FALSE;
231 short nLo = 0;
232 short nHi = nCount - 1;
233 short nIndex;
234 short nCompare;
235 while (nLo <= nHi)
237 nIndex = (nLo + nHi) / 2;
238 nCompare = Compare(pItems[nIndex], pScDataObject);
239 if (nCompare < 0)
240 nLo = nIndex + 1;
241 else
243 nHi = nIndex - 1;
244 if (nCompare == 0)
246 bFound = TRUE;
247 nLo = nIndex;
251 rIndex = nLo;
252 return bFound;
255 //------------------------------------------------------------------------
257 BOOL ScSortedCollection::Insert(ScDataObject* pScDataObject)
259 USHORT nIndex;
260 BOOL bFound = Search(pScDataObject, nIndex);
261 if (bFound)
263 if (bDuplicates)
264 return AtInsert(nIndex, pScDataObject);
265 else
266 return FALSE;
268 else
269 return AtInsert(nIndex, pScDataObject);
272 //------------------------------------------------------------------------
274 BOOL ScSortedCollection::InsertPos(ScDataObject* pScDataObject, USHORT& nIndex)
276 BOOL bFound = Search(pScDataObject, nIndex);
277 if (bFound)
279 if (bDuplicates)
280 return AtInsert(nIndex, pScDataObject);
281 else
282 return FALSE;
284 else
285 return AtInsert(nIndex, pScDataObject);
288 //------------------------------------------------------------------------
290 BOOL ScSortedCollection::operator==(const ScSortedCollection& rCmp) const
292 if ( nCount != rCmp.nCount )
293 return FALSE;
294 for (USHORT i=0; i<nCount; i++)
295 if ( !IsEqual(pItems[i],rCmp.pItems[i]) )
296 return FALSE;
297 return TRUE;
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)
322 return 0;
323 else if (eComp == COMPARE_LESS)
324 return -1;
325 else
326 return 1;
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 )
342 //UNUSED2008-05 {
343 //UNUSED2008-05 if ( pDoc->HasValueData( nCol, nRow, nTab ) )
344 //UNUSED2008-05 {
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;
349 //UNUSED2008-05 }
350 //UNUSED2008-05 else
351 //UNUSED2008-05 {
352 //UNUSED2008-05 pDoc->GetString( nCol, nRow, nTab, aStrValue );
353 //UNUSED2008-05 nValue = 0.0;
354 //UNUSED2008-05 nStrType = 1; //! Typ uebergeben ?
355 //UNUSED2008-05 }
356 //UNUSED2008-05 }
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
371 short nResult = 0;
373 if ( pKey1 && pKey2 )
375 TypedStrData& rData1 = (TypedStrData&)*pKey1;
376 TypedStrData& rData2 = (TypedStrData&)*pKey2;
378 if ( rData1.nStrType > rData2.nStrType )
379 nResult = 1;
380 else if ( rData1.nStrType < rData2.nStrType )
381 nResult = -1;
382 else if ( !rData1.nStrType /* && !rData2.nStrType */ )
384 //--------------------
385 // Zahlen vergleichen:
386 //--------------------
387 if ( rData1.nValue == rData2.nValue )
388 nResult = 0;
389 else if ( rData1.nValue < rData2.nValue )
390 nResult = -1;
391 else
392 nResult = 1;
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 );
402 else
403 nResult = (short) ScGlobal::GetpTransliteration()->compareString(
404 rData1.aStrValue, rData2.aStrValue );
408 return nResult;
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
417 BOOL bFound = FALSE;
419 String aOldResult;
420 if ( rPos != SCPOS_INVALID && rPos < nCount )
422 TypedStrData* pData = (TypedStrData*) pItems[rPos];
423 if (pData->nStrType)
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; )
435 --i;
436 TypedStrData* pData = (TypedStrData*) pItems[i];
437 if (pData->nStrType)
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;
448 rPos = i;
449 bFound = TRUE;
450 break;
456 else // vorwaerts
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];
465 if (pData->nStrType)
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;
476 rPos = i;
477 bFound = TRUE;
478 break;
485 return bFound;
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
499 return TRUE;
503 return FALSE;