summaryrefslogtreecommitdiff
path: root/binfilter/bf_sc/source/core/data/sc_column3.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_sc/source/core/data/sc_column3.cxx')
-rw-r--r--binfilter/bf_sc/source/core/data/sc_column3.cxx1060
1 files changed, 1060 insertions, 0 deletions
diff --git a/binfilter/bf_sc/source/core/data/sc_column3.cxx b/binfilter/bf_sc/source/core/data/sc_column3.cxx
new file mode 100644
index 000000000000..f84eba85b1b0
--- /dev/null
+++ b/binfilter/bf_sc/source/core/data/sc_column3.cxx
@@ -0,0 +1,1060 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#include <bf_sfx2/objsh.hxx>
+#include <bf_svtools/zforlist.hxx>
+
+#include "scitems.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "attarray.hxx"
+#include "cellform.hxx"
+#include "detfunc.hxx" // fuer Notizen bei DeleteRange
+namespace binfilter {
+
+// Err527 Workaround
+extern const ScFormulaCell* pLastFormulaTreeTop; // in cellform.cxx
+
+// STATIC DATA -----------------------------------------------------------
+
+/*N*/ BOOL ScColumn::bDoubleAlloc = FALSE; // fuer Import: Groesse beim Allozieren verdoppeln
+/*N*/
+/*N*/
+/*N*/ void ScColumn::Insert( USHORT nRow, ScBaseCell* pNewCell )
+/*N*/ {
+/*N*/ BOOL bIsAppended = FALSE;
+/*N*/ if (pItems && nCount)
+/*N*/ {
+/*N*/ if (pItems[nCount-1].nRow < nRow)
+/*N*/ {
+/*N*/ Append(nRow, pNewCell );
+/*N*/ bIsAppended = TRUE;
+/*N*/ }
+/*N*/ }
+/*N*/ if ( !bIsAppended )
+/*N*/ {
+/*N*/ USHORT nIndex;
+/*N*/ if (Search(nRow, nIndex))
+/*N*/ {
+/*N*/ ScBaseCell* pOldCell = pItems[nIndex].pCell;
+/*N*/ ScBroadcasterList* pBC = pOldCell->GetBroadcaster();
+/*N*/ if (pBC && !pNewCell->GetBroadcaster())
+/*N*/ {
+/*N*/ pNewCell->SetBroadcaster( pBC );
+/*N*/ pOldCell->ForgetBroadcaster();
+/*N*/ }
+/*N*/ if (pOldCell->GetNotePtr() && !pNewCell->GetNotePtr())
+/*?*/ pNewCell->SetNote( *pOldCell->GetNotePtr() );
+/*N*/ if ( pOldCell->GetCellType() == CELLTYPE_FORMULA && !pDocument->IsClipOrUndo() )
+/*N*/ {
+/*?*/ pOldCell->EndListeningTo( pDocument );
+/*?*/ // falls in EndListening NoteCell in gleicher Col zerstoert
+/*?*/ if ( nIndex >= nCount || pItems[nIndex].nRow != nRow )
+/*?*/ Search(nRow, nIndex);
+/*N*/ }
+/*N*/ pOldCell->Delete();
+/*N*/ pItems[nIndex].pCell = pNewCell;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ if (nCount + 1 > nLimit)
+/*N*/ {
+/*N*/ if (bDoubleAlloc)
+/*N*/ {
+/*N*/ if (nLimit < COLUMN_DELTA)
+/*N*/ nLimit = COLUMN_DELTA;
+/*N*/ else
+/*N*/ {
+/*N*/ nLimit *= 2;
+/*N*/ if ( nLimit > MAXROW+1 )
+/*N*/ nLimit = MAXROW+1;
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ nLimit += COLUMN_DELTA;
+/*N*/
+/*N*/ ColEntry* pNewItems = new ColEntry[nLimit];
+/*N*/ if (pItems)
+/*N*/ {
+/*N*/ memmove( pNewItems, pItems, nCount * sizeof(ColEntry) );
+/*N*/ delete[] pItems;
+/*N*/ }
+/*N*/ pItems = pNewItems;
+/*N*/ }
+/*N*/ memmove( &pItems[nIndex + 1], &pItems[nIndex], (nCount - nIndex) * sizeof(ColEntry) );
+/*N*/ pItems[nIndex].pCell = pNewCell;
+/*N*/ pItems[nIndex].nRow = nRow;
+/*N*/ ++nCount;
+/*N*/ }
+/*N*/ }
+/*N*/ // Bei aus Clipboard sind hier noch falsche (alte) Referenzen!
+/*N*/ // Werden in CopyBlockFromClip per UpdateReference umgesetzt,
+/*N*/ // danach StartListeningFromClip und BroadcastFromClip gerufen.
+/*N*/ // Wird ins Clipboard/UndoDoc gestellt, wird kein Broadcast gebraucht.
+/*N*/ // Nach Import wird CalcAfterLoad gerufen, dort Listening.
+/*N*/ if ( !(pDocument->IsClipOrUndo() || pDocument->IsInsertingFromOtherDoc()) )
+/*N*/ {
+/*N*/ pNewCell->StartListeningTo( pDocument );
+/*N*/ CellType eCellType = pNewCell->GetCellType();
+/*N*/ // Notizzelle entsteht beim Laden nur durch StartListeningCell,
+/*N*/ // ausloesende Formelzelle muss sowieso dirty sein.
+/*N*/ if ( !(pDocument->IsCalcingAfterLoad() && eCellType == CELLTYPE_NOTE) )
+/*N*/ {
+/*N*/ if ( eCellType == CELLTYPE_FORMULA )
+/*N*/ ((ScFormulaCell*)pNewCell)->SetDirty();
+/*N*/ else
+/*N*/ pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED,
+/*N*/ ScAddress( nCol, nRow, nTab ), pNewCell ) );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void ScColumn::Insert( USHORT nRow, ULONG nNumberFormat, ScBaseCell* pCell )
+/*N*/ {
+/*N*/ Insert(nRow, pCell);
+/*N*/ short eOldType = pDocument->GetFormatTable()->
+/*N*/ GetType( (ULONG)
+/*N*/ ((SfxUInt32Item*)GetAttr( nRow, ATTR_VALUE_FORMAT ))->
+/*N*/ GetValue() );
+/*N*/ short eNewType = pDocument->GetFormatTable()->GetType(nNumberFormat);
+/*N*/ if (!pDocument->GetFormatTable()->IsCompatible(eOldType, eNewType))
+/*N*/ ApplyAttr( nRow, SfxUInt32Item( ATTR_VALUE_FORMAT, (UINT32) nNumberFormat) );
+/*N*/ }
+
+
+/*N*/ void ScColumn::Append( USHORT nRow, ScBaseCell* pCell )
+/*N*/ {
+/*N*/ if (nCount + 1 > nLimit)
+/*N*/ {
+/*N*/ if (bDoubleAlloc)
+/*N*/ {
+/*N*/ if (nLimit < COLUMN_DELTA)
+/*N*/ nLimit = COLUMN_DELTA;
+/*N*/ else
+/*N*/ {
+/*N*/ nLimit *= 2;
+/*N*/ if ( nLimit > MAXROW+1 )
+/*N*/ nLimit = MAXROW+1;
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ nLimit += COLUMN_DELTA;
+/*N*/
+/*N*/ ColEntry* pNewItems = new ColEntry[nLimit];
+/*N*/ if (pItems)
+/*N*/ {
+/*N*/ memmove( pNewItems, pItems, nCount * sizeof(ColEntry) );
+/*N*/ delete[] pItems;
+/*N*/ }
+/*N*/ pItems = pNewItems;
+/*N*/ }
+/*N*/ pItems[nCount].pCell = pCell;
+/*N*/ pItems[nCount].nRow = nRow;
+/*N*/ ++nCount;
+/*N*/ }
+
+
+/*N*/ void ScColumn::DeleteAtIndex( USHORT nIndex )
+/*N*/ {
+/*N*/ ScBaseCell* pCell = pItems[nIndex].pCell;
+/*N*/ ScNoteCell* pNoteCell = new ScNoteCell;
+/*N*/ pItems[nIndex].pCell = pNoteCell; // Dummy fuer Interpret
+/*N*/ pDocument->Broadcast( ScHint( SC_HINT_DYING,
+/*N*/ ScAddress( nCol, pItems[nIndex].nRow, nTab ), pCell ) );
+/*N*/ delete pNoteCell;
+/*N*/ --nCount;
+/*N*/ memmove( &pItems[nIndex], &pItems[nIndex + 1], (nCount - nIndex) * sizeof(ColEntry) );
+/*N*/ pItems[nCount].nRow = 0;
+/*N*/ pItems[nCount].pCell = NULL;
+/*N*/ pCell->EndListeningTo( pDocument );
+/*N*/ pCell->Delete();
+/*N*/ }
+
+
+/*N*/ void ScColumn::FreeAll()
+/*N*/ {
+/*N*/ if (pItems)
+/*N*/ {
+/*N*/ for (USHORT i = 0; i < nCount; i++)
+/*N*/ pItems[i].pCell->Delete();
+/*N*/ delete[] pItems;
+/*N*/ pItems = NULL;
+/*N*/ }
+/*N*/ nCount = 0;
+/*N*/ nLimit = 0;
+/*N*/ }
+
+
+/*N*/ void ScColumn::DeleteRow( USHORT nStartRow, USHORT nSize )
+/*N*/ {
+/*N*/ pAttrArray->DeleteRow( nStartRow, nSize );
+/*N*/
+/*N*/ if ( !pItems || !nCount )
+/*N*/ return ;
+/*N*/
+/*N*/ USHORT nFirstIndex;
+/*N*/ Search( nStartRow, nFirstIndex );
+/*N*/ if ( nFirstIndex >= nCount )
+/*N*/ return ;
+/*N*/
+/*N*/ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+/*N*/ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+/*N*/
+/*N*/ BOOL bFound=FALSE;
+/*N*/ USHORT nEndRow = nStartRow + nSize - 1;
+/*N*/ USHORT nStartIndex;
+/*N*/ USHORT nEndIndex;
+/*N*/ USHORT i;
+/*N*/
+/*N*/ for ( i = nFirstIndex; i < nCount && pItems[i].nRow <= nEndRow; i++ )
+/*N*/ {
+/*N*/ if (!bFound)
+/*N*/ {
+/*N*/ nStartIndex = i;
+/*N*/ bFound = TRUE;
+/*N*/ }
+/*N*/ nEndIndex = i;
+/*N*/
+/*N*/ ScBaseCell* pCell = pItems[i].pCell;
+/*N*/ ScBroadcasterList* pBC = pCell->GetBroadcaster();
+/*N*/ if (pBC)
+/*N*/ {
+/*N*/ // gibt jetzt invalid reference, kein Aufruecken der direkten Referenzen
+/*N*/ // MoveListeners( *pBC, nRow+nSize );
+/*N*/ pCell->SetBroadcaster(NULL);
+/*N*/ // in DeleteRange werden leere Broadcaster geloescht
+/*N*/ }
+/*N*/ }
+/*N*/ if (bFound)
+/*N*/ {
+/*N*/ DeleteRange( nStartIndex, nEndIndex, IDF_CONTENTS );
+/*N*/ Search( nStartRow, i );
+/*N*/ if ( i >= nCount )
+/*N*/ {
+/*N*/ pDocument->SetAutoCalc( bOldAutoCalc );
+/*N*/ return ;
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ i = nFirstIndex;
+/*N*/
+/*N*/ ScAddress aAdr( nCol, 0, nTab );
+/*N*/ ScHint aHint( SC_HINT_DATACHANGED, aAdr, NULL ); // only areas (ScBaseCell* == NULL)
+/*N*/ ScAddress& rAddress = aHint.GetAddress();
+/*N*/ // for sparse occupation use single broadcasts, not ranges
+/*N*/ BOOL bSingleBroadcasts = (((pItems[nCount-1].nRow - pItems[i].nRow) /
+/*N*/ (nCount - i)) > 1);
+/*N*/ if ( bSingleBroadcasts )
+/*N*/ {
+/*N*/ USHORT nLastBroadcast = MAXROW+1;
+/*N*/ for ( ; i < nCount; i++ )
+/*N*/ {
+/*N*/ USHORT nOldRow = pItems[i].nRow;
+/*N*/ // #43940# Aenderung Quelle broadcasten
+/*N*/ rAddress.SetRow( nOldRow );
+/*N*/ pDocument->AreaBroadcast( aHint );
+/*N*/ USHORT nNewRow = (pItems[i].nRow -= nSize);
+/*N*/ // #43940# Aenderung Ziel broadcasten
+/*N*/ if ( nLastBroadcast != nNewRow )
+/*N*/ { // direkt aufeinanderfolgende nicht doppelt broadcasten
+/*N*/ rAddress.SetRow( nNewRow );
+/*N*/ pDocument->AreaBroadcast( aHint );
+/*N*/ }
+/*N*/ nLastBroadcast = nOldRow;
+/*N*/ ScBaseCell* pCell = pItems[i].pCell;
+/*N*/ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+/*N*/ ((ScFormulaCell*)pCell)->aPos.SetRow( nNewRow );
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ rAddress.SetRow( pItems[i].nRow );
+/*N*/ ScRange aRange( rAddress );
+/*N*/ aRange.aEnd.SetRow( pItems[nCount-1].nRow );
+/*N*/ for ( ; i < nCount; i++ )
+/*N*/ {
+/*N*/ USHORT nNewRow = (pItems[i].nRow -= nSize);
+/*N*/ ScBaseCell* pCell = pItems[i].pCell;
+/*N*/ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+/*N*/ ((ScFormulaCell*)pCell)->aPos.SetRow( nNewRow );
+/*N*/ }
+/*N*/ pDocument->AreaBroadcastInRange( aRange, aHint );
+/*N*/ }
+/*N*/
+/*N*/ pDocument->SetAutoCalc( bOldAutoCalc );
+/*N*/ }
+
+
+/*N*/ void ScColumn::DeleteRange( USHORT nStartIndex, USHORT nEndIndex, USHORT nDelFlag )
+/*N*/ {
+/*N*/ USHORT nDelCount = 0;
+/*N*/ ScBaseCell** ppDelCells = new ScBaseCell*[nEndIndex-nStartIndex+1];
+/*N*/
+/*N*/ BOOL bSimple = ((nDelFlag & IDF_CONTENTS) == IDF_CONTENTS);
+/*N*/ USHORT i;
+/*N*/
+/*N*/ // Notiz-Zeichenobjekte
+/*N*/ if (nDelFlag & IDF_NOTE)
+/*N*/ {
+/*N*/ for ( i = nStartIndex; i <= nEndIndex; i++ )
+/*N*/ {
+/*N*/ const ScPostIt* pNote = pItems[i].pCell->GetNotePtr();
+/*N*/ if ( pNote && pNote->IsShown() )
+/*N*/ {
+/*?*/ ScDetectiveFunc( pDocument, nTab ).HideComment( nCol, pItems[i].nRow );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ // Broadcaster stehenlassen
+/*N*/ if (bSimple)
+/*N*/ {
+/*N*/ for (i = nStartIndex; i <= nEndIndex && bSimple; i++)
+/*N*/ if (pItems[i].pCell->GetBroadcaster())
+/*N*/ bSimple = FALSE;
+/*N*/ }
+/*N*/
+/*N*/ ScHint aHint( SC_HINT_DYING, ScAddress( nCol, 0, nTab ), NULL );
+/*N*/
+/*N*/ if (bSimple) // Bereich komplett loeschen
+/*N*/ {
+/*N*/ ScBaseCell* pOldCell;
+/*N*/ ScNoteCell* pNoteCell = new ScNoteCell; // Dummy
+/*N*/ for (i = nStartIndex; i <= nEndIndex; i++)
+/*N*/ {
+/*N*/ pOldCell = pItems[i].pCell;
+/*N*/ if (pOldCell->GetCellType() == CELLTYPE_FORMULA) // Formeln spaeter loeschen
+/*N*/ ppDelCells[nDelCount++] = pOldCell;
+/*N*/ else
+/*N*/ {
+/*N*/ // Interpret in Broadcast darf kein Value finden
+/*N*/ pItems[i].pCell = pNoteCell;
+/*N*/ aHint.GetAddress().SetRow( pItems[i].nRow );
+/*N*/ aHint.SetCell( pOldCell );
+/*N*/ pDocument->Broadcast( aHint );
+/*N*/ pOldCell->Delete();
+/*N*/ }
+/*N*/ }
+/*N*/ delete pNoteCell;
+/*N*/ memmove( &pItems[nStartIndex], &pItems[nEndIndex + 1], (nCount - nEndIndex - 1) * sizeof(ColEntry) );
+/*N*/ nCount -= nEndIndex-nStartIndex+1;
+/*N*/ }
+/*N*/ else // Zellen einzeln durchgehen
+/*N*/ {
+/*N*/ USHORT j = nStartIndex;
+/*N*/ for (USHORT i = nStartIndex; i <= nEndIndex; i++)
+/*N*/ {
+/*N*/ BOOL bDelete = FALSE;
+/*N*/ ScBaseCell* pOldCell = pItems[j].pCell;
+/*N*/ CellType eCellType = pOldCell->GetCellType();
+/*N*/ switch ( eCellType )
+/*N*/ {
+/*N*/ case CELLTYPE_VALUE:
+/*N*/ if ( ( nDelFlag & (IDF_DATETIME|IDF_VALUE) ) == (IDF_DATETIME|IDF_VALUE) )
+/*N*/ bDelete = TRUE;
+/*N*/ else
+/*N*/ {
+/*?*/ ULONG nIndex = (ULONG)((SfxUInt32Item*)GetAttr( pItems[j].nRow, ATTR_VALUE_FORMAT ))->GetValue();
+/*?*/ short nTyp = pDocument->GetFormatTable()->GetType(nIndex);
+/*?*/ if ((nTyp == NUMBERFORMAT_DATE) || (nTyp == NUMBERFORMAT_TIME) || (nTyp == NUMBERFORMAT_DATETIME))
+/*?*/ bDelete = ((nDelFlag & IDF_DATETIME) != 0);
+/*?*/ else
+/*?*/ bDelete = ((nDelFlag & IDF_VALUE) != 0);
+/*N*/ }
+/*N*/ break;
+/*?*/ case CELLTYPE_STRING:
+/*N*/ case CELLTYPE_EDIT: bDelete = ((nDelFlag & IDF_STRING) != 0); break;
+/*?*/ case CELLTYPE_FORMULA: bDelete = ((nDelFlag & IDF_FORMULA) != 0); break;
+/*?*/ case CELLTYPE_NOTE:
+/*?*/ bDelete = ((nDelFlag & IDF_NOTE) != 0) &&
+/*?*/ (pOldCell->GetBroadcaster() == NULL);
+/*?*/ break;
+/*N*/ }
+/*N*/
+/*N*/ if (bDelete)
+/*N*/ {
+/*N*/ ScNoteCell* pNoteCell = NULL;
+/*N*/ if (eCellType != CELLTYPE_NOTE)
+/*N*/ {
+/*N*/ if ((nDelFlag & IDF_NOTE) == 0)
+/*N*/ {
+/*?*/ const ScPostIt* pNote = pOldCell->GetNotePtr();
+/*?*/ if (pNote)
+/*?*/ pNoteCell = new ScNoteCell(*pNote);
+/*N*/ }
+/*N*/ ScBroadcasterList* pBC = pOldCell->GetBroadcaster();
+/*N*/ if (pBC)
+/*N*/ {
+/*N*/ if (!pNoteCell)
+/*N*/ pNoteCell = new ScNoteCell;
+/*N*/ pNoteCell->SetBroadcaster(pBC);
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ USHORT nOldRow = pItems[j].nRow;
+/*N*/ if (pNoteCell)
+/*N*/ {
+/*N*/ pItems[j].pCell = pNoteCell;
+/*N*/ ++j;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ --nCount;
+/*N*/ memmove( &pItems[j], &pItems[j + 1], (nCount - j) * sizeof(ColEntry) );
+/*N*/ pItems[nCount].nRow = 0;
+/*N*/ pItems[nCount].pCell = NULL;
+/*N*/ }
+/*N*/ // ACHTUNG! pItems bereits verschoben!
+/*N*/ // Interpret in Broadcast muss neue/keine Zelle finden
+/*N*/ if (eCellType == CELLTYPE_FORMULA) // Formeln spaeter loeschen
+/*N*/ {
+/*N*/ ppDelCells[nDelCount++] = pOldCell;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ aHint.GetAddress().SetRow( nOldRow );
+/*N*/ aHint.SetCell( pOldCell );
+/*N*/ pDocument->Broadcast( aHint );
+/*N*/ if (eCellType != CELLTYPE_NOTE)
+/*N*/ pOldCell->ForgetBroadcaster();
+/*N*/ pOldCell->Delete();
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*?*/ if (nDelFlag & IDF_NOTE)
+/*?*/ if (pItems[j].pCell->GetNotePtr())
+/*?*/ pItems[j].pCell->DeleteNote();
+/*?*/ ++j;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ // erst Listener abhaengen kann Neuberechnungen sparen
+/*N*/ // eventuell werden dabei vorher entstandene NoteCell mitsamt
+/*N*/ // ihren Broadcaster deleted!
+/*N*/ for (i=0; i<nDelCount; i++)
+/*N*/ {
+/*?*/ ((ScFormulaCell*) ppDelCells[i])->EndListeningTo( pDocument );
+/*N*/ }
+/*N*/ // gibts die NoteCell und damit den Broadcaster noch?
+/*N*/ // If not, discard them all before broadcasting takes place!
+/*N*/ for (i=0; i<nDelCount; i++)
+/*N*/ {
+/*?*/ ScFormulaCell* pOldCell = (ScFormulaCell*) ppDelCells[i];
+/*?*/ USHORT nIndex;
+/*?*/ if ( !Search( pOldCell->aPos.Row(), nIndex ) )
+/*?*/ pOldCell->ForgetBroadcaster();
+/*N*/ }
+/*N*/ for (i=0; i<nDelCount; i++)
+/*N*/ {
+/*?*/ ScFormulaCell* pOldCell = (ScFormulaCell*) ppDelCells[i];
+/*?*/ aHint.SetAddress( pOldCell->aPos );
+/*?*/ aHint.SetCell( pOldCell );
+/*?*/ pDocument->Broadcast( aHint );
+/*?*/ pOldCell->ForgetBroadcaster();
+/*?*/ pOldCell->Delete();
+/*N*/ }
+/*N*/
+/*N*/ delete[] ppDelCells;
+/*N*/ }
+
+
+/*N*/ void ScColumn::DeleteArea(USHORT nStartRow, USHORT nEndRow, USHORT nDelFlag)
+/*N*/ {
+/*N*/ // FreeAll darf hier nicht gerufen werden wegen Broadcastern
+/*N*/
+/*N*/ // Attribute erst am Ende, damit vorher noch zwischen Zahlen und Datum
+/*N*/ // unterschieden werden kann (#47901#)
+/*N*/
+/*N*/ USHORT nContFlag = nDelFlag & IDF_CONTENTS;
+/*N*/ if (pItems && nCount && nContFlag)
+/*N*/ {
+/*N*/ if (nStartRow==0 && nEndRow==MAXROW)
+/*N*/ DeleteRange( 0, nCount-1, nContFlag );
+/*N*/ else
+/*N*/ {
+/*?*/ BOOL bFound=FALSE;
+/*?*/ USHORT nStartIndex;
+/*?*/ USHORT nEndIndex;
+/*?*/ for (USHORT i = 0; i < nCount; i++)
+/*?*/ if ((pItems[i].nRow >= nStartRow) && (pItems[i].nRow <= nEndRow))
+/*?*/ {
+/*?*/ if (!bFound)
+/*?*/ {
+/*?*/ nStartIndex = i;
+/*?*/ bFound = TRUE;
+/*?*/ }
+/*?*/ nEndIndex = i;
+/*?*/ }
+/*?*/ if (bFound)
+/*?*/ DeleteRange( nStartIndex, nEndIndex, nContFlag );
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if ( nDelFlag & IDF_EDITATTR )
+/*N*/ {
+/*?*/ DBG_ASSERT( nContFlag == 0, "DeleteArea: falsche Flags" );
+DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ RemoveEditAttribs( nStartRow, nEndRow );
+/*N*/ }
+/*N*/
+/*N*/ // Attribute erst hier
+/*N*/ if ((nDelFlag & IDF_ATTRIB) == IDF_ATTRIB) pAttrArray->DeleteArea( nStartRow, nEndRow );
+/*N*/ else if ((nDelFlag & IDF_ATTRIB) != 0) pAttrArray->DeleteHardAttr( nStartRow, nEndRow );
+/*N*/ }
+
+
+
+
+// rColumn = Quelle
+// nRow1, nRow2 = Zielposition
+
+
+
+ // Formelzellen werden jetzt schon hier kopiert,
+ // Notizen muessen aber evtl. noch geloescht werden
+
+/*N*/ ScBaseCell* ScColumn::CloneCell(USHORT nIndex, USHORT nFlags,
+/*N*/ ScDocument* pDestDoc, const ScAddress& rDestPos)
+/*N*/ {
+/*N*/ ScBaseCell* pNew = 0;
+/*N*/ ScBaseCell* pSource = pItems[nIndex].pCell;
+/*N*/ switch (pSource->GetCellType())
+/*N*/ {
+/*?*/ case CELLTYPE_NOTE:
+/*?*/ if (nFlags & IDF_NOTE)
+/*?*/ pNew = new ScNoteCell(*(ScNoteCell*)pSource);
+/*?*/ break;
+/*?*/ case CELLTYPE_EDIT:
+/*?*/ if (nFlags & IDF_STRING)
+/*?*/ pNew = new ScEditCell( *(ScEditCell*)pSource, pDestDoc );
+/*?*/ break;
+/*N*/ case CELLTYPE_STRING:
+/*N*/ if (nFlags & IDF_STRING)
+/*N*/ pNew = new ScStringCell(*(ScStringCell*)pSource);
+/*N*/ break;
+/*N*/ case CELLTYPE_VALUE:
+/*N*/ {
+/*N*/ BOOL bDoIns = FALSE;
+/*N*/ USHORT nMask = nFlags & ( IDF_DATETIME | IDF_VALUE );
+/*N*/ if ( nMask == (IDF_DATETIME | IDF_VALUE) )
+/*N*/ bDoIns = TRUE;
+/*N*/ else if ( nMask )
+/*N*/ {
+/*?*/ ULONG nNumIndex = (ULONG)((SfxUInt32Item*) GetAttr(
+/*?*/ pItems[nIndex].nRow, ATTR_VALUE_FORMAT ))->GetValue();
+/*?*/ short nTyp = pDocument->GetFormatTable()->GetType(nNumIndex);
+/*?*/ if (nTyp == NUMBERFORMAT_DATE || nTyp == NUMBERFORMAT_TIME || nTyp == NUMBERFORMAT_DATETIME)
+/*?*/ bDoIns = (nFlags & IDF_DATETIME)!=0;
+/*?*/ else
+/*?*/ bDoIns = (nFlags & IDF_VALUE)!=0;
+/*N*/ }
+/*N*/ if (bDoIns)
+/*N*/ pNew = new ScValueCell(*(ScValueCell*)pSource);
+/*N*/ }
+/*N*/ break;
+/*?*/ case CELLTYPE_FORMULA:
+/*?*/ {
+/*?*/ ScFormulaCell* pForm = (ScFormulaCell*)pSource;
+/*?*/ if (nFlags & IDF_FORMULA)
+/*?*/ {
+DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ pNew = pForm->Clone( pDestDoc, rDestPos, TRUE );
+/*?*/ }
+/*?*/ else if ( (nFlags & (IDF_VALUE | IDF_DATETIME | IDF_STRING)) &&
+/*?*/ !pDestDoc->IsUndo() )
+/*?*/ {
+/*?*/ // #48491# ins Undo-Dokument immer nur die Original-Zelle kopieren,
+/*?*/ // aus Formeln keine Value/String-Zellen erzeugen
+/*?*/
+/*?*/ USHORT nErr = pForm->GetErrCode();
+/*?*/ if ( nErr )
+/*?*/ {
+/*?*/ // Fehler werden immer mit "Zahlen" kopiert
+/*?*/ // (Das ist hiermit willkuerlich so festgelegt)
+/*?*/
+/*?*/ if ( nFlags & IDF_VALUE )
+/*?*/ {
+DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ ScFormulaCell* pErrCell = new ScFormulaCell( pDestDoc, rDestPos );
+/*?*/ }
+/*?*/ }
+/*?*/ else if ( pForm->IsValue() )
+/*?*/ {
+/*?*/ BOOL bDoIns = FALSE;
+/*?*/ USHORT nMask = nFlags & ( IDF_DATETIME | IDF_VALUE );
+/*?*/ if ( nMask == (IDF_DATETIME | IDF_VALUE) )
+/*?*/ bDoIns = TRUE;
+/*?*/ else if ( nMask )
+/*?*/ {
+/*?*/ ULONG nNumIndex = (ULONG)((SfxUInt32Item*) GetAttr(
+/*?*/ pItems[nIndex].nRow, ATTR_VALUE_FORMAT ))->GetValue();
+/*?*/ short nTyp = pDocument->GetFormatTable()->GetType(nNumIndex);
+/*?*/ if (nTyp == NUMBERFORMAT_DATE || nTyp == NUMBERFORMAT_TIME || nTyp == NUMBERFORMAT_DATETIME)
+/*?*/ bDoIns = (nFlags & IDF_DATETIME)!=0;
+/*?*/ else
+/*?*/ bDoIns = (nFlags & IDF_VALUE)!=0;
+/*?*/ }
+/*?*/
+/*?*/ if (bDoIns)
+/*?*/ {
+/*?*/ double nVal = pForm->GetValue();
+/*?*/ pNew = new ScValueCell(nVal);
+/*?*/ }
+/*?*/ }
+/*?*/ else
+/*?*/ {
+/*?*/ if (nFlags & IDF_STRING)
+/*?*/ {
+/*?*/ String aString;
+/*?*/ pForm->GetString(aString);
+/*?*/ if ( aString.Len() )
+/*?*/ pNew = new ScStringCell(aString);
+/*?*/ // #33224# LeerStrings nicht kopieren
+/*?*/ }
+/*?*/ }
+/*?*/ if ( pNew && pSource->GetNotePtr() && ( nFlags & IDF_NOTE ) )
+/*?*/ pNew->SetNote(*pSource->GetNotePtr());
+/*?*/ }
+/*?*/ }
+/*?*/ break;
+/*N*/ }
+/*N*/
+/*N*/ if ( !pNew && pSource->GetNotePtr() && ( nFlags & IDF_NOTE ) )
+/*?*/ pNew = new ScNoteCell(*pSource->GetNotePtr());
+/*N*/
+/*N*/ return pNew;
+/*N*/ }
+
+
+
+
+// Ergebnis in rVal1
+
+
+
+
+
+
+
+/*N*/ ScAttrIterator* ScColumn::CreateAttrIterator( USHORT nStartRow, USHORT nEndRow ) const
+/*N*/ {
+/*N*/ return new ScAttrIterator( pAttrArray, nStartRow, nEndRow );
+/*N*/ }
+
+
+/*N*/ void ScColumn::StartAllListeners()
+/*N*/ {
+/*N*/ if (pItems)
+/*N*/ for (USHORT i = 0; i < nCount; i++)
+/*N*/ {
+/*N*/ ScBaseCell* pCell = pItems[i].pCell;
+/*N*/ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+/*N*/ {
+/*N*/ USHORT nRow = pItems[i].nRow;
+/*N*/ ((ScFormulaCell*)pCell)->StartListeningTo( pDocument );
+/*N*/ if ( nRow != pItems[i].nRow )
+/*N*/ Search( nRow, i ); // Listener eingefuegt?
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void ScColumn::StartNameListeners( BOOL bOnlyRelNames )
+/*N*/ {
+/*N*/ if (pItems)
+/*N*/ {
+/*N*/ USHORT nNameListening = (bOnlyRelNames ? SC_LISTENING_NAMES_REL :
+/*N*/ SC_LISTENING_NAMES_REL | SC_LISTENING_NAMES_ABS);
+/*N*/ for (USHORT i = 0; i < nCount; i++)
+/*N*/ {
+/*N*/ ScBaseCell* pCell = pItems[i].pCell;
+/*N*/ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+/*N*/ {
+/*N*/ USHORT nRow = pItems[i].nRow;
+/*N*/ ((ScFormulaCell*)pCell)->StartListeningTo( pDocument, nNameListening );
+/*N*/ if ( nRow != pItems[i].nRow )
+/*N*/ Search( nRow, i ); // Listener eingefuegt?
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+
+
+
+
+
+// TRUE = Zahlformat gesetzt
+/*N*/ BOOL ScColumn::SetString( USHORT nRow, USHORT nTab, const String& rString )
+/*N*/ {
+/*N*/ BOOL bNumFmtSet = FALSE;
+/*N*/ if (VALIDROW(nRow))
+/*N*/ {
+/*N*/ ScBaseCell* pNewCell = NULL;
+/*N*/ BOOL bIsLoading = FALSE;
+/*N*/ if (rString.Len() > 0)
+/*N*/ {
+/*N*/ double nVal;
+/*N*/ sal_uInt32 nIndex, nOldIndex;
+/*N*/ sal_Unicode cFirstChar;
+/*N*/ SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+/*N*/ SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
+/*N*/ if ( pDocSh )
+/*N*/ bIsLoading = pDocSh->IsLoading();
+/*N*/ // IsLoading bei ConvertFrom Import
+/*N*/ if ( !bIsLoading )
+/*N*/ {
+/*N*/ nIndex = nOldIndex = GetNumberFormat( nRow );
+/*N*/ if ( rString.Len() > 1
+/*N*/ && pFormatter->GetType(nIndex) != NUMBERFORMAT_TEXT )
+/*N*/ cFirstChar = rString.GetChar(0);
+/*N*/ else
+/*N*/ cFirstChar = 0; // Text
+/*N*/ }
+/*N*/ else
+/*N*/ { // waehrend ConvertFrom Import gibt es keine gesetzten Formate
+/*N*/ cFirstChar = rString.GetChar(0);
+/*N*/ }
+/*N*/
+/*N*/ if ( cFirstChar == '=' )
+/*N*/ {
+/*?*/ if ( rString.Len() == 1 ) // = Text
+/*?*/ pNewCell = new ScStringCell( rString );
+/*?*/ else // =Formel
+/*?*/ pNewCell = new ScFormulaCell( pDocument,
+/*?*/ ScAddress( nCol, nRow, nTab ), rString, 0 );
+/*N*/ }
+/*N*/ else if ( cFirstChar == '\'') // 'Text
+/*?*/ pNewCell = new ScStringCell( rString.Copy(1) );
+/*N*/ else
+/*N*/ {
+/*N*/ BOOL bIsText = FALSE;
+/*N*/ if ( bIsLoading )
+/*N*/ {
+/*N*/ if ( pItems && nCount )
+/*N*/ {
+/*?*/ String aStr;
+/*?*/ USHORT i = nCount;
+/*?*/ USHORT nStop = (i >= 3 ? i - 3 : 0);
+/*?*/ // die letzten Zellen vergleichen, ob gleicher String
+/*?*/ // und IsNumberFormat eingespart werden kann
+/*?*/ do
+/*?*/ {
+/*?*/ i--;
+/*?*/ ScBaseCell* pCell = pItems[i].pCell;
+/*?*/ switch ( pCell->GetCellType() )
+/*?*/ {
+/*?*/ case CELLTYPE_STRING :
+/*?*/ ((ScStringCell*)pCell)->GetString( aStr );
+/*?*/ if ( rString == aStr )
+/*?*/ bIsText = TRUE;
+/*?*/ break;
+/*?*/ case CELLTYPE_NOTE : // durch =Formel referenziert
+/*?*/ break;
+/*?*/ default:
+/*?*/ if ( i == nCount - 1 )
+/*?*/ i = 0;
+/*?*/ // wahrscheinlich ganze Spalte kein String
+/*?*/ }
+/*?*/ } while ( i && i > nStop && !bIsText );
+/*N*/ }
+/*N*/ // nIndex fuer IsNumberFormat vorbelegen
+/*N*/ if ( !bIsText )
+/*N*/ nIndex = nOldIndex = pFormatter->GetStandardIndex();
+/*N*/ }
+/*N*/ if ( !bIsText &&
+/*N*/ pFormatter->IsNumberFormat(rString, nIndex, nVal) )
+/*N*/ { // Zahl
+/*?*/ pNewCell = new ScValueCell( nVal );
+/*?*/ if ( nIndex != nOldIndex)
+/*?*/ {
+/*?*/ ApplyAttr( nRow, SfxUInt32Item( ATTR_VALUE_FORMAT,
+/*?*/ (UINT32) nIndex) );
+/*?*/ bNumFmtSet = TRUE;
+/*?*/ }
+/*N*/ }
+/*N*/ else // Text
+/*N*/ pNewCell = new ScStringCell( rString );
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if ( bIsLoading && (!nCount || nRow > pItems[nCount-1].nRow) )
+/*N*/ { // Search einsparen und ohne Umweg ueber Insert, Listener aufbauen
+/*N*/ // und Broadcast kommt eh erst nach dem Laden
+/*N*/ if ( pNewCell )
+/*N*/ Append( nRow, pNewCell );
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ USHORT i;
+/*N*/ if (Search(nRow, i))
+/*N*/ {
+/*?*/ ScBaseCell* pOldCell = pItems[i].pCell;
+/*?*/ const ScPostIt* pNote = pOldCell->GetNotePtr();
+/*?*/ ScBroadcasterList* pBC = pOldCell->GetBroadcaster();
+/*?*/ if (pNewCell || pNote || pBC)
+/*?*/ {
+/*?*/ if (!pNewCell)
+/*?*/ pNewCell = new ScNoteCell();
+/*?*/ if (pNote)
+/*?*/ pNewCell->SetNote(*pNote);
+/*?*/ if (pBC)
+/*?*/ {
+/*?*/ pNewCell->SetBroadcaster(pBC);
+/*?*/ pOldCell->ForgetBroadcaster();
+/*?*/ pLastFormulaTreeTop = 0; // Err527 Workaround
+/*?*/ }
+/*?*/
+/*?*/ if ( pOldCell->GetCellType() == CELLTYPE_FORMULA )
+/*?*/ {
+/*?*/ pOldCell->EndListeningTo( pDocument );
+/*?*/ // falls in EndListening NoteCell in gleicher Col zerstoert
+/*?*/ if ( i >= nCount || pItems[i].nRow != nRow )
+/*?*/ Search(nRow, i);
+/*?*/ }
+/*?*/ pOldCell->Delete();
+/*?*/ pItems[i].pCell = pNewCell; // ersetzen
+/*?*/ if ( pNewCell->GetCellType() == CELLTYPE_FORMULA )
+/*?*/ {
+/*?*/ pNewCell->StartListeningTo( pDocument );
+/*?*/ ((ScFormulaCell*)pNewCell)->SetDirty();
+/*?*/ }
+/*?*/ else
+/*?*/ pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED,
+/*?*/ ScAddress( nCol, nRow, nTab ), pNewCell ) );
+/*?*/ }
+/*?*/ else
+/*?*/ {
+/*?*/ DeleteAtIndex(i); // loeschen und Broadcast
+/*?*/ }
+/*N*/ }
+/*N*/ else if (pNewCell)
+/*N*/ {
+/*N*/ Insert(nRow, pNewCell); // neu eintragen und Broadcast
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ // hier keine Formate mehr fuer Formeln setzen!
+/*N*/ // (werden bei der Ausgabe abgefragt)
+/*N*/
+/*N*/ }
+/*N*/ return bNumFmtSet;
+/*N*/ }
+
+
+
+//
+// GetDataEntries - Strings aus zusammenhaengendem Bereich um nRow
+//
+
+// DATENT_MAX - max. Anzahl Eintrage in Liste fuer Auto-Eingabe
+// DATENT_SEARCH - max. Anzahl Zellen, die durchsucht werden - neu: nur Strings zaehlen
+#define DATENT_MAX 200
+#define DATENT_SEARCH 2000
+
+
+
+#undef DATENT_MAX
+#undef DATENT_SEARCH
+
+
+
+
+/*N*/ void ScColumn::SetError( USHORT nRow, const USHORT nError)
+/*N*/ {
+/*N*/ if (VALIDROW(nRow))
+/*N*/ {
+/*N*/ ScFormulaCell* pCell = new ScFormulaCell
+/*N*/ ( pDocument, ScAddress( nCol, nRow, nTab ) );
+/*N*/ pCell->SetErrCode( nError );
+/*N*/ Insert( nRow, pCell );
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void ScColumn::SetValue( USHORT nRow, const double& rVal)
+/*N*/ {
+/*N*/ if (VALIDROW(nRow))
+/*N*/ {
+/*N*/ ScBaseCell* pCell = new ScValueCell(rVal);
+/*N*/ Insert( nRow, pCell );
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void ScColumn::SetNote( USHORT nRow, const ScPostIt& rNote)
+/*N*/ {
+/*N*/ BOOL bEmpty = !rNote.GetText().Len();
+/*N*/
+/*N*/ USHORT nIndex;
+/*N*/ if (Search(nRow, nIndex))
+/*N*/ {
+/*N*/ ScBaseCell* pCell = pItems[nIndex].pCell;
+/*N*/ if (bEmpty && pCell->GetCellType() == CELLTYPE_NOTE && !pCell->GetBroadcaster())
+/*?*/ DeleteAtIndex(nIndex);
+/*N*/ else
+/*N*/ pCell->SetNote(rNote);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ if (!bEmpty)
+/*N*/ Insert(nRow, new ScNoteCell(rNote));
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void ScColumn::GetString( USHORT nRow, String& rString ) const
+/*N*/ {
+/*N*/ USHORT nIndex;
+/*N*/ Color* pColor;
+/*N*/ if (Search(nRow, nIndex))
+/*N*/ {
+/*N*/ ScBaseCell* pCell = pItems[nIndex].pCell;
+/*N*/ if (pCell->GetCellType() != CELLTYPE_NOTE)
+/*N*/ {
+/*N*/ ULONG nFormat = GetNumberFormat( nRow );
+/*N*/ ScCellFormat::GetString( pCell, nFormat, rString, &pColor, *(pDocument->GetFormatTable()) );
+/*N*/ }
+/*N*/ else
+/*N*/ rString.Erase();
+/*N*/ }
+/*N*/ else
+/*N*/ rString.Erase();
+/*N*/ }
+
+
+/*N*/ void ScColumn::GetInputString( USHORT nRow, String& rString ) const
+/*N*/ {
+/*N*/ USHORT nIndex;
+/*N*/ if (Search(nRow, nIndex))
+/*N*/ {
+/*?*/ ScBaseCell* pCell = pItems[nIndex].pCell;
+/*?*/ if (pCell->GetCellType() != CELLTYPE_NOTE)
+/*?*/ {
+/*?*/ ULONG nFormat = GetNumberFormat( nRow );
+/*?*/ ScCellFormat::GetInputString( pCell, nFormat, rString, *(pDocument->GetFormatTable()) );
+/*?*/ }
+/*?*/ else
+/*?*/ rString.Erase();
+/*N*/ }
+/*N*/ else
+/*N*/ rString.Erase();
+/*N*/ }
+
+
+/*N*/ double ScColumn::GetValue( USHORT nRow ) const
+/*N*/ {
+/*N*/ USHORT nIndex;
+/*N*/ if (Search(nRow, nIndex))
+/*N*/ {
+/*N*/ ScBaseCell* pCell = pItems[nIndex].pCell;
+/*N*/ switch (pCell->GetCellType())
+/*N*/ {
+/*N*/ case CELLTYPE_VALUE:
+/*N*/ return ((ScValueCell*)pCell)->GetValue();
+/*N*/ break;
+/*N*/ case CELLTYPE_FORMULA:
+/*N*/ {
+/*N*/ if (((ScFormulaCell*)pCell)->IsValue())
+/*N*/ return ((ScFormulaCell*)pCell)->GetValue();
+/*N*/ else
+/*N*/ return 0.0;
+/*N*/ }
+/*N*/ break;
+/*N*/ default:
+/*N*/ return 0.0;
+/*N*/ break;
+/*N*/ }
+/*N*/ }
+/*N*/ return 0.0;
+/*N*/ }
+
+/*N*/ BOOL ScColumn::GetNote( USHORT nRow, ScPostIt& rNote) const
+/*N*/ {
+/*N*/ BOOL bHasNote = FALSE;
+/*N*/ USHORT nIndex;
+/*N*/ if (Search(nRow, nIndex))
+/*N*/ bHasNote = pItems[nIndex].pCell->GetNote(rNote);
+/*N*/ else
+/*?*/ rNote.Clear();
+/*N*/
+/*N*/ return bHasNote;
+/*N*/ }
+
+
+/*N*/ CellType ScColumn::GetCellType( USHORT nRow ) const
+/*N*/ {
+/*N*/ USHORT nIndex;
+/*N*/ if (Search(nRow, nIndex))
+/*N*/ return pItems[nIndex].pCell->GetCellType();
+/*N*/ return CELLTYPE_NONE;
+/*N*/ }
+
+
+/*N*/ USHORT ScColumn::GetErrCode( USHORT nRow ) const
+/*N*/ {
+/*N*/ USHORT nIndex;
+/*N*/ if (Search(nRow, nIndex))
+/*N*/ {
+/*N*/ ScBaseCell* pCell = pItems[nIndex].pCell;
+/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+/*N*/ return ((ScFormulaCell*)pCell)->GetErrCode();
+/*N*/ }
+/*N*/ return 0;
+/*N*/ }
+
+
+/*N*/ BOOL ScColumn::HasStringData( USHORT nRow ) const
+/*N*/ {
+/*N*/ USHORT nIndex;
+/*N*/ if (Search(nRow, nIndex))
+/*N*/ return (pItems[nIndex].pCell)->HasStringData();
+/*N*/ return FALSE;
+/*N*/ }
+
+
+/*N*/ BOOL ScColumn::HasValueData( USHORT nRow ) const
+/*N*/ {
+/*N*/ USHORT nIndex;
+/*N*/ if (Search(nRow, nIndex))
+/*N*/ return (pItems[nIndex].pCell)->HasValueData();
+/*N*/ return FALSE;
+/*N*/ }
+
+
+
+
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */