Files
libreoffice/sc/source/ui/view/viewfun2.cxx

3076 lines
99 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2000-09-18 16:07:07 +00:00
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2000-09-18 16:07:07 +00:00
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
2000-09-18 16:07:07 +00:00
*
* OpenOffice.org - a multi-platform office productivity suite
2000-09-18 16:07:07 +00:00
*
* This file is part of OpenOffice.org.
2000-09-18 16:07:07 +00:00
*
* 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.
2000-09-18 16:07:07 +00:00
*
* 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).
2000-09-18 16:07:07 +00:00
*
* 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.
2000-09-18 16:07:07 +00:00
*
************************************************************************/
#include "scitems.hxx"
#include <comphelper/string.hxx>
#include <editeng/eeitem.hxx>
#include <sfx2/app.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/scripttypeitem.hxx>
2009-12-10 23:06:35 +01:00
#include <svl/srchitem.hxx>
2010-01-13 22:25:07 +01:00
#include <sfx2/linkmgr.hxx>
2000-09-18 16:07:07 +00:00
#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 <svx/svdview.hxx>
2000-09-18 16:07:07 +00:00
#include <vcl/msgbox.hxx>
#include <vcl/waitobj.hxx>
#include <basic/sbstar.hxx>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
2000-09-18 16:07:07 +00:00
#include "viewfunc.hxx"
#include "sc.hrc"
#include "globstr.hrc"
#include "attrib.hxx"
#include "autoform.hxx"
#include "cell.hxx" // EnterAutoSum
#include "cellmergeoption.hxx"
2000-09-18 16:07:07 +00:00
#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"
2010-02-23 22:28:33 -05:00
#include "tabbgcolor.hxx"
#include "clipparam.hxx"
#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
2011-08-26 19:33:59 -04:00
void VBA_DeleteModule( ScDocShell& rDocSh, const rtl::OUString& sModuleName );
2000-09-18 16:07:07 +00:00
// STATIC DATA ---------------------------------------------------------------
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData )
2000-09-18 16:07:07 +00:00
{
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)
2000-09-18 16:07:07 +00:00
{
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;
ScMarkData::iterator itr = pMarkData->begin(), itrEnd = pMarkData->end();
for (; itr != itrEnd; ++itr)
{
SCTAB nTab = *itr;
SCCOLROW* pOneRange = pRanges;
sal_Bool bChanged = false;
SCROW nPaintY = 0;
for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
2000-09-18 16:07:07 +00:00
{
SCROW nStartNo = *(pOneRange++);
SCROW nEndNo = *(pOneRange++);
if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
nPPTX, nPPTY, aZoomX, aZoomY, false ))
2000-09-18 16:07:07 +00:00
{
if (!bChanged)
nPaintY = nStartNo;
bAnyChanged = bChanged = sal_True;
2000-09-18 16:07:07 +00:00
}
}
if ( bPaint && bChanged )
pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
PAINT_GRID | PAINT_LEFT );
2000-09-18 16:07:07 +00:00
}
delete[] pRanges;
if ( bPaint && bAnyChanged )
pDocSh->UpdateOle(GetViewData());
return bAnyChanged;
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, sal_Bool bPaint )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
double nPPTX = GetViewData()->GetPPTX();
double nPPTY = GetViewData()->GetPPTY();
Fraction aZoomX = GetViewData()->GetZoomX();
Fraction aZoomY = GetViewData()->GetZoomY();
sal_uInt16 nOldPixel = 0;
2000-09-18 16:07:07 +00:00
if (nStartRow == nEndRow)
nOldPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
2000-09-18 16:07:07 +00:00
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 );
2000-09-18 16:07:07 +00:00
if (bChanged && ( nStartRow == nEndRow ))
{
sal_uInt16 nNewPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
2000-09-18 16:07:07 +00:00
if ( nNewPixel == nOldPixel )
bChanged = false;
2000-09-18 16:07:07 +00:00
}
if ( bPaint && bChanged )
pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
2000-09-18 16:07:07 +00:00
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 )
2000-09-18 16:07:07 +00:00
{
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 )
2000-09-18 16:07:07 +00:00
{
sal_uInt16 nCount = 0;
2000-09-18 16:07:07 +00:00
while (nCount < SC_AUTOSUM_MAXCOUNT)
{
if ( eDir == DIR_TOP )
{
if (nRow > 0)
2000-09-18 16:07:07 +00:00
--nRow;
else
return ScAutoSumNone;
}
else
{
if (nCol > 0)
2000-09-18 16:07:07 +00:00
--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;
}
2000-09-18 16:07:07 +00:00
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
2000-09-18 16:07:07 +00:00
{
ScDocument* pDoc = GetViewData()->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
SCCOL nCol = GetViewData()->GetCurX();
SCROW nRow = GetViewData()->GetCurY();
2000-09-18 16:07:07 +00:00
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
2000-09-18 16:07:07 +00:00
sal_Bool bCol = false;
sal_Bool bRow = false;
2000-09-18 16:07:07 +00:00
ScAutoSum eSum;
if ( nRow != 0
2000-09-18 16:07:07 +00:00
&& ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
DIR_TOP, nExtend /*out*/ )) == ScAutoSumData )
2000-09-18 16:07:07 +00:00
&& ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
2000-09-18 16:07:07 +00:00
)
{
bRow = sal_True;
2000-09-18 16:07:07 +00:00
nSeekRow = nRow - 1;
}
else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
2000-09-18 16:07:07 +00:00
{
bCol = sal_True;
2000-09-18 16:07:07 +00:00
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;
2000-09-18 16:07:07 +00:00
if ( bCol || bRow )
{
if ( bRow )
{
nStartRow = nSeekRow; // nSeekRow might be adjusted via reference
2000-09-18 16:07:07 +00:00
if ( eSum == ScAutoSumSum )
nEndRow = nStartRow; // only sum sums
2000-09-18 16:07:07 +00:00
else
nEndRow = nRow - 1; // maybe extend data area at bottom
2000-09-18 16:07:07 +00:00
}
else
{
nStartCol = nSeekCol; // nSeekCol might be adjusted vie reference
2000-09-18 16:07:07 +00:00
if ( eSum == ScAutoSumSum )
nEndCol = nStartCol; // only sum sums
2000-09-18 16:07:07 +00:00
else
nEndCol = nCol - 1; // maybe extend data area to the right
2000-09-18 16:07:07 +00:00
}
sal_Bool bContinue = false;
2000-09-18 16:07:07 +00:00
do
{
if ( eSum == ScAutoSumData )
{
if ( bRow )
{
while ( nStartRow != 0 && lcl_IsAutoSumData( pDoc, nCol,
nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
2000-09-18 16:07:07 +00:00
--nStartRow;
}
else
{
while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1,
nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum )
2000-09-18 16:07:07 +00:00
--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 )
2000-09-18 16:07:07 +00:00
{
nStartRow = nEndRow;
}
}
else
{
nEndCol = static_cast< SCCOL >( nExtend );
if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true )
2000-09-18 16:07:07 +00:00
{
nStartCol = nEndCol;
}
}
}
} while ( bContinue );
return sal_True;
2000-09-18 16:07:07 +00:00
}
return false;
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
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 )
2000-09-18 16:07:07 +00:00
{
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
2000-09-18 16:07:07 +00:00
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();
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::EnterBlock( const String& rString, const EditTextObject* pData )
{
// test for multi selection
2000-09-18 16:07:07 +00:00
SCCOL nCol = GetViewData()->GetCurX();
SCROW nRow = GetViewData()->GetCurY();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
ScMarkData& rMark = GetViewData()->GetMarkData();
if ( rMark.IsMultiMarked() )
{
rMark.MarkToSimple();
if ( rMark.IsMultiMarked() )
{ // "Insert into multi selection not possible"
2000-09-18 16:07:07 +00:00
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
2000-09-18 16:07:07 +00:00
WaitObject aWait( GetFrameWin() );
ScAddress aPos( nCol, nRow, nTab );
ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
pInsDoc->ResetClip( pDoc, nTab );
if (aNewStr.GetChar(0) == '=') // Formula ?
2000-09-18 16:07:07 +00:00
{
// SetString not possible, because in Clipboard-Documents nothing will be compiled!
2000-09-18 16:07:07 +00:00
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 ) )
2000-09-18 16:07:07 +00:00
{
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
2000-09-18 16:07:07 +00:00
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
2000-09-18 16:07:07 +00:00
void ScViewFunc::InsertPageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
sal_Bool bSetModified )
2000-09-18 16:07:07 +00:00
{
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
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 );
2000-09-18 16:07:07 +00:00
if ( bSuccess && bSetModified )
UpdatePageBreakData( true ); // for PageBreak-Mode
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::DeletePageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
sal_Bool bSetModified )
2000-09-18 16:07:07 +00:00
{
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
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 );
2000-09-18 16:07:07 +00:00
if ( bSuccess && bSetModified )
UpdatePageBreakData( true ); // for PageBreak-Mode
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::RemoveManualBreaks()
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
sal_Bool bUndo(pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
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(
2000-09-18 16:07:07 +00:00
new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
}
2000-09-18 16:07:07 +00:00
pDoc->RemoveManualBreaks(nTab);
pDoc->UpdatePageBreaks(nTab);
UpdatePageBreakData( sal_True );
2000-09-18 16:07:07 +00:00
pDocSh->SetDocumentModified();
pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
}
//----------------------------------------------------------------------------
void ScViewFunc::SetPrintZoom(sal_uInt16 nScale, sal_uInt16 nPages)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
pDocSh->SetPrintZoom( nTab, nScale, nPages );
}
void ScViewFunc::AdjustPrintZoom()
{
ScRange aRange;
if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
2000-09-18 16:07:07 +00:00
GetViewData()->GetMarkData().GetMultiMarkArea( aRange );
GetViewData()->GetDocShell()->AdjustPrintZoom( aRange );
}
//----------------------------------------------------------------------------
void ScViewFunc::SetPrintRanges( sal_Bool bEntireSheet, const String* pPrint,
2000-09-18 16:07:07 +00:00
const String* pRepCol, const String* pRepRow,
sal_Bool bAddPrint )
2000-09-18 16:07:07 +00:00
{
// on all selected tables
2000-09-18 16:07:07 +00:00
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
SCTAB nTab;
sal_Bool bUndo (pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd; ++itr)
{
nTab = *itr;
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 = comphelper::string::getTokenCount(*pPrint, 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 );
}
2000-09-18 16:07:07 +00:00
}
}
else // NULL = use selection (print range is always set), use empty string to delete all ranges
{
if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
2000-09-18 16:07:07 +00:00
{
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);
2000-09-18 16:07:07 +00:00
}
}
}
2000-09-18 16:07:07 +00:00
// repeat columns
2000-09-18 16:07:07 +00:00
if ( pRepCol )
{
if ( !pRepCol->Len() )
pDoc->SetRepeatColRange( nTab, NULL );
else
if ( aRange.ParseAny( *pRepCol, pDoc, aDetails ) & SCA_VALID )
pDoc->SetRepeatColRange( nTab, &aRange );
}
2000-09-18 16:07:07 +00:00
// repeat rows
2000-09-18 16:07:07 +00:00
if ( pRepRow )
{
if ( !pRepRow->Len() )
pDoc->SetRepeatRowRange( nTab, NULL );
else
if ( aRange.ParseAny( *pRepRow, pDoc, aDetails ) & SCA_VALID )
pDoc->SetRepeatRowRange( nTab, &aRange );
}
}
2000-09-18 16:07:07 +00:00
// undo (for all tables)
if (bUndo)
{
SCTAB nCurTab = GetViewData()->GetTabNo();
ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoPrintRange( pDocSh, nCurTab, pOldRanges, pNewRanges ) );
}
2000-09-18 16:07:07 +00:00
// update page breaks
itr = rMark.begin();
for (; itr != itrEnd; ++itr)
ScPrintFunc( pDocSh, pDocSh->GetPrinter(), *itr ).UpdatePages();
2000-09-18 16:07:07 +00:00
2000-09-22 17:57:10 +00:00
SfxBindings& rBindings = GetViewData()->GetBindings();
2000-09-18 16:07:07 +00:00
rBindings.Invalidate( SID_DELETE_PRINTAREA );
pDocSh->SetDocumentModified();
}
//----------------------------------------------------------------------------
// Merge cells
2000-09-18 16:07:07 +00:00
sal_Bool ScViewFunc::TestMergeCells() // pre-test (for menu)
2000-09-18 16:07:07 +00:00
{
// 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;
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::MergeCells( sal_Bool bApi, sal_Bool& rDoContents, sal_Bool bRecord, sal_Bool bCenter )
2000-09-18 16:07:07 +00:00
{
// 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())
2000-09-18 16:07:07 +00:00
{
ErrorMessage(aTester.GetMessageId());
return false;
2000-09-18 16:07:07 +00:00
}
ScMarkData& rMark = GetViewData()->GetMarkData();
rMark.MarkToSimple();
if (!rMark.IsMarked())
{
ErrorMessage(STR_NOMULTISELECT);
return false;
2000-09-18 16:07:07 +00:00
}
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();
2000-09-18 16:07:07 +00:00
if ( nStartCol == nEndCol && nStartRow == nEndRow )
{
// nothing to do
return true;
2000-09-18 16:07:07 +00:00
}
if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
HASATTR_MERGED | HASATTR_OVERLAPPED ) )
{ // "Don't nest merging !"
2000-09-18 16:07:07 +00:00
ErrorMessage(STR_MSSG_MERGECELLS_0);
return false;
2000-09-18 16:07:07 +00:00
}
// Check for the contents of all selected tables.
bool bAskDialog = false;
ScCellMergeOption aMergeOption(nStartCol, nStartRow, nEndCol, nEndRow, bCenter);
ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd; ++itr)
{
SCTAB i = *itr;
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;
2000-09-18 16:07:07 +00:00
if (bAskDialog)
2000-09-18 16:07:07 +00:00
{
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();
2000-09-18 16:07:07 +00:00
if ( nRetVal == RET_YES )
rDoContents = sal_True;
2000-09-18 16:07:07 +00:00
else if ( nRetVal == RET_CANCEL )
bOk = false;
2000-09-18 16:07:07 +00:00
}
}
if (bOk)
{
bOk = pDocSh->GetDocFunc().MergeCells( aMergeOption, rDoContents, bRecord, bApi );
2000-09-18 16:07:07 +00:00
if (bOk)
{
SetCursor( nStartCol, nStartRow );
//DoneBlockMode( sal_False);
2000-09-18 16:07:07 +00:00
Unmark();
pDocSh->UpdateOle(GetViewData());
UpdateInputLine();
}
}
return bOk;
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::TestRemoveMerge()
2000-09-18 16:07:07 +00:00
{
sal_Bool bMerged = false;
2000-09-18 16:07:07 +00:00
ScRange aRange;
if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocument* pDoc = GetViewData()->GetDocument();
if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
bMerged = sal_True;
2000-09-18 16:07:07 +00:00
}
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 )
2000-09-18 16:07:07 +00:00
{
ScRange aRange;
ScEditableTester aTester( this );
if (!aTester.IsEditable())
{
ErrorMessage(aTester.GetMessageId());
return false;
}
else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocument* pDoc = GetViewData()->GetDocument();
ScRange aExtended( aRange );
pDoc->ExtendMerge( aExtended );
2000-09-18 16:07:07 +00:00
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScMarkData& rMark = GetViewData()->GetMarkData();
ScCellMergeOption aOption(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row());
bool bExtended = false;
do
{
bExtended = false;
2011-07-05 13:35:56 +01:00
ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd; ++itr)
{
SCTAB i = *itr;
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);
sal_Bool bOk = pDocSh->GetDocFunc().UnmergeCells(aOption, bRecord );
aExtended = aOption.getFirstSingleRange();
MarkRange( aExtended );
2000-09-18 16:07:07 +00:00
if (bOk)
pDocSh->UpdateOle(GetViewData());
}
return sal_True; //! bOk ??
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::FillSimple( FillDir eDir, bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScRange aRange;
if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScMarkData& rMark = GetViewData()->GetMarkData();
bool bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, false );
2000-09-18 16:07:07 +00:00
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 )
2000-09-18 16:07:07 +00:00
{
ScRange aRange;
if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScMarkData& rMark = GetViewData()->GetMarkData();
sal_Bool bSuccess = pDocSh->GetDocFunc().
2000-09-18 16:07:07 +00:00
FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
fStart, fStep, fMax, bRecord, false );
2000-09-18 16:07:07 +00:00
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 );
}
2000-09-18 16:07:07 +00:00
}
}
else
ErrorMessage(STR_NOMULTISELECT);
}
//----------------------------------------------------------------------------
void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
SCCOL nEndCol, SCROW nEndRow, sal_uLong nCount, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab );
ScRange aSourceRange( aRange );
2000-09-18 16:07:07 +00:00
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScMarkData& rMark = GetViewData()->GetMarkData();
sal_Bool bSuccess = pDocSh->GetDocFunc().
FillAuto( aRange, &rMark, eDir, nCount, bRecord, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
{
MarkRange( aRange, false ); // aRange was modified in FillAuto
2000-09-18 16:07:07 +00:00
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 );
}
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
void ScViewFunc::FillTab( sal_uInt16 nFlags, sal_uInt16 nFunction, sal_Bool bSkipEmpty, sal_Bool bAsLink )
2000-09-18 16:07:07 +00:00
{
//! allow source sheet to be protected
ScEditableTester aTester( this );
if (!aTester.IsEditable())
2000-09-18 16:07:07 +00:00
{
ErrorMessage(aTester.GetMessageId());
2000-09-18 16:07:07 +00:00
return;
}
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
SCTAB nTab = GetViewData()->GetTabNo();
sal_Bool bUndo(pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
ScRange aMarkRange;
rMark.MarkToSimple();
sal_Bool bMulti = rMark.IsMultiMarked();
2000-09-18 16:07:07 +00:00
if (bMulti)
rMark.GetMultiMarkArea( aMarkRange );
else if (rMark.IsMarked())
rMark.GetMarkArea( aMarkRange );
else
aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
ScDocument* pUndoDoc = NULL;
2011-01-16 19:11:44 +01:00
if (bUndo)
2000-09-18 16:07:07 +00:00
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab );
ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd; ++itr)
if (*itr != nTab )
2000-09-18 16:07:07 +00:00
{
SCTAB i = *itr;
2000-09-18 16:07:07 +00:00
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
2000-09-18 16:07:07 +00:00
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();
}
2001-03-26 18:26:30 +00:00
//----------------------------------------------------------------------------
/** 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, SC_MOVE_DOWN );
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, SC_MOVE_DOWN );
if ( nMovY > nEndY )
{
FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
nMovY - nEndY );
return;
}
}
}
}
}
//----------------------------------------------------------------------------
2001-03-26 18:26:30 +00:00
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 );
2001-03-26 18:26:30 +00:00
if (bSuccess)
{
GetViewData()->GetViewShell()->UpdateInputHandler();
}
}
2000-09-18 16:07:07 +00:00
//----------------------------------------------------------------------------
// 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)
2000-09-18 16:07:07 +00:00
{
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 )
2000-09-18 16:07:07 +00:00
{
ScRange aRange;
if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScMarkData& rMark = GetViewData()->GetMarkData();
sal_Bool bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
pDocSh->UpdateOle(GetViewData());
}
else
ErrorMessage(STR_NOMULTISELECT);
}
//----------------------------------------------------------------------------
// Suchen & Ersetzen
void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
sal_Bool bAddUndo, sal_Bool bIsApi )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
if (bAddUndo && !pDoc->IsUndoEnabled())
bAddUndo = false;
2000-09-18 16:07:07 +00:00
SCCOL nCol = GetViewData()->GetCurX();
SCROW nRow = GetViewData()->GetCurY();
SCTAB nTab = GetViewData()->GetTabNo();
sal_uInt16 nCommand = pSearchItem->GetCommand();
bool bAllTables = pSearchItem->IsAllTables();
std::set<SCTAB> aOldSelectedTables;
SCTAB nOldTab = nTab;
SCTAB nLastTab = pDoc->GetTableCount() - 1;
SCTAB nStartTab, nEndTab;
2000-09-18 16:07:07 +00:00
if ( bAllTables )
{
nStartTab = 0;
nEndTab = nLastTab;
std::set<SCTAB> aTmp(rMark.begin(), rMark.end());
aOldSelectedTables.swap(aTmp);
2000-09-18 16:07:07 +00:00
}
else
{ //! at least one is always selected
nStartTab = rMark.GetFirstSelected();
nEndTab = rMark.GetLastSelected();
2000-09-18 16:07:07 +00:00
}
if ( nCommand == SVX_SEARCHCMD_FIND
|| nCommand == SVX_SEARCHCMD_FIND_ALL)
bAddUndo = false;
2000-09-18 16:07:07 +00:00
//! account for bAttrib during Undo !!!
2000-09-18 16:07:07 +00:00
SAL_WNODEPRECATED_DECLARATIONS_PUSH
2011-09-19 20:19:16 -04:00
std::auto_ptr<ScDocument> pUndoDoc;
std::auto_ptr<ScMarkData> pUndoMark;
SAL_WNODEPRECATED_DECLARATIONS_POP
rtl::OUString aUndoStr;
2000-09-18 16:07:07 +00:00
if (bAddUndo)
{
2011-09-19 20:19:16 -04:00
pUndoMark.reset(new ScMarkData(rMark)); // Mark is being modified
2000-09-18 16:07:07 +00:00
if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
{
2011-09-19 20:19:16 -04:00
pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
2000-09-18 16:07:07 +00:00
pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
}
}
if ( bAllTables )
{ //! select all, after pUndoMark has been created
for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
2000-09-18 16:07:07 +00:00
{
2011-09-19 20:19:16 -04:00
rMark.SelectTable( j, true );
2000-09-18 16:07:07 +00:00
}
}
DoneBlockMode(true); // don't delete mark
2000-09-18 16:07:07 +00:00
InitOwnBlockMode();
// If search starts at the beginning don't ask again whether it shall start at the beginning
2011-09-19 20:19:16 -04:00
bool bFirst = true;
2000-09-18 16:07:07 +00:00
if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() )
bFirst = false;
2000-09-18 16:07:07 +00:00
bool bFound = false;
while (true)
2000-09-18 16:07:07 +00:00
{
GetFrameWin()->EnterWait();
ScRangeList aMatchedRanges;
2011-09-19 20:19:16 -04:00
if (pDoc->SearchAndReplace(*pSearchItem, nCol, nRow, nTab, rMark, aMatchedRanges, aUndoStr, pUndoDoc.get()))
2000-09-18 16:07:07 +00:00
{
2011-09-19 20:19:16 -04:00
bFound = true;
bFirst = true;
2000-09-18 16:07:07 +00:00
if (bAddUndo)
{
GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
nCol, nRow, nTab,
2011-09-19 20:19:16 -04:00
aUndoStr, pUndoDoc.release(), pSearchItem ) );
2000-09-18 16:07:07 +00:00
}
rMark.ResetMark();
for (size_t i = 0, n = aMatchedRanges.size(); i < n; ++i)
{
const ScRange& r = *aMatchedRanges[i];
if (r.aStart.Tab() == nTab)
rMark.SetMultiMarkArea(r);
}
break; // break 'while (TRUE)'
2000-09-18 16:07:07 +00:00
}
else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
nCommand == SVX_SEARCHCMD_REPLACE) )
{
bFirst = false;
sal_uInt16 nRetVal;
2000-09-18 16:07:07 +00:00
GetFrameWin()->LeaveWait();
if ( bIsApi )
nRetVal = RET_NO;
else
{
// search dialog as parent (if available)
2000-09-18 16:07:07 +00:00
Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
sal_uInt16 nStrId;
2000-09-18 16:07:07 +00:00
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)'
2000-09-18 16:07:07 +00:00
}
}
else // nothing found
2000-09-18 16:07:07 +00:00
{
if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
{
pDocSh->PostPaintGridAll(); // Mark
2000-09-18 16:07:07 +00:00
}
GetFrameWin()->LeaveWait();
if (!bIsApi)
{
// search dialog as parent if available
2000-09-18 16:07:07 +00:00
Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
// "nothing found"
2000-09-18 16:07:07 +00:00
InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
aBox.Execute();
}
break; // break 'while (TRUE)'
2000-09-18 16:07:07 +00:00
}
2011-09-19 20:53:18 -04:00
} // of while true
2000-09-18 16:07:07 +00:00
if (!aOldSelectedTables.empty())
{
// restore originally selected table
for (SCTAB i = 0; i <= nEndTab; ++i)
rMark.SelectTable(i, false);
std::set<SCTAB>::const_iterator itr = aOldSelectedTables.begin(), itrEnd = aOldSelectedTables.end();
for (; itr != itrEnd; ++itr)
rMark.SelectTable(*itr, true);
2000-09-18 16:07:07 +00:00
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 ( aOldSelectedTables.size() == 1 && nTab != nOldTab )
rMark.SelectTable( nOldTab, false );
2000-09-18 16:07:07 +00:00
}
}
MarkDataChanged();
2000-09-18 16:07:07 +00:00
if ( bFound )
{
if ( nTab != GetViewData()->GetTabNo() )
SetTabNo( nTab );
// if nothing is marked, DoneBlockMode, then marking can start
// directly from this place via Shift-Cursor
2000-09-18 16:07:07 +00:00
if (!rMark.IsMarked() && !rMark.IsMultiMarked())
2011-09-19 20:53:18 -04:00
DoneBlockMode(true);
2000-09-18 16:07:07 +00:00
AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
2011-09-19 20:19:16 -04:00
SetCursor( nCol, nRow, true );
2000-09-18 16:07:07 +00:00
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
2000-09-18 16:07:07 +00:00
GetFrameWin()->LeaveWait();
}
}
//----------------------------------------------------------------------------
// 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();
2000-09-18 16:07:07 +00:00
ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
if (!aTester.IsEditable())
2000-09-18 16:07:07 +00:00
{
ErrorMessage(aTester.GetMessageId());
2000-09-18 16:07:07 +00:00
return;
}
if ( pDoc )
{
String aTargetValStr;
if ( rParam.pStrTargetVal != NULL )
aTargetValStr = *(rParam.pStrTargetVal);
String aMsgStr;
String aResStr;
double nSolveResult;
GetFrameWin()->EnterWait();
sal_Bool bExact =
2000-09-18 16:07:07 +00:00
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;
2000-09-18 16:07:07 +00:00
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();
2000-09-18 16:07:07 +00:00
if ( RET_YES == nRetVal )
EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
2000-09-18 16:07:07 +00:00
GetViewData()->GetViewShell()->UpdateInputHandler( sal_True );
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
// multi operation
2000-09-18 16:07:07 +00:00
void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScRange aRange;
if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScMarkData& rMark = GetViewData()->GetMarkData();
pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, false );
2000-09-18 16:07:07 +00:00
}
else
ErrorMessage(STR_NOMULTISELECT);
}
//----------------------------------------------------------------------------
void ScViewFunc::MakeScenario( const String& rName, const String& rComment,
const Color& rColor, sal_uInt16 nFlags )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScMarkData& rMark = GetViewData()->GetMarkData();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
2000-09-18 16:07:07 +00:00
if (nFlags & SC_SCENARIO_COPYALL)
SetTabNo( nNewTab, true ); // SC_SCENARIO_COPYALL -> visible
2000-09-18 16:07:07 +00:00
else
{
2000-09-22 17:57:10 +00:00
SfxBindings& rBindings = GetViewData()->GetBindings();
2000-09-18 16:07:07 +00:00
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())
2000-09-18 16:07:07 +00:00
{
ErrorMessage(aTester.GetMessageId());
2000-09-18 16:07:07 +00:00
return;
}
// Undo: apply attributes
2000-09-18 16:07:07 +00:00
ScDocument* pDoc = GetViewData()->GetDocument();
ScPatternAttr aPattern( pDoc->GetPool() );
aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) );
2000-09-18 16:07:07 +00:00
ApplySelectionPattern(aPattern);
}
//----------------------------------------------------------------------------
void ScViewFunc::UseScenario( const String& rName )
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
DoneBlockMode();
InitOwnBlockMode();
pDocSh->UseScenario( nTab, rName );
}
//----------------------------------------------------------------------------
// Insert table
2000-09-18 16:07:07 +00:00
sal_Bool ScViewFunc::InsertTable( const String& rName, SCTAB nTab, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
// Order Tabl/Name is inverted for DocFunc
sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
InsertTable( nTab, rName, bRecord, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
SetTabNo( nTab, sal_True );
2000-09-18 16:07:07 +00:00
return bSuccess;
}
//----------------------------------------------------------------------------
// Insert tables
2000-09-18 16:07:07 +00:00
sal_Bool ScViewFunc::InsertTables(std::vector<rtl::OUString>& aNames, SCTAB nTab,
SCTAB nCount, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
2001-02-26 13:12:11 +00:00
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = false;
2000-09-18 16:07:07 +00:00
WaitObject aWait( GetFrameWin() );
if (bRecord)
{
pDoc->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
2000-09-18 16:07:07 +00:00
}
bool bFlag=false;
2000-09-18 16:07:07 +00:00
if(aNames.empty())
2000-09-18 16:07:07 +00:00
{
pDoc->CreateValidTabNames(aNames, nCount);
}
if (pDoc->InsertTabs(nTab, aNames, false))
{
pDocSh->Broadcast( ScTablesHint( SC_TABS_INSERTED, nTab, nCount ) );
bFlag = true;
2000-09-18 16:07:07 +00:00
}
if (bFlag)
{
if (bRecord)
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoInsertTables( pDocSh, nTab, aNames));
2000-09-18 16:07:07 +00:00
// Update views
2000-09-18 16:07:07 +00:00
SetTabNo( nTab, true );
2000-09-18 16:07:07 +00:00
pDocSh->PostPaintExtras();
pDocSh->SetDocumentModified();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
return true;
2000-09-18 16:07:07 +00:00
}
else
{
return false;
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::AppendTable( const String& rName, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
2001-02-26 13:12:11 +00:00
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = false;
2000-09-18 16:07:07 +00:00
WaitObject aWait( GetFrameWin() );
if (bRecord)
pDoc->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
2000-09-18 16:07:07 +00:00
if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
{
SCTAB nTab = pDoc->GetTableCount()-1;
2000-09-18 16:07:07 +00:00
if (bRecord)
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoInsertTab( pDocSh, nTab, sal_True, rName));
2000-09-18 16:07:07 +00:00
GetViewData()->InsertTab( nTab );
SetTabNo( nTab, sal_True );
2000-09-18 16:07:07 +00:00
pDocSh->PostPaintExtras();
pDocSh->SetDocumentModified();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
return sal_True;
2000-09-18 16:07:07 +00:00
}
else
{
return false;
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
{
SCTAB nNewTab = nTab;
2000-09-18 16:07:07 +00:00
if ( nNewTab >= pDoc->GetTableCount() )
--nNewTab;
SetTabNo( nNewTab, sal_True );
2000-09-18 16:07:07 +00:00
}
return bSuccess;
}
//only use this method for undo for now, all sheets must be connected
//this method doesn't support undo for now, merge it when it with the other method later
bool ScViewFunc::DeleteTables( const SCTAB nTab, SCTAB nSheets )
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
bool bVbaEnabled = pDoc->IsInVBAMode();
SCTAB nNewTab = nTab;
WaitObject aWait( GetFrameWin() );
while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
--nNewTab;
if (pDoc->DeleteTabs(nTab, nSheets, NULL))
{
if( bVbaEnabled )
{
for (SCTAB aTab = 0; aTab < nSheets; ++aTab)
{
2011-08-26 19:33:59 -04:00
rtl::OUString sCodeName;
bool bHasCodeName = pDoc->GetCodeName( nTab + aTab, sCodeName );
if ( bHasCodeName )
VBA_DeleteModule( *pDocSh, sCodeName );
}
}
pDocSh->Broadcast( ScTablesHint( SC_TABS_DELETED, nTab, nSheets ) );
if ( nNewTab >= pDoc->GetTableCount() )
nNewTab = pDoc->GetTableCount() - 1;
SetTabNo( nNewTab, sal_True );
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 ) );
return true;
}
return false;
}
sal_Bool ScViewFunc::DeleteTables(const vector<SCTAB> &TheTabs, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
sal_Bool bVbaEnabled = pDoc->IsInVBAMode();
SCTAB nNewTab = TheTabs[0];
2000-09-18 16:07:07 +00:00
WaitObject aWait( GetFrameWin() );
2001-02-26 13:12:11 +00:00
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = false;
if ( bVbaEnabled )
bRecord = false;
2000-09-18 16:07:07 +00:00
2000-10-05 09:55:35 +00:00
while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
--nNewTab;
sal_Bool bWasLinked = false;
2000-09-18 16:07:07 +00:00
ScDocument* pUndoDoc = NULL;
ScRefUndoData* pUndoData = NULL;
if (bRecord)
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
SCTAB nCount = pDoc->GetTableCount();
2000-09-18 16:07:07 +00:00
2011-08-26 19:33:59 -04:00
rtl::OUString aOldName;
2011-01-27 13:52:52 +00:00
for(unsigned int i=0; i<TheTabs.size(); ++i)
2000-09-18 16:07:07 +00:00
{
2011-01-27 13:52:52 +00:00
SCTAB nTab = TheTabs[i];
2000-09-18 16:07:07 +00:00
if (i==0)
pUndoDoc->InitUndo( pDoc, nTab,nTab, true,true ); // incl. column/fow flags
2000-09-18 16:07:07 +00:00
else
pUndoDoc->AddUndoTab( nTab,nTab, true,true ); // incl. column/fow flags
2000-09-18 16:07:07 +00:00
pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,false, pUndoDoc );
2000-09-18 16:07:07 +00:00
pDoc->GetName( nTab, aOldName );
pUndoDoc->RenameTab( nTab, aOldName, false );
2000-09-18 16:07:07 +00:00
if (pDoc->IsLinked(nTab))
{
bWasLinked = sal_True;
2000-09-18 16:07:07 +00:00
pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
2001-04-18 11:14:41 +00:00
pDoc->GetLinkTab(nTab),
pDoc->GetLinkRefreshDelay(nTab) );
2000-09-18 16:07:07 +00:00
}
if ( pDoc->IsScenario(nTab) )
{
pUndoDoc->SetScenario( nTab, sal_True );
2011-08-26 19:33:59 -04:00
rtl::OUString aComment;
2000-09-18 16:07:07 +00:00
Color aColor;
sal_uInt16 nScenFlags;
2000-09-18 16:07:07 +00:00
pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
sal_Bool bActive = pDoc->IsActiveScenario( nTab );
2000-09-18 16:07:07 +00:00
pUndoDoc->SetActiveScenario( nTab, bActive );
}
2000-10-05 09:55:35 +00:00
pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
2000-09-18 16:07:07 +00:00
if ( pDoc->IsTabProtected( nTab ) )
CWS-TOOLING: integrate CWS scsheetprotection02 2009-06-18 16:48:14 +0200 kohei r273124 : #i102906# Fix a crasher when loading an xls document with unsupported encrytpion. 2009-06-15 14:02:00 +0200 dr r272982 : #i10000# compiler warnings 2009-04-13 23:06:21 +0200 kohei r270740 : Renamed SetData() to SetDataFromDocument(), in order to resolve name clash with the method of the same name in class Window. This caused a compiler warning on Solaris Intel. 2009-04-13 04:09:59 +0200 kohei r270729 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@270723 (milestone: DEV300:m46) 2009-02-23 16:13:45 +0100 kohei r268361 : added tabprotection.obj to the exception file list. Apparently the older versions of boost::shared_ptr rely on C++ exceptions for its implementation. 2009-02-18 19:59:05 +0100 kohei r268253 : Switched to using ::boost::shared_ptr to wrap a pimpl class, because using ::std::auto_ptr in this header breaks the build on win32. The MSVC implementation of ::std::auto_ptr has some weird quirks... 2009-02-17 21:47:13 +0100 kohei r268192 : fixed linkage issue due to library split. 2009-02-17 04:50:34 +0100 kohei r267842 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@267171 (milestone: DEV300:m41) 2009-02-17 02:36:10 +0100 kohei r267841 : reverted the last commit, to re-surrect the removed src files. 2009-02-03 22:02:34 +0100 kohei r267342 : removed the src files to prevent them from being entered into the translation process. The dialogs that need the strings are not yet enabled in the code, so their removal will not cause any harm. 2009-01-14 12:24:29 +0100 dr r266280 : #i10000# wntmsci12 compiler warnings #4 2009-01-14 09:35:46 +0100 dr r266267 : #i10000# wntmsci12 compiler warnings #3 2009-01-13 15:42:07 +0100 dr r266231 : #i10000# wntmsci12 compiler warnings #2 2009-01-13 13:18:28 +0100 dr r266216 : #i10000# wntmsci12 compiler warnings 2009-01-07 03:59:11 +0100 kohei r265943 : remove the fscking compiler warnings. 2009-01-06 15:55:32 +0100 kohei r265925 : removed compiler warnings that caused the buildbot build to fail.... 2009-01-05 23:24:59 +0100 kohei r265888 : Undoing my own local build fix to work around the libmoz... issue. 2008-12-30 21:39:58 +0100 kohei r265833 : Duh! Sheet protection was supposed to be disabled. :-/ 2008-12-23 20:25:55 +0100 kohei r265792 : recovered the code block that was accidentally removed during cws rebase. 2008-12-23 19:03:19 +0100 kohei r265791 : fixed breakage in ods export filter due to rebase to m38. 2008-12-23 16:41:49 +0100 kohei r265787 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@265758 (milestone: DEV300:m38) 2008-12-23 05:37:47 +0100 kohei r265768 : deliberately forget document and sheet passwords when importing from or exporting to excel, to emulate the current behavior. 2008-12-23 05:12:59 +0100 kohei r265767 : removed commented-out unused method ScDocument::SetAutoFilterFlags(). 2008-12-23 05:05:19 +0100 kohei r265766 : removed one duplicate method and made associated changes with the removal, and a little more code cleanup. 2008-12-23 04:24:58 +0100 kohei r265765 : a typo in in-line comment 2008-12-23 04:23:08 +0100 kohei r265764 : remove fprintf statement that blatantly prints out document encryption password to stdout. not a good practice. 2008-12-23 04:14:21 +0100 kohei r265763 : we actually don't want to clear all options, because if we do, then we would no longer be able to select any cells on a protected sheet. 2008-12-23 04:07:10 +0100 kohei r265762 : * minor code cleanup (indentation inconsistencies & use of tab) * fixed unprotecting a sheet with password to make it work again. 2008-12-23 03:22:50 +0100 kohei r265761 : reverted all the new functionalities to the existing ones, while keeping the new code in as much as I could. 2008-12-22 23:11:08 +0100 kohei r265760 : in xls export filter, renamed two unknown records into records of known name. 2008-12-22 22:34:50 +0100 kohei r265759 : temporarily disable password capability on file export for MS Excel 97. 2008-12-22 17:01:21 +0100 kohei r265754 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@264807 (milestone: DEV300:m37) 2008-11-26 03:12:58 +0100 kohei r264335 : recovered a method that was actually used. 2008-11-25 21:51:10 +0100 kohei r264334 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@264325 (milestone: DEV300:m36) 2008-10-08 19:57:35 +0200 kohei r262094 : changed description string to make it less technical. 2008-10-01 05:56:58 +0200 kohei r261986 : migrated from the cvs-based cws. 2008-10-01 05:55:19 +0200 kohei r261985 : migrated from the cvs-based cws. 2008-10-01 05:55:00 +0200 kohei r261984 : migrated from the cvs-based cws.
2009-07-01 08:58:41 +00:00
pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
// Drawing-Layer is responsible for its Undo !!!
2000-09-18 16:07:07 +00:00
// pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
}
pUndoDoc->AddUndoTab( 0, nCount-1 ); // all Tabs for references
2000-09-18 16:07:07 +00:00
pDoc->BeginDrawUndo(); // DeleteTab creates a SdrUndoDelPage
2000-09-18 16:07:07 +00:00
pUndoData = new ScRefUndoData( pDoc );
}
sal_Bool bDelDone = false;
2000-09-18 16:07:07 +00:00
2011-01-27 13:52:52 +00:00
for(int i=TheTabs.size()-1; i>=0; --i)
2000-09-18 16:07:07 +00:00
{
2011-08-26 19:33:59 -04:00
rtl::OUString sCodeName;
sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i], sCodeName );
2011-01-27 13:52:52 +00:00
if (pDoc->DeleteTab( TheTabs[i], pUndoDoc ))
2000-09-18 16:07:07 +00:00
{
bDelDone = sal_True;
if( bVbaEnabled )
{
if( bHasCodeName )
{
VBA_DeleteModule( *pDocSh, sCodeName );
}
}
2011-01-27 13:52:52 +00:00
pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[i] ) );
2000-09-18 16:07:07 +00:00
}
}
if (bRecord)
{
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
pUndoDoc, pUndoData ));
}
2000-10-05 09:55:35 +00:00
if (bDelDone)
2000-09-18 16:07:07 +00:00
{
if ( nNewTab >= pDoc->GetTableCount() )
2000-10-05 09:55:35 +00:00
nNewTab = pDoc->GetTableCount() - 1;
SetTabNo( nNewTab, sal_True );
2000-09-18 16:07:07 +00:00
if (bWasLinked)
{
pDocSh->UpdateLinks(); // update Link-Manager
2000-09-22 17:57:10 +00:00
GetViewData()->GetBindings().Invalidate(SID_LINKS);
2000-09-18 16:07:07 +00:00
}
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 ) );
2000-09-18 16:07:07 +00:00
}
else
{
delete pUndoDoc;
delete pUndoData;
}
2000-10-05 09:55:35 +00:00
return bDelDone;
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
2000-09-18 16:07:07 +00:00
{
// order Table/Name is inverted for DocFunc
sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
RenameTable( nTab, rName, true, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
{
// the table name might be part of a formula
2000-09-18 16:07:07 +00:00
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;
}
2000-09-18 16:07:07 +00:00
//----------------------------------------------------------------------------
void ScViewFunc::InsertAreaLink( const String& rFile,
const String& rFilter, const String& rOptions,
const String& rSource, sal_uLong nRefresh )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
SCCOL nPosX = GetViewData()->GetCurX();
SCROW nPosY = GetViewData()->GetCurY();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
ScAddress aPos( nPosX, nPosY, nTab );
pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, false, false );
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::InsertTableLink( const String& rFile,
const String& rFilter, const String& rOptions,
const String& rTabName )
{
rtl::OUString aFilterName = rFilter;
rtl::OUString aOpt = rOptions;
rtl::OUString aURL = rFile;
ScDocumentLoader aLoader( aURL, aFilterName, aOpt );
2000-09-18 16:07:07 +00:00
if (!aLoader.IsError())
{
ScDocShell* pSrcSh = aLoader.GetDocShell();
ScDocument* pSrcDoc = pSrcSh->GetDocument();
SCTAB nTab = MAXTAB+1;
if (!rTabName.Len()) // no name given -> first table
2000-09-18 16:07:07 +00:00
nTab = 0;
else
{
2011-08-26 19:33:59 -04:00
rtl::OUString aTemp;
SCTAB nCount = pSrcDoc->GetTableCount();
for (SCTAB i=0; i<nCount; i++)
2000-09-18 16:07:07 +00:00
{
pSrcDoc->GetName( i, aTemp );
2011-08-26 19:33:59 -04:00
if ( aTemp.equals(rTabName) )
2000-09-18 16:07:07 +00:00
nTab = i;
}
}
if ( nTab <= MAXTAB )
ImportTables( pSrcSh, 1, &nTab, sal_True,
2000-09-18 16:07:07 +00:00
GetViewData()->GetTabNo() );
}
}
//----------------------------------------------------------------------------
// Copy/link tables from another document
2000-09-18 16:07:07 +00:00
void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab )
2000-09-18 16:07:07 +00:00
{
ScDocument* pSrcDoc = pSrcShell->GetDocument();
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
sal_Bool bUndo(pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
sal_Bool bError = false;
sal_Bool bRefs = false;
sal_Bool bName = false;
2000-09-18 16:07:07 +00:00
if (pSrcDoc->GetDrawLayer())
pDocSh->MakeDrawLayer();
if (bUndo)
pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2000-09-18 16:07:07 +00:00
SCTAB nInsCount = 0;
SCTAB i;
2000-09-18 16:07:07 +00:00
for( i=0; i<nCount; i++ )
{ // insert sheets first and update all references
2011-08-26 19:33:59 -04:00
rtl::OUString aName;
2000-09-18 16:07:07 +00:00
pSrcDoc->GetName( pSrcTabs[i], aName );
pDoc->CreateValidTabName( aName );
if ( !pDoc->InsertTab( nTab+i, aName ) )
{
bError = sal_True; // total error
2000-09-18 16:07:07 +00:00
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
2000-09-18 16:07:07 +00:00
switch (nErrVal)
{
case 0: // internal error or full of errors
bError = true;
2000-09-18 16:07:07 +00:00
break;
case 2:
bRefs = sal_True;
2000-09-18 16:07:07 +00:00
break;
case 3:
bName = sal_True;
2000-09-18 16:07:07 +00:00
break;
case 4:
bRefs = bName = sal_True;
2000-09-18 16:07:07 +00:00
break;
}
}
if (bLink)
{
2010-01-13 22:25:07 +01:00
sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
2000-09-18 16:07:07 +00:00
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 );
2000-09-18 16:07:07 +00:00
sal_uLong nRefresh = 0;
2011-08-26 19:33:59 -04:00
rtl::OUString aTabStr;
2000-09-18 16:07:07 +00:00
for (i=0; i<nInsCount; i++)
{
pSrcDoc->GetName( pSrcTabs[i], aTabStr );
pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
2001-04-18 11:14:41 +00:00
aFileName, aFilterName, aOptions, aTabStr, nRefresh );
2000-09-18 16:07:07 +00:00
}
if (!bWasThere) // Insert link only once per source document
2000-09-18 16:07:07 +00:00
{
2001-04-18 11:14:41 +00:00
ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
pLink->SetInCreate( sal_True );
2000-09-18 16:07:07 +00:00
pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
pLink->Update();
pLink->SetInCreate( false );
2000-09-18 16:07:07 +00:00
2000-09-22 17:57:10 +00:00
SfxBindings& rBindings = GetViewData()->GetBindings();
2000-09-18 16:07:07 +00:00
rBindings.Invalidate( SID_LINKS );
}
}
if (bUndo)
{
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoImportTab( pDocSh, nTab, nCount ) );
}
2000-09-18 16:07:07 +00:00
for (i=0; i<nInsCount; i++)
GetViewData()->InsertTab(nTab);
SetTabNo(nTab,sal_True);
2000-09-18 16:07:07 +00:00
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
2000-09-18 16:07:07 +00:00
2011-08-29 21:48:06 -04:00
void ScViewFunc::MoveTable(
sal_uInt16 nDestDocNo, SCTAB nDestTab, bool bCopy, const rtl::OUString* pNewTabName )
2000-09-18 16:07:07 +00:00
{
ScDocument* pDoc = GetViewData()->GetDocument();
ScDocShell* pDocShell = GetViewData()->GetDocShell();
ScDocument* pDestDoc = NULL;
ScDocShell* pDestShell = NULL;
ScTabViewShell* pDestViewSh = NULL;
sal_Bool bUndo (pDoc->IsUndoEnabled());
2011-08-29 21:48:06 -04:00
bool bRename = pNewTabName && !pNewTabName->isEmpty();
2000-09-18 16:07:07 +00:00
bool bNewDoc = (nDestDocNo == SC_DOC_NEW);
2000-09-18 16:07:07 +00:00
if ( bNewDoc )
{
nDestTab = 0; // firstly insert
2000-09-18 16:07:07 +00:00
// execute without SFX_CALLMODE_RECORD, because already contained in move command
2000-09-18 16:07:07 +00:00
String aUrl = rtl::OUString("private:factory/");
aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); // "scalc"
2000-09-18 16:07:07 +00:00
SfxStringItem aItem( SID_FILE_NAME, aUrl );
SfxStringItem aTarget( SID_TARGETNAME, rtl::OUString("_blank") );
2000-09-18 16:07:07 +00:00
const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
if ( pRetItem )
2000-09-18 16:07:07 +00:00
{
if ( pRetItem->ISA( SfxObjectItem ) )
pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() );
else if ( pRetItem->ISA( SfxViewFrameItem ) )
2000-09-18 16:07:07 +00:00
{
SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
if (pFrm)
pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() );
2000-09-18 16:07:07 +00:00
}
if (pDestShell)
pDestViewSh = pDestShell->GetBestViewShell();
2000-09-18 16:07:07 +00:00
}
}
else
pDestShell = ScDocShell::GetShellByNum( nDestDocNo );
if (!pDestShell)
{
2011-03-01 19:05:02 +01:00
OSL_FAIL("Dest-Doc nicht gefunden !!!");
2000-09-18 16:07:07 +00:00
return;
}
2010-12-13 21:43:04 -05:00
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;
}
2000-09-18 16:07:07 +00:00
pDestDoc = pDestShell->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
if (pDestDoc != pDoc)
{
if (bNewDoc)
{
while (pDestDoc->GetTableCount() > 1)
pDestDoc->DeleteTab(0);
pDestDoc->RenameTab( 0, rtl::OUString("______42_____"),
false );
2000-09-18 16:07:07 +00:00
}
SCTAB nTabCount = pDoc->GetTableCount();
SCTAB nTabSelCount = rMark.GetSelectCount();
2000-09-18 16:07:07 +00:00
2011-01-27 13:52:52 +00:00
vector<SCTAB> TheTabs;
2000-09-18 16:07:07 +00:00
2011-01-27 13:52:52 +00:00
for(SCTAB i=0; i<nTabCount; ++i)
2000-09-18 16:07:07 +00:00
{
if(rMark.GetTableSelect(i))
{
2011-08-26 19:33:59 -04:00
rtl::OUString aTabName;
2000-09-18 16:07:07 +00:00
pDoc->GetName( i, aTabName);
2011-01-27 13:52:52 +00:00
TheTabs.push_back(i);
for(SCTAB j=i+1;j<nTabCount;j++)
2000-09-18 16:07:07 +00:00
{
if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
{
pDoc->GetName( j, aTabName);
2011-01-27 13:52:52 +00:00
TheTabs.push_back(j);
2000-09-18 16:07:07 +00:00
i=j;
}
else break;
}
}
}
GetFrameWin()->EnterWait();
if (pDoc->GetDrawLayer())
pDestShell->MakeDrawLayer();
if (!bNewDoc && bUndo)
2000-09-18 16:07:07 +00:00
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;
ScClipParam aParam;
for( sal_uInt16 j=0; j<TheTabs.size(); ++j, ++nDestTab1 )
{ // insert sheets first and update all references
2011-08-26 19:33:59 -04:00
rtl::OUString aName;
2010-12-13 21:43:04 -05:00
if (bRename)
aName = *pNewTabName;
else
pDoc->GetName( TheTabs[j], aName );
2000-09-18 16:07:07 +00:00
pDestDoc->CreateValidTabName( aName );
if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
{
nErrVal = 0; // total error
break; // for
}
ScRange aRange( 0, 0, TheTabs[j], MAXCOL, MAXROW, TheTabs[j] );
aParam.maRanges.Append(aRange);
2000-09-18 16:07:07 +00:00
}
pDoc->SetClipParam(aParam);
2000-09-18 16:07:07 +00:00
if ( nErrVal > 0 )
{
nDestTab1 = nDestTab;
for(sal_uInt16 i=0; i<TheTabs.size();++i)
2000-09-18 16:07:07 +00:00
{
nErrVal = pDestShell->TransferTab( *pDocShell, TheTabs[i], static_cast<SCTAB>(nDestTab1), false, false );
2000-09-18 16:07:07 +00:00
nDestTab1++;
}
}
2011-08-26 19:33:59 -04:00
rtl::OUString sName;
if (!bNewDoc && bUndo)
2000-09-18 16:07:07 +00:00
{
pDestDoc->GetName(nDestTab, sName);
pDestShell->GetUndoManager()->AddUndoAction(
new ScUndoImportTab( pDestShell, nDestTab,
static_cast<SCTAB>(TheTabs.size())));
2000-09-18 16:07:07 +00:00
}
else
{
pDestShell->GetUndoManager()->Clear();
}
GetFrameWin()->LeaveWait();
switch (nErrVal)
{
case 0: // internal error or full of errors
2000-09-18 16:07:07 +00:00
{
ErrorMessage(STR_TABINSERT_ERROR);
return;
}
//break;
2000-09-18 16:07:07 +00:00
case 2:
ErrorMessage(STR_ABSREFLOST);
break;
case 3:
ErrorMessage(STR_NAMECONFLICT);
break;
case 4:
{
ErrorMessage(STR_ABSREFLOST);
ErrorMessage(STR_NAMECONFLICT);
}
break;
default:
break;
}
2010-12-14 18:13:46 -05:00
2000-09-18 16:07:07 +00:00
if (!bCopy)
{
if(nTabCount!=nTabSelCount)
DeleteTables(TheTabs); // incl. Paint & Undo
2000-09-18 16:07:07 +00:00
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
2000-09-18 16:07:07 +00:00
if (pDestViewSh)
{
// Make sure to clear the cached page view after sheet
// deletion, which still points to the sdr page belonging to
// the deleted sheet.
SdrView* pSdrView = pDestViewSh->GetSdrView();
if (pSdrView)
pSdrView->ClearPageView();
2000-09-18 16:07:07 +00:00
pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer
}
2000-09-18 16:07:07 +00:00
pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
PAINT_GRID | PAINT_TOP | PAINT_LEFT |
PAINT_EXTRAS | PAINT_SIZE );
// PAINT_SIZE for outline
2000-09-18 16:07:07 +00:00
}
else
{
pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
pDestShell->PostPaintExtras();
pDestShell->PostPaintGridAll();
}
2011-01-27 13:52:52 +00:00
TheTabs.clear();
2000-09-18 16:07:07 +00:00
pDestShell->SetDocumentModified();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
}
2010-12-13 21:43:04 -05:00
else
2000-09-18 16:07:07 +00:00
{
2010-12-13 21:43:04 -05:00
// Move or copy within the same document.
SCTAB nTabCount = pDoc->GetTableCount();
2000-09-18 16:07:07 +00:00
SAL_WNODEPRECATED_DECLARATIONS_PUSH
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);
SAL_WNODEPRECATED_DECLARATIONS_POP
pSrcTabs->reserve(nTabCount);
pDestTabs->reserve(nTabCount);
pTabNames->reserve(nTabCount);
2011-08-26 19:33:59 -04:00
rtl::OUString aDestName;
2000-09-18 16:07:07 +00:00
for(SCTAB i=0;i<nTabCount;i++)
2000-09-18 16:07:07 +00:00
{
if(rMark.GetTableSelect(i))
{
2011-08-26 19:33:59 -04:00
rtl::OUString aTabName;
2000-09-18 16:07:07 +00:00
pDoc->GetName( i, aTabName);
pTabNames->push_back(aTabName);
2000-09-18 16:07:07 +00:00
for(SCTAB j=i+1;j<nTabCount;j++)
2000-09-18 16:07:07 +00:00
{
if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
{
pDoc->GetName( j, aTabName);
pTabNames->push_back(aTabName);
2000-09-18 16:07:07 +00:00
i=j;
}
else break;
}
}
}
if (bCopy && bUndo)
2000-09-18 16:07:07 +00:00
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)
2000-09-18 16:07:07 +00:00
{
nTabCount = pDoc->GetTableCount();
const OUString& rStr = (*pTabNames)[j];
if(!pDoc->GetTable(rStr,nMovTab))
2000-09-18 16:07:07 +00:00
{
nMovTab=nTabCount;
}
if(!pDoc->GetTable(aDestName,nDestTab1))
{
nDestTab1=nTabCount;
}
pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, false ); // Undo is here
2000-09-18 16:07:07 +00:00
if(bCopy && pDoc->IsScenario(nMovTab))
{
2011-08-26 19:33:59 -04:00
rtl::OUString aComment;
2000-09-18 16:07:07 +00:00
Color aColor;
sal_uInt16 nFlags;
2000-09-18 16:07:07 +00:00
pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
pDoc->SetScenario(nDestTab1,sal_True);
2000-09-18 16:07:07 +00:00
pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
sal_Bool bActive = pDoc->IsActiveScenario(nMovTab );
2000-09-18 16:07:07 +00:00
pDoc->SetActiveScenario( nDestTab1, bActive );
sal_Bool bVisible=pDoc->IsVisible(nMovTab);
2000-09-18 16:07:07 +00:00
pDoc->SetVisible(nDestTab1,bVisible );
}
pSrcTabs->push_back(nMovTab);
2000-09-18 16:07:07 +00:00
if(!bCopy)
{
if(!pDoc->GetTable(rStr,nDestTab1))
2000-09-18 16:07:07 +00:00
{
nDestTab1=nTabCount;
}
}
pDestTabs->push_back(nDestTab1);
2000-09-18 16:07:07 +00:00
}
// Rename must be done after all sheets have been moved.
2010-12-13 21:43:04 -05:00
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];
rtl::OUString 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();
2000-09-18 16:07:07 +00:00
nTab = GetViewData()->GetTabNo();
if (bUndo)
2000-09-18 16:07:07 +00:00
{
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()));
}
2000-09-18 16:07:07 +00:00
}
SCTAB nNewTab = nDestTab;
2000-09-18 16:07:07 +00:00
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 );
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
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;
2011-08-26 19:33:59 -04:00
rtl::OUString aTabName;
SCTAB nCount = pDoc->GetTableCount();
for (SCTAB i=0; i<nCount; i++)
2000-09-18 16:07:07 +00:00
{
pDoc->GetName( i, aTabName );
2011-08-26 19:33:59 -04:00
if ( aTabName.equals(rName) )
2000-09-18 16:07:07 +00:00
{
nPos = i;
bFound = sal_True;
2000-09-18 16:07:07 +00:00
}
}
if (bFound)
{
pDoc->SetVisible( nPos, sal_True );
if (bUndo)
{
pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, sal_True ) );
}
SetTabNo( nPos, sal_True );
2000-09-18 16:07:07 +00:00
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
pDocSh->SetDocumentModified();
}
}
//----------------------------------------------------------------------------
void ScViewFunc::HideTable( SCTAB nTab )
2000-09-18 16:07:07 +00:00
{
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++)
2000-09-18 16:07:07 +00:00
{
if (pDoc->IsVisible(i))
++nVisible;
}
if (nVisible > 1)
{
pDoc->SetVisible( nTab, false );
if (bUndo)
{
pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nTab, false ) );
}
2000-09-18 16:07:07 +00:00
// Update views
2000-09-18 16:07:07 +00:00
pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
SetTabNo( nTab, sal_True );
2000-09-18 16:07:07 +00:00
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
pDocSh->SetDocumentModified();
}
}
//----------------------------------------------------------------------------
void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont )
{
ScEditableTester aTester( this );
if (!aTester.IsEditable())
2000-09-18 16:07:07 +00:00
{
ErrorMessage(aTester.GetMessageId());
2000-09-18 16:07:07 +00:00
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() );
2000-09-18 16:07:07 +00:00
while ( *pChar )
pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
}
//----------------------------------------------------------------------------
void ScViewFunc::UpdateLineAttrs( SvxBorderLine& rLine,
const SvxBorderLine* pDestLine,
const SvxBorderLine* pSrcLine,
sal_Bool bColor )
2000-09-18 16:07:07 +00:00
{
if ( pSrcLine && pDestLine )
{
if ( bColor )
{
rLine.SetColor ( pSrcLine->GetColor() );
rLine.SetBorderLineStyle(pDestLine->GetBorderLineStyle());
rLine.SetWidth ( pDestLine->GetWidth() );
2000-09-18 16:07:07 +00:00
}
else
{
rLine.SetColor ( pDestLine->GetColor() );
rLine.SetBorderLineStyle(pSrcLine->GetBorderLineStyle());
rLine.SetWidth ( pSrcLine->GetWidth() );
2000-09-18 16:07:07 +00:00
}
}
}
#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 )
2000-09-18 16:07:07 +00:00
{
// Not editable only due to a matrix? Attribute is ok anyhow.
2011-08-25 11:33:20 +02:00
bool bOnlyNotBecauseOfMatrix;
2000-09-18 16:07:07 +00:00
if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
{
ErrorMessage(STR_PROTECTIONERR);
return;
}
ScDocument* pDoc = GetViewData()->GetDocument();
ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
2000-09-18 16:07:07 +00:00
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScPatternAttr* pSelAttrs = GetSelectionPattern();
const SfxItemSet& rSelItemSet = pSelAttrs->GetItemSet();
2000-09-18 16:07:07 +00:00
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 );
2000-09-18 16:07:07 +00:00
// any of the lines visible?
if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
2000-09-18 16:07:07 +00:00
{
// none of the lines don't care?
if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
2000-09-18 16:07:07 +00:00
{
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
2000-09-18 16:07:07 +00:00
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
2000-09-18 16:07:07 +00:00
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 );
}
2000-09-18 16:07:07 +00:00
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 );
}
2000-09-18 16:07:07 +00:00
ApplyAttributes( pNewSet, pOldSet );
delete pOldSet;
delete pNewSet;
}
else // if ( eItemState == SFX_ITEM_DONTCARE )
{
aFuncMark.MarkToMulti();
pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
2000-09-18 16:07:07 +00:00
}
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();
2000-09-18 16:07:07 +00:00
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::SetValidation( const ScValidationData& rNew )
{
ScDocument* pDoc = GetViewData()->GetDocument();
sal_uLong nIndex = pDoc->AddValidationEntry(rNew); // for it there is no Undo
2000-09-18 16:07:07 +00:00
SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
ApplyAttr( aItem ); // with Paint and Undo...
2000-09-18 16:07:07 +00:00
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */