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 "scitems.hxx"
32cdf0e10cSrcweir #include <editeng/eeitem.hxx>
33cdf0e10cSrcweir
34cdf0e10cSrcweir #include <svx/algitem.hxx>
35cdf0e10cSrcweir #include <editeng/editobj.hxx>
36cdf0e10cSrcweir #include <editeng/editstat.hxx>
37cdf0e10cSrcweir #include <editeng/emphitem.hxx>
38cdf0e10cSrcweir #include <editeng/fhgtitem.hxx>
39cdf0e10cSrcweir #include <editeng/forbiddencharacterstable.hxx>
40cdf0e10cSrcweir #include <svx/rotmodit.hxx>
41cdf0e10cSrcweir #include <editeng/scripttypeitem.hxx>
42cdf0e10cSrcweir #include <editeng/unolingu.hxx>
43cdf0e10cSrcweir #include <svl/zforlist.hxx>
44cdf0e10cSrcweir #include <svl/broadcast.hxx>
45cdf0e10cSrcweir #include <svl/listeneriter.hxx>
46cdf0e10cSrcweir #include <vcl/outdev.hxx>
47cdf0e10cSrcweir
48cdf0e10cSrcweir #include "column.hxx"
49cdf0e10cSrcweir #include "cell.hxx"
50cdf0e10cSrcweir #include "document.hxx"
51cdf0e10cSrcweir #include "docpool.hxx"
52cdf0e10cSrcweir #include "attarray.hxx"
53cdf0e10cSrcweir #include "patattr.hxx"
54cdf0e10cSrcweir #include "cellform.hxx"
55cdf0e10cSrcweir #include "collect.hxx"
56cdf0e10cSrcweir #include "stlsheet.hxx"
57cdf0e10cSrcweir #include "rechead.hxx"
58cdf0e10cSrcweir #include "brdcst.hxx"
59cdf0e10cSrcweir #include "editutil.hxx"
60cdf0e10cSrcweir #include "subtotal.hxx"
61cdf0e10cSrcweir #include "markdata.hxx"
62cdf0e10cSrcweir #include "compiler.hxx" // ScTokenArray GetCodeLen
63cdf0e10cSrcweir #include "dbcolect.hxx"
64cdf0e10cSrcweir #include "fillinfo.hxx"
65cdf0e10cSrcweir #include "segmenttree.hxx"
66cdf0e10cSrcweir
67cdf0e10cSrcweir #include <math.h>
68cdf0e10cSrcweir
69cdf0e10cSrcweir // -----------------------------------------------------------------------
70cdf0e10cSrcweir
71cdf0e10cSrcweir // factor from font size to optimal cell height (text width)
72cdf0e10cSrcweir #define SC_ROT_BREAK_FACTOR 6
73cdf0e10cSrcweir
74cdf0e10cSrcweir // -----------------------------------------------------------------------
75cdf0e10cSrcweir
IsAmbiguousScript(sal_uInt8 nScript)76cdf0e10cSrcweir inline sal_Bool IsAmbiguousScript( sal_uInt8 nScript )
77cdf0e10cSrcweir {
78cdf0e10cSrcweir //! move to a header file
79cdf0e10cSrcweir return ( nScript != SCRIPTTYPE_LATIN &&
80cdf0e10cSrcweir nScript != SCRIPTTYPE_ASIAN &&
81cdf0e10cSrcweir nScript != SCRIPTTYPE_COMPLEX );
82cdf0e10cSrcweir }
83cdf0e10cSrcweir
84cdf0e10cSrcweir // -----------------------------------------------------------------------------------------
85cdf0e10cSrcweir
86cdf0e10cSrcweir //
87cdf0e10cSrcweir // Datei-Operationen
88cdf0e10cSrcweir //
89cdf0e10cSrcweir
90cdf0e10cSrcweir // -----------------------------------------------------------------------------------------
91cdf0e10cSrcweir
92cdf0e10cSrcweir //UNUSED2008-05 SCROW ScColumn::NoteCount( SCROW nMaxRow ) const
93cdf0e10cSrcweir //UNUSED2008-05 {
94cdf0e10cSrcweir //UNUSED2008-05 SCROW nNoteCount = 0;
95cdf0e10cSrcweir //UNUSED2008-05 SCSIZE i;
96cdf0e10cSrcweir //UNUSED2008-05
97cdf0e10cSrcweir //UNUSED2008-05 for (i=0; i<nCount; i++)
98cdf0e10cSrcweir //UNUSED2008-05 if ( pItems[i].pCell->GetNotePtr() && pItems[i].nRow<=nMaxRow )
99cdf0e10cSrcweir //UNUSED2008-05 ++nNoteCount;
100cdf0e10cSrcweir //UNUSED2008-05
101cdf0e10cSrcweir //UNUSED2008-05 return nNoteCount;
102cdf0e10cSrcweir //UNUSED2008-05 }
103cdf0e10cSrcweir
104cdf0e10cSrcweir // -----------------------------------------------------------------------------------------
105cdf0e10cSrcweir
106cdf0e10cSrcweir //UNUSED2008-05 void ScColumn::CorrectSymbolCells( CharSet eStreamCharSet )
107cdf0e10cSrcweir //UNUSED2008-05 {
108cdf0e10cSrcweir //UNUSED2008-05 // #99139# find and correct string cells that are formatted with a symbol font,
109cdf0e10cSrcweir //UNUSED2008-05 // but are not in the LoadedSymbolStringCellsList
110cdf0e10cSrcweir //UNUSED2008-05 // (because CELLTYPE_SYMBOLS wasn't written in the file)
111cdf0e10cSrcweir //UNUSED2008-05
112cdf0e10cSrcweir //UNUSED2008-05 ScFontToSubsFontConverter_AutoPtr xFontConverter;
113cdf0e10cSrcweir //UNUSED2008-05 const sal_uLong nFontConverterFlags = FONTTOSUBSFONT_EXPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS;
114cdf0e10cSrcweir //UNUSED2008-05
115cdf0e10cSrcweir //UNUSED2008-05 sal_Bool bListInitialized = sal_False;
116cdf0e10cSrcweir //UNUSED2008-05 ScSymbolStringCellEntry* pCurrentEntry = NULL;
117cdf0e10cSrcweir //UNUSED2008-05
118cdf0e10cSrcweir //UNUSED2008-05 ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
119cdf0e10cSrcweir //UNUSED2008-05 SCROW nStt, nEnd;
120cdf0e10cSrcweir //UNUSED2008-05 const ScPatternAttr* pAttr = aAttrIter.Next( nStt, nEnd );
121cdf0e10cSrcweir //UNUSED2008-05 while ( pAttr )
122cdf0e10cSrcweir //UNUSED2008-05 {
123cdf0e10cSrcweir //UNUSED2008-05 if ( (xFontConverter = pAttr->GetSubsFontConverter( nFontConverterFlags )) ||
124cdf0e10cSrcweir //UNUSED2008-05 pAttr->IsSymbolFont() )
125cdf0e10cSrcweir //UNUSED2008-05 {
126cdf0e10cSrcweir //UNUSED2008-05 ScColumnIterator aCellIter( this, nStt, nEnd );
127cdf0e10cSrcweir //UNUSED2008-05 SCROW nRow;
128cdf0e10cSrcweir //UNUSED2008-05 ScBaseCell* pCell;
129cdf0e10cSrcweir //UNUSED2008-05 while ( aCellIter.Next( nRow, pCell ) )
130cdf0e10cSrcweir //UNUSED2008-05 {
131cdf0e10cSrcweir //UNUSED2008-05 if ( pCell->GetCellType() == CELLTYPE_STRING )
132cdf0e10cSrcweir //UNUSED2008-05 {
133cdf0e10cSrcweir //UNUSED2008-05 List& rList = pDocument->GetLoadedSymbolStringCellsList();
134cdf0e10cSrcweir //UNUSED2008-05 if (!bListInitialized)
135cdf0e10cSrcweir //UNUSED2008-05 {
136cdf0e10cSrcweir //UNUSED2008-05 pCurrentEntry = (ScSymbolStringCellEntry*)rList.First();
137cdf0e10cSrcweir //UNUSED2008-05 bListInitialized = sal_True;
138cdf0e10cSrcweir //UNUSED2008-05 }
139cdf0e10cSrcweir //UNUSED2008-05
140cdf0e10cSrcweir //UNUSED2008-05 while ( pCurrentEntry && pCurrentEntry->nRow < nRow )
141cdf0e10cSrcweir //UNUSED2008-05 pCurrentEntry = (ScSymbolStringCellEntry*)rList.Next();
142cdf0e10cSrcweir //UNUSED2008-05
143cdf0e10cSrcweir //UNUSED2008-05 if ( pCurrentEntry && pCurrentEntry->nRow == nRow )
144cdf0e10cSrcweir //UNUSED2008-05 {
145cdf0e10cSrcweir //UNUSED2008-05 // found
146cdf0e10cSrcweir //UNUSED2008-05 }
147cdf0e10cSrcweir //UNUSED2008-05 else
148cdf0e10cSrcweir //UNUSED2008-05 {
149cdf0e10cSrcweir //UNUSED2008-05 // not in list -> convert and put into list
150cdf0e10cSrcweir //UNUSED2008-05
151cdf0e10cSrcweir //UNUSED2008-05 ScStringCell* pStrCell = (ScStringCell*)pCell;
152cdf0e10cSrcweir //UNUSED2008-05 String aOldStr;
153cdf0e10cSrcweir //UNUSED2008-05 pStrCell->GetString( aOldStr );
154cdf0e10cSrcweir //UNUSED2008-05
155cdf0e10cSrcweir //UNUSED2008-05 // convert back to stream character set (get original data)
156cdf0e10cSrcweir //UNUSED2008-05 ByteString aByteStr( aOldStr, eStreamCharSet );
157cdf0e10cSrcweir //UNUSED2008-05
158cdf0e10cSrcweir //UNUSED2008-05 // convert using symbol encoding, as for CELLTYPE_SYMBOLS cells
159cdf0e10cSrcweir //UNUSED2008-05 String aNewStr( aByteStr, RTL_TEXTENCODING_SYMBOL );
160cdf0e10cSrcweir //UNUSED2008-05 pStrCell->SetString( aNewStr );
161cdf0e10cSrcweir //UNUSED2008-05
162cdf0e10cSrcweir //UNUSED2008-05 ScSymbolStringCellEntry * pEntry = new ScSymbolStringCellEntry;
163cdf0e10cSrcweir //UNUSED2008-05 pEntry->pCell = pStrCell;
164cdf0e10cSrcweir //UNUSED2008-05 pEntry->nRow = nRow;
165cdf0e10cSrcweir //UNUSED2008-05
166cdf0e10cSrcweir //UNUSED2008-05 if ( pCurrentEntry )
167cdf0e10cSrcweir //UNUSED2008-05 rList.Insert( pEntry ); // before current entry - pCurrentEntry stays valid
168cdf0e10cSrcweir //UNUSED2008-05 else
169cdf0e10cSrcweir //UNUSED2008-05 rList.Insert( pEntry, LIST_APPEND ); // append if already behind last entry
170cdf0e10cSrcweir //UNUSED2008-05 }
171cdf0e10cSrcweir //UNUSED2008-05 }
172cdf0e10cSrcweir //UNUSED2008-05 }
173cdf0e10cSrcweir //UNUSED2008-05 }
174cdf0e10cSrcweir //UNUSED2008-05
175cdf0e10cSrcweir //UNUSED2008-05 pAttr = aAttrIter.Next( nStt, nEnd );
176cdf0e10cSrcweir //UNUSED2008-05 }
177cdf0e10cSrcweir //UNUSED2008-05 }
178cdf0e10cSrcweir
179cdf0e10cSrcweir // -----------------------------------------------------------------------------------------
180cdf0e10cSrcweir
181cdf0e10cSrcweir // GetNeededSize: optimale Hoehe / Breite in Pixeln
182cdf0e10cSrcweir
GetNeededSize(SCROW nRow,OutputDevice * pDev,double nPPTX,double nPPTY,const Fraction & rZoomX,const Fraction & rZoomY,sal_Bool bWidth,const ScNeededSizeOptions & rOptions)183cdf0e10cSrcweir long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev,
184cdf0e10cSrcweir double nPPTX, double nPPTY,
185cdf0e10cSrcweir const Fraction& rZoomX, const Fraction& rZoomY,
186cdf0e10cSrcweir sal_Bool bWidth, const ScNeededSizeOptions& rOptions )
187cdf0e10cSrcweir {
188cdf0e10cSrcweir long nValue=0;
189cdf0e10cSrcweir SCSIZE nIndex;
190cdf0e10cSrcweir double nPPT = bWidth ? nPPTX : nPPTY;
191cdf0e10cSrcweir if (Search(nRow,nIndex))
192cdf0e10cSrcweir {
193cdf0e10cSrcweir ScBaseCell* pCell = pItems[nIndex].pCell;
194cdf0e10cSrcweir const ScPatternAttr* pPattern = rOptions.pPattern;
195cdf0e10cSrcweir if (!pPattern)
196cdf0e10cSrcweir pPattern = pAttrArray->GetPattern( nRow );
197cdf0e10cSrcweir
198cdf0e10cSrcweir // zusammengefasst?
199cdf0e10cSrcweir // Merge nicht in bedingter Formatierung
200cdf0e10cSrcweir
201cdf0e10cSrcweir const ScMergeAttr* pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
202cdf0e10cSrcweir const ScMergeFlagAttr* pFlag = (const ScMergeFlagAttr*)&pPattern->GetItem(ATTR_MERGE_FLAG);
203cdf0e10cSrcweir
204cdf0e10cSrcweir if ( bWidth )
205cdf0e10cSrcweir {
206cdf0e10cSrcweir if ( pFlag->IsHorOverlapped() )
207cdf0e10cSrcweir return 0;
208cdf0e10cSrcweir if ( rOptions.bSkipMerged && pMerge->GetColMerge() > 1 )
209cdf0e10cSrcweir return 0;
210cdf0e10cSrcweir }
211cdf0e10cSrcweir else
212cdf0e10cSrcweir {
213cdf0e10cSrcweir if ( pFlag->IsVerOverlapped() )
214cdf0e10cSrcweir return 0;
215cdf0e10cSrcweir if ( rOptions.bSkipMerged && pMerge->GetRowMerge() > 1 )
216cdf0e10cSrcweir return 0;
217cdf0e10cSrcweir }
218cdf0e10cSrcweir
219cdf0e10cSrcweir // bedingte Formatierung
220cdf0e10cSrcweir const SfxItemSet* pCondSet = NULL;
221cdf0e10cSrcweir if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() )
222cdf0e10cSrcweir pCondSet = pDocument->GetCondResult( nCol, nRow, nTab );
223cdf0e10cSrcweir
224cdf0e10cSrcweir // Zeilenumbruch?
225cdf0e10cSrcweir
226cdf0e10cSrcweir const SfxPoolItem* pCondItem;
227cdf0e10cSrcweir SvxCellHorJustify eHorJust;
228cdf0e10cSrcweir if (pCondSet &&
229cdf0e10cSrcweir pCondSet->GetItemState(ATTR_HOR_JUSTIFY, sal_True, &pCondItem) == SFX_ITEM_SET)
230cdf0e10cSrcweir eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem*)pCondItem)->GetValue();
231cdf0e10cSrcweir else
232cdf0e10cSrcweir eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
233cdf0e10cSrcweir pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
234cdf0e10cSrcweir bool bBreak;
235cdf0e10cSrcweir if ( eHorJust == SVX_HOR_JUSTIFY_BLOCK )
236cdf0e10cSrcweir bBreak = true;
237cdf0e10cSrcweir else if ( pCondSet &&
238cdf0e10cSrcweir pCondSet->GetItemState(ATTR_LINEBREAK, sal_True, &pCondItem) == SFX_ITEM_SET)
239cdf0e10cSrcweir bBreak = ((const SfxBoolItem*)pCondItem)->GetValue();
240cdf0e10cSrcweir else
241cdf0e10cSrcweir bBreak = ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue();
242cdf0e10cSrcweir
243cdf0e10cSrcweir SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
244cdf0e10cSrcweir sal_uLong nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet );
245cdf0e10cSrcweir // #i111387# #o11817313# disable automatic line breaks only for "General" number format
246cdf0e10cSrcweir if ( bBreak && pCell->HasValueData() && ( nFormat % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 )
247cdf0e10cSrcweir {
248cdf0e10cSrcweir // also take formula result type into account for number format
249cdf0e10cSrcweir if ( pCell->GetCellType() != CELLTYPE_FORMULA ||
250cdf0e10cSrcweir ( static_cast<ScFormulaCell*>(pCell)->GetStandardFormat(*pFormatter, nFormat) % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 )
251cdf0e10cSrcweir bBreak = false;
252cdf0e10cSrcweir }
253cdf0e10cSrcweir
254cdf0e10cSrcweir // get other attributes from pattern and conditional formatting
255cdf0e10cSrcweir
256cdf0e10cSrcweir SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
257cdf0e10cSrcweir sal_Bool bAsianVertical = ( eOrient == SVX_ORIENTATION_STACKED &&
258cdf0e10cSrcweir ((const SfxBoolItem&)pPattern->GetItem( ATTR_VERTICAL_ASIAN, pCondSet )).GetValue() );
259cdf0e10cSrcweir if ( bAsianVertical )
260cdf0e10cSrcweir bBreak = false;
261cdf0e10cSrcweir
262cdf0e10cSrcweir if ( bWidth && bBreak ) // after determining bAsianVertical (bBreak may be reset)
263cdf0e10cSrcweir return 0;
264cdf0e10cSrcweir
265cdf0e10cSrcweir long nRotate = 0;
266cdf0e10cSrcweir SvxRotateMode eRotMode = SVX_ROTATE_MODE_STANDARD;
267cdf0e10cSrcweir if ( eOrient == SVX_ORIENTATION_STANDARD )
268cdf0e10cSrcweir {
269cdf0e10cSrcweir if (pCondSet &&
270cdf0e10cSrcweir pCondSet->GetItemState(ATTR_ROTATE_VALUE, sal_True, &pCondItem) == SFX_ITEM_SET)
271cdf0e10cSrcweir nRotate = ((const SfxInt32Item*)pCondItem)->GetValue();
272cdf0e10cSrcweir else
273cdf0e10cSrcweir nRotate = ((const SfxInt32Item&)pPattern->GetItem(ATTR_ROTATE_VALUE)).GetValue();
274cdf0e10cSrcweir if ( nRotate )
275cdf0e10cSrcweir {
276cdf0e10cSrcweir if (pCondSet &&
277cdf0e10cSrcweir pCondSet->GetItemState(ATTR_ROTATE_MODE, sal_True, &pCondItem) == SFX_ITEM_SET)
278cdf0e10cSrcweir eRotMode = (SvxRotateMode)((const SvxRotateModeItem*)pCondItem)->GetValue();
279cdf0e10cSrcweir else
280cdf0e10cSrcweir eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
281cdf0e10cSrcweir pPattern->GetItem(ATTR_ROTATE_MODE)).GetValue();
282cdf0e10cSrcweir
283cdf0e10cSrcweir if ( nRotate == 18000 )
284cdf0e10cSrcweir eRotMode = SVX_ROTATE_MODE_STANDARD; // keinen Ueberlauf
285cdf0e10cSrcweir }
286cdf0e10cSrcweir }
287cdf0e10cSrcweir
288cdf0e10cSrcweir if ( eHorJust == SVX_HOR_JUSTIFY_REPEAT )
289cdf0e10cSrcweir {
290cdf0e10cSrcweir // ignore orientation/rotation if "repeat" is active
291cdf0e10cSrcweir eOrient = SVX_ORIENTATION_STANDARD;
292cdf0e10cSrcweir nRotate = 0;
293cdf0e10cSrcweir bAsianVertical = sal_False;
294cdf0e10cSrcweir }
295cdf0e10cSrcweir
296cdf0e10cSrcweir const SvxMarginItem* pMargin;
297cdf0e10cSrcweir if (pCondSet &&
298cdf0e10cSrcweir pCondSet->GetItemState(ATTR_MARGIN, sal_True, &pCondItem) == SFX_ITEM_SET)
299cdf0e10cSrcweir pMargin = (const SvxMarginItem*) pCondItem;
300cdf0e10cSrcweir else
301cdf0e10cSrcweir pMargin = (const SvxMarginItem*) &pPattern->GetItem(ATTR_MARGIN);
302cdf0e10cSrcweir sal_uInt16 nIndent = 0;
303cdf0e10cSrcweir if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
304cdf0e10cSrcweir {
305cdf0e10cSrcweir if (pCondSet &&
306cdf0e10cSrcweir pCondSet->GetItemState(ATTR_INDENT, sal_True, &pCondItem) == SFX_ITEM_SET)
307cdf0e10cSrcweir nIndent = ((const SfxUInt16Item*)pCondItem)->GetValue();
308cdf0e10cSrcweir else
309cdf0e10cSrcweir nIndent = ((const SfxUInt16Item&)pPattern->GetItem(ATTR_INDENT)).GetValue();
310cdf0e10cSrcweir }
311cdf0e10cSrcweir
312cdf0e10cSrcweir sal_uInt8 nScript = pDocument->GetScriptType( nCol, nRow, nTab, pCell );
313cdf0e10cSrcweir if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
314cdf0e10cSrcweir
315cdf0e10cSrcweir // also call SetFont for edit cells, because bGetFont may be set only once
316cdf0e10cSrcweir // bGetFont is set also if script type changes
317cdf0e10cSrcweir if (rOptions.bGetFont)
318cdf0e10cSrcweir {
319cdf0e10cSrcweir Fraction aFontZoom = ( eOrient == SVX_ORIENTATION_STANDARD ) ? rZoomX : rZoomY;
320cdf0e10cSrcweir Font aFont;
321cdf0e10cSrcweir // font color doesn't matter here
322cdf0e10cSrcweir pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &aFontZoom, pCondSet, nScript );
323cdf0e10cSrcweir pDev->SetFont(aFont);
324cdf0e10cSrcweir }
325cdf0e10cSrcweir
326cdf0e10cSrcweir sal_Bool bAddMargin = sal_True;
327cdf0e10cSrcweir CellType eCellType = pCell->GetCellType();
328cdf0e10cSrcweir
329cdf0e10cSrcweir sal_Bool bEditEngine = ( eCellType == CELLTYPE_EDIT ||
330cdf0e10cSrcweir eOrient == SVX_ORIENTATION_STACKED ||
331cdf0e10cSrcweir IsAmbiguousScript( nScript ) ||
332cdf0e10cSrcweir ((eCellType == CELLTYPE_FORMULA) && ((ScFormulaCell*)pCell)->IsMultilineResult()) );
333cdf0e10cSrcweir
334cdf0e10cSrcweir if (!bEditEngine) // direkte Ausgabe
335cdf0e10cSrcweir {
336cdf0e10cSrcweir String aValStr;
337cdf0e10cSrcweir Color* pColor;
338cdf0e10cSrcweir ScCellFormat::GetString( pCell, nFormat, aValStr, &pColor,
339cdf0e10cSrcweir *pFormatter,
340cdf0e10cSrcweir sal_True, rOptions.bFormula, ftCheck );
341cdf0e10cSrcweir if (aValStr.Len())
342cdf0e10cSrcweir {
343cdf0e10cSrcweir // SetFont ist nach oben verschoben
344cdf0e10cSrcweir
345cdf0e10cSrcweir Size aSize( pDev->GetTextWidth( aValStr ), pDev->GetTextHeight() );
346cdf0e10cSrcweir if ( eOrient != SVX_ORIENTATION_STANDARD )
347cdf0e10cSrcweir {
348cdf0e10cSrcweir long nTemp = aSize.Width();
349cdf0e10cSrcweir aSize.Width() = aSize.Height();
350cdf0e10cSrcweir aSize.Height() = nTemp;
351cdf0e10cSrcweir }
352cdf0e10cSrcweir else if ( nRotate )
353cdf0e10cSrcweir {
354cdf0e10cSrcweir //! unterschiedliche Skalierung X/Y beruecksichtigen
355cdf0e10cSrcweir
356cdf0e10cSrcweir double nRealOrient = nRotate * F_PI18000; // nRotate sind 1/100 Grad
357cdf0e10cSrcweir double nCosAbs = fabs( cos( nRealOrient ) );
358cdf0e10cSrcweir double nSinAbs = fabs( sin( nRealOrient ) );
359cdf0e10cSrcweir long nHeight = (long)( aSize.Height() * nCosAbs + aSize.Width() * nSinAbs );
360cdf0e10cSrcweir long nWidth;
361cdf0e10cSrcweir if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
362cdf0e10cSrcweir nWidth = (long)( aSize.Width() * nCosAbs + aSize.Height() * nSinAbs );
363cdf0e10cSrcweir else if ( rOptions.bTotalSize )
364cdf0e10cSrcweir {
365cdf0e10cSrcweir nWidth = (long) ( pDocument->GetColWidth( nCol,nTab ) * nPPT );
366cdf0e10cSrcweir bAddMargin = sal_False;
367cdf0e10cSrcweir // nur nach rechts:
368cdf0e10cSrcweir //! unterscheiden nach Ausrichtung oben/unten (nur Text/ganze Hoehe)
369cdf0e10cSrcweir if ( pPattern->GetRotateDir( pCondSet ) == SC_ROTDIR_RIGHT )
370cdf0e10cSrcweir nWidth += (long)( pDocument->GetRowHeight( nRow,nTab ) *
371cdf0e10cSrcweir nPPT * nCosAbs / nSinAbs );
372cdf0e10cSrcweir }
373cdf0e10cSrcweir else
374cdf0e10cSrcweir nWidth = (long)( aSize.Height() / nSinAbs ); //! begrenzen?
375cdf0e10cSrcweir
376cdf0e10cSrcweir if ( bBreak && !rOptions.bTotalSize )
377cdf0e10cSrcweir {
378cdf0e10cSrcweir // #47744# limit size for line break
379cdf0e10cSrcweir long nCmp = pDev->GetFont().GetSize().Height() * SC_ROT_BREAK_FACTOR;
380cdf0e10cSrcweir if ( nHeight > nCmp )
381cdf0e10cSrcweir nHeight = nCmp;
382cdf0e10cSrcweir }
383cdf0e10cSrcweir
384cdf0e10cSrcweir aSize = Size( nWidth, nHeight );
385cdf0e10cSrcweir }
386cdf0e10cSrcweir nValue = bWidth ? aSize.Width() : aSize.Height();
387cdf0e10cSrcweir
388cdf0e10cSrcweir if ( bAddMargin )
389cdf0e10cSrcweir {
390cdf0e10cSrcweir if (bWidth)
391cdf0e10cSrcweir {
392cdf0e10cSrcweir nValue += (long) ( pMargin->GetLeftMargin() * nPPT ) +
393cdf0e10cSrcweir (long) ( pMargin->GetRightMargin() * nPPT );
394cdf0e10cSrcweir if ( nIndent )
395cdf0e10cSrcweir nValue += (long) ( nIndent * nPPT );
396cdf0e10cSrcweir }
397cdf0e10cSrcweir else
398cdf0e10cSrcweir nValue += (long) ( pMargin->GetTopMargin() * nPPT ) +
399cdf0e10cSrcweir (long) ( pMargin->GetBottomMargin() * nPPT );
400cdf0e10cSrcweir }
401cdf0e10cSrcweir
402cdf0e10cSrcweir // Zeilenumbruch ausgefuehrt ?
403cdf0e10cSrcweir
404cdf0e10cSrcweir if ( bBreak && !bWidth )
405cdf0e10cSrcweir {
406cdf0e10cSrcweir // Test mit EditEngine zur Sicherheit schon bei 90%
407cdf0e10cSrcweir // (wegen Rundungsfehlern und weil EditEngine teilweise anders formatiert)
408cdf0e10cSrcweir
409cdf0e10cSrcweir long nDocPixel = (long) ( ( pDocument->GetColWidth( nCol,nTab ) -
410cdf0e10cSrcweir pMargin->GetLeftMargin() - pMargin->GetRightMargin() -
411cdf0e10cSrcweir nIndent )
412cdf0e10cSrcweir * nPPT );
413cdf0e10cSrcweir nDocPixel = (nDocPixel * 9) / 10; // zur Sicherheit
414cdf0e10cSrcweir if ( aSize.Width() > nDocPixel )
415cdf0e10cSrcweir bEditEngine = sal_True;
416cdf0e10cSrcweir }
417cdf0e10cSrcweir }
418cdf0e10cSrcweir }
419cdf0e10cSrcweir
420cdf0e10cSrcweir if (bEditEngine)
421cdf0e10cSrcweir {
422cdf0e10cSrcweir // der Font wird bei !bEditEngine nicht jedesmal neu gesetzt
423cdf0e10cSrcweir Font aOldFont = pDev->GetFont();
424cdf0e10cSrcweir
425cdf0e10cSrcweir MapMode aHMMMode( MAP_100TH_MM, Point(), rZoomX, rZoomY );
426cdf0e10cSrcweir
427cdf0e10cSrcweir // am Dokument speichern ?
428cdf0e10cSrcweir ScFieldEditEngine* pEngine = pDocument->CreateFieldEditEngine();
429cdf0e10cSrcweir
430cdf0e10cSrcweir pEngine->SetUpdateMode( sal_False );
431cdf0e10cSrcweir sal_Bool bTextWysiwyg = ( pDev->GetOutDevType() == OUTDEV_PRINTER );
432cdf0e10cSrcweir sal_uInt32 nCtrl = pEngine->GetControlWord();
433cdf0e10cSrcweir if ( bTextWysiwyg )
434cdf0e10cSrcweir nCtrl |= EE_CNTRL_FORMAT100;
435cdf0e10cSrcweir else
436cdf0e10cSrcweir nCtrl &= ~EE_CNTRL_FORMAT100;
437cdf0e10cSrcweir pEngine->SetControlWord( nCtrl );
438cdf0e10cSrcweir MapMode aOld = pDev->GetMapMode();
439cdf0e10cSrcweir pDev->SetMapMode( aHMMMode );
440cdf0e10cSrcweir pEngine->SetRefDevice( pDev );
441cdf0e10cSrcweir pDocument->ApplyAsianEditSettings( *pEngine );
442cdf0e10cSrcweir SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
443cdf0e10cSrcweir pPattern->FillEditItemSet( pSet, pCondSet );
444cdf0e10cSrcweir
445cdf0e10cSrcweir // no longer needed, are setted with the text (is faster)
446cdf0e10cSrcweir // pEngine->SetDefaults( pSet );
447cdf0e10cSrcweir
448cdf0e10cSrcweir if ( ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() ) {
449cdf0e10cSrcweir
450cdf0e10cSrcweir com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
451cdf0e10cSrcweir pEngine->SetHyphenator( xXHyphenator );
452cdf0e10cSrcweir }
453cdf0e10cSrcweir
454cdf0e10cSrcweir Size aPaper = Size( 1000000, 1000000 );
455cdf0e10cSrcweir if ( eOrient==SVX_ORIENTATION_STACKED && !bAsianVertical )
456cdf0e10cSrcweir aPaper.Width() = 1;
457cdf0e10cSrcweir else if (bBreak)
458cdf0e10cSrcweir {
459cdf0e10cSrcweir double fWidthFactor = nPPTX;
460cdf0e10cSrcweir if ( bTextWysiwyg )
461cdf0e10cSrcweir {
462cdf0e10cSrcweir // #95593# if text is formatted for printer, don't use PixelToLogic,
463cdf0e10cSrcweir // to ensure the exact same paper width (and same line breaks) as in
464cdf0e10cSrcweir // ScEditUtil::GetEditArea, used for output.
465cdf0e10cSrcweir
466cdf0e10cSrcweir fWidthFactor = HMM_PER_TWIPS;
467cdf0e10cSrcweir }
468cdf0e10cSrcweir
469cdf0e10cSrcweir // use original width for hidden columns:
470cdf0e10cSrcweir long nDocWidth = (long) ( pDocument->GetOriginalWidth(nCol,nTab) * fWidthFactor );
471cdf0e10cSrcweir SCCOL nColMerge = pMerge->GetColMerge();
472cdf0e10cSrcweir if (nColMerge > 1)
473cdf0e10cSrcweir for (SCCOL nColAdd=1; nColAdd<nColMerge; nColAdd++)
474cdf0e10cSrcweir nDocWidth += (long) ( pDocument->GetColWidth(nCol+nColAdd,nTab) * fWidthFactor );
475cdf0e10cSrcweir nDocWidth -= (long) ( pMargin->GetLeftMargin() * fWidthFactor )
476cdf0e10cSrcweir + (long) ( pMargin->GetRightMargin() * fWidthFactor )
477cdf0e10cSrcweir + 1; // Ausgabebereich ist Breite-1 Pixel (wegen Gitterlinien)
478cdf0e10cSrcweir if ( nIndent )
479cdf0e10cSrcweir nDocWidth -= (long) ( nIndent * fWidthFactor );
480cdf0e10cSrcweir
481cdf0e10cSrcweir // space for AutoFilter button: 20 * nZoom/100
482cdf0e10cSrcweir if ( pFlag->HasAutoFilter() && !bTextWysiwyg )
483cdf0e10cSrcweir nDocWidth -= (rZoomX.GetNumerator()*20)/rZoomX.GetDenominator();
484cdf0e10cSrcweir
485cdf0e10cSrcweir aPaper.Width() = nDocWidth;
486cdf0e10cSrcweir
487cdf0e10cSrcweir if ( !bTextWysiwyg )
488cdf0e10cSrcweir aPaper = pDev->PixelToLogic( aPaper, aHMMMode );
489cdf0e10cSrcweir }
490cdf0e10cSrcweir pEngine->SetPaperSize(aPaper);
491cdf0e10cSrcweir
492cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_EDIT )
493cdf0e10cSrcweir {
494cdf0e10cSrcweir const EditTextObject* pData;
495cdf0e10cSrcweir ((ScEditCell*)pCell)->GetData(pData);
496cdf0e10cSrcweir pEngine->SetTextNewDefaults(*pData, pSet);
497cdf0e10cSrcweir }
498cdf0e10cSrcweir else
499cdf0e10cSrcweir {
500cdf0e10cSrcweir Color* pColor;
501cdf0e10cSrcweir String aString;
502cdf0e10cSrcweir ScCellFormat::GetString( pCell, nFormat, aString, &pColor,
503cdf0e10cSrcweir *pFormatter,
504cdf0e10cSrcweir sal_True, rOptions.bFormula, ftCheck );
505cdf0e10cSrcweir if (aString.Len())
506cdf0e10cSrcweir pEngine->SetTextNewDefaults(aString, pSet);
507cdf0e10cSrcweir else
508cdf0e10cSrcweir pEngine->SetDefaults(pSet);
509cdf0e10cSrcweir }
510cdf0e10cSrcweir
511cdf0e10cSrcweir sal_Bool bEngineVertical = pEngine->IsVertical();
512cdf0e10cSrcweir pEngine->SetVertical( bAsianVertical );
513cdf0e10cSrcweir pEngine->SetUpdateMode( sal_True );
514cdf0e10cSrcweir
515cdf0e10cSrcweir sal_Bool bEdWidth = bWidth;
516cdf0e10cSrcweir if ( eOrient != SVX_ORIENTATION_STANDARD && eOrient != SVX_ORIENTATION_STACKED )
517cdf0e10cSrcweir bEdWidth = !bEdWidth;
518cdf0e10cSrcweir if ( nRotate )
519cdf0e10cSrcweir {
520cdf0e10cSrcweir //! unterschiedliche Skalierung X/Y beruecksichtigen
521cdf0e10cSrcweir
522cdf0e10cSrcweir Size aSize( pEngine->CalcTextWidth(), pEngine->GetTextHeight() );
523cdf0e10cSrcweir double nRealOrient = nRotate * F_PI18000; // nRotate sind 1/100 Grad
524cdf0e10cSrcweir double nCosAbs = fabs( cos( nRealOrient ) );
525cdf0e10cSrcweir double nSinAbs = fabs( sin( nRealOrient ) );
526cdf0e10cSrcweir long nHeight = (long)( aSize.Height() * nCosAbs + aSize.Width() * nSinAbs );
527cdf0e10cSrcweir long nWidth;
528cdf0e10cSrcweir if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
529cdf0e10cSrcweir nWidth = (long)( aSize.Width() * nCosAbs + aSize.Height() * nSinAbs );
530cdf0e10cSrcweir else if ( rOptions.bTotalSize )
531cdf0e10cSrcweir {
532cdf0e10cSrcweir nWidth = (long) ( pDocument->GetColWidth( nCol,nTab ) * nPPT );
533cdf0e10cSrcweir bAddMargin = sal_False;
534cdf0e10cSrcweir if ( pPattern->GetRotateDir( pCondSet ) == SC_ROTDIR_RIGHT )
535cdf0e10cSrcweir nWidth += (long)( pDocument->GetRowHeight( nRow,nTab ) *
536cdf0e10cSrcweir nPPT * nCosAbs / nSinAbs );
537cdf0e10cSrcweir }
538cdf0e10cSrcweir else
539cdf0e10cSrcweir nWidth = (long)( aSize.Height() / nSinAbs ); //! begrenzen?
540cdf0e10cSrcweir aSize = Size( nWidth, nHeight );
541cdf0e10cSrcweir
542cdf0e10cSrcweir Size aPixSize = pDev->LogicToPixel( aSize, aHMMMode );
543cdf0e10cSrcweir if ( bEdWidth )
544cdf0e10cSrcweir nValue = aPixSize.Width();
545cdf0e10cSrcweir else
546cdf0e10cSrcweir {
547cdf0e10cSrcweir nValue = aPixSize.Height();
548cdf0e10cSrcweir
549cdf0e10cSrcweir if ( bBreak && !rOptions.bTotalSize )
550cdf0e10cSrcweir {
551cdf0e10cSrcweir // #47744# limit size for line break
552cdf0e10cSrcweir long nCmp = aOldFont.GetSize().Height() * SC_ROT_BREAK_FACTOR;
553cdf0e10cSrcweir if ( nValue > nCmp )
554cdf0e10cSrcweir nValue = nCmp;
555cdf0e10cSrcweir }
556cdf0e10cSrcweir }
557cdf0e10cSrcweir }
558cdf0e10cSrcweir else if ( bEdWidth )
559cdf0e10cSrcweir {
560cdf0e10cSrcweir if (bBreak)
561cdf0e10cSrcweir nValue = 0;
562cdf0e10cSrcweir else
563cdf0e10cSrcweir nValue = pDev->LogicToPixel(Size( pEngine->CalcTextWidth(), 0 ),
564cdf0e10cSrcweir aHMMMode).Width();
565cdf0e10cSrcweir }
566cdf0e10cSrcweir else // Hoehe
567cdf0e10cSrcweir {
568cdf0e10cSrcweir nValue = pDev->LogicToPixel(Size( 0, pEngine->GetTextHeight() ),
569cdf0e10cSrcweir aHMMMode).Height();
570cdf0e10cSrcweir
571cdf0e10cSrcweir // With non-100% zoom and several lines or paragraphs, don't shrink below the result with FORMAT100 set
572cdf0e10cSrcweir if ( !bTextWysiwyg && ( rZoomY.GetNumerator() != 1 || rZoomY.GetDenominator() != 1 ) &&
573cdf0e10cSrcweir ( pEngine->GetParagraphCount() > 1 || ( bBreak && pEngine->GetLineCount(0) > 1 ) ) )
574cdf0e10cSrcweir {
575cdf0e10cSrcweir pEngine->SetControlWord( nCtrl | EE_CNTRL_FORMAT100 );
576cdf0e10cSrcweir pEngine->QuickFormatDoc( sal_True );
577cdf0e10cSrcweir long nSecondValue = pDev->LogicToPixel(Size( 0, pEngine->GetTextHeight() ), aHMMMode).Height();
578cdf0e10cSrcweir if ( nSecondValue > nValue )
579cdf0e10cSrcweir nValue = nSecondValue;
580cdf0e10cSrcweir }
581cdf0e10cSrcweir }
582cdf0e10cSrcweir
583cdf0e10cSrcweir if ( nValue && bAddMargin )
584cdf0e10cSrcweir {
585cdf0e10cSrcweir if (bWidth)
586cdf0e10cSrcweir {
587cdf0e10cSrcweir nValue += (long) ( pMargin->GetLeftMargin() * nPPT ) +
588cdf0e10cSrcweir (long) ( pMargin->GetRightMargin() * nPPT );
589cdf0e10cSrcweir if (nIndent)
590cdf0e10cSrcweir nValue += (long) ( nIndent * nPPT );
591cdf0e10cSrcweir }
592cdf0e10cSrcweir else
593cdf0e10cSrcweir {
594cdf0e10cSrcweir nValue += (long) ( pMargin->GetTopMargin() * nPPT ) +
595cdf0e10cSrcweir (long) ( pMargin->GetBottomMargin() * nPPT );
596cdf0e10cSrcweir
597cdf0e10cSrcweir if ( bAsianVertical && pDev->GetOutDevType() != OUTDEV_PRINTER )
598cdf0e10cSrcweir {
599cdf0e10cSrcweir // add 1pt extra (default margin value) for line breaks with SetVertical
600cdf0e10cSrcweir nValue += (long) ( 20 * nPPT );
601cdf0e10cSrcweir }
602cdf0e10cSrcweir }
603cdf0e10cSrcweir }
604cdf0e10cSrcweir
605cdf0e10cSrcweir // EditEngine is cached and re-used, so the old vertical flag must be restored
606cdf0e10cSrcweir pEngine->SetVertical( bEngineVertical );
607cdf0e10cSrcweir
608cdf0e10cSrcweir pDocument->DisposeFieldEditEngine(pEngine);
609cdf0e10cSrcweir
610cdf0e10cSrcweir pDev->SetMapMode( aOld );
611cdf0e10cSrcweir pDev->SetFont( aOldFont );
612cdf0e10cSrcweir }
613cdf0e10cSrcweir
614cdf0e10cSrcweir if (bWidth)
615cdf0e10cSrcweir {
616cdf0e10cSrcweir // Platz fuer Autofilter-Button
617cdf0e10cSrcweir // 20 * nZoom/100
618cdf0e10cSrcweir // bedingte Formatierung hier nicht interessant
619cdf0e10cSrcweir
620cdf0e10cSrcweir sal_Int16 nFlags = ((const ScMergeFlagAttr&)pPattern->GetItem(ATTR_MERGE_FLAG)).GetValue();
621cdf0e10cSrcweir if (nFlags & SC_MF_AUTO)
622cdf0e10cSrcweir nValue += (rZoomX.GetNumerator()*20)/rZoomX.GetDenominator();
623cdf0e10cSrcweir }
624cdf0e10cSrcweir }
625cdf0e10cSrcweir return nValue;
626cdf0e10cSrcweir }
627cdf0e10cSrcweir
GetSimpleTextNeededSize(SCSIZE nIndex,OutputDevice * pDev,sal_Bool bWidth)628cdf0e10cSrcweir long ScColumn::GetSimpleTextNeededSize( SCSIZE nIndex, OutputDevice* pDev,
629cdf0e10cSrcweir sal_Bool bWidth )
630cdf0e10cSrcweir {
631cdf0e10cSrcweir long nValue=0;
632cdf0e10cSrcweir if ( nIndex < nCount )
633cdf0e10cSrcweir {
634cdf0e10cSrcweir SCROW nRow = pItems[nIndex].nRow;
635cdf0e10cSrcweir const ScPatternAttr* pPattern = pAttrArray->GetPattern( nRow );
636cdf0e10cSrcweir ScBaseCell* pCell = pItems[nIndex].pCell;
637cdf0e10cSrcweir String aValStr;
638cdf0e10cSrcweir Color* pColor;
639cdf0e10cSrcweir SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
640cdf0e10cSrcweir sal_uLong nFormat = pPattern->GetNumberFormat( pFormatter );
641cdf0e10cSrcweir ScCellFormat::GetString( pCell, nFormat, aValStr, &pColor,
642cdf0e10cSrcweir *pFormatter, sal_True, sal_False, ftCheck );
643cdf0e10cSrcweir if ( aValStr.Len() )
644cdf0e10cSrcweir {
645cdf0e10cSrcweir if ( bWidth )
646cdf0e10cSrcweir nValue = pDev->GetTextWidth( aValStr );
647cdf0e10cSrcweir else
648cdf0e10cSrcweir nValue = pDev->GetTextHeight();
649cdf0e10cSrcweir }
650cdf0e10cSrcweir }
651cdf0e10cSrcweir return nValue;
652cdf0e10cSrcweir }
653cdf0e10cSrcweir
GetOptimalColWidth(OutputDevice * pDev,double nPPTX,double nPPTY,const Fraction & rZoomX,const Fraction & rZoomY,sal_Bool bFormula,sal_uInt16 nOldWidth,const ScMarkData * pMarkData,sal_Bool bSimpleTextImport)654cdf0e10cSrcweir sal_uInt16 ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nPPTY,
655cdf0e10cSrcweir const Fraction& rZoomX, const Fraction& rZoomY,
656cdf0e10cSrcweir sal_Bool bFormula, sal_uInt16 nOldWidth,
657cdf0e10cSrcweir const ScMarkData* pMarkData,
658cdf0e10cSrcweir sal_Bool bSimpleTextImport )
659cdf0e10cSrcweir {
660cdf0e10cSrcweir if (nCount == 0)
661cdf0e10cSrcweir return nOldWidth;
662cdf0e10cSrcweir
663cdf0e10cSrcweir sal_uInt16 nWidth = (sal_uInt16) (nOldWidth * nPPTX);
664cdf0e10cSrcweir sal_Bool bFound = sal_False;
665cdf0e10cSrcweir
666cdf0e10cSrcweir SCSIZE nIndex;
667cdf0e10cSrcweir ScMarkedDataIter aDataIter(this, pMarkData, sal_True);
668cdf0e10cSrcweir if ( bSimpleTextImport )
669cdf0e10cSrcweir { // alles eins bis auf NumberFormate
670cdf0e10cSrcweir const ScPatternAttr* pPattern = GetPattern( 0 );
671cdf0e10cSrcweir Font aFont;
672cdf0e10cSrcweir // font color doesn't matter here
673cdf0e10cSrcweir pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &rZoomX, NULL );
674cdf0e10cSrcweir pDev->SetFont( aFont );
675cdf0e10cSrcweir const SvxMarginItem* pMargin = (const SvxMarginItem*) &pPattern->GetItem(ATTR_MARGIN);
676cdf0e10cSrcweir long nMargin = (long) ( pMargin->GetLeftMargin() * nPPTX ) +
677cdf0e10cSrcweir (long) ( pMargin->GetRightMargin() * nPPTX );
678cdf0e10cSrcweir
679cdf0e10cSrcweir while (aDataIter.Next( nIndex ))
680cdf0e10cSrcweir {
681cdf0e10cSrcweir sal_uInt16 nThis = (sal_uInt16) (GetSimpleTextNeededSize( nIndex, pDev,
682cdf0e10cSrcweir sal_True ) + nMargin);
683cdf0e10cSrcweir if (nThis)
684cdf0e10cSrcweir {
685cdf0e10cSrcweir if (nThis>nWidth || !bFound)
686cdf0e10cSrcweir {
687cdf0e10cSrcweir nWidth = nThis;
688cdf0e10cSrcweir bFound = sal_True;
689cdf0e10cSrcweir }
690cdf0e10cSrcweir }
691cdf0e10cSrcweir }
692cdf0e10cSrcweir }
693cdf0e10cSrcweir else
694cdf0e10cSrcweir {
695cdf0e10cSrcweir ScNeededSizeOptions aOptions;
696cdf0e10cSrcweir aOptions.bFormula = bFormula;
697cdf0e10cSrcweir const ScPatternAttr* pOldPattern = NULL;
698cdf0e10cSrcweir sal_uInt8 nOldScript = 0;
699cdf0e10cSrcweir
700cdf0e10cSrcweir while (aDataIter.Next( nIndex ))
701cdf0e10cSrcweir {
702cdf0e10cSrcweir SCROW nRow = pItems[nIndex].nRow;
703cdf0e10cSrcweir
704cdf0e10cSrcweir sal_uInt8 nScript = pDocument->GetScriptType( nCol, nRow, nTab, pItems[nIndex].pCell );
705cdf0e10cSrcweir if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
706cdf0e10cSrcweir
707cdf0e10cSrcweir const ScPatternAttr* pPattern = GetPattern( nRow );
708cdf0e10cSrcweir aOptions.pPattern = pPattern;
709cdf0e10cSrcweir aOptions.bGetFont = (pPattern != pOldPattern || nScript != nOldScript);
710cdf0e10cSrcweir sal_uInt16 nThis = (sal_uInt16) GetNeededSize( nRow, pDev, nPPTX, nPPTY,
711cdf0e10cSrcweir rZoomX, rZoomY, sal_True, aOptions );
712cdf0e10cSrcweir pOldPattern = pPattern;
713cdf0e10cSrcweir if (nThis)
714cdf0e10cSrcweir {
715cdf0e10cSrcweir if (nThis>nWidth || !bFound)
716cdf0e10cSrcweir {
717cdf0e10cSrcweir nWidth = nThis;
718cdf0e10cSrcweir bFound = sal_True;
719cdf0e10cSrcweir }
720cdf0e10cSrcweir }
721cdf0e10cSrcweir }
722cdf0e10cSrcweir }
723cdf0e10cSrcweir
724cdf0e10cSrcweir if (bFound)
725cdf0e10cSrcweir {
726cdf0e10cSrcweir nWidth += 2;
727cdf0e10cSrcweir sal_uInt16 nTwips = (sal_uInt16) (nWidth / nPPTX);
728cdf0e10cSrcweir return nTwips;
729cdf0e10cSrcweir }
730cdf0e10cSrcweir else
731cdf0e10cSrcweir return nOldWidth;
732cdf0e10cSrcweir }
733cdf0e10cSrcweir
lcl_GetAttribHeight(const ScPatternAttr & rPattern,sal_uInt16 nFontHeightId)734cdf0e10cSrcweir sal_uInt16 lcl_GetAttribHeight( const ScPatternAttr& rPattern, sal_uInt16 nFontHeightId )
735cdf0e10cSrcweir {
736cdf0e10cSrcweir sal_uInt16 nHeight = (sal_uInt16) ((const SvxFontHeightItem&) rPattern.GetItem(nFontHeightId)).GetHeight();
737cdf0e10cSrcweir const SvxMarginItem* pMargin = (const SvxMarginItem*) &rPattern.GetItem(ATTR_MARGIN);
738cdf0e10cSrcweir nHeight += nHeight / 5;
739cdf0e10cSrcweir // gibt bei 10pt 240
740cdf0e10cSrcweir
741cdf0e10cSrcweir if ( ((const SvxEmphasisMarkItem&)rPattern.
742cdf0e10cSrcweir GetItem(ATTR_FONT_EMPHASISMARK)).GetEmphasisMark() != EMPHASISMARK_NONE )
743cdf0e10cSrcweir {
744cdf0e10cSrcweir // add height for emphasis marks
745cdf0e10cSrcweir //! font metrics should be used instead
746cdf0e10cSrcweir nHeight += nHeight / 4;
747cdf0e10cSrcweir }
748cdf0e10cSrcweir
749cdf0e10cSrcweir if ( nHeight + 240 > ScGlobal::nDefFontHeight )
750cdf0e10cSrcweir {
751cdf0e10cSrcweir nHeight = sal::static_int_cast<sal_uInt16>( nHeight + ScGlobal::nDefFontHeight );
752cdf0e10cSrcweir nHeight -= 240;
753cdf0e10cSrcweir }
754cdf0e10cSrcweir
755cdf0e10cSrcweir // Standard-Hoehe: TextHeight + Raender - 23
756cdf0e10cSrcweir // -> 257 unter Windows
757cdf0e10cSrcweir
758cdf0e10cSrcweir if (nHeight > STD_ROWHEIGHT_DIFF)
759cdf0e10cSrcweir nHeight -= STD_ROWHEIGHT_DIFF;
760cdf0e10cSrcweir
761cdf0e10cSrcweir nHeight += pMargin->GetTopMargin() + pMargin->GetBottomMargin();
762cdf0e10cSrcweir
763cdf0e10cSrcweir return nHeight;
764cdf0e10cSrcweir }
765cdf0e10cSrcweir
766cdf0e10cSrcweir // pHeight in Twips
767cdf0e10cSrcweir // nMinHeight, nMinStart zur Optimierung: ab nRow >= nMinStart ist mindestens nMinHeight
768cdf0e10cSrcweir // (wird nur bei bStdAllowed ausgewertet)
769cdf0e10cSrcweir
GetOptimalHeight(SCROW nStartRow,SCROW nEndRow,sal_uInt16 * pHeight,OutputDevice * pDev,double nPPTX,double nPPTY,const Fraction & rZoomX,const Fraction & rZoomY,sal_Bool bShrink,sal_uInt16 nMinHeight,SCROW nMinStart)770cdf0e10cSrcweir void ScColumn::GetOptimalHeight( SCROW nStartRow, SCROW nEndRow, sal_uInt16* pHeight,
771cdf0e10cSrcweir OutputDevice* pDev,
772cdf0e10cSrcweir double nPPTX, double nPPTY,
773cdf0e10cSrcweir const Fraction& rZoomX, const Fraction& rZoomY,
774cdf0e10cSrcweir sal_Bool bShrink, sal_uInt16 nMinHeight, SCROW nMinStart )
775cdf0e10cSrcweir {
776cdf0e10cSrcweir ScAttrIterator aIter( pAttrArray, nStartRow, nEndRow );
777cdf0e10cSrcweir
778cdf0e10cSrcweir SCROW nStart = -1;
779cdf0e10cSrcweir SCROW nEnd = -1;
780cdf0e10cSrcweir SCROW nEditPos = 0;
781cdf0e10cSrcweir SCROW nNextEnd = 0;
782cdf0e10cSrcweir
783cdf0e10cSrcweir // bei bedingter Formatierung werden immer die einzelnen Zellen angesehen
784cdf0e10cSrcweir
785cdf0e10cSrcweir const ScPatternAttr* pPattern = aIter.Next(nStart,nEnd);
786cdf0e10cSrcweir while ( pPattern )
787cdf0e10cSrcweir {
788cdf0e10cSrcweir const ScMergeAttr* pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
789cdf0e10cSrcweir const ScMergeFlagAttr* pFlag = (const ScMergeFlagAttr*)&pPattern->GetItem(ATTR_MERGE_FLAG);
790cdf0e10cSrcweir if ( pMerge->GetRowMerge() > 1 || pFlag->IsOverlapped() )
791cdf0e10cSrcweir {
792cdf0e10cSrcweir // nix - vertikal bei der zusammengefassten und den ueberdeckten,
793cdf0e10cSrcweir // horizontal nur bei den ueberdeckten (unsichtbaren) -
794cdf0e10cSrcweir // eine nur horizontal zusammengefasste wird aber beruecksichtigt
795cdf0e10cSrcweir }
796cdf0e10cSrcweir else
797cdf0e10cSrcweir {
798cdf0e10cSrcweir SCROW nRow = 0;
799cdf0e10cSrcweir sal_Bool bStdAllowed = (pPattern->GetCellOrientation() == SVX_ORIENTATION_STANDARD);
800cdf0e10cSrcweir sal_Bool bStdOnly = sal_False;
801cdf0e10cSrcweir if (bStdAllowed)
802cdf0e10cSrcweir {
803cdf0e10cSrcweir sal_Bool bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() ||
804cdf0e10cSrcweir ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
805cdf0e10cSrcweir GetItem( ATTR_HOR_JUSTIFY )).GetValue() ==
806cdf0e10cSrcweir SVX_HOR_JUSTIFY_BLOCK);
807cdf0e10cSrcweir bStdOnly = !bBreak;
808cdf0e10cSrcweir
809cdf0e10cSrcweir // bedingte Formatierung: Zellen durchgehen
810cdf0e10cSrcweir if ( bStdOnly && ((const SfxUInt32Item&)pPattern->
811cdf0e10cSrcweir GetItem(ATTR_CONDITIONAL)).GetValue() )
812cdf0e10cSrcweir bStdOnly = sal_False;
813cdf0e10cSrcweir
814cdf0e10cSrcweir // gedrehter Text: Zellen durchgehen
815cdf0e10cSrcweir if ( bStdOnly && ((const SfxInt32Item&)pPattern->
816cdf0e10cSrcweir GetItem(ATTR_ROTATE_VALUE)).GetValue() )
817cdf0e10cSrcweir bStdOnly = sal_False;
818cdf0e10cSrcweir }
819cdf0e10cSrcweir
820cdf0e10cSrcweir if (bStdOnly)
821cdf0e10cSrcweir if (HasEditCells(nStart,nEnd,nEditPos)) // includes mixed script types
822cdf0e10cSrcweir {
823cdf0e10cSrcweir if (nEditPos == nStart)
824cdf0e10cSrcweir {
825cdf0e10cSrcweir bStdOnly = sal_False;
826cdf0e10cSrcweir if (nEnd > nEditPos)
827cdf0e10cSrcweir nNextEnd = nEnd;
828cdf0e10cSrcweir nEnd = nEditPos; // einzeln ausrechnen
829cdf0e10cSrcweir bStdAllowed = sal_False; // wird auf jeden Fall per Zelle berechnet
830cdf0e10cSrcweir }
831cdf0e10cSrcweir else
832cdf0e10cSrcweir {
833cdf0e10cSrcweir nNextEnd = nEnd;
834cdf0e10cSrcweir nEnd = nEditPos - 1; // Standard - Teil
835cdf0e10cSrcweir }
836cdf0e10cSrcweir }
837cdf0e10cSrcweir
838cdf0e10cSrcweir if (bStdAllowed)
839cdf0e10cSrcweir {
840cdf0e10cSrcweir sal_uInt16 nLatHeight = 0;
841cdf0e10cSrcweir sal_uInt16 nCjkHeight = 0;
842cdf0e10cSrcweir sal_uInt16 nCtlHeight = 0;
843cdf0e10cSrcweir sal_uInt16 nDefHeight;
844cdf0e10cSrcweir sal_uInt8 nDefScript = ScGlobal::GetDefaultScriptType();
845cdf0e10cSrcweir if ( nDefScript == SCRIPTTYPE_ASIAN )
846cdf0e10cSrcweir nDefHeight = nCjkHeight = lcl_GetAttribHeight( *pPattern, ATTR_CJK_FONT_HEIGHT );
847cdf0e10cSrcweir else if ( nDefScript == SCRIPTTYPE_COMPLEX )
848cdf0e10cSrcweir nDefHeight = nCtlHeight = lcl_GetAttribHeight( *pPattern, ATTR_CTL_FONT_HEIGHT );
849cdf0e10cSrcweir else
850cdf0e10cSrcweir nDefHeight = nLatHeight = lcl_GetAttribHeight( *pPattern, ATTR_FONT_HEIGHT );
851cdf0e10cSrcweir
852cdf0e10cSrcweir // if everything below is already larger, the loop doesn't have to
853cdf0e10cSrcweir // be run again
854cdf0e10cSrcweir SCROW nStdEnd = nEnd;
855cdf0e10cSrcweir if ( nDefHeight <= nMinHeight && nStdEnd >= nMinStart )
856cdf0e10cSrcweir nStdEnd = (nMinStart>0) ? nMinStart-1 : 0;
857cdf0e10cSrcweir
858cdf0e10cSrcweir for (nRow=nStart; nRow<=nStdEnd; nRow++)
859cdf0e10cSrcweir if (nDefHeight > pHeight[nRow-nStartRow])
860cdf0e10cSrcweir pHeight[nRow-nStartRow] = nDefHeight;
861cdf0e10cSrcweir
862cdf0e10cSrcweir if ( bStdOnly )
863cdf0e10cSrcweir {
864cdf0e10cSrcweir // if cells are not handled individually below,
865cdf0e10cSrcweir // check for cells with different script type
866cdf0e10cSrcweir
867cdf0e10cSrcweir SCSIZE nIndex;
868cdf0e10cSrcweir Search(nStart,nIndex);
869cdf0e10cSrcweir while ( nIndex < nCount && (nRow=pItems[nIndex].nRow) <= nEnd )
870cdf0e10cSrcweir {
871cdf0e10cSrcweir sal_uInt8 nScript = pDocument->GetScriptType( nCol, nRow, nTab, pItems[nIndex].pCell );
872cdf0e10cSrcweir if ( nScript != nDefScript )
873cdf0e10cSrcweir {
874cdf0e10cSrcweir if ( nScript == SCRIPTTYPE_ASIAN )
875cdf0e10cSrcweir {
876cdf0e10cSrcweir if ( nCjkHeight == 0 )
877cdf0e10cSrcweir nCjkHeight = lcl_GetAttribHeight( *pPattern, ATTR_CJK_FONT_HEIGHT );
878cdf0e10cSrcweir if (nCjkHeight > pHeight[nRow-nStartRow])
879cdf0e10cSrcweir pHeight[nRow-nStartRow] = nCjkHeight;
880cdf0e10cSrcweir }
881cdf0e10cSrcweir else if ( nScript == SCRIPTTYPE_COMPLEX )
882cdf0e10cSrcweir {
883cdf0e10cSrcweir if ( nCtlHeight == 0 )
884cdf0e10cSrcweir nCtlHeight = lcl_GetAttribHeight( *pPattern, ATTR_CTL_FONT_HEIGHT );
885cdf0e10cSrcweir if (nCtlHeight > pHeight[nRow-nStartRow])
886cdf0e10cSrcweir pHeight[nRow-nStartRow] = nCtlHeight;
887cdf0e10cSrcweir }
888cdf0e10cSrcweir else
889cdf0e10cSrcweir {
890cdf0e10cSrcweir if ( nLatHeight == 0 )
891cdf0e10cSrcweir nLatHeight = lcl_GetAttribHeight( *pPattern, ATTR_FONT_HEIGHT );
892cdf0e10cSrcweir if (nLatHeight > pHeight[nRow-nStartRow])
893cdf0e10cSrcweir pHeight[nRow-nStartRow] = nLatHeight;
894cdf0e10cSrcweir }
895cdf0e10cSrcweir }
896cdf0e10cSrcweir ++nIndex;
897cdf0e10cSrcweir }
898cdf0e10cSrcweir }
899cdf0e10cSrcweir }
900cdf0e10cSrcweir
901cdf0e10cSrcweir if (!bStdOnly) // belegte Zellen suchen
902cdf0e10cSrcweir {
903cdf0e10cSrcweir ScNeededSizeOptions aOptions;
904cdf0e10cSrcweir
905cdf0e10cSrcweir SCSIZE nIndex;
906cdf0e10cSrcweir Search(nStart,nIndex);
907cdf0e10cSrcweir while ( (nIndex < nCount) ? ((nRow=pItems[nIndex].nRow) <= nEnd) : sal_False )
908cdf0e10cSrcweir {
909cdf0e10cSrcweir // Zellhoehe nur berechnen, wenn sie spaeter auch gebraucht wird (#37928#)
910cdf0e10cSrcweir
911cdf0e10cSrcweir if ( bShrink || !(pDocument->GetRowFlags(nRow, nTab) & CR_MANUALSIZE) )
912cdf0e10cSrcweir {
913cdf0e10cSrcweir aOptions.pPattern = pPattern;
914cdf0e10cSrcweir sal_uInt16 nHeight = (sal_uInt16)
915cdf0e10cSrcweir ( GetNeededSize( nRow, pDev, nPPTX, nPPTY,
916cdf0e10cSrcweir rZoomX, rZoomY, sal_False, aOptions ) / nPPTY );
917cdf0e10cSrcweir if (nHeight > pHeight[nRow-nStartRow])
918cdf0e10cSrcweir pHeight[nRow-nStartRow] = nHeight;
919cdf0e10cSrcweir }
920cdf0e10cSrcweir ++nIndex;
921cdf0e10cSrcweir }
922cdf0e10cSrcweir }
923cdf0e10cSrcweir }
924cdf0e10cSrcweir
925cdf0e10cSrcweir if (nNextEnd > 0)
926cdf0e10cSrcweir {
927cdf0e10cSrcweir nStart = nEnd + 1;
928cdf0e10cSrcweir nEnd = nNextEnd;
929cdf0e10cSrcweir nNextEnd = 0;
930cdf0e10cSrcweir }
931cdf0e10cSrcweir else
932cdf0e10cSrcweir pPattern = aIter.Next(nStart,nEnd);
933cdf0e10cSrcweir }
934cdf0e10cSrcweir }
935cdf0e10cSrcweir
GetNextSpellingCell(SCROW & nRow,sal_Bool bInSel,const ScMarkData & rData) const936cdf0e10cSrcweir sal_Bool ScColumn::GetNextSpellingCell(SCROW& nRow, sal_Bool bInSel, const ScMarkData& rData) const
937cdf0e10cSrcweir {
938cdf0e10cSrcweir sal_Bool bStop = sal_False;
939cdf0e10cSrcweir CellType eCellType;
940cdf0e10cSrcweir SCSIZE nIndex;
941cdf0e10cSrcweir if (!bInSel && Search(nRow, nIndex))
942cdf0e10cSrcweir {
943cdf0e10cSrcweir eCellType = GetCellType(nRow);
944cdf0e10cSrcweir if ( (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT) &&
945cdf0e10cSrcweir !(HasAttrib( nRow, nRow, HASATTR_PROTECTED) &&
946cdf0e10cSrcweir pDocument->IsTabProtected(nTab)) )
947cdf0e10cSrcweir return sal_True;
948cdf0e10cSrcweir }
949cdf0e10cSrcweir while (!bStop)
950cdf0e10cSrcweir {
951cdf0e10cSrcweir if (bInSel)
952cdf0e10cSrcweir {
953cdf0e10cSrcweir nRow = rData.GetNextMarked(nCol, nRow, sal_False);
954cdf0e10cSrcweir if (!ValidRow(nRow))
955cdf0e10cSrcweir {
956cdf0e10cSrcweir nRow = MAXROW+1;
957cdf0e10cSrcweir bStop = sal_True;
958cdf0e10cSrcweir }
959cdf0e10cSrcweir else
960cdf0e10cSrcweir {
961cdf0e10cSrcweir eCellType = GetCellType(nRow);
962cdf0e10cSrcweir if ( (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT) &&
963cdf0e10cSrcweir !(HasAttrib( nRow, nRow, HASATTR_PROTECTED) &&
964cdf0e10cSrcweir pDocument->IsTabProtected(nTab)) )
965cdf0e10cSrcweir return sal_True;
966cdf0e10cSrcweir else
967cdf0e10cSrcweir nRow++;
968cdf0e10cSrcweir }
969cdf0e10cSrcweir }
970cdf0e10cSrcweir else if (GetNextDataPos(nRow))
971cdf0e10cSrcweir {
972cdf0e10cSrcweir eCellType = GetCellType(nRow);
973cdf0e10cSrcweir if ( (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT) &&
974cdf0e10cSrcweir !(HasAttrib( nRow, nRow, HASATTR_PROTECTED) &&
975cdf0e10cSrcweir pDocument->IsTabProtected(nTab)) )
976cdf0e10cSrcweir return sal_True;
977cdf0e10cSrcweir else
978cdf0e10cSrcweir nRow++;
979cdf0e10cSrcweir }
980cdf0e10cSrcweir else
981cdf0e10cSrcweir {
982cdf0e10cSrcweir nRow = MAXROW+1;
983cdf0e10cSrcweir bStop = sal_True;
984cdf0e10cSrcweir }
985cdf0e10cSrcweir }
986cdf0e10cSrcweir return sal_False;
987cdf0e10cSrcweir }
988cdf0e10cSrcweir
989cdf0e10cSrcweir // =========================================================================================
990cdf0e10cSrcweir
RemoveAutoSpellObj()991cdf0e10cSrcweir void ScColumn::RemoveAutoSpellObj()
992cdf0e10cSrcweir {
993cdf0e10cSrcweir ScTabEditEngine* pEngine = NULL;
994cdf0e10cSrcweir
995cdf0e10cSrcweir for (SCSIZE i=0; i<nCount; i++)
996cdf0e10cSrcweir if ( pItems[i].pCell->GetCellType() == CELLTYPE_EDIT )
997cdf0e10cSrcweir {
998cdf0e10cSrcweir ScEditCell* pOldCell = (ScEditCell*) pItems[i].pCell;
999cdf0e10cSrcweir const EditTextObject* pData = pOldCell->GetData();
1000cdf0e10cSrcweir // keine Abfrage auf HasOnlineSpellErrors, damit es auch
1001cdf0e10cSrcweir // nach dem Laden funktioniert
1002cdf0e10cSrcweir
1003cdf0e10cSrcweir // Fuer den Test auf harte Formatierung (ScEditAttrTester) sind die Defaults
1004cdf0e10cSrcweir // in der EditEngine unwichtig. Wenn der Tester spaeter einmal gleiche
1005cdf0e10cSrcweir // Attribute in Default und harter Formatierung erkennen und weglassen sollte,
1006cdf0e10cSrcweir // muessten an der EditEngine zu jeder Zelle die richtigen Defaults gesetzt
1007cdf0e10cSrcweir // werden!
1008cdf0e10cSrcweir
1009cdf0e10cSrcweir // auf Attribute testen
1010cdf0e10cSrcweir if ( !pEngine )
1011cdf0e10cSrcweir pEngine = new ScTabEditEngine(pDocument);
1012cdf0e10cSrcweir pEngine->SetText( *pData );
1013cdf0e10cSrcweir ScEditAttrTester aTester( pEngine );
1014cdf0e10cSrcweir if ( aTester.NeedsObject() ) // nur Spell-Errors entfernen
1015cdf0e10cSrcweir {
1016cdf0e10cSrcweir EditTextObject* pNewData = pEngine->CreateTextObject(); // ohne BIGOBJ
1017cdf0e10cSrcweir pOldCell->SetData( pNewData, pEngine->GetEditTextObjectPool() );
1018cdf0e10cSrcweir delete pNewData;
1019cdf0e10cSrcweir }
1020cdf0e10cSrcweir else // String erzeugen
1021cdf0e10cSrcweir {
1022cdf0e10cSrcweir String aText = ScEditUtil::GetSpaceDelimitedString( *pEngine );
1023cdf0e10cSrcweir ScBaseCell* pNewCell = new ScStringCell( aText );
1024cdf0e10cSrcweir pNewCell->TakeBroadcaster( pOldCell->ReleaseBroadcaster() );
1025cdf0e10cSrcweir pNewCell->TakeNote( pOldCell->ReleaseNote() );
1026cdf0e10cSrcweir pItems[i].pCell = pNewCell;
1027cdf0e10cSrcweir delete pOldCell;
1028cdf0e10cSrcweir }
1029cdf0e10cSrcweir }
1030cdf0e10cSrcweir
1031cdf0e10cSrcweir delete pEngine;
1032cdf0e10cSrcweir }
1033cdf0e10cSrcweir
RemoveEditAttribs(SCROW nStartRow,SCROW nEndRow)1034cdf0e10cSrcweir void ScColumn::RemoveEditAttribs( SCROW nStartRow, SCROW nEndRow )
1035cdf0e10cSrcweir {
1036cdf0e10cSrcweir ScFieldEditEngine* pEngine = NULL;
1037cdf0e10cSrcweir
1038cdf0e10cSrcweir SCSIZE i;
1039cdf0e10cSrcweir Search( nStartRow, i );
1040cdf0e10cSrcweir for (; i<nCount && pItems[i].nRow <= nEndRow; i++)
1041cdf0e10cSrcweir if ( pItems[i].pCell->GetCellType() == CELLTYPE_EDIT )
1042cdf0e10cSrcweir {
1043cdf0e10cSrcweir ScEditCell* pOldCell = (ScEditCell*) pItems[i].pCell;
1044cdf0e10cSrcweir const EditTextObject* pData = pOldCell->GetData();
1045cdf0e10cSrcweir
1046cdf0e10cSrcweir // Fuer den Test auf harte Formatierung (ScEditAttrTester) sind die Defaults
1047cdf0e10cSrcweir // in der EditEngine unwichtig. Wenn der Tester spaeter einmal gleiche
1048cdf0e10cSrcweir // Attribute in Default und harter Formatierung erkennen und weglassen sollte,
1049cdf0e10cSrcweir // muessten an der EditEngine zu jeder Zelle die richtigen Defaults gesetzt
1050cdf0e10cSrcweir // werden!
1051cdf0e10cSrcweir
1052cdf0e10cSrcweir // auf Attribute testen
1053cdf0e10cSrcweir if ( !pEngine )
1054cdf0e10cSrcweir {
1055cdf0e10cSrcweir //pEngine = new ScTabEditEngine(pDocument);
1056cdf0e10cSrcweir pEngine = new ScFieldEditEngine( pDocument->GetEditPool() );
1057cdf0e10cSrcweir // EE_CNTRL_ONLINESPELLING falls schon Fehler drin sind
1058cdf0e10cSrcweir pEngine->SetControlWord( pEngine->GetControlWord() | EE_CNTRL_ONLINESPELLING );
1059cdf0e10cSrcweir pDocument->ApplyAsianEditSettings( *pEngine );
1060cdf0e10cSrcweir }
1061cdf0e10cSrcweir pEngine->SetText( *pData );
1062cdf0e10cSrcweir sal_uInt16 nParCount = pEngine->GetParagraphCount();
1063cdf0e10cSrcweir for (sal_uInt16 nPar=0; nPar<nParCount; nPar++)
1064cdf0e10cSrcweir {
1065cdf0e10cSrcweir pEngine->QuickRemoveCharAttribs( nPar );
1066cdf0e10cSrcweir const SfxItemSet& rOld = pEngine->GetParaAttribs( nPar );
1067cdf0e10cSrcweir if ( rOld.Count() )
1068cdf0e10cSrcweir {
1069cdf0e10cSrcweir SfxItemSet aNew( *rOld.GetPool(), rOld.GetRanges() ); // leer
1070cdf0e10cSrcweir pEngine->SetParaAttribs( nPar, aNew );
1071cdf0e10cSrcweir }
1072cdf0e10cSrcweir }
1073cdf0e10cSrcweir // URL-Felder in Text wandeln (andere gibt's nicht, darum pType=0)
1074cdf0e10cSrcweir pEngine->RemoveFields( sal_True );
1075cdf0e10cSrcweir
1076cdf0e10cSrcweir sal_Bool bSpellErrors = pEngine->HasOnlineSpellErrors();
1077cdf0e10cSrcweir sal_Bool bNeedObject = bSpellErrors || nParCount>1; // Errors/Absaetze behalten
1078cdf0e10cSrcweir // ScEditAttrTester nicht mehr noetig, Felder sind raus
1079cdf0e10cSrcweir
1080cdf0e10cSrcweir if ( bNeedObject ) // bleibt Edit-Zelle
1081cdf0e10cSrcweir {
1082cdf0e10cSrcweir sal_uLong nCtrl = pEngine->GetControlWord();
1083cdf0e10cSrcweir sal_uLong nWantBig = bSpellErrors ? EE_CNTRL_ALLOWBIGOBJS : 0;
1084cdf0e10cSrcweir if ( ( nCtrl & EE_CNTRL_ALLOWBIGOBJS ) != nWantBig )
1085cdf0e10cSrcweir pEngine->SetControlWord( (nCtrl & ~EE_CNTRL_ALLOWBIGOBJS) | nWantBig );
1086cdf0e10cSrcweir EditTextObject* pNewData = pEngine->CreateTextObject();
1087cdf0e10cSrcweir pOldCell->SetData( pNewData, pEngine->GetEditTextObjectPool() );
1088cdf0e10cSrcweir delete pNewData;
1089cdf0e10cSrcweir }
1090cdf0e10cSrcweir else // String erzeugen
1091cdf0e10cSrcweir {
1092cdf0e10cSrcweir String aText = ScEditUtil::GetSpaceDelimitedString( *pEngine );
1093cdf0e10cSrcweir ScBaseCell* pNewCell = new ScStringCell( aText );
1094cdf0e10cSrcweir pNewCell->TakeBroadcaster( pOldCell->ReleaseBroadcaster() );
1095cdf0e10cSrcweir pNewCell->TakeNote( pOldCell->ReleaseNote() );
1096cdf0e10cSrcweir pItems[i].pCell = pNewCell;
1097cdf0e10cSrcweir delete pOldCell;
1098cdf0e10cSrcweir }
1099cdf0e10cSrcweir }
1100cdf0e10cSrcweir
1101cdf0e10cSrcweir delete pEngine;
1102cdf0e10cSrcweir }
1103cdf0e10cSrcweir
1104cdf0e10cSrcweir // =========================================================================================
1105cdf0e10cSrcweir
TestTabRefAbs(SCTAB nTable)1106cdf0e10cSrcweir sal_Bool ScColumn::TestTabRefAbs(SCTAB nTable)
1107cdf0e10cSrcweir {
1108cdf0e10cSrcweir sal_Bool bRet = sal_False;
1109cdf0e10cSrcweir if (pItems)
1110cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1111cdf0e10cSrcweir if ( pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA )
1112cdf0e10cSrcweir if (((ScFormulaCell*)pItems[i].pCell)->TestTabRefAbs(nTable))
1113cdf0e10cSrcweir bRet = sal_True;
1114cdf0e10cSrcweir return bRet;
1115cdf0e10cSrcweir }
1116cdf0e10cSrcweir
1117cdf0e10cSrcweir // =========================================================================================
1118cdf0e10cSrcweir
ScColumnIterator(const ScColumn * pCol,SCROW nStart,SCROW nEnd)1119cdf0e10cSrcweir ScColumnIterator::ScColumnIterator( const ScColumn* pCol, SCROW nStart, SCROW nEnd ) :
1120cdf0e10cSrcweir pColumn( pCol ),
1121cdf0e10cSrcweir nTop( nStart ),
1122cdf0e10cSrcweir nBottom( nEnd )
1123cdf0e10cSrcweir {
1124cdf0e10cSrcweir pColumn->Search( nTop, nPos );
1125cdf0e10cSrcweir }
1126cdf0e10cSrcweir
~ScColumnIterator()1127cdf0e10cSrcweir ScColumnIterator::~ScColumnIterator()
1128cdf0e10cSrcweir {
1129cdf0e10cSrcweir }
1130cdf0e10cSrcweir
Next(SCROW & rRow,ScBaseCell * & rpCell)1131cdf0e10cSrcweir sal_Bool ScColumnIterator::Next( SCROW& rRow, ScBaseCell*& rpCell )
1132cdf0e10cSrcweir {
1133cdf0e10cSrcweir if ( nPos < pColumn->nCount )
1134cdf0e10cSrcweir {
1135cdf0e10cSrcweir rRow = pColumn->pItems[nPos].nRow;
1136cdf0e10cSrcweir if ( rRow <= nBottom )
1137cdf0e10cSrcweir {
1138cdf0e10cSrcweir rpCell = pColumn->pItems[nPos].pCell;
1139cdf0e10cSrcweir ++nPos;
1140cdf0e10cSrcweir return sal_True;
1141cdf0e10cSrcweir }
1142cdf0e10cSrcweir }
1143cdf0e10cSrcweir
1144cdf0e10cSrcweir rRow = 0;
1145cdf0e10cSrcweir rpCell = NULL;
1146cdf0e10cSrcweir return sal_False;
1147cdf0e10cSrcweir }
1148cdf0e10cSrcweir
GetIndex() const1149cdf0e10cSrcweir SCSIZE ScColumnIterator::GetIndex() const // Index zur letzen abgefragten Zelle
1150cdf0e10cSrcweir {
1151cdf0e10cSrcweir return nPos - 1; // bei Next ist Pos hochgezaehlt worden
1152cdf0e10cSrcweir }
1153cdf0e10cSrcweir
1154cdf0e10cSrcweir // -----------------------------------------------------------------------------------------
1155cdf0e10cSrcweir
ScMarkedDataIter(const ScColumn * pCol,const ScMarkData * pMarkData,sal_Bool bAllIfNone)1156cdf0e10cSrcweir ScMarkedDataIter::ScMarkedDataIter( const ScColumn* pCol, const ScMarkData* pMarkData,
1157cdf0e10cSrcweir sal_Bool bAllIfNone ) :
1158cdf0e10cSrcweir pColumn( pCol ),
1159cdf0e10cSrcweir pMarkIter( NULL ),
1160cdf0e10cSrcweir bNext( sal_True ),
1161cdf0e10cSrcweir bAll( bAllIfNone )
1162cdf0e10cSrcweir {
1163cdf0e10cSrcweir if (pMarkData && pMarkData->IsMultiMarked())
1164cdf0e10cSrcweir pMarkIter = new ScMarkArrayIter( pMarkData->GetArray() + pCol->GetCol() );
1165cdf0e10cSrcweir }
1166cdf0e10cSrcweir
~ScMarkedDataIter()1167cdf0e10cSrcweir ScMarkedDataIter::~ScMarkedDataIter()
1168cdf0e10cSrcweir {
1169cdf0e10cSrcweir delete pMarkIter;
1170cdf0e10cSrcweir }
1171cdf0e10cSrcweir
Next(SCSIZE & rIndex)1172cdf0e10cSrcweir sal_Bool ScMarkedDataIter::Next( SCSIZE& rIndex )
1173cdf0e10cSrcweir {
1174cdf0e10cSrcweir sal_Bool bFound = sal_False;
1175cdf0e10cSrcweir do
1176cdf0e10cSrcweir {
1177cdf0e10cSrcweir if (bNext)
1178cdf0e10cSrcweir {
1179cdf0e10cSrcweir if (!pMarkIter || !pMarkIter->Next( nTop, nBottom ))
1180cdf0e10cSrcweir {
1181cdf0e10cSrcweir if (bAll) // ganze Spalte
1182cdf0e10cSrcweir {
1183cdf0e10cSrcweir nTop = 0;
1184cdf0e10cSrcweir nBottom = MAXROW;
1185cdf0e10cSrcweir }
1186cdf0e10cSrcweir else
1187cdf0e10cSrcweir return sal_False;
1188cdf0e10cSrcweir }
1189cdf0e10cSrcweir pColumn->Search( nTop, nPos );
1190cdf0e10cSrcweir bNext = sal_False;
1191cdf0e10cSrcweir bAll = sal_False; // nur beim ersten Versuch
1192cdf0e10cSrcweir }
1193cdf0e10cSrcweir
1194cdf0e10cSrcweir if ( nPos >= pColumn->nCount )
1195cdf0e10cSrcweir return sal_False;
1196cdf0e10cSrcweir
1197cdf0e10cSrcweir if ( pColumn->pItems[nPos].nRow <= nBottom )
1198cdf0e10cSrcweir bFound = sal_True;
1199cdf0e10cSrcweir else
1200cdf0e10cSrcweir bNext = sal_True;
1201cdf0e10cSrcweir }
1202cdf0e10cSrcweir while (!bFound);
1203cdf0e10cSrcweir
1204cdf0e10cSrcweir rIndex = nPos++;
1205cdf0e10cSrcweir return sal_True;
1206cdf0e10cSrcweir }
1207cdf0e10cSrcweir
1208cdf0e10cSrcweir //UNUSED2009-05 sal_uInt16 ScColumn::GetErrorData( SCROW nRow ) const
1209cdf0e10cSrcweir //UNUSED2009-05 {
1210cdf0e10cSrcweir //UNUSED2009-05 SCSIZE nIndex;
1211cdf0e10cSrcweir //UNUSED2009-05 if (Search(nRow, nIndex))
1212cdf0e10cSrcweir //UNUSED2009-05 {
1213cdf0e10cSrcweir //UNUSED2009-05 ScBaseCell* pCell = pItems[nIndex].pCell;
1214cdf0e10cSrcweir //UNUSED2009-05 switch (pCell->GetCellType())
1215cdf0e10cSrcweir //UNUSED2009-05 {
1216cdf0e10cSrcweir //UNUSED2009-05 case CELLTYPE_FORMULA :
1217cdf0e10cSrcweir //UNUSED2009-05 return ((ScFormulaCell*)pCell)->GetErrCode();
1218cdf0e10cSrcweir //UNUSED2009-05 // break;
1219cdf0e10cSrcweir //UNUSED2009-05 default:
1220cdf0e10cSrcweir //UNUSED2009-05 return 0;
1221cdf0e10cSrcweir //UNUSED2009-05 }
1222cdf0e10cSrcweir //UNUSED2009-05 }
1223cdf0e10cSrcweir //UNUSED2009-05 return 0;
1224cdf0e10cSrcweir //UNUSED2009-05 }
1225cdf0e10cSrcweir
1226cdf0e10cSrcweir //------------
1227cdf0e10cSrcweir
IsEmptyData() const1228cdf0e10cSrcweir sal_Bool ScColumn::IsEmptyData() const
1229cdf0e10cSrcweir {
1230cdf0e10cSrcweir return (nCount == 0);
1231cdf0e10cSrcweir }
1232cdf0e10cSrcweir
IsEmptyVisData(sal_Bool bNotes) const1233cdf0e10cSrcweir sal_Bool ScColumn::IsEmptyVisData(sal_Bool bNotes) const
1234cdf0e10cSrcweir {
1235cdf0e10cSrcweir if (!pItems || nCount == 0)
1236cdf0e10cSrcweir return sal_True;
1237cdf0e10cSrcweir else
1238cdf0e10cSrcweir {
1239cdf0e10cSrcweir sal_Bool bVisData = sal_False;
1240cdf0e10cSrcweir SCSIZE i;
1241cdf0e10cSrcweir for (i=0; i<nCount && !bVisData; i++)
1242cdf0e10cSrcweir {
1243cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1244cdf0e10cSrcweir if ( pCell->GetCellType() != CELLTYPE_NOTE || (bNotes && pCell->HasNote()) )
1245cdf0e10cSrcweir bVisData = sal_True;
1246cdf0e10cSrcweir }
1247cdf0e10cSrcweir return !bVisData;
1248cdf0e10cSrcweir }
1249cdf0e10cSrcweir }
1250cdf0e10cSrcweir
VisibleCount(SCROW nStartRow,SCROW nEndRow) const1251cdf0e10cSrcweir SCSIZE ScColumn::VisibleCount( SCROW nStartRow, SCROW nEndRow ) const
1252cdf0e10cSrcweir {
1253cdf0e10cSrcweir // Notizen werden nicht mitgezaehlt
1254cdf0e10cSrcweir
1255cdf0e10cSrcweir SCSIZE nVisCount = 0;
1256cdf0e10cSrcweir SCSIZE nIndex;
1257cdf0e10cSrcweir Search( nStartRow, nIndex );
1258cdf0e10cSrcweir while ( nIndex < nCount && pItems[nIndex].nRow <= nEndRow )
1259cdf0e10cSrcweir {
1260cdf0e10cSrcweir if ( pItems[nIndex].nRow >= nStartRow &&
1261cdf0e10cSrcweir pItems[nIndex].pCell->GetCellType() != CELLTYPE_NOTE )
1262cdf0e10cSrcweir {
1263cdf0e10cSrcweir ++nVisCount;
1264cdf0e10cSrcweir }
1265cdf0e10cSrcweir ++nIndex;
1266cdf0e10cSrcweir }
1267cdf0e10cSrcweir return nVisCount;
1268cdf0e10cSrcweir }
1269cdf0e10cSrcweir
GetLastVisDataPos(sal_Bool bNotes) const1270cdf0e10cSrcweir SCROW ScColumn::GetLastVisDataPos(sal_Bool bNotes) const
1271cdf0e10cSrcweir {
1272cdf0e10cSrcweir SCROW nRet = 0;
1273cdf0e10cSrcweir if (pItems)
1274cdf0e10cSrcweir {
1275cdf0e10cSrcweir SCSIZE i;
1276cdf0e10cSrcweir sal_Bool bFound = sal_False;
1277cdf0e10cSrcweir for (i=nCount; i>0 && !bFound; )
1278cdf0e10cSrcweir {
1279cdf0e10cSrcweir --i;
1280cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1281cdf0e10cSrcweir if ( pCell->GetCellType() != CELLTYPE_NOTE || (bNotes && pCell->HasNote()) )
1282cdf0e10cSrcweir {
1283cdf0e10cSrcweir bFound = sal_True;
1284cdf0e10cSrcweir nRet = pItems[i].nRow;
1285cdf0e10cSrcweir }
1286cdf0e10cSrcweir }
1287cdf0e10cSrcweir }
1288cdf0e10cSrcweir return nRet;
1289cdf0e10cSrcweir }
1290cdf0e10cSrcweir
GetFirstVisDataPos(sal_Bool bNotes) const1291cdf0e10cSrcweir SCROW ScColumn::GetFirstVisDataPos(sal_Bool bNotes) const
1292cdf0e10cSrcweir {
1293cdf0e10cSrcweir SCROW nRet = 0;
1294cdf0e10cSrcweir if (pItems)
1295cdf0e10cSrcweir {
1296cdf0e10cSrcweir SCSIZE i;
1297cdf0e10cSrcweir sal_Bool bFound = sal_False;
1298cdf0e10cSrcweir for (i=0; i<nCount && !bFound; i++)
1299cdf0e10cSrcweir {
1300cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1301cdf0e10cSrcweir if ( pCell->GetCellType() != CELLTYPE_NOTE || (bNotes && pCell->HasNote()) )
1302cdf0e10cSrcweir {
1303cdf0e10cSrcweir bFound = sal_True;
1304cdf0e10cSrcweir nRet = pItems[i].nRow;
1305cdf0e10cSrcweir }
1306cdf0e10cSrcweir }
1307cdf0e10cSrcweir }
1308cdf0e10cSrcweir return nRet;
1309cdf0e10cSrcweir }
1310cdf0e10cSrcweir
HasVisibleDataAt(SCROW nRow) const1311cdf0e10cSrcweir sal_Bool ScColumn::HasVisibleDataAt(SCROW nRow) const
1312cdf0e10cSrcweir {
1313cdf0e10cSrcweir SCSIZE nIndex;
1314cdf0e10cSrcweir if (Search(nRow, nIndex))
1315cdf0e10cSrcweir if (!pItems[nIndex].pCell->IsBlank())
1316cdf0e10cSrcweir return sal_True;
1317cdf0e10cSrcweir
1318cdf0e10cSrcweir return sal_False;
1319cdf0e10cSrcweir }
1320cdf0e10cSrcweir
IsEmptyAttr() const1321cdf0e10cSrcweir sal_Bool ScColumn::IsEmptyAttr() const
1322cdf0e10cSrcweir {
1323cdf0e10cSrcweir if (pAttrArray)
1324cdf0e10cSrcweir return pAttrArray->IsEmpty();
1325cdf0e10cSrcweir else
1326cdf0e10cSrcweir return sal_True;
1327cdf0e10cSrcweir }
1328cdf0e10cSrcweir
IsEmpty() const1329cdf0e10cSrcweir sal_Bool ScColumn::IsEmpty() const
1330cdf0e10cSrcweir {
1331cdf0e10cSrcweir return (IsEmptyData() && IsEmptyAttr());
1332cdf0e10cSrcweir }
1333cdf0e10cSrcweir
IsEmptyBlock(SCROW nStartRow,SCROW nEndRow,bool bIgnoreNotes) const1334cdf0e10cSrcweir sal_Bool ScColumn::IsEmptyBlock(SCROW nStartRow, SCROW nEndRow, bool bIgnoreNotes) const
1335cdf0e10cSrcweir {
1336cdf0e10cSrcweir if ( nCount == 0 || !pItems )
1337cdf0e10cSrcweir return sal_True;
1338cdf0e10cSrcweir
1339cdf0e10cSrcweir SCSIZE nIndex;
1340cdf0e10cSrcweir Search( nStartRow, nIndex );
1341cdf0e10cSrcweir while ( nIndex < nCount && pItems[nIndex].nRow <= nEndRow )
1342cdf0e10cSrcweir {
1343cdf0e10cSrcweir if ( !pItems[nIndex].pCell->IsBlank( bIgnoreNotes ) ) // found a cell
1344cdf0e10cSrcweir return sal_False; // not empty
1345cdf0e10cSrcweir ++nIndex;
1346cdf0e10cSrcweir }
1347cdf0e10cSrcweir return sal_True; // no cell found
1348cdf0e10cSrcweir }
1349cdf0e10cSrcweir
GetEmptyLinesInBlock(SCROW nStartRow,SCROW nEndRow,ScDirection eDir) const1350cdf0e10cSrcweir SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const
1351cdf0e10cSrcweir {
1352cdf0e10cSrcweir SCSIZE nLines = 0;
1353cdf0e10cSrcweir sal_Bool bFound = sal_False;
1354cdf0e10cSrcweir SCSIZE i;
1355cdf0e10cSrcweir if (pItems && (nCount > 0))
1356cdf0e10cSrcweir {
1357cdf0e10cSrcweir if (eDir == DIR_BOTTOM)
1358cdf0e10cSrcweir {
1359cdf0e10cSrcweir i = nCount;
1360cdf0e10cSrcweir while (!bFound && (i > 0))
1361cdf0e10cSrcweir {
1362cdf0e10cSrcweir i--;
1363cdf0e10cSrcweir if ( pItems[i].nRow < nStartRow )
1364cdf0e10cSrcweir break;
1365cdf0e10cSrcweir bFound = pItems[i].nRow <= nEndRow && !pItems[i].pCell->IsBlank();
1366cdf0e10cSrcweir }
1367cdf0e10cSrcweir if (bFound)
1368cdf0e10cSrcweir nLines = static_cast<SCSIZE>(nEndRow - pItems[i].nRow);
1369cdf0e10cSrcweir else
1370cdf0e10cSrcweir nLines = static_cast<SCSIZE>(nEndRow - nStartRow);
1371cdf0e10cSrcweir }
1372cdf0e10cSrcweir else if (eDir == DIR_TOP)
1373cdf0e10cSrcweir {
1374cdf0e10cSrcweir i = 0;
1375cdf0e10cSrcweir while (!bFound && (i < nCount))
1376cdf0e10cSrcweir {
1377cdf0e10cSrcweir if ( pItems[i].nRow > nEndRow )
1378cdf0e10cSrcweir break;
1379cdf0e10cSrcweir bFound = pItems[i].nRow >= nStartRow && !pItems[i].pCell->IsBlank();
1380cdf0e10cSrcweir i++;
1381cdf0e10cSrcweir }
1382cdf0e10cSrcweir if (bFound)
1383cdf0e10cSrcweir nLines = static_cast<SCSIZE>(pItems[i-1].nRow - nStartRow);
1384cdf0e10cSrcweir else
1385cdf0e10cSrcweir nLines = static_cast<SCSIZE>(nEndRow - nStartRow);
1386cdf0e10cSrcweir }
1387cdf0e10cSrcweir }
1388cdf0e10cSrcweir else
1389cdf0e10cSrcweir nLines = static_cast<SCSIZE>(nEndRow - nStartRow);
1390cdf0e10cSrcweir return nLines;
1391cdf0e10cSrcweir }
1392cdf0e10cSrcweir
GetFirstDataPos() const1393cdf0e10cSrcweir SCROW ScColumn::GetFirstDataPos() const
1394cdf0e10cSrcweir {
1395cdf0e10cSrcweir if (nCount)
1396cdf0e10cSrcweir return pItems[0].nRow;
1397cdf0e10cSrcweir else
1398cdf0e10cSrcweir return 0;
1399cdf0e10cSrcweir }
1400cdf0e10cSrcweir
GetLastDataPos() const1401cdf0e10cSrcweir SCROW ScColumn::GetLastDataPos() const
1402cdf0e10cSrcweir {
1403cdf0e10cSrcweir if (nCount)
1404cdf0e10cSrcweir return pItems[nCount-1].nRow;
1405cdf0e10cSrcweir else
1406cdf0e10cSrcweir return 0;
1407cdf0e10cSrcweir }
1408cdf0e10cSrcweir
GetPrevDataPos(SCROW & rRow) const1409cdf0e10cSrcweir sal_Bool ScColumn::GetPrevDataPos(SCROW& rRow) const
1410cdf0e10cSrcweir {
1411cdf0e10cSrcweir sal_Bool bFound = sal_False;
1412cdf0e10cSrcweir SCSIZE i = nCount;
1413cdf0e10cSrcweir while (!bFound && (i > 0))
1414cdf0e10cSrcweir {
1415cdf0e10cSrcweir --i;
1416cdf0e10cSrcweir bFound = (pItems[i].nRow < rRow);
1417cdf0e10cSrcweir if (bFound)
1418cdf0e10cSrcweir rRow = pItems[i].nRow;
1419cdf0e10cSrcweir }
1420cdf0e10cSrcweir return bFound;
1421cdf0e10cSrcweir }
1422cdf0e10cSrcweir
GetNextDataPos(SCROW & rRow) const1423cdf0e10cSrcweir sal_Bool ScColumn::GetNextDataPos(SCROW& rRow) const // greater than rRow
1424cdf0e10cSrcweir {
1425cdf0e10cSrcweir SCSIZE nIndex;
1426cdf0e10cSrcweir if (Search( rRow, nIndex ))
1427cdf0e10cSrcweir ++nIndex; // next cell
1428cdf0e10cSrcweir
1429cdf0e10cSrcweir sal_Bool bMore = ( nIndex < nCount );
1430cdf0e10cSrcweir if ( bMore )
1431cdf0e10cSrcweir rRow = pItems[nIndex].nRow;
1432cdf0e10cSrcweir return bMore;
1433cdf0e10cSrcweir }
1434cdf0e10cSrcweir
FindDataAreaPos(SCROW & rRow,long nMovY) const1435cdf0e10cSrcweir void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const
1436cdf0e10cSrcweir {
1437cdf0e10cSrcweir if (!nMovY) return;
1438cdf0e10cSrcweir sal_Bool bForward = (nMovY>0);
1439cdf0e10cSrcweir
1440cdf0e10cSrcweir SCSIZE nIndex;
1441cdf0e10cSrcweir sal_Bool bThere = Search(rRow, nIndex);
1442cdf0e10cSrcweir if (bThere && pItems[nIndex].pCell->IsBlank())
1443cdf0e10cSrcweir bThere = sal_False;
1444cdf0e10cSrcweir
1445cdf0e10cSrcweir if (bThere)
1446cdf0e10cSrcweir {
1447cdf0e10cSrcweir SCROW nLast = rRow;
1448cdf0e10cSrcweir SCSIZE nOldIndex = nIndex;
1449cdf0e10cSrcweir if (bForward)
1450cdf0e10cSrcweir {
1451cdf0e10cSrcweir if (nIndex<nCount-1)
1452cdf0e10cSrcweir {
1453cdf0e10cSrcweir ++nIndex;
1454cdf0e10cSrcweir while (nIndex<nCount-1 && pItems[nIndex].nRow==nLast+1
1455cdf0e10cSrcweir && !pItems[nIndex].pCell->IsBlank())
1456cdf0e10cSrcweir {
1457cdf0e10cSrcweir ++nIndex;
1458cdf0e10cSrcweir ++nLast;
1459cdf0e10cSrcweir }
1460cdf0e10cSrcweir if (nIndex==nCount-1)
1461cdf0e10cSrcweir if (pItems[nIndex].nRow==nLast+1 && !pItems[nIndex].pCell->IsBlank())
1462cdf0e10cSrcweir ++nLast;
1463cdf0e10cSrcweir }
1464cdf0e10cSrcweir }
1465cdf0e10cSrcweir else
1466cdf0e10cSrcweir {
1467cdf0e10cSrcweir if (nIndex>0)
1468cdf0e10cSrcweir {
1469cdf0e10cSrcweir --nIndex;
1470cdf0e10cSrcweir while (nIndex>0 && pItems[nIndex].nRow+1==nLast
1471cdf0e10cSrcweir && !pItems[nIndex].pCell->IsBlank())
1472cdf0e10cSrcweir {
1473cdf0e10cSrcweir --nIndex;
1474cdf0e10cSrcweir --nLast;
1475cdf0e10cSrcweir }
1476cdf0e10cSrcweir if (nIndex==0)
1477cdf0e10cSrcweir if (pItems[nIndex].nRow+1==nLast && !pItems[nIndex].pCell->IsBlank())
1478cdf0e10cSrcweir --nLast;
1479cdf0e10cSrcweir }
1480cdf0e10cSrcweir }
1481cdf0e10cSrcweir if (nLast==rRow)
1482cdf0e10cSrcweir {
1483cdf0e10cSrcweir bThere = sal_False;
1484cdf0e10cSrcweir nIndex = bForward ? nOldIndex+1 : nOldIndex;
1485cdf0e10cSrcweir }
1486cdf0e10cSrcweir else
1487cdf0e10cSrcweir rRow = nLast;
1488cdf0e10cSrcweir }
1489cdf0e10cSrcweir
1490cdf0e10cSrcweir if (!bThere)
1491cdf0e10cSrcweir {
1492cdf0e10cSrcweir if (bForward)
1493cdf0e10cSrcweir {
1494cdf0e10cSrcweir while (nIndex<nCount && pItems[nIndex].pCell->IsBlank())
1495cdf0e10cSrcweir ++nIndex;
1496cdf0e10cSrcweir if (nIndex<nCount)
1497cdf0e10cSrcweir rRow = pItems[nIndex].nRow;
1498cdf0e10cSrcweir else
1499cdf0e10cSrcweir rRow = MAXROW;
1500cdf0e10cSrcweir }
1501cdf0e10cSrcweir else
1502cdf0e10cSrcweir {
1503cdf0e10cSrcweir while (nIndex>0 && pItems[nIndex-1].pCell->IsBlank())
1504cdf0e10cSrcweir --nIndex;
1505cdf0e10cSrcweir if (nIndex>0)
1506cdf0e10cSrcweir rRow = pItems[nIndex-1].nRow;
1507cdf0e10cSrcweir else
1508cdf0e10cSrcweir rRow = 0;
1509cdf0e10cSrcweir }
1510cdf0e10cSrcweir }
1511cdf0e10cSrcweir }
1512cdf0e10cSrcweir
HasDataAt(SCROW nRow) const1513cdf0e10cSrcweir sal_Bool ScColumn::HasDataAt(SCROW nRow) const
1514cdf0e10cSrcweir {
1515cdf0e10cSrcweir /* SCSIZE nIndex;
1516cdf0e10cSrcweir return Search( nRow, nIndex );
1517cdf0e10cSrcweir */
1518cdf0e10cSrcweir // immer nur sichtbare interessant ?
1519cdf0e10cSrcweir //! dann HasVisibleDataAt raus
1520cdf0e10cSrcweir
1521cdf0e10cSrcweir SCSIZE nIndex;
1522cdf0e10cSrcweir if (Search(nRow, nIndex))
1523cdf0e10cSrcweir if (!pItems[nIndex].pCell->IsBlank())
1524cdf0e10cSrcweir return sal_True;
1525cdf0e10cSrcweir
1526cdf0e10cSrcweir return sal_False;
1527cdf0e10cSrcweir
1528cdf0e10cSrcweir }
1529cdf0e10cSrcweir
IsAllAttrEqual(const ScColumn & rCol,SCROW nStartRow,SCROW nEndRow) const1530cdf0e10cSrcweir sal_Bool ScColumn::IsAllAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const
1531cdf0e10cSrcweir {
1532cdf0e10cSrcweir if (pAttrArray && rCol.pAttrArray)
1533cdf0e10cSrcweir return pAttrArray->IsAllEqual( *rCol.pAttrArray, nStartRow, nEndRow );
1534cdf0e10cSrcweir else
1535cdf0e10cSrcweir return !pAttrArray && !rCol.pAttrArray;
1536cdf0e10cSrcweir }
1537cdf0e10cSrcweir
IsVisibleAttrEqual(const ScColumn & rCol,SCROW nStartRow,SCROW nEndRow) const1538cdf0e10cSrcweir sal_Bool ScColumn::IsVisibleAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const
1539cdf0e10cSrcweir {
1540cdf0e10cSrcweir if (pAttrArray && rCol.pAttrArray)
1541cdf0e10cSrcweir return pAttrArray->IsVisibleEqual( *rCol.pAttrArray, nStartRow, nEndRow );
1542cdf0e10cSrcweir else
1543cdf0e10cSrcweir return !pAttrArray && !rCol.pAttrArray;
1544cdf0e10cSrcweir }
1545cdf0e10cSrcweir
GetFirstVisibleAttr(SCROW & rFirstRow) const1546cdf0e10cSrcweir sal_Bool ScColumn::GetFirstVisibleAttr( SCROW& rFirstRow ) const
1547cdf0e10cSrcweir {
1548cdf0e10cSrcweir if (pAttrArray)
1549cdf0e10cSrcweir return pAttrArray->GetFirstVisibleAttr( rFirstRow );
1550cdf0e10cSrcweir else
1551cdf0e10cSrcweir return sal_False;
1552cdf0e10cSrcweir }
1553cdf0e10cSrcweir
GetLastVisibleAttr(SCROW & rLastRow) const1554cdf0e10cSrcweir sal_Bool ScColumn::GetLastVisibleAttr( SCROW& rLastRow ) const
1555cdf0e10cSrcweir {
1556cdf0e10cSrcweir if (pAttrArray)
1557cdf0e10cSrcweir {
1558cdf0e10cSrcweir // row of last cell is needed
1559cdf0e10cSrcweir SCROW nLastData = GetLastVisDataPos( sal_True ); // always including notes, 0 if none
1560cdf0e10cSrcweir
1561cdf0e10cSrcweir return pAttrArray->GetLastVisibleAttr( rLastRow, nLastData );
1562cdf0e10cSrcweir }
1563cdf0e10cSrcweir else
1564cdf0e10cSrcweir return sal_False;
1565cdf0e10cSrcweir }
1566cdf0e10cSrcweir
GetLastAttr(SCROW & rLastRow) const1567557cb412SWang Lei sal_Bool ScColumn::GetLastAttr( SCROW& rLastRow ) const
1568557cb412SWang Lei {
1569557cb412SWang Lei if ( pAttrArray )
1570557cb412SWang Lei {
1571557cb412SWang Lei // Row of last cell is needed, always including notes, 0 if none.
1572557cb412SWang Lei SCROW nLastData = GetLastVisDataPos( sal_True );
1573557cb412SWang Lei return pAttrArray->GetLastAttr( rLastRow, nLastData );
1574557cb412SWang Lei }
1575557cb412SWang Lei else
1576557cb412SWang Lei {
1577557cb412SWang Lei return sal_False;
1578557cb412SWang Lei }
1579557cb412SWang Lei }
HasVisibleAttrIn(SCROW nStartRow,SCROW nEndRow) const1580cdf0e10cSrcweir sal_Bool ScColumn::HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const
1581cdf0e10cSrcweir {
1582cdf0e10cSrcweir if (pAttrArray)
1583cdf0e10cSrcweir return pAttrArray->HasVisibleAttrIn( nStartRow, nEndRow );
1584cdf0e10cSrcweir else
1585cdf0e10cSrcweir return sal_False;
1586cdf0e10cSrcweir }
1587cdf0e10cSrcweir
FindUsed(SCROW nStartRow,SCROW nEndRow,sal_Bool * pUsed) const1588cdf0e10cSrcweir void ScColumn::FindUsed( SCROW nStartRow, SCROW nEndRow, sal_Bool* pUsed ) const
1589cdf0e10cSrcweir {
1590cdf0e10cSrcweir SCROW nRow = 0;
1591cdf0e10cSrcweir SCSIZE nIndex;
1592cdf0e10cSrcweir Search( nStartRow, nIndex );
1593cdf0e10cSrcweir while ( (nIndex < nCount) ? ((nRow=pItems[nIndex].nRow) <= nEndRow) : sal_False )
1594cdf0e10cSrcweir {
1595cdf0e10cSrcweir pUsed[nRow-nStartRow] = sal_True;
1596cdf0e10cSrcweir ++nIndex;
1597cdf0e10cSrcweir }
1598cdf0e10cSrcweir }
1599cdf0e10cSrcweir
StartListening(SvtListener & rLst,SCROW nRow)1600cdf0e10cSrcweir void ScColumn::StartListening( SvtListener& rLst, SCROW nRow )
1601cdf0e10cSrcweir {
1602cdf0e10cSrcweir SvtBroadcaster* pBC = NULL;
1603cdf0e10cSrcweir ScBaseCell* pCell;
1604cdf0e10cSrcweir
1605cdf0e10cSrcweir SCSIZE nIndex;
1606cdf0e10cSrcweir if (Search(nRow,nIndex))
1607cdf0e10cSrcweir {
1608cdf0e10cSrcweir pCell = pItems[nIndex].pCell;
1609cdf0e10cSrcweir pBC = pCell->GetBroadcaster();
1610cdf0e10cSrcweir }
1611cdf0e10cSrcweir else
1612cdf0e10cSrcweir {
1613cdf0e10cSrcweir pCell = new ScNoteCell;
1614cdf0e10cSrcweir Insert(nRow, pCell);
1615cdf0e10cSrcweir }
1616cdf0e10cSrcweir
1617cdf0e10cSrcweir if (!pBC)
1618cdf0e10cSrcweir {
1619cdf0e10cSrcweir pBC = new SvtBroadcaster;
1620cdf0e10cSrcweir pCell->TakeBroadcaster(pBC);
1621cdf0e10cSrcweir }
1622cdf0e10cSrcweir rLst.StartListening(*pBC);
1623cdf0e10cSrcweir }
1624cdf0e10cSrcweir
MoveListeners(SvtBroadcaster & rSource,SCROW nDestRow)1625cdf0e10cSrcweir void ScColumn::MoveListeners( SvtBroadcaster& rSource, SCROW nDestRow )
1626cdf0e10cSrcweir {
1627cdf0e10cSrcweir SvtBroadcaster* pBC = NULL;
1628cdf0e10cSrcweir ScBaseCell* pCell;
1629cdf0e10cSrcweir
1630cdf0e10cSrcweir SCSIZE nIndex;
1631cdf0e10cSrcweir if (Search(nDestRow,nIndex))
1632cdf0e10cSrcweir {
1633cdf0e10cSrcweir pCell = pItems[nIndex].pCell;
1634cdf0e10cSrcweir pBC = pCell->GetBroadcaster();
1635cdf0e10cSrcweir }
1636cdf0e10cSrcweir else
1637cdf0e10cSrcweir {
1638cdf0e10cSrcweir pCell = new ScNoteCell;
1639cdf0e10cSrcweir Insert(nDestRow, pCell);
1640cdf0e10cSrcweir }
1641cdf0e10cSrcweir
1642cdf0e10cSrcweir if (!pBC)
1643cdf0e10cSrcweir {
1644cdf0e10cSrcweir pBC = new SvtBroadcaster;
1645cdf0e10cSrcweir pCell->TakeBroadcaster(pBC);
1646cdf0e10cSrcweir }
1647cdf0e10cSrcweir
1648cdf0e10cSrcweir if (rSource.HasListeners())
1649cdf0e10cSrcweir {
1650cdf0e10cSrcweir SvtListenerIter aIter( rSource);
1651cdf0e10cSrcweir for (SvtListener* pLst = aIter.GoStart(); pLst; pLst = aIter.GoNext())
1652cdf0e10cSrcweir {
1653cdf0e10cSrcweir pLst->StartListening( *pBC);
1654cdf0e10cSrcweir pLst->EndListening( rSource);
1655cdf0e10cSrcweir }
1656cdf0e10cSrcweir }
1657cdf0e10cSrcweir }
1658cdf0e10cSrcweir
EndListening(SvtListener & rLst,SCROW nRow)1659cdf0e10cSrcweir void ScColumn::EndListening( SvtListener& rLst, SCROW nRow )
1660cdf0e10cSrcweir {
1661cdf0e10cSrcweir SCSIZE nIndex;
1662cdf0e10cSrcweir if (Search(nRow,nIndex))
1663cdf0e10cSrcweir {
1664cdf0e10cSrcweir ScBaseCell* pCell = pItems[nIndex].pCell;
1665cdf0e10cSrcweir SvtBroadcaster* pBC = pCell->GetBroadcaster();
1666cdf0e10cSrcweir if (pBC)
1667cdf0e10cSrcweir {
1668cdf0e10cSrcweir rLst.EndListening(*pBC);
1669cdf0e10cSrcweir
1670cdf0e10cSrcweir if (!pBC->HasListeners())
1671cdf0e10cSrcweir {
1672cdf0e10cSrcweir if (pCell->IsBlank())
1673cdf0e10cSrcweir DeleteAtIndex(nIndex);
1674cdf0e10cSrcweir else
1675cdf0e10cSrcweir pCell->DeleteBroadcaster();
1676cdf0e10cSrcweir }
1677cdf0e10cSrcweir }
1678cdf0e10cSrcweir // else
1679cdf0e10cSrcweir // DBG_ERROR("ScColumn::EndListening - kein Broadcaster");
1680cdf0e10cSrcweir }
1681cdf0e10cSrcweir // else
1682cdf0e10cSrcweir // DBG_ERROR("ScColumn::EndListening - keine Zelle");
1683cdf0e10cSrcweir }
1684cdf0e10cSrcweir
CompileDBFormula()1685cdf0e10cSrcweir void ScColumn::CompileDBFormula()
1686cdf0e10cSrcweir {
1687cdf0e10cSrcweir if (pItems)
1688cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1689cdf0e10cSrcweir {
1690cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1691cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
1692cdf0e10cSrcweir ((ScFormulaCell*) pCell)->CompileDBFormula();
1693cdf0e10cSrcweir }
1694cdf0e10cSrcweir }
1695cdf0e10cSrcweir
CompileDBFormula(sal_Bool bCreateFormulaString)1696cdf0e10cSrcweir void ScColumn::CompileDBFormula( sal_Bool bCreateFormulaString )
1697cdf0e10cSrcweir {
1698cdf0e10cSrcweir if (pItems)
1699cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1700cdf0e10cSrcweir {
1701cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1702cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
1703cdf0e10cSrcweir ((ScFormulaCell*) pCell)->CompileDBFormula( bCreateFormulaString );
1704cdf0e10cSrcweir }
1705cdf0e10cSrcweir }
1706cdf0e10cSrcweir
CompileNameFormula(sal_Bool bCreateFormulaString)1707cdf0e10cSrcweir void ScColumn::CompileNameFormula( sal_Bool bCreateFormulaString )
1708cdf0e10cSrcweir {
1709cdf0e10cSrcweir if (pItems)
1710cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1711cdf0e10cSrcweir {
1712cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1713cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
1714cdf0e10cSrcweir ((ScFormulaCell*) pCell)->CompileNameFormula( bCreateFormulaString );
1715cdf0e10cSrcweir }
1716cdf0e10cSrcweir }
1717cdf0e10cSrcweir
CompileColRowNameFormula()1718cdf0e10cSrcweir void ScColumn::CompileColRowNameFormula()
1719cdf0e10cSrcweir {
1720cdf0e10cSrcweir if (pItems)
1721cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; i++)
1722cdf0e10cSrcweir {
1723cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1724cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
1725cdf0e10cSrcweir ((ScFormulaCell*) pCell)->CompileColRowNameFormula();
1726cdf0e10cSrcweir }
1727cdf0e10cSrcweir }
1728cdf0e10cSrcweir
lcl_UpdateSubTotal(ScFunctionData & rData,ScBaseCell * pCell)1729cdf0e10cSrcweir void lcl_UpdateSubTotal( ScFunctionData& rData, ScBaseCell* pCell )
1730cdf0e10cSrcweir {
1731cdf0e10cSrcweir double nValue = 0.0;
1732cdf0e10cSrcweir sal_Bool bVal = sal_False;
1733cdf0e10cSrcweir sal_Bool bCell = sal_True;
1734cdf0e10cSrcweir switch (pCell->GetCellType())
1735cdf0e10cSrcweir {
1736cdf0e10cSrcweir case CELLTYPE_VALUE:
1737cdf0e10cSrcweir nValue = ((ScValueCell*)pCell)->GetValue();
1738cdf0e10cSrcweir bVal = sal_True;
1739cdf0e10cSrcweir break;
1740cdf0e10cSrcweir case CELLTYPE_FORMULA:
1741cdf0e10cSrcweir {
1742cdf0e10cSrcweir if ( rData.eFunc != SUBTOTAL_FUNC_CNT2 ) // da interessiert's nicht
1743cdf0e10cSrcweir {
1744cdf0e10cSrcweir ScFormulaCell* pFC = (ScFormulaCell*)pCell;
1745cdf0e10cSrcweir if ( pFC->GetErrCode() )
1746cdf0e10cSrcweir {
1747cdf0e10cSrcweir if ( rData.eFunc != SUBTOTAL_FUNC_CNT ) // fuer Anzahl einfach weglassen
1748cdf0e10cSrcweir rData.bError = sal_True;
1749cdf0e10cSrcweir }
1750cdf0e10cSrcweir else if (pFC->IsValue())
1751cdf0e10cSrcweir {
1752cdf0e10cSrcweir nValue = pFC->GetValue();
1753cdf0e10cSrcweir bVal = sal_True;
1754cdf0e10cSrcweir }
1755cdf0e10cSrcweir // sonst Text
1756cdf0e10cSrcweir }
1757cdf0e10cSrcweir }
1758cdf0e10cSrcweir break;
1759cdf0e10cSrcweir case CELLTYPE_NOTE:
1760cdf0e10cSrcweir bCell = sal_False;
1761cdf0e10cSrcweir break;
1762cdf0e10cSrcweir // bei Strings nichts
1763cdf0e10cSrcweir default:
1764cdf0e10cSrcweir {
1765cdf0e10cSrcweir // added to avoid warnings
1766cdf0e10cSrcweir }
1767cdf0e10cSrcweir }
1768cdf0e10cSrcweir
1769cdf0e10cSrcweir if (!rData.bError)
1770cdf0e10cSrcweir {
1771cdf0e10cSrcweir switch (rData.eFunc)
1772cdf0e10cSrcweir {
1773cdf0e10cSrcweir case SUBTOTAL_FUNC_SUM:
1774cdf0e10cSrcweir case SUBTOTAL_FUNC_AVE:
1775cdf0e10cSrcweir if (bVal)
1776cdf0e10cSrcweir {
1777cdf0e10cSrcweir ++rData.nCount;
1778cdf0e10cSrcweir if (!SubTotal::SafePlus( rData.nVal, nValue ))
1779cdf0e10cSrcweir rData.bError = sal_True;
1780cdf0e10cSrcweir }
1781cdf0e10cSrcweir break;
1782cdf0e10cSrcweir case SUBTOTAL_FUNC_CNT: // nur Werte
1783cdf0e10cSrcweir if (bVal)
1784cdf0e10cSrcweir ++rData.nCount;
1785cdf0e10cSrcweir break;
1786cdf0e10cSrcweir case SUBTOTAL_FUNC_CNT2: // alle
1787cdf0e10cSrcweir if (bCell)
1788cdf0e10cSrcweir ++rData.nCount;
1789cdf0e10cSrcweir break;
1790cdf0e10cSrcweir case SUBTOTAL_FUNC_MAX:
1791cdf0e10cSrcweir if (bVal)
1792cdf0e10cSrcweir if (++rData.nCount == 1 || nValue > rData.nVal )
1793cdf0e10cSrcweir rData.nVal = nValue;
1794cdf0e10cSrcweir break;
1795cdf0e10cSrcweir case SUBTOTAL_FUNC_MIN:
1796cdf0e10cSrcweir if (bVal)
1797cdf0e10cSrcweir if (++rData.nCount == 1 || nValue < rData.nVal )
1798cdf0e10cSrcweir rData.nVal = nValue;
1799cdf0e10cSrcweir break;
1800cdf0e10cSrcweir default:
1801cdf0e10cSrcweir {
1802cdf0e10cSrcweir // added to avoid warnings
1803cdf0e10cSrcweir }
1804cdf0e10cSrcweir }
1805cdf0e10cSrcweir }
1806cdf0e10cSrcweir }
1807cdf0e10cSrcweir
1808cdf0e10cSrcweir // Mehrfachselektion:
UpdateSelectionFunction(const ScMarkData & rMark,ScFunctionData & rData,ScFlatBoolRowSegments & rHiddenRows,sal_Bool bDoExclude,SCROW nExStartRow,SCROW nExEndRow)1809cdf0e10cSrcweir void ScColumn::UpdateSelectionFunction( const ScMarkData& rMark,
1810cdf0e10cSrcweir ScFunctionData& rData,
1811cdf0e10cSrcweir ScFlatBoolRowSegments& rHiddenRows,
1812cdf0e10cSrcweir sal_Bool bDoExclude, SCROW nExStartRow, SCROW nExEndRow )
1813cdf0e10cSrcweir {
1814cdf0e10cSrcweir SCSIZE nIndex;
1815cdf0e10cSrcweir ScMarkedDataIter aDataIter(this, &rMark, sal_False);
1816cdf0e10cSrcweir while (aDataIter.Next( nIndex ))
1817cdf0e10cSrcweir {
1818cdf0e10cSrcweir SCROW nRow = pItems[nIndex].nRow;
1819cdf0e10cSrcweir bool bRowHidden = rHiddenRows.getValue(nRow);
1820cdf0e10cSrcweir if ( !bRowHidden )
1821cdf0e10cSrcweir if ( !bDoExclude || nRow < nExStartRow || nRow > nExEndRow )
1822cdf0e10cSrcweir lcl_UpdateSubTotal( rData, pItems[nIndex].pCell );
1823cdf0e10cSrcweir }
1824cdf0e10cSrcweir }
1825cdf0e10cSrcweir
1826cdf0e10cSrcweir // bei bNoMarked die Mehrfachselektion weglassen
UpdateAreaFunction(ScFunctionData & rData,ScFlatBoolRowSegments & rHiddenRows,SCROW nStartRow,SCROW nEndRow)1827cdf0e10cSrcweir void ScColumn::UpdateAreaFunction( ScFunctionData& rData,
1828cdf0e10cSrcweir ScFlatBoolRowSegments& rHiddenRows,
1829cdf0e10cSrcweir SCROW nStartRow, SCROW nEndRow )
1830cdf0e10cSrcweir {
1831cdf0e10cSrcweir SCSIZE nIndex;
1832cdf0e10cSrcweir Search( nStartRow, nIndex );
1833cdf0e10cSrcweir while ( nIndex<nCount && pItems[nIndex].nRow<=nEndRow )
1834cdf0e10cSrcweir {
1835cdf0e10cSrcweir SCROW nRow = pItems[nIndex].nRow;
1836cdf0e10cSrcweir bool bRowHidden = rHiddenRows.getValue(nRow);
1837cdf0e10cSrcweir if ( !bRowHidden )
1838cdf0e10cSrcweir lcl_UpdateSubTotal( rData, pItems[nIndex].pCell );
1839cdf0e10cSrcweir ++nIndex;
1840cdf0e10cSrcweir }
1841cdf0e10cSrcweir }
1842cdf0e10cSrcweir
GetWeightedCount() const1843cdf0e10cSrcweir sal_uLong ScColumn::GetWeightedCount() const
1844cdf0e10cSrcweir {
1845cdf0e10cSrcweir sal_uLong nTotal = 0;
1846cdf0e10cSrcweir
1847cdf0e10cSrcweir // Notizen werden nicht gezaehlt
1848cdf0e10cSrcweir
1849cdf0e10cSrcweir for (SCSIZE i=0; i<nCount; i++)
1850cdf0e10cSrcweir {
1851cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1852cdf0e10cSrcweir switch ( pCell->GetCellType() )
1853cdf0e10cSrcweir {
1854cdf0e10cSrcweir case CELLTYPE_VALUE:
1855cdf0e10cSrcweir case CELLTYPE_STRING:
1856cdf0e10cSrcweir ++nTotal;
1857cdf0e10cSrcweir break;
1858cdf0e10cSrcweir case CELLTYPE_FORMULA:
1859cdf0e10cSrcweir nTotal += 5 + ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen();
1860cdf0e10cSrcweir break;
1861cdf0e10cSrcweir case CELLTYPE_EDIT:
1862cdf0e10cSrcweir nTotal += 50;
1863cdf0e10cSrcweir break;
1864cdf0e10cSrcweir default:
1865cdf0e10cSrcweir {
1866cdf0e10cSrcweir // added to avoid warnings
1867cdf0e10cSrcweir }
1868cdf0e10cSrcweir }
1869cdf0e10cSrcweir }
1870cdf0e10cSrcweir
1871cdf0e10cSrcweir return nTotal;
1872cdf0e10cSrcweir }
1873cdf0e10cSrcweir
GetCodeCount() const1874cdf0e10cSrcweir sal_uLong ScColumn::GetCodeCount() const
1875cdf0e10cSrcweir {
1876cdf0e10cSrcweir sal_uLong nCodeCount = 0;
1877cdf0e10cSrcweir
1878cdf0e10cSrcweir for (SCSIZE i=0; i<nCount; i++)
1879cdf0e10cSrcweir {
1880cdf0e10cSrcweir ScBaseCell* pCell = pItems[i].pCell;
1881cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_FORMULA )
1882cdf0e10cSrcweir nCodeCount += ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen();
1883cdf0e10cSrcweir }
1884cdf0e10cSrcweir
1885cdf0e10cSrcweir return nCodeCount;
1886cdf0e10cSrcweir }
1887cdf0e10cSrcweir
GetPatternCount()1888*8f4c7c28SSteve Yin SCSIZE ScColumn::GetPatternCount()
1889*8f4c7c28SSteve Yin {
1890*8f4c7c28SSteve Yin return this->pAttrArray ? this->pAttrArray->Count() : 0;
1891*8f4c7c28SSteve Yin }
1892cdf0e10cSrcweir
GetPatternCount(SCROW nRw1,SCROW nRw2)1893*8f4c7c28SSteve Yin SCSIZE ScColumn::GetPatternCount( SCROW nRw1, SCROW nRw2 )
1894*8f4c7c28SSteve Yin {
1895*8f4c7c28SSteve Yin return this->pAttrArray ? this->pAttrArray->Count( nRw1, nRw2 ) : 0;
1896*8f4c7c28SSteve Yin }
1897cdf0e10cSrcweir
ReservedPatternCount(SCSIZE nReserved)1898*8f4c7c28SSteve Yin bool ScColumn::ReservedPatternCount( SCSIZE nReserved )
1899*8f4c7c28SSteve Yin {
1900*8f4c7c28SSteve Yin return this->pAttrArray ? this->pAttrArray->Reserve( nReserved ) : false;
1901*8f4c7c28SSteve Yin }
1902