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

3190 lines
102 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
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
2000-09-18 16:07:07 +00:00
// INCLUDE ---------------------------------------------------------------
#include "scitems.hxx"
#include <editeng/eeitem.hxx>
#include <sfx2/app.hxx>
2000-09-18 16:07:07 +00:00
#define _SVSTDARR_STRINGS
#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 <svl/svstdarr.hxx>
2000-09-18 16:07:07 +00:00
#include <vcl/msgbox.hxx>
#include <vcl/sound.hxx>
#include <vcl/waitobj.hxx>
#include <basic/sbstar.hxx>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
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 <basic/sbstar.hxx>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
#include <boost/scoped_ptr.hpp>
#include <vector>
#include <memory>
using namespace com::sun::star;
using ::rtl::OUStringBuffer;
using ::rtl::OUString;
using ::std::vector;
using ::std::auto_ptr;
// helper func defined in docfunc.cxx
void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName );
2000-09-18 16:07:07 +00:00
// STATIC DATA ---------------------------------------------------------------
//----------------------------------------------------------------------------
BOOL ScViewFunc::AdjustBlockHeight( BOOL bPaint, ScMarkData* pMarkData )
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
if (!pMarkData)
pMarkData = &GetViewData()->GetMarkData();
ScDocument* pDoc = pDocSh->GetDocument();
SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges );
if (nRangeCnt == 0)
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 );
}
2000-09-18 16:07:07 +00:00
BOOL bAnyChanged = FALSE;
SCTAB nTabCount = pDoc->GetTableCount();
for (SCTAB nTab=0; nTab<nTabCount; nTab++)
2000-09-18 16:07:07 +00:00
{
if (pMarkData->GetTableSelect(nTab))
{
SCCOLROW* pOneRange = pRanges;
2000-09-18 16:07:07 +00:00
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 = TRUE;
}
}
if ( bPaint && bChanged )
pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
PAINT_GRID | PAINT_LEFT );
}
}
delete[] pRanges;
if ( bPaint && bAnyChanged )
pDocSh->UpdateOle(GetViewData());
return bAnyChanged;
}
//----------------------------------------------------------------------------
BOOL ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, BOOL bPaint )
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();
USHORT nOldPixel = 0;
2000-09-18 16:07:07 +00:00
if (nStartRow == nEndRow)
nOldPixel = (USHORT) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
ScSizeDeviceProvider aProv(pDocSh);
if (aProv.IsPrinter())
{
nPPTX = aProv.GetPPTX();
nPPTY = aProv.GetPPTY();
aZoomX = aZoomY = Fraction( 1, 1 );
}
BOOL bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
nPPTX, nPPTY, aZoomX, aZoomY, FALSE );
2000-09-18 16:07:07 +00:00
if (bChanged && ( nStartRow == nEndRow ))
{
USHORT nNewPixel = (USHORT) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
if ( nNewPixel == nOldPixel )
bChanged = FALSE;
}
if ( bPaint && bChanged )
pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
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
{
USHORT nCount = 0;
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
//----------------------------------------------------------------------------
BOOL ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
{
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; // wird per Reference gueltig bei ScAutoSumSum
2000-09-18 16:07:07 +00:00
BOOL bCol = FALSE;
BOOL bRow = FALSE;
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 = TRUE;
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 = TRUE;
nSeekCol = nCol - 1;
}
else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
2000-09-18 16:07:07 +00:00
bRow = TRUE;
else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
2000-09-18 16:07:07 +00:00
bCol = TRUE;
if ( bCol || bRow )
{
if ( bRow )
{
nStartRow = nSeekRow; // nSeekRow evtl. per Reference angepasst
if ( eSum == ScAutoSumSum )
nEndRow = nStartRow; // nur Summen summieren
else
nEndRow = nRow - 1; // Datenbereich evtl. nach unten erweitern
}
else
{
nStartCol = nSeekCol; // nSeekCol evtl. per Reference angepasst
if ( eSum == ScAutoSumSum )
nEndCol = nStartCol; // nur Summen summieren
else
nEndCol = nCol - 1; // Datenbereich evtl. nach rechts erweitern
}
BOOL bContinue = FALSE;
do
{
if ( eSum == ScAutoSumData )
{
if ( bRow )
{
while ( nStartRow != 0 && lcl_IsAutoSumData( pDoc, nCol,
nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
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 TRUE;
}
return FALSE;
}
//----------------------------------------------------------------------------
void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr)
{
String aFormula = GetAutoSumFormula( rRangeList, bSubTotal, rAddr );
EnterBlock( aFormula, NULL );
}
//----------------------------------------------------------------------------
bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue )
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);
}
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 )
{
// Mehrfachselektion vorher abfragen...
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() )
{ // "Einfuegen auf Mehrfachselektion nicht moeglich"
ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
// insert into single cell
if ( pData )
EnterData( nCol, nRow, nTab, pData );
else
EnterData( nCol, nRow, nTab, rString );
return;
}
}
ScDocument* pDoc = GetViewData()->GetDocument();
String aNewStr = rString;
if ( pData )
{
const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
aEngine.SetText(*pData);
ScEditAttrTester aTester( &aEngine );
if (!aTester.NeedsObject())
{
aNewStr = aEngine.GetText();
pData = NULL;
}
}
// Einfuegen per PasteFromClip
WaitObject aWait( GetFrameWin() );
ScAddress aPos( nCol, nRow, nTab );
ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
pInsDoc->ResetClip( pDoc, nTab );
if (aNewStr.GetChar(0) == '=') // Formel ?
{
// SetString geht nicht, weil in Clipboard-Dokumenten nicht kompiliert wird!
ScFormulaCell* pFCell = new ScFormulaCell( pDoc, aPos, aNewStr );
pInsDoc->PutCell( nCol, nRow, nTab, pFCell );
}
else if ( pData )
pInsDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pData, pDoc, NULL ) );
else
pInsDoc->SetString( nCol, nRow, nTab, aNewStr );
pInsDoc->SetClipArea( ScRange(aPos) );
// auf Block einfuegen, mit Undo etc.
if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, FALSE, FALSE,
FALSE, INS_NONE, IDF_ATTRIB ) )
{
const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr(
nCol, nRow, nTab, ATTR_VALUE_FORMAT );
if ( pItem )
{ // Numberformat setzen wenn inkompatibel
// MarkData wurde bereits in PasteFromClip MarkToSimple'ed
ScRange aRange;
rMark.GetMarkArea( aRange );
ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() );
pPattern->GetItemSet().Put( *pItem );
short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() );
pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark,
*pPattern, nNewType );
delete pPattern;
}
}
delete pInsDoc;
}
//----------------------------------------------------------------------------
// manueller Seitenumbruch
void ScViewFunc::InsertPageBreak( BOOL bColumn, BOOL bRecord, const ScAddress* pPos,
BOOL bSetModified )
{
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 );
BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, FALSE );
if ( bSuccess && bSetModified )
UpdatePageBreakData( TRUE ); // fuer PageBreak-Modus
}
//----------------------------------------------------------------------------
void ScViewFunc::DeletePageBreak( BOOL bColumn, BOOL bRecord, const ScAddress* pPos,
BOOL bSetModified )
{
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
ScAddress aCursor;
if (pPos)
aCursor = *pPos;
else
aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, FALSE );
if ( bSuccess && bSetModified )
UpdatePageBreakData( TRUE ); // fuer PageBreak-Modus
}
//----------------------------------------------------------------------------
void ScViewFunc::RemoveManualBreaks()
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
BOOL bUndo(pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
if (bUndo)
{
ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, FALSE, pUndoDoc );
pDocSh->GetUndoManager()->AddUndoAction(
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( TRUE );
pDocSh->SetDocumentModified();
pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
}
//----------------------------------------------------------------------------
void ScViewFunc::SetPrintZoom(USHORT nScale, USHORT nPages)
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
SCTAB nTab = GetViewData()->GetTabNo();
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( BOOL bEntireSheet, const String* pPrint,
2000-09-18 16:07:07 +00:00
const String* pRepCol, const String* pRepRow,
BOOL bAddPrint )
{
// on all selected tables
2000-09-18 16:07:07 +00:00
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
SCTAB nTabCount = pDoc->GetTableCount();
ScMarkData& rMark = GetViewData()->GetMarkData();
SCTAB nTab;
BOOL bUndo (pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
for (nTab=0; nTab<nTabCount; nTab++)
if (rMark.GetTableSelect(nTab))
2000-09-18 16:07:07 +00:00
{
ScRange aRange( 0,0,nTab );
// print ranges
if( !bAddPrint )
pDoc->ClearPrintRanges( nTab );
if( bEntireSheet )
2000-09-18 16:07:07 +00:00
{
pDoc->SetPrintEntireSheet( nTab );
}
else if ( pPrint )
{
if ( pPrint->Len() )
{
CWS-TOOLING: integrate CWS frmdlg 2008-12-18 09:13:09 +0100 oj r265667 : merge from odff05 2008-12-18 07:58:16 +0100 oj r265658 : #i94555# patch from <regina>, ODFF: Add GAMMA, CHISQDIST, CHISQINV. Make the 'cumulative' parameter of GAMMADIST optional. Adapt the domain of CHIDIST to allow negative x. Remove the constraint "degrees of freedom < 1.0E5" from CHIDIST and CHIINV. Plus a mechanism to write the now optional parameter of GAMMADIST to PODF and ODFF if omitted, for backwards compatibility. 2008-12-15 14:06:11 +0100 oj r265490 : CWS-TOOLING: rebase CWS frmdlg to trunk@264807 (milestone: DEV300:m37) 2008-12-15 13:55:28 +0100 oj r265488 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:55:07 +0100 oj r265487 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:48 +0100 oj r265486 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:36 +0100 oj r265485 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:24 +0100 oj r265484 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:48:11 +0100 oj r265483 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:31:12 +0100 oj r265479 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:13:58 +0100 oj r265477 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:10:09 +0100 oj r265476 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:05:11 +0100 oj r265475 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:47:17 +0100 oj r265467 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:46:19 +0100 oj r265466 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:45:47 +0100 oj r265465 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 07:35:07 +0100 oj r265458 : add dependency to formula 2008-12-15 07:34:24 +0100 oj r265457 : add dependency to formula 2008-12-12 13:22:00 +0100 msc r265413 : #i97089# 2008-12-12 13:20:25 +0100 msc r265412 : #i97089# 2008-12-12 12:35:12 +0100 msc r265406 : #i97089# 2008-12-12 12:34:16 +0100 msc r265405 : #i97089# 2008-12-12 12:33:05 +0100 msc r265404 : #i97089# 2008-12-12 12:31:11 +0100 msc r265403 : #i97089# 2008-12-08 11:59:10 +0100 oj r264981 : insert RTL_LOG 2008-12-08 11:50:17 +0100 oj r264980 : some small changes 2008-12-05 12:57:57 +0100 oj r264902 : eof changed 2008-12-05 12:56:46 +0100 oj r264901 : eof changed 2008-12-05 12:28:47 +0100 oj r264899 : wrong var used 2008-12-05 10:08:57 +0100 oj r264890 : token order reversed 2008-12-04 13:49:22 +0100 oc r264843 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:45:27 +0100 oc r264842 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:42:54 +0100 oc r264841 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:37:41 +0100 oc r264840 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:34:11 +0100 oc r264839 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 12:35:31 +0100 oj r264835 : new help ids for struct and function tabpage 2008-12-04 12:00:35 +0100 oj r264828 : set explicit help id 2008-12-03 14:53:27 +0100 oj r264786 : #i96845# change ref button 2008-12-03 14:51:49 +0100 oj r264785 : #i96845# change ref button 2008-12-03 08:51:57 +0100 oj r264746 : convert dos to unix lineends 2008-12-03 08:50:45 +0100 oj r264745 : convert dos to unix lineends 2008-12-03 08:50:05 +0100 oj r264744 : convert dos to unix lineends 2008-12-02 12:28:33 +0100 oj r264686 : clear help text when new helpid is set 2008-12-02 12:28:02 +0100 oj r264685 : set help id for listbox category 2008-12-02 07:15:56 +0100 oj r264655 : remove define to auto generate help ids 2008-12-01 14:36:43 +0100 oj r264604 : use temp var 2008-12-01 14:18:31 +0100 oj r264601 : moved ScJumpToken to formula 2008-12-01 14:18:11 +0100 oj r264600 : moved ScJumpToken to formula 2008-12-01 14:14:35 +0100 oj r264599 : moved ScJumpToken from sc 2008-12-01 10:48:51 +0100 oj r264589 : change quickhelptext from Shrink to Select 2008-12-01 10:28:41 +0100 oj r264588 : fix opcode data, has to be Any.Void 2008-11-28 11:16:48 +0100 oj r264532 : add help ids 2008-11-28 10:16:56 +0100 oj r264529 : set help id 2008-11-28 10:16:43 +0100 oj r264528 : set help id 2008-11-26 13:55:04 +0100 oj r264381 : #94535# use of optional instead of deleting a string myself and some small changes 2008-11-26 09:53:20 +0100 oj r264346 : compile error with debug/without debug 2008-11-25 07:41:28 +0100 oj r264271 : put static into the method which make use of them 2008-11-24 08:16:07 +0100 oj r264196 : removed not needed classes for op code 2008-11-24 08:13:44 +0100 oj r264195 : removed not needed classes for op code 2008-11-21 14:05:53 +0100 oj r264135 : make GetOpCode inline 2008-11-21 12:35:27 +0100 oj r264124 : hold symbols 2008-11-20 09:27:27 +0100 oj r264028 : merged code from DEV300_m35 which got lost 2008-11-19 20:42:12 +0100 oj r264022 : more changes for formula dialog remove 2008-11-19 20:37:41 +0100 oj r264021 : removed unused var 2008-11-19 20:35:35 +0100 oj r264020 : some more changes at token 2008-11-19 10:59:47 +0100 oj r263967 : deleted 2008-11-19 10:58:24 +0100 oj r263966 : add forui and for res files 2008-11-18 15:27:36 +0100 oj r263777 : unused para removed 2008-11-18 15:23:23 +0100 oj r263775 : add insert button to add field dlg 2008-11-18 13:39:53 +0100 oj r263764 : enable the formula dialog as well for conditional print as for conditional formatting 2008-11-18 12:03:25 +0100 oj r263760 : rename isRef in IsRef 2008-11-17 11:46:16 +0100 oj r263711 : patches for function handling 2008-11-17 11:36:22 +0100 oj r263710 : add new for forui and res file 2008-11-17 09:21:12 +0100 oj r263704 : patches for some resource for libformula 2008-11-15 12:45:30 +0100 oj r263701 : changes for formula editor extraction 2008-11-07 08:23:27 +0100 oj r263416 : merge from DEV300:m35 2008-11-07 08:22:35 +0100 oj r263415 : merge from DEV300:m35 2008-11-07 08:22:16 +0100 oj r263414 : merge from DEV300:m35 2008-11-07 08:21:41 +0100 oj r263413 : merge from DEV300:m35 2008-11-07 08:21:31 +0100 oj r263412 : merge from DEV300:m35 2008-11-07 08:20:38 +0100 oj r263411 : merge from DEV300:m35 2008-11-07 08:20:00 +0100 oj r263410 : merge from DEV300:m35 2008-11-07 08:18:50 +0100 oj r263409 : merge from DEV300:m35 2008-11-07 08:18:19 +0100 oj r263408 : merge from DEV300:m35 2008-11-07 08:10:27 +0100 oj r263407 : merge from DEV300:m35 2008-10-21 07:43:46 +0200 oj r262560 : some compile errors resolved 2008-10-17 16:40:01 +0200 oj r262291 : dep for 1st target 2008-10-07 10:08:39 +0200 oj r262077 : copy 2008-10-07 09:45:31 +0200 oj r262076 : #i94535# 2008-10-07 09:44:26 +0200 oj r262075 : #i94535# new base class 2008-10-07 09:43:21 +0200 oj r262074 : moved to formula 2008-10-07 09:41:51 +0200 oj r262073 : new images 2008-10-07 09:03:01 +0200 oj r262072 : new ids for formula 2008-10-02 08:46:27 +0200 oj r262024 : #i94535# move the formula compiler to formula 2008-10-02 08:08:54 +0200 oj r262023 : #i94535# 2008-10-02 08:06:28 +0200 oj r262022 : #i94535# 2008-10-02 08:05:52 +0200 oj r262021 : #i94535# 2008-10-01 17:15:29 +0200 oj r262014 : #i94535# 2008-10-01 17:12:40 +0200 oj r262013 : new module formula 2008-10-01 17:04:55 +0200 oj r262012 : #i94535# 2008-10-01 16:49:03 +0200 oj r262010 : #i94535# 2008-10-01 16:46:59 +0200 oj r262009 : #i94535#
2009-01-08 10:47:13 +00:00
const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
USHORT nTCount = pPrint->GetTokenCount(sep);
for (USHORT i=0; i<nTCount; i++)
{
String aToken = pPrint->GetToken(i, sep);
if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID )
pDoc->AddPrintRange( nTab, aRange );
}
}
2000-09-18 16:07:07 +00:00
}
else // NULL = use selection (print range is always set), use empty string to delete all ranges
2000-09-18 16:07:07 +00:00
{
if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
{
pDoc->AddPrintRange( nTab, aRange );
}
else if ( rMark.IsMultiMarked() )
2000-09-18 16:07:07 +00:00
{
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
}
}
// 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
for (nTab=0; nTab<nTabCount; nTab++)
if (rMark.GetTableSelect(nTab))
ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).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();
}
//----------------------------------------------------------------------------
// Zellen zusammenfassen
BOOL ScViewFunc::TestMergeCells() // Vorab-Test (fuer Menue)
{
// simple test: TRUE if there's a selection but no multi selection and not filtered
const ScMarkData& rMark = GetViewData()->GetMarkData();
if ( rMark.IsMarked() || rMark.IsMultiMarked() )
{
ScRange aDummy;
return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE;
}
else
return FALSE;
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
BOOL ScViewFunc::MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord, BOOL bCenter )
2000-09-18 16:07:07 +00:00
{
// Editable- und Verschachtelungs-Abfrage muss vorneweg sein (auch in DocFunc),
// damit dann nicht die Inhalte-QueryBox kommt
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 FALSE;
}
ScMarkData& rMark = GetViewData()->GetMarkData();
rMark.MarkToSimple();
if (!rMark.IsMarked())
{
ErrorMessage(STR_NOMULTISELECT);
return FALSE;
}
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScRange aMarkRange;
rMark.GetMarkArea( aMarkRange );
SCCOL nStartCol = aMarkRange.aStart.Col();
SCROW nStartRow = aMarkRange.aStart.Row();
SCTAB nStartTab = aMarkRange.aStart.Tab();
SCCOL nEndCol = aMarkRange.aEnd.Col();
SCROW nEndRow = aMarkRange.aEnd.Row();
SCTAB nEndTab = aMarkRange.aEnd.Tab();
2000-09-18 16:07:07 +00:00
if ( nStartCol == nEndCol && nStartRow == nEndRow )
{
// nichts zu tun
return TRUE;
}
if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
HASATTR_MERGED | HASATTR_OVERLAPPED ) )
{ // "Zusammenfassen nicht verschachteln !"
ErrorMessage(STR_MSSG_MERGECELLS_0);
return FALSE;
}
// Check for the contents of all selected tables.
bool bAskDialog = false;
SCTAB nTabCount = pDoc->GetTableCount();
ScCellMergeOption aMergeOption(nStartCol, nStartRow, nEndCol, nEndRow, bCenter);
for (SCTAB i = 0; i < nTabCount; ++i)
{
if (!rMark.GetTableSelect(i))
// this table is not selected.
continue;
aMergeOption.maTabs.insert(i);
if (!pDoc->IsBlockEmpty(i, nStartCol, nStartRow+1, nStartCol, nEndRow) ||
!pDoc->IsBlockEmpty(i, nStartCol+1, nStartRow, nEndCol, nEndRow))
bAskDialog = true;
}
2000-09-18 16:07:07 +00:00
BOOL bOk = TRUE;
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 ) );
USHORT nRetVal = aBox.Execute();
if ( nRetVal == RET_YES )
rDoContents = TRUE;
else if ( nRetVal == RET_CANCEL )
bOk = FALSE;
}
}
if (bOk)
{
HideCursor();
bOk = pDocSh->GetDocFunc().MergeCells( aMergeOption, rDoContents, bRecord, bApi );
2000-09-18 16:07:07 +00:00
ShowCursor();
if (bOk)
{
SetCursor( nStartCol, nStartRow );
//DoneBlockMode( FALSE);
Unmark();
pDocSh->UpdateOle(GetViewData());
UpdateInputLine();
}
}
return bOk;
}
//----------------------------------------------------------------------------
BOOL ScViewFunc::TestRemoveMerge()
{
BOOL bMerged = FALSE;
ScRange aRange;
if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocument* pDoc = GetViewData()->GetDocument();
if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
bMerged = TRUE;
}
return bMerged;
}
//----------------------------------------------------------------------------
static bool lcl_extendMergeRange(ScCellMergeOption& rOption, const ScRange& rRange)
{
bool bExtended = false;
if (rOption.mnStartCol > rRange.aStart.Col())
{
rOption.mnStartCol = rRange.aStart.Col();
bExtended = true;
}
if (rOption.mnStartRow > rRange.aStart.Row())
{
rOption.mnStartRow = rRange.aStart.Row();
bExtended = true;
}
if (rOption.mnEndCol < rRange.aEnd.Col())
{
rOption.mnEndCol = rRange.aEnd.Col();
bExtended = true;
}
if (rOption.mnEndRow < rRange.aEnd.Row())
{
rOption.mnEndRow = rRange.aEnd.Row();
bExtended = true;
}
return bExtended;
}
2000-09-18 16:07:07 +00:00
BOOL ScViewFunc::RemoveMerge( BOOL bRecord )
{
ScRange aRange;
ScEditableTester aTester( this );
if (!aTester.IsEditable())
{
ErrorMessage(aTester.GetMessageId());
return FALSE;
}
else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
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();
SCTAB nTabCount = pDoc->GetTableCount();
ScCellMergeOption aOption(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row());
bool bExtended = false;
do
{
bExtended = false;
for (SCTAB i = 0; i < nTabCount; ++i)
{
if (!rMark.GetTableSelect(i))
// This table is not selected.
continue;
aOption.maTabs.insert(i);
aExtended.aStart.SetTab(i);
aExtended.aEnd.SetTab(i);
pDoc->ExtendMerge(aExtended);
pDoc->ExtendOverlapped(aExtended);
// Expand the current range to be inclusive of all merged
// areas on all sheets.
bExtended = lcl_extendMergeRange(aOption, aExtended);
}
}
while (bExtended);
2000-09-18 16:07:07 +00:00
HideCursor();
BOOL bOk = pDocSh->GetDocFunc().UnmergeCells(aOption, bRecord, FALSE );
aExtended = aOption.getFirstSingleRange();
MarkRange( aExtended );
2000-09-18 16:07:07 +00:00
ShowCursor();
2000-09-18 16:07:07 +00:00
if (bOk)
pDocSh->UpdateOle(GetViewData());
}
return TRUE; //! bOk ??
}
//----------------------------------------------------------------------------
void ScViewFunc::FillSimple( FillDir eDir, BOOL bRecord )
{
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 );
if (bSuccess)
{
pDocSh->UpdateOle(GetViewData());
UpdateScrollBars();
}
}
else
ErrorMessage(STR_NOMULTISELECT);
}
//----------------------------------------------------------------------------
void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
double fStart, double fStep, double fMax, BOOL bRecord )
{
ScRange aRange;
if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScMarkData& rMark = GetViewData()->GetMarkData();
BOOL bSuccess = pDocSh->GetDocFunc().
FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
fStart, fStep, fMax, bRecord, FALSE );
if (bSuccess)
{
pDocSh->UpdateOle(GetViewData());
UpdateScrollBars();
// #i97876# Spreadsheet data changes are not notified
ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
if ( pModelObj && pModelObj->HasChangesListeners() )
{
ScRangeList aChangeRanges;
aChangeRanges.Append( aRange );
pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
}
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, ULONG nCount, 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();
BOOL bSuccess = pDocSh->GetDocFunc().
FillAuto( aRange, &rMark, eDir, nCount, bRecord, FALSE );
if (bSuccess)
{
MarkRange( aRange, FALSE ); // aRange ist in FillAuto veraendert worden
pDocSh->UpdateOle(GetViewData());
UpdateScrollBars();
// #i97876# Spreadsheet data changes are not notified
ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
if ( pModelObj && pModelObj->HasChangesListeners() )
{
ScRangeList aChangeRanges;
ScRange aChangeRange( aRange );
switch ( eDir )
{
case FILL_TO_BOTTOM:
{
aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 );
}
break;
case FILL_TO_TOP:
{
aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 );
}
break;
case FILL_TO_RIGHT:
{
aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 );
}
break;
case FILL_TO_LEFT:
{
aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 );
}
break;
default:
{
}
break;
}
aChangeRanges.Append( aChangeRange );
pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
}
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
void ScViewFunc::FillTab( USHORT nFlags, USHORT nFunction, BOOL bSkipEmpty, BOOL bAsLink )
{
//! 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();
BOOL bUndo(pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
ScRange aMarkRange;
rMark.MarkToSimple();
BOOL bMulti = rMark.IsMultiMarked();
if (bMulti)
rMark.GetMultiMarkArea( aMarkRange );
else if (rMark.IsMarked())
rMark.GetMarkArea( aMarkRange );
else
aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
ScDocument* pUndoDoc = NULL;
// if ( bRecord )
if (bUndo)
2000-09-18 16:07:07 +00:00
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab );
// pUndoDoc->SelectTable( nTab, TRUE ); // nur fuer Markierung
SCTAB nTabCount = pDoc->GetTableCount();
for (SCTAB i=0; i<nTabCount; i++)
2000-09-18 16:07:07 +00:00
if (i != nTab && rMark.GetTableSelect(i))
{
pUndoDoc->AddUndoTab( i, i );
aMarkRange.aStart.SetTab( i );
aMarkRange.aEnd.SetTab( i );
pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc );
// pUndoDoc->SelectTable( i, TRUE );
}
}
if (bMulti)
pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
else
{
aMarkRange.aStart.SetTab( nTab );
aMarkRange.aEnd.SetTab( nTab );
pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
}
// if ( bRecord )
if (bUndo)
2000-09-18 16:07:07 +00:00
{ //! fuer ChangeTrack erst zum Schluss
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoFillTable( pDocSh, rMark,
aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab,
aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab,
pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) );
}
pDocSh->PostPaintGridAll();
pDocSh->PostDataChanged();
}
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, 0, 1 );
if ( nMovY > nEndY )
{
FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
nMovY - nEndY );
return;
}
}
}
if ( nEndX < MAXCOL )
{
SCCOL nMovX = nEndX + 1;
SCROW nMovY = nStartY;
if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
pDoc->HasData( nMovX, nStartY + 1, nTab ) )
{
pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
if ( nMovY > nEndY )
{
FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
nMovY - nEndY );
return;
}
}
}
}
}
//----------------------------------------------------------------------------
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 ) );
}
BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
TransliterateText( aFuncMark, nType, TRUE, FALSE );
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( USHORT nFormatNo, BOOL bRecord )
{
#if 1
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();
BOOL bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, FALSE );
if (bSuccess)
pDocSh->UpdateOle(GetViewData());
}
else
ErrorMessage(STR_NOMULTISELECT);
#else
// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
BOOL bOnlyNotBecauseOfMatrix;
if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
{
ErrorMessage(STR_PROTECTIONERR);
return;
}
SCCOL nStartCol;
SCROW nStartRow;
SCTAB nStartTab;
SCCOL nEndCol;
SCROW nEndRow;
SCTAB nEndTab;
2000-09-18 16:07:07 +00:00
if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
BOOL bSize = (*ScGlobal::GetAutoFormat())[nFormatNo]->GetIncludeWidthHeight();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = FALSE;
2000-09-18 16:07:07 +00:00
ScDocument* pUndoDoc = NULL;
if ( bRecord )
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bSize, bSize );
pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
IDF_ATTRIB, FALSE, pUndoDoc );
if (bSize)
{
pDoc->CopyToDocument( nStartCol,0,nStartTab, nEndCol,MAXROW,nEndTab,
IDF_NONE, FALSE, pUndoDoc );
pDoc->CopyToDocument( 0,nStartRow,nStartTab, MAXCOL,nEndRow,nEndTab,
IDF_NONE, FALSE, pUndoDoc );
}
pDoc->BeginDrawUndo();
}
GetFrameWin()->EnterWait();
pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, rMark );
GetFrameWin()->LeaveWait();
if (bSize)
{
SetMarkedWidthOrHeight( TRUE, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, FALSE, FALSE );
SetMarkedWidthOrHeight( FALSE, SC_SIZE_VISOPT, 0, FALSE, FALSE );
pDocSh->PostPaint( 0,0,nStartTab, MAXCOL,MAXROW,nStartTab,
PAINT_GRID | PAINT_LEFT | PAINT_TOP );
}
else
{
BOOL bAdj = AdjustBlockHeight( FALSE );
if (bAdj)
pDocSh->PostPaint( 0,nStartRow,nStartTab, MAXCOL,MAXROW,nStartTab,
PAINT_GRID | PAINT_LEFT );
else
pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
nEndCol, nEndRow, nEndTab, PAINT_GRID );
}
if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
{
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoAutoFormat( pDocSh,
ScRange(nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab),
pUndoDoc, rMark, bSize, nFormatNo ) );
}
pDocSh->UpdateOle(GetViewData());
pDocSh->SetDocumentModified();
}
else
ErrorMessage(STR_NOMULTISELECT);
#endif
}
//----------------------------------------------------------------------------
// Suchen & Ersetzen
void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
BOOL bAddUndo, BOOL bIsApi )
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
if (bAddUndo && !pDoc->IsUndoEnabled())
bAddUndo = FALSE;
2000-09-18 16:07:07 +00:00
SCCOL nCol = GetViewData()->GetCurX();
SCROW nRow = GetViewData()->GetCurY();
SCTAB nTab = GetViewData()->GetTabNo();
// BOOL bAttrib = pSearchItem->GetPattern();
2000-09-18 16:07:07 +00:00
USHORT nCommand = pSearchItem->GetCommand();
BOOL bAllTables = pSearchItem->IsAllTables();
BOOL* pOldSelectedTables = NULL;
USHORT nOldSelectedCount = 0;
SCTAB nOldTab = nTab;
SCTAB nLastTab = pDoc->GetTableCount() - 1;
SCTAB nStartTab, nEndTab;
2000-09-18 16:07:07 +00:00
if ( bAllTables )
{
nStartTab = 0;
nEndTab = nLastTab;
pOldSelectedTables = new BOOL [ nEndTab + 1 ];
for ( SCTAB j = 0; j <= nEndTab; j++ )
2000-09-18 16:07:07 +00:00
{
pOldSelectedTables[j] = rMark.GetTableSelect( j );
if ( pOldSelectedTables[j] )
++nOldSelectedCount;
}
}
else
{ //! mindestens eine ist immer selektiert
nStartTab = nEndTab = rMark.GetFirstSelected();
for ( SCTAB j = nStartTab + 1; j <= nLastTab; j++ )
2000-09-18 16:07:07 +00:00
{
if ( rMark.GetTableSelect( j ) )
nEndTab = j;
}
}
if ( nCommand == SVX_SEARCHCMD_REPLACE
|| nCommand == SVX_SEARCHCMD_REPLACE_ALL )
{
for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
2000-09-18 16:07:07 +00:00
{
if ( (bAllTables || rMark.GetTableSelect( j )) &&
pDoc->IsTabProtected( j ) )
{
if ( pOldSelectedTables )
delete [] pOldSelectedTables;
ErrorMessage(STR_PROTECTIONERR);
return;
}
}
}
if ( nCommand == SVX_SEARCHCMD_FIND
|| nCommand == SVX_SEARCHCMD_FIND_ALL)
bAddUndo = FALSE;
//! bAttrib bei Undo beruecksichtigen !!!
ScDocument* pUndoDoc = NULL;
ScMarkData* pUndoMark = NULL;
String aUndoStr;
if (bAddUndo)
{
pUndoMark = new ScMarkData( rMark ); // Markierung wird veraendert
if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
}
}
if ( bAllTables )
{ //! alles selektieren, erst nachdem pUndoMark erzeugt wurde
for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
2000-09-18 16:07:07 +00:00
{
rMark.SelectTable( j, TRUE );
}
}
DoneBlockMode(TRUE); // Markierung nicht loeschen!
InitOwnBlockMode();
// wenn vom Anfang an gesucht wird, nicht nochmal fragen ob vom Anfang gesucht werden soll
BOOL bFirst = TRUE;
if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() )
bFirst = FALSE;
BOOL bFound = FALSE;
while (TRUE)
{
GetFrameWin()->EnterWait();
if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) )
{
bFound = TRUE;
bFirst = TRUE;
if (bAddUndo)
{
GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
nCol, nRow, nTab,
aUndoStr, pUndoDoc, pSearchItem ) );
pUndoDoc = NULL;
}
break; // Abbruch while True
}
else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
nCommand == SVX_SEARCHCMD_REPLACE) )
{
bFirst = FALSE;
USHORT nRetVal;
GetFrameWin()->LeaveWait();
if ( bIsApi )
nRetVal = RET_NO;
else
{
// Suchen-Dialog als Parent, wenn vorhanden
Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
USHORT nStrId;
if ( pSearchItem->GetBackward() )
{
if ( nStartTab == nEndTab )
nStrId = STR_MSSG_SEARCHANDREPLACE_1;
else
nStrId = STR_MSSG_SEARCHANDREPLACE_4;
}
else
{
if ( nStartTab == nEndTab )
nStrId = STR_MSSG_SEARCHANDREPLACE_2;
else
nStrId = STR_MSSG_SEARCHANDREPLACE_5;
}
MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
ScGlobal::GetRscString( nStrId ) );
nRetVal = aBox.Execute();
}
if ( nRetVal == RET_YES )
{
ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
if (pSearchItem->GetBackward())
nTab = nEndTab;
else
nTab = nStartTab;
}
else
{
break; // Abbruch while True
}
}
else // nichts gefunden
{
if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
{
pDocSh->PostPaintGridAll(); // Markierung
}
GetFrameWin()->LeaveWait();
if (!bIsApi)
{
// Suchen-Dialog als Parent, wenn vorhanden
Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
// "nichts gefunden"
InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
aBox.Execute();
}
break; // Abbruch while True
}
} // of while TRUE
if ( pOldSelectedTables )
{ // urspruenglich selektierte Tabellen wiederherstellen
for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
2000-09-18 16:07:07 +00:00
{
rMark.SelectTable( j, pOldSelectedTables[j] );
}
if ( bFound )
{ // durch Fundstelle neu selektierte Tabelle bleibt
rMark.SelectTable( nTab, TRUE );
// wenn vorher nur eine selektiert war, ist es ein Tausch
//! wenn nicht, ist jetzt evtl. eine mehr selektiert
if ( nOldSelectedCount == 1 && nTab != nOldTab )
rMark.SelectTable( nOldTab, FALSE );
}
delete [] pOldSelectedTables;
}
MarkDataChanged();
2000-09-18 16:07:07 +00:00
if ( bFound )
{
if ( nTab != GetViewData()->GetTabNo() )
SetTabNo( nTab );
// wenn nichts markiert ist, DoneBlockMode, damit von hier aus
// direkt per Shift-Cursor markiert werden kann:
if (!rMark.IsMarked() && !rMark.IsMultiMarked())
DoneBlockMode(TRUE);
AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
SetCursor( nCol, nRow, TRUE );
if ( nCommand == SVX_SEARCHCMD_REPLACE
|| nCommand == SVX_SEARCHCMD_REPLACE_ALL )
{
if ( nCommand == SVX_SEARCHCMD_REPLACE )
pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
else
pDocSh->PostPaintGridAll();
pDocSh->SetDocumentModified();
}
else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
pDocSh->PostPaintGridAll(); // Markierung
GetFrameWin()->LeaveWait();
}
delete pUndoDoc; // loeschen wenn nicht benutzt
delete pUndoMark; // kann immer geloescht werden
}
//----------------------------------------------------------------------------
// Zielwertsuche
void ScViewFunc::Solve( const ScSolveParam& rParam )
{
ScDocument* pDoc = GetViewData()->GetDocument();
SCCOL nDestCol = rParam.aRefVariableCell.Col();
SCROW nDestRow = rParam.aRefVariableCell.Row();
SCTAB nDestTab = rParam.aRefVariableCell.Tab();
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();
BOOL bExact =
pDoc->Solver(
rParam.aRefFormulaCell.Col(),
rParam.aRefFormulaCell.Row(),
rParam.aRefFormulaCell.Tab(),
nDestCol, nDestRow, nDestTab,
aTargetValStr,
nSolveResult );
GetFrameWin()->LeaveWait();
SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
ULONG nFormat = 0;
const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
if ( pPattern )
nFormat = pPattern->GetNumberFormat( pFormatter );
Color* p;
pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );
if ( bExact )
{
aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
aMsgStr += String( aResStr );
aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
}
else
{
aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_5 );
aMsgStr += String( aResStr );
aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_6 );
}
MessBox aBox( GetViewData()->GetDialogParent(),
WinBits(WB_YES_NO | WB_DEF_NO),
ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
USHORT nRetVal = aBox.Execute();
if ( RET_YES == nRetVal )
EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
2000-09-18 16:07:07 +00:00
GetViewData()->GetViewShell()->UpdateInputHandler( TRUE );
}
}
//----------------------------------------------------------------------------
// Mehrfachoperation
void ScViewFunc::TabOp( const ScTabOpParam& rParam, BOOL bRecord )
{
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 );
}
else
ErrorMessage(STR_NOMULTISELECT);
}
//----------------------------------------------------------------------------
void ScViewFunc::MakeScenario( const String& rName, const String& rComment,
const Color& rColor, USHORT nFlags )
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScMarkData& rMark = GetViewData()->GetMarkData();
SCTAB nTab = GetViewData()->GetTabNo();
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 -> sichtbar
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: Attribute anwenden
ScDocument* pDoc = GetViewData()->GetDocument();
ScPatternAttr aPattern( pDoc->GetPool() );
aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
aPattern.GetItemSet().Put( ScProtectionAttr( TRUE ) );
ApplySelectionPattern(aPattern);
}
//----------------------------------------------------------------------------
void ScViewFunc::UseScenario( const String& rName )
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
DoneBlockMode();
InitOwnBlockMode();
pDocSh->UseScenario( nTab, rName );
}
//----------------------------------------------------------------------------
// Tabelle einfuegen
BOOL ScViewFunc::InsertTable( const String& rName, SCTAB nTab, BOOL bRecord )
2000-09-18 16:07:07 +00:00
{
// Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
InsertTable( nTab, rName, bRecord, FALSE );
if (bSuccess)
SetTabNo( nTab, TRUE );
return bSuccess;
}
//----------------------------------------------------------------------------
// Tabellen einfuegen
BOOL ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab,
SCTAB nCount, BOOL bRecord )
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
SvStrings *pNameList= NULL;
WaitObject aWait( GetFrameWin() );
if (bRecord)
{
pNameList= new SvStrings;
pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
}
BOOL bFlag=FALSE;
String aValTabName;
String *pStr;
for(SCTAB i=0;i<nCount;i++)
2000-09-18 16:07:07 +00:00
{
if(pNames!=NULL)
{
pStr=pNames->GetObject(static_cast<USHORT>(i));
2000-09-18 16:07:07 +00:00
}
else
{
aValTabName.Erase();
pDoc->CreateValidTabName( aValTabName);
pStr=&aValTabName;
}
if(pDoc->InsertTab( nTab+i,*pStr))
{
bFlag=TRUE;
pDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab+i ) );
}
else
{
break;
}
if(pNameList!=NULL)
pNameList->Insert(new String(*pStr),pNameList->Count());
}
if (bFlag)
{
if (bRecord)
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoInsertTables( pDocSh, nTab, FALSE, pNameList));
// Views updaten:
SetTabNo( nTab, TRUE );
pDocSh->PostPaintExtras();
pDocSh->SetDocumentModified();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
return TRUE;
}
else
{
return FALSE;
}
}
//----------------------------------------------------------------------------
BOOL ScViewFunc::AppendTable( const String& rName, BOOL bRecord )
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
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 erzeugt ein SdrUndoNewPage
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, TRUE, rName));
GetViewData()->InsertTab( nTab );
SetTabNo( nTab, TRUE );
pDocSh->PostPaintExtras();
pDocSh->SetDocumentModified();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
return TRUE;
}
else
{
return FALSE;
}
}
//----------------------------------------------------------------------------
BOOL ScViewFunc::DeleteTable( SCTAB nTab, BOOL bRecord )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
BOOL bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, FALSE );
if (bSuccess)
{
SCTAB nNewTab = nTab;
2000-09-18 16:07:07 +00:00
if ( nNewTab >= pDoc->GetTableCount() )
--nNewTab;
SetTabNo( nNewTab, TRUE );
}
return bSuccess;
}
BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
BOOL bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : FALSE;
SCTAB nNewTab = TheTabs[0];
2000-09-18 16:07:07 +00:00
int i;
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;
2000-09-18 16:07:07 +00:00
BOOL bWasLinked = FALSE;
ScDocument* pUndoDoc = NULL;
ScRefUndoData* pUndoData = NULL;
if (bRecord)
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
// pUndoDoc->InitDrawLayer( pDocSh );
SCTAB nCount = pDoc->GetTableCount();
2000-09-18 16:07:07 +00:00
// pUndoDoc->InitUndo( pDoc, 0, nCount-1 ); // incl. Ref.
String aOldName;
for(i=0;i<TheTabs.Count();i++)
{
SCTAB nTab = TheTabs[sal::static_int_cast<USHORT>(i)];
2000-09-18 16:07:07 +00:00
if (i==0)
pUndoDoc->InitUndo( pDoc, nTab,nTab, TRUE,TRUE ); // incl. Spalten/Zeilenflags
else
pUndoDoc->AddUndoTab( nTab,nTab, TRUE,TRUE ); // incl. Spalten/Zeilenflags
pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,FALSE, pUndoDoc );
pDoc->GetName( nTab, aOldName );
pUndoDoc->RenameTab( nTab, aOldName, FALSE );
if (pDoc->IsLinked(nTab))
{
bWasLinked = TRUE;
pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
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, TRUE );
String aComment;
Color aColor;
USHORT nScenFlags;
pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
BOOL bActive = pDoc->IsActiveScenario( nTab );
pUndoDoc->SetActiveScenario( nTab, bActive );
}
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));
2000-09-18 16:07:07 +00:00
// Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
// pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
}
pUndoDoc->AddUndoTab( 0, nCount-1 ); // alle Tabs fuer Referenzen
pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage
pUndoData = new ScRefUndoData( pDoc );
}
2000-10-05 09:55:35 +00:00
BOOL bDelDone = FALSE;
2000-09-18 16:07:07 +00:00
for(i=TheTabs.Count()-1;i>=0;i--)
{
String sCodeName;
BOOL bHasCodeName = pDoc->GetCodeName( TheTabs[sal::static_int_cast<USHORT>(i)], sCodeName );
if (pDoc->DeleteTab( TheTabs[sal::static_int_cast<USHORT>(i)], pUndoDoc ))
2000-09-18 16:07:07 +00:00
{
2000-10-05 09:55:35 +00:00
bDelDone = TRUE;
if( bVbaEnabled )
{
if( bHasCodeName )
{
VBA_DeleteModule( *pDocSh, sCodeName );
}
}
pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[sal::static_int_cast<USHORT>(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, TRUE );
2000-09-18 16:07:07 +00:00
if (bWasLinked)
{
pDocSh->UpdateLinks(); // Link-Manager updaten
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
}
//----------------------------------------------------------------------------
BOOL ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
2000-09-18 16:07:07 +00:00
{
// Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
RenameTable( nTab, rName, TRUE, FALSE );
if (bSuccess)
{
// Der Tabellenname koennte in einer Formel vorkommen...
GetViewData()->GetViewShell()->UpdateInputHandler();
}
return bSuccess;
}
//----------------------------------------------------------------------------
bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
{
bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, TRUE, FALSE );
if (bSuccess)
{
GetViewData()->GetViewShell()->UpdateInputHandler();
}
return bSuccess;
}
bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
{
bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, TRUE, FALSE );
if (bSuccess)
{
GetViewData()->GetViewShell()->UpdateInputHandler();
}
return bSuccess;
}
2000-09-18 16:07:07 +00:00
//----------------------------------------------------------------------------
void ScViewFunc::InsertAreaLink( const String& rFile,
const String& rFilter, const String& rOptions,
2001-04-05 09:52:34 +00:00
const String& rSource, 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 )
{
String aFilterName = rFilter;
String aOpt = rOptions;
ScDocumentLoader aLoader( rFile, aFilterName, aOpt );
if (!aLoader.IsError())
{
ScDocShell* pSrcSh = aLoader.GetDocShell();
ScDocument* pSrcDoc = pSrcSh->GetDocument();
SCTAB nTab = MAXTAB+1;
2000-09-18 16:07:07 +00:00
if (!rTabName.Len()) // kein Name angegeben -> erste Tabelle
nTab = 0;
else
{
String aTemp;
SCTAB nCount = pSrcDoc->GetTableCount();
for (SCTAB i=0; i<nCount; i++)
2000-09-18 16:07:07 +00:00
{
pSrcDoc->GetName( i, aTemp );
if ( aTemp == rTabName )
nTab = i;
}
}
if ( nTab <= MAXTAB )
ImportTables( pSrcSh, 1, &nTab, TRUE,
GetViewData()->GetTabNo() );
}
}
//----------------------------------------------------------------------------
// Tabellen aus anderem Dokument kopieren / linken
void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
SCTAB nCount, const SCTAB* pSrcTabs, BOOL bLink,SCTAB nTab )
2000-09-18 16:07:07 +00:00
{
ScDocument* pSrcDoc = pSrcShell->GetDocument();
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
BOOL bUndo(pDoc->IsUndoEnabled());
//SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
BOOL bError = FALSE;
BOOL bRefs = FALSE;
BOOL bName = FALSE;
if (pSrcDoc->GetDrawLayer())
pDocSh->MakeDrawLayer();
if (bUndo)
pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
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++ )
{ // #63304# insert sheets first and update all references
String aName;
pSrcDoc->GetName( pSrcTabs[i], aName );
pDoc->CreateValidTabName( aName );
if ( !pDoc->InsertTab( nTab+i, aName ) )
{
bError = TRUE; // total error
break; // for
}
++nInsCount;
}
for (i=0; i<nCount && !bError; i++)
{
SCTAB nSrcTab = pSrcTabs[i];
SCTAB nDestTab1=nTab+i;
ULONG nErrVal = pDocSh->TransferTab( *pSrcShell, nSrcTab, nDestTab1,
FALSE, FALSE ); // no insert
2000-09-18 16:07:07 +00:00
switch (nErrVal)
{
case 0: // interner Fehler oder voll Fehler
bError = TRUE;
break;
case 2:
bRefs = TRUE;
break;
case 3:
bName = TRUE;
break;
case 4:
bRefs = bName = TRUE;
break;
}
}
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);
BOOL bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
2001-04-18 11:14:41 +00:00
ULONG nRefresh = 0;
2000-09-18 16:07:07 +00:00
String aTabStr;
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) // Link pro Quelldokument nur einmal eintragen
{
2001-04-18 11:14:41 +00:00
ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
2000-09-18 16:07:07 +00:00
pLink->SetInCreate( TRUE );
pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
pLink->Update();
pLink->SetInCreate( FALSE );
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, bLink ) );
}
2000-09-18 16:07:07 +00:00
for (i=0; i<nInsCount; i++)
GetViewData()->InsertTab(nTab);
SetTabNo(nTab,TRUE);
pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
SfxApplication* pSfxApp = SFX_APP();
pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
pDocSh->PostPaintExtras();
pDocSh->PostPaintGridAll();
pDocSh->SetDocumentModified();
if (bRefs)
ErrorMessage(STR_ABSREFLOST);
if (bName)
ErrorMessage(STR_NAMECONFLICT);
}
//----------------------------------------------------------------------------
// Tabelle in anderes Dokument verschieben / kopieren
2010-12-13 21:43:04 -05:00
void ScViewFunc::MoveTable( USHORT nDestDocNo, SCTAB nDestTab, BOOL bCopy, const String* 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;
BOOL bUndo (pDoc->IsUndoEnabled());
2010-12-13 21:43:04 -05:00
bool bRename = pNewTabName && pNewTabName->Len();
2000-09-18 16:07:07 +00:00
BOOL bNewDoc = ( nDestDocNo == SC_DOC_NEW );
if ( bNewDoc )
{
nDestTab = 0; // als erstes einfuegen
2000-09-18 16:07:07 +00:00
// ohne SFX_CALLMODE_RECORD ausfuehren, weil schon im Move-Befehl enthalten:
String aUrl = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/"));
aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); // "scalc"
2000-09-18 16:07:07 +00:00
SfxStringItem aItem( SID_FILE_NAME, aUrl );
SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_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)
{
DBG_ERROR("Dest-Doc nicht gefunden !!!");
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,
String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")),
FALSE );
}
SCTAB nTabCount = pDoc->GetTableCount();
SCTAB nTabSelCount = rMark.GetSelectCount();
2000-09-18 16:07:07 +00:00
SvShorts TheTabs;
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))
{
String aTabName;
pDoc->GetName( i, aTabName);
TheTabs.Insert(i,TheTabs.Count());
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);
TheTabs.Insert(j,TheTabs.Count());
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
ULONG nErrVal =1;
if(nDestTab==SC_TAB_APPEND)
nDestTab=pDestDoc->GetTableCount();
SCTAB nDestTab1=nDestTab;
for( USHORT j=0; j<TheTabs.Count(); j++, nDestTab1++ )
2000-09-18 16:07:07 +00:00
{ // #63304# insert sheets first and update all references
String 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
}
}
if ( nErrVal > 0 )
{
nDestTab1 = nDestTab;
for(USHORT i=0;i<TheTabs.Count();i++)
2000-09-18 16:07:07 +00:00
{
nErrVal = pDestShell->TransferTab( *pDocShell, static_cast<SCTAB>(TheTabs[i]), static_cast<SCTAB>(nDestTab1), FALSE, FALSE );
2000-09-18 16:07:07 +00:00
nDestTab1++;
}
}
String 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.Count()), FALSE));
2000-09-18 16:07:07 +00:00
}
else
{
pDestShell->GetUndoManager()->Clear();
}
GetFrameWin()->LeaveWait();
switch (nErrVal)
{
case 0: // interner Fehler oder voll Fehler
{
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;
}
//pDestShell->GetUndoManager()->Clear(); //! Undo implementieren !!!
/*
String sName;
pDestDoc->GetName(nDestTab, sName);
pDestShell->GetUndoManager()->AddUndoAction(
new ScUndoInsertTab( pDestShell, nDestTab, TRUE, sName ) );
*/
if (!bCopy)
{
if(nTabCount!=nTabSelCount)
DeleteTables(TheTabs);// incl. Paint & Undo
else
ErrorMessage(STR_TABREMOVE_ERROR);
}
if (bNewDoc)
{
// ChartListenerCollection must be updated before DeleteTab
if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
pDestDoc->UpdateChartListenerCollection();
pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.Count())); // alte erste Tabelle
2000-09-18 16:07:07 +00:00
//? pDestDoc->SelectTable(0, TRUE); // neue erste Tabelle selektieren
if (pDestViewSh)
pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer
pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
PAINT_GRID | PAINT_TOP | PAINT_LEFT |
PAINT_EXTRAS | PAINT_SIZE );
// PAINT_SIZE fuer Gliederung
}
else
{
pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
pDestShell->PostPaintExtras();
pDestShell->PostPaintGridAll();
}
TheTabs.Remove(0,TheTabs.Count());
pDestShell->SetDocumentModified();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
}
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
SvShorts TheTabs;
SvShorts TheDestTabs;
auto_ptr< vector<OUString> > pTabNames(new vector<OUString>);
auto_ptr< vector<OUString> > pDestNames(NULL);
pTabNames->reserve(nTabCount);
2000-09-18 16:07:07 +00:00
String aDestName;
for(SCTAB i=0;i<nTabCount;i++)
2000-09-18 16:07:07 +00:00
{
if(rMark.GetTableSelect(i))
{
String aTabName;
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 ist hier
if(bCopy && pDoc->IsScenario(nMovTab))
{
String aComment;
Color aColor;
USHORT nFlags;
pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
pDoc->SetScenario(nDestTab1,TRUE);
pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
BOOL bActive = pDoc->IsActiveScenario(nMovTab );
pDoc->SetActiveScenario( nDestTab1, bActive );
BOOL bVisible=pDoc->IsVisible(nMovTab);
pDoc->SetVisible(nDestTab1,bVisible );
}
TheTabs.Insert(nMovTab,TheTabs.Count());
if(!bCopy)
{
if(!pDoc->GetTable(rStr,nDestTab1))
2000-09-18 16:07:07 +00:00
{
nDestTab1=nTabCount;
}
}
TheDestTabs.Insert(nDestTab1,TheDestTabs.Count());
}
// 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 = TheDestTabs.Count();
pDestNames->reserve(n);
for (size_t j = 0; j < n; ++j)
{
SCTAB nRenameTab = static_cast<SCTAB>(TheDestTabs[j]);
2010-12-13 21:43:04 -05:00
String aTabName = *pNewTabName;
pDoc->CreateValidTabName( aTabName );
pDestNames->push_back(aTabName);
pDoc->RenameTab(nRenameTab, aTabName);
}
}
else
// No need to keep this around when we are not renaming.
pTabNames.reset();
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, TheTabs, TheDestTabs, pDestNames.release()));
}
else
{
pDocShell->GetUndoManager()->AddUndoAction(
new ScUndoMoveTab(
pDocShell, TheTabs, TheDestTabs, 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, 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();
BOOL bUndo(pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
BOOL bFound = FALSE;
SCTAB nPos = 0;
2000-09-18 16:07:07 +00:00
String aTabName;
SCTAB nCount = pDoc->GetTableCount();
for (SCTAB i=0; i<nCount; i++)
2000-09-18 16:07:07 +00:00
{
pDoc->GetName( i, aTabName );
if ( aTabName == rName )
{
nPos = i;
bFound = TRUE;
}
}
if (bFound)
{
pDoc->SetVisible( nPos, TRUE );
if (bUndo)
{
pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, TRUE ) );
}
2000-09-18 16:07:07 +00:00
SetTabNo( nPos, TRUE );
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
pDocSh->SetDocumentModified();
}
else
Sound::Beep();
}
//----------------------------------------------------------------------------
void ScViewFunc::HideTable( SCTAB nTab )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
BOOL bUndo(pDoc->IsUndoEnabled());
SCTAB nVisible = 0;
SCTAB nCount = pDoc->GetTableCount();
for (SCTAB i=0; i<nCount; i++)
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
// Views updaten:
pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
SetTabNo( nTab, TRUE );
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
pDocSh->SetDocumentModified();
}
else
Sound::Beep();
}
//----------------------------------------------------------------------------
void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont )
{
ScEditableTester aTester( this );
if (!aTester.IsEditable())
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
BYTE nScript;
ScDocument* pDoc = GetViewData()->GetDocument();
if ( pDoc->HasStringWeakCharacters( rStr ) )
nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
else
nScript = pDoc->GetStringScriptType( rStr );
SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
aSetItem.PutItemForScriptType( nScript, aFontItem );
ApplyUserItemSet( aSetItem.GetItemSet() );
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,
BOOL bColor )
{
if ( pSrcLine && pDestLine )
{
if ( bColor )
{
rLine.SetColor ( pSrcLine->GetColor() );
rLine.SetOutWidth ( pDestLine->GetOutWidth() );
rLine.SetInWidth ( pDestLine->GetInWidth() );
rLine.SetDistance ( pDestLine->GetDistance() );
rLine.SetStyle ( pDestLine->GetStyle() );
2000-09-18 16:07:07 +00:00
}
else
{
rLine.SetColor ( pDestLine->GetColor() );
rLine.SetOutWidth ( pSrcLine->GetOutWidth() );
rLine.SetInWidth ( pSrcLine->GetInWidth() );
rLine.SetDistance ( pSrcLine->GetDistance() );
rLine.SetStyle ( pSrcLine->GetStyle() );
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,
BOOL bColorOnly )
{
// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
BOOL bOnlyNotBecauseOfMatrix;
if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
{
ErrorMessage(STR_PROTECTIONERR);
return;
}
ScDocument* pDoc = GetViewData()->GetDocument();
ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
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, TRUE, &pBorderAttr );
const SfxPoolItem* pTLBRItem = 0;
SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, TRUE, &pTLBRItem );
const SfxPoolItem* pBLTRItem = 0;
SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, TRUE, &pBLTRItem );
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;
// hier wird die pBoxLine benutzt:
if( pBorderAttr )
{
SvxBoxItem aBoxItem( *(const SvxBoxItem*)pBorderAttr );
SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)
aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
aBoxInfoItem.ResetFlags(); // Lines auf Valid setzen
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::SetConditionalFormat( const ScConditionalFormat& rNew )
{
ScDocument* pDoc = GetViewData()->GetDocument();
ULONG nIndex = pDoc->AddCondFormat(rNew); // dafuer gibt's kein Undo
SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex );
ApplyAttr( aItem ); // mit Paint und Undo...
}
//----------------------------------------------------------------------------
void ScViewFunc::SetValidation( const ScValidationData& rNew )
{
ScDocument* pDoc = GetViewData()->GetDocument();
ULONG nIndex = pDoc->AddValidationEntry(rNew); // dafuer gibt's kein Undo
SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
ApplyAttr( aItem ); // mit Paint und Undo...
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */