Commits

Anonymous committed 7263080

calcdatatables: UI handling of insert/delete not possible status

  • Participants
  • Parent commits 4360005

Comments (0)

Files changed (7)

File sc/inc/document.hxx

 													SCCOL& rEndCol, SCROW& rEndRow );
 	void			LimitChartIfAll( ScRangeListRef& rRangeList );
 
-	BOOL			InsertRow( SCCOL nStartCol, SCTAB nStartTab,
-							   SCCOL nEndCol,   SCTAB nEndTab,
+    /** @returns 0 if inserted, else globstr STR_... code */
+    sal_uInt16      InsertRow( SCCOL nStartCol, SCTAB nStartTab,
+                               SCCOL nEndCol,   SCTAB nEndTab,
                                SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL,
                                const ScMarkData* pTabMark = NULL );
-	SC_DLLPUBLIC BOOL			InsertRow( const ScRange& rRange, ScDocument* pRefUndoDoc = NULL );
-	void			DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
-							   SCCOL nEndCol,   SCTAB nEndTab,
-							   SCROW nStartRow, SCSIZE nSize,
+    /** @returns 0 if inserted, else globstr STR_... code */
+    SC_DLLPUBLIC sal_uInt16     InsertRow( const ScRange& rRange, ScDocument* pRefUndoDoc = NULL );
+    /** @returns 0 if deleted, else globstr STR_... code */
+    sal_uInt16      DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
+                               SCCOL nEndCol,   SCTAB nEndTab,
+                               SCROW nStartRow, SCSIZE nSize,
                                ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL,
                                const ScMarkData* pTabMark = NULL );
-	void			DeleteRow( const ScRange& rRange,
-							   ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL );
-	BOOL			InsertCol( SCROW nStartRow, SCTAB nStartTab,
-							   SCROW nEndRow,   SCTAB nEndTab,
+    /** @returns 0 if deleted, else globstr STR_... code */
+    sal_uInt16      DeleteRow( const ScRange& rRange,
+                               ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL );
+    /** @returns 0 if inserted, else globstr STR_... code */
+    sal_uInt16      InsertCol( SCROW nStartRow, SCTAB nStartTab,
+                               SCROW nEndRow,   SCTAB nEndTab,
                                SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL,
                                const ScMarkData* pTabMark = NULL );
-	SC_DLLPUBLIC BOOL			InsertCol( const ScRange& rRange, ScDocument* pRefUndoDoc = NULL );
-	void			DeleteCol( SCROW nStartRow, SCTAB nStartTab,
-							   SCROW nEndRow, SCTAB nEndTab,
-							   SCCOL nStartCol, SCSIZE nSize,
+    /** @returns 0 if inserted, else globstr STR_... code */
+    SC_DLLPUBLIC sal_uInt16     InsertCol( const ScRange& rRange, ScDocument* pRefUndoDoc = NULL );
+    /** @returns 0 if deleted, else globstr STR_... code */
+    sal_uInt16      DeleteCol( SCROW nStartRow, SCTAB nStartTab,
+                               SCROW nEndRow, SCTAB nEndTab,
+                               SCCOL nStartCol, SCSIZE nSize,
                                ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL,
                                const ScMarkData* pTabMark = NULL );
-	void			DeleteCol( const ScRange& rRange,
-							   ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL );
+    /** @returns 0 if deleted, else globstr STR_... code */
+    sal_uInt16      DeleteCol( const ScRange& rRange,
+                               ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL );
 
-	BOOL			CanInsertRow( const ScRange& rRange ) const;
-	BOOL			CanInsertCol( const ScRange& rRange ) const;
+    BOOL            CanInsertRow( const ScRange& rRange ) const;
+    BOOL            CanInsertCol( const ScRange& rRange ) const;
 
     void            FitBlock( const ScRange& rOld, const ScRange& rNew,
                               BOOL bClear = TRUE, USHORT nDelFlags = IDF_ALL );
-	BOOL			CanFitBlock( const ScRange& rOld, const ScRange& rNew );
+    BOOL            CanFitBlock( const ScRange& rOld, const ScRange& rNew );
 
 	BOOL			IsClipOrUndo() const 						{ return bIsClip || bIsUndo; }
 	BOOL			IsUndo() const								{ return bIsUndo; }

File sc/inc/globstr.hrc

 #define STR_UNDO_SET_TAB_BG_COLOR       438
 #define STR_UNDO_SET_MULTI_TAB_BG_COLOR 439
 
-#define STR_COUNT                       440
+#define STR_SHIFT_CELLS_TABLE       440
+
+#define STR_COUNT                   441
 
 #endif
 

File sc/source/core/data/document.cxx

 }
 
 
-BOOL ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
+sal_uInt16 ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
 							SCCOL nEndCol,   SCTAB nEndTab,
                             SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc,
                             const ScMarkData* pTabMark )
 	}
 
 	BOOL bTest = TRUE;
-	BOOL bRet = FALSE;
+	sal_uInt16 nStatus = 0;
 	BOOL bOldAutoCalc = GetAutoCalc();
 	SetAutoCalc( FALSE );	// Mehrfachberechnungen vermeiden
 	for ( i = nStartTab; i <= nEndTab && bTest; i++)
     // Before references are updated, obtain DataTables before possibly being 
     // expanded, and test for fragments.
     ::std::vector<sal_uInt32> aDataTables;
-    if (bTest)
-        bTest = FindDataTablesInsert( aDataTables, nStartCol, nEndCol, 
-                nStartRow, nStartTab, nEndTab, pTabMark, false /*row*/, false /*nottestonly*/);
-
-	if (bTest)
+    if (!bTest)
+        nStatus = STR_INSERT_FULL;
+    else if (!FindDataTablesInsert( aDataTables, nStartCol, nEndCol, 
+                nStartRow, nStartTab, nEndTab, pTabMark, false /*row*/, false /*nottestonly*/))
+        nStatus = STR_SHIFT_CELLS_TABLE;
+
+	if (nStatus == 0)
 	{
         const ::std::vector<sal_uInt32> * pDataTables = (aDataTables.size() ? &aDataTables : NULL);
 
 				if (pTab[i])
 					pTab[i]->SetRelNameDirty();
 		}
-		bRet = TRUE;
 	}
 	SetAutoCalc( bOldAutoCalc );
-	if ( bRet )
+	if (nStatus == 0)
 		pChartListenerCollection->UpdateDirtyCharts();
-	return bRet;
-}
-
-
-BOOL ScDocument::InsertRow( const ScRange& rRange, ScDocument* pRefUndoDoc )
+	return nStatus;
+}
+
+
+sal_uInt16 ScDocument::InsertRow( const ScRange& rRange, ScDocument* pRefUndoDoc )
 {
 	return InsertRow( rRange.aStart.Col(), rRange.aStart.Tab(),
 					  rRange.aEnd.Col(),   rRange.aEnd.Tab(),
 }
 
 
-void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
+sal_uInt16 ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
 							SCCOL nEndCol,   SCTAB nEndTab,
 							SCROW nStartRow, SCSIZE nSize,
                             ScDocument* pRefUndoDoc, BOOL* pUndoOutline,
 	    nEndTab = MAXTAB;
 	}
 
-    bool bTest = TestDataTablesDelete( nStartCol, nEndCol, nStartRow, nSize, 
-            nStartTab, nEndTab, pTabMark, false /*row*/);
-    if (!bTest)
-        /* FIXME: return value and UI needed */
-        return;
+    if (!TestDataTablesDelete( nStartCol, nEndCol, nStartRow, nSize, 
+                nStartTab, nEndTab, pTabMark, false /*row*/))
+        return STR_SHIFT_CELLS_TABLE;
 
 	BOOL bOldAutoCalc = GetAutoCalc();
 	SetAutoCalc( FALSE );	// Mehrfachberechnungen vermeiden
 
 	SetAutoCalc( bOldAutoCalc );
 	pChartListenerCollection->UpdateDirtyCharts();
