/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"



// INCLUDE ---------------------------------------------------------------

#include <sfx2/app.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/waitobj.hxx>
#include <svx/dataaccessdescriptor.hxx>

#include <com/sun/star/sdb/CommandType.hpp>

#include "dbdocfun.hxx"
#include "sc.hrc"
#include "dbcolect.hxx"
#include "undodat.hxx"
#include "docsh.hxx"
#include "docfunc.hxx"
#include "globstr.hrc"
#include "tabvwsh.hxx"
#include "patattr.hxx"
#include "rangenam.hxx"
#include "olinetab.hxx"
#include "dpobject.hxx"
#include "dociter.hxx"		// for lcl_EmptyExcept
#include "cell.hxx"			// for lcl_EmptyExcept
#include "editable.hxx"
#include "attrib.hxx"
#include "drwlayer.hxx"
#include "dpshttab.hxx"
#include "hints.hxx"

using namespace ::com::sun::star;

// -----------------------------------------------------------------

sal_Bool ScDBDocFunc::AddDBRange( const String& rName, const ScRange& rRange, sal_Bool /* bApi */ )
{

	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	ScDBCollection* pDocColl = pDoc->GetDBCollection();
	sal_Bool bUndo (pDoc->IsUndoEnabled());

	ScDBCollection* pUndoColl = NULL;
	if (bUndo)
		pUndoColl = new ScDBCollection( *pDocColl );

	ScDBData* pNew = new ScDBData( rName, rRange.aStart.Tab(),
									rRange.aStart.Col(), rRange.aStart.Row(),
									rRange.aEnd.Col(), rRange.aEnd.Row() );

    // #i55926# While loading XML, formula cells only have a single string token,
    // so CompileDBFormula would never find any name (index) tokens, and would
    // unnecessarily loop through all cells.
    sal_Bool bCompile = !pDoc->IsImportingXML();

    if ( bCompile )
        pDoc->CompileDBFormula( sal_True );     // CreateFormulaString
	sal_Bool bOk = pDocColl->Insert( pNew );
    if ( bCompile )
        pDoc->CompileDBFormula( sal_False );    // CompileFormulaString

	if (!bOk)
	{
		delete pNew;
		delete pUndoColl;
		return sal_False;
	}

	if (bUndo)
	{
		ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl );
		rDocShell.GetUndoManager()->AddUndoAction(
						new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) );
	}

	aModificator.SetDocumentModified();
	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
	return sal_True;
}

sal_Bool ScDBDocFunc::DeleteDBRange( const String& rName, sal_Bool /* bApi */ )
{
	sal_Bool bDone = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	ScDBCollection* pDocColl = pDoc->GetDBCollection();
	sal_Bool bUndo (pDoc->IsUndoEnabled());

	sal_uInt16 nPos = 0;
	if (pDocColl->SearchName( rName, nPos ))
	{
		ScDocShellModificator aModificator( rDocShell );

		ScDBCollection* pUndoColl = NULL;
		if (bUndo)
			pUndoColl = new ScDBCollection( *pDocColl );

		pDoc->CompileDBFormula( sal_True );		// CreateFormulaString
		pDocColl->AtFree( nPos );
		pDoc->CompileDBFormula( sal_False );	// CompileFormulaString

		if (bUndo)
		{
			ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl );
			rDocShell.GetUndoManager()->AddUndoAction(
							new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) );
		}

		aModificator.SetDocumentModified();
		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
		bDone = sal_True;
	}

	return bDone;
}

sal_Bool ScDBDocFunc::RenameDBRange( const String& rOld, const String& rNew, sal_Bool /* bApi */ )
{
	sal_Bool bDone = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	ScDBCollection* pDocColl = pDoc->GetDBCollection();
	sal_Bool bUndo (pDoc->IsUndoEnabled());

	sal_uInt16 nPos = 0;
	sal_uInt16 nDummy = 0;
	if ( pDocColl->SearchName( rOld, nPos ) &&
		 !pDocColl->SearchName( rNew, nDummy ) )
	{
		ScDocShellModificator aModificator( rDocShell );

		ScDBData* pData = (*pDocColl)[nPos];
		ScDBData* pNewData = new ScDBData(*pData);
		pNewData->SetName(rNew);

		ScDBCollection* pUndoColl = new ScDBCollection( *pDocColl );

		pDoc->CompileDBFormula( sal_True );				// CreateFormulaString
		pDocColl->AtFree( nPos );
		sal_Bool bInserted = pDocColl->Insert( pNewData );
		if (!bInserted)								// Fehler -> alten Zustand wiederherstellen
		{
			delete pNewData;
			pDoc->SetDBCollection( pUndoColl );		// gehoert dann dem Dokument
		}
		pDoc->CompileDBFormula( sal_False );			// CompileFormulaString

		if (bInserted)								// Einfuegen hat geklappt
		{
			if (bUndo)
			{
				ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl );
				rDocShell.GetUndoManager()->AddUndoAction(
								new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) );
			}
			else
				delete pUndoColl;

			aModificator.SetDocumentModified();
			SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
			bDone = sal_True;
		}
	}

	return bDone;
}

sal_Bool ScDBDocFunc::ModifyDBData( const ScDBData& rNewData, sal_Bool /* bApi */ )
{
	sal_Bool bDone = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	ScDBCollection* pDocColl = pDoc->GetDBCollection();
	sal_Bool bUndo (pDoc->IsUndoEnabled());

	sal_uInt16 nPos = 0;
	if (pDocColl->SearchName( rNewData.GetName(), nPos ))
	{
		ScDocShellModificator aModificator( rDocShell );

		ScDBData* pData = (*pDocColl)[nPos];

		ScRange aOldRange, aNewRange;
		pData->GetArea(aOldRange);
		rNewData.GetArea(aNewRange);
		sal_Bool bAreaChanged = ( aOldRange != aNewRange );		// dann muss neu compiliert werden

		ScDBCollection* pUndoColl = NULL;
		if (bUndo)
			pUndoColl = new ScDBCollection( *pDocColl );

		*pData = rNewData;
		if (bAreaChanged)
			pDoc->CompileDBFormula();

		if (bUndo)
		{
			ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl );
			rDocShell.GetUndoManager()->AddUndoAction(
							new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) );
		}

		aModificator.SetDocumentModified();
		bDone = sal_True;
	}

	return bDone;
}

// -----------------------------------------------------------------

sal_Bool ScDBDocFunc::RepeatDB( const String& rDBName, sal_Bool bRecord, sal_Bool bApi )
{
	//!	auch fuer ScDBFunc::RepeatDB benutzen!

	sal_Bool bDone = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
	ScDBCollection*	pColl = pDoc->GetDBCollection();
	sal_uInt16 nIndex;
	if ( pColl && pColl->SearchName( rDBName, nIndex ) )
	{
		ScDBData* pDBData = (*pColl)[nIndex];

		ScQueryParam aQueryParam;
		pDBData->GetQueryParam( aQueryParam );
		sal_Bool bQuery = aQueryParam.GetEntry(0).bDoQuery;

		ScSortParam aSortParam;
		pDBData->GetSortParam( aSortParam );
		sal_Bool bSort = aSortParam.bDoSort[0];

		ScSubTotalParam aSubTotalParam;
		pDBData->GetSubTotalParam( aSubTotalParam );
		sal_Bool bSubTotal = aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly;

		if ( bQuery || bSort || bSubTotal )
		{
			sal_Bool bQuerySize = sal_False;
			ScRange aOldQuery;
			ScRange aNewQuery;
			if (bQuery && !aQueryParam.bInplace)
			{
				ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
														aQueryParam.nDestTab, sal_True );
				if (pDest && pDest->IsDoSize())
				{
					pDest->GetArea( aOldQuery );
					bQuerySize = sal_True;
				}
			}

			SCTAB nTab;
			SCCOL nStartCol;
			SCROW nStartRow;
			SCCOL nEndCol;
			SCROW nEndRow;
			pDBData->GetArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );

			//!		Undo nur benoetigte Daten ?

			ScDocument* pUndoDoc = NULL;
			ScOutlineTable* pUndoTab = NULL;
			ScRangeName* pUndoRange = NULL;
			ScDBCollection* pUndoDB = NULL;

			if (bRecord)
			{
				SCTAB nTabCount = pDoc->GetTableCount();
				pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
				ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
				if (pTable)
				{
					pUndoTab = new ScOutlineTable( *pTable );

                    // column/row state
					SCCOLROW nOutStartCol, nOutEndCol;
					SCCOLROW nOutStartRow, nOutEndRow;
					pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol );
					pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow );

					pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
                    pDoc->CopyToDocument( static_cast<SCCOL>(nOutStartCol), 0,
                            nTab, static_cast<SCCOL>(nOutEndCol), MAXROW, nTab,
                            IDF_NONE, sal_False, pUndoDoc );
                    pDoc->CopyToDocument( 0, static_cast<SCROW>(nOutStartRow),
                            nTab, MAXCOL, static_cast<SCROW>(nOutEndRow), nTab,
                            IDF_NONE, sal_False, pUndoDoc );
				}
				else
					pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );

				//	Datenbereich sichern - incl. Filter-Ergebnis
				pDoc->CopyToDocument( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab, IDF_ALL, sal_False, pUndoDoc );

				//	alle Formeln wegen Referenzen
				pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1, IDF_FORMULA, sal_False, pUndoDoc );

				//	DB- und andere Bereiche
				ScRangeName* pDocRange = pDoc->GetRangeName();
				if (pDocRange->GetCount())
					pUndoRange = new ScRangeName( *pDocRange );
				ScDBCollection* pDocDB = pDoc->GetDBCollection();
				if (pDocDB->GetCount())
					pUndoDB = new ScDBCollection( *pDocDB );
			}

			if (bSort && bSubTotal)
			{
				//	Sortieren ohne SubTotals

				aSubTotalParam.bRemoveOnly = sal_True;		// wird unten wieder zurueckgesetzt
				DoSubTotals( nTab, aSubTotalParam, NULL, sal_False, bApi );
			}

			if (bSort)
			{
				pDBData->GetSortParam( aSortParam );			// Bereich kann sich geaendert haben
				Sort( nTab, aSortParam, sal_False, sal_False, bApi );
			}
			if (bQuery)
			{
				pDBData->GetQueryParam( aQueryParam );			// Bereich kann sich geaendert haben
				ScRange aAdvSource;
				if (pDBData->GetAdvancedQuerySource(aAdvSource))
					Query( nTab, aQueryParam, &aAdvSource, sal_False, bApi );
				else
					Query( nTab, aQueryParam, NULL, sal_False, bApi );

				//	bei nicht-inplace kann die Tabelle umgestellt worden sein
//				if ( !aQueryParam.bInplace && aQueryParam.nDestTab != nTab )
//					SetTabNo( nTab );
			}
			if (bSubTotal)
			{
				pDBData->GetSubTotalParam( aSubTotalParam );	// Bereich kann sich geaendert haben
				aSubTotalParam.bRemoveOnly = sal_False;
				DoSubTotals( nTab, aSubTotalParam, NULL, sal_False, bApi );
			}

			if (bRecord)
			{
                SCTAB nDummyTab;
                SCCOL nDummyCol;
                SCROW nDummyRow;
				SCROW nNewEndRow;
				pDBData->GetArea( nDummyTab, nDummyCol,nDummyRow, nDummyCol,nNewEndRow );

				const ScRange* pOld = NULL;
				const ScRange* pNew = NULL;
				if (bQuerySize)
				{
					ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
															aQueryParam.nDestTab, sal_True );
					if (pDest)
					{
						pDest->GetArea( aNewQuery );
						pOld = &aOldQuery;
						pNew = &aNewQuery;
					}
				}

				rDocShell.GetUndoManager()->AddUndoAction(
					new ScUndoRepeatDB( &rDocShell, nTab,
											nStartCol, nStartRow, nEndCol, nEndRow,
											nNewEndRow,
											//nCurX, nCurY,
											nStartCol, nStartRow,
											pUndoDoc, pUndoTab,
											pUndoRange, pUndoDB,
											pOld, pNew ) );
			}

			rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
									PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
			bDone = sal_True;
		}
		else if (!bApi)		// "Keine Operationen auszufuehren"
			rDocShell.ErrorMessage(STR_MSSG_REPEATDB_0);
	}

	return bDone;
}

// -----------------------------------------------------------------

sal_Bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
							sal_Bool bRecord, sal_Bool bPaint, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
	SCTAB nSrcTab = nTab;
    ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();

	ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rSortParam.nCol1, rSortParam.nRow1,
													rSortParam.nCol2, rSortParam.nRow2 );
	if (!pDBData)
	{
		DBG_ERROR( "Sort: keine DBData" );
		return sal_False;
	}

	ScDBData* pDestData = NULL;
	ScRange aOldDest;
	sal_Bool bCopy = !rSortParam.bInplace;
	if ( bCopy && rSortParam.nDestCol == rSortParam.nCol1 &&
				  rSortParam.nDestRow == rSortParam.nRow1 && rSortParam.nDestTab == nTab )
		bCopy = sal_False;
	ScSortParam aLocalParam( rSortParam );
	if ( bCopy )
	{
		aLocalParam.MoveToDest();
        if ( !ValidColRow( aLocalParam.nCol2, aLocalParam.nRow2 ) )
        {
            if (!bApi)
                rDocShell.ErrorMessage(STR_PASTE_FULL);
            return sal_False;
        }

		nTab = rSortParam.nDestTab;
		pDestData = pDoc->GetDBAtCursor( rSortParam.nDestCol, rSortParam.nDestRow,
											rSortParam.nDestTab, sal_True );
		if (pDestData)
			pDestData->GetArea(aOldDest);
	}

	ScEditableTester aTester( pDoc, nTab, aLocalParam.nCol1,aLocalParam.nRow1,
										aLocalParam.nCol2,aLocalParam.nRow2 );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	if ( aLocalParam.bIncludePattern && pDoc->HasAttrib(
										aLocalParam.nCol1, aLocalParam.nRow1, nTab,
										aLocalParam.nCol2, aLocalParam.nRow2, nTab,
										HASATTR_MERGED | HASATTR_OVERLAPPED ) )
	{
		//	Merge-Attribute wuerden beim Sortieren durcheinanderkommen
		if (!bApi)
			rDocShell.ErrorMessage(STR_SORT_ERR_MERGED);
		return sal_False;
	}


	//		ausfuehren

	WaitObject aWait( rDocShell.GetActiveDialogParent() );

	sal_Bool bRepeatQuery = sal_False;							// bestehenden Filter wiederholen?
	ScQueryParam aQueryParam;
	pDBData->GetQueryParam( aQueryParam );
	if ( aQueryParam.GetEntry(0).bDoQuery )
		bRepeatQuery = sal_True;

	if (bRepeatQuery && bCopy)
	{
		if ( aQueryParam.bInplace ||
				aQueryParam.nDestCol != rSortParam.nDestCol ||
				aQueryParam.nDestRow != rSortParam.nDestRow ||
				aQueryParam.nDestTab != rSortParam.nDestTab )		// Query auf selben Zielbereich?
			bRepeatQuery = sal_False;
	}

    ScUndoSort* pUndoAction = 0;
    if ( bRecord )
    {
        //  Referenzen ausserhalb des Bereichs werden nicht veraendert !

        ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
        //  Zeilenhoehen immer (wegen automatischer Anpassung)
        //! auf ScBlockUndo umstellen
        pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );

        /*  #i59745# Do not copy note captions to undo document. All existing
            caption objects will be repositioned while sorting which is tracked
            in drawing undo. When undo is executed, the old positions will be
            restored, and the cells with the old notes (which still refer to the
            existing captions) will be copied back into the source document. */
        pDoc->CopyToDocument( aLocalParam.nCol1, aLocalParam.nRow1, nTab,
                                aLocalParam.nCol2, aLocalParam.nRow2, nTab,
                                IDF_ALL|IDF_NOCAPTIONS, sal_False, pUndoDoc );

        const ScRange* pR = 0;
        if (pDestData)
        {
            /*  #i59745# Do not copy note captions from destination range to
                undo document. All existing caption objects will be removed
                which is tracked in drawing undo. When undo is executed, the
                caption objects are reinserted with drawing undo, and the cells
                with the old notes (which still refer to the existing captions)
                will be copied back into the source document. */
            pDoc->CopyToDocument( aOldDest, IDF_ALL|IDF_NOCAPTIONS, sal_False, pUndoDoc );
            pR = &aOldDest;
        }

		//	Zeilenhoehen immer (wegen automatischer Anpassung)
		//!	auf ScBlockUndo umstellen
//        if (bRepeatQuery)
            pDoc->CopyToDocument( 0, aLocalParam.nRow1, nTab, MAXCOL, aLocalParam.nRow2, nTab,
                                    IDF_NONE, sal_False, pUndoDoc );

        ScDBCollection* pUndoDB = NULL;
        ScDBCollection* pDocDB = pDoc->GetDBCollection();
        if (pDocDB->GetCount())
            pUndoDB = new ScDBCollection( *pDocDB );

        pUndoAction = new ScUndoSort( &rDocShell, nTab, rSortParam, bRepeatQuery, pUndoDoc, pUndoDB, pR );
        rDocShell.GetUndoManager()->AddUndoAction( pUndoAction );

        // #i59745# collect all drawing undo actions affecting cell note captions
        if( pDrawLayer )
            pDrawLayer->BeginCalcUndo();
    }

	if ( bCopy )
	{
		if (pDestData)
			pDoc->DeleteAreaTab(aOldDest, IDF_CONTENTS);			// Zielbereich vorher loeschen

		ScRange aSource( rSortParam.nCol1,rSortParam.nRow1,nSrcTab,
							rSortParam.nCol2,rSortParam.nRow2,nSrcTab );
		ScAddress aDest( rSortParam.nDestCol, rSortParam.nDestRow, rSortParam.nDestTab );

		rDocShell.GetDocFunc().MoveBlock( aSource, aDest, sal_False, sal_False, sal_False, sal_True );
	}

	// #105780# don't call ScDocument::Sort with an empty SortParam (may be empty here if bCopy is set)
	if ( aLocalParam.bDoSort[0] )
		pDoc->Sort( nTab, aLocalParam, bRepeatQuery );

	sal_Bool bSave = sal_True;
	if (bCopy)
	{
		ScSortParam aOldSortParam;
		pDBData->GetSortParam( aOldSortParam );
		if ( aOldSortParam.bDoSort[0] && aOldSortParam.bInplace )	// Inplace-Sortierung gemerkt?
		{
			bSave = sal_False;
			aOldSortParam.nDestCol = rSortParam.nDestCol;
			aOldSortParam.nDestRow = rSortParam.nDestRow;
			aOldSortParam.nDestTab = rSortParam.nDestTab;
			pDBData->SetSortParam( aOldSortParam ); 				// dann nur DestPos merken
		}
	}
	if (bSave)												// Parameter merken
	{
		pDBData->SetSortParam( rSortParam );
		pDBData->SetHeader( rSortParam.bHasHeader );		//! ???
		pDBData->SetByRow( rSortParam.bByRow );				//! ???
	}

	if (bCopy)											// neuen DB-Bereich merken
	{
		//	Tabelle umschalten von aussen (View)
		//!	SetCursor ??!?!

		ScRange aDestPos( aLocalParam.nCol1, aLocalParam.nRow1, nTab,
							aLocalParam.nCol2, aLocalParam.nRow2, nTab );
		ScDBData* pNewData;
		if (pDestData)
			pNewData = pDestData;				// Bereich vorhanden -> anpassen
		else									// Bereich ab Cursor/Markierung wird angelegt
			pNewData = rDocShell.GetDBData(aDestPos, SC_DB_MAKE_SORT, SC_DBSEL_FORCE_MARK );
		if (pNewData)
		{
			pNewData->SetArea( nTab,
								aLocalParam.nCol1,aLocalParam.nRow1,
								aLocalParam.nCol2,aLocalParam.nRow2 );
			pNewData->SetSortParam( aLocalParam );
			pNewData->SetHeader( aLocalParam.bHasHeader );		//! ???
			pNewData->SetByRow( aLocalParam.bByRow );
		}
		else
		{
			DBG_ERROR("Zielbereich nicht da");
		}
	}

	ScRange aDirtyRange( aLocalParam.nCol1, aLocalParam.nRow1, nTab,
		aLocalParam.nCol2, aLocalParam.nRow2, nTab );
	pDoc->SetDirty( aDirtyRange );

	if (bPaint)
	{
		sal_uInt16 nPaint = PAINT_GRID;
		SCCOL nStartX = aLocalParam.nCol1;
		SCROW nStartY = aLocalParam.nRow1;
		SCCOL nEndX = aLocalParam.nCol2;
		SCROW nEndY = aLocalParam.nRow2;
		if ( bRepeatQuery )
		{
			nPaint |= PAINT_LEFT;
			nStartX = 0;
			nEndX = MAXCOL;
		}
		if (pDestData)
		{
			if ( nEndX < aOldDest.aEnd.Col() )
				nEndX = aOldDest.aEnd.Col();
			if ( nEndY < aOldDest.aEnd.Row() )
				nEndY = aOldDest.aEnd.Row();
		}
		rDocShell.PostPaint( nStartX, nStartY, nTab, nEndX, nEndY, nTab, nPaint );
	}

    //  AdjustRowHeight( aLocalParam.nRow1, aLocalParam.nRow2, bPaint );
	rDocShell.AdjustRowHeight( aLocalParam.nRow1, aLocalParam.nRow2, nTab );

    // #i59745# set collected drawing undo actions at sorting undo action
    if( pUndoAction && pDrawLayer )
        pUndoAction->SetDrawUndoAction( pDrawLayer->GetCalcUndo() );

	aModificator.SetDocumentModified();

	return sal_True;
}

