xref: /aoo41x/main/sc/source/core/data/attarray.cxx (revision 8f4c7c28)
1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10b3f79822SAndrew Rist  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19b3f79822SAndrew Rist  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir 
29cdf0e10cSrcweir //------------------------------------------------------------------------
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "scitems.hxx"
32cdf0e10cSrcweir #include <svx/algitem.hxx>
33cdf0e10cSrcweir #include <editeng/boxitem.hxx>
34cdf0e10cSrcweir #include <editeng/bolnitem.hxx>
35cdf0e10cSrcweir #include <editeng/frmdiritem.hxx>
36cdf0e10cSrcweir #include <editeng/shaditem.hxx>
37cdf0e10cSrcweir #include <svl/poolcach.hxx>
38cdf0e10cSrcweir #include <editeng/fontitem.hxx>
39cdf0e10cSrcweir #include <unotools/fontcvt.hxx>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include "attarray.hxx"
42cdf0e10cSrcweir #include "global.hxx"
43cdf0e10cSrcweir #include "document.hxx"
44cdf0e10cSrcweir #include "docpool.hxx"
45cdf0e10cSrcweir #include "patattr.hxx"
46cdf0e10cSrcweir #include "stlsheet.hxx"
47cdf0e10cSrcweir #include "stlpool.hxx"
48cdf0e10cSrcweir #include "markarr.hxx"
49cdf0e10cSrcweir #include "rechead.hxx"
50cdf0e10cSrcweir #include "globstr.hrc"
51cdf0e10cSrcweir #include "segmenttree.hxx"
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #undef DBG_INVALIDATE
54cdf0e10cSrcweir #define DBGOUTPUT(s) \
55cdf0e10cSrcweir 	DBG_ERROR( String("Invalidate ") + String(s) + String(": ") \
56cdf0e10cSrcweir 			   + String(nCol) + String('/') + String(aAdrStart.Row()) + String('/') + String(nTab) \
57cdf0e10cSrcweir 			   + String(" bis ") \
58cdf0e10cSrcweir 			   + String(nCol) + String('/') + String(aAdrEnd.Row())   + String('/') + String(nTab) \
59cdf0e10cSrcweir 			  );
60cdf0e10cSrcweir 
61cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
62cdf0e10cSrcweir 
63cdf0e10cSrcweir 
64cdf0e10cSrcweir //------------------------------------------------------------------------
65cdf0e10cSrcweir 
ScAttrArray(SCCOL nNewCol,SCTAB nNewTab,ScDocument * pDoc)66cdf0e10cSrcweir ScAttrArray::ScAttrArray( SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc ) :
67cdf0e10cSrcweir 	nCol( nNewCol ),
68cdf0e10cSrcweir 	nTab( nNewTab ),
69cdf0e10cSrcweir 	pDocument( pDoc )
70cdf0e10cSrcweir {
71cdf0e10cSrcweir     nCount = nLimit = 1;
72cdf0e10cSrcweir 	pData = new ScAttrEntry[1];
73cdf0e10cSrcweir 	if (pData)
74cdf0e10cSrcweir 	{
75cdf0e10cSrcweir 		pData[0].nRow = MAXROW;
76cdf0e10cSrcweir 		pData[0].pPattern = pDocument->GetDefPattern();		// ohne Put !!!
77cdf0e10cSrcweir 	}
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
80cdf0e10cSrcweir //------------------------------------------------------------------------
81cdf0e10cSrcweir 
~ScAttrArray()82cdf0e10cSrcweir ScAttrArray::~ScAttrArray()
83cdf0e10cSrcweir {
84cdf0e10cSrcweir #ifdef DBG_UTIL
85cdf0e10cSrcweir 	TestData();
86cdf0e10cSrcweir #endif
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 	if (pData)
89cdf0e10cSrcweir 	{
90cdf0e10cSrcweir 		ScDocumentPool* pDocPool = pDocument->GetPool();
91cdf0e10cSrcweir 		for (SCSIZE i=0; i<nCount; i++)
92cdf0e10cSrcweir 			pDocPool->Remove(*pData[i].pPattern);
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 		delete[] pData;
95cdf0e10cSrcweir 	}
96cdf0e10cSrcweir }
97cdf0e10cSrcweir 
98cdf0e10cSrcweir //------------------------------------------------------------------------
99cdf0e10cSrcweir #ifdef DBG_UTIL
TestData() const100cdf0e10cSrcweir void ScAttrArray::TestData() const
101cdf0e10cSrcweir {
102cdf0e10cSrcweir 
103cdf0e10cSrcweir 	sal_uInt16 nErr = 0;
104cdf0e10cSrcweir 	if (pData)
105cdf0e10cSrcweir 	{
106cdf0e10cSrcweir         SCSIZE nPos;
107cdf0e10cSrcweir 		for (nPos=0; nPos<nCount; nPos++)
108cdf0e10cSrcweir 		{
109cdf0e10cSrcweir 			if (nPos > 0)
110cdf0e10cSrcweir 				if (pData[nPos].pPattern == pData[nPos-1].pPattern || pData[nPos].nRow <= pData[nPos-1].nRow)
111cdf0e10cSrcweir 					++nErr;
112cdf0e10cSrcweir 			if (pData[nPos].pPattern->Which() != ATTR_PATTERN)
113cdf0e10cSrcweir 				++nErr;
114cdf0e10cSrcweir 		}
115cdf0e10cSrcweir         if ( nPos && pData[nPos-1].nRow != MAXROW )
116cdf0e10cSrcweir             ++nErr;
117cdf0e10cSrcweir 	}
118cdf0e10cSrcweir 	if (nErr)
119cdf0e10cSrcweir 	{
120cdf0e10cSrcweir 		ByteString aMsg = ByteString::CreateFromInt32(nErr);
121cdf0e10cSrcweir 		aMsg += " errors in attribute array, column ";
122cdf0e10cSrcweir 		aMsg += ByteString::CreateFromInt32(nCol);
123cdf0e10cSrcweir 		DBG_ERROR( aMsg.GetBuffer() );
124cdf0e10cSrcweir 	}
125cdf0e10cSrcweir }
126cdf0e10cSrcweir #endif
127cdf0e10cSrcweir 
128cdf0e10cSrcweir //------------------------------------------------------------------------
129cdf0e10cSrcweir 
Reset(const ScPatternAttr * pPattern,sal_Bool bAlloc)130cdf0e10cSrcweir void ScAttrArray::Reset( const ScPatternAttr* pPattern, sal_Bool bAlloc )
131cdf0e10cSrcweir {
132cdf0e10cSrcweir 	if (pData)
133cdf0e10cSrcweir 	{
134cdf0e10cSrcweir 		ScDocumentPool* 	 pDocPool = pDocument->GetPool();
135cdf0e10cSrcweir 		const ScPatternAttr* pOldPattern;
136cdf0e10cSrcweir 		ScAddress			 aAdrStart( nCol, 0, nTab );
137cdf0e10cSrcweir 		ScAddress			 aAdrEnd  ( nCol, 0, nTab );
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 		for (SCSIZE i=0; i<nCount; i++)
140cdf0e10cSrcweir 		{
141cdf0e10cSrcweir 			// ueberpruefen, ob Attributierung die Textbreite der Zelle aendert
142cdf0e10cSrcweir 			pOldPattern = pData[i].pPattern;
143cdf0e10cSrcweir 			sal_Bool bNumFormatChanged;
144cdf0e10cSrcweir 			if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
145cdf0e10cSrcweir 					pPattern->GetItemSet(), pOldPattern->GetItemSet() ) )
146cdf0e10cSrcweir 			{
147cdf0e10cSrcweir 				aAdrStart.SetRow( i ? pData[i-1].nRow+1 : 0 );
148cdf0e10cSrcweir 				aAdrEnd  .SetRow( pData[i].nRow );
149cdf0e10cSrcweir 				pDocument->InvalidateTextWidth( &aAdrStart, &aAdrEnd, bNumFormatChanged );
150cdf0e10cSrcweir #ifdef DBG_INVALIDATE
151cdf0e10cSrcweir 				DBGOUTPUT("Reset");
152cdf0e10cSrcweir #endif
153cdf0e10cSrcweir 			}
154cdf0e10cSrcweir 			// bedingtes Format gesetzt oder geloescht?
155cdf0e10cSrcweir 			if ( &pPattern->GetItem(ATTR_CONDITIONAL) != &pOldPattern->GetItem(ATTR_CONDITIONAL) )
156cdf0e10cSrcweir 			{
157cdf0e10cSrcweir 				pDocument->ConditionalChanged( ((const SfxUInt32Item&)
158cdf0e10cSrcweir 								pOldPattern->GetItem(ATTR_CONDITIONAL)).GetValue() );
159cdf0e10cSrcweir 				pDocument->ConditionalChanged( ((const SfxUInt32Item&)
160cdf0e10cSrcweir 								pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() );
161cdf0e10cSrcweir 			}
162cdf0e10cSrcweir 			pDocPool->Remove(*pOldPattern);
163cdf0e10cSrcweir 		}
164cdf0e10cSrcweir 		delete[] pData;
165cdf0e10cSrcweir 
166cdf0e10cSrcweir         if (pDocument->IsStreamValid(nTab))
167cdf0e10cSrcweir             pDocument->SetStreamValid(nTab, sal_False);
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 		if (bAlloc)
170cdf0e10cSrcweir 		{
171cdf0e10cSrcweir             nCount = nLimit = 1;
172cdf0e10cSrcweir 			pData = new ScAttrEntry[1];
173cdf0e10cSrcweir 			if (pData)
174cdf0e10cSrcweir 			{
175cdf0e10cSrcweir 				ScPatternAttr* pNewPattern = (ScPatternAttr*) &pDocPool->Put(*pPattern);
176cdf0e10cSrcweir 				pData[0].nRow = MAXROW;
177cdf0e10cSrcweir 				pData[0].pPattern = pNewPattern;
178cdf0e10cSrcweir 			}
179cdf0e10cSrcweir 		}
180cdf0e10cSrcweir 		else
181cdf0e10cSrcweir 		{
182cdf0e10cSrcweir             nCount = nLimit = 0;
183cdf0e10cSrcweir 			pData = NULL;				// muss sofort wieder belegt werden !
184cdf0e10cSrcweir 		}
185cdf0e10cSrcweir 	}
186cdf0e10cSrcweir }
187cdf0e10cSrcweir 
188cdf0e10cSrcweir 
Concat(SCSIZE nPos)189cdf0e10cSrcweir sal_Bool ScAttrArray::Concat(SCSIZE nPos)
190cdf0e10cSrcweir {
191cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
192cdf0e10cSrcweir 	if (pData && (nPos < nCount))
193cdf0e10cSrcweir 	{
194cdf0e10cSrcweir 		if (nPos > 0)
195cdf0e10cSrcweir 		{
196cdf0e10cSrcweir 			if (pData[nPos - 1].pPattern == pData[nPos].pPattern)
197cdf0e10cSrcweir 			{
198cdf0e10cSrcweir 				pData[nPos - 1].nRow = pData[nPos].nRow;
199cdf0e10cSrcweir 				pDocument->GetPool()->Remove(*pData[nPos].pPattern);
200cdf0e10cSrcweir 				memmove(&pData[nPos], &pData[nPos + 1], (nCount - nPos - 1) * sizeof(ScAttrEntry));
201cdf0e10cSrcweir 				pData[nCount - 1].pPattern = NULL;
202cdf0e10cSrcweir 				pData[nCount - 1].nRow = 0;
203cdf0e10cSrcweir 				nCount--;
204cdf0e10cSrcweir 				nPos--;
205cdf0e10cSrcweir 				bRet = sal_True;
206cdf0e10cSrcweir 			}
207cdf0e10cSrcweir 		}
208cdf0e10cSrcweir 		if (nPos + 1 < nCount)
209cdf0e10cSrcweir 		{
210cdf0e10cSrcweir 			if (pData[nPos + 1].pPattern == pData[nPos].pPattern)
211cdf0e10cSrcweir 			{
212cdf0e10cSrcweir 				pData[nPos].nRow = pData[nPos + 1].nRow;
213cdf0e10cSrcweir 				pDocument->GetPool()->Remove(*pData[nPos].pPattern);
214cdf0e10cSrcweir 				memmove(&pData[nPos + 1], &pData[nPos + 2], (nCount - nPos - 2) * sizeof(ScAttrEntry));
215cdf0e10cSrcweir 				pData[nCount - 1].pPattern = NULL;
216cdf0e10cSrcweir 				pData[nCount - 1].nRow = 0;
217cdf0e10cSrcweir 				nCount--;
218cdf0e10cSrcweir 				bRet = sal_True;
219cdf0e10cSrcweir 			}
220cdf0e10cSrcweir 		}
221cdf0e10cSrcweir 	}
222cdf0e10cSrcweir 	return bRet;
223cdf0e10cSrcweir }
224cdf0e10cSrcweir 
225cdf0e10cSrcweir //------------------------------------------------------------------------
226cdf0e10cSrcweir 
Search(SCROW nRow,SCSIZE & nIndex) const227cdf0e10cSrcweir sal_Bool ScAttrArray::Search( SCROW nRow, SCSIZE& nIndex ) const
228cdf0e10cSrcweir {
229cdf0e10cSrcweir 	long	nLo 		= 0;
230cdf0e10cSrcweir 	long	nHi 		= static_cast<long>(nCount) - 1;
231cdf0e10cSrcweir 	long	nStartRow	= 0;
232cdf0e10cSrcweir 	long	nEndRow		= 0;
233cdf0e10cSrcweir 	long	i			= 0;
234cdf0e10cSrcweir 	sal_Bool	bFound		= (nCount == 1);
235cdf0e10cSrcweir 	if (pData)
236cdf0e10cSrcweir 	{
237cdf0e10cSrcweir 		while ( !bFound && nLo <= nHi )
238cdf0e10cSrcweir 		{
239cdf0e10cSrcweir 			i = (nLo + nHi) / 2;
240cdf0e10cSrcweir 			if (i > 0)
241cdf0e10cSrcweir 				nStartRow = (long) pData[i - 1].nRow;
242cdf0e10cSrcweir 			else
243cdf0e10cSrcweir 				nStartRow = -1;
244cdf0e10cSrcweir 			nEndRow = (long) pData[i].nRow;
245cdf0e10cSrcweir 			if (nEndRow < (long) nRow)
246cdf0e10cSrcweir 				nLo = ++i;
247cdf0e10cSrcweir 			else
248cdf0e10cSrcweir 				if (nStartRow >= (long) nRow)
249cdf0e10cSrcweir 					nHi = --i;
250cdf0e10cSrcweir 				else
251cdf0e10cSrcweir 					bFound = sal_True;
252cdf0e10cSrcweir 		}
253cdf0e10cSrcweir 	}
254cdf0e10cSrcweir 	else
255cdf0e10cSrcweir 		bFound = sal_False;
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 	if (bFound)
258cdf0e10cSrcweir 		nIndex=(SCSIZE)i;
259cdf0e10cSrcweir 	else
260cdf0e10cSrcweir 		nIndex=0;
261cdf0e10cSrcweir 	return bFound;
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 
GetPattern(SCROW nRow) const265cdf0e10cSrcweir const ScPatternAttr* ScAttrArray::GetPattern( SCROW nRow ) const
266cdf0e10cSrcweir {
267cdf0e10cSrcweir 	SCSIZE i;
268cdf0e10cSrcweir 	if (Search( nRow, i ))
269cdf0e10cSrcweir 		return pData[i].pPattern;
270cdf0e10cSrcweir 	else
271cdf0e10cSrcweir 		return NULL;
272cdf0e10cSrcweir }
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 
GetPatternRange(SCROW & rStartRow,SCROW & rEndRow,SCROW nRow) const275cdf0e10cSrcweir const ScPatternAttr* ScAttrArray::GetPatternRange( SCROW& rStartRow,
276cdf0e10cSrcweir 		SCROW& rEndRow, SCROW nRow ) const
277cdf0e10cSrcweir {
278cdf0e10cSrcweir 	SCSIZE nIndex;
279cdf0e10cSrcweir 	if ( Search( nRow, nIndex ) )
280cdf0e10cSrcweir 	{
281cdf0e10cSrcweir 		if ( nIndex > 0 )
282cdf0e10cSrcweir 			rStartRow = pData[nIndex-1].nRow + 1;
283cdf0e10cSrcweir 		else
284cdf0e10cSrcweir 			rStartRow = 0;
285cdf0e10cSrcweir 		rEndRow = pData[nIndex].nRow;
286cdf0e10cSrcweir 		return pData[nIndex].pPattern;
287cdf0e10cSrcweir 	}
288cdf0e10cSrcweir 	return NULL;
289cdf0e10cSrcweir }
290cdf0e10cSrcweir 
291cdf0e10cSrcweir //------------------------------------------------------------------------
292cdf0e10cSrcweir 
SetPattern(SCROW nRow,const ScPatternAttr * pPattern,sal_Bool bPutToPool)293cdf0e10cSrcweir void ScAttrArray::SetPattern( SCROW nRow, const ScPatternAttr* pPattern, sal_Bool bPutToPool )
294cdf0e10cSrcweir {
295cdf0e10cSrcweir 	SetPatternArea( nRow, nRow, pPattern, bPutToPool );
296cdf0e10cSrcweir }
297cdf0e10cSrcweir 
Reserve(SCSIZE nReserve)298*8f4c7c28SSteve Yin bool ScAttrArray::Reserve( SCSIZE nReserve )
299*8f4c7c28SSteve Yin {
300*8f4c7c28SSteve Yin     if ( nCount <= nReserve )
301*8f4c7c28SSteve Yin     {
302*8f4c7c28SSteve Yin         if( ScAttrEntry* pNewData = new (std::nothrow) ScAttrEntry[nReserve] )
303*8f4c7c28SSteve Yin         {
304*8f4c7c28SSteve Yin             nLimit = nReserve;
305*8f4c7c28SSteve Yin             memcpy( pNewData, pData, nCount*sizeof(ScAttrEntry) );
306*8f4c7c28SSteve Yin             delete[] pData;
307*8f4c7c28SSteve Yin             pData = pNewData;
308*8f4c7c28SSteve Yin             return true;
309*8f4c7c28SSteve Yin         }
310*8f4c7c28SSteve Yin         else
311*8f4c7c28SSteve Yin             return false;
312*8f4c7c28SSteve Yin     }
313*8f4c7c28SSteve Yin     else
314*8f4c7c28SSteve Yin         return false;
315*8f4c7c28SSteve Yin }
316cdf0e10cSrcweir 
SetPatternArea(SCROW nStartRow,SCROW nEndRow,const ScPatternAttr * pPattern,sal_Bool bPutToPool)317cdf0e10cSrcweir void ScAttrArray::SetPatternArea(SCROW nStartRow, SCROW nEndRow, const ScPatternAttr *pPattern, sal_Bool bPutToPool )
318cdf0e10cSrcweir {
319cdf0e10cSrcweir 	if (ValidRow(nStartRow) && ValidRow(nEndRow))
320cdf0e10cSrcweir 	{
321cdf0e10cSrcweir 		if (bPutToPool)
322cdf0e10cSrcweir 			pPattern = (const ScPatternAttr*) &pDocument->GetPool()->Put(*pPattern);
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 		if ((nStartRow == 0) && (nEndRow == MAXROW))
325cdf0e10cSrcweir 			Reset(pPattern);
326cdf0e10cSrcweir 		else
327cdf0e10cSrcweir 		{
328cdf0e10cSrcweir             SCSIZE nNeeded = nCount + 2;
329cdf0e10cSrcweir             if ( nLimit < nNeeded )
330cdf0e10cSrcweir             {
331cdf0e10cSrcweir                 nLimit += SC_ATTRARRAY_DELTA;
332cdf0e10cSrcweir                 if ( nLimit < nNeeded )
333cdf0e10cSrcweir                     nLimit = nNeeded;
334cdf0e10cSrcweir                 ScAttrEntry* pNewData = new ScAttrEntry[nLimit];
335cdf0e10cSrcweir                 memcpy( pNewData, pData, nCount*sizeof(ScAttrEntry) );
336cdf0e10cSrcweir 				delete[] pData;
337cdf0e10cSrcweir 				pData = pNewData;
338cdf0e10cSrcweir             }
339cdf0e10cSrcweir 
340cdf0e10cSrcweir             ScAddress       aAdrStart( nCol, 0, nTab );
341cdf0e10cSrcweir             ScAddress       aAdrEnd  ( nCol, 0, nTab );
342cdf0e10cSrcweir 
343cdf0e10cSrcweir             SCSIZE ni = 0;      // number of entries in beginning
344cdf0e10cSrcweir             SCSIZE nx = 0;      // track position
345cdf0e10cSrcweir             SCROW ns = 0;      // start row of track position
346cdf0e10cSrcweir             if ( nStartRow > 0 )
347cdf0e10cSrcweir             {
348cdf0e10cSrcweir                 // skip beginning
349cdf0e10cSrcweir                 SCSIZE nIndex;
350cdf0e10cSrcweir                 Search( nStartRow, nIndex );
351cdf0e10cSrcweir                 ni = nIndex;
352cdf0e10cSrcweir 
353cdf0e10cSrcweir                 if ( ni > 0 )
354cdf0e10cSrcweir                 {
355cdf0e10cSrcweir                     nx = ni;
356cdf0e10cSrcweir                     ns = pData[ni-1].nRow+1;
357cdf0e10cSrcweir                 }
358cdf0e10cSrcweir             }
359cdf0e10cSrcweir 
360cdf0e10cSrcweir             // ueberpruefen, ob Attributierung die Textbreite der Zelle aendert
361cdf0e10cSrcweir             // oder bedingte Formate neu gesetzt oder geloescht werden
362cdf0e10cSrcweir             while ( ns <= nEndRow )
363cdf0e10cSrcweir             {
364cdf0e10cSrcweir                 const SfxItemSet& rNewSet = pPattern->GetItemSet();
365cdf0e10cSrcweir                 const SfxItemSet& rOldSet = pData[nx].pPattern->GetItemSet();
366cdf0e10cSrcweir 
367cdf0e10cSrcweir                 sal_Bool bNumFormatChanged;
368cdf0e10cSrcweir                 if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
369cdf0e10cSrcweir                         rNewSet, rOldSet ) )
370cdf0e10cSrcweir                 {
371cdf0e10cSrcweir                     aAdrStart.SetRow( Max(nStartRow,ns) );
372cdf0e10cSrcweir                     aAdrEnd  .SetRow( Min(nEndRow,pData[nx].nRow) );
373cdf0e10cSrcweir                     pDocument->InvalidateTextWidth( &aAdrStart, &aAdrEnd, bNumFormatChanged );
374cdf0e10cSrcweir #ifdef DBG_INVALIDATE
375cdf0e10cSrcweir                     DBGOUTPUT("SetPatternArea");
376cdf0e10cSrcweir #endif
377cdf0e10cSrcweir                 }
378cdf0e10cSrcweir                 if ( &rNewSet.Get(ATTR_CONDITIONAL) != &rOldSet.Get(ATTR_CONDITIONAL) )
379cdf0e10cSrcweir                 {
380cdf0e10cSrcweir                     pDocument->ConditionalChanged( ((const SfxUInt32Item&)
381cdf0e10cSrcweir                                     rOldSet.Get(ATTR_CONDITIONAL)).GetValue() );
382cdf0e10cSrcweir                     pDocument->ConditionalChanged( ((const SfxUInt32Item&)
383cdf0e10cSrcweir                                     rNewSet.Get(ATTR_CONDITIONAL)).GetValue() );
384cdf0e10cSrcweir                 }
385cdf0e10cSrcweir                 ns = pData[nx].nRow + 1;
386cdf0e10cSrcweir                 nx++;
387cdf0e10cSrcweir             }
388cdf0e10cSrcweir 
389cdf0e10cSrcweir             // continue modifying data array
390cdf0e10cSrcweir 
391cdf0e10cSrcweir             SCSIZE nInsert;     // insert position (MAXROWCOUNT := no insert)
392cdf0e10cSrcweir             sal_Bool bCombined = sal_False;
393cdf0e10cSrcweir             sal_Bool bSplit = sal_False;
394cdf0e10cSrcweir             if ( nStartRow > 0 )
395cdf0e10cSrcweir             {
396cdf0e10cSrcweir                 nInsert = MAXROWCOUNT;
397cdf0e10cSrcweir                 if ( pData[ni].pPattern != pPattern )
398cdf0e10cSrcweir                 {
399cdf0e10cSrcweir                     if ( ni == 0 || (pData[ni-1].nRow < nStartRow - 1) )
400cdf0e10cSrcweir                     {   // may be a split or a simple insert or just a shrink,
401cdf0e10cSrcweir                         // row adjustment is done further down
402cdf0e10cSrcweir                         if ( pData[ni].nRow > nEndRow )
403cdf0e10cSrcweir                             bSplit = sal_True;
404cdf0e10cSrcweir                         ni++;
405cdf0e10cSrcweir                         nInsert = ni;
406cdf0e10cSrcweir                     }
407cdf0e10cSrcweir                     else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
408cdf0e10cSrcweir                         nInsert = ni;
409cdf0e10cSrcweir                 }
410cdf0e10cSrcweir                 if ( ni > 0 && pData[ni-1].pPattern == pPattern )
411cdf0e10cSrcweir                 {   // combine
412cdf0e10cSrcweir                     pData[ni-1].nRow = nEndRow;
413cdf0e10cSrcweir                     nInsert = MAXROWCOUNT;
414cdf0e10cSrcweir                     bCombined = sal_True;
415cdf0e10cSrcweir                 }
416cdf0e10cSrcweir             }
417cdf0e10cSrcweir             else
418cdf0e10cSrcweir                 nInsert = 0;
419cdf0e10cSrcweir 
420cdf0e10cSrcweir             SCSIZE nj = ni;     // stop position of range to replace
421cdf0e10cSrcweir             while ( nj < nCount && pData[nj].nRow <= nEndRow )
422cdf0e10cSrcweir                 nj++;
423cdf0e10cSrcweir             if ( !bSplit )
424cdf0e10cSrcweir             {
425cdf0e10cSrcweir                 if ( nj < nCount && pData[nj].pPattern == pPattern )
426cdf0e10cSrcweir                 {   // combine
427cdf0e10cSrcweir                     if ( ni > 0 )
428cdf0e10cSrcweir                     {
429cdf0e10cSrcweir                         if ( pData[ni-1].pPattern == pPattern )
430cdf0e10cSrcweir                         {   // adjacent entries
431cdf0e10cSrcweir                             pData[ni-1].nRow = pData[nj].nRow;
432cdf0e10cSrcweir                             nj++;
433cdf0e10cSrcweir                         }
434cdf0e10cSrcweir                         else if ( ni == nInsert )
435cdf0e10cSrcweir                             pData[ni-1].nRow = nStartRow - 1;   // shrink
436cdf0e10cSrcweir                     }
437cdf0e10cSrcweir                     nInsert = MAXROWCOUNT;
438cdf0e10cSrcweir                     bCombined = sal_True;
439cdf0e10cSrcweir                 }
440cdf0e10cSrcweir                 else if ( ni > 0 && ni == nInsert )
441cdf0e10cSrcweir                     pData[ni-1].nRow = nStartRow - 1;   // shrink
442cdf0e10cSrcweir             }
443cdf0e10cSrcweir             ScDocumentPool* pDocPool = pDocument->GetPool();
444cdf0e10cSrcweir             if ( bSplit )
445cdf0e10cSrcweir             {   // duplicate splitted entry in pool
446cdf0e10cSrcweir                 pDocPool->Put( *pData[ni-1].pPattern );
447cdf0e10cSrcweir             }
448cdf0e10cSrcweir             if ( ni < nj )
449cdf0e10cSrcweir             {   // remove middle entries
450cdf0e10cSrcweir                 for ( SCSIZE nk=ni; nk<nj; nk++)
451cdf0e10cSrcweir                 {   // remove entries from pool
452cdf0e10cSrcweir                     pDocPool->Remove( *pData[nk].pPattern );
453cdf0e10cSrcweir                 }
454cdf0e10cSrcweir                 if ( !bCombined )
455cdf0e10cSrcweir                 {   // replace one entry
456cdf0e10cSrcweir                     pData[ni].nRow = nEndRow;
457cdf0e10cSrcweir                     pData[ni].pPattern = pPattern;
458cdf0e10cSrcweir                     ni++;
459cdf0e10cSrcweir                     nInsert = MAXROWCOUNT;
460cdf0e10cSrcweir                 }
461cdf0e10cSrcweir                 if ( ni < nj )
462cdf0e10cSrcweir                 {   // remove entries
463cdf0e10cSrcweir                     memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScAttrEntry) );
464cdf0e10cSrcweir                     nCount -= nj - ni;
465cdf0e10cSrcweir                 }
466cdf0e10cSrcweir             }
467cdf0e10cSrcweir 
468cdf0e10cSrcweir             if ( nInsert < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
469cdf0e10cSrcweir             {   // insert or append new entry
470cdf0e10cSrcweir                 if ( nInsert <= nCount )
471cdf0e10cSrcweir                 {
472cdf0e10cSrcweir                     if ( !bSplit )
473cdf0e10cSrcweir                         memmove( pData + nInsert + 1, pData + nInsert,
474cdf0e10cSrcweir                             (nCount - nInsert) * sizeof(ScAttrEntry) );
475cdf0e10cSrcweir                     else
476cdf0e10cSrcweir                     {
477cdf0e10cSrcweir                         memmove( pData + nInsert + 2, pData + nInsert,
478cdf0e10cSrcweir                             (nCount - nInsert) * sizeof(ScAttrEntry) );
479cdf0e10cSrcweir                         pData[nInsert+1] = pData[nInsert-1];
480cdf0e10cSrcweir                         nCount++;
481cdf0e10cSrcweir                     }
482cdf0e10cSrcweir                 }
483cdf0e10cSrcweir                 if ( nInsert )
484cdf0e10cSrcweir                     pData[nInsert-1].nRow = nStartRow - 1;
485cdf0e10cSrcweir                 pData[nInsert].nRow = nEndRow;
486cdf0e10cSrcweir                 pData[nInsert].pPattern = pPattern;
487cdf0e10cSrcweir                 nCount++;
488cdf0e10cSrcweir             }
489cdf0e10cSrcweir 
490cdf0e10cSrcweir             if (pDocument->IsStreamValid(nTab))
491cdf0e10cSrcweir                 pDocument->SetStreamValid(nTab, sal_False);
492cdf0e10cSrcweir 		}
493cdf0e10cSrcweir 	}
494cdf0e10cSrcweir //	InfoBox(0, String(nCount) + String(" Eintraege") ).Execute();
495cdf0e10cSrcweir 
496cdf0e10cSrcweir #ifdef DBG_UTIL
497cdf0e10cSrcweir     TestData();
498cdf0e10cSrcweir #endif
499cdf0e10cSrcweir }
500cdf0e10cSrcweir 
501cdf0e10cSrcweir 
ApplyStyleArea(SCROW nStartRow,SCROW nEndRow,ScStyleSheet * pStyle)502cdf0e10cSrcweir void ScAttrArray::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, ScStyleSheet* pStyle )
503cdf0e10cSrcweir {
504cdf0e10cSrcweir 	if (ValidRow(nStartRow) && ValidRow(nEndRow))
505cdf0e10cSrcweir 	{
506cdf0e10cSrcweir 		SCSIZE nPos;
507cdf0e10cSrcweir 		SCROW nStart=0;
508cdf0e10cSrcweir 		if (!Search( nStartRow, nPos ))
509cdf0e10cSrcweir 		{
510cdf0e10cSrcweir 			DBG_ERROR("Search-Fehler");
511cdf0e10cSrcweir 			return;
512cdf0e10cSrcweir 		}
513cdf0e10cSrcweir 
514cdf0e10cSrcweir 		ScAddress aAdrStart( nCol, 0, nTab );
515cdf0e10cSrcweir 		ScAddress aAdrEnd  ( nCol, 0, nTab );
516cdf0e10cSrcweir 
517cdf0e10cSrcweir 		do
518cdf0e10cSrcweir 		{
519cdf0e10cSrcweir 			const ScPatternAttr* pOldPattern = pData[nPos].pPattern;
520cdf0e10cSrcweir 			ScPatternAttr* pNewPattern = new ScPatternAttr(*pOldPattern);
521cdf0e10cSrcweir 			pNewPattern->SetStyleSheet(pStyle);
522cdf0e10cSrcweir 			SCROW nY1 = nStart;
523cdf0e10cSrcweir 			SCROW nY2 = pData[nPos].nRow;
524cdf0e10cSrcweir 			nStart = pData[nPos].nRow + 1;
525cdf0e10cSrcweir 
526cdf0e10cSrcweir 			if ( *pNewPattern == *pOldPattern )
527cdf0e10cSrcweir 			{
528cdf0e10cSrcweir 				// keep the original pattern (might be default)
529cdf0e10cSrcweir 				// pNewPattern is deleted below
530cdf0e10cSrcweir 				nPos++;
531cdf0e10cSrcweir 			}
532cdf0e10cSrcweir 			else if ( nY1 < nStartRow || nY2 > nEndRow )
533cdf0e10cSrcweir 			{
534cdf0e10cSrcweir 				if (nY1 < nStartRow) nY1=nStartRow;
535cdf0e10cSrcweir 				if (nY2 > nEndRow) nY2=nEndRow;
536cdf0e10cSrcweir 				SetPatternArea( nY1, nY2, pNewPattern, sal_True );
537cdf0e10cSrcweir 				Search( nStart, nPos );
538cdf0e10cSrcweir 			}
539cdf0e10cSrcweir 			else
540cdf0e10cSrcweir 			{
541cdf0e10cSrcweir 				// ueberpruefen, ob Attributierung die Textbreite der Zelle aendert
542cdf0e10cSrcweir 				// bedingte Formate in Vorlagen gibt es (noch) nicht
543cdf0e10cSrcweir 
544cdf0e10cSrcweir 				const SfxItemSet& rNewSet = pNewPattern->GetItemSet();
545cdf0e10cSrcweir 				const SfxItemSet& rOldSet = pOldPattern->GetItemSet();
546cdf0e10cSrcweir 
547cdf0e10cSrcweir 				sal_Bool bNumFormatChanged;
548cdf0e10cSrcweir 				if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
549cdf0e10cSrcweir 						rNewSet, rOldSet ) )
550cdf0e10cSrcweir 				{
551cdf0e10cSrcweir 					aAdrStart.SetRow( nPos ? pData[nPos-1].nRow+1 : 0 );
552cdf0e10cSrcweir 					aAdrEnd  .SetRow( pData[nPos].nRow );
553cdf0e10cSrcweir 					pDocument->InvalidateTextWidth( &aAdrStart, &aAdrEnd, bNumFormatChanged );
554cdf0e10cSrcweir #ifdef DBG_INVALIDATE
555cdf0e10cSrcweir 					DBGOUTPUT("ApplyStyleArea");
556cdf0e10cSrcweir #endif
557cdf0e10cSrcweir 				}
558cdf0e10cSrcweir 
559cdf0e10cSrcweir 				pDocument->GetPool()->Remove(*pData[nPos].pPattern);
560cdf0e10cSrcweir 				pData[nPos].pPattern = (const ScPatternAttr*)
561cdf0e10cSrcweir 											&pDocument->GetPool()->Put(*pNewPattern);
562cdf0e10cSrcweir 				if (Concat(nPos))
563cdf0e10cSrcweir 					Search(nStart, nPos);
564cdf0e10cSrcweir 				else
565cdf0e10cSrcweir 					nPos++;
566cdf0e10cSrcweir 			}
567cdf0e10cSrcweir 			delete pNewPattern;
568cdf0e10cSrcweir 		}
569cdf0e10cSrcweir 		while ((nStart <= nEndRow) && (nPos < nCount));
570cdf0e10cSrcweir 
571cdf0e10cSrcweir         if (pDocument->IsStreamValid(nTab))
572cdf0e10cSrcweir             pDocument->SetStreamValid(nTab, sal_False);
573cdf0e10cSrcweir 	}
574cdf0e10cSrcweir 
575cdf0e10cSrcweir #ifdef DBG_UTIL
576cdf0e10cSrcweir 	TestData();
577cdf0e10cSrcweir #endif
578cdf0e10cSrcweir }
579cdf0e10cSrcweir 
580cdf0e10cSrcweir 
581cdf0e10cSrcweir 	// const wird weggecastet, weil es sonst
582cdf0e10cSrcweir 	// zu ineffizient/kompliziert wird!
583cdf0e10cSrcweir #define SET_LINECOLOR(dest,c)						\
584cdf0e10cSrcweir 	if ((dest))										\
585cdf0e10cSrcweir 	{												\
586cdf0e10cSrcweir 		((SvxBorderLine*)(dest))->SetColor((c));	\
587cdf0e10cSrcweir 	}
588cdf0e10cSrcweir 
589cdf0e10cSrcweir #define SET_LINE(dest,src) 								\
590cdf0e10cSrcweir 	if ((dest))											\
591cdf0e10cSrcweir 	{													\
592cdf0e10cSrcweir 		SvxBorderLine* pCast = (SvxBorderLine*)(dest);	\
593cdf0e10cSrcweir 		pCast->SetOutWidth((src)->GetOutWidth());		\
594cdf0e10cSrcweir 		pCast->SetInWidth ((src)->GetInWidth());		\
595cdf0e10cSrcweir 		pCast->SetDistance((src)->GetDistance());		\
596cdf0e10cSrcweir 	}
597cdf0e10cSrcweir 
ApplyLineStyleArea(SCROW nStartRow,SCROW nEndRow,const SvxBorderLine * pLine,sal_Bool bColorOnly)598cdf0e10cSrcweir void ScAttrArray::ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow,
599cdf0e10cSrcweir 									  const SvxBorderLine* pLine, sal_Bool bColorOnly )
600cdf0e10cSrcweir {
601cdf0e10cSrcweir 	if ( bColorOnly && !pLine )
602cdf0e10cSrcweir 		return;
603cdf0e10cSrcweir 
604cdf0e10cSrcweir 	if (ValidRow(nStartRow) && ValidRow(nEndRow))
605cdf0e10cSrcweir 	{
606cdf0e10cSrcweir 		SCSIZE nPos;
607cdf0e10cSrcweir 		SCROW nStart=0;
608cdf0e10cSrcweir 		if (!Search( nStartRow, nPos ))
609cdf0e10cSrcweir 		{
610cdf0e10cSrcweir 			DBG_ERROR("Search-Fehler");
611cdf0e10cSrcweir 			return;
612cdf0e10cSrcweir 		}
613cdf0e10cSrcweir 
614cdf0e10cSrcweir 		do
615cdf0e10cSrcweir 		{
616cdf0e10cSrcweir 			const ScPatternAttr*	pOldPattern = pData[nPos].pPattern;
617cdf0e10cSrcweir             const SfxItemSet&       rOldSet = pOldPattern->GetItemSet();
618cdf0e10cSrcweir             const SfxPoolItem*      pBoxItem = 0;
619cdf0e10cSrcweir             SfxItemState            eState = rOldSet.GetItemState( ATTR_BORDER, sal_True, &pBoxItem );
620cdf0e10cSrcweir             const SfxPoolItem*      pTLBRItem = 0;
621cdf0e10cSrcweir             SfxItemState            eTLBRState = rOldSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem );
622cdf0e10cSrcweir             const SfxPoolItem*      pBLTRItem = 0;
623cdf0e10cSrcweir             SfxItemState            eBLTRState = rOldSet.GetItemState( ATTR_BORDER_BLTR, sal_True, &pBLTRItem );
624cdf0e10cSrcweir 
625cdf0e10cSrcweir             if ( (SFX_ITEM_SET == eState) || (SFX_ITEM_SET == eTLBRState) || (SFX_ITEM_SET == eBLTRState) )
626cdf0e10cSrcweir 			{
627cdf0e10cSrcweir 				ScPatternAttr*	pNewPattern = new ScPatternAttr(*pOldPattern);
628cdf0e10cSrcweir                 SfxItemSet&     rNewSet = pNewPattern->GetItemSet();
629cdf0e10cSrcweir 				SCROW			nY1 = nStart;
630cdf0e10cSrcweir 				SCROW			nY2 = pData[nPos].nRow;
631cdf0e10cSrcweir 
632cdf0e10cSrcweir                 SvxBoxItem*     pNewBoxItem = pBoxItem ? (SvxBoxItem*)pBoxItem->Clone() : 0;
633cdf0e10cSrcweir                 SvxLineItem*    pNewTLBRItem = pTLBRItem ? (SvxLineItem*)pTLBRItem->Clone() : 0;
634cdf0e10cSrcweir                 SvxLineItem*    pNewBLTRItem = pBLTRItem ? (SvxLineItem*)pBLTRItem->Clone() : 0;
635cdf0e10cSrcweir 
636cdf0e10cSrcweir 				// Linienattribute holen und mit Parametern aktualisieren
637cdf0e10cSrcweir 
638cdf0e10cSrcweir 				if ( !pLine )
639cdf0e10cSrcweir 				{
640cdf0e10cSrcweir                     if( pNewBoxItem )
641cdf0e10cSrcweir                     {
642cdf0e10cSrcweir                         if ( pNewBoxItem->GetTop() )    pNewBoxItem->SetLine( NULL, BOX_LINE_TOP );
643cdf0e10cSrcweir                         if ( pNewBoxItem->GetBottom() ) pNewBoxItem->SetLine( NULL, BOX_LINE_BOTTOM );
644cdf0e10cSrcweir                         if ( pNewBoxItem->GetLeft() )   pNewBoxItem->SetLine( NULL, BOX_LINE_LEFT );
645cdf0e10cSrcweir                         if ( pNewBoxItem->GetRight() )  pNewBoxItem->SetLine( NULL, BOX_LINE_RIGHT );
646cdf0e10cSrcweir                     }
647cdf0e10cSrcweir                     if( pNewTLBRItem && pNewTLBRItem->GetLine() )
648cdf0e10cSrcweir                         pNewTLBRItem->SetLine( 0 );
649cdf0e10cSrcweir                     if( pNewBLTRItem && pNewBLTRItem->GetLine() )
650cdf0e10cSrcweir                         pNewBLTRItem->SetLine( 0 );
651cdf0e10cSrcweir 				}
652cdf0e10cSrcweir 				else
653cdf0e10cSrcweir 				{
654cdf0e10cSrcweir 					if ( bColorOnly )
655cdf0e10cSrcweir 					{
656cdf0e10cSrcweir                         Color aColor( pLine->GetColor() );
657cdf0e10cSrcweir                         if( pNewBoxItem )
658cdf0e10cSrcweir                         {
659cdf0e10cSrcweir                             SET_LINECOLOR( pNewBoxItem->GetTop(),    aColor );
660cdf0e10cSrcweir                             SET_LINECOLOR( pNewBoxItem->GetBottom(), aColor );
661cdf0e10cSrcweir                             SET_LINECOLOR( pNewBoxItem->GetLeft(),   aColor );
662cdf0e10cSrcweir                             SET_LINECOLOR( pNewBoxItem->GetRight(),   aColor );
663cdf0e10cSrcweir                         }
664cdf0e10cSrcweir                         if( pNewTLBRItem )
665cdf0e10cSrcweir                             SET_LINECOLOR( pNewTLBRItem->GetLine(), aColor );
666cdf0e10cSrcweir                         if( pNewBLTRItem )
667cdf0e10cSrcweir                             SET_LINECOLOR( pNewBLTRItem->GetLine(), aColor );
668cdf0e10cSrcweir 					}
669cdf0e10cSrcweir 					else
670cdf0e10cSrcweir 					{
671cdf0e10cSrcweir                         if( pNewBoxItem )
672cdf0e10cSrcweir                         {
673cdf0e10cSrcweir                             SET_LINE( pNewBoxItem->GetTop(),    pLine );
674cdf0e10cSrcweir                             SET_LINE( pNewBoxItem->GetBottom(), pLine );
675cdf0e10cSrcweir                             SET_LINE( pNewBoxItem->GetLeft(),   pLine );
676cdf0e10cSrcweir                             SET_LINE( pNewBoxItem->GetRight(),   pLine );
677cdf0e10cSrcweir                         }
678cdf0e10cSrcweir                         if( pNewTLBRItem )
679cdf0e10cSrcweir                             SET_LINE( pNewTLBRItem->GetLine(), pLine );
680cdf0e10cSrcweir                         if( pNewBLTRItem )
681cdf0e10cSrcweir                             SET_LINE( pNewBLTRItem->GetLine(), pLine );
682cdf0e10cSrcweir 					}
683cdf0e10cSrcweir 				}
684cdf0e10cSrcweir                 if( pNewBoxItem )   rNewSet.Put( *pNewBoxItem );
685cdf0e10cSrcweir                 if( pNewTLBRItem )  rNewSet.Put( *pNewTLBRItem );
686cdf0e10cSrcweir                 if( pNewBLTRItem )  rNewSet.Put( *pNewBLTRItem );
687cdf0e10cSrcweir 
688cdf0e10cSrcweir 				nStart = pData[nPos].nRow + 1;
689cdf0e10cSrcweir 
690cdf0e10cSrcweir 				if ( nY1 < nStartRow || nY2 > nEndRow )
691cdf0e10cSrcweir 				{
692cdf0e10cSrcweir 					if (nY1 < nStartRow) nY1=nStartRow;
693cdf0e10cSrcweir 					if (nY2 > nEndRow) nY2=nEndRow;
694cdf0e10cSrcweir 					SetPatternArea( nY1, nY2, pNewPattern, sal_True );
695cdf0e10cSrcweir 					Search( nStart, nPos );
696cdf0e10cSrcweir 				}
697cdf0e10cSrcweir 				else
698cdf0e10cSrcweir 				{
699cdf0e10cSrcweir 						//! aus Pool loeschen?
700cdf0e10cSrcweir 					pDocument->GetPool()->Remove(*pData[nPos].pPattern);
701cdf0e10cSrcweir 					pData[nPos].pPattern = (const ScPatternAttr*)
702cdf0e10cSrcweir 								&pDocument->GetPool()->Put(*pNewPattern);
703cdf0e10cSrcweir 
704cdf0e10cSrcweir 					if (Concat(nPos))
705cdf0e10cSrcweir 						Search(nStart, nPos);
706cdf0e10cSrcweir 					else
707cdf0e10cSrcweir 						nPos++;
708cdf0e10cSrcweir 				}
709cdf0e10cSrcweir                 delete pNewBoxItem;
710cdf0e10cSrcweir                 delete pNewTLBRItem;
711cdf0e10cSrcweir                 delete pNewBLTRItem;
712cdf0e10cSrcweir 				delete pNewPattern;
713cdf0e10cSrcweir 			}
714cdf0e10cSrcweir 			else
715cdf0e10cSrcweir 			{
716cdf0e10cSrcweir 				nStart = pData[nPos].nRow + 1;
717cdf0e10cSrcweir 				nPos++;
718cdf0e10cSrcweir 			}
719cdf0e10cSrcweir 		}
720cdf0e10cSrcweir 		while ((nStart <= nEndRow) && (nPos < nCount));
721cdf0e10cSrcweir 	}
722cdf0e10cSrcweir }
723cdf0e10cSrcweir 
724cdf0e10cSrcweir #undef SET_LINECOLOR
725cdf0e10cSrcweir #undef SET_LINE
726cdf0e10cSrcweir 
727cdf0e10cSrcweir 
ApplyCacheArea(SCROW nStartRow,SCROW nEndRow,SfxItemPoolCache * pCache)728cdf0e10cSrcweir void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache )
729cdf0e10cSrcweir {
730cdf0e10cSrcweir #ifdef DBG_UTIL
731cdf0e10cSrcweir 	TestData();
732cdf0e10cSrcweir #endif
733cdf0e10cSrcweir 
734cdf0e10cSrcweir 	if (ValidRow(nStartRow) && ValidRow(nEndRow))
735cdf0e10cSrcweir 	{
736cdf0e10cSrcweir 		SCSIZE nPos;
737cdf0e10cSrcweir 		SCROW nStart=0;
738cdf0e10cSrcweir 		if (!Search( nStartRow, nPos ))
739cdf0e10cSrcweir 		{
740cdf0e10cSrcweir 			DBG_ERROR("Search-Fehler");
741cdf0e10cSrcweir 			return;
742cdf0e10cSrcweir 		}
743cdf0e10cSrcweir 
744cdf0e10cSrcweir 		ScAddress aAdrStart( nCol, 0, nTab );
745cdf0e10cSrcweir 		ScAddress aAdrEnd  ( nCol, 0, nTab );
746cdf0e10cSrcweir 
747cdf0e10cSrcweir 		do
748cdf0e10cSrcweir 		{
749cdf0e10cSrcweir 			const ScPatternAttr* pOldPattern = pData[nPos].pPattern;
750cdf0e10cSrcweir 			const ScPatternAttr* pNewPattern = (const ScPatternAttr*) &pCache->ApplyTo( *pOldPattern, sal_True );
751cdf0e10cSrcweir 			ScDocumentPool::CheckRef( *pOldPattern );
752cdf0e10cSrcweir 			ScDocumentPool::CheckRef( *pNewPattern );
753cdf0e10cSrcweir 			if (pNewPattern != pOldPattern)
754cdf0e10cSrcweir 			{
755cdf0e10cSrcweir 				SCROW nY1 = nStart;
756cdf0e10cSrcweir 				SCROW nY2 = pData[nPos].nRow;
757cdf0e10cSrcweir 				nStart = pData[nPos].nRow + 1;
758cdf0e10cSrcweir 
759cdf0e10cSrcweir 				if ( nY1 < nStartRow || nY2 > nEndRow )
760cdf0e10cSrcweir 				{
761cdf0e10cSrcweir 					if (nY1 < nStartRow) nY1=nStartRow;
762cdf0e10cSrcweir 					if (nY2 > nEndRow) nY2=nEndRow;
763cdf0e10cSrcweir 					SetPatternArea( nY1, nY2, pNewPattern );
764cdf0e10cSrcweir 					Search( nStart, nPos );
765cdf0e10cSrcweir 				}
766cdf0e10cSrcweir 				else
767cdf0e10cSrcweir 				{
768cdf0e10cSrcweir 					// ueberpruefen, ob Attributierung die Textbreite der Zelle aendert
769cdf0e10cSrcweir 
770cdf0e10cSrcweir 					const SfxItemSet& rNewSet = pNewPattern->GetItemSet();
771cdf0e10cSrcweir 					const SfxItemSet& rOldSet = pOldPattern->GetItemSet();
772cdf0e10cSrcweir 
773cdf0e10cSrcweir 					sal_Bool bNumFormatChanged;
774cdf0e10cSrcweir 					if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
775cdf0e10cSrcweir 							rNewSet, rOldSet ) )
776cdf0e10cSrcweir 					{
777cdf0e10cSrcweir 						aAdrStart.SetRow( nPos ? pData[nPos-1].nRow+1 : 0 );
778cdf0e10cSrcweir 						aAdrEnd  .SetRow( pData[nPos].nRow );
779cdf0e10cSrcweir 						pDocument->InvalidateTextWidth( &aAdrStart, &aAdrEnd, bNumFormatChanged );
780cdf0e10cSrcweir #ifdef DBG_INVALIDATE
781cdf0e10cSrcweir 						DBGOUTPUT("ApplyCacheArea");
782cdf0e10cSrcweir #endif
783cdf0e10cSrcweir 					}
784cdf0e10cSrcweir 
785cdf0e10cSrcweir 					// bedingte Formate neu gesetzt oder geloescht ?
786cdf0e10cSrcweir 
787cdf0e10cSrcweir 					if ( &rNewSet.Get(ATTR_CONDITIONAL) != &rOldSet.Get(ATTR_CONDITIONAL) )
788cdf0e10cSrcweir 					{
789cdf0e10cSrcweir 						pDocument->ConditionalChanged( ((const SfxUInt32Item&)
790cdf0e10cSrcweir 										rOldSet.Get(ATTR_CONDITIONAL)).GetValue() );
791cdf0e10cSrcweir 						pDocument->ConditionalChanged( ((const SfxUInt32Item&)
792cdf0e10cSrcweir 										rNewSet.Get(ATTR_CONDITIONAL)).GetValue() );
793cdf0e10cSrcweir 					}
794cdf0e10cSrcweir 
795cdf0e10cSrcweir 					pDocument->GetPool()->Remove(*pData[nPos].pPattern);
796cdf0e10cSrcweir 					pData[nPos].pPattern = pNewPattern;
797cdf0e10cSrcweir 					if (Concat(nPos))
798cdf0e10cSrcweir 						Search(nStart, nPos);
799cdf0e10cSrcweir 					else
800cdf0e10cSrcweir 						++nPos;
801cdf0e10cSrcweir 				}
802cdf0e10cSrcweir 			}
803cdf0e10cSrcweir 			else
804cdf0e10cSrcweir 			{
805cdf0e10cSrcweir //!!!!!!!!!!!!!!!!!! mit diesem Remove gibt es Abstuerze (Calc1 Import)
806cdf0e10cSrcweir //!				pDocument->GetPool()->Remove(*pNewPattern);
807cdf0e10cSrcweir 				nStart = pData[nPos].nRow + 1;
808cdf0e10cSrcweir 				++nPos;
809cdf0e10cSrcweir 			}
810cdf0e10cSrcweir 		}
811cdf0e10cSrcweir 		while (nStart <= nEndRow);
812cdf0e10cSrcweir 
813cdf0e10cSrcweir         if (pDocument->IsStreamValid(nTab))
814cdf0e10cSrcweir             pDocument->SetStreamValid(nTab, sal_False);
815cdf0e10cSrcweir 	}
816cdf0e10cSrcweir 
817cdf0e10cSrcweir #ifdef DBG_UTIL
818cdf0e10cSrcweir 	TestData();
819cdf0e10cSrcweir #endif
820cdf0e10cSrcweir }
821cdf0e10cSrcweir 
822cdf0e10cSrcweir 
lcl_MergeDeep(SfxItemSet & rMergeSet,const SfxItemSet & rSource)823cdf0e10cSrcweir void lcl_MergeDeep( SfxItemSet& rMergeSet, const SfxItemSet& rSource )
824cdf0e10cSrcweir {
825cdf0e10cSrcweir 	const SfxPoolItem* pNewItem;
826cdf0e10cSrcweir 	const SfxPoolItem* pOldItem;
827cdf0e10cSrcweir 	for (sal_uInt16 nId=ATTR_PATTERN_START; nId<=ATTR_PATTERN_END; nId++)
828cdf0e10cSrcweir 	{
829cdf0e10cSrcweir 		//	pMergeSet hat keinen Parent
830cdf0e10cSrcweir 		SfxItemState eOldState = rMergeSet.GetItemState( nId, sal_False, &pOldItem );
831cdf0e10cSrcweir 
832cdf0e10cSrcweir 		if ( eOldState == SFX_ITEM_DEFAULT )				// Default
833cdf0e10cSrcweir 		{
834cdf0e10cSrcweir 			SfxItemState eNewState = rSource.GetItemState( nId, sal_True, &pNewItem );
835cdf0e10cSrcweir 			if ( eNewState == SFX_ITEM_SET )
836cdf0e10cSrcweir 			{
837cdf0e10cSrcweir 				if ( *pNewItem != rMergeSet.GetPool()->GetDefaultItem(nId) )
838cdf0e10cSrcweir 					rMergeSet.InvalidateItem( nId );
839cdf0e10cSrcweir 			}
840cdf0e10cSrcweir 		}
841cdf0e10cSrcweir 		else if ( eOldState == SFX_ITEM_SET )				// Item gesetzt
842cdf0e10cSrcweir 		{
843cdf0e10cSrcweir 			SfxItemState eNewState = rSource.GetItemState( nId, sal_True, &pNewItem );
844cdf0e10cSrcweir 			if ( eNewState == SFX_ITEM_SET )
845cdf0e10cSrcweir 			{
846cdf0e10cSrcweir 				if ( pNewItem != pOldItem )					// beide gepuhlt
847cdf0e10cSrcweir 					rMergeSet.InvalidateItem( nId );
848cdf0e10cSrcweir 			}
849cdf0e10cSrcweir 			else			// Default
850cdf0e10cSrcweir 			{
851cdf0e10cSrcweir 				if ( *pOldItem != rSource.GetPool()->GetDefaultItem(nId) )
852cdf0e10cSrcweir 					rMergeSet.InvalidateItem( nId );
853cdf0e10cSrcweir 			}
854cdf0e10cSrcweir 		}
855cdf0e10cSrcweir 		//	Dontcare bleibt Dontcare
856cdf0e10cSrcweir 	}
857cdf0e10cSrcweir }
858cdf0e10cSrcweir 
859cdf0e10cSrcweir 
MergePatternArea(SCROW nStartRow,SCROW nEndRow,ScMergePatternState & rState,sal_Bool bDeep) const860cdf0e10cSrcweir void ScAttrArray::MergePatternArea( SCROW nStartRow, SCROW nEndRow,
861cdf0e10cSrcweir 									ScMergePatternState& rState, sal_Bool bDeep ) const
862cdf0e10cSrcweir {
863cdf0e10cSrcweir 	if (ValidRow(nStartRow) && ValidRow(nEndRow))
864cdf0e10cSrcweir 	{
865cdf0e10cSrcweir 		SCSIZE nPos;
866cdf0e10cSrcweir 		SCROW nStart=0;
867cdf0e10cSrcweir 		if (!Search( nStartRow, nPos ))
868cdf0e10cSrcweir 		{
869cdf0e10cSrcweir 			DBG_ERROR("Search-Fehler");
870cdf0e10cSrcweir 			return;
871cdf0e10cSrcweir 		}
872cdf0e10cSrcweir 
873cdf0e10cSrcweir 		do
874cdf0e10cSrcweir 		{
875cdf0e10cSrcweir 			//	gleiche Patterns muessen nicht mehrfach angesehen werden
876cdf0e10cSrcweir 
877cdf0e10cSrcweir 			const ScPatternAttr* pPattern = pData[nPos].pPattern;
878cdf0e10cSrcweir 			if ( pPattern != rState.pOld1 && pPattern != rState.pOld2 )
879cdf0e10cSrcweir 			{
880cdf0e10cSrcweir 				const SfxItemSet& rThisSet = pPattern->GetItemSet();
881cdf0e10cSrcweir 				if (rState.pItemSet)
882cdf0e10cSrcweir 				{
883cdf0e10cSrcweir 					//	(*ppSet)->MergeValues( rThisSet, sal_False );
884cdf0e10cSrcweir 					//	geht nicht, weil die Vorlagen nicht beruecksichtigt werden
885cdf0e10cSrcweir 
886cdf0e10cSrcweir 					if (bDeep)
887cdf0e10cSrcweir 						lcl_MergeDeep( *rState.pItemSet, rThisSet );
888cdf0e10cSrcweir 					else
889cdf0e10cSrcweir 						rState.pItemSet->MergeValues( rThisSet, sal_False );
890cdf0e10cSrcweir 				}
891cdf0e10cSrcweir 				else
892cdf0e10cSrcweir 				{
893cdf0e10cSrcweir 					//	erstes Pattern - in Set ohne Parent kopieren
894cdf0e10cSrcweir 					rState.pItemSet = new SfxItemSet( *rThisSet.GetPool(), rThisSet.GetRanges() );
895cdf0e10cSrcweir 					rState.pItemSet->Set( rThisSet, bDeep );
896cdf0e10cSrcweir 				}
897cdf0e10cSrcweir 
898cdf0e10cSrcweir 				rState.pOld2 = rState.pOld1;
899cdf0e10cSrcweir 				rState.pOld1 = pPattern;
900cdf0e10cSrcweir 			}
901cdf0e10cSrcweir 
902cdf0e10cSrcweir 			nStart = pData[nPos].nRow + 1;
903cdf0e10cSrcweir 			++nPos;
904cdf0e10cSrcweir 		}
905cdf0e10cSrcweir 		while (nStart <= nEndRow);
906cdf0e10cSrcweir 	}
907cdf0e10cSrcweir }
908cdf0e10cSrcweir 
909cdf0e10cSrcweir 
910cdf0e10cSrcweir 
911cdf0e10cSrcweir //			Umrandung zusammenbauen
912cdf0e10cSrcweir 
lcl_TestAttr(const SvxBorderLine * pOldLine,const SvxBorderLine * pNewLine,sal_uInt8 & rModified,const SvxBorderLine * & rpNew)913cdf0e10cSrcweir sal_Bool lcl_TestAttr( const SvxBorderLine* pOldLine, const SvxBorderLine* pNewLine,
914cdf0e10cSrcweir 							sal_uInt8& rModified, const SvxBorderLine*& rpNew )
915cdf0e10cSrcweir {
916cdf0e10cSrcweir 	if (rModified == SC_LINE_DONTCARE)
917cdf0e10cSrcweir 		return sal_False;						// weiter geht's nicht
918cdf0e10cSrcweir 
919cdf0e10cSrcweir 	if (rModified == SC_LINE_EMPTY)
920cdf0e10cSrcweir 	{
921cdf0e10cSrcweir 		rModified = SC_LINE_SET;
922cdf0e10cSrcweir 		rpNew = pNewLine;
923cdf0e10cSrcweir 		return sal_True;						// zum ersten mal gesetzt
924cdf0e10cSrcweir 	}
925cdf0e10cSrcweir 
926cdf0e10cSrcweir 	if (pOldLine == pNewLine)
927cdf0e10cSrcweir 	{
928cdf0e10cSrcweir 		rpNew = pOldLine;
929cdf0e10cSrcweir 		return sal_False;
930cdf0e10cSrcweir 	}
931cdf0e10cSrcweir 
932cdf0e10cSrcweir 	if (pOldLine && pNewLine)
933cdf0e10cSrcweir 		if (*pOldLine == *pNewLine)
934cdf0e10cSrcweir 		{
935cdf0e10cSrcweir 			rpNew = pOldLine;
936cdf0e10cSrcweir 			return sal_False;
937cdf0e10cSrcweir 		}
938cdf0e10cSrcweir 
939cdf0e10cSrcweir 	rModified = SC_LINE_DONTCARE;
940cdf0e10cSrcweir 	rpNew = NULL;
941cdf0e10cSrcweir 	return sal_True;							// andere Linie -> dontcare
942cdf0e10cSrcweir }
943cdf0e10cSrcweir 
944cdf0e10cSrcweir 
lcl_MergeToFrame(SvxBoxItem * pLineOuter,SvxBoxInfoItem * pLineInner,ScLineFlags & rFlags,const ScPatternAttr * pPattern,sal_Bool bLeft,SCCOL nDistRight,sal_Bool bTop,SCROW nDistBottom)945cdf0e10cSrcweir void lcl_MergeToFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner,
946cdf0e10cSrcweir 								ScLineFlags& rFlags, const ScPatternAttr* pPattern,
947cdf0e10cSrcweir 								sal_Bool bLeft, SCCOL nDistRight, sal_Bool bTop, SCROW nDistBottom )
948cdf0e10cSrcweir {
949cdf0e10cSrcweir 	//	rechten/unteren Rahmen setzen, wenn Zelle bis zum Ende zusammengefasst:
950cdf0e10cSrcweir 	const ScMergeAttr& rMerge = (const ScMergeAttr&)pPattern->GetItem(ATTR_MERGE);
951cdf0e10cSrcweir 	if ( rMerge.GetColMerge() == nDistRight + 1 )
952cdf0e10cSrcweir 		nDistRight = 0;
953cdf0e10cSrcweir 	if ( rMerge.GetRowMerge() == nDistBottom + 1 )
954cdf0e10cSrcweir 		nDistBottom = 0;
955cdf0e10cSrcweir 
956cdf0e10cSrcweir 	const SvxBoxItem* pCellFrame = (SvxBoxItem*) &pPattern->GetItemSet().Get( ATTR_BORDER );
957cdf0e10cSrcweir 	const SvxBorderLine* pLeftAttr	 = pCellFrame->GetLeft();
958cdf0e10cSrcweir 	const SvxBorderLine* pRightAttr	 = pCellFrame->GetRight();
959cdf0e10cSrcweir 	const SvxBorderLine* pTopAttr	 = pCellFrame->GetTop();
960cdf0e10cSrcweir 	const SvxBorderLine* pBottomAttr = pCellFrame->GetBottom();
961cdf0e10cSrcweir 	const SvxBorderLine* pNew;
962cdf0e10cSrcweir 
963cdf0e10cSrcweir 	if (bTop)
964cdf0e10cSrcweir 	{
965cdf0e10cSrcweir 		if (lcl_TestAttr( pLineOuter->GetTop(), pTopAttr, rFlags.nTop, pNew ))
966cdf0e10cSrcweir 			pLineOuter->SetLine( pNew, BOX_LINE_TOP );
967cdf0e10cSrcweir 	}
968cdf0e10cSrcweir 	else
969cdf0e10cSrcweir 	{
970cdf0e10cSrcweir 		if (lcl_TestAttr( pLineInner->GetHori(), pTopAttr, rFlags.nHori, pNew ))
971cdf0e10cSrcweir 			pLineInner->SetLine( pNew, BOXINFO_LINE_HORI );
972cdf0e10cSrcweir 	}
973cdf0e10cSrcweir 
974cdf0e10cSrcweir 	if (nDistBottom == 0)
975cdf0e10cSrcweir 	{
976cdf0e10cSrcweir 		if (lcl_TestAttr( pLineOuter->GetBottom(), pBottomAttr, rFlags.nBottom, pNew ))
977cdf0e10cSrcweir 			pLineOuter->SetLine( pNew, BOX_LINE_BOTTOM );
978cdf0e10cSrcweir 	}
979cdf0e10cSrcweir 	else
980cdf0e10cSrcweir 	{
981cdf0e10cSrcweir 		if (lcl_TestAttr( pLineInner->GetHori(), pBottomAttr, rFlags.nHori, pNew ))
982cdf0e10cSrcweir 			pLineInner->SetLine( pNew, BOXINFO_LINE_HORI );
983cdf0e10cSrcweir 	}
984cdf0e10cSrcweir 
985cdf0e10cSrcweir 	if (bLeft)
986cdf0e10cSrcweir 	{
987cdf0e10cSrcweir 		if (lcl_TestAttr( pLineOuter->GetLeft(), pLeftAttr, rFlags.nLeft, pNew ))
988cdf0e10cSrcweir 			pLineOuter->SetLine( pNew, BOX_LINE_LEFT );
989cdf0e10cSrcweir 	}
990cdf0e10cSrcweir 	else
991cdf0e10cSrcweir 	{
992cdf0e10cSrcweir 		if (lcl_TestAttr( pLineInner->GetVert(), pLeftAttr, rFlags.nVert, pNew ))
993cdf0e10cSrcweir 			pLineInner->SetLine( pNew, BOXINFO_LINE_VERT );
994cdf0e10cSrcweir 	}
995cdf0e10cSrcweir 
996cdf0e10cSrcweir 	if (nDistRight == 0)
997cdf0e10cSrcweir 	{
998cdf0e10cSrcweir 		if (lcl_TestAttr( pLineOuter->GetRight(), pRightAttr, rFlags.nRight, pNew ))
999cdf0e10cSrcweir 			pLineOuter->SetLine( pNew, BOX_LINE_RIGHT );
1000cdf0e10cSrcweir 	}
1001cdf0e10cSrcweir 	else
1002cdf0e10cSrcweir 	{
1003cdf0e10cSrcweir 		if (lcl_TestAttr( pLineInner->GetVert(), pRightAttr, rFlags.nVert, pNew ))
1004cdf0e10cSrcweir 			pLineInner->SetLine( pNew, BOXINFO_LINE_VERT );
1005cdf0e10cSrcweir 	}
1006cdf0e10cSrcweir }
1007cdf0e10cSrcweir 
1008cdf0e10cSrcweir 
MergeBlockFrame(SvxBoxItem * pLineOuter,SvxBoxInfoItem * pLineInner,ScLineFlags & rFlags,SCROW nStartRow,SCROW nEndRow,sal_Bool bLeft,SCCOL nDistRight) const1009cdf0e10cSrcweir void ScAttrArray::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner,
1010cdf0e10cSrcweir 					ScLineFlags& rFlags,
1011cdf0e10cSrcweir 					SCROW nStartRow, SCROW nEndRow, sal_Bool bLeft, SCCOL nDistRight ) const
1012cdf0e10cSrcweir {
1013cdf0e10cSrcweir 	const ScPatternAttr* pPattern;
1014cdf0e10cSrcweir 
1015cdf0e10cSrcweir 	if (nStartRow == nEndRow)
1016cdf0e10cSrcweir 	{
1017cdf0e10cSrcweir 		pPattern = GetPattern( nStartRow );
1018cdf0e10cSrcweir 		lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, pPattern, bLeft, nDistRight, sal_True, 0 );
1019cdf0e10cSrcweir 	}
1020cdf0e10cSrcweir 	else
1021cdf0e10cSrcweir 	{
1022cdf0e10cSrcweir 		pPattern = GetPattern( nStartRow );
1023cdf0e10cSrcweir 		lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, pPattern, bLeft, nDistRight, sal_True,
1024cdf0e10cSrcweir 							nEndRow-nStartRow );
1025cdf0e10cSrcweir 
1026cdf0e10cSrcweir 		SCSIZE nStartIndex;
1027cdf0e10cSrcweir 		SCSIZE nEndIndex;
1028cdf0e10cSrcweir 		Search( nStartRow+1, nStartIndex );
1029cdf0e10cSrcweir 		Search( nEndRow-1, nEndIndex );
1030cdf0e10cSrcweir 		for (SCSIZE i=nStartIndex; i<=nEndIndex; i++)
1031cdf0e10cSrcweir 		{
1032cdf0e10cSrcweir 			pPattern = (ScPatternAttr*) pData[i].pPattern;
1033cdf0e10cSrcweir 			lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, pPattern, bLeft, nDistRight, sal_False,
1034cdf0e10cSrcweir 							nEndRow - Min( pData[i].nRow, (SCROW)(nEndRow-1) ) );
1035cdf0e10cSrcweir 			// nDistBottom hier immer > 0
1036cdf0e10cSrcweir 		}
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir 		pPattern = GetPattern( nEndRow );
1039cdf0e10cSrcweir 		lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, pPattern, bLeft, nDistRight, sal_False, 0 );
1040cdf0e10cSrcweir 	}
1041cdf0e10cSrcweir }
1042cdf0e10cSrcweir 
1043cdf0e10cSrcweir //
1044cdf0e10cSrcweir //	Rahmen anwenden
1045cdf0e10cSrcweir //
1046cdf0e10cSrcweir 
1047cdf0e10cSrcweir //	ApplyFrame - auf einen Eintrag im Array
1048cdf0e10cSrcweir 
1049cdf0e10cSrcweir 
ApplyFrame(const SvxBoxItem * pBoxItem,const SvxBoxInfoItem * pBoxInfoItem,SCROW nStartRow,SCROW nEndRow,sal_Bool bLeft,SCCOL nDistRight,sal_Bool bTop,SCROW nDistBottom)1050cdf0e10cSrcweir sal_Bool ScAttrArray::ApplyFrame( const SvxBoxItem*		pBoxItem,
1051cdf0e10cSrcweir 							  const SvxBoxInfoItem* pBoxInfoItem,
1052cdf0e10cSrcweir 							  SCROW nStartRow, SCROW nEndRow,
1053cdf0e10cSrcweir 							  sal_Bool bLeft, SCCOL nDistRight, sal_Bool bTop, SCROW nDistBottom )
1054cdf0e10cSrcweir {
1055cdf0e10cSrcweir 	DBG_ASSERT( pBoxItem && pBoxInfoItem, "Linienattribute fehlen!" );
1056cdf0e10cSrcweir 
1057cdf0e10cSrcweir 	const ScPatternAttr* pPattern = GetPattern( nStartRow );
1058cdf0e10cSrcweir 	const SvxBoxItem* pOldFrame = (const SvxBoxItem*)
1059cdf0e10cSrcweir 								  &pPattern->GetItemSet().Get( ATTR_BORDER );
1060cdf0e10cSrcweir 
1061cdf0e10cSrcweir 	//	rechten/unteren Rahmen setzen, wenn Zelle bis zum Ende zusammengefasst:
1062cdf0e10cSrcweir 	const ScMergeAttr& rMerge = (const ScMergeAttr&)pPattern->GetItem(ATTR_MERGE);
1063cdf0e10cSrcweir 	if ( rMerge.GetColMerge() == nDistRight + 1 )
1064cdf0e10cSrcweir 		nDistRight = 0;
1065cdf0e10cSrcweir 	if ( rMerge.GetRowMerge() == nDistBottom + 1 )
1066cdf0e10cSrcweir 		nDistBottom = 0;
1067cdf0e10cSrcweir 
1068cdf0e10cSrcweir 	SvxBoxItem aNewFrame( *pOldFrame );
1069cdf0e10cSrcweir 
1070cdf0e10cSrcweir 	if ( bLeft ? pBoxInfoItem->IsValid(VALID_LEFT) : pBoxInfoItem->IsValid(VALID_VERT) )
1071cdf0e10cSrcweir 		aNewFrame.SetLine( bLeft ? pBoxItem->GetLeft() : pBoxInfoItem->GetVert(),
1072cdf0e10cSrcweir 			BOX_LINE_LEFT );
1073cdf0e10cSrcweir 	if ( (nDistRight==0) ? pBoxInfoItem->IsValid(VALID_RIGHT) : pBoxInfoItem->IsValid(VALID_VERT) )
1074cdf0e10cSrcweir 		aNewFrame.SetLine( (nDistRight==0) ? pBoxItem->GetRight() : pBoxInfoItem->GetVert(),
1075cdf0e10cSrcweir 			BOX_LINE_RIGHT );
1076cdf0e10cSrcweir 	if ( bTop ? pBoxInfoItem->IsValid(VALID_TOP) : pBoxInfoItem->IsValid(VALID_HORI) )
1077cdf0e10cSrcweir 		aNewFrame.SetLine( bTop ? pBoxItem->GetTop() : pBoxInfoItem->GetHori(),
1078cdf0e10cSrcweir 			BOX_LINE_TOP );
1079cdf0e10cSrcweir 	if ( (nDistBottom==0) ? pBoxInfoItem->IsValid(VALID_BOTTOM) : pBoxInfoItem->IsValid(VALID_HORI) )
1080cdf0e10cSrcweir 		aNewFrame.SetLine( (nDistBottom==0) ? pBoxItem->GetBottom() : pBoxInfoItem->GetHori(),
1081cdf0e10cSrcweir 			BOX_LINE_BOTTOM );
1082cdf0e10cSrcweir 
1083cdf0e10cSrcweir 	if (aNewFrame == *pOldFrame)
1084cdf0e10cSrcweir 	{
1085cdf0e10cSrcweir 		// nothing to do
1086cdf0e10cSrcweir 		return sal_False;
1087cdf0e10cSrcweir 	}
1088cdf0e10cSrcweir 	else
1089cdf0e10cSrcweir 	{
1090cdf0e10cSrcweir 		SfxItemPoolCache aCache( pDocument->GetPool(), &aNewFrame );
1091cdf0e10cSrcweir 		ApplyCacheArea( nStartRow, nEndRow, &aCache );
1092cdf0e10cSrcweir 
1093cdf0e10cSrcweir /*		ScPatternAttr* pNewPattern = (ScPatternAttr*) pPattern->Clone();
1094cdf0e10cSrcweir 		pNewPattern->GetItemSet().Put( aNewFrame );
1095cdf0e10cSrcweir 		SetPatternArea( nStartRow, nEndRow, pNewPattern, sal_True );
1096cdf0e10cSrcweir */
1097cdf0e10cSrcweir 		return sal_True;
1098cdf0e10cSrcweir 	}
1099cdf0e10cSrcweir }
1100cdf0e10cSrcweir 
1101cdf0e10cSrcweir 
ApplyBlockFrame(const SvxBoxItem * pLineOuter,const SvxBoxInfoItem * pLineInner,SCROW nStartRow,SCROW nEndRow,sal_Bool bLeft,SCCOL nDistRight)1102cdf0e10cSrcweir void ScAttrArray::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
1103cdf0e10cSrcweir 							SCROW nStartRow, SCROW nEndRow, sal_Bool bLeft, SCCOL nDistRight )
1104cdf0e10cSrcweir {
1105cdf0e10cSrcweir 	if (nStartRow == nEndRow)
1106cdf0e10cSrcweir 		ApplyFrame( pLineOuter, pLineInner, nStartRow, nEndRow, bLeft, nDistRight, sal_True, 0 );
1107cdf0e10cSrcweir 	else
1108cdf0e10cSrcweir 	{
1109cdf0e10cSrcweir 		ApplyFrame( pLineOuter, pLineInner, nStartRow, nStartRow, bLeft, nDistRight,
1110cdf0e10cSrcweir 						sal_True, nEndRow-nStartRow );
1111cdf0e10cSrcweir 
1112cdf0e10cSrcweir 		if ( nEndRow > nStartRow+1 )				// innerer Teil vorhanden?
1113cdf0e10cSrcweir 		{
1114cdf0e10cSrcweir 			SCSIZE nStartIndex;
1115cdf0e10cSrcweir 			SCSIZE nEndIndex;
1116cdf0e10cSrcweir 			Search( nStartRow+1, nStartIndex );
1117cdf0e10cSrcweir 			Search( nEndRow-1, nEndIndex );
1118cdf0e10cSrcweir 			SCROW nTmpStart = nStartRow+1;
1119cdf0e10cSrcweir 			SCROW nTmpEnd;
1120cdf0e10cSrcweir 			for (SCSIZE i=nStartIndex; i<=nEndIndex;)
1121cdf0e10cSrcweir 			{
1122cdf0e10cSrcweir 				nTmpEnd = Min( (SCROW)(nEndRow-1), (SCROW)(pData[i].nRow) );
1123cdf0e10cSrcweir 				sal_Bool bChanged = ApplyFrame( pLineOuter, pLineInner, nTmpStart, nTmpEnd,
1124cdf0e10cSrcweir 											bLeft, nDistRight, sal_False, nEndRow-nTmpEnd );
1125cdf0e10cSrcweir 				nTmpStart = nTmpEnd+1;
1126cdf0e10cSrcweir 				if (bChanged)
1127cdf0e10cSrcweir 				{
1128cdf0e10cSrcweir 					Search(nTmpStart, i);
1129cdf0e10cSrcweir 					Search(nEndRow-1, nEndIndex);
1130cdf0e10cSrcweir 				}
1131cdf0e10cSrcweir 				else
1132cdf0e10cSrcweir 					i++;
1133cdf0e10cSrcweir 			}
1134cdf0e10cSrcweir 		}
1135cdf0e10cSrcweir 
1136cdf0e10cSrcweir 		ApplyFrame( pLineOuter, pLineInner, nEndRow, nEndRow, bLeft, nDistRight, sal_False, 0 );
1137cdf0e10cSrcweir 	}
1138cdf0e10cSrcweir }
1139cdf0e10cSrcweir 
1140cdf0e10cSrcweir 
lcl_LineSize(const SvxBorderLine & rLine)1141cdf0e10cSrcweir long lcl_LineSize( const SvxBorderLine& rLine )
1142cdf0e10cSrcweir {
1143cdf0e10cSrcweir 	//	nur eine Linie -> halbe Breite, min. 20
1144cdf0e10cSrcweir 	//	doppelte Linie -> halber Abstand + eine Linie (je min. 20)
1145cdf0e10cSrcweir 
1146cdf0e10cSrcweir 	long nTotal = 0;
1147cdf0e10cSrcweir 	sal_uInt16 nWidth = Max( rLine.GetOutWidth(), rLine.GetInWidth() );
1148cdf0e10cSrcweir 	sal_uInt16 nDist = rLine.GetDistance();
1149cdf0e10cSrcweir 	if (nDist)
1150cdf0e10cSrcweir 	{
1151cdf0e10cSrcweir 		DBG_ASSERT( rLine.GetOutWidth() && rLine.GetInWidth(),
1152cdf0e10cSrcweir 						"Linie hat Abstand, aber nur eine Breite ???" );
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir //		nTotal += ( nDist > 40 ) ? ( nDist / 2 ) : 20;
1155cdf0e10cSrcweir 		nTotal += ( nDist > 20 ) ? nDist : 20;
1156cdf0e10cSrcweir 		nTotal += ( nWidth > 20 ) ? nWidth : 20;
1157cdf0e10cSrcweir 	}
1158cdf0e10cSrcweir 	else if (nWidth)
1159cdf0e10cSrcweir //		nTotal += ( nWidth > 40 ) ? ( nWidth / 2 ) : 20;
1160cdf0e10cSrcweir 		nTotal += ( nWidth > 20 ) ? nWidth  : 20;
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir 		//!	auch halbieren ???
1163cdf0e10cSrcweir 
1164cdf0e10cSrcweir 	return nTotal;
1165cdf0e10cSrcweir }
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir 
HasLines(SCROW nRow1,SCROW nRow2,Rectangle & rSizes,sal_Bool bLeft,sal_Bool bRight) const1168cdf0e10cSrcweir sal_Bool ScAttrArray::HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes,
1169cdf0e10cSrcweir 								sal_Bool bLeft, sal_Bool bRight ) const
1170cdf0e10cSrcweir {
1171cdf0e10cSrcweir 	SCSIZE nStartIndex;
1172cdf0e10cSrcweir 	SCSIZE nEndIndex;
1173cdf0e10cSrcweir 	Search( nRow1, nStartIndex );
1174cdf0e10cSrcweir 	Search( nRow2, nEndIndex );
1175cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
1176cdf0e10cSrcweir 
1177cdf0e10cSrcweir 	const SvxBoxItem* pItem = 0;
1178cdf0e10cSrcweir 	const SvxBorderLine* pLine = 0;
1179cdf0e10cSrcweir 	long nCmp;
1180cdf0e10cSrcweir 
1181cdf0e10cSrcweir 	//	oben
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir 	pItem = (const SvxBoxItem*) &pData[nStartIndex].pPattern->GetItem(ATTR_BORDER);
1184cdf0e10cSrcweir 	pLine = pItem->GetTop();
1185cdf0e10cSrcweir 	if (pLine)
1186cdf0e10cSrcweir 	{
1187cdf0e10cSrcweir 		nCmp = lcl_LineSize(*pLine);
1188cdf0e10cSrcweir 		if ( nCmp > rSizes.Top() )
1189cdf0e10cSrcweir 			rSizes.Top() = nCmp;
1190cdf0e10cSrcweir 		bFound = sal_True;
1191cdf0e10cSrcweir 	}
1192cdf0e10cSrcweir 
1193cdf0e10cSrcweir 	//	unten
1194cdf0e10cSrcweir 
1195cdf0e10cSrcweir 	if ( nEndIndex != nStartIndex )
1196cdf0e10cSrcweir 		pItem = (const SvxBoxItem*) &pData[nEndIndex].pPattern->GetItem(ATTR_BORDER);
1197cdf0e10cSrcweir 	pLine = pItem->GetBottom();
1198cdf0e10cSrcweir 	if (pLine)
1199cdf0e10cSrcweir 	{
1200cdf0e10cSrcweir 		nCmp = lcl_LineSize(*pLine);
1201cdf0e10cSrcweir 		if ( nCmp > rSizes.Bottom() )
1202cdf0e10cSrcweir 			rSizes.Bottom() = nCmp;
1203cdf0e10cSrcweir 		bFound = sal_True;
1204cdf0e10cSrcweir 	}
1205cdf0e10cSrcweir 
1206cdf0e10cSrcweir 	if ( bLeft || bRight )
1207cdf0e10cSrcweir 		for ( SCSIZE i=nStartIndex; i<=nEndIndex; i++)
1208cdf0e10cSrcweir 		{
1209cdf0e10cSrcweir 			pItem = (const SvxBoxItem*) &pData[i].pPattern->GetItem(ATTR_BORDER);
1210cdf0e10cSrcweir 
1211cdf0e10cSrcweir 			//	links
1212cdf0e10cSrcweir 
1213cdf0e10cSrcweir 			if (bLeft)
1214cdf0e10cSrcweir 			{
1215cdf0e10cSrcweir 				pLine = pItem->GetLeft();
1216cdf0e10cSrcweir 				if (pLine)
1217cdf0e10cSrcweir 				{
1218cdf0e10cSrcweir 					nCmp = lcl_LineSize(*pLine);
1219cdf0e10cSrcweir 					if ( nCmp > rSizes.Left() )
1220cdf0e10cSrcweir 						rSizes.Left() = nCmp;
1221cdf0e10cSrcweir 					bFound = sal_True;
1222cdf0e10cSrcweir 				}
1223cdf0e10cSrcweir 			}
1224cdf0e10cSrcweir 
1225cdf0e10cSrcweir 			//	rechts
1226cdf0e10cSrcweir 
1227cdf0e10cSrcweir 			if (bRight)
1228cdf0e10cSrcweir 			{
1229cdf0e10cSrcweir 				pLine = pItem->GetRight();
1230cdf0e10cSrcweir 				if (pLine)
1231cdf0e10cSrcweir 				{
1232cdf0e10cSrcweir 					nCmp = lcl_LineSize(*pLine);
1233cdf0e10cSrcweir 					if ( nCmp > rSizes.Right() )
1234cdf0e10cSrcweir 						rSizes.Right() = nCmp;
1235cdf0e10cSrcweir 					bFound = sal_True;
1236cdf0e10cSrcweir 				}
1237cdf0e10cSrcweir 			}
1238cdf0e10cSrcweir 		}
1239cdf0e10cSrcweir 
1240cdf0e10cSrcweir 	return bFound;
1241cdf0e10cSrcweir }
1242cdf0e10cSrcweir 
1243cdf0e10cSrcweir //	Testen, ob Bereich bestimmtes Attribut enthaelt
1244cdf0e10cSrcweir 
HasAttrib(SCROW nRow1,SCROW nRow2,sal_uInt16 nMask) const1245cdf0e10cSrcweir bool ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const
1246cdf0e10cSrcweir {
1247cdf0e10cSrcweir     SCSIZE nStartIndex;
1248cdf0e10cSrcweir     SCSIZE nEndIndex;
1249cdf0e10cSrcweir     Search( nRow1, nStartIndex );
1250cdf0e10cSrcweir     Search( nRow2, nEndIndex );
1251cdf0e10cSrcweir     bool bFound = false;
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir     for (SCSIZE i=nStartIndex; i<=nEndIndex && !bFound; i++)
1254cdf0e10cSrcweir     {
1255cdf0e10cSrcweir         const ScPatternAttr* pPattern = pData[i].pPattern;
1256cdf0e10cSrcweir         if ( nMask & HASATTR_MERGED )
1257cdf0e10cSrcweir         {
1258cdf0e10cSrcweir             const ScMergeAttr* pMerge =
1259cdf0e10cSrcweir                     (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE );
1260cdf0e10cSrcweir             if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 )
1261cdf0e10cSrcweir                 bFound = true;
1262cdf0e10cSrcweir         }
1263cdf0e10cSrcweir         if ( nMask & ( HASATTR_OVERLAPPED | HASATTR_NOTOVERLAPPED | HASATTR_AUTOFILTER ) )
1264cdf0e10cSrcweir         {
1265cdf0e10cSrcweir             const ScMergeFlagAttr* pMergeFlag =
1266cdf0e10cSrcweir                     (const ScMergeFlagAttr*) &pPattern->GetItem( ATTR_MERGE_FLAG );
1267cdf0e10cSrcweir             if ( (nMask & HASATTR_OVERLAPPED) && pMergeFlag->IsOverlapped() )
1268cdf0e10cSrcweir                 bFound = true;
1269cdf0e10cSrcweir             if ( (nMask & HASATTR_NOTOVERLAPPED) && !pMergeFlag->IsOverlapped() )
1270cdf0e10cSrcweir                 bFound = true;
1271cdf0e10cSrcweir             if ( (nMask & HASATTR_AUTOFILTER) && pMergeFlag->HasAutoFilter() )
1272cdf0e10cSrcweir                 bFound = true;
1273cdf0e10cSrcweir         }
1274cdf0e10cSrcweir         if ( nMask & HASATTR_LINES )
1275cdf0e10cSrcweir         {
1276cdf0e10cSrcweir             const SvxBoxItem* pBox =
1277cdf0e10cSrcweir                     (const SvxBoxItem*) &pPattern->GetItem( ATTR_BORDER );
1278cdf0e10cSrcweir             if ( pBox->GetLeft() || pBox->GetRight() || pBox->GetTop() || pBox->GetBottom() )
1279cdf0e10cSrcweir                 bFound = true;
1280cdf0e10cSrcweir         }
1281cdf0e10cSrcweir         if ( nMask & HASATTR_SHADOW )
1282cdf0e10cSrcweir         {
1283cdf0e10cSrcweir             const SvxShadowItem* pShadow =
1284cdf0e10cSrcweir                     (const SvxShadowItem*) &pPattern->GetItem( ATTR_SHADOW );
1285cdf0e10cSrcweir             if ( pShadow->GetLocation() != SVX_SHADOW_NONE )
1286cdf0e10cSrcweir                 bFound = true;
1287cdf0e10cSrcweir         }
1288cdf0e10cSrcweir         if ( nMask & HASATTR_CONDITIONAL )
1289cdf0e10cSrcweir         {
1290cdf0e10cSrcweir             const SfxUInt32Item* pConditional =
1291cdf0e10cSrcweir                     (const SfxUInt32Item*) &pPattern->GetItem( ATTR_CONDITIONAL );
1292cdf0e10cSrcweir             if ( pConditional->GetValue() != 0 )
1293cdf0e10cSrcweir                 bFound = true;
1294cdf0e10cSrcweir         }
1295cdf0e10cSrcweir         if ( nMask & HASATTR_PROTECTED )
1296cdf0e10cSrcweir         {
1297cdf0e10cSrcweir             const ScProtectionAttr* pProtect =
1298cdf0e10cSrcweir                     (const ScProtectionAttr*) &pPattern->GetItem( ATTR_PROTECTION );
1299cdf0e10cSrcweir             if ( pProtect->GetProtection() || pProtect->GetHideCell() )
1300cdf0e10cSrcweir                 bFound = true;
1301cdf0e10cSrcweir         }
1302cdf0e10cSrcweir         if ( nMask & HASATTR_ROTATE )
1303cdf0e10cSrcweir         {
1304cdf0e10cSrcweir             const SfxInt32Item* pRotate =
1305cdf0e10cSrcweir                     (const SfxInt32Item*) &pPattern->GetItem( ATTR_ROTATE_VALUE );
1306cdf0e10cSrcweir             // 90 or 270 degrees is former SvxOrientationItem - only look for other values
1307cdf0e10cSrcweir             // (see ScPatternAttr::GetCellOrientation)
1308cdf0e10cSrcweir             sal_Int32 nAngle = pRotate->GetValue();
1309cdf0e10cSrcweir             if ( nAngle != 0 && nAngle != 9000 && nAngle != 27000 )
1310cdf0e10cSrcweir                 bFound = true;
1311cdf0e10cSrcweir         }
1312cdf0e10cSrcweir         if ( nMask & HASATTR_NEEDHEIGHT )
1313cdf0e10cSrcweir         {
1314cdf0e10cSrcweir             if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD)
1315cdf0e10cSrcweir                 bFound = true;
1316cdf0e10cSrcweir             else if (((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK )).GetValue())
1317cdf0e10cSrcweir                 bFound = true;
1318cdf0e10cSrcweir             else if ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
1319cdf0e10cSrcweir                         GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK)
1320cdf0e10cSrcweir                 bFound = true;
1321cdf0e10cSrcweir             else if (((const SfxUInt32Item&)pPattern->GetItem( ATTR_CONDITIONAL )).GetValue())
1322cdf0e10cSrcweir                 bFound = true;
1323cdf0e10cSrcweir             else if (((const SfxInt32Item&)pPattern->GetItem( ATTR_ROTATE_VALUE )).GetValue())
1324cdf0e10cSrcweir                 bFound = true;
1325cdf0e10cSrcweir         }
1326cdf0e10cSrcweir         if ( nMask & ( HASATTR_SHADOW_RIGHT | HASATTR_SHADOW_DOWN ) )
1327cdf0e10cSrcweir         {
1328cdf0e10cSrcweir             const SvxShadowItem* pShadow =
1329cdf0e10cSrcweir                     (const SvxShadowItem*) &pPattern->GetItem( ATTR_SHADOW );
1330cdf0e10cSrcweir             SvxShadowLocation eLoc = pShadow->GetLocation();
1331cdf0e10cSrcweir             if ( nMask & HASATTR_SHADOW_RIGHT )
1332cdf0e10cSrcweir                 if ( eLoc == SVX_SHADOW_TOPRIGHT || eLoc == SVX_SHADOW_BOTTOMRIGHT )
1333cdf0e10cSrcweir                     bFound = true;
1334cdf0e10cSrcweir             if ( nMask & HASATTR_SHADOW_DOWN )
1335cdf0e10cSrcweir                 if ( eLoc == SVX_SHADOW_BOTTOMLEFT || eLoc == SVX_SHADOW_BOTTOMRIGHT )
1336cdf0e10cSrcweir                     bFound = true;
1337cdf0e10cSrcweir         }
1338cdf0e10cSrcweir         if ( nMask & HASATTR_RTL )
1339cdf0e10cSrcweir         {
1340cdf0e10cSrcweir             const SvxFrameDirectionItem& rDirection =
1341cdf0e10cSrcweir                     (const SvxFrameDirectionItem&) pPattern->GetItem( ATTR_WRITINGDIR );
1342cdf0e10cSrcweir             if ( rDirection.GetValue() == FRMDIR_HORI_RIGHT_TOP )
1343cdf0e10cSrcweir                 bFound = true;
1344cdf0e10cSrcweir         }
1345cdf0e10cSrcweir         if ( nMask & HASATTR_RIGHTORCENTER )
1346cdf0e10cSrcweir         {
1347cdf0e10cSrcweir             //  called only if the sheet is LTR, so physical=logical alignment can be assumed
1348cdf0e10cSrcweir             SvxCellHorJustify eHorJust = (SvxCellHorJustify)
1349cdf0e10cSrcweir                     ((const SvxHorJustifyItem&) pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
1350cdf0e10cSrcweir             if ( eHorJust == SVX_HOR_JUSTIFY_RIGHT || eHorJust == SVX_HOR_JUSTIFY_CENTER )
1351cdf0e10cSrcweir                 bFound = true;
1352cdf0e10cSrcweir         }
1353cdf0e10cSrcweir     }
1354cdf0e10cSrcweir 
1355cdf0e10cSrcweir     return bFound;
1356cdf0e10cSrcweir }
1357cdf0e10cSrcweir 
1358cdf0e10cSrcweir //	Bereich um evtl. enthaltene Zusammenfassungen erweitern
1359cdf0e10cSrcweir //	und evtl. MergeFlag anpassen (bRefresh)
1360cdf0e10cSrcweir 
ExtendMerge(SCCOL nThisCol,SCROW nStartRow,SCROW nEndRow,SCCOL & rPaintCol,SCROW & rPaintRow,sal_Bool bRefresh,sal_Bool bAttrs)1361cdf0e10cSrcweir sal_Bool ScAttrArray::ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
1362cdf0e10cSrcweir 								SCCOL& rPaintCol, SCROW& rPaintRow,
1363cdf0e10cSrcweir 								sal_Bool bRefresh, sal_Bool bAttrs )
1364cdf0e10cSrcweir {
1365cdf0e10cSrcweir 	const ScPatternAttr* pPattern;
1366cdf0e10cSrcweir 	const ScMergeAttr* pItem;
1367cdf0e10cSrcweir 	SCSIZE nStartIndex;
1368cdf0e10cSrcweir 	SCSIZE nEndIndex;
1369cdf0e10cSrcweir 	Search( nStartRow, nStartIndex );
1370cdf0e10cSrcweir 	Search( nEndRow, nEndIndex );
1371cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
1372cdf0e10cSrcweir 
1373cdf0e10cSrcweir 	for (SCSIZE i=nStartIndex; i<=nEndIndex; i++)
1374cdf0e10cSrcweir 	{
1375cdf0e10cSrcweir 		pPattern = pData[i].pPattern;
1376cdf0e10cSrcweir 		pItem = (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE );
1377cdf0e10cSrcweir 		SCsCOL	nCountX = pItem->GetColMerge();
1378cdf0e10cSrcweir 		SCsROW	nCountY = pItem->GetRowMerge();
1379cdf0e10cSrcweir 		if (nCountX>1 || nCountY>1)
1380cdf0e10cSrcweir 		{
1381cdf0e10cSrcweir 			SCROW nThisRow = (i>0) ? pData[i-1].nRow+1 : 0;
1382cdf0e10cSrcweir 			SCCOL nMergeEndCol = nThisCol + nCountX - 1;
1383cdf0e10cSrcweir 			SCROW nMergeEndRow = nThisRow + nCountY - 1;
1384cdf0e10cSrcweir 			if (nMergeEndCol > rPaintCol && nMergeEndCol <= MAXCOL)
1385cdf0e10cSrcweir 				rPaintCol = nMergeEndCol;
1386cdf0e10cSrcweir 			if (nMergeEndRow > rPaintRow && nMergeEndRow <= MAXROW)
1387cdf0e10cSrcweir 				rPaintRow = nMergeEndRow;
1388cdf0e10cSrcweir 			bFound = sal_True;
1389cdf0e10cSrcweir 
1390cdf0e10cSrcweir 			if (bAttrs)
1391cdf0e10cSrcweir 			{
1392cdf0e10cSrcweir 				const SvxShadowItem* pShadow =
1393cdf0e10cSrcweir 						(const SvxShadowItem*) &pPattern->GetItem( ATTR_SHADOW );
1394cdf0e10cSrcweir 				SvxShadowLocation eLoc = pShadow->GetLocation();
1395cdf0e10cSrcweir 				if ( eLoc == SVX_SHADOW_TOPRIGHT || eLoc == SVX_SHADOW_BOTTOMRIGHT )
1396cdf0e10cSrcweir 					if ( nMergeEndCol+1 > rPaintCol && nMergeEndCol < MAXCOL )
1397cdf0e10cSrcweir 						rPaintCol = nMergeEndCol+1;
1398cdf0e10cSrcweir 				if ( eLoc == SVX_SHADOW_BOTTOMLEFT || eLoc == SVX_SHADOW_BOTTOMRIGHT )
1399cdf0e10cSrcweir 					if ( nMergeEndRow+1 > rPaintRow && nMergeEndRow < MAXROW )
1400cdf0e10cSrcweir 						rPaintRow = nMergeEndRow+1;
1401cdf0e10cSrcweir 			}
1402cdf0e10cSrcweir 
1403cdf0e10cSrcweir 			if (bRefresh)
1404cdf0e10cSrcweir 			{
1405cdf0e10cSrcweir 				if ( nMergeEndCol > nThisCol )
1406cdf0e10cSrcweir 					pDocument->ApplyFlagsTab( nThisCol+1, nThisRow, nMergeEndCol, pData[i].nRow,
1407cdf0e10cSrcweir 								nTab, SC_MF_HOR );
1408cdf0e10cSrcweir 				if ( nMergeEndRow > nThisRow )
1409cdf0e10cSrcweir 					pDocument->ApplyFlagsTab( nThisCol, nThisRow+1, nThisCol, nMergeEndRow,
1410cdf0e10cSrcweir 								nTab, SC_MF_VER );
1411cdf0e10cSrcweir 				if ( nMergeEndCol > nThisCol && nMergeEndRow > nThisRow )
1412cdf0e10cSrcweir 					pDocument->ApplyFlagsTab( nThisCol+1, nThisRow+1, nMergeEndCol, nMergeEndRow,
1413cdf0e10cSrcweir 								nTab, SC_MF_HOR | SC_MF_VER );
1414cdf0e10cSrcweir 
1415cdf0e10cSrcweir 				Search( nThisRow, i );					// Daten wurden veraendert
1416cdf0e10cSrcweir 				Search( nStartRow, nStartIndex );
1417cdf0e10cSrcweir 				Search( nEndRow, nEndIndex );
1418cdf0e10cSrcweir 			}
1419cdf0e10cSrcweir 		}
1420cdf0e10cSrcweir 	}
1421cdf0e10cSrcweir 
1422cdf0e10cSrcweir 	return bFound;
1423cdf0e10cSrcweir }
1424cdf0e10cSrcweir 
1425cdf0e10cSrcweir 
RemoveAreaMerge(SCROW nStartRow,SCROW nEndRow)1426cdf0e10cSrcweir sal_Bool ScAttrArray::RemoveAreaMerge(SCROW nStartRow, SCROW nEndRow)
1427cdf0e10cSrcweir {
1428cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
1429cdf0e10cSrcweir 	const ScPatternAttr* pPattern;
1430cdf0e10cSrcweir 	const ScMergeAttr* pItem;
1431cdf0e10cSrcweir 	SCSIZE nIndex;
1432cdf0e10cSrcweir 
1433cdf0e10cSrcweir 	Search( nStartRow, nIndex );
1434cdf0e10cSrcweir 	SCROW nThisStart = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
1435cdf0e10cSrcweir 	if (nThisStart < nStartRow)
1436cdf0e10cSrcweir 		nThisStart = nStartRow;
1437cdf0e10cSrcweir 
1438cdf0e10cSrcweir 	while ( nThisStart <= nEndRow )
1439cdf0e10cSrcweir 	{
1440cdf0e10cSrcweir 		SCROW nThisEnd = pData[nIndex].nRow;
1441cdf0e10cSrcweir 		if (nThisEnd > nEndRow)
1442cdf0e10cSrcweir 			nThisEnd = nEndRow;
1443cdf0e10cSrcweir 
1444cdf0e10cSrcweir 		pPattern = pData[nIndex].pPattern;
1445cdf0e10cSrcweir 		pItem = (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE );
1446cdf0e10cSrcweir 		SCsCOL	nCountX = pItem->GetColMerge();
1447cdf0e10cSrcweir 		SCsROW	nCountY = pItem->GetRowMerge();
1448cdf0e10cSrcweir 		if (nCountX>1 || nCountY>1)
1449cdf0e10cSrcweir 		{
1450cdf0e10cSrcweir 			const ScMergeAttr* pAttr = (const ScMergeAttr*)
1451cdf0e10cSrcweir 											&pDocument->GetPool()->GetDefaultItem( ATTR_MERGE );
1452cdf0e10cSrcweir 			const ScMergeFlagAttr* pFlagAttr = (const ScMergeFlagAttr*)
1453cdf0e10cSrcweir 											&pDocument->GetPool()->GetDefaultItem( ATTR_MERGE_FLAG );
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir 			DBG_ASSERT( nCountY==1 || nThisStart==nThisEnd, "was'n hier los?" );
1456cdf0e10cSrcweir 
1457cdf0e10cSrcweir 			SCCOL nThisCol = nCol;
1458cdf0e10cSrcweir 			SCCOL nMergeEndCol = nThisCol + nCountX - 1;
1459cdf0e10cSrcweir 			SCROW nMergeEndRow = nThisEnd + nCountY - 1;
1460cdf0e10cSrcweir 
1461cdf0e10cSrcweir 			//!	ApplyAttr fuer Bereiche !!!
1462cdf0e10cSrcweir 
1463cdf0e10cSrcweir 			for (SCROW nThisRow = nThisStart; nThisRow <= nThisEnd; nThisRow++)
1464cdf0e10cSrcweir 				pDocument->ApplyAttr( nThisCol, nThisRow, nTab, *pAttr );
1465cdf0e10cSrcweir 
1466cdf0e10cSrcweir 			ScPatternAttr* 	pNewPattern = new ScPatternAttr( pDocument->GetPool() );
1467cdf0e10cSrcweir 			SfxItemSet*		pSet = &pNewPattern->GetItemSet();
1468cdf0e10cSrcweir 			pSet->Put( *pFlagAttr );
1469cdf0e10cSrcweir 			pDocument->ApplyPatternAreaTab( nThisCol, nThisStart, nMergeEndCol, nMergeEndRow,
1470cdf0e10cSrcweir 												nTab, *pNewPattern );
1471cdf0e10cSrcweir 			delete pNewPattern;
1472cdf0e10cSrcweir 
1473cdf0e10cSrcweir 			Search( nThisEnd, nIndex );					// Daten wurden veraendert !!!
1474cdf0e10cSrcweir 		}
1475cdf0e10cSrcweir 
1476cdf0e10cSrcweir 		++nIndex;
1477cdf0e10cSrcweir 		if ( nIndex < nCount )
1478cdf0e10cSrcweir 			nThisStart = pData[nIndex-1].nRow+1;
1479cdf0e10cSrcweir 		else
1480cdf0e10cSrcweir 			nThisStart = MAXROW+1;		// Ende
1481cdf0e10cSrcweir 	}
1482cdf0e10cSrcweir 
1483cdf0e10cSrcweir 	return bFound;
1484cdf0e10cSrcweir }
1485cdf0e10cSrcweir 
1486cdf0e10cSrcweir 			//		Bereich loeschen, aber Merge-Flags stehenlassen
1487cdf0e10cSrcweir 
DeleteAreaSafe(SCROW nStartRow,SCROW nEndRow)1488cdf0e10cSrcweir void ScAttrArray::DeleteAreaSafe(SCROW nStartRow, SCROW nEndRow)
1489cdf0e10cSrcweir {
1490cdf0e10cSrcweir 	SetPatternAreaSafe( nStartRow, nEndRow, pDocument->GetDefPattern(), sal_True );
1491cdf0e10cSrcweir }
1492cdf0e10cSrcweir 
1493cdf0e10cSrcweir 
SetPatternAreaSafe(SCROW nStartRow,SCROW nEndRow,const ScPatternAttr * pWantedPattern,sal_Bool bDefault)1494cdf0e10cSrcweir void ScAttrArray::SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow,
1495cdf0e10cSrcweir 						const ScPatternAttr* pWantedPattern, sal_Bool bDefault )
1496cdf0e10cSrcweir {
1497cdf0e10cSrcweir 	const ScPatternAttr*	pOldPattern;
1498cdf0e10cSrcweir 	const ScMergeFlagAttr*	pItem;
1499cdf0e10cSrcweir 
1500cdf0e10cSrcweir 	SCSIZE	nIndex;
1501cdf0e10cSrcweir 	SCROW	nRow;
1502cdf0e10cSrcweir 	SCROW	nThisRow;
1503cdf0e10cSrcweir 	sal_Bool	bFirstUse = sal_True;
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir 	Search( nStartRow, nIndex );
1506cdf0e10cSrcweir 	nThisRow = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
1507cdf0e10cSrcweir 	while ( nThisRow <= nEndRow )
1508cdf0e10cSrcweir 	{
1509cdf0e10cSrcweir 		pOldPattern = pData[nIndex].pPattern;
1510cdf0e10cSrcweir 		if (pOldPattern != pWantedPattern)							//! else-Zweig ?
1511cdf0e10cSrcweir 		{
1512cdf0e10cSrcweir 			if (nThisRow < nStartRow) nThisRow = nStartRow;
1513cdf0e10cSrcweir 			nRow = pData[nIndex].nRow;
1514cdf0e10cSrcweir 			SCROW nAttrRow = Min( (SCROW)nRow, (SCROW)nEndRow );
1515cdf0e10cSrcweir 			pItem = (const ScMergeFlagAttr*) &pOldPattern->GetItem( ATTR_MERGE_FLAG );
1516cdf0e10cSrcweir 
1517cdf0e10cSrcweir 			if (pItem->IsOverlapped() || pItem->HasAutoFilter())
1518cdf0e10cSrcweir 			{
1519cdf0e10cSrcweir 				//	#108045# default-constructing a ScPatternAttr for DeleteArea doesn't work
1520cdf0e10cSrcweir 				//	because it would have no cell style information.
1521cdf0e10cSrcweir 				//	Instead, the document's GetDefPattern is copied. Since it is passed as
1522cdf0e10cSrcweir 				//	pWantedPattern, no special treatment of default is needed here anymore.
1523cdf0e10cSrcweir 				ScPatternAttr*	pNewPattern = new ScPatternAttr( *pWantedPattern );
1524cdf0e10cSrcweir 				SfxItemSet*		pSet = &pNewPattern->GetItemSet();
1525cdf0e10cSrcweir 				pSet->Put( *pItem );
1526cdf0e10cSrcweir 				SetPatternArea( nThisRow, nAttrRow, pNewPattern, sal_True );
1527cdf0e10cSrcweir 				delete pNewPattern;
1528cdf0e10cSrcweir 			}
1529cdf0e10cSrcweir 			else
1530cdf0e10cSrcweir 			{
1531cdf0e10cSrcweir 				if ( !bDefault )
1532cdf0e10cSrcweir 				{
1533cdf0e10cSrcweir 					if (bFirstUse)
1534cdf0e10cSrcweir 						bFirstUse = sal_False;
1535cdf0e10cSrcweir 					else
1536cdf0e10cSrcweir 						pDocument->GetPool()->Put( *pWantedPattern );		// im Pool ist es schon!
1537cdf0e10cSrcweir 				}
1538cdf0e10cSrcweir 				SetPatternArea( nThisRow, nAttrRow, pWantedPattern );
1539cdf0e10cSrcweir 			}
1540cdf0e10cSrcweir 
1541cdf0e10cSrcweir 			Search( nThisRow, nIndex );					// Daten wurden veraendert !!!
1542cdf0e10cSrcweir 		}
1543cdf0e10cSrcweir 
1544cdf0e10cSrcweir 		++nIndex;
1545cdf0e10cSrcweir 		nThisRow = pData[nIndex-1].nRow+1;
1546cdf0e10cSrcweir 	}
1547cdf0e10cSrcweir }
1548cdf0e10cSrcweir 
1549cdf0e10cSrcweir 
ApplyFlags(SCROW nStartRow,SCROW nEndRow,sal_Int16 nFlags)1550cdf0e10cSrcweir sal_Bool ScAttrArray::ApplyFlags( SCROW nStartRow, SCROW nEndRow, sal_Int16 nFlags )
1551cdf0e10cSrcweir {
1552cdf0e10cSrcweir 	const ScPatternAttr* pOldPattern;
1553cdf0e10cSrcweir 
1554cdf0e10cSrcweir 	sal_Int16	nOldValue;
1555cdf0e10cSrcweir 	SCSIZE	nIndex;
1556cdf0e10cSrcweir 	SCROW	nRow;
1557cdf0e10cSrcweir 	SCROW	nThisRow;
1558cdf0e10cSrcweir 	sal_Bool	bChanged = sal_False;
1559cdf0e10cSrcweir 
1560cdf0e10cSrcweir 	Search( nStartRow, nIndex );
1561cdf0e10cSrcweir 	nThisRow = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
1562cdf0e10cSrcweir 	if (nThisRow < nStartRow) nThisRow = nStartRow;
1563cdf0e10cSrcweir 
1564cdf0e10cSrcweir 	while ( nThisRow <= nEndRow )
1565cdf0e10cSrcweir 	{
1566cdf0e10cSrcweir 		pOldPattern = pData[nIndex].pPattern;
1567cdf0e10cSrcweir 		nOldValue = ((const ScMergeFlagAttr*) &pOldPattern->GetItem( ATTR_MERGE_FLAG ))->GetValue();
1568cdf0e10cSrcweir 		if ( (nOldValue | nFlags) != nOldValue )
1569cdf0e10cSrcweir 		{
1570cdf0e10cSrcweir 			nRow = pData[nIndex].nRow;
1571cdf0e10cSrcweir 			SCROW nAttrRow = Min( (SCROW)nRow, (SCROW)nEndRow );
1572cdf0e10cSrcweir 			ScPatternAttr aNewPattern(*pOldPattern);
1573cdf0e10cSrcweir 			aNewPattern.GetItemSet().Put( ScMergeFlagAttr( nOldValue | nFlags ) );
1574cdf0e10cSrcweir 			SetPatternArea( nThisRow, nAttrRow, &aNewPattern, sal_True );
1575cdf0e10cSrcweir 			Search( nThisRow, nIndex );									// Daten wurden veraendert !!!
1576cdf0e10cSrcweir 			bChanged = sal_True;
1577cdf0e10cSrcweir 		}
1578cdf0e10cSrcweir 
1579cdf0e10cSrcweir 		++nIndex;
1580cdf0e10cSrcweir 		nThisRow = pData[nIndex-1].nRow+1;
1581cdf0e10cSrcweir 	}
1582cdf0e10cSrcweir 
1583cdf0e10cSrcweir 	return bChanged;
1584cdf0e10cSrcweir }
1585cdf0e10cSrcweir 
1586cdf0e10cSrcweir 
RemoveFlags(SCROW nStartRow,SCROW nEndRow,sal_Int16 nFlags)1587cdf0e10cSrcweir sal_Bool ScAttrArray::RemoveFlags( SCROW nStartRow, SCROW nEndRow, sal_Int16 nFlags )
1588cdf0e10cSrcweir {
1589cdf0e10cSrcweir 	const ScPatternAttr* pOldPattern;
1590cdf0e10cSrcweir 
1591cdf0e10cSrcweir 	sal_Int16	nOldValue;
1592cdf0e10cSrcweir 	SCSIZE	nIndex;
1593cdf0e10cSrcweir 	SCROW	nRow;
1594cdf0e10cSrcweir 	SCROW	nThisRow;
1595cdf0e10cSrcweir 	sal_Bool	bChanged = sal_False;
1596cdf0e10cSrcweir 
1597cdf0e10cSrcweir 	Search( nStartRow, nIndex );
1598cdf0e10cSrcweir 	nThisRow = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
1599cdf0e10cSrcweir 	if (nThisRow < nStartRow) nThisRow = nStartRow;
1600cdf0e10cSrcweir 
1601cdf0e10cSrcweir 	while ( nThisRow <= nEndRow )
1602cdf0e10cSrcweir 	{
1603cdf0e10cSrcweir 		pOldPattern = pData[nIndex].pPattern;
1604cdf0e10cSrcweir 		nOldValue = ((const ScMergeFlagAttr*) &pOldPattern->GetItem( ATTR_MERGE_FLAG ))->GetValue();
1605cdf0e10cSrcweir 		if ( (nOldValue & ~nFlags) != nOldValue )
1606cdf0e10cSrcweir 		{
1607cdf0e10cSrcweir 			nRow = pData[nIndex].nRow;
1608cdf0e10cSrcweir 			SCROW nAttrRow = Min( (SCROW)nRow, (SCROW)nEndRow );
1609cdf0e10cSrcweir 			ScPatternAttr aNewPattern(*pOldPattern);
1610cdf0e10cSrcweir 			aNewPattern.GetItemSet().Put( ScMergeFlagAttr( nOldValue & ~nFlags ) );
1611cdf0e10cSrcweir 			SetPatternArea( nThisRow, nAttrRow, &aNewPattern, sal_True );
1612cdf0e10cSrcweir 			Search( nThisRow, nIndex );									// Daten wurden veraendert !!!
1613cdf0e10cSrcweir 			bChanged = sal_True;
1614cdf0e10cSrcweir 		}
1615cdf0e10cSrcweir 
1616cdf0e10cSrcweir 		++nIndex;
1617cdf0e10cSrcweir 		nThisRow = pData[nIndex-1].nRow+1;
1618cdf0e10cSrcweir 	}
1619cdf0e10cSrcweir 
1620cdf0e10cSrcweir 	return bChanged;
1621cdf0e10cSrcweir }
1622cdf0e10cSrcweir 
1623cdf0e10cSrcweir 
ClearItems(SCROW nStartRow,SCROW nEndRow,const sal_uInt16 * pWhich)1624cdf0e10cSrcweir void ScAttrArray::ClearItems( SCROW nStartRow, SCROW nEndRow, const sal_uInt16* pWhich )
1625cdf0e10cSrcweir {
1626cdf0e10cSrcweir 	const ScPatternAttr* pOldPattern;
1627cdf0e10cSrcweir 
1628cdf0e10cSrcweir 	SCSIZE	nIndex;
1629cdf0e10cSrcweir 	SCROW	nRow;
1630cdf0e10cSrcweir 	SCROW	nThisRow;
1631cdf0e10cSrcweir 
1632cdf0e10cSrcweir 	Search( nStartRow, nIndex );
1633cdf0e10cSrcweir 	nThisRow = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
1634cdf0e10cSrcweir 	if (nThisRow < nStartRow) nThisRow = nStartRow;
1635cdf0e10cSrcweir 
1636cdf0e10cSrcweir 	while ( nThisRow <= nEndRow )
1637cdf0e10cSrcweir 	{
1638cdf0e10cSrcweir 		pOldPattern = pData[nIndex].pPattern;
1639cdf0e10cSrcweir 		if ( pOldPattern->HasItemsSet( pWhich ) )
1640cdf0e10cSrcweir 		{
1641cdf0e10cSrcweir 			ScPatternAttr aNewPattern(*pOldPattern);
1642cdf0e10cSrcweir 			aNewPattern.ClearItems( pWhich );
1643cdf0e10cSrcweir 
1644cdf0e10cSrcweir 			nRow = pData[nIndex].nRow;
1645cdf0e10cSrcweir 			SCROW nAttrRow = Min( (SCROW)nRow, (SCROW)nEndRow );
1646cdf0e10cSrcweir 			SetPatternArea( nThisRow, nAttrRow, &aNewPattern, sal_True );
1647cdf0e10cSrcweir 			Search( nThisRow, nIndex );									// Daten wurden veraendert !!!
1648cdf0e10cSrcweir 		}
1649cdf0e10cSrcweir 
1650cdf0e10cSrcweir 		++nIndex;
1651cdf0e10cSrcweir 		nThisRow = pData[nIndex-1].nRow+1;
1652cdf0e10cSrcweir 	}
1653cdf0e10cSrcweir }
1654cdf0e10cSrcweir 
1655cdf0e10cSrcweir 
ChangeIndent(SCROW nStartRow,SCROW nEndRow,sal_Bool bIncrement)1656cdf0e10cSrcweir void ScAttrArray::ChangeIndent( SCROW nStartRow, SCROW nEndRow, sal_Bool bIncrement )
1657cdf0e10cSrcweir {
1658cdf0e10cSrcweir 	SCSIZE nIndex;
1659cdf0e10cSrcweir 	Search( nStartRow, nIndex );
1660cdf0e10cSrcweir 	SCROW nThisStart = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
1661cdf0e10cSrcweir 	if (nThisStart < nStartRow) nThisStart = nStartRow;
1662cdf0e10cSrcweir 
1663cdf0e10cSrcweir 	while ( nThisStart <= nEndRow )
1664cdf0e10cSrcweir 	{
1665cdf0e10cSrcweir 		const ScPatternAttr* pOldPattern = pData[nIndex].pPattern;
1666cdf0e10cSrcweir 		const SfxItemSet& rOldSet = pOldPattern->GetItemSet();
1667cdf0e10cSrcweir 		const SfxPoolItem* pItem;
1668cdf0e10cSrcweir 
1669cdf0e10cSrcweir 		sal_Bool bNeedJust = ( rOldSet.GetItemState( ATTR_HOR_JUSTIFY, sal_False, &pItem ) != SFX_ITEM_SET
1670cdf0e10cSrcweir 						|| ((const SvxHorJustifyItem*)pItem)->GetValue() != SVX_HOR_JUSTIFY_LEFT );
1671cdf0e10cSrcweir 		sal_uInt16 nOldValue = ((const SfxUInt16Item&)rOldSet.Get( ATTR_INDENT )).GetValue();
1672cdf0e10cSrcweir 		sal_uInt16 nNewValue = nOldValue;
1673cdf0e10cSrcweir 		if ( bIncrement )
1674cdf0e10cSrcweir 		{
1675cdf0e10cSrcweir 			if ( nNewValue < SC_MAX_INDENT )
1676cdf0e10cSrcweir 			{
1677cdf0e10cSrcweir 				nNewValue += SC_INDENT_STEP;
1678cdf0e10cSrcweir 				if ( nNewValue > SC_MAX_INDENT ) nNewValue = SC_MAX_INDENT;
1679cdf0e10cSrcweir 			}
1680cdf0e10cSrcweir 		}
1681cdf0e10cSrcweir 		else
1682cdf0e10cSrcweir 		{
1683cdf0e10cSrcweir 			if ( nNewValue > 0 )
1684cdf0e10cSrcweir 			{
1685cdf0e10cSrcweir 				if ( nNewValue > SC_INDENT_STEP )
1686cdf0e10cSrcweir 					nNewValue -= SC_INDENT_STEP;
1687cdf0e10cSrcweir 				else
1688cdf0e10cSrcweir 					nNewValue = 0;
1689cdf0e10cSrcweir 			}
1690cdf0e10cSrcweir 		}
1691cdf0e10cSrcweir 
1692cdf0e10cSrcweir 		if ( bNeedJust || nNewValue != nOldValue )
1693cdf0e10cSrcweir 		{
1694cdf0e10cSrcweir 			SCROW nThisEnd = pData[nIndex].nRow;
1695cdf0e10cSrcweir 			SCROW nAttrRow = Min( nThisEnd, nEndRow );
1696cdf0e10cSrcweir 			ScPatternAttr aNewPattern(*pOldPattern);
1697cdf0e10cSrcweir 			aNewPattern.GetItemSet().Put( SfxUInt16Item( ATTR_INDENT, nNewValue ) );
1698cdf0e10cSrcweir 			if ( bNeedJust )
1699cdf0e10cSrcweir 				aNewPattern.GetItemSet().Put(
1700cdf0e10cSrcweir 								SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
1701cdf0e10cSrcweir 			SetPatternArea( nThisStart, nAttrRow, &aNewPattern, sal_True );
1702cdf0e10cSrcweir 
1703cdf0e10cSrcweir 			nThisStart = nThisEnd + 1;
1704cdf0e10cSrcweir 			Search( nThisStart, nIndex );				// Daten wurden veraendert !!!
1705cdf0e10cSrcweir 		}
1706cdf0e10cSrcweir 		else
1707cdf0e10cSrcweir 		{
1708cdf0e10cSrcweir 			nThisStart = pData[nIndex].nRow + 1;		// weiterzaehlen...
1709cdf0e10cSrcweir 			++nIndex;
1710cdf0e10cSrcweir 		}
1711cdf0e10cSrcweir 	}
1712cdf0e10cSrcweir }
1713cdf0e10cSrcweir 
1714cdf0e10cSrcweir 
GetNextUnprotected(SCsROW nRow,sal_Bool bUp) const1715cdf0e10cSrcweir SCsROW ScAttrArray::GetNextUnprotected( SCsROW nRow, sal_Bool bUp ) const
1716cdf0e10cSrcweir {
1717cdf0e10cSrcweir 	long nRet = nRow;
1718cdf0e10cSrcweir 	if (VALIDROW(nRow))
1719cdf0e10cSrcweir 	{
1720cdf0e10cSrcweir 		SCSIZE nIndex;
1721cdf0e10cSrcweir 		Search(nRow, nIndex);
1722cdf0e10cSrcweir 		while (((const ScProtectionAttr&)pData[nIndex].pPattern->
1723cdf0e10cSrcweir 				GetItem(ATTR_PROTECTION)).GetProtection())
1724cdf0e10cSrcweir 		{
1725cdf0e10cSrcweir 			if (bUp)
1726cdf0e10cSrcweir 			{
1727cdf0e10cSrcweir 				if (nIndex==0)
1728cdf0e10cSrcweir 					return -1;					// nichts gefunden
1729cdf0e10cSrcweir 				--nIndex;
1730cdf0e10cSrcweir 				nRet = pData[nIndex].nRow;
1731cdf0e10cSrcweir 			}
1732cdf0e10cSrcweir 			else
1733cdf0e10cSrcweir 			{
1734cdf0e10cSrcweir 				nRet = pData[nIndex].nRow+1;
1735cdf0e10cSrcweir 				++nIndex;
1736cdf0e10cSrcweir 				if (nIndex>=nCount)
1737cdf0e10cSrcweir 					return MAXROW+1;			// nichts gefunden
1738cdf0e10cSrcweir 			}
1739cdf0e10cSrcweir 		}
1740cdf0e10cSrcweir 	}
1741cdf0e10cSrcweir 	return nRet;
1742cdf0e10cSrcweir }
1743cdf0e10cSrcweir 
FindStyleSheet(const SfxStyleSheetBase * pStyleSheet,ScFlatBoolRowSegments & rUsedRows,bool bReset)1744cdf0e10cSrcweir void ScAttrArray::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset )
1745cdf0e10cSrcweir {
1746cdf0e10cSrcweir 	SCROW nStart = 0;
1747cdf0e10cSrcweir 	SCSIZE nPos = 0;
1748cdf0e10cSrcweir 	while (nPos < nCount)
1749cdf0e10cSrcweir 	{
1750cdf0e10cSrcweir 		SCROW nEnd = pData[nPos].nRow;
1751cdf0e10cSrcweir 		if (pData[nPos].pPattern->GetStyleSheet() == pStyleSheet)
1752cdf0e10cSrcweir 		{
1753cdf0e10cSrcweir //			for (SCROW nRow = nStart; nRow <= nEnd; nRow++)
1754cdf0e10cSrcweir //				pUsed[nRow] = sal_True;
1755cdf0e10cSrcweir 
1756cdf0e10cSrcweir             rUsedRows.setTrue(nStart, nEnd);
1757cdf0e10cSrcweir 
1758cdf0e10cSrcweir 			if (bReset)
1759cdf0e10cSrcweir 			{
1760cdf0e10cSrcweir 				ScPatternAttr* pNewPattern = new ScPatternAttr(*pData[nPos].pPattern);
1761cdf0e10cSrcweir 				pDocument->GetPool()->Remove(*pData[nPos].pPattern);
1762cdf0e10cSrcweir 				pNewPattern->SetStyleSheet( (ScStyleSheet*)
1763cdf0e10cSrcweir 					pDocument->GetStyleSheetPool()->
1764cdf0e10cSrcweir 						Find( ScGlobal::GetRscString(STR_STYLENAME_STANDARD),
1765cdf0e10cSrcweir 							  SFX_STYLE_FAMILY_PARA,
1766cdf0e10cSrcweir 							  SFXSTYLEBIT_AUTO | SCSTYLEBIT_STANDARD ) );
1767cdf0e10cSrcweir 				pData[nPos].pPattern = (const ScPatternAttr*)
1768cdf0e10cSrcweir 											&pDocument->GetPool()->Put(*pNewPattern);
1769cdf0e10cSrcweir 				delete pNewPattern;
1770cdf0e10cSrcweir 
1771cdf0e10cSrcweir 				if (Concat(nPos))
1772cdf0e10cSrcweir 				{
1773cdf0e10cSrcweir 					Search(nStart, nPos);
1774cdf0e10cSrcweir 					--nPos;							// wegen ++ am Ende
1775cdf0e10cSrcweir 				}
1776cdf0e10cSrcweir 			}
1777cdf0e10cSrcweir 		}
1778cdf0e10cSrcweir 		nStart = nEnd + 1;
1779cdf0e10cSrcweir 		++nPos;
1780cdf0e10cSrcweir 	}
1781cdf0e10cSrcweir }
1782cdf0e10cSrcweir 
1783cdf0e10cSrcweir 
IsStyleSheetUsed(const ScStyleSheet & rStyle,sal_Bool bGatherAllStyles) const1784cdf0e10cSrcweir sal_Bool ScAttrArray::IsStyleSheetUsed( const ScStyleSheet& rStyle,
1785cdf0e10cSrcweir         sal_Bool bGatherAllStyles ) const
1786cdf0e10cSrcweir {
1787cdf0e10cSrcweir 	sal_Bool	bIsUsed	= sal_False;
1788cdf0e10cSrcweir 	SCSIZE	nPos	= 0;
1789cdf0e10cSrcweir 
1790cdf0e10cSrcweir 	while ( nPos < nCount )
1791cdf0e10cSrcweir 	{
1792cdf0e10cSrcweir         const ScStyleSheet* pStyle = pData[nPos].pPattern->GetStyleSheet();
1793cdf0e10cSrcweir         if ( pStyle )
1794cdf0e10cSrcweir         {
1795cdf0e10cSrcweir             pStyle->SetUsage( ScStyleSheet::USED );
1796cdf0e10cSrcweir             if ( pStyle == &rStyle )
1797cdf0e10cSrcweir             {
1798cdf0e10cSrcweir                 if ( !bGatherAllStyles )
1799cdf0e10cSrcweir                     return sal_True;
1800cdf0e10cSrcweir                 bIsUsed = sal_True;
1801cdf0e10cSrcweir             }
1802cdf0e10cSrcweir         }
1803cdf0e10cSrcweir 		nPos++;
1804cdf0e10cSrcweir 	}
1805cdf0e10cSrcweir 
1806cdf0e10cSrcweir 	return bIsUsed;
1807cdf0e10cSrcweir }
1808cdf0e10cSrcweir 
1809cdf0e10cSrcweir 
IsEmpty() const1810cdf0e10cSrcweir sal_Bool ScAttrArray::IsEmpty() const
1811cdf0e10cSrcweir {
1812cdf0e10cSrcweir 	if (nCount == 1)
1813cdf0e10cSrcweir 	{
1814cdf0e10cSrcweir 		if ( pData[0].pPattern != pDocument->GetDefPattern() )
1815cdf0e10cSrcweir 			return sal_False;
1816cdf0e10cSrcweir 		else
1817cdf0e10cSrcweir 			return sal_True;
1818cdf0e10cSrcweir 	}
1819cdf0e10cSrcweir 	else
1820cdf0e10cSrcweir 		return sal_False;
1821cdf0e10cSrcweir }
1822cdf0e10cSrcweir 
1823cdf0e10cSrcweir 
1824cdf0e10cSrcweir //UNUSED2008-05  SCROW ScAttrArray::GetFirstEntryPos() const
1825cdf0e10cSrcweir //UNUSED2008-05  {
1826cdf0e10cSrcweir //UNUSED2008-05      DBG_ASSERT( nCount, "nCount = 0" );
1827cdf0e10cSrcweir //UNUSED2008-05
1828cdf0e10cSrcweir //UNUSED2008-05      if ( pData[0].pPattern != pDocument->GetDefPattern() )
1829cdf0e10cSrcweir //UNUSED2008-05          return 0;
1830cdf0e10cSrcweir //UNUSED2008-05      else
1831cdf0e10cSrcweir //UNUSED2008-05      {
1832cdf0e10cSrcweir //UNUSED2008-05          if (nCount==1)
1833cdf0e10cSrcweir //UNUSED2008-05              return 0;                               // leer
1834cdf0e10cSrcweir //UNUSED2008-05          else
1835cdf0e10cSrcweir //UNUSED2008-05              return pData[0].nRow + 1;
1836cdf0e10cSrcweir //UNUSED2008-05      }
1837cdf0e10cSrcweir //UNUSED2008-05  }
1838cdf0e10cSrcweir //UNUSED2008-05
1839cdf0e10cSrcweir //UNUSED2008-05
1840cdf0e10cSrcweir //UNUSED2008-05  SCROW ScAttrArray::GetLastEntryPos( sal_Bool bIncludeBottom ) const
1841cdf0e10cSrcweir //UNUSED2008-05  {
1842cdf0e10cSrcweir //UNUSED2008-05      DBG_ASSERT( nCount, "nCount == 0" );
1843cdf0e10cSrcweir //UNUSED2008-05
1844cdf0e10cSrcweir //UNUSED2008-05      if (bIncludeBottom)
1845cdf0e10cSrcweir //UNUSED2008-05          bIncludeBottom = ( pData[nCount-1].pPattern != pDocument->GetDefPattern() );
1846cdf0e10cSrcweir //UNUSED2008-05
1847cdf0e10cSrcweir //UNUSED2008-05      if (bIncludeBottom)
1848cdf0e10cSrcweir //UNUSED2008-05          return MAXROW;
1849cdf0e10cSrcweir //UNUSED2008-05      else
1850cdf0e10cSrcweir //UNUSED2008-05      {
1851cdf0e10cSrcweir //UNUSED2008-05          if (nCount<=1)
1852cdf0e10cSrcweir //UNUSED2008-05              return 0;                               // leer
1853cdf0e10cSrcweir //UNUSED2008-05          else
1854cdf0e10cSrcweir //UNUSED2008-05              return pData[nCount-2].nRow;
1855cdf0e10cSrcweir //UNUSED2008-05      }
1856cdf0e10cSrcweir //UNUSED2008-05  }
1857cdf0e10cSrcweir 
1858cdf0e10cSrcweir 
GetFirstVisibleAttr(SCROW & rFirstRow) const1859cdf0e10cSrcweir sal_Bool ScAttrArray::GetFirstVisibleAttr( SCROW& rFirstRow ) const
1860cdf0e10cSrcweir {
1861cdf0e10cSrcweir     DBG_ASSERT( nCount, "nCount == 0" );
1862cdf0e10cSrcweir 
1863cdf0e10cSrcweir     sal_Bool bFound = sal_False;
1864cdf0e10cSrcweir     SCSIZE nStart = 0;
1865cdf0e10cSrcweir 
1866cdf0e10cSrcweir     // Skip first entry if more than 1 row.
1867cdf0e10cSrcweir     // Entries at the end are not skipped, GetFirstVisibleAttr may be larger than GetLastVisibleAttr.
1868cdf0e10cSrcweir 
1869cdf0e10cSrcweir     SCSIZE nVisStart = 1;
1870cdf0e10cSrcweir     while ( nVisStart < nCount && pData[nVisStart].pPattern->IsVisibleEqual(*pData[nVisStart-1].pPattern) )
1871cdf0e10cSrcweir         ++nVisStart;
1872cdf0e10cSrcweir     if ( nVisStart >= nCount || pData[nVisStart-1].nRow > 0 )	// more than 1 row?
1873cdf0e10cSrcweir         nStart = nVisStart;
1874cdf0e10cSrcweir 
1875cdf0e10cSrcweir 	while ( nStart < nCount && !bFound )
1876cdf0e10cSrcweir 	{
1877cdf0e10cSrcweir 		if ( pData[nStart].pPattern->IsVisible() )
1878cdf0e10cSrcweir 		{
1879cdf0e10cSrcweir 			rFirstRow = nStart ? ( pData[nStart-1].nRow + 1 ) : 0;
1880cdf0e10cSrcweir 			bFound = sal_True;
1881cdf0e10cSrcweir 		}
1882cdf0e10cSrcweir 		else
1883cdf0e10cSrcweir 			++nStart;
1884cdf0e10cSrcweir 	}
1885cdf0e10cSrcweir 
1886cdf0e10cSrcweir     return bFound;
1887cdf0e10cSrcweir }
1888cdf0e10cSrcweir 
1889cdf0e10cSrcweir // size (rows) of a range of attributes after cell content where the search is stopped
1890cdf0e10cSrcweir // (more than a default page size, 2*42 because it's as good as any number)
1891cdf0e10cSrcweir 
1892cdf0e10cSrcweir const SCROW SC_VISATTR_STOP = 84;
1893cdf0e10cSrcweir 
GetLastVisibleAttr(SCROW & rLastRow,SCROW nLastData) const1894cdf0e10cSrcweir sal_Bool ScAttrArray::GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData ) const
1895cdf0e10cSrcweir {
1896cdf0e10cSrcweir     //  #i30830# changed behavior:
1897cdf0e10cSrcweir     //  ignore all attributes starting with the first run of SC_VISATTR_STOP equal rows
1898cdf0e10cSrcweir     //  below the last content cell
1899cdf0e10cSrcweir 
1900cdf0e10cSrcweir     if ( nLastData == MAXROW )
1901cdf0e10cSrcweir     {
1902cdf0e10cSrcweir         rLastRow = MAXROW;      // can't look for attributes below MAXROW
1903cdf0e10cSrcweir         return sal_True;
1904cdf0e10cSrcweir     }
1905cdf0e10cSrcweir 
1906cdf0e10cSrcweir     sal_Bool bFound = sal_False;
1907cdf0e10cSrcweir 
1908cdf0e10cSrcweir     //  loop backwards from the end instead of using Search, assuming that
1909cdf0e10cSrcweir     //  there usually aren't many attributes below the last cell
1910cdf0e10cSrcweir 
1911cdf0e10cSrcweir     SCSIZE nPos = nCount;
1912cdf0e10cSrcweir     while ( nPos > 0 && pData[nPos-1].nRow > nLastData )
1913cdf0e10cSrcweir     {
1914cdf0e10cSrcweir         SCSIZE nEndPos = nPos - 1;
1915cdf0e10cSrcweir         SCSIZE nStartPos = nEndPos;         // find range of visually equal formats
1916cdf0e10cSrcweir         while ( nStartPos > 0 &&
1917cdf0e10cSrcweir                 pData[nStartPos-1].nRow > nLastData &&
1918cdf0e10cSrcweir                 pData[nStartPos-1].pPattern->IsVisibleEqual(*pData[nStartPos].pPattern) )
1919cdf0e10cSrcweir             --nStartPos;
1920cdf0e10cSrcweir 
1921cdf0e10cSrcweir         SCROW nAttrStartRow = ( nStartPos > 0 ) ? ( pData[nStartPos-1].nRow + 1 ) : 0;
1922cdf0e10cSrcweir         if ( nAttrStartRow <= nLastData )
1923cdf0e10cSrcweir             nAttrStartRow = nLastData + 1;
1924cdf0e10cSrcweir         SCROW nAttrSize = pData[nEndPos].nRow + 1 - nAttrStartRow;
1925cdf0e10cSrcweir         if ( nAttrSize >= SC_VISATTR_STOP )
1926cdf0e10cSrcweir         {
1927cdf0e10cSrcweir             bFound = sal_False;        // ignore this range and below
1928cdf0e10cSrcweir         }
1929cdf0e10cSrcweir         else if ( !bFound && pData[nEndPos].pPattern->IsVisible() )
1930cdf0e10cSrcweir         {
1931cdf0e10cSrcweir             rLastRow = pData[nEndPos].nRow;
1932cdf0e10cSrcweir             bFound = sal_True;
1933cdf0e10cSrcweir         }
1934cdf0e10cSrcweir 
1935cdf0e10cSrcweir         nPos = nStartPos;           // look further from the top of the range
1936cdf0e10cSrcweir     }
1937cdf0e10cSrcweir 
1938cdf0e10cSrcweir     return bFound;
1939cdf0e10cSrcweir }
1940cdf0e10cSrcweir 
GetLastAttr(SCROW & rLastRow,SCROW nLastData) const1941557cb412SWang Lei sal_Bool ScAttrArray::GetLastAttr( SCROW& rLastRow, SCROW nLastData ) const
1942557cb412SWang Lei {
1943557cb412SWang Lei     if ( nLastData == MAXROW )
1944557cb412SWang Lei     {
1945557cb412SWang Lei         rLastRow = MAXROW;
1946557cb412SWang Lei         return sal_True;
1947557cb412SWang Lei     }
19486a261b58SHerbert Dürr 
19496a261b58SHerbert Dürr     sal_Bool bFound = sal_False;
19506a261b58SHerbert Dürr 
19516a261b58SHerbert Dürr     // Loop backwards from the end instead of using Search, assuming that
19526a261b58SHerbert Dürr     // there usually aren't many attributes below the last cell.
19536a261b58SHerbert Dürr     SCSIZE nPos = nCount;
19546a261b58SHerbert Dürr     while ( nPos > 0 && pData[nPos - 1].nRow > nLastData )
19556a261b58SHerbert Dürr     {
19566a261b58SHerbert Dürr         SCSIZE nEndPos = nPos - 1;
19576a261b58SHerbert Dürr         SCSIZE nStartPos = nEndPos;
19586a261b58SHerbert Dürr         while ( nStartPos > 0 && pData[nStartPos - 1].nRow > nLastData &&
19596a261b58SHerbert Dürr                 pData[nStartPos - 1].pPattern->IsEqual( *pData[nStartPos].pPattern ) )
19606a261b58SHerbert Dürr             --nStartPos;
19616a261b58SHerbert Dürr 
19626a261b58SHerbert Dürr         SCROW nAttrStartRow = ( nStartPos > 0 ) ? ( pData[nStartPos - 1].nRow + 1 ) : 0;
19636a261b58SHerbert Dürr         if ( nAttrStartRow <= nLastData )
19646a261b58SHerbert Dürr             nAttrStartRow = nLastData + 1;
19656a261b58SHerbert Dürr         SCROW nAttrSize = pData[nEndPos].nRow + 1 - nAttrStartRow;
19666a261b58SHerbert Dürr         if ( nAttrSize >= SC_VISATTR_STOP )
19676a261b58SHerbert Dürr         {
19686a261b58SHerbert Dürr             bFound = sal_False;
19696a261b58SHerbert Dürr         }
19706a261b58SHerbert Dürr         else if ( !bFound )
19716a261b58SHerbert Dürr         {
19726a261b58SHerbert Dürr             rLastRow = pData[nEndPos].nRow;
19736a261b58SHerbert Dürr             bFound = sal_True;
19746a261b58SHerbert Dürr         }
19756a261b58SHerbert Dürr 
19766a261b58SHerbert Dürr         // look further from the top of the range.
19776a261b58SHerbert Dürr         nPos = nStartPos;
19786a261b58SHerbert Dürr     }
19796a261b58SHerbert Dürr 
1980557cb412SWang Lei     return bFound;
1981557cb412SWang Lei }
1982557cb412SWang Lei 
1983cdf0e10cSrcweir 
HasVisibleAttrIn(SCROW nStartRow,SCROW nEndRow) const1984cdf0e10cSrcweir sal_Bool ScAttrArray::HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const
1985cdf0e10cSrcweir {
1986cdf0e10cSrcweir 	SCSIZE nIndex;
1987cdf0e10cSrcweir 	Search( nStartRow, nIndex );
1988cdf0e10cSrcweir 	SCROW nThisStart = nStartRow;
1989cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
1990cdf0e10cSrcweir 	while ( nIndex < nCount && nThisStart <= nEndRow && !bFound )
1991cdf0e10cSrcweir 	{
1992cdf0e10cSrcweir 		if ( pData[nIndex].pPattern->IsVisible() )
1993cdf0e10cSrcweir 			bFound = sal_True;
1994cdf0e10cSrcweir 
1995cdf0e10cSrcweir 		nThisStart = pData[nIndex].nRow + 1;
1996cdf0e10cSrcweir 		++nIndex;
1997cdf0e10cSrcweir 	}
1998cdf0e10cSrcweir 
1999cdf0e10cSrcweir 	return bFound;
2000cdf0e10cSrcweir }
2001cdf0e10cSrcweir 
2002cdf0e10cSrcweir 
IsVisibleEqual(const ScAttrArray & rOther,SCROW nStartRow,SCROW nEndRow) const2003cdf0e10cSrcweir sal_Bool ScAttrArray::IsVisibleEqual( const ScAttrArray& rOther,
2004cdf0e10cSrcweir 									SCROW nStartRow, SCROW nEndRow ) const
2005cdf0e10cSrcweir {
2006cdf0e10cSrcweir 	sal_Bool bEqual = sal_True;
2007cdf0e10cSrcweir 	SCSIZE nThisPos = 0;
2008cdf0e10cSrcweir 	SCSIZE nOtherPos = 0;
2009cdf0e10cSrcweir 	if ( nStartRow > 0 )
2010cdf0e10cSrcweir 	{
2011cdf0e10cSrcweir 		Search( nStartRow, nThisPos );
2012cdf0e10cSrcweir 		rOther.Search( nStartRow, nOtherPos );
2013cdf0e10cSrcweir 	}
2014cdf0e10cSrcweir 
2015cdf0e10cSrcweir 	while ( nThisPos<nCount && nOtherPos<rOther.nCount && bEqual )
2016cdf0e10cSrcweir 	{
2017cdf0e10cSrcweir 		SCROW nThisRow = pData[nThisPos].nRow;
2018cdf0e10cSrcweir 		SCROW nOtherRow = rOther.pData[nOtherPos].nRow;
2019cdf0e10cSrcweir 		const ScPatternAttr* pThisPattern = pData[nThisPos].pPattern;
2020cdf0e10cSrcweir 		const ScPatternAttr* pOtherPattern = rOther.pData[nOtherPos].pPattern;
2021cdf0e10cSrcweir 		bEqual = ( pThisPattern == pOtherPattern ||
2022cdf0e10cSrcweir 					pThisPattern->IsVisibleEqual(*pOtherPattern) );
2023cdf0e10cSrcweir 
2024cdf0e10cSrcweir 		if ( nThisRow >= nOtherRow )
2025cdf0e10cSrcweir 		{
2026cdf0e10cSrcweir 			if ( nOtherRow >= nEndRow ) break;
2027cdf0e10cSrcweir 			++nOtherPos;
2028cdf0e10cSrcweir 		}
2029cdf0e10cSrcweir 		if ( nThisRow <= nOtherRow )
2030cdf0e10cSrcweir 		{
2031cdf0e10cSrcweir 			if ( nThisRow >= nEndRow ) break;
2032cdf0e10cSrcweir 			++nThisPos;
2033cdf0e10cSrcweir 		}
2034cdf0e10cSrcweir 	}
2035cdf0e10cSrcweir 
2036cdf0e10cSrcweir 	return bEqual;
2037cdf0e10cSrcweir }
2038cdf0e10cSrcweir 
2039cdf0e10cSrcweir 
IsAllEqual(const ScAttrArray & rOther,SCROW nStartRow,SCROW nEndRow) const2040cdf0e10cSrcweir sal_Bool ScAttrArray::IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW nEndRow ) const
2041cdf0e10cSrcweir {
2042cdf0e10cSrcweir 	//!	mit IsVisibleEqual zusammenfassen?
2043cdf0e10cSrcweir 
2044cdf0e10cSrcweir 	sal_Bool bEqual = sal_True;
2045cdf0e10cSrcweir 	SCSIZE nThisPos = 0;
2046cdf0e10cSrcweir 	SCSIZE nOtherPos = 0;
2047cdf0e10cSrcweir 	if ( nStartRow > 0 )
2048cdf0e10cSrcweir 	{
2049cdf0e10cSrcweir 		Search( nStartRow, nThisPos );
2050cdf0e10cSrcweir 		rOther.Search( nStartRow, nOtherPos );
2051cdf0e10cSrcweir 	}
2052cdf0e10cSrcweir 
2053cdf0e10cSrcweir 	while ( nThisPos<nCount && nOtherPos<rOther.nCount && bEqual )
2054cdf0e10cSrcweir 	{
2055cdf0e10cSrcweir 		SCROW nThisRow = pData[nThisPos].nRow;
2056cdf0e10cSrcweir 		SCROW nOtherRow = rOther.pData[nOtherPos].nRow;
2057cdf0e10cSrcweir 		const ScPatternAttr* pThisPattern = pData[nThisPos].pPattern;
2058cdf0e10cSrcweir 		const ScPatternAttr* pOtherPattern = rOther.pData[nOtherPos].pPattern;
2059cdf0e10cSrcweir 		bEqual = ( pThisPattern == pOtherPattern );
2060cdf0e10cSrcweir 
2061cdf0e10cSrcweir 		if ( nThisRow >= nOtherRow )
2062cdf0e10cSrcweir 		{
2063cdf0e10cSrcweir 			if ( nOtherRow >= nEndRow ) break;
2064cdf0e10cSrcweir 			++nOtherPos;
2065cdf0e10cSrcweir 		}
2066cdf0e10cSrcweir 		if ( nThisRow <= nOtherRow )
2067cdf0e10cSrcweir 		{
2068cdf0e10cSrcweir 			if ( nThisRow >= nEndRow ) break;
2069cdf0e10cSrcweir 			++nThisPos;
2070cdf0e10cSrcweir 		}
2071cdf0e10cSrcweir 	}
2072cdf0e10cSrcweir 
2073cdf0e10cSrcweir 	return bEqual;
2074cdf0e10cSrcweir }
2075cdf0e10cSrcweir 
2076cdf0e10cSrcweir 
TestInsertCol(SCROW nStartRow,SCROW nEndRow) const2077cdf0e10cSrcweir sal_Bool ScAttrArray::TestInsertCol( SCROW nStartRow, SCROW nEndRow) const
2078cdf0e10cSrcweir {
2079cdf0e10cSrcweir 	//	horizontal zusammengefasste duerfen nicht herausgeschoben werden
2080cdf0e10cSrcweir 	//	(ob die ganze Zusammenfassung betroffen ist, ist hier nicht zu erkennen)
2081cdf0e10cSrcweir 
2082cdf0e10cSrcweir 	sal_Bool bTest = sal_True;
2083cdf0e10cSrcweir 	if (!IsEmpty())
2084cdf0e10cSrcweir 	{
2085cdf0e10cSrcweir 		SCSIZE nIndex = 0;
2086cdf0e10cSrcweir 		if ( nStartRow > 0 )
2087cdf0e10cSrcweir 			Search( nStartRow, nIndex );
2088cdf0e10cSrcweir 
2089cdf0e10cSrcweir 		for ( ; nIndex < nCount; nIndex++ )
2090cdf0e10cSrcweir 		{
2091cdf0e10cSrcweir 			if ( ((const ScMergeFlagAttr&)pData[nIndex].pPattern->
2092cdf0e10cSrcweir 						GetItem(ATTR_MERGE_FLAG)).IsHorOverlapped() )
2093cdf0e10cSrcweir 			{
2094cdf0e10cSrcweir 				bTest = sal_False;						// darf nicht herausgeschoben werden
2095cdf0e10cSrcweir 				break;
2096cdf0e10cSrcweir 			}
2097cdf0e10cSrcweir 			if ( pData[nIndex].nRow >= nEndRow )	// Ende des Bereichs
2098cdf0e10cSrcweir 				break;
2099cdf0e10cSrcweir 		}
2100cdf0e10cSrcweir 	}
2101cdf0e10cSrcweir 	return bTest;
2102cdf0e10cSrcweir }
2103cdf0e10cSrcweir 
2104cdf0e10cSrcweir 
TestInsertRow(SCSIZE nSize) const2105cdf0e10cSrcweir sal_Bool ScAttrArray::TestInsertRow( SCSIZE nSize ) const
2106cdf0e10cSrcweir {
2107cdf0e10cSrcweir 	//	wenn die erste herausgeschobene Zeile vertikal ueberlappt ist,
2108cdf0e10cSrcweir 	//	wuerde eine kaputte Zusammenfassung uebrigbleiben
2109cdf0e10cSrcweir 
2110cdf0e10cSrcweir 	if (pData)
2111cdf0e10cSrcweir 	{
2112cdf0e10cSrcweir 		//	MAXROW + 1 - nSize	= erste herausgeschobene Zeile
2113cdf0e10cSrcweir 
2114cdf0e10cSrcweir 		SCSIZE nFirstLost = nCount-1;
2115cdf0e10cSrcweir         while ( nFirstLost && pData[nFirstLost-1].nRow >= sal::static_int_cast<SCROW>(MAXROW + 1 - nSize) )
2116cdf0e10cSrcweir 			--nFirstLost;
2117cdf0e10cSrcweir 
2118cdf0e10cSrcweir 		if ( ((const ScMergeFlagAttr&)pData[nFirstLost].pPattern->
2119cdf0e10cSrcweir 							GetItem(ATTR_MERGE_FLAG)).IsVerOverlapped() )
2120cdf0e10cSrcweir 			return sal_False;
2121cdf0e10cSrcweir 	}
2122cdf0e10cSrcweir 
2123cdf0e10cSrcweir 	return sal_True;
2124cdf0e10cSrcweir }
2125cdf0e10cSrcweir 
2126cdf0e10cSrcweir 
InsertRow(SCROW nStartRow,SCSIZE nSize)2127cdf0e10cSrcweir void ScAttrArray::InsertRow( SCROW nStartRow, SCSIZE nSize )
2128cdf0e10cSrcweir {
2129cdf0e10cSrcweir 	if (!pData)
2130cdf0e10cSrcweir 		return;
2131cdf0e10cSrcweir 
2132cdf0e10cSrcweir 	SCROW nSearch = nStartRow > 0 ? nStartRow - 1 : 0;		// Vorgaenger erweitern
2133cdf0e10cSrcweir 	SCSIZE nIndex;
2134cdf0e10cSrcweir 	Search( nSearch, nIndex );
2135cdf0e10cSrcweir 
2136cdf0e10cSrcweir 	//	ein gesetztes ScMergeAttr darf nicht ausgedehnt werden
2137cdf0e10cSrcweir 	//	(darum hinterher wieder loeschen)
2138cdf0e10cSrcweir 
2139cdf0e10cSrcweir 	sal_Bool bDoMerge = ((const ScMergeAttr&) pData[nIndex].pPattern->GetItem(ATTR_MERGE)).IsMerged();
2140cdf0e10cSrcweir 
2141cdf0e10cSrcweir 	SCSIZE nRemove = 0;
2142cdf0e10cSrcweir 	SCSIZE i;
2143cdf0e10cSrcweir 	for (i = nIndex; i < nCount-1; i++)
2144cdf0e10cSrcweir 	{
2145cdf0e10cSrcweir 		SCROW nNew = pData[i].nRow + nSize;
2146cdf0e10cSrcweir 		if ( nNew >= MAXROW )					// Ende erreicht ?
2147cdf0e10cSrcweir 		{
2148cdf0e10cSrcweir 			nNew = MAXROW;
2149cdf0e10cSrcweir 			if (!nRemove)
2150cdf0e10cSrcweir 				nRemove = i+1;					// folgende loeschen
2151cdf0e10cSrcweir 		}
2152cdf0e10cSrcweir 		pData[i].nRow = nNew;
2153cdf0e10cSrcweir 	}
2154cdf0e10cSrcweir 
2155cdf0e10cSrcweir 	//	muessen Eintraege am Ende geloescht werden?
2156cdf0e10cSrcweir 
2157cdf0e10cSrcweir 	if (nRemove && nRemove < nCount)
2158cdf0e10cSrcweir 		DeleteRange( nRemove, nCount-1 );
2159cdf0e10cSrcweir 
2160cdf0e10cSrcweir 	if (bDoMerge)			// ausgedehntes ScMergeAttr wieder reparieren
2161cdf0e10cSrcweir 	{
2162cdf0e10cSrcweir 			//!	ApplyAttr fuer Bereiche !!!
2163cdf0e10cSrcweir 
2164cdf0e10cSrcweir 		const SfxPoolItem& rDef = pDocument->GetPool()->GetDefaultItem( ATTR_MERGE );
2165cdf0e10cSrcweir         for (SCSIZE nAdd=0; nAdd<nSize; nAdd++)
2166cdf0e10cSrcweir             pDocument->ApplyAttr( nCol, nStartRow+nAdd, nTab, rDef );
2167cdf0e10cSrcweir 
2168cdf0e10cSrcweir 		//	im eingefuegten Bereich ist nichts zusammengefasst
2169cdf0e10cSrcweir 	}
2170cdf0e10cSrcweir 
2171cdf0e10cSrcweir     // Don't duplicate the merge flags in the inserted row.
2172cdf0e10cSrcweir     // #i108488# SC_MF_SCENARIO has to be allowed.
2173cdf0e10cSrcweir     RemoveFlags( nStartRow, nStartRow+nSize-1, SC_MF_HOR | SC_MF_VER | SC_MF_AUTO | SC_MF_BUTTON );
2174cdf0e10cSrcweir }
2175cdf0e10cSrcweir 
2176cdf0e10cSrcweir 
DeleteRow(SCROW nStartRow,SCSIZE nSize)2177cdf0e10cSrcweir void ScAttrArray::DeleteRow( SCROW nStartRow, SCSIZE nSize )
2178cdf0e10cSrcweir {
2179cdf0e10cSrcweir 	if (pData)
2180cdf0e10cSrcweir 	{
2181cdf0e10cSrcweir 		sal_Bool bFirst=sal_True;
2182cdf0e10cSrcweir         SCSIZE nStartIndex = 0;
2183cdf0e10cSrcweir         SCSIZE nEndIndex = 0;
2184cdf0e10cSrcweir 		SCSIZE i;
2185cdf0e10cSrcweir 
2186cdf0e10cSrcweir 		for ( i = 0; i < nCount-1; i++)
2187cdf0e10cSrcweir             if (pData[i].nRow >= nStartRow && pData[i].nRow <= sal::static_int_cast<SCROW>(nStartRow+nSize-1))
2188cdf0e10cSrcweir 			{
2189cdf0e10cSrcweir 				if (bFirst)
2190cdf0e10cSrcweir 				{
2191cdf0e10cSrcweir 					nStartIndex = i;
2192cdf0e10cSrcweir 					bFirst = sal_False;
2193cdf0e10cSrcweir 				}
2194cdf0e10cSrcweir 				nEndIndex = i;
2195cdf0e10cSrcweir 			}
2196cdf0e10cSrcweir 		if (!bFirst)
2197cdf0e10cSrcweir 		{
2198cdf0e10cSrcweir 			SCROW nStart;
2199cdf0e10cSrcweir 			if (nStartIndex==0)
2200cdf0e10cSrcweir 				nStart = 0;
2201cdf0e10cSrcweir 			else
2202cdf0e10cSrcweir 				nStart = pData[nStartIndex-1].nRow + 1;
2203cdf0e10cSrcweir 
2204cdf0e10cSrcweir 			if (nStart < nStartRow)
2205cdf0e10cSrcweir 			{
2206cdf0e10cSrcweir 				pData[nStartIndex].nRow = nStartRow - 1;
2207cdf0e10cSrcweir 				++nStartIndex;
2208cdf0e10cSrcweir 			}
2209cdf0e10cSrcweir 			if (nEndIndex >= nStartIndex)
2210cdf0e10cSrcweir 			{
2211cdf0e10cSrcweir 				DeleteRange( nStartIndex, nEndIndex );
2212cdf0e10cSrcweir 				if (nStartIndex > 0)
2213cdf0e10cSrcweir 					if ( pData[nStartIndex-1].pPattern == pData[nStartIndex].pPattern )
2214cdf0e10cSrcweir 						DeleteRange( nStartIndex-1, nStartIndex-1 );
2215cdf0e10cSrcweir 			}
2216cdf0e10cSrcweir 		}
2217cdf0e10cSrcweir 		for (i = 0; i < nCount-1; i++)
2218cdf0e10cSrcweir 			if (pData[i].nRow >= nStartRow)
2219cdf0e10cSrcweir 				pData[i].nRow -= nSize;
2220cdf0e10cSrcweir 
2221cdf0e10cSrcweir //		unten nicht Default-Pattern nachschieben, um Druckbereiche erkennen zu koennen
2222cdf0e10cSrcweir //		stattdessen nur Merge-Flags loeschen
2223cdf0e10cSrcweir 
2224cdf0e10cSrcweir 		RemoveFlags( MAXROW-nSize+1, MAXROW, SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
2225cdf0e10cSrcweir 	}
2226cdf0e10cSrcweir }
2227cdf0e10cSrcweir 
2228cdf0e10cSrcweir 
DeleteRange(SCSIZE nStartIndex,SCSIZE nEndIndex)2229cdf0e10cSrcweir void ScAttrArray::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex )
2230cdf0e10cSrcweir {
2231cdf0e10cSrcweir 	ScDocumentPool* pDocPool = pDocument->GetPool();
2232cdf0e10cSrcweir 	for (SCSIZE i = nStartIndex; i <= nEndIndex; i++)
2233cdf0e10cSrcweir 		pDocPool->Remove(*pData[i].pPattern);
2234cdf0e10cSrcweir 
2235cdf0e10cSrcweir 	memmove( &pData[nStartIndex], &pData[nEndIndex + 1], (nCount - nEndIndex - 1) * sizeof(ScAttrEntry) );
2236cdf0e10cSrcweir 	nCount -= nEndIndex-nStartIndex+1;
2237cdf0e10cSrcweir }
2238cdf0e10cSrcweir 
2239cdf0e10cSrcweir 
DeleteArea(SCROW nStartRow,SCROW nEndRow)2240cdf0e10cSrcweir void ScAttrArray::DeleteArea(SCROW nStartRow, SCROW nEndRow)
2241cdf0e10cSrcweir {
2242cdf0e10cSrcweir 	RemoveAreaMerge( nStartRow, nEndRow );			// von zusammengefassten auch die Flags loeschen
2243cdf0e10cSrcweir 
2244cdf0e10cSrcweir 	if ( !HasAttrib( nStartRow, nEndRow, HASATTR_OVERLAPPED | HASATTR_AUTOFILTER) )
2245cdf0e10cSrcweir 		SetPatternArea( nStartRow, nEndRow, pDocument->GetDefPattern() );
2246cdf0e10cSrcweir 	else
2247cdf0e10cSrcweir 		DeleteAreaSafe( nStartRow, nEndRow );		// Merge-Flags stehenlassen
2248cdf0e10cSrcweir }
2249cdf0e10cSrcweir 
2250cdf0e10cSrcweir 
DeleteHardAttr(SCROW nStartRow,SCROW nEndRow)2251cdf0e10cSrcweir void ScAttrArray::DeleteHardAttr(SCROW nStartRow, SCROW nEndRow)
2252cdf0e10cSrcweir {
2253cdf0e10cSrcweir 	const ScPatternAttr* pDefPattern = pDocument->GetDefPattern();
2254cdf0e10cSrcweir 	const ScPatternAttr* pOldPattern;
2255cdf0e10cSrcweir 
2256cdf0e10cSrcweir 	SCSIZE	nIndex;
2257cdf0e10cSrcweir 	SCROW	nRow;
2258cdf0e10cSrcweir 	SCROW	nThisRow;
2259cdf0e10cSrcweir 
2260cdf0e10cSrcweir 	Search( nStartRow, nIndex );
2261cdf0e10cSrcweir 	nThisRow = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
2262cdf0e10cSrcweir 	if (nThisRow < nStartRow) nThisRow = nStartRow;
2263cdf0e10cSrcweir 
2264cdf0e10cSrcweir 	while ( nThisRow <= nEndRow )
2265cdf0e10cSrcweir 	{
2266cdf0e10cSrcweir 		pOldPattern = pData[nIndex].pPattern;
2267cdf0e10cSrcweir 
2268cdf0e10cSrcweir 		if ( pOldPattern->GetItemSet().Count() )		// harte Attribute ?
2269cdf0e10cSrcweir 		{
2270cdf0e10cSrcweir 			nRow = pData[nIndex].nRow;
2271cdf0e10cSrcweir 			SCROW nAttrRow = Min( (SCROW)nRow, (SCROW)nEndRow );
2272cdf0e10cSrcweir 
2273cdf0e10cSrcweir 			ScPatternAttr aNewPattern(*pOldPattern);
2274cdf0e10cSrcweir 			SfxItemSet& rSet = aNewPattern.GetItemSet();
2275cdf0e10cSrcweir 			for (sal_uInt16 nId = ATTR_PATTERN_START; nId <= ATTR_PATTERN_END; nId++)
2276cdf0e10cSrcweir 				if (nId != ATTR_MERGE && nId != ATTR_MERGE_FLAG)
2277cdf0e10cSrcweir 					rSet.ClearItem(nId);
2278cdf0e10cSrcweir 
2279cdf0e10cSrcweir 			if ( aNewPattern == *pDefPattern )
2280cdf0e10cSrcweir 				SetPatternArea( nThisRow, nAttrRow, pDefPattern, sal_False );
2281cdf0e10cSrcweir 			else
2282cdf0e10cSrcweir 				SetPatternArea( nThisRow, nAttrRow, &aNewPattern, sal_True );
2283cdf0e10cSrcweir 
2284cdf0e10cSrcweir 			Search( nThisRow, nIndex );									// Daten wurden veraendert !!!
2285cdf0e10cSrcweir 		}
2286cdf0e10cSrcweir 
2287cdf0e10cSrcweir 		++nIndex;
2288cdf0e10cSrcweir 		nThisRow = pData[nIndex-1].nRow+1;
2289cdf0e10cSrcweir 	}
2290cdf0e10cSrcweir }
2291cdf0e10cSrcweir 
2292cdf0e10cSrcweir 		// Verschieben innerhalb eines Dokuments
2293cdf0e10cSrcweir 
MoveTo(SCROW nStartRow,SCROW nEndRow,ScAttrArray & rAttrArray)2294cdf0e10cSrcweir void ScAttrArray::MoveTo(SCROW nStartRow, SCROW nEndRow, ScAttrArray& rAttrArray)
2295cdf0e10cSrcweir {
2296cdf0e10cSrcweir 	SCROW nStart = nStartRow;
2297cdf0e10cSrcweir 	for (SCSIZE i = 0; i < nCount; i++)
2298cdf0e10cSrcweir 	{
2299cdf0e10cSrcweir 		if ((pData[i].nRow >= nStartRow) && ((i==0) ? sal_True : pData[i-1].nRow < nEndRow))
2300cdf0e10cSrcweir 		{
2301cdf0e10cSrcweir 			//	Kopieren (bPutToPool=sal_True)
2302cdf0e10cSrcweir 			rAttrArray.SetPatternArea( nStart, Min( (SCROW)pData[i].nRow, (SCROW)nEndRow ),
2303cdf0e10cSrcweir 										pData[i].pPattern, sal_True );
2304cdf0e10cSrcweir 		}
2305cdf0e10cSrcweir 		nStart = Max( (SCROW)nStart, (SCROW)(pData[i].nRow + 1) );
2306cdf0e10cSrcweir 	}
2307cdf0e10cSrcweir 	DeleteArea(nStartRow, nEndRow);
2308cdf0e10cSrcweir }
2309cdf0e10cSrcweir 
2310cdf0e10cSrcweir 
2311cdf0e10cSrcweir 		// Kopieren zwischen Dokumenten (Clipboard)
2312cdf0e10cSrcweir 
CopyArea(SCROW nStartRow,SCROW nEndRow,long nDy,ScAttrArray & rAttrArray,sal_Int16 nStripFlags)2313cdf0e10cSrcweir void ScAttrArray::CopyArea( SCROW nStartRow, SCROW nEndRow, long nDy, ScAttrArray& rAttrArray,
2314cdf0e10cSrcweir 								sal_Int16 nStripFlags )
2315cdf0e10cSrcweir {
2316cdf0e10cSrcweir 	nStartRow -= nDy;		// Source
2317cdf0e10cSrcweir 	nEndRow -= nDy;
2318cdf0e10cSrcweir 
2319cdf0e10cSrcweir 	SCROW nDestStart = Max((long)((long)nStartRow + nDy), (long) 0);
2320cdf0e10cSrcweir 	SCROW nDestEnd = Min((long)((long)nEndRow + nDy), (long) MAXROW);
2321cdf0e10cSrcweir 
2322cdf0e10cSrcweir 	ScDocumentPool* pSourceDocPool = pDocument->GetPool();
2323cdf0e10cSrcweir 	ScDocumentPool* pDestDocPool = rAttrArray.pDocument->GetPool();
2324cdf0e10cSrcweir 	sal_Bool bSamePool = (pSourceDocPool==pDestDocPool);
2325cdf0e10cSrcweir 
2326cdf0e10cSrcweir 	for (SCSIZE i = 0; (i < nCount) && (nDestStart <= nDestEnd); i++)
2327cdf0e10cSrcweir 	{
2328cdf0e10cSrcweir 		if (pData[i].nRow >= nStartRow)
2329cdf0e10cSrcweir 		{
2330cdf0e10cSrcweir 			const ScPatternAttr* pOldPattern = pData[i].pPattern;
2331cdf0e10cSrcweir 			const ScPatternAttr* pNewPattern;
2332cdf0e10cSrcweir 
2333cdf0e10cSrcweir 			if (IsDefaultItem( pOldPattern ))
2334cdf0e10cSrcweir 			{
2335cdf0e10cSrcweir 				//	am Default muss nichts veraendert werden
2336cdf0e10cSrcweir 
2337cdf0e10cSrcweir 				pNewPattern = (const ScPatternAttr*)
2338cdf0e10cSrcweir 								&pDestDocPool->GetDefaultItem( ATTR_PATTERN );
2339cdf0e10cSrcweir 			}
2340cdf0e10cSrcweir 			else if ( nStripFlags )
2341cdf0e10cSrcweir 			{
2342cdf0e10cSrcweir 				ScPatternAttr* pTmpPattern = new ScPatternAttr( *pOldPattern );
2343cdf0e10cSrcweir 				sal_Int16 nNewFlags = 0;
2344cdf0e10cSrcweir 				if ( nStripFlags != SC_MF_ALL )
2345cdf0e10cSrcweir 					nNewFlags = ((const ScMergeFlagAttr&)pTmpPattern->GetItem(ATTR_MERGE_FLAG)).
2346cdf0e10cSrcweir 								GetValue() & ~nStripFlags;
2347cdf0e10cSrcweir 
2348cdf0e10cSrcweir 				if ( nNewFlags )
2349cdf0e10cSrcweir 					pTmpPattern->GetItemSet().Put( ScMergeFlagAttr( nNewFlags ) );
2350cdf0e10cSrcweir 				else
2351cdf0e10cSrcweir 					pTmpPattern->GetItemSet().ClearItem( ATTR_MERGE_FLAG );
2352cdf0e10cSrcweir 
2353cdf0e10cSrcweir 				if (bSamePool)
2354cdf0e10cSrcweir 					pNewPattern = (ScPatternAttr*) &pDestDocPool->Put(*pTmpPattern);
2355cdf0e10cSrcweir 				else
2356cdf0e10cSrcweir 					pNewPattern = pTmpPattern->PutInPool( rAttrArray.pDocument, pDocument );
2357cdf0e10cSrcweir 				delete pTmpPattern;
2358cdf0e10cSrcweir 			}
2359cdf0e10cSrcweir 			else
2360cdf0e10cSrcweir 			{
2361cdf0e10cSrcweir 				if (bSamePool)
2362cdf0e10cSrcweir 					pNewPattern = (ScPatternAttr*) &pDestDocPool->Put(*pOldPattern);
2363cdf0e10cSrcweir 				else
2364cdf0e10cSrcweir 					pNewPattern = pOldPattern->PutInPool( rAttrArray.pDocument, pDocument );
2365cdf0e10cSrcweir 			}
2366cdf0e10cSrcweir 
2367cdf0e10cSrcweir 			rAttrArray.SetPatternArea(nDestStart,
2368cdf0e10cSrcweir 							Min((SCROW)(pData[i].nRow + nDy), nDestEnd), pNewPattern);
2369cdf0e10cSrcweir 		}
2370cdf0e10cSrcweir 
2371cdf0e10cSrcweir 		// when pasting from clipboard and skipping filtered rows, the adjusted end position
2372cdf0e10cSrcweir 		// can be negative
2373cdf0e10cSrcweir 		nDestStart = Max((long)nDestStart, (long)(pData[i].nRow + nDy + 1));
2374cdf0e10cSrcweir 	}
2375cdf0e10cSrcweir }
2376cdf0e10cSrcweir 
2377cdf0e10cSrcweir 		// Flags stehenlassen
2378cdf0e10cSrcweir 		//! mit CopyArea zusammenfassen !!!
2379cdf0e10cSrcweir 
CopyAreaSafe(SCROW nStartRow,SCROW nEndRow,long nDy,ScAttrArray & rAttrArray)2380cdf0e10cSrcweir void ScAttrArray::CopyAreaSafe( SCROW nStartRow, SCROW nEndRow, long nDy, ScAttrArray& rAttrArray )
2381cdf0e10cSrcweir {
2382cdf0e10cSrcweir 	nStartRow -= nDy;		// Source
2383cdf0e10cSrcweir 	nEndRow -= nDy;
2384cdf0e10cSrcweir 
2385cdf0e10cSrcweir 	SCROW nDestStart = Max((long)((long)nStartRow + nDy), (long) 0);
2386cdf0e10cSrcweir 	SCROW nDestEnd = Min((long)((long)nEndRow + nDy), (long) MAXROW);
2387cdf0e10cSrcweir 
2388cdf0e10cSrcweir 	if ( !rAttrArray.HasAttrib( nDestStart, nDestEnd, HASATTR_OVERLAPPED ) )
2389cdf0e10cSrcweir 	{
2390cdf0e10cSrcweir 		CopyArea( nStartRow+nDy, nEndRow+nDy, nDy, rAttrArray );
2391cdf0e10cSrcweir 		return;
2392cdf0e10cSrcweir 	}
2393cdf0e10cSrcweir 
2394cdf0e10cSrcweir 	ScDocumentPool* pSourceDocPool = pDocument->GetPool();
2395cdf0e10cSrcweir 	ScDocumentPool* pDestDocPool = rAttrArray.pDocument->GetPool();
2396cdf0e10cSrcweir 	sal_Bool bSamePool = (pSourceDocPool==pDestDocPool);
2397cdf0e10cSrcweir 
2398cdf0e10cSrcweir 	for (SCSIZE i = 0; (i < nCount) && (nDestStart <= nDestEnd); i++)
2399cdf0e10cSrcweir 	{
2400cdf0e10cSrcweir 		if (pData[i].nRow >= nStartRow)
2401cdf0e10cSrcweir 		{
2402cdf0e10cSrcweir 			const ScPatternAttr* pOldPattern = pData[i].pPattern;
2403cdf0e10cSrcweir 			const ScPatternAttr* pNewPattern;
2404cdf0e10cSrcweir 
2405cdf0e10cSrcweir 			if (bSamePool)
2406cdf0e10cSrcweir 				pNewPattern = (ScPatternAttr*) &pDestDocPool->Put(*pOldPattern);
2407cdf0e10cSrcweir 			else
2408cdf0e10cSrcweir 				pNewPattern = pOldPattern->PutInPool( rAttrArray.pDocument, pDocument );
2409cdf0e10cSrcweir 
2410cdf0e10cSrcweir 			rAttrArray.SetPatternAreaSafe(nDestStart,
2411cdf0e10cSrcweir 							Min((SCROW)(pData[i].nRow + nDy), nDestEnd), pNewPattern, sal_False);
2412cdf0e10cSrcweir 		}
2413cdf0e10cSrcweir 
2414cdf0e10cSrcweir 		// when pasting from clipboard and skipping filtered rows, the adjusted end position
2415cdf0e10cSrcweir 		// can be negative
2416cdf0e10cSrcweir 		nDestStart = Max((long)nDestStart, (long)(pData[i].nRow + nDy + 1));
2417cdf0e10cSrcweir 	}
2418cdf0e10cSrcweir }
2419cdf0e10cSrcweir 
2420cdf0e10cSrcweir 
SearchStyle(SCsROW nRow,const ScStyleSheet * pSearchStyle,sal_Bool bUp,ScMarkArray * pMarkArray)2421cdf0e10cSrcweir SCsROW ScAttrArray::SearchStyle( SCsROW nRow, const ScStyleSheet* pSearchStyle,
2422cdf0e10cSrcweir 									sal_Bool bUp, ScMarkArray* pMarkArray )
2423cdf0e10cSrcweir {
2424cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
2425cdf0e10cSrcweir 
2426cdf0e10cSrcweir 	if (pMarkArray)
2427cdf0e10cSrcweir 	{
2428cdf0e10cSrcweir 		nRow = pMarkArray->GetNextMarked( nRow, bUp );
2429cdf0e10cSrcweir 		if (!VALIDROW(nRow))
2430cdf0e10cSrcweir 			return nRow;
2431cdf0e10cSrcweir 	}
2432cdf0e10cSrcweir 
2433cdf0e10cSrcweir 	SCSIZE nIndex;
2434cdf0e10cSrcweir 	Search(nRow, nIndex);
2435cdf0e10cSrcweir 	const ScPatternAttr* pPattern = pData[nIndex].pPattern;
2436cdf0e10cSrcweir 
2437cdf0e10cSrcweir 	while (nIndex < nCount && !bFound)
2438cdf0e10cSrcweir 	{
2439cdf0e10cSrcweir 		if (pPattern->GetStyleSheet() == pSearchStyle)
2440cdf0e10cSrcweir 		{
2441cdf0e10cSrcweir 			if (pMarkArray)
2442cdf0e10cSrcweir 			{
2443cdf0e10cSrcweir 				nRow = pMarkArray->GetNextMarked( nRow, bUp );
2444cdf0e10cSrcweir 				SCROW nStart = nIndex ? pData[nIndex-1].nRow+1 : 0;
2445cdf0e10cSrcweir 				if (nRow >= nStart && nRow <= pData[nIndex].nRow)
2446cdf0e10cSrcweir 					bFound = sal_True;
2447cdf0e10cSrcweir 			}
2448cdf0e10cSrcweir 			else
2449cdf0e10cSrcweir 				bFound = sal_True;
2450cdf0e10cSrcweir 		}
2451cdf0e10cSrcweir 
2452cdf0e10cSrcweir 		if (!bFound)
2453cdf0e10cSrcweir 		{
2454cdf0e10cSrcweir 			if (bUp)
2455cdf0e10cSrcweir 			{
2456cdf0e10cSrcweir 				if (nIndex==0)
2457cdf0e10cSrcweir                 {
2458cdf0e10cSrcweir                     nIndex = nCount;
2459cdf0e10cSrcweir 					nRow = -1;
2460cdf0e10cSrcweir                 }
2461cdf0e10cSrcweir                 else
2462cdf0e10cSrcweir 				{
2463cdf0e10cSrcweir                     --nIndex;
2464cdf0e10cSrcweir 					nRow = pData[nIndex].nRow;
2465cdf0e10cSrcweir 					pPattern = pData[nIndex].pPattern;
2466cdf0e10cSrcweir 				}
2467cdf0e10cSrcweir 			}
2468cdf0e10cSrcweir 			else
2469cdf0e10cSrcweir 			{
2470cdf0e10cSrcweir 				nRow = pData[nIndex].nRow+1;
2471cdf0e10cSrcweir 				++nIndex;
2472cdf0e10cSrcweir 				if (nIndex<nCount)
2473cdf0e10cSrcweir 					pPattern = pData[nIndex].pPattern;
2474cdf0e10cSrcweir 			}
2475cdf0e10cSrcweir 		}
2476cdf0e10cSrcweir 	}
2477cdf0e10cSrcweir 
2478cdf0e10cSrcweir 	DBG_ASSERT( bFound || !ValidRow(nRow), "interner Fehler in ScAttrArray::SearchStyle" );
2479cdf0e10cSrcweir 
2480cdf0e10cSrcweir 	return nRow;
2481cdf0e10cSrcweir }
2482cdf0e10cSrcweir 
2483cdf0e10cSrcweir 
SearchStyleRange(SCsROW & rRow,SCsROW & rEndRow,const ScStyleSheet * pSearchStyle,sal_Bool bUp,ScMarkArray * pMarkArray)2484cdf0e10cSrcweir sal_Bool ScAttrArray::SearchStyleRange( SCsROW& rRow, SCsROW& rEndRow,
2485cdf0e10cSrcweir 						const ScStyleSheet* pSearchStyle, sal_Bool bUp, ScMarkArray* pMarkArray )
2486cdf0e10cSrcweir {
2487cdf0e10cSrcweir 	SCsROW nStartRow = SearchStyle( rRow, pSearchStyle, bUp, pMarkArray );
2488cdf0e10cSrcweir 	if (VALIDROW(nStartRow))
2489cdf0e10cSrcweir 	{
2490cdf0e10cSrcweir 		SCSIZE nIndex;
2491cdf0e10cSrcweir 		Search(nStartRow,nIndex);
2492cdf0e10cSrcweir 
2493cdf0e10cSrcweir 		rRow = nStartRow;
2494cdf0e10cSrcweir 		if (bUp)
2495cdf0e10cSrcweir 		{
2496cdf0e10cSrcweir 			if (nIndex>0)
2497cdf0e10cSrcweir 				rEndRow = pData[nIndex-1].nRow + 1;
2498cdf0e10cSrcweir 			else
2499cdf0e10cSrcweir 				rEndRow = 0;
2500cdf0e10cSrcweir 			if (pMarkArray)
2501cdf0e10cSrcweir 			{
2502cdf0e10cSrcweir 				SCROW nMarkEnd = pMarkArray->GetMarkEnd( nStartRow, sal_True );
2503cdf0e10cSrcweir 				if (nMarkEnd>rEndRow)
2504cdf0e10cSrcweir 					rEndRow = nMarkEnd;
2505cdf0e10cSrcweir 			}
2506cdf0e10cSrcweir 		}
2507cdf0e10cSrcweir 		else
2508cdf0e10cSrcweir 		{
2509cdf0e10cSrcweir 			rEndRow = pData[nIndex].nRow;
2510cdf0e10cSrcweir 			if (pMarkArray)
2511cdf0e10cSrcweir 			{
2512cdf0e10cSrcweir 				SCROW nMarkEnd = pMarkArray->GetMarkEnd( nStartRow, sal_False );
2513cdf0e10cSrcweir 				if (nMarkEnd<rEndRow)
2514cdf0e10cSrcweir 					rEndRow = nMarkEnd;
2515cdf0e10cSrcweir 			}
2516cdf0e10cSrcweir 		}
2517cdf0e10cSrcweir 
2518cdf0e10cSrcweir 		return sal_True;
2519cdf0e10cSrcweir 	}
2520cdf0e10cSrcweir 	else
2521cdf0e10cSrcweir 		return sal_False;
2522cdf0e10cSrcweir }
2523cdf0e10cSrcweir 
2524cdf0e10cSrcweir //------------------------------------------------------------------------
2525cdf0e10cSrcweir //
2526cdf0e10cSrcweir //							Laden / Speichern
2527cdf0e10cSrcweir //
2528cdf0e10cSrcweir 
2529cdf0e10cSrcweir 
2530cdf0e10cSrcweir #if 0
2531cdf0e10cSrcweir void ScAttrArray::Save( SvStream& /* rStream */ ) const
2532cdf0e10cSrcweir {
2533cdf0e10cSrcweir #if SC_ROWLIMIT_STREAM_ACCESS
2534cdf0e10cSrcweir #error address types changed!
2535cdf0e10cSrcweir     ScWriteHeader aHdr( rStream, 8 );
2536cdf0e10cSrcweir 
2537cdf0e10cSrcweir     ScDocumentPool* pDocPool = pDocument->GetPool();
2538cdf0e10cSrcweir 
2539cdf0e10cSrcweir     sal_uInt16 nSaveCount = nCount;
2540cdf0e10cSrcweir     SCROW nSaveMaxRow = pDocument->GetSrcMaxRow();
2541cdf0e10cSrcweir     if ( nSaveMaxRow != MAXROW )
2542cdf0e10cSrcweir     {
2543cdf0e10cSrcweir         if ( nSaveCount > 1 && pData[nSaveCount-2].nRow >= nSaveMaxRow )
2544cdf0e10cSrcweir         {
2545cdf0e10cSrcweir             pDocument->SetLostData();           // Warnung ausgeben
2546cdf0e10cSrcweir             do
2547cdf0e10cSrcweir                 --nSaveCount;
2548cdf0e10cSrcweir             while ( nSaveCount > 1 && pData[nSaveCount-2].nRow >= nSaveMaxRow );
2549cdf0e10cSrcweir         }
2550cdf0e10cSrcweir     }
2551cdf0e10cSrcweir 
2552cdf0e10cSrcweir     rStream << nSaveCount;
2553cdf0e10cSrcweir 
2554cdf0e10cSrcweir     const SfxPoolItem* pItem;
2555cdf0e10cSrcweir     for (SCSIZE i=0; i<nSaveCount; i++)
2556cdf0e10cSrcweir     {
2557cdf0e10cSrcweir         rStream << Min( pData[i].nRow, nSaveMaxRow );
2558cdf0e10cSrcweir 
2559cdf0e10cSrcweir         const ScPatternAttr* pPattern = pData[i].pPattern;
2560cdf0e10cSrcweir         pDocPool->StoreSurrogate( rStream, pPattern );
2561cdf0e10cSrcweir 
2562cdf0e10cSrcweir         //	sal_False, weil ATTR_CONDITIONAL (noch) nicht in Vorlagen:
2563cdf0e10cSrcweir         if (pPattern->GetItemSet().GetItemState(ATTR_CONDITIONAL,sal_False,&pItem) == SFX_ITEM_SET)
2564cdf0e10cSrcweir             pDocument->SetConditionalUsed( ((const SfxUInt32Item*)pItem)->GetValue() );
2565cdf0e10cSrcweir 
2566cdf0e10cSrcweir         if (pPattern->GetItemSet().GetItemState(ATTR_VALIDDATA,sal_False,&pItem) == SFX_ITEM_SET)
2567cdf0e10cSrcweir             pDocument->SetValidationUsed( ((const SfxUInt32Item*)pItem)->GetValue() );
2568cdf0e10cSrcweir     }
2569cdf0e10cSrcweir #endif // SC_ROWLIMIT_STREAM_ACCESS
2570cdf0e10cSrcweir }
2571cdf0e10cSrcweir 
2572cdf0e10cSrcweir 
2573cdf0e10cSrcweir void ScAttrArray::Load( SvStream& /* rStream */ )
2574cdf0e10cSrcweir {
2575cdf0e10cSrcweir #if SC_ROWLIMIT_STREAM_ACCESS
2576cdf0e10cSrcweir #error address types changed!
2577cdf0e10cSrcweir     ScDocumentPool* pDocPool = pDocument->GetPool();
2578cdf0e10cSrcweir 
2579cdf0e10cSrcweir     ScReadHeader aHdr( rStream );
2580cdf0e10cSrcweir 
2581cdf0e10cSrcweir     sal_uInt16 nNewCount;
2582cdf0e10cSrcweir     rStream >> nNewCount;
2583cdf0e10cSrcweir     if ( nNewCount > MAXROW+1 )                     // wuerde das Array zu gross?
2584cdf0e10cSrcweir     {
2585cdf0e10cSrcweir         pDocument->SetLostData();
2586cdf0e10cSrcweir         rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
2587cdf0e10cSrcweir         return;
2588cdf0e10cSrcweir     }
2589cdf0e10cSrcweir 
2590cdf0e10cSrcweir     Reset( pDocument->GetDefPattern(), sal_False );     // loeschen
2591cdf0e10cSrcweir     pData = new ScAttrEntry[nNewCount];             // neu anlegen
2592cdf0e10cSrcweir     for (SCSIZE i=0; i<nNewCount; i++)
2593cdf0e10cSrcweir     {
2594cdf0e10cSrcweir         rStream >> pData[i].nRow;
2595cdf0e10cSrcweir 
2596cdf0e10cSrcweir         sal_uInt16 nWhich = ATTR_PATTERN;
2597cdf0e10cSrcweir         const ScPatternAttr* pNewPattern = (const ScPatternAttr*)
2598cdf0e10cSrcweir                                            pDocPool->LoadSurrogate( rStream, nWhich, ATTR_PATTERN );
2599cdf0e10cSrcweir         if (!pNewPattern)
2600cdf0e10cSrcweir         {
2601cdf0e10cSrcweir             // da is was schiefgelaufen
2602cdf0e10cSrcweir             DBG_ERROR("ScAttrArray::Load: Surrogat nicht im Pool");
2603cdf0e10cSrcweir             pNewPattern = pDocument->GetDefPattern();
2604cdf0e10cSrcweir         }
2605cdf0e10cSrcweir         ScDocumentPool::CheckRef( *pNewPattern );
2606cdf0e10cSrcweir         pData[i].pPattern = pNewPattern;
2607cdf0e10cSrcweir 
2608cdf0e10cSrcweir         // LoadSurrogate erhoeht auch die Ref
2609cdf0e10cSrcweir     }
2610cdf0e10cSrcweir     nCount = nLimit = nNewCount;
2611cdf0e10cSrcweir 
2612cdf0e10cSrcweir     if ( nCount > 1 && pData[nCount-2].nRow >= MAXROW ) // faengt ein Attribut hinter MAXROW an?
2613cdf0e10cSrcweir     {
2614cdf0e10cSrcweir         pDocument->SetLostData();
2615cdf0e10cSrcweir         rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
2616cdf0e10cSrcweir         return;
2617cdf0e10cSrcweir     }
2618cdf0e10cSrcweir 
2619cdf0e10cSrcweir     if ( pDocument->GetSrcMaxRow() != MAXROW )          // Ende anpassen?
2620cdf0e10cSrcweir     {
2621cdf0e10cSrcweir         //	Ende immer auf MAXROW umsetzen (nur auf 32 Bit)
2622cdf0e10cSrcweir 
2623cdf0e10cSrcweir         DBG_ASSERT( pData[nCount-1].nRow == pDocument->GetSrcMaxRow(), "Attribut-Ende ?!?" );
2624cdf0e10cSrcweir         pData[nCount-1].nRow = MAXROW;
2625cdf0e10cSrcweir     }
2626cdf0e10cSrcweir #endif // SC_ROWLIMIT_STREAM_ACCESS
2627cdf0e10cSrcweir }
2628cdf0e10cSrcweir #endif
2629cdf0e10cSrcweir 
2630cdf0e10cSrcweir 
2631cdf0e10cSrcweir //UNUSED2008-05  void ScAttrArray::ConvertFontsAfterLoad()
2632cdf0e10cSrcweir //UNUSED2008-05  {
2633cdf0e10cSrcweir //UNUSED2008-05      ScFontToSubsFontConverter_AutoPtr xFontConverter;
2634cdf0e10cSrcweir //UNUSED2008-05      const sal_uLong nFlags = FONTTOSUBSFONT_IMPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS;
2635cdf0e10cSrcweir //UNUSED2008-05      SCSIZE   nIndex = 0;
2636cdf0e10cSrcweir //UNUSED2008-05      SCROW  nThisRow = 0;
2637cdf0e10cSrcweir //UNUSED2008-05
2638cdf0e10cSrcweir //UNUSED2008-05      while ( nThisRow <= MAXROW )
2639cdf0e10cSrcweir //UNUSED2008-05      {
2640cdf0e10cSrcweir //UNUSED2008-05          const ScPatternAttr* pOldPattern = pData[nIndex].pPattern;
2641cdf0e10cSrcweir //UNUSED2008-05          const SfxPoolItem* pItem;
2642cdf0e10cSrcweir //UNUSED2008-05          if( pOldPattern->GetItemSet().GetItemState( ATTR_FONT, sal_False, &pItem ) == SFX_ITEM_SET )
2643cdf0e10cSrcweir //UNUSED2008-05          {
2644cdf0e10cSrcweir //UNUSED2008-05              const SvxFontItem* pFontItem = (const SvxFontItem*) pItem;
2645cdf0e10cSrcweir //UNUSED2008-05              const String& rOldName = pFontItem->GetFamilyName();
2646cdf0e10cSrcweir //UNUSED2008-05              xFontConverter = CreateFontToSubsFontConverter( rOldName, nFlags );
2647cdf0e10cSrcweir //UNUSED2008-05              if ( xFontConverter )
2648cdf0e10cSrcweir //UNUSED2008-05              {
2649cdf0e10cSrcweir //UNUSED2008-05                  String aNewName( GetFontToSubsFontName( xFontConverter ) );
2650cdf0e10cSrcweir //UNUSED2008-05                  if ( aNewName != rOldName )
2651cdf0e10cSrcweir //UNUSED2008-05                  {
2652cdf0e10cSrcweir //UNUSED2008-05                      SCROW nAttrRow = pData[nIndex].nRow;
2653cdf0e10cSrcweir //UNUSED2008-05                      SvxFontItem aNewItem( pFontItem->GetFamily(), aNewName,
2654cdf0e10cSrcweir //UNUSED2008-05                          pFontItem->GetStyleName(), pFontItem->GetPitch(),
2655cdf0e10cSrcweir //UNUSED2008-05                          RTL_TEXTENCODING_DONTKNOW, ATTR_FONT );
2656cdf0e10cSrcweir //UNUSED2008-05                      ScPatternAttr aNewPattern( *pOldPattern );
2657cdf0e10cSrcweir //UNUSED2008-05                      aNewPattern.GetItemSet().Put( aNewItem );
2658cdf0e10cSrcweir //UNUSED2008-05                      SetPatternArea( nThisRow, nAttrRow, &aNewPattern, sal_True );
2659cdf0e10cSrcweir //UNUSED2008-05                      Search( nThisRow, nIndex );     //! data changed
2660cdf0e10cSrcweir //UNUSED2008-05                  }
2661cdf0e10cSrcweir //UNUSED2008-05              }
2662cdf0e10cSrcweir //UNUSED2008-05          }
2663cdf0e10cSrcweir //UNUSED2008-05          ++nIndex;
2664cdf0e10cSrcweir //UNUSED2008-05          nThisRow = pData[nIndex-1].nRow+1;
2665cdf0e10cSrcweir //UNUSED2008-05      }
2666cdf0e10cSrcweir //UNUSED2008-05  }
2667cdf0e10cSrcweir 
Count(SCROW nStartRow,SCROW nEndRow)2668*8f4c7c28SSteve Yin SCSIZE ScAttrArray::Count( SCROW nStartRow, SCROW nEndRow )
2669*8f4c7c28SSteve Yin {
2670*8f4c7c28SSteve Yin     SCSIZE	nIndex1, nIndex2;
2671*8f4c7c28SSteve Yin 
2672*8f4c7c28SSteve Yin     if( !Search( nStartRow, nIndex1 ) )
2673*8f4c7c28SSteve Yin         return 0;
2674*8f4c7c28SSteve Yin 
2675*8f4c7c28SSteve Yin     if( !Search( nEndRow, nIndex2 ) )
2676*8f4c7c28SSteve Yin         nIndex2 = this->nCount - 1;
2677*8f4c7c28SSteve Yin 
2678*8f4c7c28SSteve Yin     return nIndex2 - nIndex1 + 1;
2679*8f4c7c28SSteve Yin }
2680