xref: /trunk/main/sc/source/core/data/column.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
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) const3223a02adb1SWang Lei const ScPatternAttr* ScColumn::GetPatternRange( SCROW& rStartRow, SCROW& rEndRow, SCROW nRow ) const
3233a02adb1SWang Lei {
3243a02adb1SWang Lei     return pAttrArray->GetPatternRange( rStartRow, rEndRow, nRow );
3253a02adb1SWang 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
72986e1cf34SPedro Giffuni             long nLoRow = pItems[nLo].nRow;     // no unsigned underflow upon subtraction
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 
1986*8fbda7e2SJohn Bampton         // If the cell was already 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 }
2159