// -----------------------------------------------------------------

sal_Bool ScDBDocFunc::Query( SCTAB nTab, const ScQueryParam& rQueryParam,
						const ScRange* pAdvSource, sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
	ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rQueryParam.nCol1, rQueryParam.nRow1,
													rQueryParam.nCol2, rQueryParam.nRow2 );
	if (!pDBData)
	{
		DBG_ERROR( "Query: keine DBData" );
		return sal_False;
	}

	//	Wechsel von Inplace auf nicht-Inplace, dann erst Inplace aufheben:
	//	(nur, wenn im Dialog "Persistent" ausgewaehlt ist)

	if ( !rQueryParam.bInplace && pDBData->HasQueryParam() && rQueryParam.bDestPers )
	{
		ScQueryParam aOldQuery;
		pDBData->GetQueryParam(aOldQuery);
		if (aOldQuery.bInplace)
		{
			//	alte Filterung aufheben

			SCSIZE nEC = aOldQuery.GetEntryCount();
			for (SCSIZE i=0; i<nEC; i++)
				aOldQuery.GetEntry(i).bDoQuery = sal_False;
			aOldQuery.bDuplicate = sal_True;
			Query( nTab, aOldQuery, NULL, bRecord, bApi );
		}
	}

	ScQueryParam aLocalParam( rQueryParam );		// fuer Paint / Zielbereich
	sal_Bool bCopy = !rQueryParam.bInplace; 			// kopiert wird in Table::Query
	ScDBData* pDestData = NULL;						// Bereich, in den kopiert wird
	sal_Bool bDoSize = sal_False;							// Zielgroesse anpassen (einf./loeschen)
	SCCOL nFormulaCols = 0;						// nur bei bDoSize
	sal_Bool bKeepFmt = sal_False;
	ScRange aOldDest;
	ScRange aDestTotal;
	if ( bCopy && rQueryParam.nDestCol == rQueryParam.nCol1 &&
				  rQueryParam.nDestRow == rQueryParam.nRow1 && rQueryParam.nDestTab == nTab )
		bCopy = sal_False;
	SCTAB nDestTab = nTab;
	if ( bCopy )
	{
		aLocalParam.MoveToDest();
		nDestTab = rQueryParam.nDestTab;
        if ( !ValidColRow( aLocalParam.nCol2, aLocalParam.nRow2 ) )
        {
            if (!bApi)
                rDocShell.ErrorMessage(STR_PASTE_FULL);
            return sal_False;
        }

		ScEditableTester aTester( pDoc, nDestTab, aLocalParam.nCol1,aLocalParam.nRow1,
												aLocalParam.nCol2,aLocalParam.nRow2);
		if (!aTester.IsEditable())
		{
			if (!bApi)
				rDocShell.ErrorMessage(aTester.GetMessageId());
			return sal_False;
		}

		pDestData = pDoc->GetDBAtCursor( rQueryParam.nDestCol, rQueryParam.nDestRow,
											rQueryParam.nDestTab, sal_True );
		if (pDestData)
		{
			pDestData->GetArea( aOldDest );
			aDestTotal=ScRange( rQueryParam.nDestCol,
								rQueryParam.nDestRow,
								nDestTab,
								rQueryParam.nDestCol + rQueryParam.nCol2 - rQueryParam.nCol1,
								rQueryParam.nDestRow + rQueryParam.nRow2 - rQueryParam.nRow1,
								nDestTab );

			bDoSize = pDestData->IsDoSize();
			//	Test, ob Formeln aufgefuellt werden muessen (nFormulaCols):
			if ( bDoSize && aOldDest.aEnd.Col() == aDestTotal.aEnd.Col() )
			{
				SCCOL nTestCol = aOldDest.aEnd.Col() + 1;		// neben dem Bereich
				SCROW nTestRow = rQueryParam.nDestRow +
									( aLocalParam.bHasHeader ? 1 : 0 );
				while ( nTestCol <= MAXCOL &&
						pDoc->GetCellType(ScAddress( nTestCol, nTestRow, nTab )) == CELLTYPE_FORMULA )
					++nTestCol, ++nFormulaCols;
			}

			bKeepFmt = pDestData->IsKeepFmt();
			if ( bDoSize && !pDoc->CanFitBlock( aOldDest, aDestTotal ) )
			{
				if (!bApi)
					rDocShell.ErrorMessage(STR_MSSG_DOSUBTOTALS_2);		// kann keine Zeilen einfuegen
				return sal_False;
			}
		}
	}

	//		ausfuehren

	WaitObject aWait( rDocShell.GetActiveDialogParent() );

	sal_Bool bKeepSub = sal_False;							// bestehende Teilergebnisse wiederholen?
	ScSubTotalParam aSubTotalParam;
	if (rQueryParam.GetEntry(0).bDoQuery)			// nicht beim Aufheben
	{
		pDBData->GetSubTotalParam( aSubTotalParam );	// Teilergebnisse vorhanden?

		if ( aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly )
			bKeepSub = sal_True;
	}

    ScDocument* pUndoDoc = NULL;
    ScDBCollection* pUndoDB = NULL;
    const ScRange* pOld = NULL;

	if ( bRecord )
	{
		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		if (bCopy)
		{
			pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab, sal_False, sal_True );
			pDoc->CopyToDocument( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
									aLocalParam.nCol2, aLocalParam.nRow2, nDestTab,
									IDF_ALL, sal_False, pUndoDoc );
			//	Attribute sichern, falls beim Filtern mitkopiert

			if (pDestData)
			{
				pDoc->CopyToDocument( aOldDest, IDF_ALL, sal_False, pUndoDoc );
				pOld = &aOldDest;
			}
		}
		else
		{
			pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
			pDoc->CopyToDocument( 0, rQueryParam.nRow1, nTab, MAXCOL, rQueryParam.nRow2, nTab,
										IDF_NONE, sal_False, pUndoDoc );
		}

		ScDBCollection* pDocDB = pDoc->GetDBCollection();
		if (pDocDB->GetCount())
			pUndoDB = new ScDBCollection( *pDocDB );

        pDoc->BeginDrawUndo();
	}

	ScDocument* pAttribDoc = NULL;
	ScRange aAttribRange;
	if (pDestData)										// Zielbereich loeschen
	{
		if ( bKeepFmt )
		{
			//	kleinere der End-Spalten, Header+1 Zeile
			aAttribRange = aOldDest;
			if ( aAttribRange.aEnd.Col() > aDestTotal.aEnd.Col() )
				aAttribRange.aEnd.SetCol( aDestTotal.aEnd.Col() );
			aAttribRange.aEnd.SetRow( aAttribRange.aStart.Row() +
										( aLocalParam.bHasHeader ? 1 : 0 ) );

			//	auch fuer aufgefuellte Formeln
			aAttribRange.aEnd.SetCol( aAttribRange.aEnd.Col() + nFormulaCols );

			pAttribDoc = new ScDocument( SCDOCMODE_UNDO );
			pAttribDoc->InitUndo( pDoc, nDestTab, nDestTab, sal_False, sal_True );
			pDoc->CopyToDocument( aAttribRange, IDF_ATTRIB, sal_False, pAttribDoc );
		}

		if ( bDoSize )
			pDoc->FitBlock( aOldDest, aDestTotal );
		else
			pDoc->DeleteAreaTab(aOldDest, IDF_ALL);			// einfach loeschen
	}

	//	Filtern am Dokument ausfuehren
	SCSIZE nCount = pDoc->Query( nTab, rQueryParam, bKeepSub );
	if (bCopy)
	{
		aLocalParam.nRow2 = aLocalParam.nRow1 + nCount;
		if (!aLocalParam.bHasHeader && nCount > 0)
			--aLocalParam.nRow2;

		if ( bDoSize )
		{
			//	auf wirklichen Ergebnis-Bereich anpassen
			//	(das hier ist immer eine Verkleinerung)

			ScRange aNewDest( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
								aLocalParam.nCol2, aLocalParam.nRow2, nDestTab );
			pDoc->FitBlock( aDestTotal, aNewDest, sal_False );		// sal_False - nicht loeschen

			if ( nFormulaCols > 0 )
			{
				//	Formeln ausfuellen
				//!	Undo (Query und Repeat) !!!

				ScRange aNewForm( aLocalParam.nCol2+1, aLocalParam.nRow1, nDestTab,
								  aLocalParam.nCol2+nFormulaCols, aLocalParam.nRow2, nDestTab );
				ScRange aOldForm = aNewForm;
				aOldForm.aEnd.SetRow( aOldDest.aEnd.Row() );
				pDoc->FitBlock( aOldForm, aNewForm, sal_False );

				ScMarkData aMark;
				aMark.SelectOneTable(nDestTab);
				SCROW nFStartY = aLocalParam.nRow1 + ( aLocalParam.bHasHeader ? 1 : 0 );
				pDoc->Fill( aLocalParam.nCol2+1, nFStartY,
							aLocalParam.nCol2+nFormulaCols, nFStartY, aMark,
							aLocalParam.nRow2 - nFStartY,
							FILL_TO_BOTTOM, FILL_SIMPLE );
			}
		}

		if ( pAttribDoc )		// gemerkte Attribute zurueckkopieren
		{
			//	Header
			if (aLocalParam.bHasHeader)
			{
				ScRange aHdrRange = aAttribRange;
				aHdrRange.aEnd.SetRow( aHdrRange.aStart.Row() );
				pAttribDoc->CopyToDocument( aHdrRange, IDF_ATTRIB, sal_False, pDoc );
			}

			//	Daten
			SCCOL nAttrEndCol = aAttribRange.aEnd.Col();
			SCROW nAttrRow = aAttribRange.aStart.Row() + ( aLocalParam.bHasHeader ? 1 : 0 );
			for (SCCOL nCol = aAttribRange.aStart.Col(); nCol<=nAttrEndCol; nCol++)
			{
				const ScPatternAttr* pSrcPattern = pAttribDoc->GetPattern(
													nCol, nAttrRow, nDestTab );
				DBG_ASSERT(pSrcPattern,"Pattern ist 0");
				if (pSrcPattern)
					pDoc->ApplyPatternAreaTab( nCol, nAttrRow, nCol, aLocalParam.nRow2,
													nDestTab, *pSrcPattern );
				const ScStyleSheet* pStyle = pSrcPattern->GetStyleSheet();
				if (pStyle)
					pDoc->ApplyStyleAreaTab( nCol, nAttrRow, nCol, aLocalParam.nRow2,
													nDestTab, *pStyle );
			}

			delete pAttribDoc;
		}
	}

	//	speichern: Inplace immer, sonst je nach Einstellung
	//			   alter Inplace-Filter ist ggf. schon aufgehoben

	sal_Bool bSave = rQueryParam.bInplace || rQueryParam.bDestPers;
	if (bSave)													// merken
	{
		pDBData->SetQueryParam( rQueryParam );
		pDBData->SetHeader( rQueryParam.bHasHeader );		//! ???
		pDBData->SetAdvancedQuerySource( pAdvSource );		// after SetQueryParam
	}

	if (bCopy)												// neuen DB-Bereich merken
	{
		//	selektieren wird hinterher von aussen (dbfunc)
		//	momentan ueber DB-Bereich an der Zielposition, darum muss dort
		//	auf jeden Fall ein Bereich angelegt werden.

		ScDBData* pNewData;
		if (pDestData)
			pNewData = pDestData;				// Bereich vorhanden -> anpassen (immer!)
		else									// Bereich anlegen
			pNewData = rDocShell.GetDBData(
							ScRange( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
									 aLocalParam.nCol2, aLocalParam.nRow2, nDestTab ),
							SC_DB_MAKE_FILTER, SC_DBSEL_FORCE_MARK );

		if (pNewData)
		{
			pNewData->SetArea( nDestTab, aLocalParam.nCol1, aLocalParam.nRow1,
											aLocalParam.nCol2, aLocalParam.nRow2 );

			//	Query-Param wird am Ziel nicht mehr eingestellt, fuehrt nur zu Verwirrung
			//	und Verwechslung mit dem Query-Param am Quellbereich (#37187#)
		}
		else
		{
			DBG_ERROR("Zielbereich nicht da");
		}
	}

	if (!bCopy)
    {
        pDoc->InvalidatePageBreaks(nTab);    
		pDoc->UpdatePageBreaks( nTab );
    }

    // #i23299# because of Subtotal functions, the whole rows must be set dirty
	ScRange aDirtyRange( 0 , aLocalParam.nRow1, nDestTab,
		MAXCOL, aLocalParam.nRow2, nDestTab );
	pDoc->SetDirty( aDirtyRange );

    if ( bRecord )
    {
        // create undo action after executing, because of drawing layer undo
		rDocShell.GetUndoManager()->AddUndoAction(
					new ScUndoQuery( &rDocShell, nTab, rQueryParam, pUndoDoc, pUndoDB,
										pOld, bDoSize, pAdvSource ) );
    }


	if (bCopy)
	{
		SCCOL nEndX = aLocalParam.nCol2;
		SCROW nEndY = aLocalParam.nRow2;
		if (pDestData)
		{
			if ( aOldDest.aEnd.Col() > nEndX )
				nEndX = aOldDest.aEnd.Col();
			if ( aOldDest.aEnd.Row() > nEndY )
				nEndY = aOldDest.aEnd.Row();
		}
		if (bDoSize)
			nEndY = MAXROW;
		rDocShell.PostPaint( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
									nEndX, nEndY, nDestTab, PAINT_GRID );
	}
	else
		rDocShell.PostPaint( 0, rQueryParam.nRow1, nTab, MAXCOL, MAXROW, nTab,
												PAINT_GRID | PAINT_LEFT );
	aModificator.SetDocumentModified();

	return sal_True;
}

// -----------------------------------------------------------------

sal_Bool ScDBDocFunc::DoSubTotals( SCTAB nTab, const ScSubTotalParam& rParam,
								const ScSortParam* pForceNewSort, sal_Bool bRecord, sal_Bool bApi )
{
	//!	auch fuer ScDBFunc::DoSubTotals benutzen!
	//	dann bleibt aussen:
	//	- neuen Bereich (aus DBData) markieren
	//	- SelectionChanged (?)

	sal_Bool bDo = !rParam.bRemoveOnly;							// sal_False = nur loeschen
	sal_Bool bRet = sal_False;

	ScDocument* pDoc = rDocShell.GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
	ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1,
												rParam.nCol2, rParam.nRow2 );
	if (!pDBData)
	{
		DBG_ERROR( "SubTotals: keine DBData" );
		return sal_False;
	}

	ScEditableTester aTester( pDoc, nTab, 0,rParam.nRow1+1, MAXCOL,MAXROW );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	if (pDoc->HasAttrib( rParam.nCol1, rParam.nRow1+1, nTab,
						 rParam.nCol2, rParam.nRow2, nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ))
	{
		if (!bApi)
			rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);	// nicht in zusammengefasste einfuegen
		return sal_False;
	}

	sal_Bool bOk = sal_True;
	sal_Bool bDelete = sal_False;
	if (rParam.bReplace)
		if (pDoc->TestRemoveSubTotals( nTab, rParam ))
		{
			bDelete = sal_True;
			bOk = ( MessBox( rDocShell.GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
				// "StarCalc" "Daten loeschen?"
				ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
				ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_1 ) ).Execute()
				== RET_YES );
		}

	if (bOk)
	{
		WaitObject aWait( rDocShell.GetActiveDialogParent() );
		ScDocShellModificator aModificator( rDocShell );

		ScSubTotalParam aNewParam( rParam );		// Bereichsende wird veraendert
		ScDocument*		pUndoDoc = NULL;
		ScOutlineTable*	pUndoTab = NULL;
		ScRangeName*	pUndoRange = NULL;
		ScDBCollection* pUndoDB = NULL;
		SCTAB 			nTabCount = 0;				// fuer Referenz-Undo

		if (bRecord)										// alte Daten sichern
		{
			sal_Bool bOldFilter = bDo && rParam.bDoSort;

			nTabCount = pDoc->GetTableCount();
			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
			ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
			if (pTable)
			{
				pUndoTab = new ScOutlineTable( *pTable );

                // column/row state
                SCCOLROW nOutStartCol, nOutEndCol;
                SCCOLROW nOutStartRow, nOutEndRow;
				pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol );
				pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow );

				pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
				pDoc->CopyToDocument( static_cast<SCCOL>(nOutStartCol), 0, nTab, static_cast<SCCOL>(nOutEndCol), MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
				pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
			}
			else
				pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, bOldFilter );

			//	Datenbereich sichern - incl. Filter-Ergebnis
			pDoc->CopyToDocument( 0,rParam.nRow1+1,nTab, MAXCOL,rParam.nRow2,nTab,
									IDF_ALL, sal_False, pUndoDoc );

			//	alle Formeln wegen Referenzen
			pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1,
										IDF_FORMULA, sal_False, pUndoDoc );

			//	DB- und andere Bereiche
			ScRangeName* pDocRange = pDoc->GetRangeName();
			if (pDocRange->GetCount())
				pUndoRange = new ScRangeName( *pDocRange );
			ScDBCollection* pDocDB = pDoc->GetDBCollection();
			if (pDocDB->GetCount())
				pUndoDB = new ScDBCollection( *pDocDB );
		}

