diff options
author | Bartosz Kosiorek <gang65@poczta.onet.pl> | 2018-01-19 16:08:30 +0100 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2018-03-15 18:21:06 +0100 |
commit | 45d5c18a9a643590b18e7cc48ab80076a31b75b3 (patch) | |
tree | a266a4be78b558a11891ed5b716cf2d9df4b417e | |
parent | eeb4a2ec37bf88b26a9f243cc5682e96c9e35df6 (diff) |
tdf#50916 Refactor of the table7.cxx to allow dynamic column size
Change-Id: I60ea249ca621e25b3585e1d2f75bdf15d96f6dcc
Reviewed-on: https://gerrit.libreoffice.org/48205
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Reviewed-by: Eike Rathke <erack@redhat.com>
-rw-r--r-- | sc/inc/column.hxx | 2 | ||||
-rw-r--r-- | sc/inc/table.hxx | 37 | ||||
-rw-r--r-- | sc/source/core/data/column4.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 15 | ||||
-rw-r--r-- | sc/source/core/data/table7.cxx | 74 |
5 files changed, 74 insertions, 56 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index ff22791b6f7c..9957b05225fd 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -362,7 +362,7 @@ public: void SetRawString( SCROW nRow, const svl::SharedString& rStr ); void SetRawString( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, const svl::SharedString& rStr, bool bBroadcast = true ); void SetValue( SCROW nRow, double fVal ); - void SetValues( SCROW nRow, const std::vector<double>& rVals ); + void SetValues( const SCROW nRow, const std::vector<double>& rVals ); void SetValue( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, double fVal, bool bBroadcast = true ); void SetError( SCROW nRow, const FormulaError nError); diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index a7b3e6352cec..5a1cd564a759 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -277,11 +277,11 @@ public: ScOutlineTable* GetOutlineTable() { return pOutlineTable; } - ScColumn& CreateColumnIfNotExists( SCCOL nScCol ) + ScColumn& CreateColumnIfNotExists( const SCCOL nScCol ) { if ( nScCol >= aCol.size() ) { - SCCOL aOldColSize = aCol.size(); + const SCCOL aOldColSize = aCol.size(); bool bUseEmptyAttrArray = false; if ( aOldColSize == 0 ) bUseEmptyAttrArray = true; @@ -316,15 +316,15 @@ public: bool IsStreamValid() const { return bStreamValid; } void SetStreamValid( bool bSet, bool bIgnoreLock = false ); - SAL_WARN_UNUSED_RESULT bool IsColValid( SCCOL nScCol ) const + SAL_WARN_UNUSED_RESULT bool IsColValid( const SCCOL nScCol ) const { return nScCol >= static_cast< SCCOL >( 0 ) && nScCol < aCol.size(); } - SAL_WARN_UNUSED_RESULT bool IsColRowValid( SCCOL nScCol, SCROW nScRow ) const + SAL_WARN_UNUSED_RESULT bool IsColRowValid( const SCCOL nScCol, const SCROW nScRow ) const { return IsColValid( nScCol ) && ValidRow( nScRow ); } - SAL_WARN_UNUSED_RESULT bool IsColRowTabValid( SCCOL nScCol, SCROW nScRow, SCTAB nScTab ) const + SAL_WARN_UNUSED_RESULT bool IsColRowTabValid( const SCCOL nScCol, const SCROW nScRow, const SCTAB nScTab ) const { return IsColValid( nScCol ) && ValidRow( nScRow ) && ValidTab( nScTab ); } @@ -400,7 +400,7 @@ public: bool IsSelectionEditable( const ScMarkData& rMark, bool* pOnlyNotBecauseOfMatrix = nullptr ) const; - bool HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const; + bool HasBlockMatrixFragment( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ) const; bool HasSelectionMatrixFragment( const ScMarkData& rMark ) const; bool IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes ) const; @@ -428,12 +428,12 @@ public: bool SetFormulaCells( SCCOL nCol, SCROW nRow, std::vector<ScFormulaCell*>& rCells ); - bool HasFormulaCell( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const; + bool HasFormulaCell( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ) const; svl::SharedString GetSharedString( SCCOL nCol, SCROW nRow ) const; void SetValue( SCCOL nCol, SCROW nRow, const double& rVal ); - void SetValues( SCCOL nCol, SCROW nRow, const std::vector<double>& rVals ); + void SetValues( const SCCOL nCol, const SCROW nRow, const std::vector<double>& rVals ); void SetError( SCCOL nCol, SCROW nRow, FormulaError nError); SCSIZE GetPatternCount( SCCOL nCol ) const; SCSIZE GetPatternCount( SCCOL nCol, SCROW nRow1, SCROW nRow2 ) const; @@ -505,7 +505,9 @@ public: sc::CopyFromClipContext& rCxt, const ScTable& rClipTab, sc::ColumnSpanSet& rBroadcastSpans ); void CopyOneCellFromClip( - sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCROW nSrcRow, const ScTable* pSrcTab ); + sc::CopyFromClipContext& rCxt, const SCCOL nCol1, const SCROW nRow1, + const SCCOL nCol2, const SCROW nRow2, + const SCROW nSrcRow, const ScTable* pSrcTab ); void CopyFromClip( sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, @@ -978,7 +980,7 @@ public: SvtScriptType GetScriptType( SCCOL nCol, SCROW nRow ) const; void SetScriptType( SCCOL nCol, SCROW nRow, SvtScriptType nType ); - void UpdateScriptTypes( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ); + void UpdateScriptTypes( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ); SvtScriptType GetRangeScriptType( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 ); @@ -1032,21 +1034,22 @@ public: */ void BroadcastRecalcOnRefMove(); - void CollectListeners( std::vector<SvtListener*>& rListeners, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ); + void CollectListeners( std::vector<SvtListener*>& rListeners, const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ); void TransferListeners( ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCCOL nColDelta, SCROW nRowDelta ); - void TransferCellValuesTo( SCCOL nCol, SCROW nRow, size_t nLen, sc::CellValues& rDest ); - void CopyCellValuesFrom( SCCOL nCol, SCROW nRow, const sc::CellValues& rSrc ); + void TransferCellValuesTo( const SCCOL nCol, SCROW nRow, size_t nLen, sc::CellValues& rDest ); + void CopyCellValuesFrom( const SCCOL nCol, SCROW nRow, const sc::CellValues& rSrc ); std::unique_ptr<sc::ColumnIterator> GetColumnIterator( SCCOL nCol, SCROW nRow1, SCROW nRow2 ) const; - void EnsureFormulaCellResults( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ); + void EnsureFormulaCellResults( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ); void ConvertFormulaToValue( - sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + sc::EndListeningContext& rCxt, + const SCCOL nCol1, const SCROW nRow1, const SCCOL nCol2, const SCROW nRow2, sc::TableValues* pUndo ); void SwapNonEmpty( @@ -1225,10 +1228,10 @@ private: sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, std::vector<ScAddress>* pGroupPos ); void EndListeningIntersectedGroups( - sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + sc::EndListeningContext& rCxt, const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2, std::vector<ScAddress>* pGroupPos ); - void EndListeningGroup( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow ); + void EndListeningGroup( sc::EndListeningContext& rCxt, const SCCOL nCol, SCROW nRow ); void SetNeedsListeningGroup( SCCOL nCol, SCROW nRow ); /** diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx index d76b17496fb0..3c8871f7b111 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -306,7 +306,7 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, } } -void ScColumn::SetValues( SCROW nRow, const std::vector<double>& rVals ) +void ScColumn::SetValues( const SCROW nRow, const std::vector<double>& rVals ) { if (!ValidRow(nRow)) return; diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 67e4da17f9c8..4e51b19b345e 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2224,13 +2224,18 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC } } -bool ScTable::HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const +bool ScTable::HasBlockMatrixFragment( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ) const { using namespace sc; + if ( !IsColValid( nCol1 ) ) + return false; + + const SCCOL nMaxCol2 = std::min<SCCOL>( nCol2, aCol.size() - 1 ); + MatrixEdge nEdges = MatrixEdge::Nothing; - if ( nCol1 == nCol2 ) + if ( nCol1 == nMaxCol2 ) { // left and right column const MatrixEdge n = MatrixEdge::Left | MatrixEdge::Right; nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, n ); @@ -2243,7 +2248,7 @@ bool ScTable::HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCR if ((nEdges != MatrixEdge::Nothing) && ((!(nEdges & MatrixEdge::Left)) || (nEdges & (MatrixEdge::Inside|MatrixEdge::Open)))) return true; // left edge missing or open // right column - nEdges = aCol[nCol2].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdge::Right); + nEdges = aCol[nMaxCol2].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdge::Right); if ((nEdges != MatrixEdge::Nothing) && ((!(nEdges & MatrixEdge::Right)) || (nEdges & (MatrixEdge::Inside|MatrixEdge::Open)))) return true; // right edge is missing or open } @@ -2252,7 +2257,7 @@ bool ScTable::HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCR { // Row on top and on bottom bool bOpen = false; const MatrixEdge n = MatrixEdge::Bottom | MatrixEdge::Top; - for ( SCCOL i=nCol1; i<=nCol2; i++) + for ( SCCOL i=nCol1; i<=nMaxCol2; i++) { nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow1, n ); if (nEdges != MatrixEdge::Nothing) @@ -2280,7 +2285,7 @@ bool ScTable::HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCR j++, n = MatrixEdge::Bottom, nR=nRow2) { bool bOpen = false; - for ( SCCOL i=nCol1; i<=nCol2; i++) + for ( SCCOL i=nCol1; i<=nMaxCol2; i++) { nEdges = aCol[i].GetBlockMatrixEdges( nR, nR, n ); if ( nEdges != MatrixEdge::Nothing) diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx index 54a84e31e20f..8ba58ccde185 100644 --- a/sc/source/core/data/table7.cxx +++ b/sc/source/core/data/table7.cxx @@ -118,7 +118,7 @@ void ScTable::DeleteBeforeCopyFromClip( } void ScTable::CopyOneCellFromClip( - sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCROW nSrcRow, const ScTable* pSrcTab ) + sc::CopyFromClipContext& rCxt, const SCCOL nCol1, const SCROW nRow1, const SCCOL nCol2, const SCROW nRow2, const SCROW nSrcRow, const ScTable* pSrcTab ) { ScRange aSrcRange = rCxt.getClipDoc()->GetClipParam().getWholeRange(); SCCOL nSrcColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1; @@ -142,39 +142,39 @@ void ScTable::CopyOneCellFromClip( mpRowHeights->setValue(nRow1, nRow2, pSrcTab->GetOriginalHeight(nSrcRow)); } -void ScTable::SetValues( SCCOL nCol, SCROW nRow, const std::vector<double>& rVals ) +void ScTable::SetValues( const SCCOL nCol, const SCROW nRow, const std::vector<double>& rVals ) { if (!ValidCol(nCol)) return; - aCol[nCol].SetValues(nRow, rVals); + CreateColumnIfNotExists(nCol).SetValues(nRow, rVals); } -void ScTable::TransferCellValuesTo( SCCOL nCol, SCROW nRow, size_t nLen, sc::CellValues& rDest ) +void ScTable::TransferCellValuesTo( const SCCOL nCol, SCROW nRow, size_t nLen, sc::CellValues& rDest ) { if (!ValidCol(nCol)) return; - aCol[nCol].TransferCellValuesTo(nRow, nLen, rDest); + CreateColumnIfNotExists(nCol).TransferCellValuesTo(nRow, nLen, rDest); } -void ScTable::CopyCellValuesFrom( SCCOL nCol, SCROW nRow, const sc::CellValues& rSrc ) +void ScTable::CopyCellValuesFrom( const SCCOL nCol, SCROW nRow, const sc::CellValues& rSrc ) { if (!ValidCol(nCol)) return; - aCol[nCol].CopyCellValuesFrom(nRow, rSrc); + CreateColumnIfNotExists(nCol).CopyCellValuesFrom(nRow, rSrc); } void ScTable::ConvertFormulaToValue( - sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + sc::EndListeningContext& rCxt, const SCCOL nCol1, const SCROW nRow1, const SCCOL nCol2, const SCROW nRow2, sc::TableValues* pUndo ) { if (!ValidCol(nCol1) || !ValidCol(nCol2) || nCol1 > nCol2) return; for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) - aCol[nCol].ConvertFormulaToValue(rCxt, nRow1, nRow2, pUndo); + CreateColumnIfNotExists(nCol).ConvertFormulaToValue(rCxt, nRow1, nRow2, pUndo); } void ScTable::SwapNonEmpty( @@ -183,7 +183,7 @@ void ScTable::SwapNonEmpty( const ScRange& rRange = rValues.getRange(); assert(rRange.IsValid()); for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol) - aCol[nCol].SwapNonEmpty(rValues, rStartCxt, rEndCxt); + CreateColumnIfNotExists(nCol).SwapNonEmpty(rValues, rStartCxt, rEndCxt); } void ScTable::PreprocessRangeNameUpdate( @@ -207,12 +207,14 @@ void ScTable::CompileHybridFormula( aCol[i].CompileHybridFormula(rStartListenCxt, rCompileCxt); } -void ScTable::UpdateScriptTypes( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) +void ScTable::UpdateScriptTypes( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ) { - if (!ValidCol(nCol1) || !ValidCol(nCol2) || nCol1 > nCol2) + if (!IsColValid(nCol1) || !ValidCol(nCol2) || nCol1 > nCol2) return; - for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) + const SCCOL nMaxCol2 = std::min<SCCOL>( nCol2, aCol.size() - 1 ); + + for (SCCOL nCol = nCol1; nCol <= nMaxCol2; ++nCol) aCol[nCol].UpdateScriptTypes(nRow1, nRow2); } @@ -231,7 +233,7 @@ bool ScTable::HasUniformRowHeight( SCROW nRow1, SCROW nRow2 ) const void ScTable::SplitFormulaGroups( SCCOL nCol, std::vector<SCROW>& rRows ) { - if (!ValidCol(nCol)) + if (!IsColValid(nCol)) return; sc::SharedFormulaUtil::splitFormulaCellGroups(aCol[nCol].maCells, rRows); @@ -239,7 +241,7 @@ void ScTable::SplitFormulaGroups( SCCOL nCol, std::vector<SCROW>& rRows ) void ScTable::UnshareFormulaCells( SCCOL nCol, std::vector<SCROW>& rRows ) { - if (!ValidCol(nCol)) + if (!IsColValid(nCol)) return; sc::SharedFormulaUtil::unshareFormulaCells(aCol[nCol].maCells, rRows); @@ -247,28 +249,32 @@ void ScTable::UnshareFormulaCells( SCCOL nCol, std::vector<SCROW>& rRows ) void ScTable::RegroupFormulaCells( SCCOL nCol ) { - if (!ValidCol(nCol)) + if (!IsColValid(nCol)) return; aCol[nCol].RegroupFormulaCells(); } void ScTable::CollectListeners( - std::vector<SvtListener*>& rListeners, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) + std::vector<SvtListener*>& rListeners, const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ) { - if (nCol2 < nCol1 || !ValidCol(nCol1) || !ValidCol(nCol2)) + if (nCol2 < nCol1 || !IsColValid(nCol1) || !ValidCol(nCol2)) return; - for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) + const SCCOL nMaxCol2 = std::min<SCCOL>( nCol2, aCol.size() - 1 ); + + for (SCCOL nCol = nCol1; nCol <= nMaxCol2; ++nCol) aCol[nCol].CollectListeners(rListeners, nRow1, nRow2); } -bool ScTable::HasFormulaCell( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const +bool ScTable::HasFormulaCell( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ) const { - if (nCol2 < nCol1 || !ValidCol(nCol1) || !ValidCol(nCol2)) + if (nCol2 < nCol1 || !IsColValid(nCol1) || !ValidCol(nCol2)) return false; - for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) + const SCCOL nMaxCol2 = std::min<SCCOL>( nCol2, aCol.size() - 1 ); + + for (SCCOL nCol = nCol1; nCol <= nMaxCol2; ++nCol) if (aCol[nCol].HasFormulaCell(nRow1, nRow2)) return true; @@ -278,26 +284,28 @@ bool ScTable::HasFormulaCell( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 void ScTable::EndListeningIntersectedGroup( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, std::vector<ScAddress>* pGroupPos ) { - if (!ValidCol(nCol)) + if (!IsColValid(nCol)) return; aCol[nCol].EndListeningIntersectedGroup(rCxt, nRow, pGroupPos); } void ScTable::EndListeningIntersectedGroups( - sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + sc::EndListeningContext& rCxt, const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2, std::vector<ScAddress>* pGroupPos ) { - if (nCol2 < nCol1 || !ValidCol(nCol1) || !ValidCol(nCol2)) + if (nCol2 < nCol1 || !IsColValid(nCol1) || !ValidCol(nCol2)) return; - for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) + const SCCOL nMaxCol2 = std::min<SCCOL>( nCol2, aCol.size() - 1 ); + + for (SCCOL nCol = nCol1; nCol <= nMaxCol2; ++nCol) aCol[nCol].EndListeningIntersectedGroups(rCxt, nRow1, nRow2, pGroupPos); } -void ScTable::EndListeningGroup( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow ) +void ScTable::EndListeningGroup( sc::EndListeningContext& rCxt, const SCCOL nCol, SCROW nRow ) { - if (!ValidCol(nCol)) + if (!IsColValid(nCol)) return; aCol[nCol].EndListeningGroup(rCxt, nRow); @@ -308,7 +316,7 @@ void ScTable::SetNeedsListeningGroup( SCCOL nCol, SCROW nRow ) if (!ValidCol(nCol)) return; - aCol[nCol].SetNeedsListeningGroup(nRow); + CreateColumnIfNotExists(nCol).SetNeedsListeningGroup(nRow); } bool ScTable::IsEditActionAllowed( @@ -400,12 +408,14 @@ std::unique_ptr<sc::ColumnIterator> ScTable::GetColumnIterator( SCCOL nCol, SCRO return aCol[nCol].GetColumnIterator(nRow1, nRow2); } -void ScTable::EnsureFormulaCellResults( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) +void ScTable::EnsureFormulaCellResults( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ) { - if (nCol2 < nCol1 || !ValidCol(nCol1) || !ValidCol(nCol2)) + if (nCol2 < nCol1 || !IsColValid(nCol1) || !ValidCol(nCol2)) return; - for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) + const SCCOL nMaxCol2 = std::min<SCCOL>( nCol2, aCol.size() - 1 ); + + for (SCCOL nCol = nCol1; nCol <= nMaxCol2; ++nCol) aCol[nCol].EnsureFormulaCellResults(nRow1, nRow2); } |