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
10cdf0e10cSrcweir *
11b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
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.
19cdf0e10cSrcweir *
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 // INCLUDE ---------------------------------------------------------------
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include <map>
32cdf0e10cSrcweir
33cdf0e10cSrcweir #include <svl/poolcach.hxx>
34cdf0e10cSrcweir #include <svl/zforlist.hxx>
35cdf0e10cSrcweir #include <editeng/scripttypeitem.hxx>
36cdf0e10cSrcweir #include <string.h>
37cdf0e10cSrcweir
38cdf0e10cSrcweir #include "scitems.hxx"
39cdf0e10cSrcweir #include "column.hxx"
40cdf0e10cSrcweir #include "cell.hxx"
41cdf0e10cSrcweir #include "document.hxx"
42cdf0e10cSrcweir #include "docpool.hxx"
43cdf0e10cSrcweir #include "attarray.hxx"
44cdf0e10cSrcweir #include "patattr.hxx"
45cdf0e10cSrcweir #include "compiler.hxx"
46cdf0e10cSrcweir #include "brdcst.hxx"
47cdf0e10cSrcweir #include "markdata.hxx"
48cdf0e10cSrcweir #include "detfunc.hxx" // for Notes in Sort/Swap
49cdf0e10cSrcweir #include "postit.hxx"
50cdf0e10cSrcweir
51cdf0e10cSrcweir //#pragma optimize ( "", off )
52cdf0e10cSrcweir // nur Search ohne Optimierung!
53cdf0e10cSrcweir
54cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
55cdf0e10cSrcweir using namespace formula;
56cdf0e10cSrcweir
IsAmbiguousScriptNonZero(sal_uInt8 nScript)57cdf0e10cSrcweir inline sal_Bool IsAmbiguousScriptNonZero( sal_uInt8 nScript )
58cdf0e10cSrcweir {
59cdf0e10cSrcweir //! move to a header file
60cdf0e10cSrcweir return ( nScript != SCRIPTTYPE_LATIN &&
61cdf0e10cSrcweir nScript != SCRIPTTYPE_ASIAN &&
62cdf0e10cSrcweir nScript != SCRIPTTYPE_COMPLEX &&
63cdf0e10cSrcweir nScript != 0 );
64cdf0e10cSrcweir }
65cdf0e10cSrcweir
66cdf0e10cSrcweir // -----------------------------------------------------------------------------------------
67cdf0e10cSrcweir
68cdf0e10cSrcweir
ScColumn()69cdf0e10cSrcweir ScColumn::ScColumn() :
70cdf0e10cSrcweir nCol( 0 ),
71cdf0e10cSrcweir nCount( 0 ),
72cdf0e10cSrcweir nLimit( 0 ),
73cdf0e10cSrcweir pItems( NULL ),
74cdf0e10cSrcweir pAttrArray( NULL ),
75cdf0e10cSrcweir pDocument( NULL )
76cdf0e10cSrcweir {
77cdf0e10cSrcweir }
78cdf0e10cSrcweir
79cdf0e10cSrcweir
~ScColumn()80cdf0e10cSrcweir ScColumn::~ScColumn()
81cdf0e10cSrcweir {
82cdf0e10cSrcweir FreeAll();
83cdf0e10cSrcweir if (pAttrArray) delete pAttrArray;
84cdf0e10cSrcweir }
85cdf0e10cSrcweir
86cdf0e10cSrcweir
Init(SCCOL nNewCol,SCTAB nNewTab,ScDocument * pDoc)87cdf0e10cSrcweir void ScColumn::Init(SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc)
88cdf0e10cSrcweir {
89cdf0e10cSrcweir nCol = nNewCol;
90cdf0e10cSrcweir nTab = nNewTab;
91cdf0e10cSrcweir pDocument = pDoc;
92cdf0e10cSrcweir pAttrArray = new ScAttrArray( nCol, nTab, pDocument );
93cdf0e10cSrcweir }
94cdf0e10cSrcweir
95cdf0e10cSrcweir
GetNextUnprotected(SCROW nRow,sal_Bool bUp) const96cdf0e10cSrcweir SCsROW ScColumn::GetNextUnprotected( SCROW nRow, sal_Bool bUp ) const
97cdf0e10cSrcweir {
98cdf0e10cSrcweir return pAttrArray->GetNextUnprotected(nRow, bUp);
99cdf0e10cSrcweir }
100cdf0e10cSrcweir
101cdf0e10cSrcweir
GetBlockMatrixEdges(SCROW nRow1,SCROW nRow2,sal_uInt16 nMask) const102cdf0e10cSrcweir sal_uInt16 ScColumn::GetBlockMatrixEdges( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const
103cdf0e10cSrcweir {
104cdf0e10cSrcweir // nix:0, mitte:1, unten:2, links:4, oben:8, rechts:16, offen:32
105cdf0e10cSrcweir if ( !pItems )
106cdf0e10cSrcweir return 0;
107cdf0e10cSrcweir if ( nRow1 == nRow2 )
108cdf0e10cSrcweir {
109cdf0e10cSrcweir SCSIZE nIndex;
110cdf0e10cSrcweir if ( Search( nRow1, nIndex ) )
111cdf0e10cSrcweir {
112cdf0e10cSrcweir ScBaseCell* pCell = pItems[nIndex].pCell;
113cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA
114cdf0e10cSrcweir && ((ScFormulaCell*)pCell)->GetMatrixFlag() )
115cdf0e10cSrcweir {
116cdf0e10cSrcweir ScAddress aOrg( ScAddress::INITIALIZE_INVALID );
117cdf0e10cSrcweir return ((ScFormulaCell*)pCell)->GetMatrixEdge( aOrg );
118cdf0e10cSrcweir }
119cdf0e10cSrcweir }
120cdf0e10cSrcweir return 0;
121cdf0e10cSrcweir }
122cdf0e10cSrcweir else
123cdf0e10cSrcweir {
124cdf0e10cSrcweir ScAddress aOrg( ScAddress::INITIALIZE_INVALID );
125cdf0e10cSrcweir sal_Bool bOpen = sal_False;
126cdf0e10cSrcweir sal_uInt16 nEdges = 0;
127cdf0e10cSrcweir SCSIZE nIndex;
128cdf0e10cSrcweir Search( nRow1, nIndex );
129cdf0e10cSrcweir while ( nIndex < nCount && pItems[nIndex].nRow <= nRow2 )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir ScBaseCell* pCell = pItems[nIndex].pCell;
132cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA
133cdf0e10cSrcweir && ((ScFormulaCell*)pCell)->GetMatrixFlag() )
134cdf0e10cSrcweir {
135cdf0e10cSrcweir nEdges = ((ScFormulaCell*)pCell)->GetMatrixEdge( aOrg );
136cdf0e10cSrcweir if ( nEdges )
137cdf0e10cSrcweir {
138cdf0e10cSrcweir if ( nEdges & 8 )
139cdf0e10cSrcweir bOpen = sal_True; // obere Kante oeffnet, weitersehen
140cdf0e10cSrcweir else if ( !bOpen )
141cdf0e10cSrcweir return nEdges | 32; // es gibt was, was nicht geoeffnet wurde
142cdf0e10cSrcweir else if ( nEdges & 1 )
143cdf0e10cSrcweir return nEdges; // mittendrin
144cdf0e10cSrcweir // (nMask & 16 und (4 und nicht 16)) oder
145cdf0e10cSrcweir // (nMask & 4 und (16 und nicht 4))
146cdf0e10cSrcweir if ( ((nMask & 16) && (nEdges & 4) && !(nEdges & 16))
147cdf0e10cSrcweir || ((nMask & 4) && (nEdges & 16) && !(nEdges & 4)) )
148cdf0e10cSrcweir return nEdges; // nur linke/rechte Kante
149cdf0e10cSrcweir if ( nEdges & 2 )
150cdf0e10cSrcweir bOpen = sal_False; // untere Kante schliesst
151cdf0e10cSrcweir }
152cdf0e10cSrcweir }
153cdf0e10cSrcweir nIndex++;
154cdf0e10cSrcweir }
155cdf0e10cSrcweir if ( bOpen )
156cdf0e10cSrcweir nEdges |= 32; // es geht noch weiter
157cdf0e10cSrcweir return nEdges;
158cdf0e10cSrcweir }
159cdf0e10cSrcweir }
160cdf0e10cSrcweir
161cdf0e10cSrcweir
HasSelectionMatrixFragment(const ScMarkData & rMark) const162cdf0e10cSrcweir sal_Bool ScColumn::HasSelectionMatrixFragment(const ScMarkData& rMark) const
163cdf0e10cSrcweir {
164cdf0e10cSrcweir if ( rMark.IsMultiMarked() )
165cdf0e10cSrcweir {
166cdf0e10cSrcweir sal_Bool bFound = sal_False;
167cdf0e10cSrcweir
168cdf0e10cSrcweir ScAddress aOrg( ScAddress::INITIALIZE_INVALID );
169cdf0e10cSrcweir ScAddress aCurOrg( ScAddress::INITIALIZE_INVALID );
170cdf0e10cSrcweir SCROW nTop, nBottom;
171cdf0e10cSrcweir ScMarkArrayIter aMarkIter( rMark.GetArray()+nCol );
172cdf0e10cSrcweir while ( !bFound && aMarkIter.Next( nTop, nBottom ) )
173cdf0e10cSrcweir {
174cdf0e10cSrcweir sal_Bool bOpen = sal_False;
175cdf0e10cSrcweir sal_uInt16 nEdges;
176cdf0e10cSrcweir SCSIZE nIndex;
177cdf0e10cSrcweir Search( nTop, nIndex );
178cdf0e10cSrcweir while ( !bFound && nIndex < nCount && pItems[nIndex].nRow <= nBottom )
179cdf0e10cSrcweir {
180cdf0e10cSrcweir ScBaseCell* pCell = pItems[nIndex].pCell;
181cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA
182cdf0e10cSrcweir && ((ScFormulaCell*)pCell)->GetMatrixFlag() )
183cdf0e10cSrcweir {
184cdf0e10cSrcweir nEdges = ((ScFormulaCell*)pCell)->GetMatrixEdge( aOrg );
185cdf0e10cSrcweir if ( nEdges )
186cdf0e10cSrcweir {
187cdf0e10cSrcweir if ( nEdges & 8 )
188cdf0e10cSrcweir bOpen = sal_True; // obere Kante oeffnet, weitersehen
189cdf0e10cSrcweir else if ( !bOpen )
190cdf0e10cSrcweir return sal_True; // es gibt was, was nicht geoeffnet wurde
191cdf0e10cSrcweir else if ( nEdges & 1 )
192cdf0e10cSrcweir bFound = sal_True; // mittendrin, alles selektiert?
193cdf0e10cSrcweir // (4 und nicht 16) oder (16 und nicht 4)
194cdf0e10cSrcweir if ( (((nEdges & 4) | 16) ^ ((nEdges & 16) | 4)) )
195cdf0e10cSrcweir bFound = sal_True; // nur linke/rechte Kante, alles selektiert?
196cdf0e10cSrcweir if ( nEdges & 2 )
197cdf0e10cSrcweir bOpen = sal_False; // untere Kante schliesst
198cdf0e10cSrcweir
199cdf0e10cSrcweir if ( bFound )
200cdf0e10cSrcweir { // alles selektiert?
201cdf0e10cSrcweir if ( aCurOrg != aOrg )
202cdf0e10cSrcweir { // neue Matrix zu pruefen?
203cdf0e10cSrcweir aCurOrg = aOrg;
204cdf0e10cSrcweir ScFormulaCell* pFCell;
205cdf0e10cSrcweir if ( ((ScFormulaCell*)pCell)->GetMatrixFlag()
206cdf0e10cSrcweir == MM_REFERENCE )
207cdf0e10cSrcweir pFCell = (ScFormulaCell*) pDocument->GetCell( aOrg );
208cdf0e10cSrcweir else
209cdf0e10cSrcweir pFCell = (ScFormulaCell*)pCell;
210cdf0e10cSrcweir SCCOL nC;
211cdf0e10cSrcweir SCROW nR;
212cdf0e10cSrcweir pFCell->GetMatColsRows( nC, nR );
213cdf0e10cSrcweir ScRange aRange( aOrg, ScAddress(
214cdf0e10cSrcweir aOrg.Col() + nC - 1, aOrg.Row() + nR - 1,
215cdf0e10cSrcweir aOrg.Tab() ) );
216cdf0e10cSrcweir if ( rMark.IsAllMarked( aRange ) )
217cdf0e10cSrcweir bFound = sal_False;
218cdf0e10cSrcweir }
219cdf0e10cSrcweir else
220cdf0e10cSrcweir bFound = sal_False; // war schon
221cdf0e10cSrcweir }
222cdf0e10cSrcweir }
223cdf0e10cSrcweir }
224cdf0e10cSrcweir nIndex++;
225cdf0e10cSrcweir }
226cdf0e10cSrcweir if ( bOpen )
227cdf0e10cSrcweir return sal_True;
228cdf0e10cSrcweir }
229cdf0e10cSrcweir return bFound;
230cdf0e10cSrcweir }
231cdf0e10cSrcweir else
232cdf0e10cSrcweir return sal_False;
233cdf0e10cSrcweir }
234cdf0e10cSrcweir
235cdf0e10cSrcweir
236cdf0e10cSrcweir //UNUSED2009-05 sal_Bool ScColumn::HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes,
237cdf0e10cSrcweir //UNUSED2009-05 sal_Bool bLeft, sal_Bool bRight ) const
238cdf0e10cSrcweir //UNUSED2009-05 {
239cdf0e10cSrcweir //UNUSED2009-05 return pAttrArray->HasLines( nRow1, nRow2, rSizes, bLeft, bRight );
240cdf0e10cSrcweir //UNUSED2009-05 }
241cdf0e10cSrcweir
242cdf0e10cSrcweir
HasAttrib(SCROW nRow1,SCROW nRow2,sal_uInt16 nMask) const243cdf0e10cSrcweir bool ScColumn::HasAttrib( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const
244cdf0e10cSrcweir {
245cdf0e10cSrcweir return pAttrArray->HasAttrib( nRow1, nRow2, nMask );
246cdf0e10cSrcweir }
247cdf0e10cSrcweir
248cdf0e10cSrcweir
HasAttribSelection(const ScMarkData & rMark,sal_uInt16 nMask) const249cdf0e10cSrcweir sal_Bool ScColumn::HasAttribSelection( const ScMarkData& rMark, sal_uInt16 nMask ) const
250cdf0e10cSrcweir {
251cdf0e10cSrcweir sal_Bool bFound = sal_False;
252cdf0e10cSrcweir
253cdf0e10cSrcweir SCROW nTop;
254cdf0e10cSrcweir SCROW nBottom;
255cdf0e10cSrcweir
256cdf0e10cSrcweir if (rMark.IsMultiMarked())
257cdf0e10cSrcweir {
258cdf0e10cSrcweir ScMarkArrayIter aMarkIter( rMark.GetArray()+nCol );
259cdf0e10cSrcweir while (aMarkIter.Next( nTop, nBottom ) && !bFound)
260cdf0e10cSrcweir {
261cdf0e10cSrcweir if (pAttrArray->HasAttrib( nTop, nBottom, nMask ))
262cdf0e10cSrcweir bFound = sal_True;
263cdf0e10cSrcweir }
264cdf0e10cSrcweir }
265cdf0e10cSrcweir
266cdf0e10cSrcweir return bFound;
267cdf0e10cSrcweir }
268cdf0e10cSrcweir
269cdf0e10cSrcweir
ExtendMerge(SCCOL nThisCol,SCROW nStartRow,SCROW nEndRow,SCCOL & rPaintCol,SCROW & rPaintRow,sal_Bool bRefresh,sal_Bool bAttrs)270cdf0e10cSrcweir sal_Bool ScColumn::ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
271cdf0e10cSrcweir SCCOL& rPaintCol, SCROW& rPaintRow,
272cdf0e10cSrcweir sal_Bool bRefresh, sal_Bool bAttrs )
273cdf0e10cSrcweir {
274cdf0e10cSrcweir return pAttrArray->ExtendMerge( nThisCol, nStartRow, nEndRow, rPaintCol, rPaintRow, bRefresh, bAttrs );
275cdf0e10cSrcweir }
276cdf0e10cSrcweir
277cdf0e10cSrcweir
MergeSelectionPattern(ScMergePatternState & rState,const ScMarkData & rMark,sal_Bool bDeep) const278cdf0e10cSrcweir void ScColumn::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, sal_Bool bDeep ) const
279cdf0e10cSrcweir {
280cdf0e10cSrcweir SCROW nTop;
281cdf0e10cSrcweir SCROW nBottom;
282cdf0e10cSrcweir
283cdf0e10cSrcweir if ( rMark.IsMultiMarked() )
284cdf0e10cSrcweir {
285cdf0e10cSrcweir const ScMarkArray* pArray = rMark.GetArray() + nCol;
286cdf0e10cSrcweir if ( pArray->HasMarks() )
287cdf0e10cSrcweir {
288cdf0e10cSrcweir ScMarkArrayIter aMarkIter( pArray );
289cdf0e10cSrcweir while (aMarkIter.Next( nTop, nBottom ))
290cdf0e10cSrcweir pAttrArray->MergePatternArea( nTop, nBottom, rState, bDeep );
291cdf0e10cSrcweir }
292cdf0e10cSrcweir }
293cdf0e10cSrcweir }
294cdf0e10cSrcweir
295cdf0e10cSrcweir
MergePatternArea(ScMergePatternState & rState,SCROW nRow1,SCROW nRow2,sal_Bool bDeep) const296cdf0e10cSrcweir void ScColumn::MergePatternArea( ScMergePatternState& rState, SCROW nRow1, SCROW nRow2, sal_Bool bDeep ) const
297cdf0e10cSrcweir {
298cdf0e10cSrcweir pAttrArray->MergePatternArea( nRow1, nRow2, rState, bDeep );
299cdf0e10cSrcweir }
300cdf0e10cSrcweir
301cdf0e10cSrcweir
MergeBlockFrame(SvxBoxItem * pLineOuter,SvxBoxInfoItem * pLineInner,ScLineFlags & rFlags,SCROW nStartRow,SCROW nEndRow,sal_Bool bLeft,SCCOL nDistRight) const302cdf0e10cSrcweir void ScColumn::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner,
303cdf0e10cSrcweir ScLineFlags& rFlags,
304cdf0e10cSrcweir SCROW nStartRow, SCROW nEndRow, sal_Bool bLeft, SCCOL nDistRight ) const
305cdf0e10cSrcweir {
306cdf0e10cSrcweir pAttrArray->MergeBlockFrame( pLineOuter, pLineInner, rFlags, nStartRow, nEndRow, bLeft, nDistRight );
307cdf0e10cSrcweir }
308cdf0e10cSrcweir
309cdf0e10cSrcweir
ApplyBlockFrame(const SvxBoxItem * pLineOuter,const SvxBoxInfoItem * pLineInner,SCROW nStartRow,SCROW nEndRow,sal_Bool bLeft,SCCOL nDistRight)310cdf0e10cSrcweir void ScColumn::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
311cdf0e10cSrcweir SCROW nStartRow, SCROW nEndRow, sal_Bool bLeft, SCCOL nDistRight )
312cdf0e10cSrcweir {
313cdf0e10cSrcweir pAttrArray->ApplyBlockFrame( pLineOuter, pLineInner, nStartRow, nEndRow, bLeft, nDistRight );
314cdf0e10cSrcweir }
315cdf0e10cSrcweir
316cdf0e10cSrcweir
GetPattern(SCROW nRow) const317cdf0e10cSrcweir const ScPatternAttr* ScColumn::GetPattern( SCROW nRow ) const
318cdf0e10cSrcweir {
319cdf0e10cSrcweir return pAttrArray->GetPattern( nRow );
320cdf0e10cSrcweir }
321cdf0e10cSrcweir
GetPatternRange(SCROW & rStartRow,SCROW & rEndRow,SCROW nRow) const322*3a02adb1SWang Lei const ScPatternAttr* ScColumn::GetPatternRange( SCROW& rStartRow, SCROW& rEndRow, SCROW nRow ) const
323*3a02adb1SWang Lei {
324*3a02adb1SWang Lei return pAttrArray->GetPatternRange( rStartRow, rEndRow, nRow );
325*3a02adb1SWang Lei }
326cdf0e10cSrcweir
GetAttr(SCROW nRow,sal_uInt16 nWhich) const327cdf0e10cSrcweir const SfxPoolItem* ScColumn::GetAttr( SCROW nRow, sal_uInt16 nWhich ) const
328cdf0e10cSrcweir {
329cdf0e10cSrcweir return &pAttrArray->GetPattern( nRow )->GetItemSet().Get(nWhich);
330cdf0e10cSrcweir }
331cdf0e10cSrcweir
332cdf0e10cSrcweir
GetMostUsedPattern(SCROW nStartRow,SCROW nEndRow) const333cdf0e10cSrcweir const ScPatternAttr* ScColumn::GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const
334cdf0e10cSrcweir {
335cdf0e10cSrcweir ::std::map< const ScPatternAttr*, size_t > aAttrMap;
336cdf0e10cSrcweir const ScPatternAttr* pMaxPattern = 0;
337cdf0e10cSrcweir size_t nMaxCount = 0;
338cdf0e10cSrcweir
339cdf0e10cSrcweir ScAttrIterator aAttrIter( pAttrArray, nStartRow, nEndRow );
340cdf0e10cSrcweir const ScPatternAttr* pPattern;
341cdf0e10cSrcweir SCROW nAttrRow1 = 0, nAttrRow2 = 0;
342cdf0e10cSrcweir
343cdf0e10cSrcweir while( (pPattern = aAttrIter.Next( nAttrRow1, nAttrRow2 )) != 0 )
344cdf0e10cSrcweir {
345cdf0e10cSrcweir size_t& rnCount = aAttrMap[ pPattern ];
346cdf0e10cSrcweir rnCount += (nAttrRow2 - nAttrRow1 + 1);
347cdf0e10cSrcweir if( rnCount > nMaxCount )
348cdf0e10cSrcweir {
349cdf0e10cSrcweir pMaxPattern = pPattern;
350cdf0e10cSrcweir nMaxCount = rnCount;
351cdf0e10cSrcweir }
352cdf0e10cSrcweir }
353cdf0e10cSrcweir
354cdf0e10cSrcweir return pMaxPattern;
355cdf0e10cSrcweir }
356cdf0e10cSrcweir
357cdf0e10cSrcweir
GetNumberFormat(SCROW nRow) const358cdf0e10cSrcweir sal_uLong ScColumn::GetNumberFormat( SCROW nRow ) const
359cdf0e10cSrcweir {
360cdf0e10cSrcweir return pAttrArray->GetPattern( nRow )->GetNumberFormat( pDocument->GetFormatTable() );
361cdf0e10cSrcweir }
362cdf0e10cSrcweir
363cdf0e10cSrcweir
ApplySelectionCache(SfxItemPoolCache * pCache,const ScMarkData & rMark)364cdf0e10cSrcweir SCsROW ScColumn::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark )
365cdf0e10cSrcweir {
366cdf0e10cSrcweir SCROW nTop = 0;
367cdf0e10cSrcweir SCROW nBottom = 0;
368cdf0e10cSrcweir sal_Bool bFound = sal_False;
369cdf0e10cSrcweir
370cdf0e10cSrcweir if ( rMark.IsMultiMarked() )
371cdf0e10cSrcweir {
372cdf0e10cSrcweir ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
373cdf0e10cSrcweir while (aMarkIter.Next( nTop, nBottom ))
374cdf0e10cSrcweir {
375cdf0e10cSrcweir pAttrArray->ApplyCacheArea( nTop, nBottom, pCache );
376cdf0e10cSrcweir bFound = sal_True;
377cdf0e10cSrcweir }
378cdf0e10cSrcweir }
379cdf0e10cSrcweir
380cdf0e10cSrcweir if (!bFound)
381cdf0e10cSrcweir return -1;
382cdf0e10cSrcweir else if (nTop==0 && nBottom==MAXROW)
383cdf0e10cSrcweir return 0;
384cdf0e10cSrcweir else
385cdf0e10cSrcweir return nBottom;
386cdf0e10cSrcweir }
387cdf0e10cSrcweir
388cdf0e10cSrcweir
ChangeSelectionIndent(sal_Bool bIncrement,const ScMarkData & rMark)389cdf0e10cSrcweir void ScColumn::ChangeSelectionIndent( sal_Bool bIncrement, const ScMarkData& rMark )
390cdf0e10cSrcweir {
391cdf0e10cSrcweir SCROW nTop;
392cdf0e10cSrcweir SCROW nBottom;
393cdf0e10cSrcweir
394cdf0e10cSrcweir if ( pAttrArray && rMark.IsMultiMarked() )
395cdf0e10cSrcweir {
396cdf0e10cSrcweir ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
397cdf0e10cSrcweir while (aMarkIter.Next( nTop, nBottom ))
398cdf0e10cSrcweir pAttrArray->ChangeIndent(nTop, nBottom, bIncrement);
399cdf0e10cSrcweir }
400cdf0e10cSrcweir }
401cdf0e10cSrcweir
402cdf0e10cSrcweir
ClearSelectionItems(const sal_uInt16 * pWhich,const ScMarkData & rMark)403cdf0e10cSrcweir void ScColumn::ClearSelectionItems( const sal_uInt16* pWhich,const ScMarkData& rMark )
404cdf0e10cSrcweir {
405cdf0e10cSrcweir SCROW nTop;
406cdf0e10cSrcweir SCROW nBottom;
407cdf0e10cSrcweir
408cdf0e10cSrcweir if ( pAttrArray && rMark.IsMultiMarked() )
409cdf0e10cSrcweir {
410cdf0e10cSrcweir ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
411cdf0e10cSrcweir while (aMarkIter.Next( nTop, nBottom ))
412cdf0e10cSrcweir pAttrArray->ClearItems(nTop, nBottom, pWhich);
413cdf0e10cSrcweir }
414cdf0e10cSrcweir }
415cdf0e10cSrcweir
416cdf0e10cSrcweir
DeleteSelection(sal_uInt16 nDelFlag,const ScMarkData & rMark)417cdf0e10cSrcweir void ScColumn::DeleteSelection( sal_uInt16 nDelFlag, const ScMarkData& rMark )
418cdf0e10cSrcweir {
419cdf0e10cSrcweir SCROW nTop;
420cdf0e10cSrcweir SCROW nBottom;
421cdf0e10cSrcweir
422cdf0e10cSrcweir if ( rMark.IsMultiMarked() )
423cdf0e10cSrcweir {
424cdf0e10cSrcweir ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
425cdf0e10cSrcweir while (aMarkIter.Next( nTop, nBottom ))
426cdf0e10cSrcweir DeleteArea(nTop, nBottom, nDelFlag);
427cdf0e10cSrcweir }
428cdf0e10cSrcweir }
429cdf0e10cSrcweir
430cdf0e10cSrcweir
ApplyPattern(SCROW nRow,const ScPatternAttr & rPatAttr)431cdf0e10cSrcweir void ScColumn::ApplyPattern( SCROW nRow, const ScPatternAttr& rPatAttr )
432cdf0e10cSrcweir {
433cdf0e10cSrcweir const SfxItemSet* pSet = &rPatAttr.GetItemSet();
434cdf0e10cSrcweir SfxItemPoolCache aCache( pDocument->GetPool(), pSet );
435cdf0e10cSrcweir
436cdf0e10cSrcweir const ScPatternAttr* pPattern = pAttrArray->GetPattern( nRow );
437cdf0e10cSrcweir
438cdf0e10cSrcweir // sal_True = alten Eintrag behalten
439cdf0e10cSrcweir
440cdf0e10cSrcweir ScPatternAttr* pNewPattern = (ScPatternAttr*) &aCache.ApplyTo( *pPattern, sal_True );
441cdf0e10cSrcweir ScDocumentPool::CheckRef( *pPattern );
442cdf0e10cSrcweir ScDocumentPool::CheckRef( *pNewPattern );
443cdf0e10cSrcweir
444cdf0e10cSrcweir if (pNewPattern != pPattern)
445cdf0e10cSrcweir pAttrArray->SetPattern( nRow, pNewPattern );
446cdf0e10cSrcweir }
447cdf0e10cSrcweir
448cdf0e10cSrcweir
ApplyPatternArea(SCROW nStartRow,SCROW nEndRow,const ScPatternAttr & rPatAttr)449cdf0e10cSrcweir void ScColumn::ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr )
450cdf0e10cSrcweir {
451cdf0e10cSrcweir const SfxItemSet* pSet = &rPatAttr.GetItemSet();
452cdf0e10cSrcweir SfxItemPoolCache aCache( pDocument->GetPool(), pSet );
453cdf0e10cSrcweir pAttrArray->ApplyCacheArea( nStartRow, nEndRow, &aCache );
454cdf0e10cSrcweir }
455cdf0e10cSrcweir
456cdf0e10cSrcweir
ApplyPatternIfNumberformatIncompatible(const ScRange & rRange,const ScPatternAttr & rPattern,short nNewType)457cdf0e10cSrcweir void ScColumn::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
458cdf0e10cSrcweir const ScPatternAttr& rPattern, short nNewType )
459cdf0e10cSrcweir {
460cdf0e10cSrcweir const SfxItemSet* pSet = &rPattern.GetItemSet();
461cdf0e10cSrcweir SfxItemPoolCache aCache( pDocument->GetPool(), pSet );
462cdf0e10cSrcweir SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
463cdf0e10cSrcweir SCROW nEndRow = rRange.aEnd.Row();
464cdf0e10cSrcweir for ( SCROW nRow = rRange.aStart.Row(); nRow <= nEndRow; nRow++ )
465cdf0e10cSrcweir {
466cdf0e10cSrcweir SCROW nRow1, nRow2;
467cdf0e10cSrcweir const ScPatternAttr* pPattern = pAttrArray->GetPatternRange(
468cdf0e10cSrcweir nRow1, nRow2, nRow );
469cdf0e10cSrcweir sal_uLong nFormat = pPattern->GetNumberFormat( pFormatter );
470cdf0e10cSrcweir short nOldType = pFormatter->GetType( nFormat );
471cdf0e10cSrcweir if ( nOldType == nNewType || pFormatter->IsCompatible( nOldType, nNewType ) )
472cdf0e10cSrcweir nRow = nRow2;
473cdf0e10cSrcweir else
474cdf0e10cSrcweir {
475cdf0e10cSrcweir SCROW nNewRow1 = Max( nRow1, nRow );
476cdf0e10cSrcweir SCROW nNewRow2 = Min( nRow2, nEndRow );
477cdf0e10cSrcweir pAttrArray->ApplyCacheArea( nNewRow1, nNewRow2, &aCache );
478cdf0e10cSrcweir nRow = nNewRow2;
479cdf0e10cSrcweir }
480cdf0e10cSrcweir }
481cdf0e10cSrcweir }
482cdf0e10cSrcweir
483cdf0e10cSrcweir
ApplyStyle(SCROW nRow,const ScStyleSheet & rStyle)484cdf0e10cSrcweir void ScColumn::ApplyStyle( SCROW nRow, const ScStyleSheet& rStyle )
485cdf0e10cSrcweir {
486cdf0e10cSrcweir const ScPatternAttr* pPattern = pAttrArray->GetPattern(nRow);
487cdf0e10cSrcweir ScPatternAttr* pNewPattern = new ScPatternAttr(*pPattern);
488cdf0e10cSrcweir if (pNewPattern)
489cdf0e10cSrcweir {
490cdf0e10cSrcweir pNewPattern->SetStyleSheet((ScStyleSheet*)&rStyle);
491cdf0e10cSrcweir pAttrArray->SetPattern(nRow, pNewPattern, sal_True);
492cdf0e10cSrcweir delete pNewPattern;
493cdf0e10cSrcweir }
494cdf0e10cSrcweir }
495cdf0e10cSrcweir
496cdf0e10cSrcweir
ApplyStyleArea(SCROW nStartRow,SCROW nEndRow,const ScStyleSheet & rStyle)497cdf0e10cSrcweir void ScColumn::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleSheet& rStyle )
498cdf0e10cSrcweir {
499cdf0e10cSrcweir pAttrArray->ApplyStyleArea(nStartRow, nEndRow, (ScStyleSheet*)&rStyle);
500cdf0e10cSrcweir }
501cdf0e10cSrcweir
502cdf0e10cSrcweir
ApplySelectionStyle(const ScStyleSheet & rStyle,const ScMarkData & rMark)503cdf0e10cSrcweir void ScColumn::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
504cdf0e10cSrcweir {
505cdf0e10cSrcweir SCROW nTop;
506cdf0e10cSrcweir SCROW nBottom;
507cdf0e10cSrcweir
508cdf0e10cSrcweir if ( rMark.IsMultiMarked() )
509cdf0e10cSrcweir {
510cdf0e10cSrcweir ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
511cdf0e10cSrcweir while (aMarkIter.Next( nTop, nBottom ))
512cdf0e10cSrcweir pAttrArray->ApplyStyleArea(nTop, nBottom, (ScStyleSheet*)&rStyle);
513cdf0e10cSrcweir }
514cdf0e10cSrcweir }
515cdf0e10cSrcweir
516cdf0e10cSrcweir
ApplySelectionLineStyle(const ScMarkData & rMark,const SvxBorderLine * pLine,sal_Bool bColorOnly)517cdf0e10cSrcweir void ScColumn::ApplySelectionLineStyle( const ScMarkData& rMark,
518cdf0e10cSrcweir const SvxBorderLine* pLine, sal_Bool bColorOnly )
519cdf0e10cSrcweir {
520cdf0e10cSrcweir if ( bColorOnly && !pLine )
521cdf0e10cSrcweir return;
522cdf0e10cSrcweir
523cdf0e10cSrcweir SCROW nTop;
524cdf0e10cSrcweir SCROW nBottom;
525cdf0e10cSrcweir
526cdf0e10cSrcweir if (rMark.IsMultiMarked())
527cdf0e10cSrcweir {
528cdf0e10cSrcweir ScMarkArrayIter aMarkIter( rMark.GetArray()+nCol );
529cdf0e10cSrcweir while (aMarkIter.Next( nTop, nBottom ))
530cdf0e10cSrcweir pAttrArray->ApplyLineStyleArea(nTop, nBottom, pLine, bColorOnly );
531cdf0e10cSrcweir }
532cdf0e10cSrcweir }
533cdf0e10cSrcweir
534cdf0e10cSrcweir
GetStyle(SCROW nRow) const535cdf0e10cSrcweir const ScStyleSheet* ScColumn::GetStyle( SCROW nRow ) const
536cdf0e10cSrcweir {
537cdf0e10cSrcweir return pAttrArray->GetPattern( nRow )->GetStyleSheet();
538cdf0e10cSrcweir }
539cdf0e10cSrcweir
540cdf0e10cSrcweir
GetSelectionStyle(const ScMarkData & rMark,sal_Bool & rFound) const541cdf0e10cSrcweir const ScStyleSheet* ScColumn::GetSelectionStyle( const ScMarkData& rMark, sal_Bool& rFound ) const
542cdf0e10cSrcweir {
543cdf0e10cSrcweir rFound = sal_False;
544cdf0e10cSrcweir if (!rMark.IsMultiMarked())
545cdf0e10cSrcweir {
546cdf0e10cSrcweir DBG_ERROR("ScColumn::GetSelectionStyle ohne Selektion");
547cdf0e10cSrcweir return NULL;
548cdf0e10cSrcweir }
549cdf0e10cSrcweir
550cdf0e10cSrcweir sal_Bool bEqual = sal_True;
551cdf0e10cSrcweir
552cdf0e10cSrcweir const ScStyleSheet* pStyle = NULL;
553cdf0e10cSrcweir const ScStyleSheet* pNewStyle;
554cdf0e10cSrcweir
555cdf0e10cSrcweir ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
556cdf0e10cSrcweir SCROW nTop;
557cdf0e10cSrcweir SCROW nBottom;
558cdf0e10cSrcweir while (bEqual && aMarkIter.Next( nTop, nBottom ))
559cdf0e10cSrcweir {
560cdf0e10cSrcweir ScAttrIterator aAttrIter( pAttrArray, nTop, nBottom );
561cdf0e10cSrcweir SCROW nRow;
562cdf0e10cSrcweir SCROW nDummy;
563cdf0e10cSrcweir const ScPatternAttr* pPattern;
564cdf0e10cSrcweir while (bEqual && ( pPattern = aAttrIter.Next( nRow, nDummy ) ) != NULL)
565cdf0e10cSrcweir {
566cdf0e10cSrcweir pNewStyle = pPattern->GetStyleSheet();
567cdf0e10cSrcweir rFound = sal_True;
568cdf0e10cSrcweir if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
569cdf0e10cSrcweir bEqual = sal_False; // unterschiedliche
570cdf0e10cSrcweir pStyle = pNewStyle;
571cdf0e10cSrcweir }
572cdf0e10cSrcweir }
573cdf0e10cSrcweir
574cdf0e10cSrcweir return bEqual ? pStyle : NULL;
575cdf0e10cSrcweir }
576cdf0e10cSrcweir
577cdf0e10cSrcweir
GetAreaStyle(sal_Bool & rFound,SCROW nRow1,SCROW nRow2) const578cdf0e10cSrcweir const ScStyleSheet* ScColumn::GetAreaStyle( sal_Bool& rFound, SCROW nRow1, SCROW nRow2 ) const
579cdf0e10cSrcweir {
580cdf0e10cSrcweir rFound = sal_False;
581cdf0e10cSrcweir
582cdf0e10cSrcweir sal_Bool bEqual = sal_True;
583cdf0e10cSrcweir
584cdf0e10cSrcweir const ScStyleSheet* pStyle = NULL;
585cdf0e10cSrcweir const ScStyleSheet* pNewStyle;
586cdf0e10cSrcweir
587cdf0e10cSrcweir ScAttrIterator aAttrIter( pAttrArray, nRow1, nRow2 );
588cdf0e10cSrcweir SCROW nRow;
589cdf0e10cSrcweir SCROW nDummy;
590cdf0e10cSrcweir const ScPatternAttr* pPattern;
591cdf0e10cSrcweir while (bEqual && ( pPattern = aAttrIter.Next( nRow, nDummy ) ) != NULL)
592cdf0e10cSrcweir {
593cdf0e10cSrcweir pNewStyle = pPattern->GetStyleSheet();
594cdf0e10cSrcweir rFound = sal_True;
595cdf0e10cSrcweir if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
596cdf0e10cSrcweir bEqual = sal_False; // unterschiedliche
597cdf0e10cSrcweir pStyle = pNewStyle;
598cdf0e10cSrcweir }
599cdf0e10cSrcweir
600cdf0e10cSrcweir return bEqual ? pStyle : NULL;
601cdf0e10cSrcweir }
602cdf0e10cSrcweir
FindStyleSheet(const SfxStyleSheetBase * pStyleSheet,ScFlatBoolRowSegments & rUsedRows,bool bReset)603cdf0e10cSrcweir void ScColumn::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset )
604cdf0e10cSrcweir {
605cdf0e10cSrcweir pAttrArray->FindStyleSheet( pStyleSheet, rUsedRows, bReset );
606cdf0e10cSrcweir }
607cdf0e10cSrcweir
IsStyleSheetUsed(const ScStyleSheet & rStyle,sal_Bool bGatherAllStyles) const608cdf0e10cSrcweir sal_Bool ScColumn::IsStyleSheetUsed( const ScStyleSheet& rStyle, sal_Bool bGatherAllStyles ) const
609cdf0e10cSrcweir {
610cdf0e10cSrcweir return pAttrArray->IsStyleSheetUsed( rStyle, bGatherAllStyles );
611cdf0e10cSrcweir }
612cdf0e10cSrcweir
613cdf0e10cSrcweir
ApplyFlags(SCROW nStartRow,SCROW nEndRow,sal_Int16 nFlags)614cdf0e10cSrcweir sal_Bool ScColumn::ApplyFlags( SCROW nStartRow, SCROW nEndRow, sal_Int16 nFlags )
615cdf0e10cSrcweir {
616cdf0e10cSrcweir return pAttrArray->ApplyFlags( nStartRow, nEndRow, nFlags );
617cdf0e10cSrcweir }
618cdf0e10cSrcweir
619cdf0e10cSrcweir
RemoveFlags(SCROW nStartRow,SCROW nEndRow,sal_Int16 nFlags)620cdf0e10cSrcweir sal_Bool ScColumn::RemoveFlags( SCROW nStartRow, SCROW nEndRow, sal_Int16 nFlags )
621cdf0e10cSrcweir {
622cdf0e10cSrcweir return pAttrArray->RemoveFlags( nStartRow, nEndRow, nFlags );
623cdf0e10cSrcweir }
624cdf0e10cSrcweir
625cdf0e10cSrcweir
ClearItems(SCROW nStartRow,SCROW nEndRow,const sal_uInt16 * pWhich)626cdf0e10cSrcweir void ScColumn::ClearItems( SCROW nStartRow, SCROW nEndRow, const sal_uInt16* pWhich )
627cdf0e10cSrcweir {
628cdf0e10cSrcweir pAttrArray->ClearItems( nStartRow, nEndRow, pWhich );
629cdf0e10cSrcweir }
630cdf0e10cSrcweir
631cdf0e10cSrcweir
SetPattern(SCROW nRow,const ScPatternAttr & rPatAttr,sal_Bool bPutToPool)632cdf0e10cSrcweir void ScColumn::SetPattern( SCROW nRow, const ScPatternAttr& rPatAttr, sal_Bool bPutToPool )
633cdf0e10cSrcweir {
634cdf0e10cSrcweir pAttrArray->SetPattern( nRow, &rPatAttr, bPutToPool );
635cdf0e10cSrcweir }
636cdf0e10cSrcweir
637cdf0e10cSrcweir
SetPatternArea(SCROW nStartRow,SCROW nEndRow,const ScPatternAttr & rPatAttr,sal_Bool bPutToPool)638cdf0e10cSrcweir void ScColumn::SetPatternArea( SCROW nStartRow, SCROW nEndRow,
639cdf0e10cSrcweir const ScPatternAttr& rPatAttr, sal_Bool bPutToPool )
640cdf0e10cSrcweir {
641cdf0e10cSrcweir pAttrArray->SetPatternArea( nStartRow, nEndRow, &rPatAttr, bPutToPool );
642cdf0e10cSrcweir }
643cdf0e10cSrcweir
644cdf0e10cSrcweir
ApplyAttr(SCROW nRow,const SfxPoolItem & rAttr)645cdf0e10cSrcweir void ScColumn::ApplyAttr( SCROW nRow, const SfxPoolItem& rAttr )
646cdf0e10cSrcweir {
647cdf0e10cSrcweir // um nur ein neues SetItem zu erzeugen, brauchen wir keinen SfxItemPoolCache.
648cdf0e10cSrcweir //! Achtung: der SfxItemPoolCache scheint zuviele Refs fuer das neue SetItem zu erzeugen ??
649cdf0e10cSrcweir
650cdf0e10cSrcweir ScDocumentPool* pDocPool = pDocument->GetPool();
651cdf0e10cSrcweir
652cdf0e10cSrcweir const ScPatternAttr* pOldPattern = pAttrArray->GetPattern( nRow );
653cdf0e10cSrcweir ScPatternAttr* pTemp = new ScPatternAttr(*pOldPattern);
654cdf0e10cSrcweir pTemp->GetItemSet().Put(rAttr);
655cdf0e10cSrcweir const ScPatternAttr* pNewPattern = (const ScPatternAttr*) &pDocPool->Put( *pTemp );
656cdf0e10cSrcweir
657cdf0e10cSrcweir if ( pNewPattern != pOldPattern )
658cdf0e10cSrcweir pAttrArray->SetPattern( nRow, pNewPattern );
659cdf0e10cSrcweir else
660cdf0e10cSrcweir pDocPool->Remove( *pNewPattern ); // ausser Spesen nichts gewesen
661cdf0e10cSrcweir
662cdf0e10cSrcweir delete pTemp;
663cdf0e10cSrcweir
664cdf0e10cSrcweir // alte Version mit SfxItemPoolCache:
665cdf0e10cSrcweir #if 0
666cdf0e10cSrcweir SfxItemPoolCache aCache( pDocument->GetPool(), &rAttr );
667cdf0e10cSrcweir
668cdf0e10cSrcweir const ScPatternAttr* pPattern = pAttrArray->GetPattern( nRow );
669cdf0e10cSrcweir
670cdf0e10cSrcweir // sal_True = alten Eintrag behalten
671cdf0e10cSrcweir
672cdf0e10cSrcweir ScPatternAttr* pNewPattern = (ScPatternAttr*) &aCache.ApplyTo( *pPattern, sal_True );
673cdf0e10cSrcweir ScDocumentPool::CheckRef( *pPattern );
674cdf0e10cSrcweir ScDocumentPool::CheckRef( *pNewPattern );
675cdf0e10cSrcweir
676cdf0e10cSrcweir if (pNewPattern != pPattern)
677cdf0e10cSrcweir pAttrArray->SetPattern( nRow, pNewPattern );
678cdf0e10cSrcweir #endif
679cdf0e10cSrcweir }
680cdf0e10cSrcweir
681cdf0e10cSrcweir #ifdef _MSC_VER
682cdf0e10cSrcweir #pragma optimize ( "", off )
683cdf0e10cSrcweir #endif
684cdf0e10cSrcweir
685cdf0e10cSrcweir
Search(SCROW nRow,SCSIZE & nIndex) const686cdf0e10cSrcweir sal_Bool ScColumn::Search( SCROW nRow, SCSIZE& nIndex ) const
687cdf0e10cSrcweir {
688cdf0e10cSrcweir if ( !pItems || !nCount )
689cdf0e10cSrcweir {
690cdf0e10cSrcweir nIndex = 0;
691cdf0e10cSrcweir return sal_False;
692cdf0e10cSrcweir }
693cdf0e10cSrcweir SCROW nMinRow = pItems[0].nRow;
694cdf0e10cSrcweir if ( nRow <= nMinRow )
695cdf0e10cSrcweir {
696cdf0e10cSrcweir nIndex = 0;
697cdf0e10cSrcweir return nRow == nMinRow;
698cdf0e10cSrcweir }
699cdf0e10cSrcweir SCROW nMaxRow = pItems[nCount-1].nRow;
700cdf0e10cSrcweir if ( nRow >= nMaxRow )
701cdf0e10cSrcweir {
702cdf0e10cSrcweir if ( nRow == nMaxRow )
703cdf0e10cSrcweir {
704cdf0e10cSrcweir nIndex = nCount - 1;
705cdf0e10cSrcweir return sal_True;
706cdf0e10cSrcweir }
707cdf0e10cSrcweir else
708cdf0e10cSrcweir {
709cdf0e10cSrcweir nIndex = nCount;
710cdf0e10cSrcweir return sal_False;
711cdf0e10cSrcweir }
712cdf0e10cSrcweir }
713cdf0e10cSrcweir
714cdf0e10cSrcweir long nOldLo, nOldHi;
715cdf0e10cSrcweir long nLo = nOldLo = 0;
716cdf0e10cSrcweir long nHi = nOldHi = Min(static_cast<long>(nCount)-1, static_cast<long>(nRow) );
717cdf0e10cSrcweir long i = 0;
718cdf0e10cSrcweir sal_Bool bFound = sal_False;
719cdf0e10cSrcweir // quite continuous distribution? => interpolating search
720cdf0e10cSrcweir sal_Bool bInterpol = (static_cast<SCSIZE>(nMaxRow - nMinRow) < nCount * 2);
721cdf0e10cSrcweir SCROW nR;
722cdf0e10cSrcweir
723cdf0e10cSrcweir while ( !bFound && nLo <= nHi )
724cdf0e10cSrcweir {
725cdf0e10cSrcweir if ( !bInterpol || nHi - nLo < 3 )
726cdf0e10cSrcweir i = (nLo+nHi) / 2; // no effort, no division by zero
727cdf0e10cSrcweir else
728cdf0e10cSrcweir { // interpolating search
729cdf0e10cSrcweir long nLoRow = pItems[nLo].nRow; // no unsigned underflow upon substraction
730cdf0e10cSrcweir i = nLo + (long)((long)(nRow - nLoRow) * (nHi - nLo)
731cdf0e10cSrcweir / (pItems[nHi].nRow - nLoRow));
732cdf0e10cSrcweir if ( i < 0 || static_cast<SCSIZE>(i) >= nCount )
733cdf0e10cSrcweir { // oops ...
734cdf0e10cSrcweir i = (nLo+nHi) / 2;
735cdf0e10cSrcweir bInterpol = sal_False;
736cdf0e10cSrcweir }
737cdf0e10cSrcweir }
738cdf0e10cSrcweir nR = pItems[i].nRow;
739cdf0e10cSrcweir if ( nR < nRow )
740cdf0e10cSrcweir {
741cdf0e10cSrcweir nLo = i+1;
742cdf0e10cSrcweir if ( bInterpol )
743cdf0e10cSrcweir {
744cdf0e10cSrcweir if ( nLo <= nOldLo )
745cdf0e10cSrcweir bInterpol = sal_False;
746cdf0e10cSrcweir else
747cdf0e10cSrcweir nOldLo = nLo;
748cdf0e10cSrcweir }
749cdf0e10cSrcweir }
750cdf0e10cSrcweir else
751cdf0e10cSrcweir {
752cdf0e10cSrcweir if ( nR > nRow )
753cdf0e10cSrcweir {
754cdf0e10cSrcweir nHi = i-1;
755cdf0e10cSrcweir if ( bInterpol )
756cdf0e10cSrcweir {
757cdf0e10cSrcweir if ( nHi >= nOldHi )
758cdf0e10cSrcweir bInterpol = sal_False;
759cdf0e10cSrcweir else
760cdf0e10cSrcweir nOldHi = nHi;
761cdf0e10cSrcweir }
762cdf0e10cSrcweir }
763cdf0e10cSrcweir else
764cdf0e10cSrcweir bFound = sal_True;
765cdf0e10cSrcweir }
766cdf0e10cSrcweir }
767cdf0e10cSrcweir if (bFound)
768cdf0e10cSrcweir nIndex = static_cast<SCSIZE>(i);
769cdf0e10cSrcweir else
770cdf0e10cSrcweir nIndex = static_cast<SCSIZE>(nLo); // rear index
771cdf0e10cSrcweir return bFound;
772cdf0e10cSrcweir }
773cdf0e10cSrcweir
774cdf0e10cSrcweir #ifdef _MSC_VER
775cdf0e10cSrcweir #pragma optimize ( "", on )
776cdf0e10cSrcweir #endif
777cdf0e10cSrcweir
778cdf0e10cSrcweir
GetCell(SCROW nRow) const779cdf0e10cSrcweir ScBaseCell* ScColumn::GetCell( SCROW nRow ) const
780cdf0e10cSrcweir {
781cdf0e10cSrcweir SCSIZE nIndex;
782cdf0e10cSrcweir if (Search(nRow, nIndex))
783cdf0e10cSrcweir return pItems[nIndex].pCell;
784cdf0e10cSrcweir return NULL;
785cdf0e10cSrcweir }
786cdf0e10cSrcweir
787cdf0e10cSrcweir
Resize(SCSIZE nSize)788cdf0e10cSrcweir void ScColumn::Resize( SCSIZE nSize )
789cdf0e10cSrcweir {
790cdf0e10cSrcweir if (nSize > sal::static_int_cast<SCSIZE>(MAXROWCOUNT))
791cdf0e10cSrcweir nSize = MAXROWCOUNT;
792cdf0e10cSrcweir if (nSize < nCount)
793cdf0e10cSrcweir nSize = nCount;
794cdf0e10cSrcweir
795cdf0e10cSrcweir ColEntry* pNewItems;
796cdf0e10cSrcweir if (nSize)
797cdf0e10cSrcweir {
798cdf0e10cSrcweir SCSIZE nNewSize = nSize + COLUMN_DELTA - 1;
799cdf0e10cSrcweir nNewSize -= nNewSize % COLUMN_DELTA;
800cdf0e10cSrcweir nLimit = nNewSize;
801cdf0e10cSrcweir pNewItems = new ColEntry[nLimit];
802cdf0e10cSrcweir }
803cdf0e10cSrcweir else
804cdf0e10cSrcweir {
805cdf0e10cSrcweir nLimit = 0;
806cdf0e10cSrcweir pNewItems = NULL;
807cdf0e10cSrcweir }
808cdf0e10cSrcweir if (pItems)
809cdf0e10cSrcweir {
810cdf0e10cSrcweir if (pNewItems)
811cdf0e10cSrcweir memmove( pNewItems, pItems, nCount * sizeof(ColEntry) );
812cdf0e10cSrcweir delete[] pItems;
813cdf0e10cSrcweir }
814cdf0e10cSrcweir pItems = pNewItems;
815cdf0e10cSrcweir }
816cdf0e10cSrcweir
817cdf0e10cSrcweir // SwapRow zum Sortieren
818cdf0e10cSrcweir
819cdf0e10cSrcweir namespace {
820cdf0e10cSrcweir
821cdf0e10cSrcweir /** Moves broadcaster from old cell to new cell if exists, otherwise creates a new note cell. */
lclTakeBroadcaster(ScBaseCell * & rpCell,SvtBroadcaster * pBC)822cdf0e10cSrcweir void lclTakeBroadcaster( ScBaseCell*& rpCell, SvtBroadcaster* pBC )
823cdf0e10cSrcweir {
824cdf0e10cSrcweir if( pBC )
825cdf0e10cSrcweir {
826cdf0e10cSrcweir if( rpCell )
827cdf0e10cSrcweir rpCell->TakeBroadcaster( pBC );
828cdf0e10cSrcweir else
829cdf0e10cSrcweir rpCell = new ScNoteCell( pBC );
830cdf0e10cSrcweir }
831cdf0e10cSrcweir }
832cdf0e10cSrcweir
833cdf0e10cSrcweir } // namespace
834cdf0e10cSrcweir
SwapRow(SCROW nRow1,SCROW nRow2)835cdf0e10cSrcweir void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
836cdf0e10cSrcweir {
837cdf0e10cSrcweir /* Simple swap of cell pointers does not work if broadcasters exist (crash
838cdf0e10cSrcweir if cell broadcasts directly or indirectly to itself). While swapping
839cdf0e10cSrcweir the cells, broadcasters have to remain at old positions! */
840cdf0e10cSrcweir
841cdf0e10cSrcweir /* While cloning cells, do not clone notes, but move note pointers to new
842cdf0e10cSrcweir cells. This prevents creation of new caption drawing objects for every
843cdf0e10cSrcweir swap operation while sorting. */
844cdf0e10cSrcweir
845cdf0e10cSrcweir ScBaseCell* pCell1 = 0;
846cdf0e10cSrcweir SCSIZE nIndex1;
847cdf0e10cSrcweir if ( Search( nRow1, nIndex1 ) )
848cdf0e10cSrcweir pCell1 = pItems[nIndex1].pCell;
849cdf0e10cSrcweir
850cdf0e10cSrcweir ScBaseCell* pCell2 = 0;
851cdf0e10cSrcweir SCSIZE nIndex2;
852cdf0e10cSrcweir if ( Search( nRow2, nIndex2 ) )
853cdf0e10cSrcweir pCell2 = pItems[nIndex2].pCell;
854cdf0e10cSrcweir
855cdf0e10cSrcweir // no cells found, nothing to do
856cdf0e10cSrcweir if ( !pCell1 && !pCell2 )
857cdf0e10cSrcweir return ;
858cdf0e10cSrcweir
859cdf0e10cSrcweir // swap variables if first cell is empty, to save some code below
860cdf0e10cSrcweir if ( !pCell1 )
861cdf0e10cSrcweir {
862cdf0e10cSrcweir ::std::swap( nRow1, nRow2 );
863cdf0e10cSrcweir ::std::swap( nIndex1, nIndex2 );
864cdf0e10cSrcweir ::std::swap( pCell1, pCell2 );
865cdf0e10cSrcweir }
866cdf0e10cSrcweir
867cdf0e10cSrcweir // from here: first cell (pCell1, nIndex1) exists always
868cdf0e10cSrcweir
869cdf0e10cSrcweir ScAddress aPos1( nCol, nRow1, nTab );
870cdf0e10cSrcweir ScAddress aPos2( nCol, nRow2, nTab );
871cdf0e10cSrcweir
872cdf0e10cSrcweir CellType eType1 = pCell1->GetCellType();
873cdf0e10cSrcweir CellType eType2 = pCell2 ? pCell2->GetCellType() : CELLTYPE_NONE;
874cdf0e10cSrcweir
875cdf0e10cSrcweir ScFormulaCell* pFmlaCell1 = (eType1 == CELLTYPE_FORMULA) ? static_cast< ScFormulaCell* >( pCell1 ) : 0;
876cdf0e10cSrcweir ScFormulaCell* pFmlaCell2 = (eType2 == CELLTYPE_FORMULA) ? static_cast< ScFormulaCell* >( pCell2 ) : 0;
877cdf0e10cSrcweir
878cdf0e10cSrcweir // simple swap if no formula cells present
879cdf0e10cSrcweir if ( !pFmlaCell1 && !pFmlaCell2 )
880cdf0e10cSrcweir {
881cdf0e10cSrcweir // remember cell broadcasters, must remain at old position
882cdf0e10cSrcweir SvtBroadcaster* pBC1 = pCell1->ReleaseBroadcaster();
883cdf0e10cSrcweir
884cdf0e10cSrcweir if ( pCell2 )
885cdf0e10cSrcweir {
886cdf0e10cSrcweir /* Both cells exist, no formula cells involved, a simple swap can
887cdf0e10cSrcweir be performed (but keep broadcasters and notes at old position). */
888cdf0e10cSrcweir pItems[nIndex1].pCell = pCell2;
889cdf0e10cSrcweir pItems[nIndex2].pCell = pCell1;
890cdf0e10cSrcweir
891cdf0e10cSrcweir SvtBroadcaster* pBC2 = pCell2->ReleaseBroadcaster();
892cdf0e10cSrcweir pCell1->TakeBroadcaster( pBC2 );
893cdf0e10cSrcweir pCell2->TakeBroadcaster( pBC1 );
894cdf0e10cSrcweir }
895cdf0e10cSrcweir else
896cdf0e10cSrcweir {
897cdf0e10cSrcweir ScNoteCell* pDummyCell = pBC1 ? new ScNoteCell( pBC1 ) : 0;
898cdf0e10cSrcweir if ( pDummyCell )
899cdf0e10cSrcweir {
900cdf0e10cSrcweir // insert dummy note cell (without note) containing old broadcaster
901cdf0e10cSrcweir pItems[nIndex1].pCell = pDummyCell;
902cdf0e10cSrcweir }
903cdf0e10cSrcweir else
904cdf0e10cSrcweir {
905cdf0e10cSrcweir // remove ColEntry at old position
906cdf0e10cSrcweir --nCount;
907cdf0e10cSrcweir memmove( &pItems[nIndex1], &pItems[nIndex1 + 1], (nCount - nIndex1) * sizeof(ColEntry) );
908cdf0e10cSrcweir pItems[nCount].nRow = 0;
909cdf0e10cSrcweir pItems[nCount].pCell = 0;
910cdf0e10cSrcweir }
911cdf0e10cSrcweir
912cdf0e10cSrcweir // insert ColEntry at new position
913cdf0e10cSrcweir Insert( nRow2, pCell1 );
914cdf0e10cSrcweir }
915cdf0e10cSrcweir
916cdf0e10cSrcweir return;
917cdf0e10cSrcweir }
918cdf0e10cSrcweir
919cdf0e10cSrcweir // from here: at least one of the cells is a formula cell
920cdf0e10cSrcweir
921cdf0e10cSrcweir /* Never move any array formulas. Disabling sort if parts of array
922cdf0e10cSrcweir formulas are contained is done at UI. */
923cdf0e10cSrcweir if ( (pFmlaCell1 && (pFmlaCell1->GetMatrixFlag() != 0)) || (pFmlaCell2 && (pFmlaCell2->GetMatrixFlag() != 0)) )
924cdf0e10cSrcweir return;
925cdf0e10cSrcweir
926cdf0e10cSrcweir // do not swap, if formulas are equal
927cdf0e10cSrcweir if ( pFmlaCell1 && pFmlaCell2 )
928cdf0e10cSrcweir {
929cdf0e10cSrcweir ScTokenArray* pCode1 = pFmlaCell1->GetCode();
930cdf0e10cSrcweir ScTokenArray* pCode2 = pFmlaCell2->GetCode();
931cdf0e10cSrcweir
932cdf0e10cSrcweir if (pCode1->GetLen() == pCode2->GetLen()) // nicht-UPN
933cdf0e10cSrcweir {
934cdf0e10cSrcweir sal_Bool bEqual = sal_True;
935cdf0e10cSrcweir sal_uInt16 nLen = pCode1->GetLen();
936cdf0e10cSrcweir FormulaToken** ppToken1 = pCode1->GetArray();
937cdf0e10cSrcweir FormulaToken** ppToken2 = pCode2->GetArray();
938cdf0e10cSrcweir for (sal_uInt16 i=0; i<nLen; i++)
939cdf0e10cSrcweir {
940cdf0e10cSrcweir if ( !ppToken1[i]->TextEqual(*(ppToken2[i])) ||
941cdf0e10cSrcweir ppToken1[i]->Is3DRef() || ppToken2[i]->Is3DRef() )
942cdf0e10cSrcweir {
943cdf0e10cSrcweir bEqual = sal_False;
944cdf0e10cSrcweir break;
945cdf0e10cSrcweir }
946cdf0e10cSrcweir }
947cdf0e10cSrcweir
948cdf0e10cSrcweir // do not swap formula cells with equal formulas, but swap notes
949cdf0e10cSrcweir if (bEqual)
950cdf0e10cSrcweir {
951cdf0e10cSrcweir ScPostIt* pNote1 = pCell1->ReleaseNote();
952cdf0e10cSrcweir pCell1->TakeNote( pCell2->ReleaseNote() );
953cdf0e10cSrcweir pCell2->TakeNote( pNote1 );
954cdf0e10cSrcweir return;
955cdf0e10cSrcweir }
956cdf0e10cSrcweir }
957cdf0e10cSrcweir }
958cdf0e10cSrcweir
959cdf0e10cSrcweir // hier kein UpdateReference wegen #30529# - mitsortiert werden nur noch relative Referenzen
960cdf0e10cSrcweir // long dy = (long)nRow2 - (long)nRow1;
961cdf0e10cSrcweir
962cdf0e10cSrcweir /* Create clone of pCell1 at position of pCell2 (pCell1 exists always, see
963cdf0e10cSrcweir variable swapping above). Do not clone the note, but move pointer of
964cdf0e10cSrcweir old note to new cell. */
965cdf0e10cSrcweir ScBaseCell* pNew2 = pCell1->CloneWithoutNote( *pDocument, aPos2, SC_CLONECELL_ADJUST3DREL );
966cdf0e10cSrcweir pNew2->TakeNote( pCell1->ReleaseNote() );
967cdf0e10cSrcweir
968cdf0e10cSrcweir /* Create clone of pCell2 at position of pCell1. Do not clone the note,
969cdf0e10cSrcweir but move pointer of old note to new cell. */
970cdf0e10cSrcweir ScBaseCell* pNew1 = 0;
971cdf0e10cSrcweir if ( pCell2 )
972cdf0e10cSrcweir {
973cdf0e10cSrcweir pNew1 = pCell2->CloneWithoutNote( *pDocument, aPos1, SC_CLONECELL_ADJUST3DREL );
974cdf0e10cSrcweir pNew1->TakeNote( pCell2->ReleaseNote() );
975cdf0e10cSrcweir }
976cdf0e10cSrcweir
977cdf0e10cSrcweir // move old broadcasters new cells at the same old position
978cdf0e10cSrcweir SvtBroadcaster* pBC1 = pCell1->ReleaseBroadcaster();
979cdf0e10cSrcweir lclTakeBroadcaster( pNew1, pBC1 );
980cdf0e10cSrcweir SvtBroadcaster* pBC2 = pCell2 ? pCell2->ReleaseBroadcaster() : 0;
981cdf0e10cSrcweir lclTakeBroadcaster( pNew2, pBC2 );
982cdf0e10cSrcweir
983cdf0e10cSrcweir /* Insert the new cells. Old cell has to be deleted, if there is no new
984cdf0e10cSrcweir cell (call to Insert deletes old cell by itself). */
985cdf0e10cSrcweir if ( !pNew1 )
986cdf0e10cSrcweir Delete( nRow1 ); // deletes pCell1
987cdf0e10cSrcweir else
988cdf0e10cSrcweir Insert( nRow1, pNew1 ); // deletes pCell1, inserts pNew1
989cdf0e10cSrcweir
990cdf0e10cSrcweir if ( pCell2 && !pNew2 )
991cdf0e10cSrcweir Delete( nRow2 ); // deletes pCell2
992cdf0e10cSrcweir else if ( pNew2 )
993cdf0e10cSrcweir Insert( nRow2, pNew2 ); // deletes pCell2 (if existing), inserts pNew2
994cdf0e10cSrcweir }
995cdf0e10cSrcweir
996cdf0e10cSrcweir
SwapCell(SCROW nRow,ScColumn & rCol)997cdf0e10cSrcweir void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
998cdf0e10cSrcweir {
999cdf0e10cSrcweir ScBaseCell* pCell1 = 0;
1000cdf0e10cSrcweir SCSIZE nIndex1;
1001cdf0e10cSrcweir if ( Search( nRow, nIndex1 ) )
1002cdf0e10cSrcweir pCell1 = pItems[nIndex1].pCell;
1003cdf0e10cSrcweir
1004cdf0e10cSrcweir ScBaseCell* pCell2 = 0;
1005cdf0e10cSrcweir SCSIZE nIndex2;
1006cdf0e10cSrcweir if ( rCol.Search( nRow, nIndex2 ) )
1007cdf0e10cSrcweir pCell2 = rCol.pItems[nIndex2].pCell;
1008cdf0e10cSrcweir
1009cdf0e10cSrcweir // reverse call if own cell is missing (ensures own existing cell in following code)
1010cdf0e10cSrcweir if( !pCell1 )
1011cdf0e10cSrcweir {
1012cdf0e10cSrcweir if( pCell2 )
1013cdf0e10cSrcweir rCol.SwapCell( nRow, *this );
1014cdf0e10cSrcweir return;
1015cdf0e10cSrcweir }
1016cdf0e10cSrcweir
1017cdf0e10cSrcweir // from here: own cell (pCell1, nIndex1) exists always
1018cdf0e10cSrcweir
1019cdf0e10cSrcweir ScFormulaCell* pFmlaCell1 = (pCell1->GetCellType() == CELLTYPE_FORMULA) ? static_cast< ScFormulaCell* >( pCell1 ) : 0;
1020cdf0e10cSrcweir ScFormulaCell* pFmlaCell2 = (pCell2 && (pCell2->GetCellType() == CELLTYPE_FORMULA)) ? static_cast< ScFormulaCell* >( pCell2 ) : 0;
1021cdf0e10cSrcweir
1022cdf0e10cSrcweir if ( pCell2 )
1023cdf0e10cSrcweir {
1024cdf0e10cSrcweir // Tauschen
1025cdf0e10cSrcweir pItems[nIndex1].pCell = pCell2;
1026cdf0e10cSrcweir rCol.pItems[nIndex2].pCell = pCell1;
1027cdf0e10cSrcweir // Referenzen aktualisieren
1028cdf0e10cSrcweir SCsCOL dx = rCol.nCol - nCol;
1029cdf0e10cSrcweir if ( pFmlaCell1 )
1030cdf0e10cSrcweir {
1031cdf0e10cSrcweir ScRange aRange( ScAddress( rCol.nCol, 0, nTab ),
1032cdf0e10cSrcweir ScAddress( rCol.nCol, MAXROW, nTab ) );
1033cdf0e10cSrcweir pFmlaCell1->aPos.SetCol( rCol.nCol );
1034cdf0e10cSrcweir pFmlaCell1->UpdateReference(URM_MOVE, aRange, dx, 0, 0);
1035cdf0e10cSrcweir }
1036cdf0e10cSrcweir if ( pFmlaCell2 )
1037cdf0e10cSrcweir {
1038cdf0e10cSrcweir ScRange aRange( ScAddress( nCol, 0, nTab ),
1039cdf0e10cSrcweir ScAddress( nCol, MAXROW, nTab ) );
1040cdf0e10cSrcweir pFmlaCell2->aPos.SetCol( nCol );
1041cdf0e10cSrcweir pFmlaCell2->UpdateReference(URM_MOVE, aRange, -dx, 0, 0);
1042cdf0e10cSrcweir }
1043cdf0e10cSrcweir }
1044cdf0e10cSrcweir else
1045cdf0e10cSrcweir {
1046cdf0e10cSrcweir // Loeschen
1047cdf0e10cSrcweir --nCount;
1048cdf0e10cSrcweir memmove( &pItems[nIndex1], &pItems[nIndex1 + 1], (nCount - nIndex1) * sizeof(ColEntry) );
1049cdf0e10cSrcweir pItems[nCount].nRow = 0;
1050cdf0e10cSrcweir pItems[nCount].pCell = 0;
1051cdf0e10cSrcweir // Referenzen aktualisieren
1052cdf0e10cSrcweir SCsCOL dx = rCol.nCol - nCol;
1053cdf0e10cSrcweir if ( pFmlaCell1 )
1054cdf0e10cSrcweir {
1055cdf0e10cSrcweir ScRange aRange( ScAddress( rCol.nCol, 0, nTab ),
1056cdf0e10cSrcweir ScAddress( rCol.nCol, MAXROW, nTab ) );
1057cdf0e10cSrcweir pFmlaCell1->aPos.SetCol( rCol.nCol );
1058cdf0e10cSrcweir pFmlaCell1->UpdateReference(URM_MOVE, aRange, dx, 0, 0);
1059cdf0e10cSrcweir }
1060cdf0e10cSrcweir // Einfuegen
1061cdf0e10cSrcweir rCol.Insert(nRow, pCell1);
1062cdf0e10cSrcweir }
1063cdf0e10cSrcweir }
1064cdf0e10cSrcweir
1065cdf0e10cSrcweir
TestInsertCol(SCROW nStartRow,SCROW nEndRow) const1066cdf0e10cSrcweir sal_Bool ScColumn::TestInsertCol( SCROW nStartRow, SCROW nEndRow) const
1067cdf0e10cSrcweir {
1068cdf0e10cSrcweir if (!IsEmpty())
1069cdf0e10cSrcweir {
1070cdf0e10cSrcweir sal_Bool bTest = sal_True;
1071cdf0e10cSrcweir if (pItems)
1072cdf0e10cSrcweir for (SCSIZE i=0; (i<nCount) && bTest; i++)
1073cdf0e10cSrcweir bTest = (pItems[i].nRow < nStartRow) || (pItems[i].nRow > nEndRow)
1074cdf0e10cSrcweir || pItems[i].pCell->IsBlank();
1075cdf0e10cSrcweir
1076cdf0e10cSrcweir // AttrArray testet nur zusammengefasste
1077cdf0e10cSrcweir
1078cdf0e10cSrcweir if ((bTest) && (pAttrArray))
1079cdf0e10cSrcweir bTest = pAttrArray->TestInsertCol(nStartRow, nEndRow);
1080cdf0e10cSrcweir
1081cdf0e10cSrcweir //! rausgeschobene Attribute bei Undo beruecksichtigen
1082cdf0e10cSrcweir
1083cdf0e10cSrcweir return bTest;
1084cdf0e10cSrcweir }
1085cdf0e10cSrcweir else
1086cdf0e10cSrcweir return sal_True;
1087cdf0e10cSrcweir }
1088cdf0e10cSrcweir
1089cdf0e10cSrcweir
TestInsertRow(SCSIZE nSize) const1090cdf0e10cSrcweir sal_Bool ScColumn::TestInsertRow( SCSIZE nSize ) const
1091cdf0e10cSrcweir {
1092cdf0e10cSrcweir // AttrArray only looks for merged cells
1093cdf0e10cSrcweir
1094cdf0e10cSrcweir if ( pItems && nCount )
1095cdf0e10cSrcweir return ( nSize <= sal::static_int_cast<SCSIZE>(MAXROW) &&
1096cdf0e10cSrcweir pItems[nCount-1].nRow <= MAXROW-(SCROW)nSize && pAttrArray->TestInsertRow( nSize ) );
1097cdf0e10cSrcweir else
1098cdf0e10cSrcweir return pAttrArray->TestInsertRow( nSize );
1099cdf0e10cSrcweir
1100cdf0e10cSrcweir #if 0
1101cdf0e10cSrcweir //! rausgeschobene Attribute bei Undo beruecksichtigen
1102cdf0e10cSrcweir
1103cdf0e10cSrcweir if ( nSize > static_cast<SCSIZE>(MAXROW) )
1104cdf0e10cSrcweir return sal_False;
1105cdf0e10cSrcweir
1106cdf0e10cSrcweir SCSIZE nVis = nCount;
1107cdf0e10cSrcweir while ( nVis && pItems[nVis-1].pCell->IsBlank() )
1108cdf0e10cSrcweir --nVis;
1109cdf0e10cSrcweir
1110cdf0e10cSrcweir if ( nVis )
1111cdf0e10cSrcweir return ( pItems[nVis-1].nRow <= MAXROW-nSize );
1112cdf0e10cSrcweir else
1113cdf0e10cSrcweir return sal_True;
1114cdf0e10cSrcweir #endif
1115cdf0e10cSrcweir }
1116cdf0e10cSrcweir
1117cdf0e10cSrcweir
InsertRow(SCROW nStartRow,SCSIZE nSize)1118cdf0e10cSrcweir void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
1119cdf0e10cSrcweir {
1120cdf0e10cSrcweir pAttrArray->InsertRow( nStartRow, nSize );
1121cdf0e10cSrcweir
1122cdf0e10cSrcweir //! Search
1123cdf0e10cSrcweir
1124cdf0e10cSrcweir if ( !pItems || !nCount )
1125cdf0e10cSrcweir return;
1126cdf0e10cSrcweir
1127cdf0e10cSrcweir SCSIZE i;
1128cdf0e10cSrcweir Search( nStartRow, i );
1129cdf0e10cSrcweir if ( i >= nCount )
1130cdf0e10cSrcweir return ;
1131cdf0e10cSrcweir
1132cdf0e10cSrcweir sal_Bool bOldAutoCalc = pDocument->GetAutoCalc();
1133cdf0e10cSrcweir pDocument->SetAutoCalc( sal_False ); // Mehrfachberechnungen vermeiden
1134cdf0e10cSrcweir
1135cdf0e10cSrcweir SCSIZE nNewCount = nCount;
1136cdf0e10cSrcweir sal_Bool bCountChanged = sal_False;
1137cdf0e10cSrcweir ScAddress aAdr( nCol, 0, nTab );
1138cdf0e10cSrcweir ScHint aHint( SC_HINT_DATACHANGED, aAdr, NULL ); // only areas (ScBaseCell* == NULL)
1139cdf0e10cSrcweir ScAddress& rAddress = aHint.GetAddress();
1140cdf0e10cSrcweir // for sparse occupation use single broadcasts, not ranges
1141cdf0e10cSrcweir sal_Bool bSingleBroadcasts = (((pItems[nCount-1].nRow - pItems[i].nRow) /
1142cdf0e10cSrcweir (nCount - i)) > 1);
1143cdf0e10cSrcweir if ( bSingleBroadcasts )
1144cdf0e10cSrcweir {
1145cdf0e10cSrcweir SCROW nLastBroadcast = MAXROW+1;
1146cdf0e10cSrcweir for ( ; i < nCount; i++)
1147cdf0e10cSrcweir {
1148cdf0e10cSrcweir SCROW nOldRow = pItems[i].nRow;
1149cdf0e10cSrcweir // #43940# Aenderung Quelle broadcasten
1150cdf0e10cSrcweir if ( nLastBroadcast != nOldRow )
1151cdf0e10cSrcweir { // direkt aufeinanderfolgende nicht doppelt broadcasten
1152cdf0e10cSrcweir rAddress.SetRow( nOldRow );
1153cdf0e10cSrcweir pDocument->AreaBroadcast( aHint );
1154cdf0e10cSrcweir }
1155cdf0e10cSrcweir SCROW nNewRow = (pItems[i].nRow += nSize);
1156cdf0e10cSrcweir // #43940# Aenderung Ziel broadcasten
1157cdf0e10cSrcweir rAddress.SetRow( nNewRow );
1158cdf0e10cSrcweir pDocument->AreaBroadcast( aHint );
1159cdf0e10cSrcweir nLastBroadcast = nNewRow;
1160cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1161cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
1162cdf0e10cSrcweir ((ScFormulaCell*)pCell)->aPos.SetRow( nNewRow );
1163cdf0e10cSrcweir if ( nNewRow > MAXROW && !bCountChanged )
1164cdf0e10cSrcweir {
1165cdf0e10cSrcweir nNewCount = i;
1166cdf0e10cSrcweir bCountChanged = sal_True;
1167cdf0e10cSrcweir }
1168cdf0e10cSrcweir }
1169cdf0e10cSrcweir }
1170cdf0e10cSrcweir else
1171cdf0e10cSrcweir {
1172cdf0e10cSrcweir rAddress.SetRow( pItems[i].nRow );
1173cdf0e10cSrcweir ScRange aRange( rAddress );
1174cdf0e10cSrcweir for ( ; i < nCount; i++)
1175cdf0e10cSrcweir {
1176cdf0e10cSrcweir SCROW nNewRow = (pItems[i].nRow += nSize);
1177cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1178cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
1179cdf0e10cSrcweir ((ScFormulaCell*)pCell)->aPos.SetRow( nNewRow );
1180cdf0e10cSrcweir if ( nNewRow > MAXROW && !bCountChanged )
1181cdf0e10cSrcweir {
1182cdf0e10cSrcweir nNewCount = i;
1183cdf0e10cSrcweir bCountChanged = sal_True;
1184cdf0e10cSrcweir aRange.aEnd.SetRow( MAXROW );
1185cdf0e10cSrcweir }
1186cdf0e10cSrcweir }
1187cdf0e10cSrcweir if ( !bCountChanged )
1188cdf0e10cSrcweir aRange.aEnd.SetRow( pItems[nCount-1].nRow );
1189cdf0e10cSrcweir pDocument->AreaBroadcastInRange( aRange, aHint );
1190cdf0e10cSrcweir }
1191cdf0e10cSrcweir
1192cdf0e10cSrcweir if (bCountChanged)
1193cdf0e10cSrcweir {
1194cdf0e10cSrcweir SCSIZE nDelCount = nCount - nNewCount;
1195cdf0e10cSrcweir ScBaseCell** ppDelCells = new ScBaseCell*[nDelCount];
1196cdf0e10cSrcweir SCROW* pDelRows = new SCROW[nDelCount];
1197cdf0e10cSrcweir for (i = 0; i < nDelCount; i++)
1198cdf0e10cSrcweir {
1199cdf0e10cSrcweir ppDelCells[i] = pItems[nNewCount+i].pCell;
1200cdf0e10cSrcweir pDelRows[i] = pItems[nNewCount+i].nRow;
1201cdf0e10cSrcweir }
1202cdf0e10cSrcweir nCount = nNewCount;
1203cdf0e10cSrcweir
1204cdf0e10cSrcweir for (i = 0; i < nDelCount; i++)
1205cdf0e10cSrcweir {
1206cdf0e10cSrcweir ScBaseCell* pCell = ppDelCells[i];
1207cdf0e10cSrcweir DBG_ASSERT( pCell->IsBlank(), "sichtbare Zelle weggeschoben" );
1208cdf0e10cSrcweir SvtBroadcaster* pBC = pCell->GetBroadcaster();
1209cdf0e10cSrcweir if (pBC)
1210cdf0e10cSrcweir {
1211cdf0e10cSrcweir MoveListeners( *pBC, pDelRows[i] - nSize );
1212cdf0e10cSrcweir pCell->DeleteBroadcaster();
1213cdf0e10cSrcweir pCell->Delete();
1214cdf0e10cSrcweir }
1215cdf0e10cSrcweir }
1216cdf0e10cSrcweir
1217cdf0e10cSrcweir delete [] pDelRows;
1218cdf0e10cSrcweir delete [] ppDelCells;
1219cdf0e10cSrcweir }
1220cdf0e10cSrcweir
1221cdf0e10cSrcweir pDocument->SetAutoCalc( bOldAutoCalc );
1222cdf0e10cSrcweir }
1223cdf0e10cSrcweir
1224cdf0e10cSrcweir
CopyToClip(SCROW nRow1,SCROW nRow2,ScColumn & rColumn,sal_Bool bKeepScenarioFlags,sal_Bool bCloneNoteCaptions)1225cdf0e10cSrcweir void ScColumn::CopyToClip(SCROW nRow1, SCROW nRow2, ScColumn& rColumn, sal_Bool bKeepScenarioFlags, sal_Bool bCloneNoteCaptions)
1226cdf0e10cSrcweir {
1227cdf0e10cSrcweir pAttrArray->CopyArea( nRow1, nRow2, 0, *rColumn.pAttrArray,
1228cdf0e10cSrcweir bKeepScenarioFlags ? (SC_MF_ALL & ~SC_MF_SCENARIO) : SC_MF_ALL );
1229cdf0e10cSrcweir
1230cdf0e10cSrcweir SCSIZE i;
1231cdf0e10cSrcweir SCSIZE nBlockCount = 0;
1232cdf0e10cSrcweir SCSIZE nStartIndex = 0, nEndIndex = 0;
1233cdf0e10cSrcweir for (i = 0; i < nCount; i++)
1234cdf0e10cSrcweir if ((pItems[i].nRow >= nRow1) && (pItems[i].nRow <= nRow2))
1235cdf0e10cSrcweir {
1236cdf0e10cSrcweir if (!nBlockCount)
1237cdf0e10cSrcweir nStartIndex = i;
1238cdf0e10cSrcweir nEndIndex = i;
1239cdf0e10cSrcweir ++nBlockCount;
1240cdf0e10cSrcweir
1241cdf0e10cSrcweir // im Clipboard muessen interpretierte Zellen stehen, um andere Formate
1242cdf0e10cSrcweir // (Text, Grafik...) erzueugen zu koennen
1243cdf0e10cSrcweir
1244cdf0e10cSrcweir if ( pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA )
1245cdf0e10cSrcweir {
1246cdf0e10cSrcweir ScFormulaCell* pFCell = (ScFormulaCell*) pItems[i].pCell;
1247cdf0e10cSrcweir if (pFCell->GetDirty() && pDocument->GetAutoCalc())
1248cdf0e10cSrcweir pFCell->Interpret();
1249cdf0e10cSrcweir }
1250cdf0e10cSrcweir }
1251cdf0e10cSrcweir
1252cdf0e10cSrcweir if (nBlockCount)
1253cdf0e10cSrcweir {
1254cdf0e10cSrcweir int nCloneFlags = bCloneNoteCaptions ? SC_CLONECELL_DEFAULT : SC_CLONECELL_NOCAPTION;
1255cdf0e10cSrcweir rColumn.Resize( rColumn.GetCellCount() + nBlockCount );
1256cdf0e10cSrcweir ScAddress aOwnPos( nCol, 0, nTab );
1257cdf0e10cSrcweir ScAddress aDestPos( rColumn.nCol, 0, rColumn.nTab );
1258cdf0e10cSrcweir for (i = nStartIndex; i <= nEndIndex; i++)
1259cdf0e10cSrcweir {
1260cdf0e10cSrcweir aOwnPos.SetRow( pItems[i].nRow );
1261cdf0e10cSrcweir aDestPos.SetRow( pItems[i].nRow );
1262cdf0e10cSrcweir ScBaseCell* pNewCell = pItems[i].pCell->CloneWithNote( aOwnPos, *rColumn.pDocument, aDestPos, nCloneFlags );
1263cdf0e10cSrcweir rColumn.Append( aDestPos.Row(), pNewCell );
1264cdf0e10cSrcweir }
1265cdf0e10cSrcweir }
1266cdf0e10cSrcweir }
1267cdf0e10cSrcweir
1268cdf0e10cSrcweir
CopyToColumn(SCROW nRow1,SCROW nRow2,sal_uInt16 nFlags,sal_Bool bMarked,ScColumn & rColumn,const ScMarkData * pMarkData,sal_Bool bAsLink)1269cdf0e10cSrcweir void ScColumn::CopyToColumn(SCROW nRow1, SCROW nRow2, sal_uInt16 nFlags, sal_Bool bMarked,
1270cdf0e10cSrcweir ScColumn& rColumn, const ScMarkData* pMarkData, sal_Bool bAsLink )
1271cdf0e10cSrcweir {
1272cdf0e10cSrcweir if (bMarked)
1273cdf0e10cSrcweir {
1274cdf0e10cSrcweir SCROW nStart, nEnd;
1275cdf0e10cSrcweir if (pMarkData && pMarkData->IsMultiMarked())
1276cdf0e10cSrcweir {
1277cdf0e10cSrcweir ScMarkArrayIter aIter( pMarkData->GetArray()+nCol );
1278cdf0e10cSrcweir
1279cdf0e10cSrcweir while ( aIter.Next( nStart, nEnd ) && nStart <= nRow2 )
1280cdf0e10cSrcweir {
1281cdf0e10cSrcweir if ( nEnd >= nRow1 )
1282cdf0e10cSrcweir CopyToColumn( Max(nRow1,nStart), Min(nRow2,nEnd),
1283cdf0e10cSrcweir nFlags, sal_False, rColumn, pMarkData, bAsLink );
1284cdf0e10cSrcweir }
1285cdf0e10cSrcweir }
1286cdf0e10cSrcweir else
1287cdf0e10cSrcweir {
1288cdf0e10cSrcweir DBG_ERROR("CopyToColumn: bMarked, aber keine Markierung");
1289cdf0e10cSrcweir }
1290cdf0e10cSrcweir return;
1291cdf0e10cSrcweir }
1292cdf0e10cSrcweir
1293cdf0e10cSrcweir if ( (nFlags & IDF_ATTRIB) != 0 )
1294cdf0e10cSrcweir {
1295cdf0e10cSrcweir if ( (nFlags & IDF_STYLES) != IDF_STYLES )
1296cdf0e10cSrcweir { // StyleSheets im Zieldokument bleiben erhalten
1297cdf0e10cSrcweir // z.B. DIF und RTF Clipboard-Import
1298cdf0e10cSrcweir for ( SCROW nRow = nRow1; nRow <= nRow2; nRow++ )
1299cdf0e10cSrcweir {
1300cdf0e10cSrcweir const ScStyleSheet* pStyle =
1301cdf0e10cSrcweir rColumn.pAttrArray->GetPattern( nRow )->GetStyleSheet();
1302cdf0e10cSrcweir const ScPatternAttr* pPattern = pAttrArray->GetPattern( nRow );
1303cdf0e10cSrcweir ScPatternAttr* pNewPattern = new ScPatternAttr( *pPattern );
1304cdf0e10cSrcweir pNewPattern->SetStyleSheet( (ScStyleSheet*)pStyle );
1305cdf0e10cSrcweir rColumn.pAttrArray->SetPattern( nRow, pNewPattern, sal_True );
1306cdf0e10cSrcweir delete pNewPattern;
1307cdf0e10cSrcweir }
1308cdf0e10cSrcweir }
1309cdf0e10cSrcweir else
1310cdf0e10cSrcweir pAttrArray->CopyArea( nRow1, nRow2, 0, *rColumn.pAttrArray);
1311cdf0e10cSrcweir }
1312cdf0e10cSrcweir
1313cdf0e10cSrcweir
1314cdf0e10cSrcweir if ((nFlags & IDF_CONTENTS) != 0)
1315cdf0e10cSrcweir {
1316cdf0e10cSrcweir SCSIZE i;
1317cdf0e10cSrcweir SCSIZE nBlockCount = 0;
1318cdf0e10cSrcweir SCSIZE nStartIndex = 0, nEndIndex = 0;
1319cdf0e10cSrcweir for (i = 0; i < nCount; i++)
1320cdf0e10cSrcweir if ((pItems[i].nRow >= nRow1) && (pItems[i].nRow <= nRow2))
1321cdf0e10cSrcweir {
1322cdf0e10cSrcweir if (!nBlockCount)
1323cdf0e10cSrcweir nStartIndex = i;
1324cdf0e10cSrcweir nEndIndex = i;
1325cdf0e10cSrcweir ++nBlockCount;
1326cdf0e10cSrcweir }
1327cdf0e10cSrcweir
1328cdf0e10cSrcweir if (nBlockCount)
1329cdf0e10cSrcweir {
1330cdf0e10cSrcweir rColumn.Resize( rColumn.GetCellCount() + nBlockCount );
1331cdf0e10cSrcweir ScAddress aDestPos( rColumn.nCol, 0, rColumn.nTab );
1332cdf0e10cSrcweir for (i = nStartIndex; i <= nEndIndex; i++)
1333cdf0e10cSrcweir {
1334cdf0e10cSrcweir aDestPos.SetRow( pItems[i].nRow );
1335cdf0e10cSrcweir ScBaseCell* pNew = bAsLink ?
1336cdf0e10cSrcweir CreateRefCell( rColumn.pDocument, aDestPos, i, nFlags ) :
1337cdf0e10cSrcweir CloneCell( i, nFlags, *rColumn.pDocument, aDestPos );
1338cdf0e10cSrcweir
1339cdf0e10cSrcweir if (pNew)
1340cdf0e10cSrcweir rColumn.Insert(pItems[i].nRow, pNew);
1341cdf0e10cSrcweir }
1342cdf0e10cSrcweir }
1343cdf0e10cSrcweir }
1344cdf0e10cSrcweir }
1345cdf0e10cSrcweir
1346cdf0e10cSrcweir
UndoToColumn(SCROW nRow1,SCROW nRow2,sal_uInt16 nFlags,sal_Bool bMarked,ScColumn & rColumn,const ScMarkData * pMarkData)1347cdf0e10cSrcweir void ScColumn::UndoToColumn(SCROW nRow1, SCROW nRow2, sal_uInt16 nFlags, sal_Bool bMarked,
1348cdf0e10cSrcweir ScColumn& rColumn, const ScMarkData* pMarkData )
1349cdf0e10cSrcweir {
1350cdf0e10cSrcweir if (nRow1 > 0)
1351cdf0e10cSrcweir CopyToColumn( 0, nRow1-1, IDF_FORMULA, sal_False, rColumn );
1352cdf0e10cSrcweir
1353cdf0e10cSrcweir CopyToColumn( nRow1, nRow2, nFlags, bMarked, rColumn, pMarkData ); //! bMarked ????
1354cdf0e10cSrcweir
1355cdf0e10cSrcweir if (nRow2 < MAXROW)
1356cdf0e10cSrcweir CopyToColumn( nRow2+1, MAXROW, IDF_FORMULA, sal_False, rColumn );
1357cdf0e10cSrcweir }
1358cdf0e10cSrcweir
1359cdf0e10cSrcweir
CopyUpdated(const ScColumn & rPosCol,ScColumn & rDestCol) const1360cdf0e10cSrcweir void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const
1361cdf0e10cSrcweir {
1362cdf0e10cSrcweir ScDocument& rDestDoc = *rDestCol.pDocument;
1363cdf0e10cSrcweir ScAddress aOwnPos( nCol, 0, nTab );
1364cdf0e10cSrcweir ScAddress aDestPos( rDestCol.nCol, 0, rDestCol.nTab );
1365cdf0e10cSrcweir
1366cdf0e10cSrcweir SCSIZE nPosCount = rPosCol.nCount;
1367cdf0e10cSrcweir for (SCSIZE nPosIndex = 0; nPosIndex < nPosCount; nPosIndex++)
1368cdf0e10cSrcweir {
1369cdf0e10cSrcweir aOwnPos.SetRow( rPosCol.pItems[nPosIndex].nRow );
1370cdf0e10cSrcweir aDestPos.SetRow( aOwnPos.Row() );
1371cdf0e10cSrcweir SCSIZE nThisIndex;
1372cdf0e10cSrcweir if ( Search( aDestPos.Row(), nThisIndex ) )
1373cdf0e10cSrcweir {
1374cdf0e10cSrcweir ScBaseCell* pNew = pItems[nThisIndex].pCell->CloneWithNote( aOwnPos, rDestDoc, aDestPos );
1375cdf0e10cSrcweir rDestCol.Insert( aDestPos.Row(), pNew );
1376cdf0e10cSrcweir }
1377cdf0e10cSrcweir }
1378cdf0e10cSrcweir
1379cdf0e10cSrcweir // Dummy:
1380cdf0e10cSrcweir // CopyToColumn( 0,MAXROW, IDF_FORMULA, sal_False, rDestCol, NULL, sal_False );
1381cdf0e10cSrcweir }
1382cdf0e10cSrcweir
1383cdf0e10cSrcweir
CopyScenarioFrom(const ScColumn & rSrcCol)1384cdf0e10cSrcweir void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol )
1385cdf0e10cSrcweir {
1386cdf0e10cSrcweir // Dies ist die Szenario-Tabelle, die Daten werden hineinkopiert
1387cdf0e10cSrcweir
1388cdf0e10cSrcweir ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
1389cdf0e10cSrcweir SCROW nStart = -1, nEnd = -1;
1390cdf0e10cSrcweir const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
1391cdf0e10cSrcweir while (pPattern)
1392cdf0e10cSrcweir {
1393cdf0e10cSrcweir if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
1394cdf0e10cSrcweir {
1395cdf0e10cSrcweir DeleteArea( nStart, nEnd, IDF_CONTENTS );
1396cdf0e10cSrcweir ((ScColumn&)rSrcCol).
1397cdf0e10cSrcweir CopyToColumn( nStart, nEnd, IDF_CONTENTS, sal_False, *this );
1398cdf0e10cSrcweir
1399cdf0e10cSrcweir // UpdateUsed nicht noetig, schon in TestCopyScenario passiert
1400cdf0e10cSrcweir
1401cdf0e10cSrcweir SCsTAB nDz = nTab - rSrcCol.nTab;
1402cdf0e10cSrcweir UpdateReference(URM_COPY, nCol, nStart, nTab,
1403cdf0e10cSrcweir nCol, nEnd, nTab,
1404cdf0e10cSrcweir 0, 0, nDz, NULL);
1405cdf0e10cSrcweir UpdateCompile();
1406cdf0e10cSrcweir }
1407cdf0e10cSrcweir
1408cdf0e10cSrcweir //! CopyToColumn "const" machen !!!
1409cdf0e10cSrcweir
1410cdf0e10cSrcweir pPattern = aAttrIter.Next( nStart, nEnd );
1411cdf0e10cSrcweir }
1412cdf0e10cSrcweir }
1413cdf0e10cSrcweir
1414cdf0e10cSrcweir
CopyScenarioTo(ScColumn & rDestCol) const1415cdf0e10cSrcweir void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const
1416cdf0e10cSrcweir {
1417cdf0e10cSrcweir // Dies ist die Szenario-Tabelle, die Daten werden in die andere kopiert
1418cdf0e10cSrcweir
1419cdf0e10cSrcweir ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
1420cdf0e10cSrcweir SCROW nStart = -1, nEnd = -1;
1421cdf0e10cSrcweir const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
1422cdf0e10cSrcweir while (pPattern)
1423cdf0e10cSrcweir {
1424cdf0e10cSrcweir if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
1425cdf0e10cSrcweir {
1426cdf0e10cSrcweir rDestCol.DeleteArea( nStart, nEnd, IDF_CONTENTS );
1427cdf0e10cSrcweir ((ScColumn*)this)->
1428cdf0e10cSrcweir CopyToColumn( nStart, nEnd, IDF_CONTENTS, sal_False, rDestCol );
1429cdf0e10cSrcweir
1430cdf0e10cSrcweir // UpdateUsed nicht noetig, schon in TestCopyScenario passiert
1431cdf0e10cSrcweir
1432cdf0e10cSrcweir SCsTAB nDz = rDestCol.nTab - nTab;
1433cdf0e10cSrcweir rDestCol.UpdateReference(URM_COPY, rDestCol.nCol, nStart, rDestCol.nTab,
1434cdf0e10cSrcweir rDestCol.nCol, nEnd, rDestCol.nTab,
1435cdf0e10cSrcweir 0, 0, nDz, NULL);
1436cdf0e10cSrcweir rDestCol.UpdateCompile();
1437cdf0e10cSrcweir }
1438cdf0e10cSrcweir
1439cdf0e10cSrcweir //! CopyToColumn "const" machen !!!
1440cdf0e10cSrcweir
1441cdf0e10cSrcweir pPattern = aAttrIter.Next( nStart, nEnd );
1442cdf0e10cSrcweir }
1443cdf0e10cSrcweir }
1444cdf0e10cSrcweir
1445cdf0e10cSrcweir
TestCopyScenarioTo(const ScColumn & rDestCol) const1446cdf0e10cSrcweir sal_Bool ScColumn::TestCopyScenarioTo( const ScColumn& rDestCol ) const
1447cdf0e10cSrcweir {
1448cdf0e10cSrcweir sal_Bool bOk = sal_True;
1449cdf0e10cSrcweir ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
1450cdf0e10cSrcweir SCROW nStart = 0, nEnd = 0;
1451cdf0e10cSrcweir const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
1452cdf0e10cSrcweir while (pPattern && bOk)
1453cdf0e10cSrcweir {
1454cdf0e10cSrcweir if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
1455cdf0e10cSrcweir if ( rDestCol.pAttrArray->HasAttrib( nStart, nEnd, HASATTR_PROTECTED ) )
1456cdf0e10cSrcweir bOk = sal_False;
1457cdf0e10cSrcweir
1458cdf0e10cSrcweir pPattern = aAttrIter.Next( nStart, nEnd );
1459cdf0e10cSrcweir }
1460cdf0e10cSrcweir return bOk;
1461cdf0e10cSrcweir }
1462cdf0e10cSrcweir
1463cdf0e10cSrcweir
MarkScenarioIn(ScMarkData & rDestMark) const1464cdf0e10cSrcweir void ScColumn::MarkScenarioIn( ScMarkData& rDestMark ) const
1465cdf0e10cSrcweir {
1466cdf0e10cSrcweir ScRange aRange( nCol, 0, nTab );
1467cdf0e10cSrcweir
1468cdf0e10cSrcweir ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
1469cdf0e10cSrcweir SCROW nStart = -1, nEnd = -1;
1470cdf0e10cSrcweir const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
1471cdf0e10cSrcweir while (pPattern)
1472cdf0e10cSrcweir {
1473cdf0e10cSrcweir if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
1474cdf0e10cSrcweir {
1475cdf0e10cSrcweir aRange.aStart.SetRow( nStart );
1476cdf0e10cSrcweir aRange.aEnd.SetRow( nEnd );
1477cdf0e10cSrcweir rDestMark.SetMultiMarkArea( aRange, sal_True );
1478cdf0e10cSrcweir }
1479cdf0e10cSrcweir
1480cdf0e10cSrcweir pPattern = aAttrIter.Next( nStart, nEnd );
1481cdf0e10cSrcweir }
1482cdf0e10cSrcweir }
1483cdf0e10cSrcweir
1484cdf0e10cSrcweir
SwapCol(ScColumn & rCol)1485cdf0e10cSrcweir void ScColumn::SwapCol(ScColumn& rCol)
1486cdf0e10cSrcweir {
1487cdf0e10cSrcweir SCSIZE nTemp;
1488cdf0e10cSrcweir
1489cdf0e10cSrcweir nTemp = rCol.nCount;
1490cdf0e10cSrcweir rCol.nCount = nCount;
1491cdf0e10cSrcweir nCount = nTemp;
1492cdf0e10cSrcweir
1493cdf0e10cSrcweir nTemp = rCol.nLimit;
1494cdf0e10cSrcweir rCol.nLimit = nLimit;
1495cdf0e10cSrcweir nLimit = nTemp;
1496cdf0e10cSrcweir
1497cdf0e10cSrcweir ColEntry* pTempItems = rCol.pItems;
1498cdf0e10cSrcweir rCol.pItems = pItems;
1499cdf0e10cSrcweir pItems = pTempItems;
1500cdf0e10cSrcweir
1501cdf0e10cSrcweir ScAttrArray* pTempAttr = rCol.pAttrArray;
1502cdf0e10cSrcweir rCol.pAttrArray = pAttrArray;
1503cdf0e10cSrcweir pAttrArray = pTempAttr;
1504cdf0e10cSrcweir
1505cdf0e10cSrcweir // #38415# AttrArray muss richtige Spaltennummer haben
1506cdf0e10cSrcweir pAttrArray->SetCol(nCol);
1507cdf0e10cSrcweir rCol.pAttrArray->SetCol(rCol.nCol);
1508cdf0e10cSrcweir
1509cdf0e10cSrcweir SCSIZE i;
1510cdf0e10cSrcweir if (pItems)
1511cdf0e10cSrcweir for (i = 0; i < nCount; i++)
1512cdf0e10cSrcweir {
1513cdf0e10cSrcweir ScFormulaCell* pCell = (ScFormulaCell*) pItems[i].pCell;
1514cdf0e10cSrcweir if( pCell->GetCellType() == CELLTYPE_FORMULA)
1515cdf0e10cSrcweir pCell->aPos.SetCol(nCol);
1516cdf0e10cSrcweir }
1517cdf0e10cSrcweir if (rCol.pItems)
1518cdf0e10cSrcweir for (i = 0; i < rCol.nCount; i++)
1519cdf0e10cSrcweir {
1520cdf0e10cSrcweir ScFormulaCell* pCell = (ScFormulaCell*) rCol.pItems[i].pCell;
1521cdf0e10cSrcweir if( pCell->GetCellType() == CELLTYPE_FORMULA)
1522cdf0e10cSrcweir pCell->aPos.SetCol(rCol.nCol);
1523cdf0e10cSrcweir }
1524cdf0e10cSrcweir }
1525cdf0e10cSrcweir
1526cdf0e10cSrcweir
MoveTo(SCROW nStartRow,SCROW nEndRow,ScColumn & rCol)1527cdf0e10cSrcweir void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
1528cdf0e10cSrcweir {
1529cdf0e10cSrcweir pAttrArray->MoveTo(nStartRow, nEndRow, *rCol.pAttrArray);
1530cdf0e10cSrcweir
1531cdf0e10cSrcweir if (pItems)
1532cdf0e10cSrcweir {
1533cdf0e10cSrcweir ::std::vector<SCROW> aRows;
1534cdf0e10cSrcweir bool bConsecutive = true;
1535cdf0e10cSrcweir SCSIZE i;
1536cdf0e10cSrcweir Search( nStartRow, i); // i points to start row or position thereafter
1537cdf0e10cSrcweir SCSIZE nStartPos = i;
1538cdf0e10cSrcweir for ( ; i < nCount && pItems[i].nRow <= nEndRow; ++i)
1539cdf0e10cSrcweir {
1540cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1541cdf0e10cSrcweir aRows.push_back( nRow);
1542cdf0e10cSrcweir rCol.Insert( nRow, pItems[i].pCell);
1543cdf0e10cSrcweir if (nRow != pItems[i].nRow)
1544cdf0e10cSrcweir { // Listener inserted
1545cdf0e10cSrcweir bConsecutive = false;
1546cdf0e10cSrcweir Search( nRow, i);
1547cdf0e10cSrcweir }
1548cdf0e10cSrcweir }
1549cdf0e10cSrcweir SCSIZE nStopPos = i;
1550cdf0e10cSrcweir if (nStartPos < nStopPos)
1551cdf0e10cSrcweir {
1552cdf0e10cSrcweir // Create list of ranges of cell entry positions
1553cdf0e10cSrcweir typedef ::std::pair<SCSIZE,SCSIZE> PosPair;
1554cdf0e10cSrcweir typedef ::std::vector<PosPair> EntryPosPairs;
1555cdf0e10cSrcweir EntryPosPairs aEntries;
1556cdf0e10cSrcweir if (bConsecutive)
1557cdf0e10cSrcweir aEntries.push_back( PosPair(nStartPos, nStopPos));
1558cdf0e10cSrcweir else
1559cdf0e10cSrcweir {
1560cdf0e10cSrcweir bool bFirst = true;
1561cdf0e10cSrcweir nStopPos = 0;
1562cdf0e10cSrcweir for (::std::vector<SCROW>::const_iterator it( aRows.begin());
1563cdf0e10cSrcweir it != aRows.end() && nStopPos < nCount; ++it,
1564cdf0e10cSrcweir ++nStopPos)
1565cdf0e10cSrcweir {
1566cdf0e10cSrcweir if (!bFirst && *it != pItems[nStopPos].nRow)
1567cdf0e10cSrcweir {
1568cdf0e10cSrcweir aEntries.push_back( PosPair(nStartPos, nStopPos));
1569cdf0e10cSrcweir bFirst = true;
1570cdf0e10cSrcweir }
1571cdf0e10cSrcweir if (bFirst && Search( *it, nStartPos))
1572cdf0e10cSrcweir {
1573cdf0e10cSrcweir bFirst = false;
1574cdf0e10cSrcweir nStopPos = nStartPos;
1575cdf0e10cSrcweir }
1576cdf0e10cSrcweir }
1577cdf0e10cSrcweir if (!bFirst && nStartPos < nStopPos)
1578cdf0e10cSrcweir aEntries.push_back( PosPair(nStartPos, nStopPos));
1579cdf0e10cSrcweir }
1580cdf0e10cSrcweir // Broadcast changes
1581cdf0e10cSrcweir ScAddress aAdr( nCol, 0, nTab );
1582cdf0e10cSrcweir ScHint aHint( SC_HINT_DYING, aAdr, NULL ); // areas only
1583cdf0e10cSrcweir ScAddress& rAddress = aHint.GetAddress();
1584cdf0e10cSrcweir ScNoteCell* pNoteCell = new ScNoteCell; // Dummy like in DeleteRange
1585cdf0e10cSrcweir
1586cdf0e10cSrcweir // #121990# must iterate backwards, because indexes of following cells become invalid
1587cdf0e10cSrcweir for (EntryPosPairs::reverse_iterator it( aEntries.rbegin());
1588cdf0e10cSrcweir it != aEntries.rend(); ++it)
1589cdf0e10cSrcweir {
1590cdf0e10cSrcweir nStartPos = (*it).first;
1591cdf0e10cSrcweir nStopPos = (*it).second;
1592cdf0e10cSrcweir for (i=nStartPos; i<nStopPos; ++i)
1593cdf0e10cSrcweir pItems[i].pCell = pNoteCell;
1594cdf0e10cSrcweir for (i=nStartPos; i<nStopPos; ++i)
1595cdf0e10cSrcweir {
1596cdf0e10cSrcweir rAddress.SetRow( pItems[i].nRow );
1597cdf0e10cSrcweir pDocument->AreaBroadcast( aHint );
1598cdf0e10cSrcweir }
1599cdf0e10cSrcweir nCount -= nStopPos - nStartPos;
1600cdf0e10cSrcweir memmove( &pItems[nStartPos], &pItems[nStopPos],
1601cdf0e10cSrcweir (nCount - nStartPos) * sizeof(ColEntry) );
1602cdf0e10cSrcweir }
1603cdf0e10cSrcweir delete pNoteCell;
1604cdf0e10cSrcweir pItems[nCount].nRow = 0;
1605cdf0e10cSrcweir pItems[nCount].pCell = NULL;
1606cdf0e10cSrcweir }
1607cdf0e10cSrcweir }
1608cdf0e10cSrcweir }
1609cdf0e10cSrcweir
1610cdf0e10cSrcweir
UpdateReference(UpdateRefMode eUpdateRefMode,SCCOL nCol1,SCROW nRow1,SCTAB nTab1,SCCOL nCol2,SCROW nRow2,SCTAB nTab2,SCsCOL nDx,SCsROW nDy,SCsTAB nDz,ScDocument * pUndoDoc)1611cdf0e10cSrcweir void ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1612cdf0e10cSrcweir SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
1613cdf0e10cSrcweir ScDocument* pUndoDoc )
1614cdf0e10cSrcweir {
1615cdf0e10cSrcweir if (pItems)
1616cdf0e10cSrcweir {
1617cdf0e10cSrcweir ScRange aRange( ScAddress( nCol1, nRow1, nTab1 ),
1618cdf0e10cSrcweir ScAddress( nCol2, nRow2, nTab2 ) );
1619cdf0e10cSrcweir if ( eUpdateRefMode == URM_COPY && nRow1 == nRow2 )
1620cdf0e10cSrcweir { // z.B. eine einzelne Zelle aus dem Clipboard eingefuegt
1621cdf0e10cSrcweir SCSIZE nIndex;
1622cdf0e10cSrcweir if ( Search( nRow1, nIndex ) )
1623cdf0e10cSrcweir {
1624cdf0e10cSrcweir ScFormulaCell* pCell = (ScFormulaCell*) pItems[nIndex].pCell;
1625cdf0e10cSrcweir if( pCell->GetCellType() == CELLTYPE_FORMULA)
1626cdf0e10cSrcweir pCell->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
1627cdf0e10cSrcweir }
1628cdf0e10cSrcweir }
1629cdf0e10cSrcweir else
1630cdf0e10cSrcweir {
1631cdf0e10cSrcweir // #90279# For performance reasons two loop bodies instead of
1632cdf0e10cSrcweir // testing for update mode in each iteration.
1633cdf0e10cSrcweir // Anyways, this is still a bottleneck on large arrays with few
1634cdf0e10cSrcweir // formulas cells.
1635cdf0e10cSrcweir if ( eUpdateRefMode == URM_COPY )
1636cdf0e10cSrcweir {
1637cdf0e10cSrcweir SCSIZE i;
1638cdf0e10cSrcweir Search( nRow1, i );
1639cdf0e10cSrcweir for ( ; i < nCount; i++ )
1640cdf0e10cSrcweir {
1641cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1642cdf0e10cSrcweir if ( nRow > nRow2 )
1643cdf0e10cSrcweir break;
1644cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1645cdf0e10cSrcweir if( pCell->GetCellType() == CELLTYPE_FORMULA)
1646cdf0e10cSrcweir {
1647cdf0e10cSrcweir ((ScFormulaCell*)pCell)->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
1648cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
1649cdf0e10cSrcweir Search( nRow, i ); // Listener removed/inserted?
1650cdf0e10cSrcweir }
1651cdf0e10cSrcweir }
1652cdf0e10cSrcweir }
1653cdf0e10cSrcweir else
1654cdf0e10cSrcweir {
1655cdf0e10cSrcweir SCSIZE i = 0;
1656cdf0e10cSrcweir for ( ; i < nCount; i++ )
1657cdf0e10cSrcweir {
1658cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1659cdf0e10cSrcweir if( pCell->GetCellType() == CELLTYPE_FORMULA)
1660cdf0e10cSrcweir {
1661cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1662cdf0e10cSrcweir // When deleting rows on several sheets, the formula's position may be updated with the first call,
1663cdf0e10cSrcweir // so the undo position must be passed from here.
1664cdf0e10cSrcweir ScAddress aUndoPos( nCol, nRow, nTab );
1665cdf0e10cSrcweir ((ScFormulaCell*)pCell)->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc, &aUndoPos );
1666cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
1667cdf0e10cSrcweir Search( nRow, i ); // Listener removed/inserted?
1668cdf0e10cSrcweir }
1669cdf0e10cSrcweir }
1670cdf0e10cSrcweir }
1671cdf0e10cSrcweir }
1672cdf0e10cSrcweir }
1673cdf0e10cSrcweir }
1674cdf0e10cSrcweir
1675cdf0e10cSrcweir
UpdateTranspose(const ScRange & rSource,const ScAddress & rDest,ScDocument * pUndoDoc)1676cdf0e10cSrcweir void ScColumn::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
1677cdf0e10cSrcweir ScDocument* pUndoDoc )
1678cdf0e10cSrcweir {
1679cdf0e10cSrcweir if (pItems)
1680cdf0e10cSrcweir for (SCSIZE i=0; i<nCount; i++)
1681cdf0e10cSrcweir {
1682cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1683cdf0e10cSrcweir if (pCell->GetCellType() == CELLTYPE_FORMULA)
1684cdf0e10cSrcweir {
1685cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1686cdf0e10cSrcweir ((ScFormulaCell*)pCell)->UpdateTranspose( rSource, rDest, pUndoDoc );
1687cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
1688cdf0e10cSrcweir Search( nRow, i ); // Listener geloescht/eingefuegt?
1689cdf0e10cSrcweir }
1690cdf0e10cSrcweir }
1691cdf0e10cSrcweir }
1692cdf0e10cSrcweir
1693cdf0e10cSrcweir
UpdateGrow(const ScRange & rArea,SCCOL nGrowX,SCROW nGrowY)1694cdf0e10cSrcweir void ScColumn::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
1695cdf0e10cSrcweir {
1696cdf0e10cSrcweir if (pItems)
1697cdf0e10cSrcweir for (SCSIZE i=0; i<nCount; i++)
1698cdf0e10cSrcweir {
1699cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1700cdf0e10cSrcweir if (pCell->GetCellType() == CELLTYPE_FORMULA)
1701cdf0e10cSrcweir {
1702cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1703cdf0e10cSrcweir ((ScFormulaCell*)pCell)->UpdateGrow( rArea, nGrowX, nGrowY );
1704cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
1705cdf0e10cSrcweir Search( nRow, i ); // Listener geloescht/eingefuegt?
1706cdf0e10cSrcweir }
1707cdf0e10cSrcweir }
1708cdf0e10cSrcweir }
1709cdf0e10cSrcweir
1710cdf0e10cSrcweir
UpdateInsertTab(SCTAB nTable)1711cdf0e10cSrcweir void ScColumn::UpdateInsertTab( SCTAB nTable)
1712cdf0e10cSrcweir {
1713cdf0e10cSrcweir if (nTab >= nTable)
1714cdf0e10cSrcweir pAttrArray->SetTab(++nTab);
1715cdf0e10cSrcweir if( pItems )
1716cdf0e10cSrcweir UpdateInsertTabOnlyCells( nTable );
1717cdf0e10cSrcweir }
1718cdf0e10cSrcweir
1719cdf0e10cSrcweir
UpdateInsertTabOnlyCells(SCTAB nTable)1720cdf0e10cSrcweir void ScColumn::UpdateInsertTabOnlyCells( SCTAB nTable)
1721cdf0e10cSrcweir {
1722cdf0e10cSrcweir if (pItems)
1723cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1724cdf0e10cSrcweir {
1725cdf0e10cSrcweir ScFormulaCell* pCell = (ScFormulaCell*) pItems[i].pCell;
1726cdf0e10cSrcweir if( pCell->GetCellType() == CELLTYPE_FORMULA)
1727cdf0e10cSrcweir {
1728cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1729cdf0e10cSrcweir pCell->UpdateInsertTab(nTable);
1730cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
1731cdf0e10cSrcweir Search( nRow, i ); // Listener geloescht/eingefuegt?
1732cdf0e10cSrcweir }
1733cdf0e10cSrcweir }
1734cdf0e10cSrcweir }
1735cdf0e10cSrcweir
1736cdf0e10cSrcweir
UpdateInsertTabAbs(SCTAB nTable)1737cdf0e10cSrcweir void ScColumn::UpdateInsertTabAbs(SCTAB nTable)
1738cdf0e10cSrcweir {
1739cdf0e10cSrcweir if (pItems)
1740cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1741cdf0e10cSrcweir {
1742cdf0e10cSrcweir ScFormulaCell* pCell = (ScFormulaCell*) pItems[i].pCell;
1743cdf0e10cSrcweir if( pCell->GetCellType() == CELLTYPE_FORMULA)
1744cdf0e10cSrcweir {
1745cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1746cdf0e10cSrcweir pCell->UpdateInsertTabAbs(nTable);
1747cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
1748cdf0e10cSrcweir Search( nRow, i ); // Listener geloescht/eingefuegt?
1749cdf0e10cSrcweir }
1750cdf0e10cSrcweir }
1751cdf0e10cSrcweir }
1752cdf0e10cSrcweir
1753cdf0e10cSrcweir
UpdateDeleteTab(SCTAB nTable,sal_Bool bIsMove,ScColumn * pRefUndo)1754cdf0e10cSrcweir void ScColumn::UpdateDeleteTab( SCTAB nTable, sal_Bool bIsMove, ScColumn* pRefUndo )
1755cdf0e10cSrcweir {
1756cdf0e10cSrcweir if (nTab > nTable)
1757cdf0e10cSrcweir pAttrArray->SetTab(--nTab);
1758cdf0e10cSrcweir
1759cdf0e10cSrcweir if (pItems)
1760cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1761cdf0e10cSrcweir if ( pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA )
1762cdf0e10cSrcweir {
1763cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1764cdf0e10cSrcweir ScFormulaCell* pOld = (ScFormulaCell*)pItems[i].pCell;
1765cdf0e10cSrcweir
1766cdf0e10cSrcweir /* Do not copy cell note to the undo document. Undo will copy
1767cdf0e10cSrcweir back the formula cell while keeping the original note. */
1768cdf0e10cSrcweir ScBaseCell* pSave = pRefUndo ? pOld->CloneWithoutNote( *pDocument ) : 0;
1769cdf0e10cSrcweir
1770cdf0e10cSrcweir sal_Bool bChanged = pOld->UpdateDeleteTab(nTable, bIsMove);
1771cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
1772cdf0e10cSrcweir Search( nRow, i ); // Listener geloescht/eingefuegt?
1773cdf0e10cSrcweir
1774cdf0e10cSrcweir if (pRefUndo)
1775cdf0e10cSrcweir {
1776cdf0e10cSrcweir if (bChanged)
1777cdf0e10cSrcweir pRefUndo->Insert( nRow, pSave );
1778cdf0e10cSrcweir else if(pSave)
1779cdf0e10cSrcweir pSave->Delete();
1780cdf0e10cSrcweir }
1781cdf0e10cSrcweir }
1782cdf0e10cSrcweir }
1783cdf0e10cSrcweir
1784cdf0e10cSrcweir
UpdateMoveTab(SCTAB nOldPos,SCTAB nNewPos,SCTAB nTabNo)1785cdf0e10cSrcweir void ScColumn::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo )
1786cdf0e10cSrcweir {
1787cdf0e10cSrcweir nTab = nTabNo;
1788cdf0e10cSrcweir pAttrArray->SetTab( nTabNo );
1789cdf0e10cSrcweir if (pItems)
1790cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1791cdf0e10cSrcweir {
1792cdf0e10cSrcweir ScFormulaCell* pCell = (ScFormulaCell*) pItems[i].pCell;
1793cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
1794cdf0e10cSrcweir {
1795cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1796cdf0e10cSrcweir pCell->UpdateMoveTab( nOldPos, nNewPos, nTabNo );
1797cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
1798cdf0e10cSrcweir Search( nRow, i ); // Listener geloescht/eingefuegt?
1799cdf0e10cSrcweir }
1800cdf0e10cSrcweir }
1801cdf0e10cSrcweir }
1802cdf0e10cSrcweir
1803cdf0e10cSrcweir
UpdateCompile(sal_Bool bForceIfNameInUse)1804cdf0e10cSrcweir void ScColumn::UpdateCompile( sal_Bool bForceIfNameInUse )
1805cdf0e10cSrcweir {
1806cdf0e10cSrcweir if (pItems)
1807cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1808cdf0e10cSrcweir {
1809cdf0e10cSrcweir ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
1810cdf0e10cSrcweir if( p->GetCellType() == CELLTYPE_FORMULA )
1811cdf0e10cSrcweir {
1812cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1813cdf0e10cSrcweir p->UpdateCompile( bForceIfNameInUse );
1814cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
1815cdf0e10cSrcweir Search( nRow, i ); // Listener geloescht/eingefuegt?
1816cdf0e10cSrcweir }
1817cdf0e10cSrcweir }
1818cdf0e10cSrcweir }
1819cdf0e10cSrcweir
1820cdf0e10cSrcweir
SetTabNo(SCTAB nNewTab)1821cdf0e10cSrcweir void ScColumn::SetTabNo(SCTAB nNewTab)
1822cdf0e10cSrcweir {
1823cdf0e10cSrcweir nTab = nNewTab;
1824cdf0e10cSrcweir pAttrArray->SetTab( nNewTab );
1825cdf0e10cSrcweir if (pItems)
1826cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1827cdf0e10cSrcweir {
1828cdf0e10cSrcweir ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
1829cdf0e10cSrcweir if( p->GetCellType() == CELLTYPE_FORMULA )
1830cdf0e10cSrcweir p->aPos.SetTab( nNewTab );
1831cdf0e10cSrcweir }
1832cdf0e10cSrcweir }
1833cdf0e10cSrcweir
1834cdf0e10cSrcweir
IsRangeNameInUse(SCROW nRow1,SCROW nRow2,sal_uInt16 nIndex) const1835cdf0e10cSrcweir sal_Bool ScColumn::IsRangeNameInUse(SCROW nRow1, SCROW nRow2, sal_uInt16 nIndex) const
1836cdf0e10cSrcweir {
1837cdf0e10cSrcweir sal_Bool bInUse = sal_False;
1838cdf0e10cSrcweir if (pItems)
1839cdf0e10cSrcweir for (SCSIZE i = 0; !bInUse && (i < nCount); i++)
1840cdf0e10cSrcweir if ((pItems[i].nRow >= nRow1) &&
1841cdf0e10cSrcweir (pItems[i].nRow <= nRow2) &&
1842cdf0e10cSrcweir (pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA))
1843cdf0e10cSrcweir bInUse = ((ScFormulaCell*)pItems[i].pCell)->IsRangeNameInUse(nIndex);
1844cdf0e10cSrcweir return bInUse;
1845cdf0e10cSrcweir }
1846cdf0e10cSrcweir
FindRangeNamesInUse(SCROW nRow1,SCROW nRow2,std::set<sal_uInt16> & rIndexes) const1847cdf0e10cSrcweir void ScColumn::FindRangeNamesInUse(SCROW nRow1, SCROW nRow2, std::set<sal_uInt16>& rIndexes) const
1848cdf0e10cSrcweir {
1849cdf0e10cSrcweir if (pItems)
1850cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1851cdf0e10cSrcweir if ((pItems[i].nRow >= nRow1) &&
1852cdf0e10cSrcweir (pItems[i].nRow <= nRow2) &&
1853cdf0e10cSrcweir (pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA))
1854cdf0e10cSrcweir ((ScFormulaCell*)pItems[i].pCell)->FindRangeNamesInUse(rIndexes);
1855cdf0e10cSrcweir }
1856cdf0e10cSrcweir
ReplaceRangeNamesInUse(SCROW nRow1,SCROW nRow2,const ScRangeData::IndexMap & rMap)1857cdf0e10cSrcweir void ScColumn::ReplaceRangeNamesInUse(SCROW nRow1, SCROW nRow2,
1858cdf0e10cSrcweir const ScRangeData::IndexMap& rMap )
1859cdf0e10cSrcweir {
1860cdf0e10cSrcweir if (pItems)
1861cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1862cdf0e10cSrcweir {
1863cdf0e10cSrcweir if ((pItems[i].nRow >= nRow1) &&
1864cdf0e10cSrcweir (pItems[i].nRow <= nRow2) &&
1865cdf0e10cSrcweir (pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA))
1866cdf0e10cSrcweir {
1867cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
1868cdf0e10cSrcweir ((ScFormulaCell*)pItems[i].pCell)->ReplaceRangeNamesInUse( rMap );
1869cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
1870cdf0e10cSrcweir Search( nRow, i ); // Listener geloescht/eingefuegt?
1871cdf0e10cSrcweir }
1872cdf0e10cSrcweir }
1873cdf0e10cSrcweir }
1874cdf0e10cSrcweir
SetDirtyVar()1875cdf0e10cSrcweir void ScColumn::SetDirtyVar()
1876cdf0e10cSrcweir {
1877cdf0e10cSrcweir for (SCSIZE i=0; i<nCount; i++)
1878cdf0e10cSrcweir {
1879cdf0e10cSrcweir ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
1880cdf0e10cSrcweir if( p->GetCellType() == CELLTYPE_FORMULA )
1881cdf0e10cSrcweir p->SetDirtyVar();
1882cdf0e10cSrcweir }
1883cdf0e10cSrcweir }
1884cdf0e10cSrcweir
1885cdf0e10cSrcweir
SetDirty()1886cdf0e10cSrcweir void ScColumn::SetDirty()
1887cdf0e10cSrcweir {
1888cdf0e10cSrcweir // wird nur dokumentweit verwendet, kein FormulaTrack
1889cdf0e10cSrcweir sal_Bool bOldAutoCalc = pDocument->GetAutoCalc();
1890cdf0e10cSrcweir pDocument->SetAutoCalc( sal_False ); // Mehrfachberechnungen vermeiden
1891cdf0e10cSrcweir for (SCSIZE i=0; i<nCount; i++)
1892cdf0e10cSrcweir {
1893cdf0e10cSrcweir ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
1894cdf0e10cSrcweir if( p->GetCellType() == CELLTYPE_FORMULA )
1895cdf0e10cSrcweir {
1896cdf0e10cSrcweir p->SetDirtyVar();
1897cdf0e10cSrcweir if ( !pDocument->IsInFormulaTree( p ) )
1898cdf0e10cSrcweir pDocument->PutInFormulaTree( p );
1899cdf0e10cSrcweir }
1900cdf0e10cSrcweir }
1901cdf0e10cSrcweir pDocument->SetAutoCalc( bOldAutoCalc );
1902cdf0e10cSrcweir }
1903cdf0e10cSrcweir
1904cdf0e10cSrcweir
SetDirty(const ScRange & rRange)1905cdf0e10cSrcweir void ScColumn::SetDirty( const ScRange& rRange )
1906cdf0e10cSrcweir { // broadcastet alles innerhalb eines Range, mit FormulaTrack
1907cdf0e10cSrcweir if ( !pItems || !nCount )
1908cdf0e10cSrcweir return ;
1909cdf0e10cSrcweir sal_Bool bOldAutoCalc = pDocument->GetAutoCalc();
1910cdf0e10cSrcweir pDocument->SetAutoCalc( sal_False ); // Mehrfachberechnungen vermeiden
1911cdf0e10cSrcweir SCROW nRow2 = rRange.aEnd.Row();
1912cdf0e10cSrcweir ScAddress aPos( nCol, 0, nTab );
1913cdf0e10cSrcweir ScHint aHint( SC_HINT_DATACHANGED, aPos, NULL );
1914cdf0e10cSrcweir SCROW nRow;
1915cdf0e10cSrcweir SCSIZE nIndex;
1916cdf0e10cSrcweir Search( rRange.aStart.Row(), nIndex );
1917cdf0e10cSrcweir while ( nIndex < nCount && (nRow = pItems[nIndex].nRow) <= nRow2 )
1918cdf0e10cSrcweir {
1919cdf0e10cSrcweir ScBaseCell* pCell = pItems[nIndex].pCell;
1920cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
1921cdf0e10cSrcweir ((ScFormulaCell*)pCell)->SetDirty();
1922cdf0e10cSrcweir else
1923cdf0e10cSrcweir {
1924cdf0e10cSrcweir aHint.GetAddress().SetRow( nRow );
1925cdf0e10cSrcweir aHint.SetCell( pCell );
1926cdf0e10cSrcweir pDocument->Broadcast( aHint );
1927cdf0e10cSrcweir }
1928cdf0e10cSrcweir nIndex++;
1929cdf0e10cSrcweir }
1930cdf0e10cSrcweir pDocument->SetAutoCalc( bOldAutoCalc );
1931cdf0e10cSrcweir }
1932cdf0e10cSrcweir
1933cdf0e10cSrcweir
SetTableOpDirty(const ScRange & rRange)1934cdf0e10cSrcweir void ScColumn::SetTableOpDirty( const ScRange& rRange )
1935cdf0e10cSrcweir {
1936cdf0e10cSrcweir if ( !pItems || !nCount )
1937cdf0e10cSrcweir return ;
1938cdf0e10cSrcweir sal_Bool bOldAutoCalc = pDocument->GetAutoCalc();
1939cdf0e10cSrcweir pDocument->SetAutoCalc( sal_False ); // no multiple recalculation
1940cdf0e10cSrcweir SCROW nRow2 = rRange.aEnd.Row();
1941cdf0e10cSrcweir ScAddress aPos( nCol, 0, nTab );
1942cdf0e10cSrcweir ScHint aHint( SC_HINT_TABLEOPDIRTY, aPos, NULL );
1943cdf0e10cSrcweir SCROW nRow;
1944cdf0e10cSrcweir SCSIZE nIndex;
1945cdf0e10cSrcweir Search( rRange.aStart.Row(), nIndex );
1946cdf0e10cSrcweir while ( nIndex < nCount && (nRow = pItems[nIndex].nRow) <= nRow2 )
1947cdf0e10cSrcweir {
1948cdf0e10cSrcweir ScBaseCell* pCell = pItems[nIndex].pCell;
1949cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
1950cdf0e10cSrcweir ((ScFormulaCell*)pCell)->SetTableOpDirty();
1951cdf0e10cSrcweir else
1952cdf0e10cSrcweir {
1953cdf0e10cSrcweir aHint.GetAddress().SetRow( nRow );
1954cdf0e10cSrcweir aHint.SetCell( pCell );
1955cdf0e10cSrcweir pDocument->Broadcast( aHint );
1956cdf0e10cSrcweir }
1957cdf0e10cSrcweir nIndex++;
1958cdf0e10cSrcweir }
1959cdf0e10cSrcweir pDocument->SetAutoCalc( bOldAutoCalc );
1960cdf0e10cSrcweir }
1961cdf0e10cSrcweir
1962cdf0e10cSrcweir
SetDirtyAfterLoad()1963cdf0e10cSrcweir void ScColumn::SetDirtyAfterLoad()
1964cdf0e10cSrcweir {
1965cdf0e10cSrcweir sal_Bool bOldAutoCalc = pDocument->GetAutoCalc();
1966cdf0e10cSrcweir pDocument->SetAutoCalc( sal_False ); // Mehrfachberechnungen vermeiden
1967cdf0e10cSrcweir for (SCSIZE i=0; i<nCount; i++)
1968cdf0e10cSrcweir {
1969cdf0e10cSrcweir ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
1970cdf0e10cSrcweir #if 1
1971cdf0e10cSrcweir // Simply set dirty and append to FormulaTree, without broadcasting,
1972cdf0e10cSrcweir // which is a magnitude faster. This is used to calculate the entire
1973cdf0e10cSrcweir // document, e.g. when loading alien file formats.
1974cdf0e10cSrcweir if ( p->GetCellType() == CELLTYPE_FORMULA )
1975cdf0e10cSrcweir p->SetDirtyAfterLoad();
1976cdf0e10cSrcweir #else
1977cdf0e10cSrcweir /* This was used with the binary file format that stored results, where only
1978cdf0e10cSrcweir * newly compiled and volatile functions and their dependents had to be
1979cdf0e10cSrcweir * recalculated, which was faster then. Since that was moved to 'binfilter' to
1980cdf0e10cSrcweir * convert to an XML file this isn't needed anymore, and not used for other
1981cdf0e10cSrcweir * file formats. Kept for reference in case mechanism needs to be reactivated
1982cdf0e10cSrcweir * for some file formats, we'd have to introduce a controlling parameter to
1983cdf0e10cSrcweir * this method here then.
1984cdf0e10cSrcweir */
1985cdf0e10cSrcweir
1986cdf0e10cSrcweir // If the cell was alsready dirty because of CalcAfterLoad,
1987cdf0e10cSrcweir // FormulaTracking has to take place.
1988cdf0e10cSrcweir if ( p->GetCellType() == CELLTYPE_FORMULA && p->GetDirty() )
1989cdf0e10cSrcweir p->SetDirty();
1990cdf0e10cSrcweir #endif
1991cdf0e10cSrcweir }
1992cdf0e10cSrcweir pDocument->SetAutoCalc( bOldAutoCalc );
1993cdf0e10cSrcweir }
1994cdf0e10cSrcweir
1995cdf0e10cSrcweir
SetRelNameDirty()1996cdf0e10cSrcweir void ScColumn::SetRelNameDirty()
1997cdf0e10cSrcweir {
1998cdf0e10cSrcweir sal_Bool bOldAutoCalc = pDocument->GetAutoCalc();
1999cdf0e10cSrcweir pDocument->SetAutoCalc( sal_False ); // Mehrfachberechnungen vermeiden
2000cdf0e10cSrcweir for (SCSIZE i=0; i<nCount; i++)
2001cdf0e10cSrcweir {
2002cdf0e10cSrcweir ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
2003cdf0e10cSrcweir if( p->GetCellType() == CELLTYPE_FORMULA && p->HasRelNameReference() )
2004cdf0e10cSrcweir p->SetDirty();
2005cdf0e10cSrcweir }
2006cdf0e10cSrcweir pDocument->SetAutoCalc( bOldAutoCalc );
2007cdf0e10cSrcweir }
2008cdf0e10cSrcweir
2009cdf0e10cSrcweir
CalcAll()2010cdf0e10cSrcweir void ScColumn::CalcAll()
2011cdf0e10cSrcweir {
2012cdf0e10cSrcweir if (pItems)
2013cdf0e10cSrcweir for (SCSIZE i=0; i<nCount; i++)
2014cdf0e10cSrcweir {
2015cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
2016cdf0e10cSrcweir if (pCell->GetCellType() == CELLTYPE_FORMULA)
2017cdf0e10cSrcweir {
2018cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2019cdf0e10cSrcweir // nach F9 ctrl-F9: ueberprueft die Berechnung per FormulaTree
2020cdf0e10cSrcweir ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
2021cdf0e10cSrcweir double nOldVal, nNewVal;
2022cdf0e10cSrcweir nOldVal = pFCell->GetValue();
2023cdf0e10cSrcweir #endif
2024cdf0e10cSrcweir ((ScFormulaCell*)pCell)->Interpret();
2025cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2026cdf0e10cSrcweir if ( pFCell->GetCode()->IsRecalcModeNormal() )
2027cdf0e10cSrcweir nNewVal = pFCell->GetValue();
2028cdf0e10cSrcweir else
2029cdf0e10cSrcweir nNewVal = nOldVal; // random(), jetzt() etc.
2030cdf0e10cSrcweir DBG_ASSERT( nOldVal==nNewVal, "CalcAll: nOldVal != nNewVal" );
2031cdf0e10cSrcweir #endif
2032cdf0e10cSrcweir }
2033cdf0e10cSrcweir }
2034cdf0e10cSrcweir }
2035cdf0e10cSrcweir
2036cdf0e10cSrcweir
CompileAll()2037cdf0e10cSrcweir void ScColumn::CompileAll()
2038cdf0e10cSrcweir {
2039cdf0e10cSrcweir if (pItems)
2040cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
2041cdf0e10cSrcweir {
2042cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
2043cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
2044cdf0e10cSrcweir {
2045cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
2046cdf0e10cSrcweir // fuer unbedingtes kompilieren
2047cdf0e10cSrcweir // bCompile=sal_True und pCode->nError=0
2048cdf0e10cSrcweir ((ScFormulaCell*)pCell)->GetCode()->SetCodeError( 0 );
2049cdf0e10cSrcweir ((ScFormulaCell*)pCell)->SetCompile( sal_True );
2050cdf0e10cSrcweir ((ScFormulaCell*)pCell)->CompileTokenArray();
2051cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
2052cdf0e10cSrcweir Search( nRow, i ); // Listener geloescht/eingefuegt?
2053cdf0e10cSrcweir }
2054cdf0e10cSrcweir }
2055cdf0e10cSrcweir }
2056cdf0e10cSrcweir
2057cdf0e10cSrcweir
CompileXML(ScProgress & rProgress)2058cdf0e10cSrcweir void ScColumn::CompileXML( ScProgress& rProgress )
2059cdf0e10cSrcweir {
2060cdf0e10cSrcweir if (pItems)
2061cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
2062cdf0e10cSrcweir {
2063cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
2064cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
2065cdf0e10cSrcweir {
2066cdf0e10cSrcweir SCROW nRow = pItems[i].nRow;
2067cdf0e10cSrcweir ((ScFormulaCell*)pCell)->CompileXML( rProgress );
2068cdf0e10cSrcweir if ( nRow != pItems[i].nRow )
2069cdf0e10cSrcweir Search( nRow, i ); // Listener geloescht/eingefuegt?
2070cdf0e10cSrcweir }
2071cdf0e10cSrcweir }
2072cdf0e10cSrcweir }
2073cdf0e10cSrcweir
2074cdf0e10cSrcweir
CalcAfterLoad()2075cdf0e10cSrcweir void ScColumn::CalcAfterLoad()
2076cdf0e10cSrcweir {
2077cdf0e10cSrcweir if (pItems)
2078cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
2079cdf0e10cSrcweir {
2080cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
2081cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
2082cdf0e10cSrcweir ((ScFormulaCell*)pCell)->CalcAfterLoad();
2083cdf0e10cSrcweir }
2084cdf0e10cSrcweir }
2085cdf0e10cSrcweir
2086cdf0e10cSrcweir
ResetChanged(SCROW nStartRow,SCROW nEndRow)2087cdf0e10cSrcweir void ScColumn::ResetChanged( SCROW nStartRow, SCROW nEndRow )
2088cdf0e10cSrcweir {
2089cdf0e10cSrcweir if (pItems)
2090cdf0e10cSrcweir {
2091cdf0e10cSrcweir SCSIZE nIndex;
2092cdf0e10cSrcweir Search(nStartRow,nIndex);
2093cdf0e10cSrcweir while (nIndex<nCount && pItems[nIndex].nRow <= nEndRow)
2094cdf0e10cSrcweir {
2095cdf0e10cSrcweir ScBaseCell* pCell = pItems[nIndex].pCell;
2096cdf0e10cSrcweir if (pCell->GetCellType() == CELLTYPE_FORMULA)
2097cdf0e10cSrcweir ((ScFormulaCell*)pCell)->ResetChanged();
2098cdf0e10cSrcweir ++nIndex;
2099cdf0e10cSrcweir }
2100cdf0e10cSrcweir }
2101cdf0e10cSrcweir }
2102cdf0e10cSrcweir
2103cdf0e10cSrcweir
HasEditCells(SCROW nStartRow,SCROW nEndRow,SCROW & rFirst) const2104cdf0e10cSrcweir sal_Bool ScColumn::HasEditCells(SCROW nStartRow, SCROW nEndRow, SCROW& rFirst) const
2105cdf0e10cSrcweir {
2106cdf0e10cSrcweir // used in GetOptimalHeight - ambiguous script type counts as edit cell
2107cdf0e10cSrcweir
2108cdf0e10cSrcweir SCROW nRow = 0;
2109cdf0e10cSrcweir SCSIZE nIndex;
2110cdf0e10cSrcweir Search(nStartRow,nIndex);
2111cdf0e10cSrcweir while ( (nIndex < nCount) ? ((nRow=pItems[nIndex].nRow) <= nEndRow) : sal_False )
2112cdf0e10cSrcweir {
2113cdf0e10cSrcweir ScBaseCell* pCell = pItems[nIndex].pCell;
2114cdf0e10cSrcweir CellType eCellType = pCell->GetCellType();
2115cdf0e10cSrcweir if ( eCellType == CELLTYPE_EDIT ||
2116cdf0e10cSrcweir IsAmbiguousScriptNonZero( pDocument->GetScriptType(nCol, nRow, nTab, pCell) ) ||
2117cdf0e10cSrcweir ((eCellType == CELLTYPE_FORMULA) && ((ScFormulaCell*)pCell)->IsMultilineResult()) )
2118cdf0e10cSrcweir {
2119cdf0e10cSrcweir rFirst = nRow;
2120cdf0e10cSrcweir return sal_True;
2121cdf0e10cSrcweir }
2122cdf0e10cSrcweir ++nIndex;
2123cdf0e10cSrcweir }
2124cdf0e10cSrcweir
2125cdf0e10cSrcweir return sal_False;
2126cdf0e10cSrcweir }
2127cdf0e10cSrcweir
2128cdf0e10cSrcweir
SearchStyle(SCsROW nRow,const ScStyleSheet * pSearchStyle,sal_Bool bUp,sal_Bool bInSelection,const ScMarkData & rMark)2129cdf0e10cSrcweir SCsROW ScColumn::SearchStyle( SCsROW nRow, const ScStyleSheet* pSearchStyle,
2130cdf0e10cSrcweir sal_Bool bUp, sal_Bool bInSelection, const ScMarkData& rMark )
2131cdf0e10cSrcweir {
2132cdf0e10cSrcweir if (bInSelection)
2133cdf0e10cSrcweir {
2134cdf0e10cSrcweir if (rMark.IsMultiMarked())
2135cdf0e10cSrcweir return pAttrArray->SearchStyle( nRow, pSearchStyle, bUp,
2136cdf0e10cSrcweir (ScMarkArray*) rMark.GetArray()+nCol ); //! const
2137cdf0e10cSrcweir else
2138cdf0e10cSrcweir return -1;
2139cdf0e10cSrcweir }
2140cdf0e10cSrcweir else
2141cdf0e10cSrcweir return pAttrArray->SearchStyle( nRow, pSearchStyle, bUp, NULL );
2142cdf0e10cSrcweir }
2143cdf0e10cSrcweir
2144cdf0e10cSrcweir
SearchStyleRange(SCsROW & rRow,SCsROW & rEndRow,const ScStyleSheet * pSearchStyle,sal_Bool bUp,sal_Bool bInSelection,const ScMarkData & rMark)2145cdf0e10cSrcweir sal_Bool ScColumn::SearchStyleRange( SCsROW& rRow, SCsROW& rEndRow, const ScStyleSheet* pSearchStyle,
2146cdf0e10cSrcweir sal_Bool bUp, sal_Bool bInSelection, const ScMarkData& rMark )
2147cdf0e10cSrcweir {
2148cdf0e10cSrcweir if (bInSelection)
2149cdf0e10cSrcweir {
2150cdf0e10cSrcweir if (rMark.IsMultiMarked())
2151cdf0e10cSrcweir return pAttrArray->SearchStyleRange( rRow, rEndRow, pSearchStyle, bUp,
2152cdf0e10cSrcweir (ScMarkArray*) rMark.GetArray()+nCol ); //! const
2153cdf0e10cSrcweir else
2154cdf0e10cSrcweir return sal_False;
2155cdf0e10cSrcweir }
2156cdf0e10cSrcweir else
2157cdf0e10cSrcweir return pAttrArray->SearchStyleRange( rRow, rEndRow, pSearchStyle, bUp, NULL );
2158cdf0e10cSrcweir }
2159cdf0e10cSrcweir
2160cdf0e10cSrcweir
2161