//		pDoc->SetOutlineTable( nTab, NULL );
		ScOutlineTable*	pOut = pDoc->GetOutlineTable( nTab );
		if (pOut)
			pOut->GetRowArray()->RemoveAll();		// nur Zeilen-Outlines loeschen

		if (rParam.bReplace)
			pDoc->RemoveSubTotals( nTab, aNewParam );
		sal_Bool bSuccess = sal_True;
		if (bDo)
		{
			// Sortieren
			if ( rParam.bDoSort || pForceNewSort )
			{
				pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );

				//	Teilergebnis-Felder vor die Sortierung setzen
				//	(doppelte werden weggelassen, kann darum auch wieder aufgerufen werden)

				ScSortParam aOldSort;
				pDBData->GetSortParam( aOldSort );
				ScSortParam aSortParam( aNewParam, pForceNewSort ? *pForceNewSort : aOldSort );
				Sort( nTab, aSortParam, sal_False, sal_False, bApi );
			}

			bSuccess = pDoc->DoSubTotals( nTab, aNewParam );
		}
		ScRange aDirtyRange( aNewParam.nCol1, aNewParam.nRow1, nTab,
			aNewParam.nCol2, aNewParam.nRow2, nTab );
		pDoc->SetDirty( aDirtyRange );

		if (bRecord)
		{
//			ScDBData* pUndoDBData = pDBData ? new ScDBData( *pDBData ) : NULL;
			rDocShell.GetUndoManager()->AddUndoAction(
				new ScUndoSubTotals( &rDocShell, nTab,
										rParam, aNewParam.nRow2,
										pUndoDoc, pUndoTab, // pUndoDBData,
										pUndoRange, pUndoDB ) );
		}

		if (!bSuccess)
		{
			// "Kann keine Zeilen einfuegen"
			if (!bApi)
				rDocShell.ErrorMessage(STR_MSSG_DOSUBTOTALS_2);
		}

													// merken
		pDBData->SetSubTotalParam( aNewParam );
		pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
		pDoc->CompileDBFormula();

		rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
												PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
		aModificator.SetDocumentModified();

		bRet = bSuccess;
	}
	return bRet;
}

//==================================================================

sal_Bool lcl_EmptyExcept( ScDocument* pDoc, const ScRange& rRange, const ScRange& rExcept )
{
	ScCellIterator aIter( pDoc, rRange );
	ScBaseCell* pCell = aIter.GetFirst();
	while (pCell)
	{
        if ( !pCell->IsBlank() )      // real content?
		{
			if ( !rExcept.In( ScAddress( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() ) ) )
				return sal_False;		// cell found
		}
		pCell = aIter.GetNext();
	}

	return sal_True;		// nothing found - empty
}

sal_Bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj,
										sal_Bool bRecord, sal_Bool bApi, sal_Bool bAllowMove )
{
	ScDocShellModificator aModificator( rDocShell );
	WaitObject aWait( rDocShell.GetActiveDialogParent() );

	sal_Bool bDone = sal_False;
	sal_Bool bUndoSelf = sal_False;
	sal_uInt16 nErrId = 0;

	ScDocument* pOldUndoDoc = NULL;
	ScDocument* pNewUndoDoc = NULL;
	ScDPObject* pUndoDPObj = NULL;
	if ( bRecord && pOldObj )
		pUndoDPObj = new ScDPObject( *pOldObj );	// copy old settings for undo

	ScDocument* pDoc = rDocShell.GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
	if ( !rDocShell.IsEditable() || pDoc->GetChangeTrack() )
	{
		//	not recorded -> disallow
		//!	different error messages?

		nErrId = STR_PROTECTIONERR;
	}
	if ( pOldObj && !nErrId )
	{
		ScRange aOldOut = pOldObj->GetOutRange();
		ScEditableTester aTester( pDoc, aOldOut );
		if ( !aTester.IsEditable() )
			nErrId = aTester.GetMessageId();
	}
	if ( pNewObj && !nErrId )
	{
		//	at least one cell at the output position must be editable
		//	-> check in advance
		//	(start of output range in pNewObj is valid)

		ScRange aNewStart( pNewObj->GetOutRange().aStart );
		ScEditableTester aTester( pDoc, aNewStart );
		if ( !aTester.IsEditable() )
			nErrId = aTester.GetMessageId();
	}

	ScDPObject* pDestObj = NULL;
	if ( !nErrId )
	{
		if ( pOldObj && !pNewObj )
		{
			//	delete table

			ScRange aRange = pOldObj->GetOutRange();
			SCTAB nTab = aRange.aStart.Tab();

			if ( bRecord )
			{
				pOldUndoDoc = new ScDocument( SCDOCMODE_UNDO );
				pOldUndoDoc->InitUndo( pDoc, nTab, nTab );
				pDoc->CopyToDocument( aRange, IDF_ALL, sal_False, pOldUndoDoc );
			}

			pDoc->DeleteAreaTab( aRange.aStart.Col(), aRange.aStart.Row(),
								 aRange.aEnd.Col(),   aRange.aEnd.Row(),
								 nTab, IDF_ALL );
			pDoc->RemoveFlagsTab( aRange.aStart.Col(), aRange.aStart.Row(),
								  aRange.aEnd.Col(),   aRange.aEnd.Row(),
								  nTab, SC_MF_AUTO );

            pDoc->GetDPCollection()->FreeTable( pOldObj );  // object is deleted here

			rDocShell.PostPaintGridAll();	//! only necessary parts
			rDocShell.PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), nTab,
								 aRange.aEnd.Col(),   aRange.aEnd.Row(),   nTab,
								 PAINT_GRID );
			bDone = sal_True;
		}
		else if ( pNewObj )
		{
			if ( pOldObj )
			{
				if ( bRecord )
				{
					ScRange aRange = pOldObj->GetOutRange();
					SCTAB nTab = aRange.aStart.Tab();
					pOldUndoDoc = new ScDocument( SCDOCMODE_UNDO );
					pOldUndoDoc->InitUndo( pDoc, nTab, nTab );
					pDoc->CopyToDocument( aRange, IDF_ALL, sal_False, pOldUndoDoc );
				}

				if ( pNewObj == pOldObj )
				{
					//	refresh only - no settings modified
				}
				else
				{
					pNewObj->WriteSourceDataTo( *pOldObj );		// copy source data

					ScDPSaveData* pData = pNewObj->GetSaveData();
					DBG_ASSERT( pData, "no SaveData from living DPObject" );
					if ( pData )
						pOldObj->SetSaveData( *pData );		// copy SaveData
				}

				pDestObj = pOldObj;
				pDestObj->SetAllowMove( bAllowMove );
			}
			else
			{
				//	output range must be set at pNewObj

				pDestObj = new ScDPObject( *pNewObj );

                // #i94570# When changing the output position in the dialog, a new table is created
                // with the settings from the old table, including the name.
                // So we have to check for duplicate names here (before inserting).
                if ( pDoc->GetDPCollection()->GetByName(pDestObj->GetName()) )
                    pDestObj->SetName( String() );      // ignore the invalid name, create a new name below

				pDestObj->SetAlive(sal_True);
                if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) )
				{
					DBG_ERROR("cannot insert DPObject");
					DELETEZ( pDestObj );
				}
			}
			if ( pDestObj )
			{
				// #78541# create new database connection for "refresh"
				// (and re-read column entry collections)
				// so all changes take effect
				if ( pNewObj == pOldObj && pDestObj->IsImportData() )
					pDestObj->InvalidateSource();

				pDestObj->InvalidateData();				// before getting the new output area

				//	make sure the table has a name (not set by dialog)
				if ( !pDestObj->GetName().Len() )
					pDestObj->SetName( pDoc->GetDPCollection()->CreateNewName() );

				sal_Bool bOverflow = sal_False;
				ScRange aNewOut = pDestObj->GetNewOutputRange( bOverflow );

                //!	test for overlap with other data pilot tables
                if( pOldObj )
                {   
                    const ScSheetSourceDesc* pSheetDesc = pOldObj->GetSheetDesc();
                    if( pSheetDesc && pSheetDesc->aSourceRange.Intersects( aNewOut ) )
                    {
                        ScRange aOldRange = pOldObj->GetOutRange();
                        SCsROW nDiff = aOldRange.aStart.Row()-aNewOut.aStart.Row();
                        aNewOut.aStart.SetRow( aOldRange.aStart.Row() );
                        aNewOut.aEnd.SetRow( aNewOut.aEnd.Row()+nDiff );
                        if( !ValidRow( aNewOut.aStart.Row() ) || !ValidRow( aNewOut.aEnd.Row() ) )
                            bOverflow = sal_True;
                    }
                }

				if ( bOverflow )
				{
					//	like with STR_PROTECTIONERR, use undo to reverse everything
					DBG_ASSERT( bRecord, "DataPilotUpdate: can't undo" );
					bUndoSelf = sal_True;
					nErrId = STR_PIVOT_ERROR;
				}
				else
				{
					ScEditableTester aTester( pDoc, aNewOut );
					if ( !aTester.IsEditable() )
					{
						//	destination area isn't editable
						//!	reverse everything done so far, don't proceed

						//	quick solution: proceed to end, use undo action
						//	to reverse everything:
						DBG_ASSERT( bRecord, "DataPilotUpdate: can't undo" );
						bUndoSelf = sal_True;
						nErrId = aTester.GetMessageId();
					}
				}

				//	test if new output area is empty except for old area
				if ( !bApi )
				{
					sal_Bool bEmpty;
					if ( pOldObj )	// OutRange of pOldObj (pDestObj) is still old area
						bEmpty = lcl_EmptyExcept( pDoc, aNewOut, pOldObj->GetOutRange() );
					else
						bEmpty = pDoc->IsBlockEmpty( aNewOut.aStart.Tab(),
											aNewOut.aStart.Col(), aNewOut.aStart.Row(),
											aNewOut.aEnd.Col(), aNewOut.aEnd.Row() );

					if ( !bEmpty )
					{
						QueryBox aBox( rDocShell.GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
										 ScGlobal::GetRscString(STR_PIVOT_NOTEMPTY) );
						if (aBox.Execute() == RET_NO)
						{
							//!	like above (not editable), use undo to reverse everything
							DBG_ASSERT( bRecord, "DataPilotUpdate: can't undo" );
							bUndoSelf = sal_True;
						}
					}
				}

				if ( bRecord )
				{
					SCTAB nTab = aNewOut.aStart.Tab();
					pNewUndoDoc = new ScDocument( SCDOCMODE_UNDO );
					pNewUndoDoc->InitUndo( pDoc, nTab, nTab );
					pDoc->CopyToDocument( aNewOut, IDF_ALL, sal_False, pNewUndoDoc );
				}

				pDestObj->Output( aNewOut.aStart );

				rDocShell.PostPaintGridAll();			//! only necessary parts
				bDone = sal_True;
			}
		}
		// else nothing (no old, no new)
	}

	if ( bRecord && bDone )
	{
		SfxUndoAction* pAction = new ScUndoDataPilot( &rDocShell,
									pOldUndoDoc, pNewUndoDoc, pUndoDPObj, pDestObj, bAllowMove );
		pOldUndoDoc = NULL;
		pNewUndoDoc = NULL;		// pointers are used in undo action
		// pUndoDPObj is copied

		if (bUndoSelf)
		{
			//	use undo action to restore original state
			//!	prevent setting the document modified? (ScDocShellModificator)

			pAction->Undo();
			delete pAction;
			bDone = sal_False;
		}
		else
			rDocShell.GetUndoManager()->AddUndoAction( pAction );
	}

	delete pOldUndoDoc;		// if not used for undo
	delete pNewUndoDoc;
	delete pUndoDPObj;

	if (bDone)
    {
        // notify API objects
        if (pDestObj)
            pDoc->BroadcastUno( ScDataPilotModifiedHint( pDestObj->GetName() ) );
		aModificator.SetDocumentModified();
    }

	if ( nErrId && !bApi )
		rDocShell.ErrorMessage( nErrId );

	return bDone;
}

//==================================================================
//
//      database import

void ScDBDocFunc::UpdateImport( const String& rTarget, const svx::ODataAccessDescriptor& rDescriptor )
{
    // rTarget is the name of a database range

	ScDocument* pDoc = rDocShell.GetDocument();
	ScDBCollection& rDBColl = *pDoc->GetDBCollection();
    ScDBData* pData = NULL;
	ScImportParam aImportParam;
	sal_Bool bFound = sal_False;
	sal_uInt16 nCount = rDBColl.GetCount();
	for (sal_uInt16 i=0; i<nCount && !bFound; i++)
	{
		pData = rDBColl[i];
		if (pData->GetName() == rTarget)
			bFound = sal_True;
	}
	if (!bFound)
	{
		InfoBox aInfoBox(rDocShell.GetActiveDialogParent(),
					ScGlobal::GetRscString( STR_TARGETNOTFOUND ) );
		aInfoBox.Execute();
		return;
	}

	SCTAB nTab;
	SCCOL nDummyCol;
    SCROW nDummyRow;
	pData->GetArea( nTab, nDummyCol,nDummyRow,nDummyCol,nDummyRow );
	pData->GetImportParam( aImportParam );

    rtl::OUString sDBName;
    rtl::OUString sDBTable;
    sal_Int32 nCommandType = 0;
    rDescriptor[svx::daDataSource]  >>= sDBName;
    rDescriptor[svx::daCommand]     >>= sDBTable;
    rDescriptor[svx::daCommandType] >>= nCommandType;

    aImportParam.aDBName    = sDBName;
    aImportParam.bSql       = ( nCommandType == sdb::CommandType::COMMAND );
    aImportParam.aStatement = sDBTable;
    aImportParam.bNative    = sal_False;
    aImportParam.nType      = static_cast<sal_uInt8>( ( nCommandType == sdb::CommandType::QUERY ) ? ScDbQuery : ScDbTable );
    aImportParam.bImport	= sal_True;

    sal_Bool bContinue = DoImport( nTab, aImportParam, &rDescriptor, sal_True );

	//	DB-Operationen wiederholen

	ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();
	if (pViewSh)
	{
		ScRange aRange;
		pData->GetArea(aRange);
		pViewSh->MarkRange(aRange);			// selektieren

		if ( bContinue )		// #41905# Fehler beim Import -> Abbruch
		{
			//	interne Operationen, wenn welche gespeichert

			if ( pData->HasQueryParam() || pData->HasSortParam() || pData->HasSubTotalParam() )
				pViewSh->RepeatDB();

			//	Pivottabellen die den Bereich als Quelldaten haben

			rDocShell.RefreshPivotTables(aRange);
		}
	}
}