-}
-
-
-void ScDocument::DeleteRow( const ScRange& rRange, ScDocument* pRefUndoDoc, BOOL* pUndoOutline )
-{
-	DeleteRow( rRange.aStart.Col(), rRange.aStart.Tab(),
+    return 0;
+}
+
+
+sal_uInt16 ScDocument::DeleteRow( const ScRange& rRange, ScDocument* pRefUndoDoc, BOOL* pUndoOutline )
+{
+	return DeleteRow( rRange.aStart.Col(), rRange.aStart.Tab(),
 			   rRange.aEnd.Col(),   rRange.aEnd.Tab(),
 			   rRange.aStart.Row(), static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1),
 			   pRefUndoDoc, pUndoOutline );
 }
 
 
-BOOL ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
+sal_uInt16 ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
 							SCROW nEndRow,   SCTAB nEndTab,
                             SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc,
                             const ScMarkData* pTabMark )
 	}
 
 	BOOL bTest = TRUE;
-	BOOL bRet = FALSE;
+	sal_uInt16 nStatus = 0;
 	BOOL bOldAutoCalc = GetAutoCalc();
 	SetAutoCalc( FALSE );	// Mehrfachberechnungen vermeiden
 	for ( i = nStartTab; i <= nEndTab && bTest; i++)
     // Before references are updated, obtain DataTables before possibly being 
     // expanded, and test for fragments.
     ::std::vector<sal_uInt32> aDataTables;
-    if (bTest)
-        bTest = FindDataTablesInsert( aDataTables, nStartRow, nEndRow, 
-                nStartCol, nStartTab, nEndTab, pTabMark, true /*col*/, true /*testonly*/);
-
-	if (bTest)
+	if (!bTest)
+        nStatus = STR_INSERT_FULL;
+    else if (!FindDataTablesInsert( aDataTables, nStartRow, nEndRow, 
+                nStartCol, nStartTab, nEndTab, pTabMark, true /*col*/, true /*testonly*/))
+        nStatus = STR_SHIFT_CELLS_TABLE;
+
+	if (nStatus == 0)
 	{
         // handle chunks of consecutive selected sheets together
         SCTAB nTabRangeStart = nStartTab;
 				if (pTab[i])
 					pTab[i]->SetRelNameDirty();
 		}
-		bRet = TRUE;
 	}
 	SetAutoCalc( bOldAutoCalc );
-	if ( bRet )
+	if (nStatus == 0)
 		pChartListenerCollection->UpdateDirtyCharts();
-	return bRet;
-}
-
-
-BOOL ScDocument::InsertCol( const ScRange& rRange, ScDocument* pRefUndoDoc )
+	return nStatus;
+}
+
+
+sal_uInt16 ScDocument::InsertCol( const ScRange& rRange, ScDocument* pRefUndoDoc )
 {
 	return InsertCol( rRange.aStart.Row(), rRange.aStart.Tab(),
 					  rRange.aEnd.Row(),   rRange.aEnd.Tab(),
 }
 
 
-void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab,
+sal_uInt16 ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab,
 								SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc,
                                 BOOL* pUndoOutline, const ScMarkData* pTabMark )
 {
 	    nEndTab = MAXTAB;
 	}
 
-    bool bTest = TestDataTablesDelete( nStartRow, nEndRow, nStartCol, nSize, 
-            nStartTab, nEndTab, pTabMark, true /*col*/);
-    if (!bTest)
-        /* FIXME: return value and UI needed */
-        return;
+    if (!TestDataTablesDelete( nStartRow, nEndRow, nStartCol, nSize, 
+                nStartTab, nEndTab, pTabMark, true /*col*/))
+        return STR_SHIFT_CELLS_TABLE;
 
 	BOOL bOldAutoCalc = GetAutoCalc();
 	SetAutoCalc( FALSE );	// Mehrfachberechnungen vermeiden
 
 	SetAutoCalc( bOldAutoCalc );
 	pChartListenerCollection->UpdateDirtyCharts();
