summaryrefslogtreecommitdiff
path: root/sc/source/core/data/table4.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/data/table4.cxx')
-rw-r--r--sc/source/core/data/table4.cxx1982
1 files changed, 1982 insertions, 0 deletions
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
new file mode 100644
index 000000000000..edba012fadd1
--- /dev/null
+++ b/sc/source/core/data/table4.cxx
@@ -0,0 +1,1982 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+ // sonst Absturz Win beim Fuellen
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/keycodes.hxx>
+#include <rtl/math.hxx>
+#include <unotools/charclass.hxx>
+
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+#include "table.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "document.hxx"
+#include "autoform.hxx"
+#include "userlist.hxx"
+#include "zforauto.hxx"
+#include "subtotal.hxx"
+#include "formula/errorcodes.hxx"
+#include "rangenam.hxx"
+#include "docpool.hxx"
+#include "progress.hxx"
+#include "segmenttree.hxx"
+
+#include <math.h>
+
+// STATIC DATA -----------------------------------------------------------
+
+#define _D_MAX_LONG_ (double) 0x7fffffff
+
+extern sal_uInt16 nScFillModeMouseModifier; // global.cxx
+
+// -----------------------------------------------------------------------
+
+short lcl_DecompValueString( String& aValue, sal_Int32& nVal, sal_uInt16* pMinDigits = NULL )
+{
+ if ( !aValue.Len() )
+ {
+ nVal = 0;
+ return 0;
+ }
+ const sal_Unicode* p = aValue.GetBuffer();
+ xub_StrLen nNeg = 0;
+ xub_StrLen nNum = 0;
+ if ( p[nNum] == '-' )
+ nNum = nNeg = 1;
+ while ( p[nNum] && CharClass::isAsciiNumeric( p[nNum] ) )
+ nNum++;
+
+ sal_Unicode cNext = p[nNum]; // 0 if at the end
+ sal_Unicode cLast = p[aValue.Len()-1];
+
+ // #i5550# If there are numbers at the beginning and the end,
+ // prefer the one at the beginning only if it's followed by a space.
+ // Otherwise, use the number at the end, to enable things like IP addresses.
+ if ( nNum > nNeg && ( cNext == 0 || cNext == ' ' || !CharClass::isAsciiNumeric(cLast) ) )
+ { // number at the beginning
+ nVal = aValue.Copy( 0, nNum ).ToInt32();
+ // any number with a leading zero sets the minimum number of digits
+ if ( p[nNeg] == '0' && pMinDigits && ( nNum - nNeg > *pMinDigits ) )
+ *pMinDigits = nNum - nNeg;
+ aValue.Erase( 0, nNum );
+ return -1;
+ }
+ else
+ {
+ nNeg = 0;
+ xub_StrLen nEnd = nNum = aValue.Len() - 1;
+ while ( nNum && CharClass::isAsciiNumeric( p[nNum] ) )
+ nNum--;
+ if ( p[nNum] == '-' )
+ {
+ nNum--;
+ nNeg = 1;
+ }
+ if ( nNum < nEnd - nNeg )
+ { // number at the end
+ nVal = aValue.Copy( nNum + 1 ).ToInt32();
+ // any number with a leading zero sets the minimum number of digits
+ if ( p[nNum+1+nNeg] == '0' && pMinDigits && ( nEnd - nNum - nNeg > *pMinDigits ) )
+ *pMinDigits = nEnd - nNum - nNeg;
+ aValue.Erase( nNum + 1 );
+ return 1;
+ }
+ }
+ nVal = 0;
+ return 0;
+}
+
+String lcl_ValueString( sal_Int32 nValue, sal_uInt16 nMinDigits )
+{
+ if ( nMinDigits <= 1 )
+ return String::CreateFromInt32( nValue ); // simple case...
+ else
+ {
+ String aStr = String::CreateFromInt32( Abs( nValue ) );
+ if ( aStr.Len() < nMinDigits )
+ {
+ String aZero;
+ aZero.Fill( nMinDigits - aStr.Len(), '0' );
+ aStr.Insert( aZero, 0 );
+ }
+ // nMinDigits doesn't include the '-' sign -> add after inserting zeros
+ if ( nValue < 0 )
+ aStr.Insert( '-', 0 );
+ return aStr;
+ }
+}
+
+static ScBaseCell * lcl_getSuffixCell( ScDocument* pDocument, sal_Int32 nValue,
+ sal_uInt16 nDigits, const String& rSuffix, CellType eCellType,
+ sal_Bool bIsOrdinalSuffix )
+{
+ String aValue( lcl_ValueString( nValue, nDigits ));
+ if (!bIsOrdinalSuffix)
+ return new ScStringCell( aValue += rSuffix);
+
+ String aOrdinalSuffix( ScGlobal::GetOrdinalSuffix( nValue));
+ if (eCellType != CELLTYPE_EDIT)
+ return new ScStringCell( aValue += aOrdinalSuffix);
+
+ EditEngine aEngine( pDocument->GetEnginePool() );
+ SfxItemSet aAttr = aEngine.GetEmptyItemSet();
+ aAttr.Put( SvxEscapementItem( SVX_ESCAPEMENT_SUPERSCRIPT, EE_CHAR_ESCAPEMENT));
+ aEngine.SetText( aValue );
+ aEngine.QuickInsertText( aOrdinalSuffix, ESelection( 0, aValue.Len(), 0,
+ aValue.Len() + aOrdinalSuffix.Len()));
+ aEngine.QuickSetAttribs( aAttr, ESelection( 0, aValue.Len(), 0, aValue.Len() +
+ aOrdinalSuffix.Len()));
+ return new ScEditCell( aEngine.CreateTextObject(), pDocument, NULL );
+}
+
+void ScTable::FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ FillCmd& rCmd, FillDateCmd& rDateCmd,
+ double& rInc, sal_uInt16& rMinDigits,
+ ScUserListData*& rListData, sal_uInt16& rListIndex)
+{
+ DBG_ASSERT( nCol1==nCol2 || nRow1==nRow2, "FillAnalyse: falscher Bereich" );
+
+ rInc = 0.0;
+ rMinDigits = 0;
+ rListData = NULL;
+ rCmd = FILL_SIMPLE;
+ if ( (nScFillModeMouseModifier & KEY_MOD1) || IsDataFiltered() )
+ return ; // Ctrl-Taste: Copy
+
+ SCCOL nAddX;
+ SCROW nAddY;
+ SCSIZE nCount;
+ if (nCol1 == nCol2)
+ {
+ nAddX = 0;
+ nAddY = 1;
+ nCount = static_cast<SCSIZE>(nRow2 - nRow1 + 1);
+ }
+ else
+ {
+ nAddX = 1;
+ nAddY = 0;
+ nCount = static_cast<SCSIZE>(nCol2 - nCol1 + 1);
+ }
+
+ SCCOL nCol = nCol1;
+ SCROW nRow = nRow1;
+
+ ScBaseCell* pFirstCell = GetCell( nCol, nRow );
+ CellType eCellType = pFirstCell ? pFirstCell->GetCellType() : CELLTYPE_NONE;
+
+ if (eCellType == CELLTYPE_VALUE)
+ {
+ sal_uInt32 nFormat = ((const SfxUInt32Item*)GetAttr(nCol,nRow,ATTR_VALUE_FORMAT))->GetValue();
+ sal_Bool bDate = ( pDocument->GetFormatTable()->GetType(nFormat) == NUMBERFORMAT_DATE );
+ if (bDate)
+ {
+ if (nCount > 1)
+ {
+ double nVal;
+ Date aNullDate = *pDocument->GetFormatTable()->GetNullDate();
+ Date aDate1 = aNullDate;
+ nVal = ((ScValueCell*)pFirstCell)->GetValue();
+ aDate1 += (long)nVal;
+ Date aDate2 = aNullDate;
+ nVal = GetValue(nCol+nAddX, nRow+nAddY);
+ aDate2 += (long)nVal;
+ if ( aDate1 != aDate2 )
+ {
+ long nCmpInc = 0;
+ FillDateCmd eType;
+ long nDDiff = aDate2.GetDay() - (long) aDate1.GetDay();
+ long nMDiff = aDate2.GetMonth() - (long) aDate1.GetMonth();
+ long nYDiff = aDate2.GetYear() - (long) aDate1.GetYear();
+ if ( nDDiff )
+ {
+ eType = FILL_DAY;
+ nCmpInc = aDate2 - aDate1;
+ }
+ else
+ {
+ eType = FILL_MONTH;
+ nCmpInc = nMDiff + 12 * nYDiff;
+ }
+
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ sal_Bool bVal = sal_True;
+ for (sal_uInt16 i=1; i<nCount && bVal; i++)
+ {
+ ScBaseCell* pCell = GetCell(nCol,nRow);
+ if (pCell && pCell->GetCellType() == CELLTYPE_VALUE)
+ {
+ nVal = ((ScValueCell*)pCell)->GetValue();
+ aDate2 = aNullDate + (long) nVal;
+ if ( eType == FILL_DAY )
+ {
+ if ( aDate2-aDate1 != nCmpInc )
+ bVal = false;
+ }
+ else
+ {
+ nDDiff = aDate2.GetDay() - (long) aDate1.GetDay();
+ nMDiff = aDate2.GetMonth() - (long) aDate1.GetMonth();
+ nYDiff = aDate2.GetYear() - (long) aDate1.GetYear();
+ if (nDDiff || ( nMDiff + 12 * nYDiff != nCmpInc ))
+ bVal = false;
+ }
+ aDate1 = aDate2;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ }
+ else
+ bVal = false; // kein Datum passt auch nicht
+ }
+ if (bVal)
+ {
+ if ( eType == FILL_MONTH && ( nCmpInc % 12 == 0 ) )
+ {
+ eType = FILL_YEAR;
+ nCmpInc /= 12;
+ }
+ rCmd = FILL_DATE;
+ rDateCmd = eType;
+ rInc = nCmpInc;
+ }
+ }
+ }
+ else // einzelnes Datum -> Tage hochzaehlen
+ {
+ rCmd = FILL_DATE;
+ rDateCmd = FILL_DAY;
+ rInc = 1.0;
+ }
+ }
+ else
+ {
+ if (nCount > 1)
+ {
+ double nVal1 = ((ScValueCell*)pFirstCell)->GetValue();
+ double nVal2 = GetValue(nCol+nAddX, nRow+nAddY);
+ rInc = nVal2 - nVal1;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ sal_Bool bVal = sal_True;
+ for (sal_uInt16 i=1; i<nCount && bVal; i++)
+ {
+ ScBaseCell* pCell = GetCell(nCol,nRow);
+ if (pCell && pCell->GetCellType() == CELLTYPE_VALUE)
+ {
+ nVal2 = ((ScValueCell*)pCell)->GetValue();
+ double nDiff = nVal2 - nVal1;
+ if ( !::rtl::math::approxEqual( nDiff, rInc ) )
+ bVal = false;
+ nVal1 = nVal2;
+ }
+ else
+ bVal = false;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ }
+ if (bVal)
+ rCmd = FILL_LINEAR;
+ }
+ }
+ }
+ else if (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT)
+ {
+ String aStr;
+ GetString(nCol, nRow, aStr);
+ rListData = (ScUserListData*)(ScGlobal::GetUserList()->GetData(aStr));
+ if (rListData)
+ {
+ rListData->GetSubIndex(aStr, rListIndex);
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ for (sal_uInt16 i=1; i<nCount && rListData; i++)
+ {
+ GetString(nCol, nRow, aStr);
+ if (!rListData->GetSubIndex(aStr, rListIndex))
+ rListData = NULL;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ }
+ }
+ else if ( nCount > 1 )
+ {
+ // pass rMinDigits to all DecompValueString calls
+ // -> longest number defines rMinDigits
+
+ sal_Int32 nVal1;
+ short nFlag1 = lcl_DecompValueString( aStr, nVal1, &rMinDigits );
+ if ( nFlag1 )
+ {
+ sal_Int32 nVal2;
+ GetString( nCol+nAddX, nRow+nAddY, aStr );
+ short nFlag2 = lcl_DecompValueString( aStr, nVal2, &rMinDigits );
+ if ( nFlag1 == nFlag2 )
+ {
+ rInc = (double)nVal2 - (double)nVal1;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ sal_Bool bVal = sal_True;
+ for (sal_uInt16 i=1; i<nCount && bVal; i++)
+ {
+ ScBaseCell* pCell = GetCell(nCol,nRow);
+ CellType eType = pCell ? pCell->GetCellType() : CELLTYPE_NONE;
+ if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
+ {
+ if ( eType == CELLTYPE_STRING )
+ ((ScStringCell*)pCell)->GetString( aStr );
+ else
+ ((ScEditCell*)pCell)->GetString( aStr );
+ nFlag2 = lcl_DecompValueString( aStr, nVal2, &rMinDigits );
+ if ( nFlag1 == nFlag2 )
+ {
+ double nDiff = (double)nVal2 - (double)nVal1;
+ if ( !::rtl::math::approxEqual( nDiff, rInc ) )
+ bVal = false;
+ nVal1 = nVal2;
+ }
+ else
+ bVal = false;
+ }
+ else
+ bVal = false;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ }
+ if (bVal)
+ rCmd = FILL_LINEAR;
+ }
+ }
+ }
+ else
+ {
+ // call DecompValueString to set rMinDigits
+ sal_Int32 nDummy;
+ lcl_DecompValueString( aStr, nDummy, &rMinDigits );
+ }
+ }
+}
+
+void ScTable::FillFormula(sal_uLong& /* nFormulaCounter */, sal_Bool /* bFirst */, ScFormulaCell* pSrcCell,
+ SCCOL nDestCol, SCROW nDestRow, sal_Bool bLast )
+{
+
+ pDocument->SetNoListening( true ); // noch falsche Referenzen
+ ScAddress aAddr( nDestCol, nDestRow, nTab );
+ ScFormulaCell* pDestCell = new ScFormulaCell( *pSrcCell, *pDocument, aAddr );
+ aCol[nDestCol].Insert(nDestRow, pDestCell);
+
+ if ( bLast && pDestCell->GetMatrixFlag() )
+ {
+ ScAddress aOrg;
+ if ( pDestCell->GetMatrixOrigin( aOrg ) )
+ {
+ if ( nDestCol >= aOrg.Col() && nDestRow >= aOrg.Row() )
+ {
+ ScBaseCell* pOrgCell = pDocument->GetCell( aOrg );
+ if ( pOrgCell && pOrgCell->GetCellType() == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pOrgCell)->GetMatrixFlag() == MM_FORMULA )
+ {
+ ((ScFormulaCell*)pOrgCell)->SetMatColsRows(
+ nDestCol - aOrg.Col() + 1,
+ nDestRow - aOrg.Row() + 1 );
+ }
+ else
+ {
+ DBG_ERRORFILE( "FillFormula: MatrixOrigin keine Formelzelle mit MM_FORMULA" );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "FillFormula: MatrixOrigin rechts unten" );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "FillFormula: kein MatrixOrigin" );
+ }
+ }
+ pDocument->SetNoListening( false );
+ pDestCell->StartListeningTo( pDocument );
+
+}
+
+void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ sal_uLong nFillCount, FillDir eFillDir, ScProgress& rProgress )
+{
+ if ( (nFillCount == 0) || !ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2) )
+ return;
+
+ //
+ // Richtung auswerten
+ //
+
+ sal_Bool bVertical = (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_TOP);
+ sal_Bool bPositive = (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_RIGHT);
+
+ sal_uLong nCol = 0;
+ sal_uLong nRow = 0;
+ sal_uLong& rInner = bVertical ? nRow : nCol; // Schleifenvariablen
+ sal_uLong& rOuter = bVertical ? nCol : nRow;
+ sal_uLong nOStart;
+ sal_uLong nOEnd;
+ sal_uLong nIStart;
+ sal_uLong nIEnd;
+ sal_uLong nISrcStart;
+ sal_uLong nISrcEnd;
+
+ if (bVertical)
+ {
+ nOStart = nCol1;
+ nOEnd = nCol2;
+ if (bPositive)
+ {
+ nISrcStart = nRow1;
+ nISrcEnd = nRow2;
+ nIStart = nRow2 + 1;
+ nIEnd = nRow2 + nFillCount;
+ }
+ else
+ {
+ nISrcStart = nRow2;
+ nISrcEnd = nRow1;
+ nIStart = nRow1 - 1;
+ nIEnd = nRow1 - nFillCount;
+ }
+ }
+ else
+ {
+ nOStart = nRow1;
+ nOEnd = nRow2;
+ if (bPositive)
+ {
+ nISrcStart = nCol1;
+ nISrcEnd = nCol2;
+ nIStart = nCol2 + 1;
+ nIEnd = nCol2 + nFillCount;
+ }
+ else
+ {
+ nISrcStart = nCol2;
+ nISrcEnd = nCol1;
+ nIStart = nCol1 - 1;
+ nIEnd = nCol1 - nFillCount;
+ }
+ }
+ sal_uLong nIMin = nIStart;
+ sal_uLong nIMax = nIEnd;
+ PutInOrder(nIMin,nIMax);
+ sal_Bool bHasFiltered = IsDataFiltered();
+
+ if (!bHasFiltered)
+ {
+ if (bVertical)
+ DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), IDF_AUTOFILL);
+ else
+ DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, IDF_AUTOFILL);
+ }
+
+ sal_uLong nProgress = rProgress.GetState();
+
+ //
+ // ausfuehren
+ //
+
+ sal_uLong nActFormCnt = 0;
+ for (rOuter = nOStart; rOuter <= nOEnd; rOuter++)
+ {
+ sal_uLong nMaxFormCnt = 0; // fuer Formeln
+
+ // Attributierung uebertragen
+
+ const ScPatternAttr* pSrcPattern = NULL;
+ const ScStyleSheet* pStyleSheet = NULL;
+ sal_uLong nAtSrc = nISrcStart;
+ ScPatternAttr* pNewPattern = NULL;
+ sal_Bool bGetPattern = sal_True;
+ rInner = nIStart;
+ while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
+ {
+ if ( bGetPattern )
+ {
+ if ( pNewPattern )
+ delete pNewPattern;
+ if (bVertical) // rInner&:=nRow, rOuter&:=nCol
+ pSrcPattern = aCol[nCol].GetPattern(static_cast<SCROW>(nAtSrc));
+ else // rInner&:=nCol, rOuter&:=nRow
+ pSrcPattern = aCol[nAtSrc].GetPattern(static_cast<SCROW>(nRow));
+ bGetPattern = false;
+ pStyleSheet = pSrcPattern->GetStyleSheet();
+ // Merge/Mergeflag nicht uebernehmen,
+ const SfxItemSet& rSet = pSrcPattern->GetItemSet();
+ if ( rSet.GetItemState(ATTR_MERGE, false) == SFX_ITEM_SET
+ || rSet.GetItemState(ATTR_MERGE_FLAG, false) == SFX_ITEM_SET )
+ {
+ pNewPattern = new ScPatternAttr( *pSrcPattern );
+ SfxItemSet& rNewSet = pNewPattern->GetItemSet();
+ rNewSet.ClearItem(ATTR_MERGE);
+ rNewSet.ClearItem(ATTR_MERGE_FLAG);
+ }
+ else
+ pNewPattern = NULL;
+ }
+
+ if ( bVertical && nISrcStart == nISrcEnd && !bHasFiltered )
+ {
+ // Attribute komplett am Stueck setzen
+ if (pNewPattern || pSrcPattern != pDocument->GetDefPattern())
+ {
+ // Default steht schon da (DeleteArea)
+ SCROW nY1 = static_cast<SCROW>(Min( nIStart, nIEnd ));
+ SCROW nY2 = static_cast<SCROW>(Max( nIStart, nIEnd ));
+ if ( pStyleSheet )
+ aCol[nCol].ApplyStyleArea( nY1, nY2, *pStyleSheet );
+ if ( pNewPattern )
+ aCol[nCol].ApplyPatternArea( nY1, nY2, *pNewPattern );
+ else
+ aCol[nCol].ApplyPatternArea( nY1, nY2, *pSrcPattern );
+ }
+ break; // Schleife abbrechen
+ }
+
+ if (!RowFiltered( nRow ))
+ {
+ if ( bHasFiltered )
+ DeleteArea(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow),
+ static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), IDF_AUTOFILL);
+
+ if ( pSrcPattern != aCol[nCol].GetPattern( static_cast<SCROW>(nRow) ) )
+ {
+ // Vorlage auch uebernehmen
+ //! am AttrArray mit ApplyPattern zusammenfassen ??
+ if ( pStyleSheet )
+ aCol[nCol].ApplyStyle( static_cast<SCROW>(nRow), *pStyleSheet );
+
+ // ApplyPattern statt SetPattern um alte MergeFlags stehenzulassen
+ if ( pNewPattern )
+ aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pNewPattern );
+ else
+ aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pSrcPattern );
+ }
+
+ if (nAtSrc==nISrcEnd)
+ {
+ if ( nAtSrc != nISrcStart )
+ { // mehr als eine Source-Zelle
+ nAtSrc = nISrcStart;
+ bGetPattern = sal_True;
+ }
+ }
+ else if (bPositive)
+ {
+ ++nAtSrc;
+ bGetPattern = sal_True;
+ }
+ else
+ {
+ --nAtSrc;
+ bGetPattern = sal_True;
+ }
+ }
+
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+ }
+ if ( pNewPattern )
+ delete pNewPattern;
+
+ // Analyse
+
+ FillCmd eFillCmd;
+ FillDateCmd eDateCmd;
+ double nInc;
+ sal_uInt16 nMinDigits;
+ ScUserListData* pListData = NULL;
+ sal_uInt16 nListIndex;
+ if (bVertical)
+ FillAnalyse(static_cast<SCCOL>(nCol),nRow1,
+ static_cast<SCCOL>(nCol),nRow2, eFillCmd,eDateCmd,
+ nInc,nMinDigits, pListData,nListIndex);
+ else
+ FillAnalyse(nCol1,static_cast<SCROW>(nRow),
+ nCol2,static_cast<SCROW>(nRow), eFillCmd,eDateCmd,
+ nInc,nMinDigits, pListData,nListIndex);
+
+ if (bVertical)
+ aCol[nCol].Resize( aCol[nCol].GetCellCount() + nFillCount );
+
+ if (pListData)
+ {
+ sal_uInt16 nListCount = pListData->GetSubCount();
+ if ( !bPositive )
+ {
+ // nListIndex auf FillAnalyse zeigt auf den letzten Eintrag -> anpassen
+ sal_uLong nSub = nISrcStart - nISrcEnd;
+ for (sal_uLong i=0; i<nSub; i++)
+ {
+ if (nListIndex == 0) nListIndex = nListCount;
+ --nListIndex;
+ }
+ }
+
+ rInner = nIStart;
+ while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
+ {
+ if (bPositive)
+ {
+ ++nListIndex;
+ if (nListIndex >= nListCount) nListIndex = 0;
+ }
+ else
+ {
+ if (nListIndex == 0) nListIndex = nListCount;
+ --nListIndex;
+ }
+ aCol[nCol].Insert(static_cast<SCROW>(nRow), new ScStringCell(pListData->GetSubStr(nListIndex)));
+
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+ }
+ nProgress += nIMax - nIMin + 1;
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ else if (eFillCmd == FILL_SIMPLE) // Auffuellen mit Muster
+ {
+ sal_uLong nSource = nISrcStart;
+ double nDelta;
+ if ( (nScFillModeMouseModifier & KEY_MOD1) || bHasFiltered )
+ nDelta = 0.0;
+ else if ( bPositive )
+ nDelta = 1.0;
+ else
+ nDelta = -1.0;
+ double nVal = 0.0;
+ sal_uLong nFormulaCounter = nActFormCnt;
+ sal_Bool bFirst = sal_True;
+ sal_Bool bGetCell = sal_True;
+ sal_uInt16 nCellDigits = 0;
+ short nHeadNoneTail = 0;
+ sal_Int32 nStringValue = 0;
+ String aValue;
+ ScBaseCell* pSrcCell = NULL;
+ CellType eCellType = CELLTYPE_NONE;
+ sal_Bool bIsOrdinalSuffix = false;
+ sal_Bool bRowFiltered = false;
+
+ rInner = nIStart;
+ while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
+ {
+ if ( bGetCell )
+ {
+ if (bVertical) // rInner&:=nRow, rOuter&:=nCol
+ pSrcCell = aCol[nCol].GetCell( static_cast<SCROW>(nSource) );
+ else // rInner&:=nCol, rOuter&:=nRow
+ pSrcCell = aCol[nSource].GetCell( static_cast<SCROW>(nRow) );
+ bGetCell = false;
+ if ( pSrcCell )
+ {
+ eCellType = pSrcCell->GetCellType();
+ switch ( eCellType )
+ {
+ case CELLTYPE_VALUE:
+ nVal = ((ScValueCell*)pSrcCell)->GetValue();
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ if ( eCellType == CELLTYPE_STRING )
+ ((ScStringCell*)pSrcCell)->GetString( aValue );
+ else
+ ((ScEditCell*)pSrcCell)->GetString( aValue );
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !bHasFiltered )
+ {
+ nCellDigits = 0; // look at each source cell individually
+ nHeadNoneTail = lcl_DecompValueString(
+ aValue, nStringValue, &nCellDigits );
+
+ bIsOrdinalSuffix = aValue.Equals(
+ ScGlobal::GetOrdinalSuffix( nStringValue));
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ eCellType = CELLTYPE_NONE;
+ }
+
+ bRowFiltered = mpFilteredRows->getValue(nRow);
+
+ if (!bRowFiltered)
+ {
+ switch (eCellType)
+ {
+ case CELLTYPE_VALUE:
+ aCol[nCol].Insert(static_cast<SCROW>(nRow), new ScValueCell(nVal + nDelta));
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ if ( nHeadNoneTail )
+ {
+ // #i48009# with the "nStringValue+(long)nDelta" expression within the
+ // lcl_ValueString calls, gcc 3.4.1 makes wrong optimizations (ok in 3.4.3),
+ // so nNextValue is now calculated ahead.
+ sal_Int32 nNextValue = nStringValue+(sal_Int32)nDelta;
+
+ String aStr;
+ if ( nHeadNoneTail < 0 )
+ {
+ aCol[nCol].Insert( static_cast<SCROW>(nRow),
+ lcl_getSuffixCell( pDocument,
+ nNextValue, nCellDigits, aValue,
+ eCellType, bIsOrdinalSuffix));
+ }
+ else
+ {
+ aStr = aValue;
+ aStr += lcl_ValueString( nNextValue, nCellDigits );
+ aCol[nCol].Insert( static_cast<SCROW>(nRow),
+ new ScStringCell( aStr));
+ }
+ }
+ else
+ {
+ ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
+ switch ( eCellType )
+ {
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ break;
+ case CELLTYPE_FORMULA :
+ FillFormula( nFormulaCounter, bFirst,
+ (ScFormulaCell*) pSrcCell,
+ static_cast<SCCOL>(nCol),
+ static_cast<SCROW>(nRow), (rInner == nIEnd) );
+ if (nFormulaCounter - nActFormCnt > nMaxFormCnt)
+ nMaxFormCnt = nFormulaCounter - nActFormCnt;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (nSource==nISrcEnd)
+ {
+ if ( nSource != nISrcStart )
+ { // mehr als eine Source-Zelle
+ nSource = nISrcStart;
+ bGetCell = sal_True;
+ }
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !bHasFiltered )
+ {
+ if ( bPositive )
+ nDelta += 1.0;
+ else
+ nDelta -= 1.0;
+ }
+ nFormulaCounter = nActFormCnt;
+ bFirst = false;
+ }
+ else if (bPositive)
+ {
+ ++nSource;
+ bGetCell = sal_True;
+ }
+ else
+ {
+ --nSource;
+ bGetCell = sal_True;
+ }
+ }
+
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+
+ // Progress in der inneren Schleife nur bei teuren Zellen,
+ // und auch dann nicht fuer jede einzelne
+
+ ++nProgress;
+ if ( eCellType == CELLTYPE_FORMULA || eCellType == CELLTYPE_EDIT )
+ rProgress.SetStateOnPercent( nProgress );
+
+ }
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ else
+ {
+ if (!bPositive)
+ nInc = -nInc;
+ double nEndVal = (nInc>=0.0) ? MAXDOUBLE : -MAXDOUBLE;
+ if (bVertical)
+ FillSeries( static_cast<SCCOL>(nCol), nRow1,
+ static_cast<SCCOL>(nCol), nRow2, nFillCount, eFillDir,
+ eFillCmd, eDateCmd, nInc, nEndVal, nMinDigits, false,
+ rProgress );
+ else
+ FillSeries( nCol1, static_cast<SCROW>(nRow), nCol2,
+ static_cast<SCROW>(nRow), nFillCount, eFillDir,
+ eFillCmd, eDateCmd, nInc, nEndVal, nMinDigits, false,
+ rProgress );
+ nProgress = rProgress.GetState();
+ }
+
+ nActFormCnt += nMaxFormCnt;
+ }
+}
+
+String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY )
+{
+ String aValue;
+
+ SCCOL nCol1 = rSource.aStart.Col();
+ SCROW nRow1 = rSource.aStart.Row();
+ SCCOL nCol2 = rSource.aEnd.Col();
+ SCROW nRow2 = rSource.aEnd.Row();
+ sal_Bool bOk = sal_True;
+ long nIndex = 0;
+ sal_uLong nSrcCount = 0;
+ FillDir eFillDir = FILL_TO_BOTTOM;
+ if ( nEndX == nCol2 && nEndY == nRow2 ) // leer
+ bOk = false;
+ else if ( nEndX == nCol2 ) // nach oben/unten
+ {
+ nEndX = nCol2 = nCol1; // nur erste Spalte ansehen
+ nSrcCount = nRow2 - nRow1 + 1;
+ nIndex = ((long)nEndY) - nRow1; // kann negativ werden
+ if ( nEndY >= nRow1 )
+ eFillDir = FILL_TO_BOTTOM;
+ else
+ eFillDir = FILL_TO_TOP;
+ }
+ else if ( nEndY == nRow2 ) // nach links/rechts
+ {
+ nEndY = nRow2 = nRow1; // nur erste Zeile ansehen
+ nSrcCount = nCol2 - nCol1 + 1;
+ nIndex = ((long)nEndX) - nCol1; // kann negativ werden
+ if ( nEndX >= nCol1 )
+ eFillDir = FILL_TO_RIGHT;
+ else
+ eFillDir = FILL_TO_LEFT;
+ }
+ else // Richtung nicht eindeutig
+ bOk = false;
+
+ if ( bOk )
+ {
+ FillCmd eFillCmd;
+ FillDateCmd eDateCmd;
+ double nInc;
+ sal_uInt16 nMinDigits;
+ ScUserListData* pListData = NULL;
+ sal_uInt16 nListIndex;
+
+ FillAnalyse(nCol1,nRow1, nCol2,nRow2, eFillCmd,eDateCmd, nInc,nMinDigits, pListData,nListIndex);
+
+ if ( pListData ) // benutzerdefinierte Liste
+ {
+ sal_uInt16 nListCount = pListData->GetSubCount();
+ if ( nListCount )
+ {
+ sal_uLong nSub = nSrcCount - 1; // nListIndex ist vom letzten Source-Eintrag
+ while ( nIndex < sal::static_int_cast<long>(nSub) )
+ nIndex += nListCount;
+ sal_uLong nPos = ( nListIndex + nIndex - nSub ) % nListCount;
+ aValue = pListData->GetSubStr(sal::static_int_cast<sal_uInt16>(nPos));
+ }
+ }
+ else if ( eFillCmd == FILL_SIMPLE ) // Auffuellen mit Muster
+ {
+ if ((eFillDir == FILL_TO_BOTTOM)||(eFillDir == FILL_TO_TOP))
+ {
+ long nBegin = 0;
+ long nEnd = 0;
+ if (nEndY > nRow1)
+ {
+ nBegin = nRow2+1;
+ nEnd = nEndY;
+ }
+ else
+ {
+ nBegin = nEndY;
+ nEnd = nRow1 -1;
+ }
+
+ long nNonFiltered = CountNonFilteredRows(nBegin, nEnd);
+ long nFiltered = nEnd + 1 - nBegin - nNonFiltered;
+
+ if (nIndex > 0)
+ nIndex = nIndex - nFiltered;
+ else
+ nIndex = nIndex + nFiltered;
+ }
+
+ long nPosIndex = nIndex;
+ while ( nPosIndex < 0 )
+ nPosIndex += nSrcCount;
+ sal_uLong nPos = nPosIndex % nSrcCount;
+ SCCOL nSrcX = nCol1;
+ SCROW nSrcY = nRow1;
+ if ( eFillDir == FILL_TO_TOP || eFillDir == FILL_TO_BOTTOM )
+ nSrcY = sal::static_int_cast<SCROW>( nSrcY + static_cast<SCROW>(nPos) );
+ else
+ nSrcX = sal::static_int_cast<SCCOL>( nSrcX + static_cast<SCCOL>(nPos) );
+
+ ScBaseCell* pCell = GetCell( nSrcX, nSrcY );
+ if ( pCell )
+ {
+ sal_Int32 nDelta;
+ if (nIndex >= 0)
+ nDelta = nIndex / nSrcCount;
+ else
+ nDelta = ( nIndex - nSrcCount + 1 ) / nSrcCount; // -1 -> -1
+
+ CellType eType = pCell->GetCellType();
+ switch ( eType )
+ {
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ {
+ if ( eType == CELLTYPE_STRING )
+ ((ScStringCell*)pCell)->GetString( aValue );
+ else
+ ((ScEditCell*)pCell)->GetString( aValue );
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered() )
+ {
+ sal_Int32 nVal;
+ sal_uInt16 nCellDigits = 0; // look at each source cell individually
+ short nFlag = lcl_DecompValueString( aValue, nVal, &nCellDigits );
+ if ( nFlag < 0 )
+ {
+ if (aValue.Equals( ScGlobal::GetOrdinalSuffix( nVal)))
+ aValue = ScGlobal::GetOrdinalSuffix( nVal + nDelta);
+
+ aValue.Insert( lcl_ValueString( nVal + nDelta, nCellDigits ), 0 );
+ }
+ else if ( nFlag > 0 )
+ aValue += lcl_ValueString( nVal + nDelta, nCellDigits );
+ }
+ }
+ break;
+ case CELLTYPE_VALUE:
+ {
+ // dabei kann's keinen Ueberlauf geben...
+ double nVal = ((ScValueCell*)pCell)->GetValue();
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered() )
+ nVal += (double) nDelta;
+
+ Color* pColor;
+ sal_uLong nNumFmt = GetNumberFormat( nSrcX, nSrcY );
+ pDocument->GetFormatTable()->
+ GetOutputString( nVal, nNumFmt, aValue, &pColor );
+ }
+ break;
+ // Formeln nicht
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ else if ( eFillCmd == FILL_LINEAR || eFillCmd == FILL_DATE ) // Werte
+ {
+ sal_Bool bValueOk;
+ double nStart;
+ sal_Int32 nVal = 0;
+ short nHeadNoneTail = 0;
+ ScBaseCell* pCell = GetCell( nCol1, nRow1 );
+ if ( pCell )
+ {
+ CellType eType = pCell->GetCellType();
+ switch ( eType )
+ {
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ {
+ if ( eType == CELLTYPE_STRING )
+ ((ScStringCell*)pCell)->GetString( aValue );
+ else
+ ((ScEditCell*)pCell)->GetString( aValue );
+ nHeadNoneTail = lcl_DecompValueString( aValue, nVal );
+ if ( nHeadNoneTail )
+ nStart = (double)nVal;
+ else
+ nStart = 0.0;
+ }
+ break;
+ case CELLTYPE_VALUE:
+ nStart = ((ScValueCell*)pCell)->GetValue();
+ break;
+ case CELLTYPE_FORMULA:
+ nStart = ((ScFormulaCell*)pCell)->GetValue();
+ break;
+ default:
+ nStart = 0.0;
+ }
+ }
+ else
+ nStart = 0.0;
+ if ( eFillCmd == FILL_LINEAR )
+ {
+ double nAdd = nInc;
+ bValueOk = ( SubTotal::SafeMult( nAdd, (double) nIndex ) &&
+ SubTotal::SafePlus( nStart, nAdd ) );
+ }
+ else // Datum
+ {
+ bValueOk = sal_True;
+ sal_uInt16 nDayOfMonth = 0;
+ if ( nIndex < 0 )
+ {
+ nIndex = -nIndex;
+ nInc = -nInc;
+ }
+ for (long i=0; i<nIndex; i++)
+ IncDate( nStart, nDayOfMonth, nInc, eDateCmd );
+ }
+
+ if (bValueOk)
+ {
+ if ( nHeadNoneTail )
+ {
+ if ( nHeadNoneTail < 0 )
+ {
+ if (aValue.Equals( ScGlobal::GetOrdinalSuffix( nVal)))
+ aValue = ScGlobal::GetOrdinalSuffix( (sal_Int32)nStart );
+
+ aValue.Insert( lcl_ValueString( (sal_Int32)nStart, nMinDigits ), 0 );
+ }
+ else
+ aValue += lcl_ValueString( (sal_Int32)nStart, nMinDigits );
+ }
+ else
+ {
+ //! Zahlformat je nach Index holen?
+ Color* pColor;
+ sal_uLong nNumFmt = GetNumberFormat( nCol1, nRow1 );
+ pDocument->GetFormatTable()->
+ GetOutputString( nStart, nNumFmt, aValue, &pColor );
+ }
+ }
+ }
+ else
+ {
+ OSL_FAIL("GetAutoFillPreview: falscher Modus");
+ }
+ }
+
+ return aValue;
+}
+
+void ScTable::IncDate(double& rVal, sal_uInt16& nDayOfMonth, double nStep, FillDateCmd eCmd)
+{
+ if (eCmd == FILL_DAY)
+ {
+ rVal += nStep;
+ return;
+ }
+
+ // class Date Grenzen
+ const sal_uInt16 nMinYear = 1583;
+ const sal_uInt16 nMaxYear = 9956;
+
+ long nInc = (long) nStep; // nach oben/unten begrenzen ?
+ Date aNullDate = *pDocument->GetFormatTable()->GetNullDate();
+ Date aDate = aNullDate;
+ aDate += (long)rVal;
+ switch (eCmd)
+ {
+ case FILL_WEEKDAY:
+ {
+ aDate += nInc;
+ DayOfWeek eWeekDay = aDate.GetDayOfWeek();
+ if (nInc >= 0)
+ {
+ if (eWeekDay == SATURDAY)
+ aDate += 2;
+ else if (eWeekDay == SUNDAY)
+ aDate += 1;
+ }
+ else
+ {
+ if (eWeekDay == SATURDAY)
+ aDate -= 1;
+ else if (eWeekDay == SUNDAY)
+ aDate -= 2;
+ }
+ }
+ break;
+ case FILL_MONTH:
+ {
+ if ( nDayOfMonth == 0 )
+ nDayOfMonth = aDate.GetDay(); // init
+ long nMonth = aDate.GetMonth();
+ long nYear = aDate.GetYear();
+
+ nMonth += nInc;
+
+ if (nInc >= 0)
+ {
+ if (nMonth > 12)
+ {
+ long nYAdd = (nMonth-1) / 12;
+ nMonth -= nYAdd * 12;
+ nYear += nYAdd;
+ }
+ }
+ else
+ {
+ if (nMonth < 1)
+ {
+ long nYAdd = 1 - nMonth / 12; // positiv
+ nMonth += nYAdd * 12;
+ nYear -= nYAdd;
+ }
+ }
+
+ if ( nYear < nMinYear )
+ aDate = Date( 1,1, nMinYear );
+ else if ( nYear > nMaxYear )
+ aDate = Date( 31,12, nMaxYear );
+ else
+ {
+ aDate.SetMonth((sal_uInt16) nMonth);
+ aDate.SetYear((sal_uInt16) nYear);
+ if ( nDayOfMonth > 28 )
+ aDate.SetDay( Min( aDate.GetDaysInMonth(), nDayOfMonth ) );
+ }
+ }
+ break;
+ case FILL_YEAR:
+ {
+ long nYear = aDate.GetYear();
+ nYear += nInc;
+ if ( nYear < nMinYear )
+ aDate = Date( 1,1, nMinYear );
+ else if ( nYear > nMaxYear )
+ aDate = Date( 31,12, nMaxYear );
+ else
+ aDate.SetYear((sal_uInt16) nYear);
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ rVal = aDate - aNullDate;
+}
+
+void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
+ double nStepValue, double nMaxValue, sal_uInt16 nArgMinDigits,
+ sal_Bool bAttribs, ScProgress& rProgress )
+{
+ //
+ // Richtung auswerten
+ //
+
+ sal_Bool bVertical = (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_TOP);
+ sal_Bool bPositive = (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_RIGHT);
+
+ sal_uLong nCol = 0;
+ sal_uLong nRow = 0;
+ sal_uLong& rInner = bVertical ? nRow : nCol; // Schleifenvariablen
+ sal_uLong& rOuter = bVertical ? nCol : nRow;
+ sal_uLong nOStart;
+ sal_uLong nOEnd;
+ sal_uLong nIStart;
+ sal_uLong nIEnd;
+ sal_uLong nISource;
+
+ if (bVertical)
+ {
+ nFillCount += (nRow2 - nRow1);
+ if (nFillCount == 0)
+ return;
+ nOStart = nCol1;
+ nOEnd = nCol2;
+ if (bPositive)
+ {
+ nISource = nRow1;
+ nIStart = nRow1 + 1;
+ nIEnd = nRow1 + nFillCount;
+ }
+ else
+ {
+ nISource = nRow2;
+ nIStart = nRow2 - 1;
+ nIEnd = nRow2 - nFillCount;
+ }
+ }
+ else
+ {
+ nFillCount += (nCol2 - nCol1);
+ if (nFillCount == 0)
+ return;
+ nOStart = nRow1;
+ nOEnd = nRow2;
+ if (bPositive)
+ {
+ nISource = nCol1;
+ nIStart = nCol1 + 1;
+ nIEnd = nCol1 + nFillCount;
+ }
+ else
+ {
+ nISource = nCol2;
+ nIStart = nCol2 - 1;
+ nIEnd = nCol2 - nFillCount;
+ }
+ }
+
+ sal_uLong nIMin = nIStart;
+ sal_uLong nIMax = nIEnd;
+ PutInOrder(nIMin,nIMax);
+ sal_uInt16 nDel = bAttribs ? IDF_AUTOFILL : (IDF_AUTOFILL & IDF_CONTENTS);
+ if (bVertical)
+ DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), nDel);
+ else
+ DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, nDel);
+
+ sal_uLong nProgress = rProgress.GetState();
+
+ //
+ // ausfuehren
+ //
+
+ sal_uLong nActFormCnt = 0;
+ for (rOuter = nOStart; rOuter <= nOEnd; rOuter++)
+ {
+ sal_Bool bFirst = sal_True;
+ rInner = nISource;
+ ScBaseCell* pSrcCell = aCol[nCol].GetCell(static_cast<SCROW>(nRow));
+
+ if (bVertical && bAttribs)
+ aCol[nCol].Resize( aCol[nCol].GetCellCount() + nFillCount );
+
+ if (bAttribs)
+ {
+ const ScPatternAttr* pSrcPattern = aCol[nCol].GetPattern(static_cast<SCROW>(nRow));
+ if (bVertical)
+ aCol[nCol].SetPatternArea( static_cast<SCROW>(nIMin),
+ static_cast<SCROW>(nIMax), *pSrcPattern, sal_True );
+ else
+ for (SCCOL nAtCol = static_cast<SCCOL>(nIMin); nAtCol <= sal::static_int_cast<SCCOL>(nIMax); nAtCol++)
+ aCol[nAtCol].SetPattern(static_cast<SCROW>(nRow), *pSrcPattern, sal_True);
+ }
+
+ if (pSrcCell)
+ {
+ CellType eCellType = pSrcCell->GetCellType();
+
+ if (eFillCmd == FILL_SIMPLE) // kopieren
+ {
+ if (eCellType == CELLTYPE_FORMULA)
+ {
+ for (rInner = nIMin; rInner <= nIMax; rInner++)
+ {
+ if (pDocument->RowFiltered( rInner, nTab))
+ continue;
+ sal_uLong nInd = nActFormCnt;
+ FillFormula(nInd, bFirst, (ScFormulaCell*)pSrcCell,
+ static_cast<SCCOL>(nCol), nRow, (rInner == nIEnd) );
+ bFirst = false;
+ rProgress.SetStateOnPercent( ++nProgress );
+ }
+ }
+ else if (eCellType != CELLTYPE_NOTE)
+ {
+ for (rInner = nIMin; rInner <= nIMax; rInner++)
+ {
+ if (pDocument->RowFiltered( rInner, nTab))
+ continue;
+ ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
+ aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) );
+ }
+ nProgress += nIMax - nIMin + 1;
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ }
+ else if (eCellType == CELLTYPE_VALUE || eCellType == CELLTYPE_FORMULA)
+ {
+ double nStartVal;
+ if (eCellType == CELLTYPE_VALUE)
+ nStartVal = ((ScValueCell*)pSrcCell)->GetValue();
+ else
+ nStartVal = ((ScFormulaCell*)pSrcCell)->GetValue();
+ double nVal = nStartVal;
+ long nIndex = 0;
+
+ sal_Bool bError = false;
+ sal_Bool bOverflow = false;
+
+ sal_uInt16 nDayOfMonth = 0;
+ rInner = nIStart;
+ while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
+ {
+ if (!bError && !bOverflow)
+ {
+ switch (eFillCmd)
+ {
+ case FILL_LINEAR:
+ {
+ // use multiplication instead of repeated addition
+ // to avoid accumulating rounding errors
+ nVal = nStartVal;
+ double nAdd = nStepValue;
+ if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) ||
+ !SubTotal::SafePlus( nVal, nAdd ) )
+ bError = sal_True;
+ }
+ break;
+ case FILL_GROWTH:
+ if (!SubTotal::SafeMult(nVal, nStepValue))
+ bError = sal_True;
+ break;
+ case FILL_DATE:
+ if (fabs(nVal) > _D_MAX_LONG_)
+ bError = sal_True;
+ else
+ IncDate(nVal, nDayOfMonth, nStepValue, eFillDateCmd);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (nStepValue >= 0)
+ {
+ if (nVal > nMaxValue) // Zielwert erreicht?
+ {
+ nVal = nMaxValue;
+ bOverflow = sal_True;
+ }
+ }
+ else
+ {
+ if (nVal < nMaxValue)
+ {
+ nVal = nMaxValue;
+ bOverflow = sal_True;
+ }
+ }
+ }
+
+ if (bError)
+ aCol[nCol].SetError(static_cast<SCROW>(nRow), errNoValue);
+ else if (!bOverflow)
+ aCol[nCol].SetValue(static_cast<SCROW>(nRow), nVal);
+
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+ }
+ nProgress += nIMax - nIMin + 1;
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ else if (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT)
+ {
+ if ( nStepValue >= 0 )
+ {
+ if ( nMaxValue >= (double)LONG_MAX )
+ nMaxValue = (double)LONG_MAX - 1;
+ }
+ else
+ {
+ if ( nMaxValue <= (double)LONG_MIN )
+ nMaxValue = (double)LONG_MIN + 1;
+ }
+ String aValue;
+ if (eCellType == CELLTYPE_STRING)
+ ((ScStringCell*)pSrcCell)->GetString( aValue );
+ else
+ ((ScEditCell*)pSrcCell)->GetString( aValue );
+ sal_Int32 nStringValue;
+ sal_uInt16 nMinDigits = nArgMinDigits;
+ short nHeadNoneTail = lcl_DecompValueString( aValue, nStringValue, &nMinDigits );
+ if ( nHeadNoneTail )
+ {
+ double nStartVal = (double)nStringValue;
+ double nVal = nStartVal;
+ long nIndex = 0;
+ sal_Bool bError = false;
+ sal_Bool bOverflow = false;
+
+ sal_Bool bIsOrdinalSuffix = aValue.Equals( ScGlobal::GetOrdinalSuffix(
+ (sal_Int32)nStartVal));
+
+ rInner = nIStart;
+ while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
+ {
+ if (!bError && !bOverflow)
+ {
+ switch (eFillCmd)
+ {
+ case FILL_LINEAR:
+ {
+ // use multiplication instead of repeated addition
+ // to avoid accumulating rounding errors
+ nVal = nStartVal;
+ double nAdd = nStepValue;
+ if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) ||
+ !SubTotal::SafePlus( nVal, nAdd ) )
+ bError = sal_True;
+ }
+ break;
+ case FILL_GROWTH:
+ if (!SubTotal::SafeMult(nVal, nStepValue))
+ bError = sal_True;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (nStepValue >= 0)
+ {
+ if (nVal > nMaxValue) // Zielwert erreicht?
+ {
+ nVal = nMaxValue;
+ bOverflow = sal_True;
+ }
+ }
+ else
+ {
+ if (nVal < nMaxValue)
+ {
+ nVal = nMaxValue;
+ bOverflow = sal_True;
+ }
+ }
+ }
+
+ if (bError)
+ aCol[nCol].SetError(static_cast<SCROW>(nRow), errNoValue);
+ else if (!bOverflow)
+ {
+ nStringValue = (sal_Int32)nVal;
+ String aStr;
+ if ( nHeadNoneTail < 0 )
+ {
+ aCol[nCol].Insert( static_cast<SCROW>(nRow),
+ lcl_getSuffixCell( pDocument,
+ nStringValue, nMinDigits, aValue,
+ eCellType, bIsOrdinalSuffix ));
+ }
+ else
+ {
+ aStr = aValue;
+ aStr += lcl_ValueString( nStringValue, nMinDigits );
+ ScStringCell* pCell = new ScStringCell( aStr );
+ aCol[nCol].Insert( static_cast<SCROW>(nRow), pCell );
+ }
+ }
+
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+ }
+ }
+ nProgress += nIMax - nIMin + 1;
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ }
+ else
+ {
+ nProgress += nIMax - nIMin + 1;
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ ++nActFormCnt;
+ }
+}
+
+void ScTable::Fill( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
+ double nStepValue, double nMaxValue)
+{
+ sal_uLong nProgCount;
+ if (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_TOP)
+ nProgCount = nCol2 - nCol1 + 1;
+ else
+ nProgCount = nRow2 - nRow1 + 1;
+ nProgCount *= nFillCount;
+ ScProgress aProgress( pDocument->GetDocumentShell(),
+ ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS), nProgCount );
+
+ if (eFillCmd == FILL_AUTO)
+ FillAuto(nCol1, nRow1, nCol2, nRow2, nFillCount, eFillDir, aProgress);
+ else
+ FillSeries(nCol1, nRow1, nCol2, nRow2, nFillCount, eFillDir,
+ eFillCmd, eFillDateCmd, nStepValue, nMaxValue, 0, sal_True, aProgress);
+}
+
+
+void ScTable::AutoFormatArea(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ const ScPatternAttr& rAttr, sal_uInt16 nFormatNo)
+{
+ ScAutoFormat* pAutoFormat = ScGlobal::GetAutoFormat();
+ if (pAutoFormat)
+ {
+ ScAutoFormatData* pData = (*pAutoFormat)[nFormatNo];
+ if (pData)
+ {
+ ApplyPatternArea(nStartCol, nStartRow, nEndCol, nEndRow, rAttr);
+ }
+ }
+}
+
+void ScTable::AutoFormat( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ sal_uInt16 nFormatNo )
+{
+ if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
+ {
+ ScAutoFormat* pAutoFormat = ScGlobal::GetAutoFormat();
+ if (pAutoFormat)
+ {
+ ScAutoFormatData* pData = (*pAutoFormat)[nFormatNo];
+ if (pData)
+ {
+ ScPatternAttr* pPatternAttrs[16];
+ for (sal_uInt8 i = 0; i < 16; ++i)
+ {
+ pPatternAttrs[i] = new ScPatternAttr(pDocument->GetPool());
+ pData->FillToItemSet(i, pPatternAttrs[i]->GetItemSet(), *pDocument);
+ }
+
+ SCCOL nCol = nStartCol;
+ SCROW nRow = nStartRow;
+ sal_uInt16 nIndex = 0;
+ // Linke obere Ecke
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ // Linke Spalte
+ if (pData->IsEqualData(4, 8))
+ AutoFormatArea(nStartCol, nStartRow + 1, nStartCol, nEndRow - 1, *pPatternAttrs[4], nFormatNo);
+ else
+ {
+ nIndex = 4;
+ for (nRow = nStartRow + 1; nRow < nEndRow; nRow++)
+ {
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ if (nIndex == 4)
+ nIndex = 8;
+ else
+ nIndex = 4;
+ }
+ }
+ // Linke untere Ecke
+ nRow = nEndRow;
+ nIndex = 12;
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ // Rechte obere Ecke
+ nCol = nEndCol;
+ nRow = nStartRow;
+ nIndex = 3;
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ // Rechte Spalte
+ if (pData->IsEqualData(7, 11))
+ AutoFormatArea(nEndCol, nStartRow + 1, nEndCol, nEndRow - 1, *pPatternAttrs[7], nFormatNo);
+ else
+ {
+ nIndex = 7;
+ for (nRow = nStartRow + 1; nRow < nEndRow; nRow++)
+ {
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ if (nIndex == 7)
+ nIndex = 11;
+ else
+ nIndex = 7;
+ }
+ }
+ // Rechte untere Ecke
+ nRow = nEndRow;
+ nIndex = 15;
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ nRow = nStartRow;
+ nIndex = 1;
+ for (nCol = nStartCol + 1; nCol < nEndCol; nCol++)
+ {
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ if (nIndex == 1)
+ nIndex = 2;
+ else
+ nIndex = 1;
+ }
+ // Untere Zeile
+ nRow = nEndRow;
+ nIndex = 13;
+ for (nCol = nStartCol + 1; nCol < nEndCol; nCol++)
+ {
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ if (nIndex == 13)
+ nIndex = 14;
+ else
+ nIndex = 13;
+ }
+ // Boddy
+ if ((pData->IsEqualData(5, 6)) && (pData->IsEqualData(9, 10)) && (pData->IsEqualData(5, 9)))
+ AutoFormatArea(nStartCol + 1, nStartRow + 1, nEndCol-1, nEndRow - 1, *pPatternAttrs[5], nFormatNo);
+ else
+ {
+ if ((pData->IsEqualData(5, 9)) && (pData->IsEqualData(6, 10)))
+ {
+ nIndex = 5;
+ for (nCol = nStartCol + 1; nCol < nEndCol; nCol++)
+ {
+ AutoFormatArea(nCol, nStartRow + 1, nCol, nEndRow - 1, *pPatternAttrs[nIndex], nFormatNo);
+ if (nIndex == 5)
+ nIndex = 6;
+ else
+ nIndex = 5;
+ }
+ }
+ else
+ {
+ nIndex = 5;
+ for (nCol = nStartCol + 1; nCol < nEndCol; nCol++)
+ {
+ for (nRow = nStartRow + 1; nRow < nEndRow; nRow++)
+ {
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ if ((nIndex == 5) || (nIndex == 9))
+ {
+ if (nIndex == 5)
+ nIndex = 9;
+ else
+ nIndex = 5;
+ }
+ else
+ {
+ if (nIndex == 6)
+ nIndex = 10;
+ else
+ nIndex = 6;
+ }
+ } // for nRow
+ if ((nIndex == 5) || (nIndex == 9))
+ nIndex = 6;
+ else
+ nIndex = 5;
+ } // for nCol
+ } // if not equal Column
+ } // if not all equal
+
+ for (sal_uInt8 j = 0; j < 16; ++j)
+ delete pPatternAttrs[j];
+ } // if AutoFormatData != NULL
+ } // if AutoFormat != NULL
+ } // if ValidColRow
+}
+
+void ScTable::GetAutoFormatAttr(SCCOL nCol, SCROW nRow, sal_uInt16 nIndex, ScAutoFormatData& rData)
+{
+ sal_uInt32 nFormatIndex = GetNumberFormat( nCol, nRow );
+ ScNumFormatAbbrev aNumFormat( nFormatIndex, *pDocument->GetFormatTable() );
+ rData.GetFromItemSet( nIndex, GetPattern( nCol, nRow )->GetItemSet(), aNumFormat );
+}
+
+#define LF_LEFT 1
+#define LF_TOP 2
+#define LF_RIGHT 4
+#define LF_BOTTOM 8
+#define LF_ALL (LF_LEFT | LF_TOP | LF_RIGHT | LF_BOTTOM)
+
+void ScTable::GetAutoFormatFrame(SCCOL nCol, SCROW nRow, sal_uInt16 nFlags, sal_uInt16 nIndex, ScAutoFormatData& rData)
+{
+ const SvxBoxItem* pTheBox = (SvxBoxItem*)GetAttr(nCol, nRow, ATTR_BORDER);
+ const SvxBoxItem* pLeftBox = (SvxBoxItem*)GetAttr(nCol - 1, nRow, ATTR_BORDER);
+ const SvxBoxItem* pTopBox = (SvxBoxItem*)GetAttr(nCol, nRow - 1, ATTR_BORDER);
+ const SvxBoxItem* pRightBox = (SvxBoxItem*)GetAttr(nCol + 1, nRow, ATTR_BORDER);
+ const SvxBoxItem* pBottomBox = (SvxBoxItem*)GetAttr(nCol, nRow + 1, ATTR_BORDER);
+
+ SvxBoxItem aBox( ATTR_BORDER );
+ if (nFlags & LF_LEFT)
+ {
+ if (pLeftBox)
+ {
+ if (ScHasPriority(pTheBox->GetLeft(), pLeftBox->GetRight()))
+ aBox.SetLine(pTheBox->GetLeft(), BOX_LINE_LEFT);
+ else
+ aBox.SetLine(pLeftBox->GetRight(), BOX_LINE_LEFT);
+ }
+ else
+ aBox.SetLine(pTheBox->GetLeft(), BOX_LINE_LEFT);
+ }
+ if (nFlags & LF_TOP)
+ {
+ if (pTopBox)
+ {
+ if (ScHasPriority(pTheBox->GetTop(), pTopBox->GetBottom()))
+ aBox.SetLine(pTheBox->GetTop(), BOX_LINE_TOP);
+ else
+ aBox.SetLine(pTopBox->GetBottom(), BOX_LINE_TOP);
+ }
+ else
+ aBox.SetLine(pTheBox->GetTop(), BOX_LINE_TOP);
+ }
+ if (nFlags & LF_RIGHT)
+ {
+ if (pRightBox)
+ {
+ if (ScHasPriority(pTheBox->GetRight(), pRightBox->GetLeft()))
+ aBox.SetLine(pTheBox->GetRight(), BOX_LINE_RIGHT);
+ else
+ aBox.SetLine(pRightBox->GetLeft(), BOX_LINE_RIGHT);
+ }
+ else
+ aBox.SetLine(pTheBox->GetRight(), BOX_LINE_RIGHT);
+ }
+ if (nFlags & LF_BOTTOM)
+ {
+ if (pBottomBox)
+ {
+ if (ScHasPriority(pTheBox->GetBottom(), pBottomBox->GetTop()))
+ aBox.SetLine(pTheBox->GetBottom(), BOX_LINE_BOTTOM);
+ else
+ aBox.SetLine(pBottomBox->GetTop(), BOX_LINE_BOTTOM);
+ }
+ else
+ aBox.SetLine(pTheBox->GetBottom(), BOX_LINE_BOTTOM);
+ }
+ rData.PutItem( nIndex, aBox );
+}
+
+void ScTable::GetAutoFormatData(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScAutoFormatData& rData)
+{
+ if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
+ {
+ if ((nEndCol - nStartCol >= 3) && (nEndRow - nStartRow >= 3))
+ {
+ // Linke obere Ecke
+ GetAutoFormatAttr(nStartCol, nStartRow, 0, rData);
+ GetAutoFormatFrame(nStartCol, nStartRow, LF_ALL, 0, rData);
+ // Linke Spalte
+ GetAutoFormatAttr(nStartCol, nStartRow + 1, 4, rData);
+ GetAutoFormatAttr(nStartCol, nStartRow + 2, 8, rData);
+ GetAutoFormatFrame(nStartCol, nStartRow + 1, LF_LEFT | LF_RIGHT | LF_BOTTOM, 4, rData);
+ if (nEndRow - nStartRow >= 4)
+ GetAutoFormatFrame(nStartCol, nStartRow + 2, LF_LEFT | LF_RIGHT | LF_BOTTOM, 8, rData);
+ else
+ rData.CopyItem( 8, 4, ATTR_BORDER );
+ // Linke untere Ecke
+ GetAutoFormatAttr(nStartCol, nEndRow, 12, rData);
+ GetAutoFormatFrame(nStartCol, nEndRow, LF_ALL, 12, rData);
+ // Rechte obere Ecke
+ GetAutoFormatAttr(nEndCol, nStartRow, 3, rData);
+ GetAutoFormatFrame(nEndCol, nStartRow, LF_ALL, 3, rData);
+ // Rechte Spalte
+ GetAutoFormatAttr(nEndCol, nStartRow + 1, 7, rData);
+ GetAutoFormatAttr(nEndCol, nStartRow + 2, 11, rData);
+ GetAutoFormatFrame(nEndCol, nStartRow + 1, LF_LEFT | LF_RIGHT | LF_BOTTOM, 7, rData);
+ if (nEndRow - nStartRow >= 4)
+ GetAutoFormatFrame(nEndCol, nStartRow + 2, LF_LEFT | LF_RIGHT | LF_BOTTOM, 11, rData);
+ else
+ rData.CopyItem( 11, 7, ATTR_BORDER );
+ // Rechte untere Ecke
+ GetAutoFormatAttr(nEndCol, nEndRow, 15, rData);
+ GetAutoFormatFrame(nEndCol, nEndRow, LF_ALL, 15, rData);
+ // Ober Zeile
+ GetAutoFormatAttr(nStartCol + 1, nStartRow, 1, rData);
+ GetAutoFormatAttr(nStartCol + 2, nStartRow, 2, rData);
+ GetAutoFormatFrame(nStartCol + 1, nStartRow, LF_TOP | LF_BOTTOM | LF_RIGHT, 1, rData);
+ if (nEndCol - nStartCol >= 4)
+ GetAutoFormatFrame(nStartCol + 2, nStartRow, LF_TOP | LF_BOTTOM | LF_RIGHT, 2, rData);
+ else
+ rData.CopyItem( 2, 1, ATTR_BORDER );
+ // Untere Zeile
+ GetAutoFormatAttr(nStartCol + 1, nEndRow, 13, rData);
+ GetAutoFormatAttr(nStartCol + 2, nEndRow, 14, rData);
+ GetAutoFormatFrame(nStartCol + 1, nEndRow, LF_TOP | LF_BOTTOM | LF_RIGHT, 13, rData);
+ if (nEndCol - nStartCol >= 4)
+ GetAutoFormatFrame(nStartCol + 2, nEndRow, LF_TOP | LF_BOTTOM | LF_RIGHT, 14, rData);
+ else
+ rData.CopyItem( 14, 13, ATTR_BORDER );
+ // Body
+ GetAutoFormatAttr(nStartCol + 1, nStartRow + 1, 5, rData);
+ GetAutoFormatAttr(nStartCol + 2, nStartRow + 1, 6, rData);
+ GetAutoFormatAttr(nStartCol + 1, nStartRow + 2, 9, rData);
+ GetAutoFormatAttr(nStartCol + 2, nStartRow + 2, 10, rData);
+ GetAutoFormatFrame(nStartCol + 1, nStartRow + 1, LF_RIGHT | LF_BOTTOM, 5, rData);
+ if ((nEndCol - nStartCol >= 4) && (nEndRow - nStartRow >= 4))
+ {
+ GetAutoFormatFrame(nStartCol + 2, nStartRow + 1, LF_RIGHT | LF_BOTTOM, 6, rData);
+ GetAutoFormatFrame(nStartCol + 1, nStartRow + 2, LF_RIGHT | LF_BOTTOM, 9, rData);
+ GetAutoFormatFrame(nStartCol + 2, nStartRow + 2, LF_RIGHT | LF_BOTTOM, 10, rData);
+ }
+ else
+ {
+ rData.CopyItem( 6, 5, ATTR_BORDER );
+ rData.CopyItem( 9, 5, ATTR_BORDER );
+ rData.CopyItem( 10, 5, ATTR_BORDER );
+ }
+ }
+ }
+}
+
+void ScTable::SetError( SCCOL nCol, SCROW nRow, sal_uInt16 nError)
+{
+ if (ValidColRow(nCol, nRow))
+ aCol[nCol].SetError( nRow, nError );
+}
+
+void ScTable::UpdateInsertTabAbs(SCTAB nTable)
+{
+ for (SCCOL i=0; i <= MAXCOL; i++)
+ aCol[i].UpdateInsertTabAbs(nTable);
+}
+
+sal_Bool ScTable::GetNextSpellingCell(SCCOL& rCol, SCROW& rRow, sal_Bool bInSel,
+ const ScMarkData& rMark) const
+{
+ if (rRow == MAXROW+2) // Tabellenende
+ {
+ rRow = 0;
+ rCol = 0;
+ }
+ else
+ {
+ rRow++;
+ if (rRow == MAXROW+1)
+ {
+ rCol++;
+ rRow = 0;
+ }
+ }
+ if (rCol == MAXCOL+1)
+ return sal_True;
+ else
+ {
+ sal_Bool bStop = false;
+ while (!bStop)
+ {
+ if (ValidCol(rCol))
+ {
+ bStop = aCol[rCol].GetNextSpellingCell(rRow, bInSel, rMark);
+ if (bStop)
+ return sal_True;
+ else /*if (rRow == MAXROW+1) */
+ {
+ rCol++;
+ rRow = 0;
+ }
+ }
+ else
+ return sal_True;
+ }
+ }
+ return false;
+}
+
+void ScTable::RemoveAutoSpellObj()
+{
+ for (SCCOL i=0; i <= MAXCOL; i++)
+ aCol[i].RemoveAutoSpellObj();
+}
+
+sal_Bool ScTable::TestTabRefAbs(SCTAB nTable)
+{
+ sal_Bool bRet = false;
+ for (SCCOL i=0; i <= MAXCOL; i++)
+ if (aCol[i].TestTabRefAbs(nTable))
+ bRet = sal_True;
+ return bRet;
+}
+
+void ScTable::CompileDBFormula()
+{
+ for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileDBFormula();
+}
+
+void ScTable::CompileDBFormula( sal_Bool bCreateFormulaString )
+{
+ for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileDBFormula( bCreateFormulaString );
+}
+
+void ScTable::CompileNameFormula( sal_Bool bCreateFormulaString )
+{
+ for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileNameFormula( bCreateFormulaString );
+}
+
+void ScTable::CompileColRowNameFormula()
+{
+ for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileColRowNameFormula();
+}
+
+
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */