summaryrefslogtreecommitdiff
path: root/sc/source/ui/view/viewfun2.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/view/viewfun2.cxx')
-rw-r--r--sc/source/ui/view/viewfun2.cxx3147
1 files changed, 3147 insertions, 0 deletions
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
new file mode 100644
index 000000000000..34fbbfdad5b5
--- /dev/null
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -0,0 +1,3147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#define _SVSTDARR_STRINGS
+#include <editeng/boxitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <svl/srchitem.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objitem.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/stritem.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/svstdarr.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/waitobj.hxx>
+
+#include "viewfunc.hxx"
+
+#include "sc.hrc"
+#include "globstr.hrc"
+
+#include "attrib.hxx"
+#include "autoform.hxx"
+#include "cell.hxx" // EnterAutoSum
+#include "compiler.hxx"
+#include "docfunc.hxx"
+#include "docpool.hxx"
+#include "docsh.hxx"
+#include "global.hxx"
+#include "patattr.hxx"
+#include "printfun.hxx"
+#include "rangenam.hxx"
+#include "rangeutl.hxx"
+#include "refundo.hxx"
+#include "tablink.hxx"
+#include "tabvwsh.hxx"
+#include "uiitems.hxx"
+#include "undoblk.hxx"
+#include "undocell.hxx"
+#include "undotab.hxx"
+#include "sizedev.hxx"
+#include "editable.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "funcdesc.hxx"
+#include "docuno.hxx"
+#include "charthelper.hxx"
+#include "tabbgcolor.hxx"
+
+#include <basic/sbstar.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+using namespace com::sun::star;
+
+// helper func defined in docfunc.cxx
+void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName );
+
+// STATIC DATA ---------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::AdjustBlockHeight( BOOL bPaint, ScMarkData* pMarkData )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if (!pMarkData)
+ pMarkData = &GetViewData()->GetMarkData();
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
+ SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges );
+ if (nRangeCnt == 0)
+ {
+ pRanges[0] = pRanges[1] = GetViewData()->GetCurY();
+ nRangeCnt = 1;
+ }
+
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+
+ BOOL bAnyChanged = FALSE;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ SCCOLROW* pOneRange = pRanges;
+ BOOL bChanged = FALSE;
+ SCROW nPaintY = 0;
+ for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCROW nStartNo = *(pOneRange++);
+ SCROW nEndNo = *(pOneRange++);
+ if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, FALSE ))
+ {
+ if (!bChanged)
+ nPaintY = nStartNo;
+ bAnyChanged = bChanged = TRUE;
+ }
+ }
+ if ( bPaint && bChanged )
+ pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
+ PAINT_GRID | PAINT_LEFT );
+ }
+ }
+ delete[] pRanges;
+
+ if ( bPaint && bAnyChanged )
+ pDocSh->UpdateOle(GetViewData());
+
+ return bAnyChanged;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, BOOL bPaint )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+ USHORT nOldPixel = 0;
+ if (nStartRow == nEndRow)
+ nOldPixel = (USHORT) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+ BOOL bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, FALSE );
+
+ if (bChanged && ( nStartRow == nEndRow ))
+ {
+ USHORT nNewPixel = (USHORT) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
+ if ( nNewPixel == nOldPixel )
+ bChanged = FALSE;
+ }
+
+ if ( bPaint && bChanged )
+ pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
+ PAINT_GRID | PAINT_LEFT );
+
+ return bChanged;
+}
+
+
+//----------------------------------------------------------------------------
+
+enum ScAutoSum
+{
+ ScAutoSumNone = 0,
+ ScAutoSumData,
+ ScAutoSumSum
+};
+
+
+ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
+ SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
+{
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ if ( pCell && pCell->HasValueData() )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScTokenArray* pCode = ((ScFormulaCell*)pCell)->GetCode();
+ if ( pCode && pCode->GetOuterFuncOpCode() == ocSum )
+ {
+ if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend,
+ ScAddress( nCol, nRow, nTab ), eDir ) )
+ return ScAutoSumSum;
+ }
+ }
+ return ScAutoSumData;
+ }
+ return ScAutoSumNone;
+}
+
+
+//----------------------------------------------------------------------------
+
+#define SC_AUTOSUM_MAXCOUNT 20
+
+ScAutoSum lcl_SeekAutoSumData( ScDocument* pDoc, SCCOL& nCol, SCROW& nRow,
+ SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
+{
+ USHORT nCount = 0;
+ while (nCount < SC_AUTOSUM_MAXCOUNT)
+ {
+ if ( eDir == DIR_TOP )
+ {
+ if (nRow > 0)
+ --nRow;
+ else
+ return ScAutoSumNone;
+ }
+ else
+ {
+ if (nCol > 0)
+ --nCol;
+ else
+ return ScAutoSumNone;
+ }
+ ScAutoSum eSum;
+ if ( (eSum = lcl_IsAutoSumData(
+ pDoc, nCol, nRow, nTab, eDir, nExtend )) != ScAutoSumNone )
+ return eSum;
+ ++nCount;
+ }
+ return ScAutoSumNone;
+}
+
+#undef SC_AUTOSUM_MAXCOUNT
+
+//----------------------------------------------------------------------------
+
+bool lcl_FindNextSumEntryInColumn( ScDocument* pDoc, SCCOL nCol, SCROW& nRow,
+ SCTAB nTab, SCCOLROW& nExtend, SCROW nMinRow )
+{
+ const SCROW nTmp = nRow;
+ ScAutoSum eSkip = ScAutoSumNone;
+ while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) ) == ScAutoSumData &&
+ nRow > nMinRow )
+ {
+ --nRow;
+ }
+ if ( eSkip == ScAutoSumSum && nRow < nTmp )
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+
+bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow,
+ SCTAB nTab, SCCOLROW& nExtend, SCROW nMinCol )
+{
+ const SCCOL nTmp = nCol;
+ ScAutoSum eSkip = ScAutoSumNone;
+ while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) ) == ScAutoSumData &&
+ nCol > nMinCol )
+ {
+ --nCol;
+ }
+ if ( eSkip == ScAutoSumSum && nCol < nTmp )
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+
+bool lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
+{
+ const ScAddress aStart = rRange.aStart;
+ const ScAddress aEnd = rRange.aEnd;
+ if ( aStart.Col() != aEnd.Col() )
+ {
+ return false;
+ }
+
+ const SCTAB nTab = aEnd.Tab();
+ const SCCOL nCol = aEnd.Col();
+ SCROW nEndRow = aEnd.Row();
+ SCROW nStartRow = nEndRow;
+ SCCOLROW nExtend = 0;
+ const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nCol, nEndRow, nTab, DIR_TOP, nExtend /*out*/ );
+
+ if ( eSum == ScAutoSumSum )
+ {
+ bool bContinue = false;
+ do
+ {
+ rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
+ nEndRow = static_cast< SCROW >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, aStart.Row() ) ) == true )
+ {
+ nStartRow = nEndRow;
+ }
+ } while ( bContinue );
+ }
+ else
+ {
+ while ( nStartRow > aStart.Row() &&
+ lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) != ScAutoSumSum )
+ {
+ --nStartRow;
+ }
+ rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+
+bool lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
+{
+ const ScAddress aStart = rRange.aStart;
+ const ScAddress aEnd = rRange.aEnd;
+ if ( aStart.Row() != aEnd.Row() )
+ {
+ return false;
+ }
+
+ const SCTAB nTab = aEnd.Tab();
+ const SCROW nRow = aEnd.Row();
+ SCCOL nEndCol = aEnd.Col();
+ SCCOL nStartCol = nEndCol;
+ SCCOLROW nExtend = 0;
+ const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ );
+
+ if ( eSum == ScAutoSumSum )
+ {
+ bool bContinue = false;
+ do
+ {
+ rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
+ nEndCol = static_cast< SCCOL >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, aStart.Col() ) ) == true )
+ {
+ nStartCol = nEndCol;
+ }
+ } while ( bContinue );
+ }
+ else
+ {
+ while ( nStartCol > aStart.Col() &&
+ lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ ) != ScAutoSumSum )
+ {
+ --nStartCol;
+ }
+ rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+
+ SCCOL nStartCol = nCol;
+ SCROW nStartRow = nRow;
+ SCCOL nEndCol = nCol;
+ SCROW nEndRow = nRow;
+ SCCOL nSeekCol = nCol;
+ SCROW nSeekRow = nRow;
+ SCCOLROW nExtend; // wird per Reference gueltig bei ScAutoSumSum
+
+ BOOL bCol = FALSE;
+ BOOL bRow = FALSE;
+
+ ScAutoSum eSum;
+ if ( nRow != 0
+ && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
+ DIR_TOP, nExtend /*out*/ )) == ScAutoSumData )
+ && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
+ DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
+ )
+ {
+ bRow = TRUE;
+ nSeekRow = nRow - 1;
+ }
+ else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
+ DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
+ {
+ bCol = TRUE;
+ nSeekCol = nCol - 1;
+ }
+ else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
+ bRow = TRUE;
+ else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
+ bCol = TRUE;
+
+ if ( bCol || bRow )
+ {
+ if ( bRow )
+ {
+ nStartRow = nSeekRow; // nSeekRow evtl. per Reference angepasst
+ if ( eSum == ScAutoSumSum )
+ nEndRow = nStartRow; // nur Summen summieren
+ else
+ nEndRow = nRow - 1; // Datenbereich evtl. nach unten erweitern
+ }
+ else
+ {
+ nStartCol = nSeekCol; // nSeekCol evtl. per Reference angepasst
+ if ( eSum == ScAutoSumSum )
+ nEndCol = nStartCol; // nur Summen summieren
+ else
+ nEndCol = nCol - 1; // Datenbereich evtl. nach rechts erweitern
+ }
+ BOOL bContinue = FALSE;
+ do
+ {
+ if ( eSum == ScAutoSumData )
+ {
+ if ( bRow )
+ {
+ while ( nStartRow != 0 && lcl_IsAutoSumData( pDoc, nCol,
+ nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
+ --nStartRow;
+ }
+ else
+ {
+ while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1,
+ nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum )
+ --nStartCol;
+ }
+ }
+ rRangeList.Append(
+ ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) );
+ if ( eSum == ScAutoSumSum )
+ {
+ if ( bRow )
+ {
+ nEndRow = static_cast< SCROW >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, 0 ) ) == true )
+ {
+ nStartRow = nEndRow;
+ }
+ }
+ else
+ {
+ nEndCol = static_cast< SCCOL >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true )
+ {
+ nStartCol = nEndCol;
+ }
+ }
+ }
+ } while ( bContinue );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, sal_Bool bSubTotal) // Block mit Summen fuellen
+{
+ String aFormula = GetAutoSumFormula( rRangeList, bSubTotal );
+ EnterBlock( aFormula, NULL );
+}
+
+//----------------------------------------------------------------------------
+
+bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ const SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ const SCCOL nEndCol = rRange.aEnd.Col();
+ const SCROW nEndRow = rRange.aEnd.Row();
+ SCCOLROW nExtend = 0; // out parameter for lcl_IsAutoSumData
+
+ // ignore rows at the top of the given range which don't contain autosum data
+ bool bRowData = false;
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) != ScAutoSumNone )
+ {
+ bRowData = true;
+ break;
+ }
+ }
+ if ( bRowData )
+ {
+ nStartRow = nRow;
+ break;
+ }
+ }
+ if ( !bRowData )
+ {
+ return false;
+ }
+
+ // ignore columns at the left of the given range which don't contain autosum data
+ bool bColData = false;
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) != ScAutoSumNone )
+ {
+ bColData = true;
+ break;
+ }
+ }
+ if ( bColData )
+ {
+ nStartCol = nCol;
+ break;
+ }
+ }
+ if ( !bColData )
+ {
+ return false;
+ }
+
+ const bool bEndRowEmpty = pDoc->IsBlockEmpty( nTab, nStartCol, nEndRow, nEndCol, nEndRow );
+ const bool bEndColEmpty = pDoc->IsBlockEmpty( nTab, nEndCol, nStartRow, nEndCol, nEndRow );
+ bool bRow = ( ( nStartRow != nEndRow ) && ( bEndRowEmpty || ( !bEndRowEmpty && !bEndColEmpty ) ) );
+ bool bCol = ( ( nStartCol != nEndCol ) && ( bEndColEmpty || nStartRow == nEndRow ) );
+
+ // find an empty row for entering the result
+ SCROW nInsRow = nEndRow;
+ if ( bRow && !bEndRowEmpty )
+ {
+ if ( nInsRow < MAXROW )
+ {
+ ++nInsRow;
+ while ( !pDoc->IsBlockEmpty( nTab, nStartCol, nInsRow, nEndCol, nInsRow ) )
+ {
+ if ( nInsRow < MAXROW )
+ {
+ ++nInsRow;
+ }
+ else
+ {
+ bRow = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ bRow = false;
+ }
+ }
+
+ // find an empty column for entering the result
+ SCCOL nInsCol = nEndCol;
+ if ( bCol && !bEndColEmpty )
+ {
+ if ( nInsCol < MAXCOL )
+ {
+ ++nInsCol;
+ while ( !pDoc->IsBlockEmpty( nTab, nInsCol, nStartRow, nInsCol, nEndRow ) )
+ {
+ if ( nInsCol < MAXCOL )
+ {
+ ++nInsCol;
+ }
+ else
+ {
+ bCol = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ bCol = false;
+ }
+ }
+
+ if ( !bRow && !bCol )
+ {
+ return false;
+ }
+
+ SCCOL nMarkEndCol = nEndCol;
+ SCROW nMarkEndRow = nEndRow;
+
+ if ( bRow )
+ {
+ // calculate the row sums for all columns of the given range
+
+ SCROW nSumEndRow = nEndRow;
+
+ if ( bEndRowEmpty )
+ {
+ // the last row of the given range is empty;
+ // don't take into account for calculating the autosum
+ --nSumEndRow;
+ }
+ else
+ {
+ // increase mark range
+ ++nMarkEndRow;
+ }
+
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ if ( !pDoc->IsBlockEmpty( nTab, nCol, nStartRow, nCol, nSumEndRow ) )
+ {
+ ScRangeList aRangeList;
+ const ScRange aRange( nCol, nStartRow, nTab, nCol, nSumEndRow, nTab );
+ if ( lcl_GetAutoSumForColumnRange( pDoc, aRangeList, aRange ) )
+ {
+ const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
+ EnterData( nCol, nInsRow, nTab, aFormula );
+ }
+ }
+ }
+ }
+
+ if ( bCol )
+ {
+ // calculate the column sums for all rows of the given range
+
+ SCCOL nSumEndCol = nEndCol;
+
+ if ( bEndColEmpty )
+ {
+ // the last column of the given range is empty;
+ // don't take into account for calculating the autosum
+ --nSumEndCol;
+ }
+ else
+ {
+ // increase mark range
+ ++nMarkEndCol;
+ }
+
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ if ( !pDoc->IsBlockEmpty( nTab, nStartCol, nRow, nSumEndCol, nRow ) )
+ {
+ ScRangeList aRangeList;
+ const ScRange aRange( nStartCol, nRow, nTab, nSumEndCol, nRow, nTab );
+ if ( lcl_GetAutoSumForRowRange( pDoc, aRangeList, aRange ) )
+ {
+ const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
+ EnterData( nInsCol, nRow, nTab, aFormula );
+ }
+ }
+ }
+ }
+
+ // set new mark range and cursor position
+ const ScRange aMarkRange( nStartCol, nStartRow, nTab, nMarkEndCol, nMarkEndRow, nTab );
+ MarkRange( aMarkRange, FALSE, bContinue );
+ if ( bSetCursor )
+ {
+ SetCursor( nMarkEndCol, nMarkEndRow );
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+
+String ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal )
+{
+ String aFormula = '=';
+ ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
+ const ScFuncDesc* pDesc = NULL;
+ if ( bSubTotal )
+ {
+ pDesc = pFuncMgr->Get( SC_OPCODE_SUB_TOTAL );
+ }
+ else
+ {
+ pDesc = pFuncMgr->Get( SC_OPCODE_SUM );
+ }
+ if ( pDesc && pDesc->pFuncName )
+ {
+ aFormula += *pDesc->pFuncName;
+ if ( bSubTotal )
+ {
+ aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "(9;" ) );
+ }
+ else
+ {
+ aFormula += '(';
+ }
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ String aRef;
+ rRangeList.Format( aRef, SCA_VALID, pDoc );
+ aFormula += aRef;
+ aFormula += ')';
+ }
+ return aFormula;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::EnterBlock( const String& rString, const EditTextObject* pData )
+{
+ // Mehrfachselektion vorher abfragen...
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rMark.IsMultiMarked() )
+ {
+ rMark.MarkToSimple();
+ if ( rMark.IsMultiMarked() )
+ { // "Einfuegen auf Mehrfachselektion nicht moeglich"
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+
+ // insert into single cell
+ if ( pData )
+ EnterData( nCol, nRow, nTab, pData );
+ else
+ EnterData( nCol, nRow, nTab, rString );
+ return;
+ }
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ String aNewStr = rString;
+ if ( pData )
+ {
+ const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
+ aEngine.SetText(*pData);
+
+ ScEditAttrTester aTester( &aEngine );
+ if (!aTester.NeedsObject())
+ {
+ aNewStr = aEngine.GetText();
+ pData = NULL;
+ }
+ }
+
+ // Einfuegen per PasteFromClip
+
+ WaitObject aWait( GetFrameWin() );
+
+ ScAddress aPos( nCol, nRow, nTab );
+
+ ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
+ pInsDoc->ResetClip( pDoc, nTab );
+
+ if (aNewStr.GetChar(0) == '=') // Formel ?
+ {
+ // SetString geht nicht, weil in Clipboard-Dokumenten nicht kompiliert wird!
+ ScFormulaCell* pFCell = new ScFormulaCell( pDoc, aPos, aNewStr );
+ pInsDoc->PutCell( nCol, nRow, nTab, pFCell );
+ }
+ else if ( pData )
+ pInsDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pData, pDoc, NULL ) );
+ else
+ pInsDoc->SetString( nCol, nRow, nTab, aNewStr );
+
+ pInsDoc->SetClipArea( ScRange(aPos) );
+ // auf Block einfuegen, mit Undo etc.
+ if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, FALSE, FALSE,
+ FALSE, INS_NONE, IDF_ATTRIB ) )
+ {
+ const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr(
+ nCol, nRow, nTab, ATTR_VALUE_FORMAT );
+ if ( pItem )
+ { // Numberformat setzen wenn inkompatibel
+ // MarkData wurde bereits in PasteFromClip MarkToSimple'ed
+ ScRange aRange;
+ rMark.GetMarkArea( aRange );
+ ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() );
+ pPattern->GetItemSet().Put( *pItem );
+ short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() );
+ pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark,
+ *pPattern, nNewType );
+ delete pPattern;
+ }
+ }
+
+ delete pInsDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+//UNUSED2008-05 void ScViewFunc::PaintWidthHeight( BOOL bColumns, SCCOLROW nStart, SCCOLROW nEnd )
+//UNUSED2008-05 {
+//UNUSED2008-05 SCTAB nTab = GetViewData()->GetTabNo();
+//UNUSED2008-05 ScDocument* pDoc = GetViewData()->GetDocument();
+//UNUSED2008-05
+//UNUSED2008-05 USHORT nParts = PAINT_GRID;
+//UNUSED2008-05 SCCOL nStartCol = 0;
+//UNUSED2008-05 SCROW nStartRow = 0;
+//UNUSED2008-05 SCCOL nEndCol = MAXCOL; // fuer Test auf Merge
+//UNUSED2008-05 SCROW nEndRow = MAXROW;
+//UNUSED2008-05 if ( bColumns )
+//UNUSED2008-05 {
+//UNUSED2008-05 nParts |= PAINT_TOP;
+//UNUSED2008-05 nStartCol = static_cast<SCCOL>(nStart);
+//UNUSED2008-05 nEndCol = static_cast<SCCOL>(nEnd);
+//UNUSED2008-05 }
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 nParts |= PAINT_LEFT;
+//UNUSED2008-05 nStartRow = nStart;
+//UNUSED2008-05 nEndRow = nEnd;
+//UNUSED2008-05 }
+//UNUSED2008-05 if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
+//UNUSED2008-05 HASATTR_MERGED | HASATTR_OVERLAPPED ))
+//UNUSED2008-05 {
+//UNUSED2008-05 nStartCol = 0;
+//UNUSED2008-05 nStartRow = 0;
+//UNUSED2008-05 }
+//UNUSED2008-05 GetViewData()->GetDocShell()->PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts );
+//UNUSED2008-05 }
+
+
+//----------------------------------------------------------------------------
+// manueller Seitenumbruch
+
+void ScViewFunc::InsertPageBreak( BOOL bColumn, BOOL bRecord, const ScAddress* pPos,
+ BOOL bSetModified )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCursor;
+ if (pPos)
+ aCursor = *pPos;
+ else
+ aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
+
+ BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, FALSE );
+
+ if ( bSuccess && bSetModified )
+ UpdatePageBreakData( TRUE ); // fuer PageBreak-Modus
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::DeletePageBreak( BOOL bColumn, BOOL bRecord, const ScAddress* pPos,
+ BOOL bSetModified )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCursor;
+ if (pPos)
+ aCursor = *pPos;
+ else
+ aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
+
+ BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, FALSE );
+
+ if ( bSuccess && bSetModified )
+ UpdatePageBreakData( TRUE ); // fuer PageBreak-Modus
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::RemoveManualBreaks()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ if (bUndo)
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, FALSE, pUndoDoc );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
+ }
+
+ pDoc->RemoveManualBreaks(nTab);
+ pDoc->UpdatePageBreaks(nTab);
+
+ UpdatePageBreakData( TRUE );
+ pDocSh->SetDocumentModified();
+ pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetPrintZoom(USHORT nScale, USHORT nPages)
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ pDocSh->SetPrintZoom( nTab, nScale, nPages );
+}
+
+void ScViewFunc::AdjustPrintZoom()
+{
+ ScRange aRange;
+ if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
+ GetViewData()->GetMarkData().GetMultiMarkArea( aRange );
+ GetViewData()->GetDocShell()->AdjustPrintZoom( aRange );
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetPrintRanges( BOOL bEntireSheet, const String* pPrint,
+ const String* pRepCol, const String* pRepRow,
+ BOOL bAddPrint )
+{
+ // on all selected tables
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab;
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
+
+ ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (rMark.GetTableSelect(nTab))
+ {
+ ScRange aRange( 0,0,nTab );
+
+ // print ranges
+
+ if( !bAddPrint )
+ pDoc->ClearPrintRanges( nTab );
+
+ if( bEntireSheet )
+ {
+ pDoc->SetPrintEntireSheet( nTab );
+ }
+ else if ( pPrint )
+ {
+ if ( pPrint->Len() )
+ {
+ const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ USHORT nTCount = pPrint->GetTokenCount(sep);
+ for (USHORT i=0; i<nTCount; i++)
+ {
+ String aToken = pPrint->GetToken(i, sep);
+ if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID )
+ pDoc->AddPrintRange( nTab, aRange );
+ }
+ }
+ }
+ else // NULL = use selection (print range is always set), use empty string to delete all ranges
+ {
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ pDoc->AddPrintRange( nTab, aRange );
+ }
+ else if ( rMark.IsMultiMarked() )
+ {
+ rMark.MarkToMulti();
+ ScRangeListRef aList( new ScRangeList );
+ rMark.FillRangeListWithMarks( aList, FALSE );
+ USHORT nCnt = (USHORT) aList->Count();
+ if ( nCnt )
+ {
+ ScRangePtr pR;
+ USHORT i;
+ for ( pR = aList->First(), i=0; i < nCnt;
+ pR = aList->Next(), i++ )
+ {
+ pDoc->AddPrintRange( nTab, *pR );
+ }
+ }
+ }
+ }
+
+ // repeat columns
+
+ if ( pRepCol )
+ {
+ if ( !pRepCol->Len() )
+ pDoc->SetRepeatColRange( nTab, NULL );
+ else
+ if ( aRange.ParseAny( *pRepCol, pDoc, aDetails ) & SCA_VALID )
+ pDoc->SetRepeatColRange( nTab, &aRange );
+ }
+
+ // repeat rows
+
+ if ( pRepRow )
+ {
+ if ( !pRepRow->Len() )
+ pDoc->SetRepeatRowRange( nTab, NULL );
+ else
+ if ( aRange.ParseAny( *pRepRow, pDoc, aDetails ) & SCA_VALID )
+ pDoc->SetRepeatRowRange( nTab, &aRange );
+ }
+ }
+
+ // undo (for all tables)
+ if (bUndo)
+ {
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoPrintRange( pDocSh, nCurTab, pOldRanges, pNewRanges ) );
+ }
+
+ // update page breaks
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (rMark.GetTableSelect(nTab))
+ ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_DELETE_PRINTAREA );
+
+ pDocSh->SetDocumentModified();
+}
+
+//----------------------------------------------------------------------------
+// Zellen zusammenfassen
+
+BOOL ScViewFunc::TestMergeCells() // Vorab-Test (fuer Menue)
+{
+ // simple test: TRUE if there's a selection but no multi selection and not filtered
+
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ ScRange aDummy;
+ return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE;
+ }
+ else
+ return FALSE;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord )
+{
+ // Editable- und Verschachtelungs-Abfrage muss vorneweg sein (auch in DocFunc),
+ // damit dann nicht die Inhalte-QueryBox kommt
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ rMark.MarkToSimple();
+ if (!rMark.IsMarked())
+ {
+ ErrorMessage(STR_NOMULTISELECT);
+ return FALSE;
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ SCCOL nStartCol = aMarkRange.aStart.Col();
+ SCROW nStartRow = aMarkRange.aStart.Row();
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCCOL nEndCol = aMarkRange.aEnd.Col();
+ SCROW nEndRow = aMarkRange.aEnd.Row();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+ if ( nStartCol == nEndCol && nStartRow == nEndRow )
+ {
+ // nichts zu tun
+ return TRUE;
+ }
+
+ if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ { // "Zusammenfassen nicht verschachteln !"
+ ErrorMessage(STR_MSSG_MERGECELLS_0);
+ return FALSE;
+ }
+
+ BOOL bOk = TRUE;
+
+ if ( !pDoc->IsBlockEmpty( nStartTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
+ !pDoc->IsBlockEmpty( nStartTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) )
+ {
+ if (!bApi)
+ {
+ MessBox aBox( GetViewData()->GetDialogParent(),
+ WinBits(WB_YES_NO_CANCEL | WB_DEF_NO),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
+ ScGlobal::GetRscString( STR_MERGE_NOTEMPTY ) );
+ USHORT nRetVal = aBox.Execute();
+
+ if ( nRetVal == RET_YES )
+ rDoContents = TRUE;
+ else if ( nRetVal == RET_CANCEL )
+ bOk = FALSE;
+ }
+ }
+
+ if (bOk)
+ {
+ HideCursor();
+ bOk = pDocSh->GetDocFunc().MergeCells( aMarkRange, rDoContents, bRecord, bApi );
+ ShowCursor();
+
+ if (bOk)
+ {
+ SetCursor( nStartCol, nStartRow );
+ //DoneBlockMode( FALSE);
+ Unmark();
+
+ pDocSh->UpdateOle(GetViewData());
+ UpdateInputLine();
+ }
+ }
+
+ return bOk;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::TestRemoveMerge()
+{
+ BOOL bMerged = FALSE;
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
+ bMerged = TRUE;
+ }
+ return bMerged;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::RemoveMerge( BOOL bRecord )
+{
+ ScRange aRange;
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+ else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
+ {
+ ScRange aExtended( aRange );
+ GetViewData()->GetDocument()->ExtendMerge( aExtended );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+
+ HideCursor();
+ BOOL bOk = pDocSh->GetDocFunc().UnmergeCells( aRange, bRecord, FALSE );
+ MarkRange( aExtended );
+ ShowCursor();
+
+ if (bOk)
+ pDocSh->UpdateOle(GetViewData());
+ }
+ return TRUE; //! bOk ??
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillSimple( FillDir eDir, BOOL bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ BOOL bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, FALSE );
+ if (bSuccess)
+ {
+ pDocSh->UpdateOle(GetViewData());
+ UpdateScrollBars();
+ }
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
+ double fStart, double fStep, double fMax, BOOL bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ BOOL bSuccess = pDocSh->GetDocFunc().
+ FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
+ fStart, fStep, fMax, bRecord, FALSE );
+ if (bSuccess)
+ {
+ pDocSh->UpdateOle(GetViewData());
+ UpdateScrollBars();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ aChangeRanges.Append( aRange );
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+ }
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, ULONG nCount, BOOL bRecord )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab );
+ ScRange aSourceRange( aRange );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ BOOL bSuccess = pDocSh->GetDocFunc().
+ FillAuto( aRange, &rMark, eDir, nCount, bRecord, FALSE );
+ if (bSuccess)
+ {
+ MarkRange( aRange, FALSE ); // aRange ist in FillAuto veraendert worden
+ pDocSh->UpdateOle(GetViewData());
+ UpdateScrollBars();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ ScRange aChangeRange( aRange );
+ switch ( eDir )
+ {
+ case FILL_TO_BOTTOM:
+ {
+ aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 );
+ }
+ break;
+ case FILL_TO_TOP:
+ {
+ aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 );
+ }
+ break;
+ case FILL_TO_RIGHT:
+ {
+ aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 );
+ }
+ break;
+ case FILL_TO_LEFT:
+ {
+ aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 );
+ }
+ break;
+ default:
+ {
+
+ }
+ break;
+ }
+ aChangeRanges.Append( aChangeRange );
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillTab( USHORT nFlags, USHORT nFunction, BOOL bSkipEmpty, BOOL bAsLink )
+{
+ //! allow source sheet to be protected
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ ScRange aMarkRange;
+ rMark.MarkToSimple();
+ BOOL bMulti = rMark.IsMultiMarked();
+ if (bMulti)
+ rMark.GetMultiMarkArea( aMarkRange );
+ else if (rMark.IsMarked())
+ rMark.GetMarkArea( aMarkRange );
+ else
+ aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
+
+ ScDocument* pUndoDoc = NULL;
+// if ( bRecord )
+ if (bUndo)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+// pUndoDoc->SelectTable( nTab, TRUE ); // nur fuer Markierung
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nTab && rMark.GetTableSelect(i))
+ {
+ pUndoDoc->AddUndoTab( i, i );
+ aMarkRange.aStart.SetTab( i );
+ aMarkRange.aEnd.SetTab( i );
+ pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc );
+// pUndoDoc->SelectTable( i, TRUE );
+ }
+ }
+
+ if (bMulti)
+ pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
+ else
+ {
+ aMarkRange.aStart.SetTab( nTab );
+ aMarkRange.aEnd.SetTab( nTab );
+ pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
+ }
+
+// if ( bRecord )
+ if (bUndo)
+ { //! fuer ChangeTrack erst zum Schluss
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoFillTable( pDocSh, rMark,
+ aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab,
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab,
+ pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) );
+ }
+
+ pDocSh->PostPaintGridAll();
+ pDocSh->PostDataChanged();
+}
+
+//----------------------------------------------------------------------------
+
+/** Downward fill of selected cell(s) by double-clicking cross-hair cursor
+
+ Extends a current selection down to the last non-empty cell of an adjacent
+ column when the lower-right corner of the selection is double-clicked. It
+ uses a left-adjoining non-empty column as a guide if such is available,
+ otherwise a right-adjoining non-empty column is used.
+
+ @author Kohei Yoshida (kohei@openoffice.org)
+
+ @return No return value
+
+ @see #i12313#
+*/
+void ScViewFunc::FillCrossDblClick()
+{
+ ScRange aRange;
+ GetViewData()->GetSimpleArea( aRange );
+ aRange.Justify();
+
+ SCTAB nTab = GetViewData()->GetCurPos().Tab();
+ SCCOL nStartX = aRange.aStart.Col();
+ SCROW nStartY = aRange.aStart.Row();
+ SCCOL nEndX = aRange.aEnd.Col();
+ SCROW nEndY = aRange.aEnd.Row();
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ // Make sure the selection is not empty
+ if ( pDoc->IsBlockEmpty( nTab, nStartX, nStartY, nEndX, nEndY ) )
+ return;
+
+ if ( nEndY < MAXROW )
+ {
+ if ( nStartX > 0 )
+ {
+ SCCOL nMovX = nStartX - 1;
+ SCROW nMovY = nStartY;
+
+ if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
+ pDoc->HasData( nMovX, nStartY + 1, nTab ) )
+ {
+ pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
+
+ if ( nMovY > nEndY )
+ {
+ FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
+ nMovY - nEndY );
+ return;
+ }
+ }
+ }
+
+ if ( nEndX < MAXCOL )
+ {
+ SCCOL nMovX = nEndX + 1;
+ SCROW nMovY = nStartY;
+
+ if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
+ pDoc->HasData( nMovX, nStartY + 1, nTab ) )
+ {
+ pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
+
+ if ( nMovY > nEndY )
+ {
+ FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
+ nMovY - nEndY );
+ return;
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::TransliterateText( sal_Int32 nType )
+{
+ ScMarkData aFuncMark = GetViewData()->GetMarkData();
+ if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
+ {
+ // no selection -> use cursor position
+
+ ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ aFuncMark.SetMarkArea( ScRange( aCursor ) );
+ }
+
+ BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ TransliterateText( aFuncMark, nType, TRUE, FALSE );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+}
+
+//----------------------------------------------------------------------------
+// AutoFormat
+
+ScAutoFormatData* ScViewFunc::CreateAutoFormatData()
+{
+ ScAutoFormatData* pData = NULL;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ {
+ if ( nEndCol-nStartCol >= 3 && nEndRow-nStartRow >= 3 )
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ pData = new ScAutoFormatData;
+ pDoc->GetAutoFormatData( nStartTab, nStartCol,nStartRow,nEndCol,nEndRow, *pData );
+ }
+ }
+ return pData;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::AutoFormat( USHORT nFormatNo, BOOL bRecord )
+{
+#if 1
+
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ BOOL bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, FALSE );
+ if (bSuccess)
+ pDocSh->UpdateOle(GetViewData());
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+
+#else
+
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ BOOL bSize = (*ScGlobal::GetAutoFormat())[nFormatNo]->GetIncludeWidthHeight();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScDocument* pUndoDoc = NULL;
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bSize, bSize );
+ pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
+ IDF_ATTRIB, FALSE, pUndoDoc );
+ if (bSize)
+ {
+ pDoc->CopyToDocument( nStartCol,0,nStartTab, nEndCol,MAXROW,nEndTab,
+ IDF_NONE, FALSE, pUndoDoc );
+ pDoc->CopyToDocument( 0,nStartRow,nStartTab, MAXCOL,nEndRow,nEndTab,
+ IDF_NONE, FALSE, pUndoDoc );
+ }
+ pDoc->BeginDrawUndo();
+ }
+
+ GetFrameWin()->EnterWait();
+ pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, rMark );
+ GetFrameWin()->LeaveWait();
+
+ if (bSize)
+ {
+ SetMarkedWidthOrHeight( TRUE, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, FALSE, FALSE );
+ SetMarkedWidthOrHeight( FALSE, SC_SIZE_VISOPT, 0, FALSE, FALSE );
+ pDocSh->PostPaint( 0,0,nStartTab, MAXCOL,MAXROW,nStartTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP );
+ }
+ else
+ {
+ BOOL bAdj = AdjustBlockHeight( FALSE );
+ if (bAdj)
+ pDocSh->PostPaint( 0,nStartRow,nStartTab, MAXCOL,MAXROW,nStartTab,
+ PAINT_GRID | PAINT_LEFT );
+ else
+ pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab, PAINT_GRID );
+ }
+
+ if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFormat( pDocSh,
+ ScRange(nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab),
+ pUndoDoc, rMark, bSize, nFormatNo ) );
+ }
+
+ pDocSh->UpdateOle(GetViewData());
+ pDocSh->SetDocumentModified();
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+
+#endif
+}
+
+
+//----------------------------------------------------------------------------
+// Suchen & Ersetzen
+
+void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
+ BOOL bAddUndo, BOOL bIsApi )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if (bAddUndo && !pDoc->IsUndoEnabled())
+ bAddUndo = FALSE;
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+// BOOL bAttrib = pSearchItem->GetPattern();
+ USHORT nCommand = pSearchItem->GetCommand();
+ BOOL bAllTables = pSearchItem->IsAllTables();
+ BOOL* pOldSelectedTables = NULL;
+ USHORT nOldSelectedCount = 0;
+ SCTAB nOldTab = nTab;
+ SCTAB nLastTab = pDoc->GetTableCount() - 1;
+ SCTAB nStartTab, nEndTab;
+ if ( bAllTables )
+ {
+ nStartTab = 0;
+ nEndTab = nLastTab;
+ pOldSelectedTables = new BOOL [ nEndTab + 1 ];
+ for ( SCTAB j = 0; j <= nEndTab; j++ )
+ {
+ pOldSelectedTables[j] = rMark.GetTableSelect( j );
+ if ( pOldSelectedTables[j] )
+ ++nOldSelectedCount;
+ }
+ }
+ else
+ { //! mindestens eine ist immer selektiert
+ nStartTab = nEndTab = rMark.GetFirstSelected();
+ for ( SCTAB j = nStartTab + 1; j <= nLastTab; j++ )
+ {
+ if ( rMark.GetTableSelect( j ) )
+ nEndTab = j;
+ }
+ }
+
+ if ( nCommand == SVX_SEARCHCMD_REPLACE
+ || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ if ( (bAllTables || rMark.GetTableSelect( j )) &&
+ pDoc->IsTabProtected( j ) )
+ {
+ if ( pOldSelectedTables )
+ delete [] pOldSelectedTables;
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+ }
+ }
+
+ if ( nCommand == SVX_SEARCHCMD_FIND
+ || nCommand == SVX_SEARCHCMD_FIND_ALL)
+ bAddUndo = FALSE;
+
+ //! bAttrib bei Undo beruecksichtigen !!!
+
+ ScDocument* pUndoDoc = NULL;
+ ScMarkData* pUndoMark = NULL;
+ String aUndoStr;
+ if (bAddUndo)
+ {
+ pUndoMark = new ScMarkData( rMark ); // Markierung wird veraendert
+ if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
+ }
+ }
+
+ if ( bAllTables )
+ { //! alles selektieren, erst nachdem pUndoMark erzeugt wurde
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ rMark.SelectTable( j, TRUE );
+ }
+ }
+
+ DoneBlockMode(TRUE); // Markierung nicht loeschen!
+ InitOwnBlockMode();
+
+ // wenn vom Anfang an gesucht wird, nicht nochmal fragen ob vom Anfang gesucht werden soll
+ BOOL bFirst = TRUE;
+ if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() )
+ bFirst = FALSE;
+
+ BOOL bFound = FALSE;
+ while (TRUE)
+ {
+ GetFrameWin()->EnterWait();
+ if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) )
+ {
+ bFound = TRUE;
+ bFirst = TRUE;
+ if (bAddUndo)
+ {
+ GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
+ new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
+ nCol, nRow, nTab,
+ aUndoStr, pUndoDoc, pSearchItem ) );
+ pUndoDoc = NULL;
+ }
+
+ break; // Abbruch while True
+ }
+ else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
+ nCommand == SVX_SEARCHCMD_REPLACE) )
+ {
+ bFirst = FALSE;
+ USHORT nRetVal;
+ GetFrameWin()->LeaveWait();
+ if ( bIsApi )
+ nRetVal = RET_NO;
+ else
+ {
+ // Suchen-Dialog als Parent, wenn vorhanden
+ Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
+ USHORT nStrId;
+ if ( pSearchItem->GetBackward() )
+ {
+ if ( nStartTab == nEndTab )
+ nStrId = STR_MSSG_SEARCHANDREPLACE_1;
+ else
+ nStrId = STR_MSSG_SEARCHANDREPLACE_4;
+ }
+ else
+ {
+ if ( nStartTab == nEndTab )
+ nStrId = STR_MSSG_SEARCHANDREPLACE_2;
+ else
+ nStrId = STR_MSSG_SEARCHANDREPLACE_5;
+ }
+ MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
+ ScGlobal::GetRscString( nStrId ) );
+ nRetVal = aBox.Execute();
+ }
+
+ if ( nRetVal == RET_YES )
+ {
+ ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
+ if (pSearchItem->GetBackward())
+ nTab = nEndTab;
+ else
+ nTab = nStartTab;
+ }
+ else
+ {
+ break; // Abbruch while True
+ }
+ }
+ else // nichts gefunden
+ {
+ if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ pDocSh->PostPaintGridAll(); // Markierung
+ }
+
+ GetFrameWin()->LeaveWait();
+ if (!bIsApi)
+ {
+ // Suchen-Dialog als Parent, wenn vorhanden
+ Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
+ // "nichts gefunden"
+ InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
+ aBox.Execute();
+ }
+
+ break; // Abbruch while True
+ }
+ } // of while TRUE
+
+ if ( pOldSelectedTables )
+ { // urspruenglich selektierte Tabellen wiederherstellen
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ rMark.SelectTable( j, pOldSelectedTables[j] );
+ }
+ if ( bFound )
+ { // durch Fundstelle neu selektierte Tabelle bleibt
+ rMark.SelectTable( nTab, TRUE );
+ // wenn vorher nur eine selektiert war, ist es ein Tausch
+ //! wenn nicht, ist jetzt evtl. eine mehr selektiert
+ if ( nOldSelectedCount == 1 && nTab != nOldTab )
+ rMark.SelectTable( nOldTab, FALSE );
+ }
+ delete [] pOldSelectedTables;
+ }
+
+ MarkDataChanged();
+
+ if ( bFound )
+ {
+ if ( nTab != GetViewData()->GetTabNo() )
+ SetTabNo( nTab );
+
+ // wenn nichts markiert ist, DoneBlockMode, damit von hier aus
+ // direkt per Shift-Cursor markiert werden kann:
+ if (!rMark.IsMarked() && !rMark.IsMultiMarked())
+ DoneBlockMode(TRUE);
+
+ AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
+ SetCursor( nCol, nRow, TRUE );
+
+ if ( nCommand == SVX_SEARCHCMD_REPLACE
+ || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ if ( nCommand == SVX_SEARCHCMD_REPLACE )
+ pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
+ else
+ pDocSh->PostPaintGridAll();
+ pDocSh->SetDocumentModified();
+ }
+ else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
+ pDocSh->PostPaintGridAll(); // Markierung
+ GetFrameWin()->LeaveWait();
+ }
+
+ delete pUndoDoc; // loeschen wenn nicht benutzt
+ delete pUndoMark; // kann immer geloescht werden
+}
+
+
+//----------------------------------------------------------------------------
+// Zielwertsuche
+
+void ScViewFunc::Solve( const ScSolveParam& rParam )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ SCCOL nDestCol = rParam.aRefVariableCell.Col();
+ SCROW nDestRow = rParam.aRefVariableCell.Row();
+ SCTAB nDestTab = rParam.aRefVariableCell.Tab();
+
+ ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ if ( pDoc )
+ {
+ String aTargetValStr;
+ if ( rParam.pStrTargetVal != NULL )
+ aTargetValStr = *(rParam.pStrTargetVal);
+
+ String aMsgStr;
+ String aResStr;
+ double nSolveResult;
+
+ GetFrameWin()->EnterWait();
+
+ BOOL bExact =
+ pDoc->Solver(
+ rParam.aRefFormulaCell.Col(),
+ rParam.aRefFormulaCell.Row(),
+ rParam.aRefFormulaCell.Tab(),
+ nDestCol, nDestRow, nDestTab,
+ aTargetValStr,
+ nSolveResult );
+
+ GetFrameWin()->LeaveWait();
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ ULONG nFormat = 0;
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
+ if ( pPattern )
+ nFormat = pPattern->GetNumberFormat( pFormatter );
+ Color* p;
+ pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );
+
+ if ( bExact )
+ {
+ aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
+ aMsgStr += String( aResStr );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
+ }
+ else
+ {
+ aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_5 );
+ aMsgStr += String( aResStr );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_6 );
+ }
+
+ MessBox aBox( GetViewData()->GetDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_NO),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
+ USHORT nRetVal = aBox.Execute();
+
+ if ( RET_YES == nRetVal )
+ EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
+
+ GetViewData()->GetViewShell()->UpdateInputHandler( TRUE );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Mehrfachoperation
+
+void ScViewFunc::TabOp( const ScTabOpParam& rParam, BOOL bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, FALSE );
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::MakeScenario( const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
+ if (nFlags & SC_SCENARIO_COPYALL)
+ SetTabNo( nNewTab, TRUE ); // SC_SCENARIO_COPYALL -> sichtbar
+ else
+ {
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
+ rBindings.Invalidate( SID_TABLES_COUNT );
+ rBindings.Invalidate( SID_SELECT_SCENARIO );
+ rBindings.Invalidate( FID_TABLE_SHOW );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::ExtendScenario()
+{
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ // Undo: Attribute anwenden
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
+ aPattern.GetItemSet().Put( ScProtectionAttr( TRUE ) );
+ ApplySelectionPattern(aPattern);
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::UseScenario( const String& rName )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ DoneBlockMode();
+ InitOwnBlockMode();
+ pDocSh->UseScenario( nTab, rName );
+}
+
+
+//----------------------------------------------------------------------------
+// Tabelle einfuegen
+
+BOOL ScViewFunc::InsertTable( const String& rName, SCTAB nTab, BOOL bRecord )
+{
+ // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
+ BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ InsertTable( nTab, rName, bRecord, FALSE );
+ if (bSuccess)
+ SetTabNo( nTab, TRUE );
+
+ return bSuccess;
+}
+
+//----------------------------------------------------------------------------
+// Tabellen einfuegen
+
+BOOL ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab,
+ SCTAB nCount, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ SvStrings *pNameList= NULL;
+
+ WaitObject aWait( GetFrameWin() );
+
+ if (bRecord)
+ {
+ pNameList= new SvStrings;
+ pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
+ }
+
+ BOOL bFlag=FALSE;
+
+ String aValTabName;
+ String *pStr;
+
+ for(SCTAB i=0;i<nCount;i++)
+ {
+ if(pNames!=NULL)
+ {
+ pStr=pNames->GetObject(static_cast<USHORT>(i));
+ }
+ else
+ {
+ aValTabName.Erase();
+ pDoc->CreateValidTabName( aValTabName);
+ pStr=&aValTabName;
+ }
+
+ if(pDoc->InsertTab( nTab+i,*pStr))
+ {
+ bFlag=TRUE;
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab+i ) );
+ }
+ else
+ {
+ break;
+ }
+
+ if(pNameList!=NULL)
+ pNameList->Insert(new String(*pStr),pNameList->Count());
+
+ }
+
+ if (bFlag)
+ {
+ if (bRecord)
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTables( pDocSh, nTab, FALSE, pNameList));
+
+ // Views updaten:
+
+ SetTabNo( nTab, TRUE );
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::AppendTable( const String& rName, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ WaitObject aWait( GetFrameWin() );
+
+ if (bRecord)
+ pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
+
+ if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
+ {
+ SCTAB nTab = pDoc->GetTableCount()-1;
+ if (bRecord)
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( pDocSh, nTab, TRUE, rName));
+ GetViewData()->InsertTab( nTab );
+ SetTabNo( nTab, TRUE );
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::DeleteTable( SCTAB nTab, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ BOOL bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, FALSE );
+ if (bSuccess)
+ {
+ SCTAB nNewTab = nTab;
+ if ( nNewTab >= pDoc->GetTableCount() )
+ --nNewTab;
+ SetTabNo( nNewTab, TRUE );
+ }
+ return bSuccess;
+}
+
+BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : FALSE;
+ SCTAB nNewTab = TheTabs[0];
+ int i;
+ WaitObject aWait( GetFrameWin() );
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
+ --nNewTab;
+
+ BOOL bWasLinked = FALSE;
+ ScDocument* pUndoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+// pUndoDoc->InitDrawLayer( pDocSh );
+ SCTAB nCount = pDoc->GetTableCount();
+
+// pUndoDoc->InitUndo( pDoc, 0, nCount-1 ); // incl. Ref.
+
+ String aOldName;
+ for(i=0;i<TheTabs.Count();i++)
+ {
+ SCTAB nTab = TheTabs[sal::static_int_cast<USHORT>(i)];
+ if (i==0)
+ pUndoDoc->InitUndo( pDoc, nTab,nTab, TRUE,TRUE ); // incl. Spalten/Zeilenflags
+ else
+ pUndoDoc->AddUndoTab( nTab,nTab, TRUE,TRUE ); // incl. Spalten/Zeilenflags
+
+ pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,FALSE, pUndoDoc );
+ pDoc->GetName( nTab, aOldName );
+ pUndoDoc->RenameTab( nTab, aOldName, FALSE );
+ if (pDoc->IsLinked(nTab))
+ {
+ bWasLinked = TRUE;
+ pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
+ pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
+ pDoc->GetLinkTab(nTab),
+ pDoc->GetLinkRefreshDelay(nTab) );
+ }
+ if ( pDoc->IsScenario(nTab) )
+ {
+ pUndoDoc->SetScenario( nTab, TRUE );
+ String aComment;
+ Color aColor;
+ USHORT nScenFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
+ pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
+ BOOL bActive = pDoc->IsActiveScenario( nTab );
+ pUndoDoc->SetActiveScenario( nTab, bActive );
+ }
+ pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
+ pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
+ pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
+
+ if ( pDoc->IsTabProtected( nTab ) )
+ pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
+
+ // Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
+ // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
+ }
+
+ pUndoDoc->AddUndoTab( 0, nCount-1 ); // alle Tabs fuer Referenzen
+
+ pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage
+
+ pUndoData = new ScRefUndoData( pDoc );
+ }
+
+ BOOL bDelDone = FALSE;
+
+ for(i=TheTabs.Count()-1;i>=0;i--)
+ {
+ String sCodeName;
+ BOOL bHasCodeName = pDoc->GetCodeName( TheTabs[sal::static_int_cast<USHORT>(i)], sCodeName );
+ if (pDoc->DeleteTab( TheTabs[sal::static_int_cast<USHORT>(i)], pUndoDoc ))
+ {
+ bDelDone = TRUE;
+ if( bVbaEnabled )
+ {
+ if( bHasCodeName )
+ {
+ VBA_DeleteModule( *pDocSh, sCodeName );
+ }
+ }
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[sal::static_int_cast<USHORT>(i)] ) );
+ }
+ }
+ if (bRecord)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
+ pUndoDoc, pUndoData ));
+ }
+
+
+ if (bDelDone)
+ {
+ if ( nNewTab >= pDoc->GetTableCount() )
+ nNewTab = pDoc->GetTableCount() - 1;
+
+ SetTabNo( nNewTab, TRUE );
+
+ if (bWasLinked)
+ {
+ pDocSh->UpdateLinks(); // Link-Manager updaten
+ GetViewData()->GetBindings().Invalidate(SID_LINKS);
+ }
+
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+
+ SfxApplication* pSfxApp = SFX_APP(); // Navigator
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+ }
+ else
+ {
+ delete pUndoDoc;
+ delete pUndoData;
+ }
+ return bDelDone;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
+{
+ // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
+ BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ RenameTable( nTab, rName, TRUE, FALSE );
+ if (bSuccess)
+ {
+ // Der Tabellenname koennte in einer Formel vorkommen...
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+
+//----------------------------------------------------------------------------
+
+bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
+{
+ bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, TRUE, FALSE );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
+{
+ bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, TRUE, FALSE );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::InsertAreaLink( const String& rFile,
+ const String& rFilter, const String& rOptions,
+ const String& rSource, ULONG nRefresh )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCCOL nPosX = GetViewData()->GetCurX();
+ SCROW nPosY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aPos( nPosX, nPosY, nTab );
+
+ pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, FALSE, FALSE );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::InsertTableLink( const String& rFile,
+ const String& rFilter, const String& rOptions,
+ const String& rTabName )
+{
+ String aFilterName = rFilter;
+ String aOpt = rOptions;
+ ScDocumentLoader aLoader( rFile, aFilterName, aOpt );
+ if (!aLoader.IsError())
+ {
+ ScDocShell* pSrcSh = aLoader.GetDocShell();
+ ScDocument* pSrcDoc = pSrcSh->GetDocument();
+ SCTAB nTab = MAXTAB+1;
+ if (!rTabName.Len()) // kein Name angegeben -> erste Tabelle
+ nTab = 0;
+ else
+ {
+ String aTemp;
+ SCTAB nCount = pSrcDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ pSrcDoc->GetName( i, aTemp );
+ if ( aTemp == rTabName )
+ nTab = i;
+ }
+ }
+
+ if ( nTab <= MAXTAB )
+ ImportTables( pSrcSh, 1, &nTab, TRUE,
+ GetViewData()->GetTabNo() );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Tabellen aus anderem Dokument kopieren / linken
+
+void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
+ SCTAB nCount, const SCTAB* pSrcTabs, BOOL bLink,SCTAB nTab )
+{
+ ScDocument* pSrcDoc = pSrcShell->GetDocument();
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ //SCTAB nTab = GetViewData()->GetTabNo();
+
+ BOOL bError = FALSE;
+ BOOL bRefs = FALSE;
+ BOOL bName = FALSE;
+
+ if (pSrcDoc->GetDrawLayer())
+ pDocSh->MakeDrawLayer();
+
+ if (bUndo)
+ pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ SCTAB nInsCount = 0;
+ SCTAB i;
+ for( i=0; i<nCount; i++ )
+ { // #63304# insert sheets first and update all references
+ String aName;
+ pSrcDoc->GetName( pSrcTabs[i], aName );
+ pDoc->CreateValidTabName( aName );
+ if ( !pDoc->InsertTab( nTab+i, aName ) )
+ {
+ bError = TRUE; // total error
+ break; // for
+ }
+ ++nInsCount;
+ }
+ for (i=0; i<nCount && !bError; i++)
+ {
+ SCTAB nSrcTab = pSrcTabs[i];
+ SCTAB nDestTab1=nTab+i;
+ ULONG nErrVal = pDoc->TransferTab( pSrcDoc, nSrcTab, nDestTab1,
+ FALSE ); // no insert
+
+ switch (nErrVal)
+ {
+ case 0: // interner Fehler oder voll Fehler
+ bError = TRUE;
+ break;
+ case 2:
+ bRefs = TRUE;
+ break;
+ case 3:
+ bName = TRUE;
+ break;
+ case 4:
+ bRefs = bName = TRUE;
+ break;
+ }
+
+ // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
+ if ( !bError )
+ pDoc->TransferDrawPage( pSrcDoc, nSrcTab, nDestTab1 );
+
+ if(!bError &&pSrcDoc->IsScenario(nSrcTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+
+ pSrcDoc->GetScenarioData(nSrcTab, aComment,aColor, nFlags);
+ pDoc->SetScenario( nDestTab1,TRUE);
+ pDoc->SetScenarioData( nTab+i,aComment,aColor,nFlags);
+ BOOL bActive = pSrcDoc->IsActiveScenario(nSrcTab );
+ pDoc->SetActiveScenario( nDestTab1, bActive );
+ BOOL bVisible=pSrcDoc->IsVisible(nSrcTab);
+ pDoc->SetVisible(nDestTab1,bVisible );
+
+ }
+ }
+
+ if (bLink)
+ {
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+
+ SfxMedium* pMed = pSrcShell->GetMedium();
+ String aFileName = pMed->GetName();
+ String aFilterName;
+ if (pMed->GetFilter())
+ aFilterName = pMed->GetFilter()->GetFilterName();
+ String aOptions = ScDocumentLoader::GetOptions(*pMed);
+
+ BOOL bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
+
+ ULONG nRefresh = 0;
+ String aTabStr;
+ for (i=0; i<nInsCount; i++)
+ {
+ pSrcDoc->GetName( pSrcTabs[i], aTabStr );
+ pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
+ aFileName, aFilterName, aOptions, aTabStr, nRefresh );
+ }
+
+ if (!bWasThere) // Link pro Quelldokument nur einmal eintragen
+ {
+ ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
+ pLink->SetInCreate( TRUE );
+ pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
+ pLink->Update();
+ pLink->SetInCreate( FALSE );
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_LINKS );
+ }
+ }
+
+
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoImportTab( pDocSh, nTab, nCount, bLink ) );
+ }
+
+ for (i=0; i<nInsCount; i++)
+ GetViewData()->InsertTab(nTab);
+ SetTabNo(nTab,TRUE);
+ pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
+ PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
+
+ SfxApplication* pSfxApp = SFX_APP();
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
+
+ pDocSh->PostPaintExtras();
+ pDocSh->PostPaintGridAll();
+ pDocSh->SetDocumentModified();
+
+ if (bRefs)
+ ErrorMessage(STR_ABSREFLOST);
+ if (bName)
+ ErrorMessage(STR_NAMECONFLICT);
+}
+
+
+//----------------------------------------------------------------------------
+// Tabelle in anderes Dokument verschieben / kopieren
+
+void ScViewFunc::MoveTable( USHORT nDestDocNo, SCTAB nDestTab, BOOL bCopy )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocument* pDestDoc = NULL;
+ ScDocShell* pDestShell = NULL;
+ ScTabViewShell* pDestViewSh = NULL;
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ BOOL bNewDoc = ( nDestDocNo == SC_DOC_NEW );
+ if ( bNewDoc )
+ {
+ nDestTab = 0; // als erstes einfuegen
+
+ // ohne SFX_CALLMODE_RECORD ausfuehren, weil schon im Move-Befehl enthalten:
+
+ String aUrl = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/"));
+ aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); // "scalc"
+ SfxStringItem aItem( SID_FILE_NAME, aUrl );
+ SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
+
+ const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
+ SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
+ if ( pRetItem )
+ {
+ if ( pRetItem->ISA( SfxObjectItem ) )
+ pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() );
+ else if ( pRetItem->ISA( SfxViewFrameItem ) )
+ {
+ SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
+ if (pFrm)
+ pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() );
+ }
+ if (pDestShell)
+ pDestViewSh = pDestShell->GetBestViewShell();
+ }
+ }
+ else
+ pDestShell = ScDocShell::GetShellByNum( nDestDocNo );
+
+ if (!pDestShell)
+ {
+ DBG_ERROR("Dest-Doc nicht gefunden !!!");
+ return;
+ }
+
+ pDestDoc = pDestShell->GetDocument();
+
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ if (pDestDoc != pDoc)
+ {
+ if (bNewDoc)
+ {
+ while (pDestDoc->GetTableCount() > 1)
+ pDestDoc->DeleteTab(0);
+ pDestDoc->RenameTab( 0,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")),
+ FALSE );
+ }
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+ SvShorts TheTabs;
+
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i))
+ {
+ String aTabName;
+ pDoc->GetName( i, aTabName);
+ TheTabs.Insert(i,TheTabs.Count());
+ for(SCTAB j=i+1;j<nTabCount;j++)
+ {
+ if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
+ {
+ pDoc->GetName( j, aTabName);
+ TheTabs.Insert(j,TheTabs.Count());
+ i=j;
+ }
+ else break;
+ }
+ }
+ }
+
+ GetFrameWin()->EnterWait();
+
+ if (pDoc->GetDrawLayer())
+ pDestShell->MakeDrawLayer();
+
+ if (!bNewDoc && bUndo)
+ pDestDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ ULONG nErrVal =1;
+ if(nDestTab==SC_TAB_APPEND)
+ nDestTab=pDestDoc->GetTableCount();
+ SCTAB nDestTab1=nDestTab;
+ for( USHORT j=0; j<TheTabs.Count(); j++, nDestTab1++ )
+ { // #63304# insert sheets first and update all references
+ String aName;
+ pDoc->GetName( TheTabs[j], aName );
+ pDestDoc->CreateValidTabName( aName );
+ if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
+ {
+ nErrVal = 0; // total error
+ break; // for
+ }
+ }
+ if ( nErrVal > 0 )
+ {
+ nDestTab1 = nDestTab;
+ for(USHORT i=0;i<TheTabs.Count();i++)
+ {
+ nErrVal = pDestDoc->TransferTab( pDoc, TheTabs[i], nDestTab1,
+ FALSE ); // no insert
+
+ // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
+ if ( nErrVal > 0 )
+ pDestDoc->TransferDrawPage( pDoc, TheTabs[i], nDestTab1 );
+
+ if(nErrVal>0 && pDoc->IsScenario(TheTabs[i]))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+
+ pDoc->GetScenarioData(TheTabs[i], aComment,aColor, nFlags);
+ pDestDoc->SetScenario(nDestTab1,TRUE);
+ pDestDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
+ BOOL bActive = pDoc->IsActiveScenario(TheTabs[i]);
+ pDestDoc->SetActiveScenario(nDestTab1, bActive );
+
+ BOOL bVisible=pDoc->IsVisible(TheTabs[i]);
+ pDestDoc->SetVisible(nDestTab1,bVisible );
+
+ }
+
+ if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) )
+ pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i]));
+
+ nDestTab1++;
+ }
+ }
+ String sName;
+ if (!bNewDoc && bUndo)
+ {
+ pDestDoc->GetName(nDestTab, sName);
+ pDestShell->GetUndoManager()->AddUndoAction(
+ new ScUndoImportTab( pDestShell, nDestTab,
+ static_cast<SCTAB>(TheTabs.Count()), FALSE));
+
+ }
+ else
+ {
+ pDestShell->GetUndoManager()->Clear();
+ }
+
+ GetFrameWin()->LeaveWait();
+ switch (nErrVal)
+ {
+ case 0: // interner Fehler oder voll Fehler
+ {
+ ErrorMessage(STR_TABINSERT_ERROR);
+ return;
+ }
+ //break;
+ case 2:
+ ErrorMessage(STR_ABSREFLOST);
+ break;
+ case 3:
+ ErrorMessage(STR_NAMECONFLICT);
+ break;
+ case 4:
+ {
+ ErrorMessage(STR_ABSREFLOST);
+ ErrorMessage(STR_NAMECONFLICT);
+ }
+ break;
+ default:
+ break;
+ }
+ //pDestShell->GetUndoManager()->Clear(); //! Undo implementieren !!!
+/*
+ String sName;
+ pDestDoc->GetName(nDestTab, sName);
+ pDestShell->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( pDestShell, nDestTab, TRUE, sName ) );
+*/
+ if (!bCopy)
+ {
+ if(nTabCount!=nTabSelCount)
+ DeleteTables(TheTabs);// incl. Paint & Undo
+ else
+ ErrorMessage(STR_TABREMOVE_ERROR);
+ }
+
+ if (bNewDoc)
+ {
+ // ChartListenerCollection must be updated before DeleteTab
+ if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
+ pDestDoc->UpdateChartListenerCollection();
+
+ pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.Count())); // alte erste Tabelle
+//? pDestDoc->SelectTable(0, TRUE); // neue erste Tabelle selektieren
+ if (pDestViewSh)
+ pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer
+ pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
+ PAINT_GRID | PAINT_TOP | PAINT_LEFT |
+ PAINT_EXTRAS | PAINT_SIZE );
+ // PAINT_SIZE fuer Gliederung
+ }
+ else
+ {
+ pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
+ pDestShell->PostPaintExtras();
+ pDestShell->PostPaintGridAll();
+ }
+
+ TheTabs.Remove(0,TheTabs.Count());
+
+ pDestShell->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ }
+ else // innerhalb des Dokuments
+ {
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+
+ SvShorts TheTabs;
+ SvShorts TheDestTabs;
+ SvStrings TheTabNames;
+ String aDestName;
+ String *pString;
+
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i))
+ {
+ String aTabName;
+ pDoc->GetName( i, aTabName);
+ TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
+
+ for(SCTAB j=i+1;j<nTabCount;j++)
+ {
+ if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
+ {
+ pDoc->GetName( j, aTabName);
+ TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
+ i=j;
+ }
+ else break;
+ }
+
+ }
+ }
+
+ if (bCopy && bUndo)
+ pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ pDoc->GetName( nDestTab, aDestName);
+ SCTAB nDestTab1=nDestTab;
+ SCTAB nMovTab=0;
+ for(int j=0;j<TheTabNames.Count();j++)
+ {
+ nTabCount = pDoc->GetTableCount();
+ pString=TheTabNames[sal::static_int_cast<USHORT>(j)];
+ if(!pDoc->GetTable(*pString,nMovTab))
+ {
+ nMovTab=nTabCount;
+ }
+ if(!pDoc->GetTable(aDestName,nDestTab1))
+ {
+ nDestTab1=nTabCount;
+ }
+ pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, FALSE ); // Undo ist hier
+
+ if(bCopy && pDoc->IsScenario(nMovTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+
+ pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
+ pDoc->SetScenario(nDestTab1,TRUE);
+ pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
+ BOOL bActive = pDoc->IsActiveScenario(nMovTab );
+ pDoc->SetActiveScenario( nDestTab1, bActive );
+ BOOL bVisible=pDoc->IsVisible(nMovTab);
+ pDoc->SetVisible(nDestTab1,bVisible );
+ }
+
+ TheTabs.Insert(nMovTab,TheTabs.Count());
+
+ if(!bCopy)
+ {
+ if(!pDoc->GetTable(*pString,nDestTab1))
+ {
+ nDestTab1=nTabCount;
+ }
+ }
+
+ TheDestTabs.Insert(nDestTab1,TheDestTabs.Count());
+ delete pString;
+ }
+
+ nTab = GetViewData()->GetTabNo();
+
+ if (bUndo)
+ {
+ if (bCopy)
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoCopyTab( pDocShell, TheTabs, TheDestTabs));
+ }
+ else
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoMoveTab( pDocShell, TheTabs, TheDestTabs));
+ }
+ }
+
+ SCTAB nNewTab = nDestTab;
+ if (nNewTab == SC_TAB_APPEND)
+ nNewTab = pDoc->GetTableCount()-1;
+ else if (!bCopy && nTab<nDestTab)
+ nNewTab--;
+
+ SetTabNo( nNewTab, TRUE );
+
+ //#i29848# adjust references to data on the copied sheet
+ if( bCopy )
+ ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::ShowTable( const String& rName )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ BOOL bFound = FALSE;
+ SCTAB nPos = 0;
+ String aTabName;
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ pDoc->GetName( i, aTabName );
+ if ( aTabName == rName )
+ {
+ nPos = i;
+ bFound = TRUE;
+ }
+ }
+
+ if (bFound)
+ {
+ pDoc->SetVisible( nPos, TRUE );
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, TRUE ) );
+ }
+ SetTabNo( nPos, TRUE );
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
+ pDocSh->SetDocumentModified();
+ }
+ else
+ Sound::Beep();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::HideTable( SCTAB nTab )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ SCTAB nVisible = 0;
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ if (pDoc->IsVisible(i))
+ ++nVisible;
+ }
+
+ if (nVisible > 1)
+ {
+ pDoc->SetVisible( nTab, FALSE );
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nTab, FALSE ) );
+ }
+
+ // Views updaten:
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
+
+ SetTabNo( nTab, TRUE );
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
+ pDocSh->SetDocumentModified();
+ }
+ else
+ Sound::Beep();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont )
+{
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ const sal_Unicode* pChar = rStr.GetBuffer();
+ ScTabViewShell* pViewShell = GetViewData()->GetViewShell();
+ SvxFontItem aFontItem( rFont.GetFamily(),
+ rFont.GetName(),
+ rFont.GetStyleName(),
+ rFont.GetPitch(),
+ rFont.GetCharSet(),
+ ATTR_FONT );
+
+ // if string contains WEAK characters, set all fonts
+ BYTE nScript;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( pDoc->HasStringWeakCharacters( rStr ) )
+ nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+ else
+ nScript = pDoc->GetStringScriptType( rStr );
+
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
+ aSetItem.PutItemForScriptType( nScript, aFontItem );
+ ApplyUserItemSet( aSetItem.GetItemSet() );
+
+ while ( *pChar )
+ pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::UpdateLineAttrs( SvxBorderLine& rLine,
+ const SvxBorderLine* pDestLine,
+ const SvxBorderLine* pSrcLine,
+ BOOL bColor )
+{
+ if ( pSrcLine && pDestLine )
+ {
+ if ( bColor )
+ {
+ rLine.SetColor ( pSrcLine->GetColor() );
+ rLine.SetOutWidth ( pDestLine->GetOutWidth() );
+ rLine.SetInWidth ( pDestLine->GetInWidth() );
+ rLine.SetDistance ( pDestLine->GetDistance() );
+ }
+ else
+ {
+ rLine.SetColor ( pDestLine->GetColor() );
+ rLine.SetOutWidth ( pSrcLine->GetOutWidth() );
+ rLine.SetInWidth ( pSrcLine->GetInWidth() );
+ rLine.SetDistance ( pSrcLine->GetDistance() );
+ }
+ }
+}
+
+
+#define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
+ pBoxLine = aBoxItem.Get##LINE(); \
+ if ( pBoxLine ) \
+ { \
+ if ( pLine ) \
+ { \
+ UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \
+ aBoxItem.SetLine( &aLine, BOXLINE ); \
+ } \
+ else \
+ aBoxItem.SetLine( NULL, BOXLINE ); \
+ }
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine,
+ BOOL bColorOnly )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScPatternAttr* pSelAttrs = GetSelectionPattern();
+ const SfxItemSet& rSelItemSet = pSelAttrs->GetItemSet();
+
+ const SfxPoolItem* pBorderAttr = NULL;
+ SfxItemState eItemState = rSelItemSet.GetItemState( ATTR_BORDER, TRUE, &pBorderAttr );
+
+ const SfxPoolItem* pTLBRItem = 0;
+ SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, TRUE, &pTLBRItem );
+
+ const SfxPoolItem* pBLTRItem = 0;
+ SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, TRUE, &pBLTRItem );
+
+ // any of the lines visible?
+ if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
+ {
+ // none of the lines don't care?
+ if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
+ {
+ SfxItemSet* pOldSet = new SfxItemSet(
+ *(pDoc->GetPool()),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+ SfxItemSet* pNewSet = new SfxItemSet(
+ *(pDoc->GetPool()),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+
+ //------------------------------------------------------------
+ const SvxBorderLine* pBoxLine = NULL;
+ SvxBorderLine aLine;
+
+ // hier wird die pBoxLine benutzt:
+
+ if( pBorderAttr )
+ {
+ SvxBoxItem aBoxItem( *(const SvxBoxItem*)pBorderAttr );
+ SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
+
+ SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
+ SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
+ SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
+ SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)
+
+ aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
+ aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
+ aBoxInfoItem.ResetFlags(); // Lines auf Valid setzen
+
+ pOldSet->Put( *pBorderAttr );
+ pNewSet->Put( aBoxItem );
+ pNewSet->Put( aBoxInfoItem );
+ }
+
+ if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() )
+ {
+ SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem );
+ UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly );
+ aTLBRItem.SetLine( &aLine );
+ pOldSet->Put( *pTLBRItem );
+ pNewSet->Put( aTLBRItem );
+ }
+
+ if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() )
+ {
+ SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem );
+ UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly );
+ aBLTRItem.SetLine( &aLine );
+ pOldSet->Put( *pBLTRItem );
+ pNewSet->Put( aBLTRItem );
+ }
+
+ ApplyAttributes( pNewSet, pOldSet );
+
+ delete pOldSet;
+ delete pNewSet;
+ }
+ else // if ( eItemState == SFX_ITEM_DONTCARE )
+ {
+ aFuncMark.MarkToMulti();
+ pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
+ }
+
+ ScRange aMarkRange;
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+ SCCOL nStartCol = aMarkRange.aStart.Col();
+ SCROW nStartRow = aMarkRange.aStart.Row();
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCCOL nEndCol = aMarkRange.aEnd.Col();
+ SCROW nEndRow = aMarkRange.aEnd.Row();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+ pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab,
+ PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ pDocSh->UpdateOle( GetViewData() );
+ pDocSh->SetDocumentModified();
+ }
+}
+
+#undef SET_LINE_ATTRIBUTES
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetConditionalFormat( const ScConditionalFormat& rNew )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ULONG nIndex = pDoc->AddCondFormat(rNew); // dafuer gibt's kein Undo
+ SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex );
+
+ ApplyAttr( aItem ); // mit Paint und Undo...
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetValidation( const ScValidationData& rNew )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ULONG nIndex = pDoc->AddValidationEntry(rNew); // dafuer gibt's kein Undo
+ SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
+
+ ApplyAttr( aItem ); // mit Paint und Undo...
+}
+
+