-}
-
-
-void ScDocument::DeleteCol( const ScRange& rRange, ScDocument* pRefUndoDoc, BOOL* pUndoOutline )
-{
-	DeleteCol( rRange.aStart.Row(), rRange.aStart.Tab(),
+    return 0;
+}
+
+
+sal_uInt16 ScDocument::DeleteCol( const ScRange& rRange, ScDocument* pRefUndoDoc, BOOL* pUndoOutline )
+{
+	return DeleteCol( rRange.aStart.Row(), rRange.aStart.Tab(),
 			   rRange.aEnd.Row(),   rRange.aEnd.Tab(),
 			   rRange.aStart.Col(), static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1),
 			   pRefUndoDoc, pUndoOutline );

File sc/source/core/data/table3.cxx

 					aRowEntry.nFuncStart = aRowEntry.nSubStartRow;
 					aRowEntry.nFuncEnd   = nRow-1;
 
-                    bSpaceLeft = pDocument->InsertRow( 0, nTab, MAXCOL, nTab,
-                            aRowEntry.nDestRow, 1 );
+                    bSpaceLeft = (pDocument->InsertRow( 0, nTab, MAXCOL, nTab,
+                            aRowEntry.nDestRow, 1 ) == 0);
 					DBShowRow( aRowEntry.nDestRow, bBlockVis );
 					bBlockVis = FALSE;
                     if ( rParam.bPagebreak && nRow < MAXROW &&

File sc/source/core/tool/chgtrack.cxx

 	switch ( GetType() )
 	{
 		case SC_CAT_INSERT_COLS :
-			pDoc->DeleteCol( aRange );
+			if (pDoc->DeleteCol( aRange ) != 0)
+                return FALSE;
 		break;
 		case SC_CAT_INSERT_ROWS :
-			pDoc->DeleteRow( aRange );
+			if (pDoc->DeleteRow( aRange ) != 0)
+                return FALSE;
 		break;
 		case SC_CAT_INSERT_TABS :
 			pDoc->DeleteTab( aRange.aStart.Tab() );
 					if ( !(aRange.aStart.Col() == 0 && aRange.aEnd.Col() == MAXCOL) )
 					{	// nur wenn nicht TabDelete
                         if ( ( bOk = pDoc->CanInsertCol( aRange ) ) != FALSE )
-							bOk = pDoc->InsertCol( aRange );
+							bOk = (pDoc->InsertCol( aRange ) == 0);
 					}
 				break;
 				case SC_CAT_DELETE_ROWS :
                     if ( ( bOk = pDoc->CanInsertRow( aRange ) ) != FALSE )
-						bOk = pDoc->InsertRow( aRange );
+						bOk = (pDoc->InsertRow( aRange ) == 0);
 				break;
 				case SC_CAT_DELETE_TABS :
 				{

File sc/source/ui/docshell/docfunc.cxx

 	SCCOL nPaintEndX = nEndCol;
 	SCROW nPaintEndY = nEndRow;
 	USHORT nPaintFlags = PAINT_GRID;
-	BOOL bSuccess;
     SCTAB i;
 
     ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();  //preserve current cursor position
         }
     }
 
+	sal_uInt16 nStatus;
 	switch (eCmd)
 	{
 		case INS_CELLSDOWN:
-            bSuccess = pDoc->InsertRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
+            nStatus = pDoc->InsertRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
 			nPaintEndY = MAXROW;
 			break;
 		case INS_INSROWS:
-            bSuccess = pDoc->InsertRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
+            nStatus = pDoc->InsertRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
 			nPaintStartX = 0;
 			nPaintEndX = MAXCOL;
 			nPaintEndY = MAXROW;
 			nPaintFlags |= PAINT_LEFT;
 			break;
 		case INS_CELLSRIGHT:
-            bSuccess = pDoc->InsertCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
+            nStatus = pDoc->InsertCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
 			nPaintEndX = MAXCOL;
 			break;
 		case INS_INSCOLS:
-            bSuccess = pDoc->InsertCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
+            nStatus = pDoc->InsertCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
 			nPaintStartY = 0;
 			nPaintEndY = MAXROW;
 			nPaintEndX = MAXCOL;
 			break;
 		default:
 			DBG_ERROR("Falscher Code beim Einfuegen");
-			bSuccess = FALSE;
+            nStatus = STR_SHIFT_CELLS_TABLE;    // an error error ...
 			break;
 	}
 
-	if ( bSuccess )
+	if ( nStatus == 0 )
 	{
         SCTAB* pTabs      = NULL;
         SCTAB* pScenarios = NULL;
 		delete pRefUndoDoc;
 		delete pUndoData;
 		if (!bApi)
-			rDocShell.ErrorMessage(STR_INSERT_FULL);		// Spalte/Zeile voll
+			rDocShell.ErrorMessage( nStatus);
 	}
 
     aModificator.SetDocumentModified();
 
     SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
-	return bSuccess;
+
+	return nStatus == 0;
 }
 
 BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, DelCellCmd eCmd,
 	USHORT nPaintFlags = PAINT_GRID;
     SCTAB i;
 
+    ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();  //preserve current cursor position
+    SCCOL nCursorCol = 0;
+    SCROW nCursorRow = 0;
+    if( pViewSh )
+    {
+        nCursorCol = pViewSh->GetViewData()->GetCurX();
+        nCursorRow = pViewSh->GetViewData()->GetCurY();
+    }
+
 	if (bRecord && !pDoc->IsUndoEnabled())
 		bRecord = FALSE;
 
     }
 
 	BOOL bUndoOutline = FALSE;
+    sal_uInt16 nStatus = 0;
 	switch (eCmd)
 	{
 		case DEL_CELLSUP:
-            pDoc->DeleteRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, NULL, &aFullMark );
+            nStatus = pDoc->DeleteRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, NULL, &aFullMark );
 			nPaintEndY = MAXROW;
 			break;
 		case DEL_DELROWS:
-            pDoc->DeleteRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
+            nStatus = pDoc->DeleteRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
 			nPaintStartX = 0;
 			nPaintEndX = MAXCOL;
 			nPaintEndY = MAXROW;
 			nPaintFlags |= PAINT_LEFT;
 			break;
 		case DEL_CELLSLEFT:
-            pDoc->DeleteCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, NULL, &aFullMark );
+            nStatus = pDoc->DeleteCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, NULL, &aFullMark );
 			nPaintEndX = MAXCOL;
 			break;
 		case DEL_DELCOLS:
-            pDoc->DeleteCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
+            nStatus = pDoc->DeleteCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
 			nPaintStartY = 0;
 			nPaintEndY = MAXROW;
 			nPaintEndX = MAXCOL;
 			break;
 		default:
 			DBG_ERROR("Falscher Code beim Loeschen");
+            nStatus = STR_SHIFT_CELLS_TABLE;    // an error error ...
 			break;
 	}
 
-	//!	Test, ob Outline in Groesse geaendert
-
-	if ( bRecord )
-	{
-        for( i=0; i<nTabCount; i++ )
-            if( aFullMark.GetTableSelect( i ) )
-                pRefUndoDoc->DeleteAreaTab(nUndoStartX,nUndoStartY,nUndoEndX,nUndoEndY, i, IDF_ALL);
-
-			//	alle Tabellen anlegen, damit Formeln kopiert werden koennen:
-		pUndoDoc->AddUndoTab( 0, nTabCount-1, FALSE, FALSE );
-
-			//	kopieren mit bColRowFlags=FALSE (#54194#)
-		pRefUndoDoc->CopyToDocument(0,0,0,MAXCOL,MAXROW,MAXTAB,IDF_FORMULA,FALSE,pUndoDoc,NULL,FALSE);
-		delete pRefUndoDoc;
-
-        SCTAB* pTabs      = new SCTAB[nSelCount];
-        SCTAB* pScenarios = new SCTAB[nSelCount];
-        SCTAB   nUndoPos  = 0;
+    if (nStatus == 0)
+    {
+        //!	Test, ob Outline in Groesse geaendert
+
+        if ( bRecord )
+        {
+            for( i=0; i<nTabCount; i++ )
+                if( aFullMark.GetTableSelect( i ) )
+                    pRefUndoDoc->DeleteAreaTab(nUndoStartX,nUndoStartY,nUndoEndX,nUndoEndY, i, IDF_ALL);
+
+            //	alle Tabellen anlegen, damit Formeln kopiert werden koennen:
+            pUndoDoc->AddUndoTab( 0, nTabCount-1, FALSE, FALSE );
+
+            //	kopieren mit bColRowFlags=FALSE (#54194#)
+            pRefUndoDoc->CopyToDocument(0,0,0,MAXCOL,MAXROW,MAXTAB,IDF_FORMULA,FALSE,pUndoDoc,NULL,FALSE);
+            delete pRefUndoDoc;
+
+            SCTAB* pTabs      = new SCTAB[nSelCount];
+            SCTAB* pScenarios = new SCTAB[nSelCount];
+            SCTAB   nUndoPos  = 0;
+
+            for( i=0; i<nTabCount; i++ )
+            {
+                if( aMark.GetTableSelect( i ) )
+                {
+                    SCTAB nCount = 0;
+                    for( SCTAB j=i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
+                        nCount ++;
+
+                    pScenarios[nUndoPos] = nCount;
+                    pTabs[nUndoPos] = i;
+                    nUndoPos ++;
+                }
+            }
+
+            if( !bDeletingMerge )
+            {
+                rDocShell.GetUndoManager()->LeaveListAction();
+            }
+
+            rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDeleteCells(
+                        &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),nUndoPos, pTabs, pScenarios,
+                        eCmd, pUndoDoc, pUndoData ) );
+        }
+
+        // #i8302 want to be able to insert into the middle of merged cells
+        // the patch comes from maoyg
+
+        while( !qDecreaseRange.empty() )
+        {
+            ScRange aRange = qDecreaseRange.back();
+
+            long nDecreaseRowCount = 0;
+            long nDecreaseColCount = 0;
+            if( eCmd == DEL_CELLSUP || eCmd == DEL_DELROWS )
+            {
+                if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
+                    nDecreaseRowCount = nEndRow-nStartRow+1;
+                else if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow >= aRange.aStart.Row() && nEndRow >= aRange.aEnd.Row() )
+                    nDecreaseRowCount = aRange.aEnd.Row()-nStartRow+1;
+                else if( nStartRow >= aRange.aStart.Row() && nStartRow >= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
+                    nDecreaseRowCount = aRange.aEnd.Row()-nEndRow+1;
+            }
+            else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
+            {
+                if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
+                    nDecreaseColCount = nEndCol-nStartCol+1;
+                else if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol >= aRange.aStart.Col() && nEndCol >= aRange.aEnd.Col() )
+                    nDecreaseColCount = aRange.aEnd.Col()-nStartCol+1;
+                else if( nStartCol >= aRange.aStart.Col() && nStartCol >= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
+                    nDecreaseColCount = aRange.aEnd.Col()-nEndCol+1;
+            }
+
+            switch (eCmd)
+            {
+                case DEL_CELLSUP:
+                case DEL_DELROWS:
+                    aRange.aEnd.SetRow(static_cast<SCsCOL>( aRange.aEnd.Row()-nDecreaseRowCount));
+                    break;
+                case DEL_CELLSLEFT:
+                case DEL_DELCOLS:
+                    aRange.aEnd.SetCol(static_cast<SCsCOL>( aRange.aEnd.Col()-nDecreaseColCount));
+                    break;
+                default:
+                    break;
+            }
+
+            if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
+            {
+                MergeCells( aRange, FALSE, TRUE, TRUE );
+            }
+            qDecreaseRange.pop_back();
+        }
+
+        if( bDeletingMerge )
+            rDocShell.GetUndoManager()->LeaveListAction();
+
+        if ( bNeedRefresh )
+        {
+            // #i51445# old merge flag attributes must be deleted also for single cells,
+            // not only for whole columns/rows
+
+            if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
+                nMergeTestEndX = MAXCOL;
+            if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
+                nMergeTestEndY = MAXROW;
+            ScPatternAttr aPattern( pDoc->GetPool() );
+            aPattern.GetItemSet().Put( ScMergeFlagAttr() );
+
+            pDoc->ApplyPatternArea( nExtendStartCol, nExtendStartRow, nMergeTestEndX, nMergeTestEndY, aMark, aPattern );
+
+            for( i=0; i<nTabCount; i++ )
+            {
+                if( aMark.GetTableSelect( i ) )
+                {
+                    SCTAB nScenarioCount = 0;
+
+                    for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
+                        nScenarioCount ++;
+
+                    ScRange aMergedRange( nExtendStartCol, nExtendStartRow, i, nMergeTestEndX, nMergeTestEndY, i+nScenarioCount );
+                    pDoc->ExtendMerge( aMergedRange, TRUE );
+                }
+            }
+        }
 
         for( i=0; i<nTabCount; i++ )
         {
             if( aMark.GetTableSelect( i ) )
             {
-                SCTAB nCount = 0;
-                for( SCTAB j=i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
-                    nCount ++;
-
-                pScenarios[nUndoPos] = nCount;
-                pTabs[nUndoPos] = i;
-                nUndoPos ++;
+                if ( eCmd == DEL_DELCOLS || eCmd == DEL_DELROWS )
+                    pDoc->UpdatePageBreaks( i );
+
+                rDocShell.UpdatePaintExt( nExtFlags, nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i );
+
+                SCTAB nScenarioCount = 0;
+
+                for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
+                    nScenarioCount ++;
+
+                //	ganze Zeilen loeschen: nichts anpassen
+                if ( eCmd == DEL_DELROWS || !AdjustRowHeight(ScRange( 0, nPaintStartY, i, MAXCOL, nPaintEndY, i+nScenarioCount )) )
+                    rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, nPaintFlags,  nExtFlags );
+                else
+                {
+                    //	paint only what is not done by AdjustRowHeight
+                    if (nExtFlags & SC_PF_LINES)
+                        rDocShell.PostPaintAbove( ScRange( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount) );
+                    if (nPaintFlags & PAINT_TOP)
+                        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, PAINT_TOP );
+                }
             }
         }
-
-        if( !bDeletingMerge )
+    }
+    else
+    {
+        if( bDeletingMerge )
         {
-            rDocShell.GetUndoManager()->LeaveListAction();
-        }
-
-		rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDeleteCells(
-            &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),nUndoPos, pTabs, pScenarios,
-			eCmd, pUndoDoc, pUndoData ) );
-	}
-
-    // #i8302 want to be able to insert into the middle of merged cells
-    // the patch comes from maoyg
-
-    while( !qDecreaseRange.empty() )
-    {
-        ScRange aRange = qDecreaseRange.back();
-
-        long nDecreaseRowCount = 0;
-        long nDecreaseColCount = 0;
-        if( eCmd == DEL_CELLSUP || eCmd == DEL_DELROWS )
-        {
-            if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
-                nDecreaseRowCount = nEndRow-nStartRow+1;
-            else if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow >= aRange.aStart.Row() && nEndRow >= aRange.aEnd.Row() )
-                nDecreaseRowCount = aRange.aEnd.Row()-nStartRow+1;
-            else if( nStartRow >= aRange.aStart.Row() && nStartRow >= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
-                nDecreaseRowCount = aRange.aEnd.Row()-nEndRow+1;
-        }
-        else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
-        {
-            if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
-                nDecreaseColCount = nEndCol-nStartCol+1;
-            else if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol >= aRange.aStart.Col() && nEndCol >= aRange.aEnd.Col() )
-                nDecreaseColCount = aRange.aEnd.Col()-nStartCol+1;
-            else if( nStartCol >= aRange.aStart.Col() && nStartCol >= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
-                nDecreaseColCount = aRange.aEnd.Col()-nEndCol+1;
-        }
-
-        switch (eCmd)
-        {
-            case DEL_CELLSUP:
-            case DEL_DELROWS:
-                aRange.aEnd.SetRow(static_cast<SCsCOL>( aRange.aEnd.Row()-nDecreaseRowCount));
-                break;
-            case DEL_CELLSLEFT:
-            case DEL_DELCOLS:
-                aRange.aEnd.SetCol(static_cast<SCsCOL>( aRange.aEnd.Col()-nDecreaseColCount));
-                break;
-            default:
-                break;
-        }
-
-        if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
-        {
-            MergeCells( aRange, FALSE, TRUE, TRUE );
-        }
-        qDecreaseRange.pop_back();
-    }
-
-    if( bDeletingMerge )
-        rDocShell.GetUndoManager()->LeaveListAction();
-
-	if ( bNeedRefresh )
-	{
-        // #i51445# old merge flag attributes must be deleted also for single cells,
-        // not only for whole columns/rows
-
-        if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
-            nMergeTestEndX = MAXCOL;
-        if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
-            nMergeTestEndY = MAXROW;
-		ScPatternAttr aPattern( pDoc->GetPool() );
-		aPattern.GetItemSet().Put( ScMergeFlagAttr() );
-
-        pDoc->ApplyPatternArea( nExtendStartCol, nExtendStartRow, nMergeTestEndX, nMergeTestEndY, aMark, aPattern );
-
-        for( i=0; i<nTabCount; i++ )
-        {
-            if( aMark.GetTableSelect( i ) )
+            while( !qDecreaseRange.empty() )
             {
-                SCTAB nScenarioCount = 0;
-
-                for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
-                    nScenarioCount ++;
-
-                ScRange aMergedRange( nExtendStartCol, nExtendStartRow, i, nMergeTestEndX, nMergeTestEndY, i+nScenarioCount );
-                pDoc->ExtendMerge( aMergedRange, TRUE );
+                ScRange aRange = qDecreaseRange.back();
+                MergeCells(aRange, FALSE, TRUE, TRUE);
+                qDecreaseRange.pop_back();
+            }
+
+            if( pViewSh )
+            {
+                pViewSh->MarkRange( rRange, FALSE );
+                pViewSh->SetCursor( nCursorCol, nCursorRow );
             }
         }
-	}
-
-    for( i=0; i<nTabCount; i++ )
-    {
-        if( aMark.GetTableSelect( i ) )
-        {
-	        if ( eCmd == DEL_DELCOLS || eCmd == DEL_DELROWS )
-                pDoc->UpdatePageBreaks( i );
-
-	        rDocShell.UpdatePaintExt( nExtFlags, nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i );
-
-            SCTAB nScenarioCount = 0;
-
-            for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
-                nScenarioCount ++;
-
-	        //	ganze Zeilen loeschen: nichts anpassen
-	        if ( eCmd == DEL_DELROWS || !AdjustRowHeight(ScRange( 0, nPaintStartY, i, MAXCOL, nPaintEndY, i+nScenarioCount )) )
-		        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, nPaintFlags,  nExtFlags );
-    	    else
-	        {
-		        //	paint only what is not done by AdjustRowHeight
-		        if (nExtFlags & SC_PF_LINES)
-			        rDocShell.PostPaintAbove( ScRange( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount) );
-		        if (nPaintFlags & PAINT_TOP)
-			        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, PAINT_TOP );
-	        }
-        }
+
+        rDocShell.GetUndoManager()->LeaveListAction();
+        SfxUndoManager* pMgr = rDocShell.GetUndoManager();
+        pMgr->RemoveLastUndoAction();
+
+		delete pRefUndoDoc;
+		delete pUndoData;
+		if (!bApi)
+			rDocShell.ErrorMessage( nStatus);
     }
+
 	aModificator.SetDocumentModified();
 
     SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
 
-	return TRUE;
+	return nStatus == 0;
 }
 
 BOOL ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,

File sc/source/ui/src/globstr.src

 	{
 		Text [ en-US ] = "DataPilot table needs at least two rows of data to create or refresh." ;
 	};
+	String STR_SHIFT_CELLS_TABLE
+    {
+        Text [ en-US ] = "This operation would shift cells in a data table and is not allowed." ;
+    };
 };