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.cxx3093
1 files changed, 3093 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..17bf069f274d
--- /dev/null
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -0,0 +1,3093 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// 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 <basic/sbstar.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+
+#include "viewfunc.hxx"
+
+#include "sc.hrc"
+#include "globstr.hrc"
+
+#include "attrib.hxx"
+#include "autoform.hxx"
+#include "cell.hxx" // EnterAutoSum
+#include "cellmergeoption.hxx"
+#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>
+
+#include <boost/scoped_ptr.hpp>
+#include <vector>
+#include <memory>
+
+using namespace com::sun::star;
+using ::rtl::OUStringBuffer;
+using ::rtl::OUString;
+using ::editeng::SvxBorderLine;
+
+using ::std::vector;
+using ::std::auto_ptr;
+
+// helper func defined in docfunc.cxx
+void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName );
+
+// STATIC DATA ---------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::AdjustBlockHeight( sal_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 );
+ }
+
+ sal_Bool bAnyChanged = false;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ SCCOLROW* pOneRange = pRanges;
+ sal_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 = sal_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;
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, sal_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();
+ sal_uInt16 nOldPixel = 0;
+ if (nStartRow == nEndRow)
+ nOldPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+ sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, false );
+
+ if (bChanged && ( nStartRow == nEndRow ))
+ {
+ sal_uInt16 nNewPixel = (sal_uInt16) (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 )
+{
+ sal_uInt16 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;
+}
+
+//----------------------------------------------------------------------------
+
+sal_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; // will become valid via reference for ScAutoSumSum
+
+ sal_Bool bCol = false;
+ sal_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 = sal_True;
+ nSeekRow = nRow - 1;
+ }
+ else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
+ DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
+ {
+ bCol = sal_True;
+ nSeekCol = nCol - 1;
+ }
+ else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
+ bRow = sal_True;
+ else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
+ bCol = sal_True;
+
+ if ( bCol || bRow )
+ {
+ if ( bRow )
+ {
+ nStartRow = nSeekRow; // nSeekRow might be adjusted via reference
+ if ( eSum == ScAutoSumSum )
+ nEndRow = nStartRow; // only sum sums
+ else
+ nEndRow = nRow - 1; // maybe extend data area at bottom
+ }
+ else
+ {
+ nStartCol = nSeekCol; // nSeekCol might be adjusted vie reference
+ if ( eSum == ScAutoSumSum )
+ nEndCol = nStartCol; // only sum sums
+ else
+ nEndCol = nCol - 1; // maybe extend data area to the right
+ }
+ sal_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 sal_True;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr)
+{
+ String aFormula = GetAutoSumFormula( rRangeList, bSubTotal, rAddr );
+ 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, ScAddress(nCol, nInsRow, nTab));
+ 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, ScAddress(nInsCol, nRow, nTab) );
+ 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, const ScAddress& rAddr )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ::boost::scoped_ptr<ScTokenArray> pArray(new ScTokenArray);
+
+ pArray->AddOpCode(bSubTotal ? ocSubTotal : ocSum);
+ pArray->AddOpCode(ocOpen);
+
+ if (bSubTotal)
+ {
+ pArray->AddDouble(9);
+ pArray->AddOpCode(ocSep);
+ }
+
+ if(!rRangeList.empty())
+ {
+ ScRangeList aRangeList = rRangeList;
+ const ScRange* pFirst = aRangeList.front();
+ size_t ListSize = aRangeList.size();
+ for ( size_t i = 0; i < ListSize; ++i )
+ {
+ const ScRange* p = aRangeList[i];
+ if (p != pFirst)
+ pArray->AddOpCode(ocSep);
+ ScComplexRefData aRef;
+ aRef.InitRangeRel(*p, rAddr);
+ pArray->AddDoubleReference(aRef);
+ }
+ }
+
+ pArray->AddOpCode(ocClose);
+
+ ScCompiler aComp(pDoc, rAddr, *pArray);
+ aComp.SetGrammar(pDoc->GetGrammar());
+ OUStringBuffer aBuf;
+ aComp.CreateStringFromTokenArray(aBuf);
+ OUString aFormula = aBuf.makeStringAndClear();
+ aBuf.append(sal_Unicode('='));
+ aBuf.append(aFormula);
+ return aBuf.makeStringAndClear();
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::EnterBlock( const String& rString, const EditTextObject* pData )
+{
+ // test for multi selection
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rMark.IsMultiMarked() )
+ {
+ rMark.MarkToSimple();
+ if ( rMark.IsMultiMarked() )
+ { // "Insert into multi selection not possible"
+ 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;
+ }
+ }
+
+ // Insert via PasteFromClip
+
+ WaitObject aWait( GetFrameWin() );
+
+ ScAddress aPos( nCol, nRow, nTab );
+
+ ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
+ pInsDoc->ResetClip( pDoc, nTab );
+
+ if (aNewStr.GetChar(0) == '=') // Formula ?
+ {
+ // SetString not possible, because in Clipboard-Documents nothing will be compiled!
+ 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) );
+ // insert Block, with 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 )
+ { // set number format if incompatible
+ // MarkData was already MarkToSimple'ed in PasteFromClip
+ 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;
+}
+
+
+//----------------------------------------------------------------------------
+// manual page break
+
+void ScViewFunc::InsertPageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
+ sal_Bool bSetModified )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCursor;
+ if (pPos)
+ aCursor = *pPos;
+ else
+ aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
+
+ sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, false );
+
+ if ( bSuccess && bSetModified )
+ UpdatePageBreakData( true ); // for PageBreak-Mode
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::DeletePageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
+ sal_Bool bSetModified )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCursor;
+ if (pPos)
+ aCursor = *pPos;
+ else
+ aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
+
+ sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, false );
+
+ if ( bSuccess && bSetModified )
+ UpdatePageBreakData( true ); // for PageBreak-Mode
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::RemoveManualBreaks()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+
+ if (bUndo)
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_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( sal_True );
+ pDocSh->SetDocumentModified();
+ pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetPrintZoom(sal_uInt16 nScale, sal_uInt16 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( sal_Bool bEntireSheet, const String* pPrint,
+ const String* pRepCol, const String* pRepRow,
+ sal_Bool bAddPrint )
+{
+ // on all selected tables
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab;
+ sal_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);
+ sal_uInt16 nTCount = pPrint->GetTokenCount(sep);
+ for (sal_uInt16 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 pList( new ScRangeList );
+ rMark.FillRangeListWithMarks( pList, false );
+ for (size_t i = 0, n = pList->size(); i < n; ++i)
+ {
+ ScRange* pR = (*pList)[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();
+}
+
+//----------------------------------------------------------------------------
+// Merge cells
+
+sal_Bool ScViewFunc::TestMergeCells() // pre-test (for menu)
+{
+ // simple test: sal_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;
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::MergeCells( sal_Bool bApi, sal_Bool& rDoContents, sal_Bool bRecord, sal_Bool bCenter )
+{
+ // Editable- and Being-Nested- test must be at the beginning (in DocFunc too),
+ // so that the Contents-QueryBox won't appear
+ 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 )
+ {
+ // nothing to do
+ return true;
+ }
+
+ if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ { // "Don't nest merging !"
+ ErrorMessage(STR_MSSG_MERGECELLS_0);
+ return false;
+ }
+
+ // Check for the contents of all selected tables.
+ bool bAskDialog = false;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScCellMergeOption aMergeOption(nStartCol, nStartRow, nEndCol, nEndRow, bCenter);
+ for (SCTAB i = 0; i < nTabCount; ++i)
+ {
+ if (!rMark.GetTableSelect(i))
+ // this table is not selected.
+ continue;
+
+ aMergeOption.maTabs.insert(i);
+
+ if (!pDoc->IsBlockEmpty(i, nStartCol, nStartRow+1, nStartCol, nEndRow) ||
+ !pDoc->IsBlockEmpty(i, nStartCol+1, nStartRow, nEndCol, nEndRow))
+ bAskDialog = true;
+ }
+
+ sal_Bool bOk = true;
+
+ if (bAskDialog)
+ {
+ 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 ) );
+ sal_uInt16 nRetVal = aBox.Execute();
+
+ if ( nRetVal == RET_YES )
+ rDoContents = sal_True;
+ else if ( nRetVal == RET_CANCEL )
+ bOk = false;
+ }
+ }
+
+ if (bOk)
+ {
+ HideCursor();
+ bOk = pDocSh->GetDocFunc().MergeCells( aMergeOption, rDoContents, bRecord, bApi );
+ ShowCursor();
+
+ if (bOk)
+ {
+ SetCursor( nStartCol, nStartRow );
+ //DoneBlockMode( sal_False);
+ Unmark();
+
+ pDocSh->UpdateOle(GetViewData());
+ UpdateInputLine();
+ }
+ }
+
+ return bOk;
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::TestRemoveMerge()
+{
+ sal_Bool bMerged = false;
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
+ bMerged = sal_True;
+ }
+ return bMerged;
+}
+
+
+//----------------------------------------------------------------------------
+
+static bool lcl_extendMergeRange(ScCellMergeOption& rOption, const ScRange& rRange)
+{
+ bool bExtended = false;
+ if (rOption.mnStartCol > rRange.aStart.Col())
+ {
+ rOption.mnStartCol = rRange.aStart.Col();
+ bExtended = true;
+ }
+ if (rOption.mnStartRow > rRange.aStart.Row())
+ {
+ rOption.mnStartRow = rRange.aStart.Row();
+ bExtended = true;
+ }
+ if (rOption.mnEndCol < rRange.aEnd.Col())
+ {
+ rOption.mnEndCol = rRange.aEnd.Col();
+ bExtended = true;
+ }
+ if (rOption.mnEndRow < rRange.aEnd.Row())
+ {
+ rOption.mnEndRow = rRange.aEnd.Row();
+ bExtended = true;
+ }
+ return bExtended;
+}
+
+sal_Bool ScViewFunc::RemoveMerge( sal_Bool bRecord )
+{
+ ScRange aRange;
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return false;
+ }
+ else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScRange aExtended( aRange );
+ pDoc->ExtendMerge( aExtended );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScCellMergeOption aOption(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row());
+ bool bExtended = false;
+ do
+ {
+ bExtended = false;
+ for (SCTAB i = 0; i < nTabCount; ++i)
+ {
+ if (!rMark.GetTableSelect(i))
+ // This table is not selected.
+ continue;
+
+ aOption.maTabs.insert(i);
+ aExtended.aStart.SetTab(i);
+ aExtended.aEnd.SetTab(i);
+ pDoc->ExtendMerge(aExtended);
+ pDoc->ExtendOverlapped(aExtended);
+
+ // Expand the current range to be inclusive of all merged
+ // areas on all sheets.
+ bExtended = lcl_extendMergeRange(aOption, aExtended);
+ }
+ }
+ while (bExtended);
+
+ HideCursor();
+ sal_Bool bOk = pDocSh->GetDocFunc().UnmergeCells(aOption, bRecord, false );
+ aExtended = aOption.getFirstSingleRange();
+ MarkRange( aExtended );
+ ShowCursor();
+
+ if (bOk)
+ pDocSh->UpdateOle(GetViewData());
+ }
+ return sal_True; //! bOk ??
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillSimple( FillDir eDir, sal_Bool bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ sal_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, sal_Bool bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ sal_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, sal_uLong nCount, sal_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();
+ sal_Bool bSuccess = pDocSh->GetDocFunc().
+ FillAuto( aRange, &rMark, eDir, nCount, bRecord, false );
+ if (bSuccess)
+ {
+ MarkRange( aRange, false ); // aRange was modified in FillAuto
+ 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( sal_uInt16 nFlags, sal_uInt16 nFunction, sal_Bool bSkipEmpty, sal_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();
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+
+ ScRange aMarkRange;
+ rMark.MarkToSimple();
+ sal_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 (bUndo)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+
+ 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 );
+ }
+ }
+
+ 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 (bUndo)
+ { //! for ChangeTrack not until the end
+ 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 ) );
+ }
+
+ sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ TransliterateText( aFuncMark, nType, sal_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( sal_uInt16 nFormatNo, sal_Bool bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ sal_Bool bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, false );
+ if (bSuccess)
+ pDocSh->UpdateOle(GetViewData());
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+
+//----------------------------------------------------------------------------
+// Suchen & Ersetzen
+
+void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
+ sal_Bool bAddUndo, sal_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();
+ sal_uInt16 nCommand = pSearchItem->GetCommand();
+ sal_Bool bAllTables = pSearchItem->IsAllTables();
+ sal_Bool* pOldSelectedTables = NULL;
+ sal_uInt16 nOldSelectedCount = 0;
+ SCTAB nOldTab = nTab;
+ SCTAB nLastTab = pDoc->GetTableCount() - 1;
+ SCTAB nStartTab, nEndTab;
+ if ( bAllTables )
+ {
+ nStartTab = 0;
+ nEndTab = nLastTab;
+ pOldSelectedTables = new sal_Bool [ nEndTab + 1 ];
+ for ( SCTAB j = 0; j <= nEndTab; j++ )
+ {
+ pOldSelectedTables[j] = rMark.GetTableSelect( j );
+ if ( pOldSelectedTables[j] )
+ ++nOldSelectedCount;
+ }
+ }
+ else
+ { //! at least one is always selected
+ 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;
+
+ //! account for bAttrib during Undo !!!
+
+ ScDocument* pUndoDoc = NULL;
+ ScMarkData* pUndoMark = NULL;
+ String aUndoStr;
+ if (bAddUndo)
+ {
+ pUndoMark = new ScMarkData( rMark ); // Mark is being modified
+ if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
+ }
+ }
+
+ if ( bAllTables )
+ { //! select all, after pUndoMark has been created
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ rMark.SelectTable( j, sal_True );
+ }
+ }
+
+ DoneBlockMode(true); // don't delete mark
+ InitOwnBlockMode();
+
+ // If search starts at the beginning don't ask again whether it shall start at the beginning
+ sal_Bool bFirst = true;
+ if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() )
+ bFirst = false;
+
+ sal_Bool bFound = false;
+ while (sal_True)
+ {
+ GetFrameWin()->EnterWait();
+ if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) )
+ {
+ bFound = sal_True;
+ bFirst = sal_True;
+ if (bAddUndo)
+ {
+ GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
+ new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
+ nCol, nRow, nTab,
+ aUndoStr, pUndoDoc, pSearchItem ) );
+ pUndoDoc = NULL;
+ }
+
+ break; // break 'while (TRUE)'
+ }
+ else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
+ nCommand == SVX_SEARCHCMD_REPLACE) )
+ {
+ bFirst = false;
+ sal_uInt16 nRetVal;
+ GetFrameWin()->LeaveWait();
+ if ( bIsApi )
+ nRetVal = RET_NO;
+ else
+ {
+ // search dialog as parent (if available)
+ Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
+ sal_uInt16 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; // break 'while (TRUE)'
+ }
+ }
+ else // nothing found
+ {
+ if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ pDocSh->PostPaintGridAll(); // Mark
+ }
+
+ GetFrameWin()->LeaveWait();
+ if (!bIsApi)
+ {
+ // search dialog as parent if available
+ Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
+ // "nothing found"
+ InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
+ aBox.Execute();
+ }
+
+ break; // break 'while (TRUE)'
+ }
+ } // of while sal_True
+
+ if ( pOldSelectedTables )
+ { // restore originally selected table
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ rMark.SelectTable( j, pOldSelectedTables[j] );
+ }
+ if ( bFound )
+ { // if a table is selected as a "match" it remains (selected)
+ rMark.SelectTable( nTab, true );
+ // It's a swap if only one table was selected before
+ //! otherwise now one table more might be selected
+ if ( nOldSelectedCount == 1 && nTab != nOldTab )
+ rMark.SelectTable( nOldTab, false );
+ }
+ delete [] pOldSelectedTables;
+ }
+
+ MarkDataChanged();
+
+ if ( bFound )
+ {
+ if ( nTab != GetViewData()->GetTabNo() )
+ SetTabNo( nTab );
+
+ // if nothing is marked, DoneBlockMode, then marking can start
+ // directly from this place via Shift-Cursor
+ if (!rMark.IsMarked() && !rMark.IsMultiMarked())
+ DoneBlockMode(sal_True);
+
+ AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
+ SetCursor( nCol, nRow, sal_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(); // mark
+ GetFrameWin()->LeaveWait();
+ }
+
+ delete pUndoDoc; // remove if not used
+ delete pUndoMark; // can always be removed
+}
+
+
+//----------------------------------------------------------------------------
+// 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();
+
+ sal_Bool bExact =
+ pDoc->Solver(
+ rParam.aRefFormulaCell.Col(),
+ rParam.aRefFormulaCell.Row(),
+ rParam.aRefFormulaCell.Tab(),
+ nDestCol, nDestRow, nDestTab,
+ aTargetValStr,
+ nSolveResult );
+
+ GetFrameWin()->LeaveWait();
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ sal_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 );
+ sal_uInt16 nRetVal = aBox.Execute();
+
+ if ( RET_YES == nRetVal )
+ EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
+
+ GetViewData()->GetViewShell()->UpdateInputHandler( sal_True );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// multi operation
+
+void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_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, sal_uInt16 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 -> visible
+ 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: apply attributes
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
+ aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) );
+ ApplySelectionPattern(aPattern);
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::UseScenario( const String& rName )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ DoneBlockMode();
+ InitOwnBlockMode();
+ pDocSh->UseScenario( nTab, rName );
+}
+
+
+//----------------------------------------------------------------------------
+// Insert table
+
+sal_Bool ScViewFunc::InsertTable( const String& rName, SCTAB nTab, sal_Bool bRecord )
+{
+ // Order Tabl/Name is inverted for DocFunc
+ sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ InsertTable( nTab, rName, bRecord, false );
+ if (bSuccess)
+ SetTabNo( nTab, sal_True );
+
+ return bSuccess;
+}
+
+//----------------------------------------------------------------------------
+// Insert tables
+
+sal_Bool ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab,
+ SCTAB nCount, sal_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 creates a SdrUndoNewPage
+ }
+
+ sal_Bool bFlag=false;
+
+ String aValTabName;
+ String *pStr;
+
+ for(SCTAB i=0;i<nCount;i++)
+ {
+ if(pNames!=NULL)
+ {
+ pStr=pNames->GetObject(static_cast<sal_uInt16>(i));
+ }
+ else
+ {
+ aValTabName.Erase();
+ pDoc->CreateValidTabName( aValTabName);
+ pStr=&aValTabName;
+ }
+
+ if(pDoc->InsertTab( nTab+i,*pStr))
+ {
+ bFlag=sal_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));
+
+ // Update views
+
+ SetTabNo( nTab, sal_True );
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ return sal_True;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::AppendTable( const String& rName, sal_Bool bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = false;
+
+ WaitObject aWait( GetFrameWin() );
+
+ if (bRecord)
+ pDoc->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
+
+ if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
+ {
+ SCTAB nTab = pDoc->GetTableCount()-1;
+ if (bRecord)
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( pDocSh, nTab, sal_True, rName));
+ GetViewData()->InsertTab( nTab );
+ SetTabNo( nTab, sal_True );
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ return sal_True;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, false );
+ if (bSuccess)
+ {
+ SCTAB nNewTab = nTab;
+ if ( nNewTab >= pDoc->GetTableCount() )
+ --nNewTab;
+ SetTabNo( nNewTab, sal_True );
+ }
+ return bSuccess;
+}
+
+sal_Bool ScViewFunc::DeleteTables(const vector<SCTAB> &TheTabs, sal_Bool bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : false;
+ SCTAB nNewTab = TheTabs[0];
+ WaitObject aWait( GetFrameWin() );
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = false;
+ if ( bVbaEnabled )
+ bRecord = false;
+
+ while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
+ --nNewTab;
+
+ sal_Bool bWasLinked = false;
+ ScDocument* pUndoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nCount = pDoc->GetTableCount();
+
+ String aOldName;
+ for(unsigned int i=0; i<TheTabs.size(); ++i)
+ {
+ SCTAB nTab = TheTabs[i];
+ if (i==0)
+ pUndoDoc->InitUndo( pDoc, nTab,nTab, true,true ); // incl. column/fow flags
+ else
+ pUndoDoc->AddUndoTab( nTab,nTab, true,true ); // incl. column/fow flags
+
+ 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 = sal_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, sal_True );
+ String aComment;
+ Color aColor;
+ sal_uInt16 nScenFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
+ pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
+ sal_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 is responsible for its Undo !!!
+ // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
+ }
+
+ pUndoDoc->AddUndoTab( 0, nCount-1 ); // all Tabs for references
+
+ pDoc->BeginDrawUndo(); // DeleteTab creates a SdrUndoDelPage
+
+ pUndoData = new ScRefUndoData( pDoc );
+ }
+
+ sal_Bool bDelDone = false;
+
+ for(int i=TheTabs.size()-1; i>=0; --i)
+ {
+ String sCodeName;
+ sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i], sCodeName );
+ if (pDoc->DeleteTab( TheTabs[i], pUndoDoc ))
+ {
+ bDelDone = sal_True;
+ if( bVbaEnabled )
+ {
+ if( bHasCodeName )
+ {
+ VBA_DeleteModule( *pDocSh, sCodeName );
+ }
+ }
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[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, sal_True );
+
+ if (bWasLinked)
+ {
+ pDocSh->UpdateLinks(); // update Link-Manager
+ 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;
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
+{
+ // order Table/Name is inverted for DocFunc
+ sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ RenameTable( nTab, rName, true, false );
+ if (bSuccess)
+ {
+ // the table name might be part of a formula
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+
+//----------------------------------------------------------------------------
+
+bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
+{
+ bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, sal_True, false );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
+{
+ bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, sal_True, false );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::InsertAreaLink( const String& rFile,
+ const String& rFilter, const String& rOptions,
+ const String& rSource, sal_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()) // no name given -> first table
+ 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, sal_True,
+ GetViewData()->GetTabNo() );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Copy/link tables from another document
+
+void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
+ SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab )
+{
+ ScDocument* pSrcDoc = pSrcShell->GetDocument();
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+
+ sal_Bool bError = false;
+ sal_Bool bRefs = false;
+ sal_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++ )
+ { // insert sheets first and update all references
+ String aName;
+ pSrcDoc->GetName( pSrcTabs[i], aName );
+ pDoc->CreateValidTabName( aName );
+ if ( !pDoc->InsertTab( nTab+i, aName ) )
+ {
+ bError = sal_True; // total error
+ break; // for
+ }
+ ++nInsCount;
+ }
+ for (i=0; i<nCount && !bError; i++)
+ {
+ SCTAB nSrcTab = pSrcTabs[i];
+ SCTAB nDestTab1=nTab+i;
+ sal_uLong nErrVal = pDocSh->TransferTab( *pSrcShell, nSrcTab, nDestTab1,
+ false, false ); // no insert
+
+ switch (nErrVal)
+ {
+ case 0: // internal error or full of errors
+ bError = true;
+ break;
+ case 2:
+ bRefs = sal_True;
+ break;
+ case 3:
+ bName = sal_True;
+ break;
+ case 4:
+ bRefs = bName = sal_True;
+ break;
+ }
+
+ }
+
+ 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);
+
+ sal_Bool bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
+
+ sal_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) // Insert link only once per source document
+ {
+ ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
+ pLink->SetInCreate( sal_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,sal_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);
+}
+
+
+//----------------------------------------------------------------------------
+// Move/Copy table to another document
+
+void ScViewFunc::MoveTable( sal_uInt16 nDestDocNo, SCTAB nDestTab, sal_Bool bCopy, const String* pNewTabName )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocument* pDestDoc = NULL;
+ ScDocShell* pDestShell = NULL;
+ ScTabViewShell* pDestViewSh = NULL;
+ sal_Bool bUndo (pDoc->IsUndoEnabled());
+ bool bRename = pNewTabName && pNewTabName->Len();
+
+ sal_Bool bNewDoc = ( nDestDocNo == SC_DOC_NEW );
+ if ( bNewDoc )
+ {
+ nDestTab = 0; // firstly insert
+
+ // execute without SFX_CALLMODE_RECORD, because already contained in move command
+
+ 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)
+ {
+ OSL_FAIL("Dest-Doc nicht gefunden !!!");
+ return;
+ }
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if (bRename && rMark.GetSelectCount() != 1)
+ {
+ // Custom sheet name is provided, but more than one sheet is selected.
+ // We don't support this scenario at the moment.
+ 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 );
+ }
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+ vector<SCTAB> TheTabs;
+
+ for(SCTAB i=0; i<nTabCount; ++i)
+ {
+ if(rMark.GetTableSelect(i))
+ {
+ String aTabName;
+ pDoc->GetName( i, aTabName);
+ TheTabs.push_back(i);
+ for(SCTAB j=i+1;j<nTabCount;j++)
+ {
+ if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
+ {
+ pDoc->GetName( j, aTabName);
+ TheTabs.push_back(j);
+ i=j;
+ }
+ else break;
+ }
+ }
+ }
+
+ GetFrameWin()->EnterWait();
+
+ if (pDoc->GetDrawLayer())
+ pDestShell->MakeDrawLayer();
+
+ if (!bNewDoc && bUndo)
+ pDestDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ sal_uLong nErrVal =1;
+ if(nDestTab==SC_TAB_APPEND)
+ nDestTab=pDestDoc->GetTableCount();
+ SCTAB nDestTab1=nDestTab;
+ for( sal_uInt16 j=0; j<TheTabs.size(); ++j, ++nDestTab1 )
+ { // insert sheets first and update all references
+ String aName;
+ if (bRename)
+ aName = *pNewTabName;
+ else
+ 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(sal_uInt16 i=0; i<TheTabs.size();++i)
+ {
+ nErrVal = pDestShell->TransferTab( *pDocShell, TheTabs[i], static_cast<SCTAB>(nDestTab1), false, false );
+ nDestTab1++;
+ }
+ }
+ String sName;
+ if (!bNewDoc && bUndo)
+ {
+ pDestDoc->GetName(nDestTab, sName);
+ pDestShell->GetUndoManager()->AddUndoAction(
+ new ScUndoImportTab( pDestShell, nDestTab,
+ static_cast<SCTAB>(TheTabs.size()), false));
+
+ }
+ else
+ {
+ pDestShell->GetUndoManager()->Clear();
+ }
+
+ GetFrameWin()->LeaveWait();
+ switch (nErrVal)
+ {
+ case 0: // internal error or full of errors
+ {
+ 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;
+ }
+
+ 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.size())); // old first table
+ 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 for outline
+ }
+ else
+ {
+ pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
+ pDestShell->PostPaintExtras();
+ pDestShell->PostPaintGridAll();
+ }
+
+ TheTabs.clear();
+
+ pDestShell->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ }
+ else
+ {
+ // Move or copy within the same document.
+ SCTAB nTabCount = pDoc->GetTableCount();
+
+ auto_ptr< vector<SCTAB> > pSrcTabs(new vector<SCTAB>);
+ auto_ptr< vector<SCTAB> > pDestTabs(new vector<SCTAB>);
+ auto_ptr< vector<OUString> > pTabNames(new vector<OUString>);
+ auto_ptr< vector<OUString> > pDestNames(NULL);
+ pSrcTabs->reserve(nTabCount);
+ pDestTabs->reserve(nTabCount);
+ pTabNames->reserve(nTabCount);
+ String aDestName;
+
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i))
+ {
+ String aTabName;
+ pDoc->GetName( i, aTabName);
+ pTabNames->push_back(aTabName);
+
+ for(SCTAB j=i+1;j<nTabCount;j++)
+ {
+ if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
+ {
+ pDoc->GetName( j, aTabName);
+ pTabNames->push_back(aTabName);
+ 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 (size_t j = 0, n = pTabNames->size(); j < n; ++j)
+ {
+ nTabCount = pDoc->GetTableCount();
+ const OUString& rStr = (*pTabNames)[j];
+ if(!pDoc->GetTable(rStr,nMovTab))
+ {
+ nMovTab=nTabCount;
+ }
+ if(!pDoc->GetTable(aDestName,nDestTab1))
+ {
+ nDestTab1=nTabCount;
+ }
+ pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, false ); // Undo is here
+
+ if(bCopy && pDoc->IsScenario(nMovTab))
+ {
+ String aComment;
+ Color aColor;
+ sal_uInt16 nFlags;
+
+ pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
+ pDoc->SetScenario(nDestTab1,sal_True);
+ pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
+ sal_Bool bActive = pDoc->IsActiveScenario(nMovTab );
+ pDoc->SetActiveScenario( nDestTab1, bActive );
+ sal_Bool bVisible=pDoc->IsVisible(nMovTab);
+ pDoc->SetVisible(nDestTab1,bVisible );
+ }
+
+ pSrcTabs->push_back(nMovTab);
+
+ if(!bCopy)
+ {
+ if(!pDoc->GetTable(rStr,nDestTab1))
+ {
+ nDestTab1=nTabCount;
+ }
+ }
+
+ pDestTabs->push_back(nDestTab1);
+ }
+
+ // Rename must be done after all sheets have been moved.
+ if (bRename)
+ {
+ pDestNames.reset(new vector<OUString>);
+ size_t n = pDestTabs->size();
+ pDestNames->reserve(n);
+ for (size_t j = 0; j < n; ++j)
+ {
+ SCTAB nRenameTab = (*pDestTabs)[j];
+ String aTabName = *pNewTabName;
+ pDoc->CreateValidTabName( aTabName );
+ pDestNames->push_back(aTabName);
+ pDoc->RenameTab(nRenameTab, aTabName);
+ }
+ }
+ else
+ // No need to keep this around when we are not renaming.
+ pTabNames.reset();
+
+ nTab = GetViewData()->GetTabNo();
+
+ if (bUndo)
+ {
+ if (bCopy)
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoCopyTab(
+ pDocShell, pSrcTabs.release(), pDestTabs.release(), pDestNames.release()));
+ }
+ else
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoMoveTab(
+ pDocShell, pSrcTabs.release(), pDestTabs.release(), pTabNames.release(), pDestNames.release()));
+ }
+ }
+
+ SCTAB nNewTab = nDestTab;
+ if (nNewTab == SC_TAB_APPEND)
+ nNewTab = pDoc->GetTableCount()-1;
+ else if (!bCopy && nTab<nDestTab)
+ nNewTab--;
+
+ SetTabNo( nNewTab, sal_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();
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+ sal_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 = sal_True;
+ }
+ }
+
+ if (bFound)
+ {
+ pDoc->SetVisible( nPos, sal_True );
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, sal_True ) );
+ }
+ SetTabNo( nPos, sal_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();
+ sal_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 ) );
+ }
+
+ // Update views
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
+
+ SetTabNo( nTab, sal_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
+ sal_uInt8 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,
+ sal_Bool bColor )
+{
+ if ( pSrcLine && pDestLine )
+ {
+ if ( bColor )
+ {
+ rLine.SetColor ( pSrcLine->GetColor() );
+ rLine.SetStyle ( pDestLine->GetStyle() );
+ rLine.SetWidth ( pDestLine->GetWidth() );
+ }
+ else
+ {
+ rLine.SetColor ( pDestLine->GetColor() );
+ rLine.SetStyle ( pSrcLine->GetStyle() );
+ rLine.SetWidth ( pSrcLine->GetWidth() );
+ }
+ }
+}
+
+
+#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,
+ sal_Bool bColorOnly )
+{
+ // Not editable only due to a matrix? Attribute is ok anyhow.
+ sal_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, sal_True, &pBorderAttr );
+
+ const SfxPoolItem* pTLBRItem = 0;
+ SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem );
+
+ const SfxPoolItem* pBLTRItem = 0;
+ SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, sal_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;
+
+ // here pBoxLine is used
+
+ 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(); // set Lines to Valid
+
+ 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();
+ sal_uLong nIndex = pDoc->AddCondFormat(rNew); // for it there is no Undo
+ SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex );
+
+ ApplyAttr( aItem ); // with Paint and Undo...
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetValidation( const ScValidationData& rNew )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ sal_uLong nIndex = pDoc->AddValidationEntry(rNew); // for it there is no Undo
+ SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
+
+ ApplyAttr( aItem ); // with Paint and Undo...
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */