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

3122 lines
101 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
re-base on ALv2 code. Includes: Patches contributed by Herbert Duerr i#118735 prevent endless loop if vlookup/hlookup doesn't find anything http://svn.apache.org/viewvc?view=revision&revision=1239673 Patches contributed by Andre Fischer remove lp_solver http://svn.apache.org/viewvc?view=revision&revision=1199180 i#118160: Added external CoinMP library. http://svn.apache.org/viewvc?view=revision&revision=1233909 Patches contributed by Armin Le-Grand i#118485 - Styles for OLEs are not saved. http://svn.apache.org/viewvc?view=revision&revision=1182166 i#118524: apply patch, followup fixes to 118485 http://svn.apache.org/viewvc?view=revision&revision=1186077 Patches contributed by lihuiibm i#108860 - Fix range validation. http://svn.apache.org/viewvc?view=revision&revision=1242846 i#118954 Chart data will lost after copy to different file http://svn.apache.org/viewvc?view=revision&revision=1301345 Patches contributed by Ariel Constenla-Haile Fix Linux build breaker: extra qualification on member http://svn.apache.org/viewvc?view=revision&revision=1301591 i#118696 - i#118697 - Fix some Sheet Tab Color API issues http://svn.apache.org/viewvc?view=revision&revision=1225428 i#118697 - Fix uninitialized variable http://svn.apache.org/viewvc?view=revision&revision=1225859 i#118771 - ScUndoImportTab should preserve tab background color http://svn.apache.org/viewvc?view=revision&revision=1230356 i#118921 - Repaint linked sheet tab background color after updating link http://svn.apache.org/viewvc?view=revision&revision=1245177 i#118927 - Undo/Redo "Update Link" does not reset sheet tab color http://svn.apache.org/viewvc?view=revision&revision=1245241 i#118747 - Copy tab color when transferring sheets across documents http://svn.apache.org/viewvc?view=revision&revision=1230355 Patch contributed by Oliver Rainer-Wittman i#118012 - methods <ScBroadcastAreaSlot::AreaBroadcast(..)> and <ScBroadcastAreaSlot::AreaBroadcastInRange(..)> adapt stl-container iteration in order to avoid destroyed iterators during iteration. http://svn.apache.org/viewvc?view=revision&revision=1297916 Patches contributed by Mathias Bauer gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394707 http://svn.apache.org/viewvc?view=revision&revision=1394326 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1397315 Patch contributed by Daniel Rentz calc69: #i116936# fix VBA symbol Cells http://svn.apache.org/viewvc?view=revision&revision=1172135 Patches contributed by leiw: i#118546 CPU 100% on switched off AutoCalculate with Conditional Formatting on date values http://svn.apache.org/viewvc?view=revision&revision=1301380 Re-add new function documentation. Many various cleanups. Add missing calc66: #o11817313# also look at formula result number format, remove redundant binaries.
2012-11-30 12:23:25 +00:00
/*
* This file is part of the LibreOffice project.
2000-09-18 16:07:07 +00:00
*
re-base on ALv2 code. Includes: Patches contributed by Herbert Duerr i#118735 prevent endless loop if vlookup/hlookup doesn't find anything http://svn.apache.org/viewvc?view=revision&revision=1239673 Patches contributed by Andre Fischer remove lp_solver http://svn.apache.org/viewvc?view=revision&revision=1199180 i#118160: Added external CoinMP library. http://svn.apache.org/viewvc?view=revision&revision=1233909 Patches contributed by Armin Le-Grand i#118485 - Styles for OLEs are not saved. http://svn.apache.org/viewvc?view=revision&revision=1182166 i#118524: apply patch, followup fixes to 118485 http://svn.apache.org/viewvc?view=revision&revision=1186077 Patches contributed by lihuiibm i#108860 - Fix range validation. http://svn.apache.org/viewvc?view=revision&revision=1242846 i#118954 Chart data will lost after copy to different file http://svn.apache.org/viewvc?view=revision&revision=1301345 Patches contributed by Ariel Constenla-Haile Fix Linux build breaker: extra qualification on member http://svn.apache.org/viewvc?view=revision&revision=1301591 i#118696 - i#118697 - Fix some Sheet Tab Color API issues http://svn.apache.org/viewvc?view=revision&revision=1225428 i#118697 - Fix uninitialized variable http://svn.apache.org/viewvc?view=revision&revision=1225859 i#118771 - ScUndoImportTab should preserve tab background color http://svn.apache.org/viewvc?view=revision&revision=1230356 i#118921 - Repaint linked sheet tab background color after updating link http://svn.apache.org/viewvc?view=revision&revision=1245177 i#118927 - Undo/Redo "Update Link" does not reset sheet tab color http://svn.apache.org/viewvc?view=revision&revision=1245241 i#118747 - Copy tab color when transferring sheets across documents http://svn.apache.org/viewvc?view=revision&revision=1230355 Patch contributed by Oliver Rainer-Wittman i#118012 - methods <ScBroadcastAreaSlot::AreaBroadcast(..)> and <ScBroadcastAreaSlot::AreaBroadcastInRange(..)> adapt stl-container iteration in order to avoid destroyed iterators during iteration. http://svn.apache.org/viewvc?view=revision&revision=1297916 Patches contributed by Mathias Bauer gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394707 http://svn.apache.org/viewvc?view=revision&revision=1394326 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1397315 Patch contributed by Daniel Rentz calc69: #i116936# fix VBA symbol Cells http://svn.apache.org/viewvc?view=revision&revision=1172135 Patches contributed by leiw: i#118546 CPU 100% on switched off AutoCalculate with Conditional Formatting on date values http://svn.apache.org/viewvc?view=revision&revision=1301380 Re-add new function documentation. Many various cleanups. Add missing calc66: #o11817313# also look at formula result number format, remove redundant binaries.
2012-11-30 12:23:25 +00:00
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
2000-09-18 16:07:07 +00:00
*
re-base on ALv2 code. Includes: Patches contributed by Herbert Duerr i#118735 prevent endless loop if vlookup/hlookup doesn't find anything http://svn.apache.org/viewvc?view=revision&revision=1239673 Patches contributed by Andre Fischer remove lp_solver http://svn.apache.org/viewvc?view=revision&revision=1199180 i#118160: Added external CoinMP library. http://svn.apache.org/viewvc?view=revision&revision=1233909 Patches contributed by Armin Le-Grand i#118485 - Styles for OLEs are not saved. http://svn.apache.org/viewvc?view=revision&revision=1182166 i#118524: apply patch, followup fixes to 118485 http://svn.apache.org/viewvc?view=revision&revision=1186077 Patches contributed by lihuiibm i#108860 - Fix range validation. http://svn.apache.org/viewvc?view=revision&revision=1242846 i#118954 Chart data will lost after copy to different file http://svn.apache.org/viewvc?view=revision&revision=1301345 Patches contributed by Ariel Constenla-Haile Fix Linux build breaker: extra qualification on member http://svn.apache.org/viewvc?view=revision&revision=1301591 i#118696 - i#118697 - Fix some Sheet Tab Color API issues http://svn.apache.org/viewvc?view=revision&revision=1225428 i#118697 - Fix uninitialized variable http://svn.apache.org/viewvc?view=revision&revision=1225859 i#118771 - ScUndoImportTab should preserve tab background color http://svn.apache.org/viewvc?view=revision&revision=1230356 i#118921 - Repaint linked sheet tab background color after updating link http://svn.apache.org/viewvc?view=revision&revision=1245177 i#118927 - Undo/Redo "Update Link" does not reset sheet tab color http://svn.apache.org/viewvc?view=revision&revision=1245241 i#118747 - Copy tab color when transferring sheets across documents http://svn.apache.org/viewvc?view=revision&revision=1230355 Patch contributed by Oliver Rainer-Wittman i#118012 - methods <ScBroadcastAreaSlot::AreaBroadcast(..)> and <ScBroadcastAreaSlot::AreaBroadcastInRange(..)> adapt stl-container iteration in order to avoid destroyed iterators during iteration. http://svn.apache.org/viewvc?view=revision&revision=1297916 Patches contributed by Mathias Bauer gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394707 http://svn.apache.org/viewvc?view=revision&revision=1394326 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1397315 Patch contributed by Daniel Rentz calc69: #i116936# fix VBA symbol Cells http://svn.apache.org/viewvc?view=revision&revision=1172135 Patches contributed by leiw: i#118546 CPU 100% on switched off AutoCalculate with Conditional Formatting on date values http://svn.apache.org/viewvc?view=revision&revision=1301380 Re-add new function documentation. Many various cleanups. Add missing calc66: #o11817313# also look at formula result number format, remove redundant binaries.
2012-11-30 12:23:25 +00:00
* This file incorporates work covered by the following license notice:
2000-09-18 16:07:07 +00:00
*
re-base on ALv2 code. Includes: Patches contributed by Herbert Duerr i#118735 prevent endless loop if vlookup/hlookup doesn't find anything http://svn.apache.org/viewvc?view=revision&revision=1239673 Patches contributed by Andre Fischer remove lp_solver http://svn.apache.org/viewvc?view=revision&revision=1199180 i#118160: Added external CoinMP library. http://svn.apache.org/viewvc?view=revision&revision=1233909 Patches contributed by Armin Le-Grand i#118485 - Styles for OLEs are not saved. http://svn.apache.org/viewvc?view=revision&revision=1182166 i#118524: apply patch, followup fixes to 118485 http://svn.apache.org/viewvc?view=revision&revision=1186077 Patches contributed by lihuiibm i#108860 - Fix range validation. http://svn.apache.org/viewvc?view=revision&revision=1242846 i#118954 Chart data will lost after copy to different file http://svn.apache.org/viewvc?view=revision&revision=1301345 Patches contributed by Ariel Constenla-Haile Fix Linux build breaker: extra qualification on member http://svn.apache.org/viewvc?view=revision&revision=1301591 i#118696 - i#118697 - Fix some Sheet Tab Color API issues http://svn.apache.org/viewvc?view=revision&revision=1225428 i#118697 - Fix uninitialized variable http://svn.apache.org/viewvc?view=revision&revision=1225859 i#118771 - ScUndoImportTab should preserve tab background color http://svn.apache.org/viewvc?view=revision&revision=1230356 i#118921 - Repaint linked sheet tab background color after updating link http://svn.apache.org/viewvc?view=revision&revision=1245177 i#118927 - Undo/Redo "Update Link" does not reset sheet tab color http://svn.apache.org/viewvc?view=revision&revision=1245241 i#118747 - Copy tab color when transferring sheets across documents http://svn.apache.org/viewvc?view=revision&revision=1230355 Patch contributed by Oliver Rainer-Wittman i#118012 - methods <ScBroadcastAreaSlot::AreaBroadcast(..)> and <ScBroadcastAreaSlot::AreaBroadcastInRange(..)> adapt stl-container iteration in order to avoid destroyed iterators during iteration. http://svn.apache.org/viewvc?view=revision&revision=1297916 Patches contributed by Mathias Bauer gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394707 http://svn.apache.org/viewvc?view=revision&revision=1394326 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1397315 Patch contributed by Daniel Rentz calc69: #i116936# fix VBA symbol Cells http://svn.apache.org/viewvc?view=revision&revision=1172135 Patches contributed by leiw: i#118546 CPU 100% on switched off AutoCalculate with Conditional Formatting on date values http://svn.apache.org/viewvc?view=revision&revision=1301380 Re-add new function documentation. Many various cleanups. Add missing calc66: #o11817313# also look at formula result number format, remove redundant binaries.
2012-11-30 12:23:25 +00:00
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
2000-09-18 16:07:07 +00:00
#include "scitems.hxx"
#include <comphelper/string.hxx>
#include <editeng/eeitem.hxx>
#include <sfx2/app.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/scripttypeitem.hxx>
2009-12-10 23:06:35 +01:00
#include <svl/srchitem.hxx>
2010-01-13 22:25:07 +01:00
#include <sfx2/linkmgr.hxx>
2000-09-18 16:07:07 +00:00
#include <sfx2/dispatch.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/objitem.hxx>
#include <sfx2/viewfrm.hxx>
#include <svl/stritem.hxx>
#include <svl/zforlist.hxx>
#include <svx/svdview.hxx>
2000-09-18 16:07:07 +00:00
#include <vcl/msgbox.hxx>
#include <vcl/waitobj.hxx>
#include <basic/sbstar.hxx>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
2000-09-18 16:07:07 +00:00
#include "viewfunc.hxx"
#include "sc.hrc"
#include "globstr.hrc"
#include "attrib.hxx"
#include "autoform.hxx"
#include "formulacell.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 "table.hxx"
2000-09-18 16:07:07 +00:00
#include "tablink.hxx"
#include "tabvwsh.hxx"
#include "uiitems.hxx"
#include "undoblk.hxx"
#include "undocell.hxx"
#include "undotab.hxx"
#include "sizedev.hxx"
#include "editable.hxx"
#include "scmod.hxx"
#include "inputhdl.hxx"
#include "inputwin.hxx"
#include "funcdesc.hxx"
#include "docuno.hxx"
#include "charthelper.hxx"
2010-02-23 22:28:33 -05:00
#include "tabbgcolor.hxx"
#include "clipparam.hxx"
#include "prnsave.hxx"
#include "searchresults.hxx"
#include "tokenarray.hxx"
#include <boost/scoped_ptr.hpp>
#include <vector>
#include <memory>
using namespace com::sun::star;
using ::editeng::SvxBorderLine;
using ::std::vector;
using ::std::auto_ptr;
// helper func defined in docfunc.cxx
void VBA_DeleteModule( ScDocShell& rDocSh, const OUString& sModuleName );
2000-09-18 16:07:07 +00:00
// STATIC DATA ---------------------------------------------------------------
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
if (!pMarkData)
pMarkData = &GetViewData()->GetMarkData();
ScDocument* pDoc = pDocSh->GetDocument();
SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges );
if (nRangeCnt == 0)
2000-09-18 16:07:07 +00:00
{
pRanges[0] = pRanges[1] = GetViewData()->GetCurY();
nRangeCnt = 1;
}
double nPPTX = GetViewData()->GetPPTX();
double nPPTY = GetViewData()->GetPPTY();
Fraction aZoomX = GetViewData()->GetZoomX();
Fraction aZoomY = GetViewData()->GetZoomY();
ScSizeDeviceProvider aProv(pDocSh);
if (aProv.IsPrinter())
{
nPPTX = aProv.GetPPTX();
nPPTY = aProv.GetPPTY();
aZoomX = aZoomY = Fraction( 1, 1 );
}
sal_Bool bAnyChanged = false;
ScMarkData::iterator itr = pMarkData->begin(), itrEnd = pMarkData->end();
for (; itr != itrEnd; ++itr)
{
SCTAB nTab = *itr;
SCCOLROW* pOneRange = pRanges;
sal_Bool bChanged = false;
SCROW nPaintY = 0;
for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
2000-09-18 16:07:07 +00:00
{
SCROW nStartNo = *(pOneRange++);
SCROW nEndNo = *(pOneRange++);
if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
nPPTX, nPPTY, aZoomX, aZoomY, false ))
2000-09-18 16:07:07 +00:00
{
if (!bChanged)
nPaintY = nStartNo;
bAnyChanged = bChanged = sal_True;
2000-09-18 16:07:07 +00:00
}
}
if ( bPaint && bChanged )
pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
PAINT_GRID | PAINT_LEFT );
2000-09-18 16:07:07 +00:00
}
delete[] pRanges;
if ( bPaint && bAnyChanged )
pDocSh->UpdateOle(GetViewData());
return bAnyChanged;
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, sal_Bool bPaint )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
double nPPTX = GetViewData()->GetPPTX();
double nPPTY = GetViewData()->GetPPTY();
Fraction aZoomX = GetViewData()->GetZoomX();
Fraction aZoomY = GetViewData()->GetZoomY();
sal_uInt16 nOldPixel = 0;
2000-09-18 16:07:07 +00:00
if (nStartRow == nEndRow)
nOldPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
2000-09-18 16:07:07 +00:00
ScSizeDeviceProvider aProv(pDocSh);
if (aProv.IsPrinter())
{
nPPTX = aProv.GetPPTX();
nPPTY = aProv.GetPPTY();
aZoomX = aZoomY = Fraction( 1, 1 );
}
sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
nPPTX, nPPTY, aZoomX, aZoomY, false );
2000-09-18 16:07:07 +00:00
if (bChanged && ( nStartRow == nEndRow ))
{
sal_uInt16 nNewPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
2000-09-18 16:07:07 +00:00
if ( nNewPixel == nOldPixel )
bChanged = false;
2000-09-18 16:07:07 +00:00
}
if ( bPaint && bChanged )
pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
2000-09-18 16:07:07 +00:00
PAINT_GRID | PAINT_LEFT );
return bChanged;
}
//----------------------------------------------------------------------------
enum ScAutoSum
{
ScAutoSumNone = 0,
ScAutoSumData,
ScAutoSumSum
};
static ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
2000-09-18 16:07:07 +00:00
{
ScRefCellValue aCell;
aCell.assign(*pDoc, ScAddress(nCol, nRow, nTab));
if (aCell.hasNumeric())
2000-09-18 16:07:07 +00:00
{
if (aCell.meType == CELLTYPE_FORMULA)
2000-09-18 16:07:07 +00:00
{
ScTokenArray* pCode = aCell.mpFormula->GetCode();
2000-09-18 16:07:07 +00:00
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
static ScAutoSum lcl_SeekAutoSumData( ScDocument* pDoc, SCCOL& nCol, SCROW& nRow,
SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
2000-09-18 16:07:07 +00:00
{
sal_uInt16 nCount = 0;
2000-09-18 16:07:07 +00:00
while (nCount < SC_AUTOSUM_MAXCOUNT)
{
if ( eDir == DIR_TOP )
{
if (nRow > 0)
2000-09-18 16:07:07 +00:00
--nRow;
else
return ScAutoSumNone;
}
else
{
if (nCol > 0)
2000-09-18 16:07:07 +00:00
--nCol;
else
return ScAutoSumNone;
}
ScAutoSum eSum;
if ( (eSum = lcl_IsAutoSumData(
pDoc, nCol, nRow, nTab, eDir, nExtend )) != ScAutoSumNone )
return eSum;
++nCount;
}
return ScAutoSumNone;
}
#undef SC_AUTOSUM_MAXCOUNT
//----------------------------------------------------------------------------
static 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;
}
//----------------------------------------------------------------------------
static 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;
}
//----------------------------------------------------------------------------
static 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;
}
//----------------------------------------------------------------------------
static bool lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
{
const ScAddress aStart = rRange.aStart;
const ScAddress aEnd = rRange.aEnd;
if ( aStart.Row() != aEnd.Row() )
{
return false;
}
const SCTAB nTab = aEnd.Tab();
const SCROW nRow = aEnd.Row();
SCCOL nEndCol = aEnd.Col();
SCCOL nStartCol = nEndCol;
SCCOLROW nExtend = 0;
const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ );
if ( eSum == ScAutoSumSum )
{
bool bContinue = false;
do
{
rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
nEndCol = static_cast< SCCOL >( nExtend );
if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, aStart.Col() ) ) == true )
{
nStartCol = nEndCol;
}
} while ( bContinue );
}
else
{
while ( nStartCol > aStart.Col() &&
lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ ) != ScAutoSumSum )
{
--nStartCol;
}
rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
}
return true;
}
2000-09-18 16:07:07 +00:00
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
2000-09-18 16:07:07 +00:00
{
ScDocument* pDoc = GetViewData()->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
SCCOL nCol = GetViewData()->GetCurX();
SCROW nRow = GetViewData()->GetCurY();
2000-09-18 16:07:07 +00:00
SCCOL nStartCol = nCol;
SCROW nStartRow = nRow;
SCCOL nEndCol = nCol;
SCROW nEndRow = nRow;
SCCOL nSeekCol = nCol;
SCROW nSeekRow = nRow;
SCCOLROW nExtend; // will become valid via reference for ScAutoSumSum
2000-09-18 16:07:07 +00:00
sal_Bool bCol = false;
sal_Bool bRow = false;
2000-09-18 16:07:07 +00:00
ScAutoSum eSum;
if ( nRow != 0
2000-09-18 16:07:07 +00:00
&& ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
DIR_TOP, nExtend /*out*/ )) == ScAutoSumData )
2000-09-18 16:07:07 +00:00
&& ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
2000-09-18 16:07:07 +00:00
)
{
bRow = sal_True;
2000-09-18 16:07:07 +00:00
nSeekRow = nRow - 1;
}
else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
2000-09-18 16:07:07 +00:00
{
bCol = sal_True;
2000-09-18 16:07:07 +00:00
nSeekCol = nCol - 1;
}
else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
bRow = sal_True;
else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
bCol = sal_True;
2000-09-18 16:07:07 +00:00
if ( bCol || bRow )
{
if ( bRow )
{
nStartRow = nSeekRow; // nSeekRow might be adjusted via reference
2000-09-18 16:07:07 +00:00
if ( eSum == ScAutoSumSum )
nEndRow = nStartRow; // only sum sums
2000-09-18 16:07:07 +00:00
else
nEndRow = nRow - 1; // maybe extend data area at bottom
2000-09-18 16:07:07 +00:00
}
else
{
nStartCol = nSeekCol; // nSeekCol might be adjusted vie reference
2000-09-18 16:07:07 +00:00
if ( eSum == ScAutoSumSum )
nEndCol = nStartCol; // only sum sums
2000-09-18 16:07:07 +00:00
else
nEndCol = nCol - 1; // maybe extend data area to the right
2000-09-18 16:07:07 +00:00
}
sal_Bool bContinue = false;
2000-09-18 16:07:07 +00:00
do
{
if ( eSum == ScAutoSumData )
{
if ( bRow )
{
while ( nStartRow != 0 && lcl_IsAutoSumData( pDoc, nCol,
nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
2000-09-18 16:07:07 +00:00
--nStartRow;
}
else
{
while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1,
nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum )
2000-09-18 16:07:07 +00:00
--nStartCol;
}
}
rRangeList.Append(
ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) );
if ( eSum == ScAutoSumSum )
{
if ( bRow )
{
nEndRow = static_cast< SCROW >( nExtend );
if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, 0 ) ) == true )
2000-09-18 16:07:07 +00:00
{
nStartRow = nEndRow;
}
}
else
{
nEndCol = static_cast< SCCOL >( nExtend );
if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true )
2000-09-18 16:07:07 +00:00
{
nStartCol = nEndCol;
}
}
}
} while ( bContinue );
return sal_True;
2000-09-18 16:07:07 +00:00
}
return false;
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr)
{
OUString 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 OUString 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 OUString 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;
}
//----------------------------------------------------------------------------
OUString ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr )
{
ScViewData* pViewData = GetViewData();
ScDocument* pDoc = pViewData->GetDocument();
::boost::scoped_ptr<ScTokenArray> pArray(new ScTokenArray);
pArray->AddOpCode(bSubTotal ? ocSubTotal : ocSum);
pArray->AddOpCode(ocOpen);
if (bSubTotal)
{
pArray->AddDouble(9);
pArray->AddOpCode(ocSep);
}
if(!rRangeList.empty())
{
ScRangeList aRangeList = rRangeList;
const ScRange* pFirst = aRangeList.front();
size_t ListSize = aRangeList.size();
for ( size_t i = 0; i < ListSize; ++i )
{
const ScRange* p = aRangeList[i];
if (p != pFirst)
pArray->AddOpCode(ocSep);
ScComplexRefData aRef;
aRef.InitRangeRel(*p, rAddr);
pArray->AddDoubleReference(aRef);
}
}
pArray->AddOpCode(ocClose);
ScCompiler aComp(pDoc, rAddr, *pArray);
aComp.SetGrammar(pDoc->GetGrammar());
OUStringBuffer aBuf;
aComp.CreateStringFromTokenArray(aBuf);
OUString aFormula = aBuf.makeStringAndClear();
aBuf.append(sal_Unicode('='));
aBuf.append(aFormula);
return aBuf.makeStringAndClear();
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::EnterBlock( const OUString& rString, const EditTextObject* pData )
2000-09-18 16:07:07 +00:00
{
// test for multi selection
2000-09-18 16:07:07 +00:00
SCCOL nCol = GetViewData()->GetCurX();
SCROW nRow = GetViewData()->GetCurY();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
ScMarkData& rMark = GetViewData()->GetMarkData();
if ( rMark.IsMultiMarked() )
{
rMark.MarkToSimple();
if ( rMark.IsMultiMarked() )
{ // "Insert into multi selection not possible"
2000-09-18 16:07:07 +00:00
ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
// insert into single cell
if ( pData )
EnterData(nCol, nRow, nTab, *pData);
2000-09-18 16:07:07 +00:00
else
EnterData( nCol, nRow, nTab, rString );
return;
}
}
ScDocument* pDoc = GetViewData()->GetDocument();
OUString aNewStr = rString;
2000-09-18 16:07:07 +00:00
if ( pData )
{
const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
aEngine.SetText(*pData);
ScEditAttrTester aTester( &aEngine );
if (!aTester.NeedsObject())
{
aNewStr = aEngine.GetText();
pData = NULL;
}
}
// Insert via PasteFromClip
2000-09-18 16:07:07 +00:00
WaitObject aWait( GetFrameWin() );
ScAddress aPos( nCol, nRow, nTab );
ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
pInsDoc->ResetClip( pDoc, nTab );
if (aNewStr[0] == '=') // Formula ?
2000-09-18 16:07:07 +00:00
{
// SetString not possible, because in Clipboard-Documents nothing will be compiled!
pInsDoc->SetFormulaCell(aPos, new ScFormulaCell(pDoc, aPos, aNewStr));
2000-09-18 16:07:07 +00:00
}
else if ( pData )
{
// A copy of pData will be stored.
pInsDoc->SetEditText(aPos, *pData, pDoc->GetEditPool());
}
2000-09-18 16:07:07 +00:00
else
pInsDoc->SetString( nCol, nRow, nTab, aNewStr );
pInsDoc->SetClipArea( ScRange(aPos) );
// insert Block, with Undo etc.
if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, false, false,
false, INS_NONE, IDF_ATTRIB ) )
2000-09-18 16:07:07 +00:00
{
const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr(
nCol, nRow, nTab, ATTR_VALUE_FORMAT );
if ( pItem )
{ // set number format if incompatible
// MarkData was already MarkToSimple'ed in PasteFromClip
2000-09-18 16:07:07 +00:00
ScRange aRange;
rMark.GetMarkArea( aRange );
ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() );
pPattern->GetItemSet().Put( *pItem );
short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() );
pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark,
*pPattern, nNewType );
delete pPattern;
}
}
delete pInsDoc;
}
//----------------------------------------------------------------------------
// manual page break
2000-09-18 16:07:07 +00:00
void ScViewFunc::InsertPageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
sal_Bool bSetModified )
2000-09-18 16:07:07 +00:00
{
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
ScAddress aCursor;
if (pPos)
aCursor = *pPos;
else
aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, false );
2000-09-18 16:07:07 +00:00
if ( bSuccess && bSetModified )
UpdatePageBreakData( true ); // for PageBreak-Mode
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::DeletePageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
sal_Bool bSetModified )
2000-09-18 16:07:07 +00:00
{
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
ScAddress aCursor;
if (pPos)
aCursor = *pPos;
else
aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, false );
2000-09-18 16:07:07 +00:00
if ( bSuccess && bSetModified )
UpdatePageBreakData( true ); // for PageBreak-Mode
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::RemoveManualBreaks()
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
sal_Bool bUndo(pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
if (bUndo)
{
ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, false, pUndoDoc );
pDocSh->GetUndoManager()->AddUndoAction(
2000-09-18 16:07:07 +00:00
new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
}
2000-09-18 16:07:07 +00:00
pDoc->RemoveManualBreaks(nTab);
pDoc->UpdatePageBreaks(nTab);
UpdatePageBreakData( sal_True );
2000-09-18 16:07:07 +00:00
pDocSh->SetDocumentModified();
pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
}
//----------------------------------------------------------------------------
void ScViewFunc::SetPrintZoom(sal_uInt16 nScale, sal_uInt16 nPages)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
pDocSh->SetPrintZoom( nTab, nScale, nPages );
}
void ScViewFunc::AdjustPrintZoom()
{
ScRange aRange;
if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
2000-09-18 16:07:07 +00:00
GetViewData()->GetMarkData().GetMultiMarkArea( aRange );
GetViewData()->GetDocShell()->AdjustPrintZoom( aRange );
}
//----------------------------------------------------------------------------
void ScViewFunc::SetPrintRanges( sal_Bool bEntireSheet, const OUString* pPrint,
const OUString* pRepCol, const OUString* pRepRow,
sal_Bool bAddPrint )
2000-09-18 16:07:07 +00:00
{
// on all selected tables
2000-09-18 16:07:07 +00:00
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
SCTAB nTab;
sal_Bool bUndo (pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd; ++itr)
{
nTab = *itr;
ScRange aRange( 0,0,nTab );
// print ranges
if( !bAddPrint )
pDoc->ClearPrintRanges( nTab );
if( bEntireSheet )
{
pDoc->SetPrintEntireSheet( nTab );
}
else if ( pPrint )
{
if ( !pPrint->isEmpty() )
{
const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep);
sal_uInt16 nTCount = comphelper::string::getTokenCount(*pPrint, sep);
for (sal_uInt16 i=0; i<nTCount; i++)
{
OUString aToken = pPrint->getToken(i, sep);
if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID )
pDoc->AddPrintRange( nTab, aRange );
}
2000-09-18 16:07:07 +00:00
}
}
else // NULL = use selection (print range is always set), use empty string to delete all ranges
{
if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
2000-09-18 16:07:07 +00:00
{
pDoc->AddPrintRange( nTab, aRange );
}
else if ( rMark.IsMultiMarked() )
{
rMark.MarkToMulti();
ScRangeListRef pList( new ScRangeList );
rMark.FillRangeListWithMarks( pList, false );
for (size_t i = 0, n = pList->size(); i < n; ++i)
{
ScRange* pR = (*pList)[i];
pDoc->AddPrintRange(nTab, *pR);
2000-09-18 16:07:07 +00:00
}
}
}
2000-09-18 16:07:07 +00:00
// repeat columns
2000-09-18 16:07:07 +00:00
if ( pRepCol )
{
if ( pRepCol->isEmpty() )
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->isEmpty() )
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 ) );
}
else
delete pOldRanges;
2000-09-18 16:07:07 +00:00
// update page breaks
itr = rMark.begin();
for (; itr != itrEnd; ++itr)
ScPrintFunc( pDocSh, pDocSh->GetPrinter(), *itr ).UpdatePages();
2000-09-18 16:07:07 +00:00
2000-09-22 17:57:10 +00:00
SfxBindings& rBindings = GetViewData()->GetBindings();
2000-09-18 16:07:07 +00:00
rBindings.Invalidate( SID_DELETE_PRINTAREA );
pDocSh->SetDocumentModified();
}
//----------------------------------------------------------------------------
// Merge cells
2000-09-18 16:07:07 +00:00
sal_Bool ScViewFunc::TestMergeCells() // pre-test (for menu)
2000-09-18 16:07:07 +00:00
{
// simple test: sal_True if there's a selection but no multi selection and not filtered
const ScMarkData& rMark = GetViewData()->GetMarkData();
if ( rMark.IsMarked() || rMark.IsMultiMarked() )
{
ScRange aDummy;
return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE;
}
else
return false;
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::MergeCells( sal_Bool bApi, sal_Bool& rDoContents, sal_Bool bRecord, sal_Bool bCenter )
2000-09-18 16:07:07 +00:00
{
// Editable- and Being-Nested- test must be at the beginning (in DocFunc too),
// so that the Contents-QueryBox won't appear
ScEditableTester aTester( this );
if (!aTester.IsEditable())
2000-09-18 16:07:07 +00:00
{
ErrorMessage(aTester.GetMessageId());
return false;
2000-09-18 16:07:07 +00:00
}
ScMarkData& rMark = GetViewData()->GetMarkData();
rMark.MarkToSimple();
if (!rMark.IsMarked())
{
ErrorMessage(STR_NOMULTISELECT);
return false;
2000-09-18 16:07:07 +00:00
}
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScRange aMarkRange;
rMark.GetMarkArea( aMarkRange );
SCCOL nStartCol = aMarkRange.aStart.Col();
SCROW nStartRow = aMarkRange.aStart.Row();
SCTAB nStartTab = aMarkRange.aStart.Tab();
SCCOL nEndCol = aMarkRange.aEnd.Col();
SCROW nEndRow = aMarkRange.aEnd.Row();
SCTAB nEndTab = aMarkRange.aEnd.Tab();
2000-09-18 16:07:07 +00:00
if ( nStartCol == nEndCol && nStartRow == nEndRow )
{
// nothing to do
return true;
2000-09-18 16:07:07 +00:00
}
if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
HASATTR_MERGED | HASATTR_OVERLAPPED ) )
{ // "Don't nest merging !"
2000-09-18 16:07:07 +00:00
ErrorMessage(STR_MSSG_MERGECELLS_0);
return false;
2000-09-18 16:07:07 +00:00
}
// Check for the contents of all selected tables.
bool bAskDialog = false;
ScCellMergeOption aMergeOption(nStartCol, nStartRow, nEndCol, nEndRow, bCenter);
ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd; ++itr)
{
SCTAB i = *itr;
aMergeOption.maTabs.insert(i);
if (!pDoc->IsBlockEmpty(i, nStartCol, nStartRow+1, nStartCol, nEndRow) ||
!pDoc->IsBlockEmpty(i, nStartCol+1, nStartRow, nEndCol, nEndRow))
bAskDialog = true;
}
sal_Bool bOk = true;
2000-09-18 16:07:07 +00:00
if (bAskDialog)
2000-09-18 16:07:07 +00:00
{
if (!bApi)
{
MessBox aBox( GetViewData()->GetDialogParent(),
WinBits(WB_YES_NO_CANCEL | WB_DEF_NO),
ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
ScGlobal::GetRscString( STR_MERGE_NOTEMPTY ) );
sal_uInt16 nRetVal = aBox.Execute();
2000-09-18 16:07:07 +00:00
if ( nRetVal == RET_YES )
rDoContents = sal_True;
2000-09-18 16:07:07 +00:00
else if ( nRetVal == RET_CANCEL )
bOk = false;
2000-09-18 16:07:07 +00:00
}
}
if (bOk)
{
bOk = pDocSh->GetDocFunc().MergeCells( aMergeOption, rDoContents, bRecord, bApi );
2000-09-18 16:07:07 +00:00
if (bOk)
{
SetCursor( nStartCol, nStartRow );
//DoneBlockMode( sal_False);
2000-09-18 16:07:07 +00:00
Unmark();
pDocSh->UpdateOle(GetViewData());
UpdateInputLine();
}
}
return bOk;
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::TestRemoveMerge()
2000-09-18 16:07:07 +00:00
{
sal_Bool bMerged = false;
2000-09-18 16:07:07 +00:00
ScRange aRange;
if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocument* pDoc = GetViewData()->GetDocument();
if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
bMerged = sal_True;
2000-09-18 16:07:07 +00:00
}
return bMerged;
}
//----------------------------------------------------------------------------
static bool lcl_extendMergeRange(ScCellMergeOption& rOption, const ScRange& rRange)
{
bool bExtended = false;
if (rOption.mnStartCol > rRange.aStart.Col())
{
rOption.mnStartCol = rRange.aStart.Col();
bExtended = true;
}
if (rOption.mnStartRow > rRange.aStart.Row())
{
rOption.mnStartRow = rRange.aStart.Row();
bExtended = true;
}
if (rOption.mnEndCol < rRange.aEnd.Col())
{
rOption.mnEndCol = rRange.aEnd.Col();
bExtended = true;
}
if (rOption.mnEndRow < rRange.aEnd.Row())
{
rOption.mnEndRow = rRange.aEnd.Row();
bExtended = true;
}
return bExtended;
}
sal_Bool ScViewFunc::RemoveMerge( sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScRange aRange;
ScEditableTester aTester( this );
if (!aTester.IsEditable())
{
ErrorMessage(aTester.GetMessageId());
return false;
}
else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocument* pDoc = GetViewData()->GetDocument();
ScRange aExtended( aRange );
pDoc->ExtendMerge( aExtended );
2000-09-18 16:07:07 +00:00
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScMarkData& rMark = GetViewData()->GetMarkData();
ScCellMergeOption aOption(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row());
bool bExtended = false;
do
{
bExtended = false;
2011-07-05 13:35:56 +01:00
ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd; ++itr)
{
SCTAB i = *itr;
aOption.maTabs.insert(i);
aExtended.aStart.SetTab(i);
aExtended.aEnd.SetTab(i);
pDoc->ExtendMerge(aExtended);
pDoc->ExtendOverlapped(aExtended);
// Expand the current range to be inclusive of all merged
// areas on all sheets.
bExtended = lcl_extendMergeRange(aOption, aExtended);
}
}
while (bExtended);
sal_Bool bOk = pDocSh->GetDocFunc().UnmergeCells(aOption, bRecord );
aExtended = aOption.getFirstSingleRange();
MarkRange( aExtended );
2000-09-18 16:07:07 +00:00
if (bOk)
pDocSh->UpdateOle(GetViewData());
}
return sal_True; //! bOk ??
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::FillSimple( FillDir eDir, bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScRange aRange;
if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScMarkData& rMark = GetViewData()->GetMarkData();
bool bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
{
pDocSh->UpdateOle(GetViewData());
UpdateScrollBars();
}
}
else
ErrorMessage(STR_NOMULTISELECT);
}
//----------------------------------------------------------------------------
void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
double fStart, double fStep, double fMax, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScRange aRange;
if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScMarkData& rMark = GetViewData()->GetMarkData();
sal_Bool bSuccess = pDocSh->GetDocFunc().
2000-09-18 16:07:07 +00:00
FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
fStart, fStep, fMax, bRecord, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
{
pDocSh->UpdateOle(GetViewData());
UpdateScrollBars();
// #i97876# Spreadsheet data changes are not notified
ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
if ( pModelObj && pModelObj->HasChangesListeners() )
{
ScRangeList aChangeRanges;
aChangeRanges.Append( aRange );
pModelObj->NotifyChanges( OUString( "cell-change" ), aChangeRanges );
}
2000-09-18 16:07:07 +00:00
}
}
else
ErrorMessage(STR_NOMULTISELECT);
}
//----------------------------------------------------------------------------
void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
SCCOL nEndCol, SCROW nEndRow, sal_uLong nCount, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab );
ScRange aSourceRange( aRange );
2000-09-18 16:07:07 +00:00
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScMarkData& rMark = GetViewData()->GetMarkData();
sal_Bool bSuccess = pDocSh->GetDocFunc().
FillAuto( aRange, &rMark, eDir, nCount, bRecord, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
{
MarkRange( aRange, false ); // aRange was modified in FillAuto
2000-09-18 16:07:07 +00:00
pDocSh->UpdateOle(GetViewData());
UpdateScrollBars();
// #i97876# Spreadsheet data changes are not notified
ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
if ( pModelObj && pModelObj->HasChangesListeners() )
{
ScRangeList aChangeRanges;
ScRange aChangeRange( aRange );
switch ( eDir )
{
case FILL_TO_BOTTOM:
{
aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 );
}
break;
case FILL_TO_TOP:
{
aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 );
}
break;
case FILL_TO_RIGHT:
{
aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 );
}
break;
case FILL_TO_LEFT:
{
aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 );
}
break;
default:
{
}
break;
}
aChangeRanges.Append( aChangeRange );
pModelObj->NotifyChanges( OUString( "cell-change" ), aChangeRanges );
}
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
void ScViewFunc::FillTab( sal_uInt16 nFlags, sal_uInt16 nFunction, sal_Bool bSkipEmpty, sal_Bool bAsLink )
2000-09-18 16:07:07 +00:00
{
//! allow source sheet to be protected
ScEditableTester aTester( this );
if (!aTester.IsEditable())
2000-09-18 16:07:07 +00:00
{
ErrorMessage(aTester.GetMessageId());
2000-09-18 16:07:07 +00:00
return;
}
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
SCTAB nTab = GetViewData()->GetTabNo();
sal_Bool bUndo(pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
ScRange aMarkRange;
rMark.MarkToSimple();
sal_Bool bMulti = rMark.IsMultiMarked();
2000-09-18 16:07:07 +00:00
if (bMulti)
rMark.GetMultiMarkArea( aMarkRange );
else if (rMark.IsMarked())
rMark.GetMarkArea( aMarkRange );
else
aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
ScDocument* pUndoDoc = NULL;
2011-01-16 19:11:44 +01:00
if (bUndo)
2000-09-18 16:07:07 +00:00
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab );
ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd; ++itr)
if (*itr != nTab )
2000-09-18 16:07:07 +00:00
{
SCTAB i = *itr;
2000-09-18 16:07:07 +00:00
pUndoDoc->AddUndoTab( i, i );
aMarkRange.aStart.SetTab( i );
aMarkRange.aEnd.SetTab( i );
pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc );
}
}
if (bMulti)
pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
else
{
aMarkRange.aStart.SetTab( nTab );
aMarkRange.aEnd.SetTab( nTab );
pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
}
if (bUndo)
{ //! for ChangeTrack not until the end
2000-09-18 16:07:07 +00:00
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoFillTable( pDocSh, rMark,
aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab,
aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab,
pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) );
}
pDocSh->PostPaintGridAll();
pDocSh->PostDataChanged();
}
2001-03-26 18:26:30 +00:00
//----------------------------------------------------------------------------
/** Downward fill of selected cell(s) by double-clicking cross-hair cursor
Extends a current selection down to the last non-empty cell of an adjacent
column when the lower-right corner of the selection is double-clicked. It
uses a left-adjoining non-empty column as a guide if such is available,
otherwise a right-adjoining non-empty column is used.
@author Kohei Yoshida (kohei@openoffice.org)
@return No return value
@see #i12313#
*/
void ScViewFunc::FillCrossDblClick()
{
ScRange aRange;
GetViewData()->GetSimpleArea( aRange );
aRange.Justify();
SCTAB nTab = GetViewData()->GetCurPos().Tab();
SCCOL nStartX = aRange.aStart.Col();
SCROW nStartY = aRange.aStart.Row();
SCCOL nEndX = aRange.aEnd.Col();
SCROW nEndY = aRange.aEnd.Row();
ScDocument* pDoc = GetViewData()->GetDocument();
// Make sure the selection is not empty
if ( pDoc->IsBlockEmpty( nTab, nStartX, nStartY, nEndX, nEndY ) )
return;
if ( nEndY < MAXROW )
{
if ( nStartX > 0 )
{
SCCOL nMovX = nStartX - 1;
SCROW nMovY = nStartY;
if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
pDoc->HasData( nMovX, nStartY + 1, nTab ) )
{
pDoc->FindAreaPos( nMovX, nMovY, nTab, SC_MOVE_DOWN );
if ( nMovY > nEndY )
{
FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
nMovY - nEndY );
return;
}
}
}
if ( nEndX < MAXCOL )
{
SCCOL nMovX = nEndX + 1;
SCROW nMovY = nStartY;
if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
pDoc->HasData( nMovX, nStartY + 1, nTab ) )
{
pDoc->FindAreaPos( nMovX, nMovY, nTab, SC_MOVE_DOWN );
if ( nMovY > nEndY )
{
FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
nMovY - nEndY );
return;
}
}
}
}
}
//----------------------------------------------------------------------------
2001-03-26 18:26:30 +00:00
void ScViewFunc::TransliterateText( sal_Int32 nType )
{
ScMarkData aFuncMark = GetViewData()->GetMarkData();
if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
{
// no selection -> use cursor position
ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
aFuncMark.SetMarkArea( ScRange( aCursor ) );
}
sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
TransliterateText( aFuncMark, nType, sal_True, false );
2001-03-26 18:26:30 +00:00
if (bSuccess)
{
GetViewData()->GetViewShell()->UpdateInputHandler();
}
}
2000-09-18 16:07:07 +00:00
//----------------------------------------------------------------------------
// AutoFormat
ScAutoFormatData* ScViewFunc::CreateAutoFormatData()
{
ScAutoFormatData* pData = NULL;
SCCOL nStartCol;
SCROW nStartRow;
SCTAB nStartTab;
SCCOL nEndCol;
SCROW nEndRow;
SCTAB nEndTab;
if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
if ( nEndCol-nStartCol >= 3 && nEndRow-nStartRow >= 3 )
{
ScDocument* pDoc = GetViewData()->GetDocument();
pData = new ScAutoFormatData;
pDoc->GetAutoFormatData( nStartTab, nStartCol,nStartRow,nEndCol,nEndRow, *pData );
}
}
return pData;
}
//----------------------------------------------------------------------------
void ScViewFunc::AutoFormat( sal_uInt16 nFormatNo, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScRange aRange;
if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScMarkData& rMark = GetViewData()->GetMarkData();
sal_Bool bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
pDocSh->UpdateOle(GetViewData());
}
else
ErrorMessage(STR_NOMULTISELECT);
}
//----------------------------------------------------------------------------
// Suchen & Ersetzen
void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
sal_Bool bAddUndo, sal_Bool bIsApi )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
if (bAddUndo && !pDoc->IsUndoEnabled())
bAddUndo = false;
2000-09-18 16:07:07 +00:00
SCCOL nCol, nOldCol;
SCROW nRow, nOldRow;
SCTAB nTab, nOldTab;
nCol = nOldCol = GetViewData()->GetCurX();
nRow = nOldRow = GetViewData()->GetCurY();
nTab = nOldTab = GetViewData()->GetTabNo();
sal_uInt16 nCommand = pSearchItem->GetCommand();
bool bAllTables = pSearchItem->IsAllTables();
std::set<SCTAB> aOldSelectedTables;
SCTAB nLastTab = pDoc->GetTableCount() - 1;
SCTAB nStartTab, nEndTab;
2000-09-18 16:07:07 +00:00
if ( bAllTables )
{
nStartTab = 0;
nEndTab = nLastTab;
std::set<SCTAB> aTmp(rMark.begin(), rMark.end());
aOldSelectedTables.swap(aTmp);
2000-09-18 16:07:07 +00:00
}
else
{ //! at least one is always selected
nStartTab = rMark.GetFirstSelected();
nEndTab = rMark.GetLastSelected();
2000-09-18 16:07:07 +00:00
}
if ( nCommand == SVX_SEARCHCMD_FIND
|| nCommand == SVX_SEARCHCMD_FIND_ALL)
bAddUndo = false;
2000-09-18 16:07:07 +00:00
//! account for bAttrib during Undo !!!
2000-09-18 16:07:07 +00:00
SAL_WNODEPRECATED_DECLARATIONS_PUSH
2011-09-19 20:19:16 -04:00
std::auto_ptr<ScDocument> pUndoDoc;
std::auto_ptr<ScMarkData> pUndoMark;
SAL_WNODEPRECATED_DECLARATIONS_POP
OUString aUndoStr;
2000-09-18 16:07:07 +00:00
if (bAddUndo)
{
2011-09-19 20:19:16 -04:00
pUndoMark.reset(new ScMarkData(rMark)); // Mark is being modified
2000-09-18 16:07:07 +00:00
if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
{
2011-09-19 20:19:16 -04:00
pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
2000-09-18 16:07:07 +00:00
pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
}
}
if ( bAllTables )
{ //! select all, after pUndoMark has been created
for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
2000-09-18 16:07:07 +00:00
{
2011-09-19 20:19:16 -04:00
rMark.SelectTable( j, true );
2000-09-18 16:07:07 +00:00
}
}
DoneBlockMode(true); // don't delete mark
2000-09-18 16:07:07 +00:00
InitOwnBlockMode();
// If search starts at the beginning don't ask again whether it shall start at the beginning
2011-09-19 20:19:16 -04:00
bool bFirst = true;
2000-09-18 16:07:07 +00:00
if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() )
bFirst = false;
2000-09-18 16:07:07 +00:00
bool bFound = false;
while (true)
2000-09-18 16:07:07 +00:00
{
GetFrameWin()->EnterWait();
ScRangeList aMatchedRanges;
2011-09-19 20:19:16 -04:00
if (pDoc->SearchAndReplace(*pSearchItem, nCol, nRow, nTab, rMark, aMatchedRanges, aUndoStr, pUndoDoc.get()))
2000-09-18 16:07:07 +00:00
{
2011-09-19 20:19:16 -04:00
bFound = true;
bFirst = true;
2000-09-18 16:07:07 +00:00
if (bAddUndo)
{
GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
nCol, nRow, nTab,
2011-09-19 20:19:16 -04:00
aUndoStr, pUndoDoc.release(), pSearchItem ) );
2000-09-18 16:07:07 +00:00
}
if (nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL)
{
static SearchResults *aSearchResults = new SearchResults(pDoc);
aSearchResults->Show(aMatchedRanges);
rMark.ResetMark();
for (size_t i = 0, n = aMatchedRanges.size(); i < n; ++i)
{
const ScRange& r = *aMatchedRanges[i];
if (r.aStart.Tab() == nTab)
rMark.SetMultiMarkArea(r);
}
}
break; // break 'while (TRUE)'
2000-09-18 16:07:07 +00:00
}
else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
nCommand == SVX_SEARCHCMD_REPLACE) )
{
bFirst = false;
sal_uInt16 nRetVal;
2000-09-18 16:07:07 +00:00
GetFrameWin()->LeaveWait();
if ( bIsApi )
nRetVal = RET_NO;
else
{
// search dialog as parent (if available)
2000-09-18 16:07:07 +00:00
Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
sal_uInt16 nStrId;
2000-09-18 16:07:07 +00:00
if ( pSearchItem->GetBackward() )
{
if ( nStartTab == nEndTab )
nStrId = STR_MSSG_SEARCHANDREPLACE_1;
else
nStrId = STR_MSSG_SEARCHANDREPLACE_4;
}
else
{
if ( nStartTab == nEndTab )
nStrId = STR_MSSG_SEARCHANDREPLACE_2;
else
nStrId = STR_MSSG_SEARCHANDREPLACE_5;
}
MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
ScGlobal::GetRscString( nStrId ) );
nRetVal = aBox.Execute();
}
if ( nRetVal == RET_YES )
{
ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
if (pSearchItem->GetBackward())
nTab = nEndTab;
else
nTab = nStartTab;
}
else
{
break; // break 'while (TRUE)'
2000-09-18 16:07:07 +00:00
}
}
else // nothing found
2000-09-18 16:07:07 +00:00
{
if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
{
pDocSh->PostPaintGridAll(); // Mark
2000-09-18 16:07:07 +00:00
}
GetFrameWin()->LeaveWait();
if (!bIsApi)
{
// search dialog as parent if available
2000-09-18 16:07:07 +00:00
Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
// "nothing found"
2000-09-18 16:07:07 +00:00
InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
aBox.Execute();
}
break; // break 'while (TRUE)'
2000-09-18 16:07:07 +00:00
}
2011-09-19 20:53:18 -04:00
} // of while true
2000-09-18 16:07:07 +00:00
if (!aOldSelectedTables.empty())
{
// restore originally selected table
for (SCTAB i = 0; i <= nEndTab; ++i)
rMark.SelectTable(i, false);
std::set<SCTAB>::const_iterator itr = aOldSelectedTables.begin(), itrEnd = aOldSelectedTables.end();
for (; itr != itrEnd; ++itr)
rMark.SelectTable(*itr, true);
2000-09-18 16:07:07 +00:00
if ( bFound )
{ // if a table is selected as a "match" it remains selected.
rMark.SelectTable( nTab, true );
// It's a swap if only one table was selected before
//! otherwise now one table more might be selected
if ( aOldSelectedTables.size() == 1 && nTab != nOldTab )
rMark.SelectTable( nOldTab, false );
2000-09-18 16:07:07 +00:00
}
}
MarkDataChanged();
2000-09-18 16:07:07 +00:00
if ( bFound )
{
if ( nTab != GetViewData()->GetTabNo() )
SetTabNo( nTab );
// if nothing is marked, DoneBlockMode, then marking can start
// directly from this place via Shift-Cursor
2000-09-18 16:07:07 +00:00
if (!rMark.IsMarked() && !rMark.IsMultiMarked())
2011-09-19 20:53:18 -04:00
DoneBlockMode(true);
2000-09-18 16:07:07 +00:00
AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
2011-09-19 20:19:16 -04:00
SetCursor( nCol, nRow, true );
2000-09-18 16:07:07 +00:00
if ( nCommand == SVX_SEARCHCMD_REPLACE
|| nCommand == SVX_SEARCHCMD_REPLACE_ALL )
{
if ( nCommand == SVX_SEARCHCMD_REPLACE )
{
2000-09-18 16:07:07 +00:00
pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
// jump to next cell if we replaced everything in the cell
// where the cursor was positioned (but avoid switching tabs)
if ( nCol == nOldCol && nRow == nOldRow && nTab == nOldTab )
{
SvxSearchItem aSearchItem = ScGlobal::GetSearchItem();
aSearchItem.SetCommand(SVX_SEARCHCMD_FIND);
aSearchItem.SetWhich(SID_SEARCH_ITEM);
ScRangeList aMatchedRanges;
ScTable::UpdateSearchItemAddressForReplace( aSearchItem, nCol, nRow );
if ( pDoc->SearchAndReplace( aSearchItem, nCol, nRow, nTab, rMark, aMatchedRanges, aUndoStr, NULL ) &&
( nTab == nOldTab ) &&
( nCol != nOldCol || nRow != nOldRow ) )
{
SetCursor( nCol, nRow, true );
}
}
}
2000-09-18 16:07:07 +00:00
else
pDocSh->PostPaintGridAll();
pDocSh->SetDocumentModified();
}
else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
pDocSh->PostPaintGridAll(); // mark
2000-09-18 16:07:07 +00:00
GetFrameWin()->LeaveWait();
}
}
//----------------------------------------------------------------------------
// Zielwertsuche
void ScViewFunc::Solve( const ScSolveParam& rParam )
{
ScDocument* pDoc = GetViewData()->GetDocument();
SCCOL nDestCol = rParam.aRefVariableCell.Col();
SCROW nDestRow = rParam.aRefVariableCell.Row();
SCTAB nDestTab = rParam.aRefVariableCell.Tab();
2000-09-18 16:07:07 +00:00
ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
if (!aTester.IsEditable())
2000-09-18 16:07:07 +00:00
{
ErrorMessage(aTester.GetMessageId());
2000-09-18 16:07:07 +00:00
return;
}
if ( pDoc )
{
OUString aTargetValStr;
2000-09-18 16:07:07 +00:00
if ( rParam.pStrTargetVal != NULL )
aTargetValStr = *(rParam.pStrTargetVal);
OUString aMsgStr;
OUString aResStr;
2000-09-18 16:07:07 +00:00
double nSolveResult;
GetFrameWin()->EnterWait();
sal_Bool bExact =
2000-09-18 16:07:07 +00:00
pDoc->Solver(
rParam.aRefFormulaCell.Col(),
rParam.aRefFormulaCell.Row(),
rParam.aRefFormulaCell.Tab(),
nDestCol, nDestRow, nDestTab,
aTargetValStr,
nSolveResult );
GetFrameWin()->LeaveWait();
SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
sal_uLong nFormat = 0;
2000-09-18 16:07:07 +00:00
const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
if ( pPattern )
nFormat = pPattern->GetNumberFormat( pFormatter );
Color* p;
pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );
if ( bExact )
{
aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
aMsgStr += aResStr;
aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
2000-09-18 16:07:07 +00:00
}
else
{
aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
aMsgStr += aResStr ;
aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
2000-09-18 16:07:07 +00:00
}
MessBox aBox( GetViewData()->GetDialogParent(),
WinBits(WB_YES_NO | WB_DEF_NO),
ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
sal_uInt16 nRetVal = aBox.Execute();
2000-09-18 16:07:07 +00:00
if ( RET_YES == nRetVal )
EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
2000-09-18 16:07:07 +00:00
GetViewData()->GetViewShell()->UpdateInputHandler( sal_True );
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
// multi operation
2000-09-18 16:07:07 +00:00
void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScRange aRange;
if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScMarkData& rMark = GetViewData()->GetMarkData();
pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, false );
2000-09-18 16:07:07 +00:00
}
else
ErrorMessage(STR_NOMULTISELECT);
}
//----------------------------------------------------------------------------
void ScViewFunc::MakeScenario( const OUString& rName, const OUString& rComment,
const Color& rColor, sal_uInt16 nFlags )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScMarkData& rMark = GetViewData()->GetMarkData();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
2000-09-18 16:07:07 +00:00
if (nFlags & SC_SCENARIO_COPYALL)
SetTabNo( nNewTab, true ); // SC_SCENARIO_COPYALL -> visible
2000-09-18 16:07:07 +00:00
else
{
2000-09-22 17:57:10 +00:00
SfxBindings& rBindings = GetViewData()->GetBindings();
2000-09-18 16:07:07 +00:00
rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
rBindings.Invalidate( SID_TABLES_COUNT );
rBindings.Invalidate( SID_SELECT_SCENARIO );
rBindings.Invalidate( FID_TABLE_SHOW );
}
}
//----------------------------------------------------------------------------
void ScViewFunc::ExtendScenario()
{
ScEditableTester aTester( this );
if (!aTester.IsEditable())
2000-09-18 16:07:07 +00:00
{
ErrorMessage(aTester.GetMessageId());
2000-09-18 16:07:07 +00:00
return;
}
// Undo: apply attributes
2000-09-18 16:07:07 +00:00
ScDocument* pDoc = GetViewData()->GetDocument();
ScPatternAttr aPattern( pDoc->GetPool() );
aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) );
2000-09-18 16:07:07 +00:00
ApplySelectionPattern(aPattern);
}
//----------------------------------------------------------------------------
void ScViewFunc::UseScenario( const OUString& rName )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
DoneBlockMode();
InitOwnBlockMode();
pDocSh->UseScenario( nTab, rName );
}
//----------------------------------------------------------------------------
// Insert table
2000-09-18 16:07:07 +00:00
sal_Bool ScViewFunc::InsertTable( const OUString& rName, SCTAB nTab, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
// Order Tabl/Name is inverted for DocFunc
sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
InsertTable( nTab, rName, bRecord, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
SetTabNo( nTab, sal_True );
2000-09-18 16:07:07 +00:00
return bSuccess;
}
//----------------------------------------------------------------------------
// Insert tables
2000-09-18 16:07:07 +00:00
sal_Bool ScViewFunc::InsertTables(std::vector<OUString>& aNames, SCTAB nTab,
SCTAB nCount, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
2001-02-26 13:12:11 +00:00
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = false;
2000-09-18 16:07:07 +00:00
WaitObject aWait( GetFrameWin() );
if (bRecord)
{
pDoc->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
2000-09-18 16:07:07 +00:00
}
bool bFlag=false;
2000-09-18 16:07:07 +00:00
if(aNames.empty())
2000-09-18 16:07:07 +00:00
{
pDoc->CreateValidTabNames(aNames, nCount);
}
if (pDoc->InsertTabs(nTab, aNames, false))
{
pDocSh->Broadcast( ScTablesHint( SC_TABS_INSERTED, nTab, nCount ) );
bFlag = true;
2000-09-18 16:07:07 +00:00
}
if (bFlag)
{
if (bRecord)
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoInsertTables( pDocSh, nTab, aNames));
2000-09-18 16:07:07 +00:00
// Update views
2000-09-18 16:07:07 +00:00
SetTabNo( nTab, true );
2000-09-18 16:07:07 +00:00
pDocSh->PostPaintExtras();
pDocSh->SetDocumentModified();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
return true;
2000-09-18 16:07:07 +00:00
}
else
{
return false;
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::AppendTable( const OUString& rName, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
2001-02-26 13:12:11 +00:00
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = false;
2000-09-18 16:07:07 +00:00
WaitObject aWait( GetFrameWin() );
if (bRecord)
pDoc->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
2000-09-18 16:07:07 +00:00
if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
{
SCTAB nTab = pDoc->GetTableCount()-1;
2000-09-18 16:07:07 +00:00
if (bRecord)
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoInsertTab( pDocSh, nTab, sal_True, rName));
2000-09-18 16:07:07 +00:00
GetViewData()->InsertTab( nTab );
SetTabNo( nTab, sal_True );
2000-09-18 16:07:07 +00:00
pDocSh->PostPaintExtras();
pDocSh->SetDocumentModified();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
return sal_True;
2000-09-18 16:07:07 +00:00
}
else
{
return false;
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
{
SCTAB nNewTab = nTab;
2000-09-18 16:07:07 +00:00
if ( nNewTab >= pDoc->GetTableCount() )
--nNewTab;
SetTabNo( nNewTab, sal_True );
2000-09-18 16:07:07 +00:00
}
return bSuccess;
}
//only use this method for undo for now, all sheets must be connected
//this method doesn't support undo for now, merge it when it with the other method later
bool ScViewFunc::DeleteTables( const SCTAB nTab, SCTAB nSheets )
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
bool bVbaEnabled = pDoc->IsInVBAMode();
SCTAB nNewTab = nTab;
WaitObject aWait( GetFrameWin() );
while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
--nNewTab;
if (pDoc->DeleteTabs(nTab, nSheets))
{
if( bVbaEnabled )
{
for (SCTAB aTab = 0; aTab < nSheets; ++aTab)
{
OUString sCodeName;
bool bHasCodeName = pDoc->GetCodeName( nTab + aTab, sCodeName );
if ( bHasCodeName )
VBA_DeleteModule( *pDocSh, sCodeName );
}
}
pDocSh->Broadcast( ScTablesHint( SC_TABS_DELETED, nTab, nSheets ) );
if ( nNewTab >= pDoc->GetTableCount() )
nNewTab = pDoc->GetTableCount() - 1;
SetTabNo( nNewTab, sal_True );
pDocSh->PostPaintExtras();
pDocSh->SetDocumentModified();
SfxApplication* pSfxApp = SFX_APP(); // Navigator
pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
return true;
}
return false;
}
sal_Bool ScViewFunc::DeleteTables(const vector<SCTAB> &TheTabs, sal_Bool bRecord )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
sal_Bool bVbaEnabled = pDoc->IsInVBAMode();
re-base on ALv2 code. Includes: Patches contributed by Herbert Duerr i#118735 prevent endless loop if vlookup/hlookup doesn't find anything http://svn.apache.org/viewvc?view=revision&revision=1239673 Patches contributed by Andre Fischer remove lp_solver http://svn.apache.org/viewvc?view=revision&revision=1199180 i#118160: Added external CoinMP library. http://svn.apache.org/viewvc?view=revision&revision=1233909 Patches contributed by Armin Le-Grand i#118485 - Styles for OLEs are not saved. http://svn.apache.org/viewvc?view=revision&revision=1182166 i#118524: apply patch, followup fixes to 118485 http://svn.apache.org/viewvc?view=revision&revision=1186077 Patches contributed by lihuiibm i#108860 - Fix range validation. http://svn.apache.org/viewvc?view=revision&revision=1242846 i#118954 Chart data will lost after copy to different file http://svn.apache.org/viewvc?view=revision&revision=1301345 Patches contributed by Ariel Constenla-Haile Fix Linux build breaker: extra qualification on member http://svn.apache.org/viewvc?view=revision&revision=1301591 i#118696 - i#118697 - Fix some Sheet Tab Color API issues http://svn.apache.org/viewvc?view=revision&revision=1225428 i#118697 - Fix uninitialized variable http://svn.apache.org/viewvc?view=revision&revision=1225859 i#118771 - ScUndoImportTab should preserve tab background color http://svn.apache.org/viewvc?view=revision&revision=1230356 i#118921 - Repaint linked sheet tab background color after updating link http://svn.apache.org/viewvc?view=revision&revision=1245177 i#118927 - Undo/Redo "Update Link" does not reset sheet tab color http://svn.apache.org/viewvc?view=revision&revision=1245241 i#118747 - Copy tab color when transferring sheets across documents http://svn.apache.org/viewvc?view=revision&revision=1230355 Patch contributed by Oliver Rainer-Wittman i#118012 - methods <ScBroadcastAreaSlot::AreaBroadcast(..)> and <ScBroadcastAreaSlot::AreaBroadcastInRange(..)> adapt stl-container iteration in order to avoid destroyed iterators during iteration. http://svn.apache.org/viewvc?view=revision&revision=1297916 Patches contributed by Mathias Bauer gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394707 http://svn.apache.org/viewvc?view=revision&revision=1394326 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1397315 Patch contributed by Daniel Rentz calc69: #i116936# fix VBA symbol Cells http://svn.apache.org/viewvc?view=revision&revision=1172135 Patches contributed by leiw: i#118546 CPU 100% on switched off AutoCalculate with Conditional Formatting on date values http://svn.apache.org/viewvc?view=revision&revision=1301380 Re-add new function documentation. Many various cleanups. Add missing calc66: #o11817313# also look at formula result number format, remove redundant binaries.
2012-11-30 12:23:25 +00:00
SCTAB nNewTab = TheTabs.front();
2000-09-18 16:07:07 +00:00
WaitObject aWait( GetFrameWin() );
2001-02-26 13:12:11 +00:00
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = false;
if ( bVbaEnabled )
bRecord = false;
2000-09-18 16:07:07 +00:00
2000-10-05 09:55:35 +00:00
while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
--nNewTab;
sal_Bool bWasLinked = false;
2000-09-18 16:07:07 +00:00
ScDocument* pUndoDoc = NULL;
ScRefUndoData* pUndoData = NULL;
if (bRecord)
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
SCTAB nCount = pDoc->GetTableCount();
2000-09-18 16:07:07 +00:00
OUString aOldName;
2011-01-27 13:52:52 +00:00
for(unsigned int i=0; i<TheTabs.size(); ++i)
2000-09-18 16:07:07 +00:00
{
2011-01-27 13:52:52 +00:00
SCTAB nTab = TheTabs[i];
2000-09-18 16:07:07 +00:00
if (i==0)
pUndoDoc->InitUndo( pDoc, nTab,nTab, true,true ); // incl. column/fow flags
2000-09-18 16:07:07 +00:00
else
pUndoDoc->AddUndoTab( nTab,nTab, true,true ); // incl. column/fow flags
2000-09-18 16:07:07 +00:00
pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,false, pUndoDoc );
2000-09-18 16:07:07 +00:00
pDoc->GetName( nTab, aOldName );
pUndoDoc->RenameTab( nTab, aOldName, false );
2000-09-18 16:07:07 +00:00
if (pDoc->IsLinked(nTab))
{
bWasLinked = sal_True;
2000-09-18 16:07:07 +00:00
pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
2001-04-18 11:14:41 +00:00
pDoc->GetLinkTab(nTab),
pDoc->GetLinkRefreshDelay(nTab) );
2000-09-18 16:07:07 +00:00
}
if ( pDoc->IsScenario(nTab) )
{
pUndoDoc->SetScenario( nTab, sal_True );
OUString aComment;
2000-09-18 16:07:07 +00:00
Color aColor;
sal_uInt16 nScenFlags;
2000-09-18 16:07:07 +00:00
pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
sal_Bool bActive = pDoc->IsActiveScenario( nTab );
2000-09-18 16:07:07 +00:00
pUndoDoc->SetActiveScenario( nTab, bActive );
}
2000-10-05 09:55:35 +00:00
pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
pUndoDoc->SetLayoutRTL( nTab, pDoc->IsLayoutRTL( nTab ) );
2000-09-18 16:07:07 +00:00
if ( pDoc->IsTabProtected( nTab ) )
CWS-TOOLING: integrate CWS scsheetprotection02 2009-06-18 16:48:14 +0200 kohei r273124 : #i102906# Fix a crasher when loading an xls document with unsupported encrytpion. 2009-06-15 14:02:00 +0200 dr r272982 : #i10000# compiler warnings 2009-04-13 23:06:21 +0200 kohei r270740 : Renamed SetData() to SetDataFromDocument(), in order to resolve name clash with the method of the same name in class Window. This caused a compiler warning on Solaris Intel. 2009-04-13 04:09:59 +0200 kohei r270729 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@270723 (milestone: DEV300:m46) 2009-02-23 16:13:45 +0100 kohei r268361 : added tabprotection.obj to the exception file list. Apparently the older versions of boost::shared_ptr rely on C++ exceptions for its implementation. 2009-02-18 19:59:05 +0100 kohei r268253 : Switched to using ::boost::shared_ptr to wrap a pimpl class, because using ::std::auto_ptr in this header breaks the build on win32. The MSVC implementation of ::std::auto_ptr has some weird quirks... 2009-02-17 21:47:13 +0100 kohei r268192 : fixed linkage issue due to library split. 2009-02-17 04:50:34 +0100 kohei r267842 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@267171 (milestone: DEV300:m41) 2009-02-17 02:36:10 +0100 kohei r267841 : reverted the last commit, to re-surrect the removed src files. 2009-02-03 22:02:34 +0100 kohei r267342 : removed the src files to prevent them from being entered into the translation process. The dialogs that need the strings are not yet enabled in the code, so their removal will not cause any harm. 2009-01-14 12:24:29 +0100 dr r266280 : #i10000# wntmsci12 compiler warnings #4 2009-01-14 09:35:46 +0100 dr r266267 : #i10000# wntmsci12 compiler warnings #3 2009-01-13 15:42:07 +0100 dr r266231 : #i10000# wntmsci12 compiler warnings #2 2009-01-13 13:18:28 +0100 dr r266216 : #i10000# wntmsci12 compiler warnings 2009-01-07 03:59:11 +0100 kohei r265943 : remove the fscking compiler warnings. 2009-01-06 15:55:32 +0100 kohei r265925 : removed compiler warnings that caused the buildbot build to fail.... 2009-01-05 23:24:59 +0100 kohei r265888 : Undoing my own local build fix to work around the libmoz... issue. 2008-12-30 21:39:58 +0100 kohei r265833 : Duh! Sheet protection was supposed to be disabled. :-/ 2008-12-23 20:25:55 +0100 kohei r265792 : recovered the code block that was accidentally removed during cws rebase. 2008-12-23 19:03:19 +0100 kohei r265791 : fixed breakage in ods export filter due to rebase to m38. 2008-12-23 16:41:49 +0100 kohei r265787 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@265758 (milestone: DEV300:m38) 2008-12-23 05:37:47 +0100 kohei r265768 : deliberately forget document and sheet passwords when importing from or exporting to excel, to emulate the current behavior. 2008-12-23 05:12:59 +0100 kohei r265767 : removed commented-out unused method ScDocument::SetAutoFilterFlags(). 2008-12-23 05:05:19 +0100 kohei r265766 : removed one duplicate method and made associated changes with the removal, and a little more code cleanup. 2008-12-23 04:24:58 +0100 kohei r265765 : a typo in in-line comment 2008-12-23 04:23:08 +0100 kohei r265764 : remove fprintf statement that blatantly prints out document encryption password to stdout. not a good practice. 2008-12-23 04:14:21 +0100 kohei r265763 : we actually don't want to clear all options, because if we do, then we would no longer be able to select any cells on a protected sheet. 2008-12-23 04:07:10 +0100 kohei r265762 : * minor code cleanup (indentation inconsistencies & use of tab) * fixed unprotecting a sheet with password to make it work again. 2008-12-23 03:22:50 +0100 kohei r265761 : reverted all the new functionalities to the existing ones, while keeping the new code in as much as I could. 2008-12-22 23:11:08 +0100 kohei r265760 : in xls export filter, renamed two unknown records into records of known name. 2008-12-22 22:34:50 +0100 kohei r265759 : temporarily disable password capability on file export for MS Excel 97. 2008-12-22 17:01:21 +0100 kohei r265754 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@264807 (milestone: DEV300:m37) 2008-11-26 03:12:58 +0100 kohei r264335 : recovered a method that was actually used. 2008-11-25 21:51:10 +0100 kohei r264334 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@264325 (milestone: DEV300:m36) 2008-10-08 19:57:35 +0200 kohei r262094 : changed description string to make it less technical. 2008-10-01 05:56:58 +0200 kohei r261986 : migrated from the cvs-based cws. 2008-10-01 05:55:19 +0200 kohei r261985 : migrated from the cvs-based cws. 2008-10-01 05:55:00 +0200 kohei r261984 : migrated from the cvs-based cws.
2009-07-01 08:58:41 +00:00
pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
// Drawing-Layer is responsible for its Undo !!!
2000-09-18 16:07:07 +00:00
// pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
}
pUndoDoc->AddUndoTab( 0, nCount-1 ); // all Tabs for references
2000-09-18 16:07:07 +00:00
pDoc->BeginDrawUndo(); // DeleteTab creates a SdrUndoDelPage
2000-09-18 16:07:07 +00:00
pUndoData = new ScRefUndoData( pDoc );
}
sal_Bool bDelDone = false;
2000-09-18 16:07:07 +00:00
2011-01-27 13:52:52 +00:00
for(int i=TheTabs.size()-1; i>=0; --i)
2000-09-18 16:07:07 +00:00
{
OUString sCodeName;
sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i], sCodeName );
if (pDoc->DeleteTab(TheTabs[i]))
2000-09-18 16:07:07 +00:00
{
bDelDone = sal_True;
if( bVbaEnabled )
{
if( bHasCodeName )
{
VBA_DeleteModule( *pDocSh, sCodeName );
}
}
2011-01-27 13:52:52 +00:00
pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[i] ) );
2000-09-18 16:07:07 +00:00
}
}
if (bRecord)
{
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
pUndoDoc, pUndoData ));
}
2000-10-05 09:55:35 +00:00
if (bDelDone)
2000-09-18 16:07:07 +00:00
{
if ( nNewTab >= pDoc->GetTableCount() )
2000-10-05 09:55:35 +00:00
nNewTab = pDoc->GetTableCount() - 1;
SetTabNo( nNewTab, sal_True );
2000-09-18 16:07:07 +00:00
if (bWasLinked)
{
pDocSh->UpdateLinks(); // update Link-Manager
2000-09-22 17:57:10 +00:00
GetViewData()->GetBindings().Invalidate(SID_LINKS);
2000-09-18 16:07:07 +00:00
}
pDocSh->PostPaintExtras();
pDocSh->SetDocumentModified();
SfxApplication* pSfxApp = SFX_APP(); // Navigator
pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2000-09-18 16:07:07 +00:00
}
else
{
delete pUndoDoc;
delete pUndoData;
}
2000-10-05 09:55:35 +00:00
return bDelDone;
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
sal_Bool ScViewFunc::RenameTable( const OUString& rName, SCTAB nTab )
2000-09-18 16:07:07 +00:00
{
// order Table/Name is inverted for DocFunc
sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
RenameTable( nTab, rName, true, false );
2000-09-18 16:07:07 +00:00
if (bSuccess)
{
// the table name might be part of a formula
2000-09-18 16:07:07 +00:00
GetViewData()->GetViewShell()->UpdateInputHandler();
}
return bSuccess;
}
//----------------------------------------------------------------------------
bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
{
bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, sal_True, false );
if (bSuccess)
{
GetViewData()->GetViewShell()->UpdateInputHandler();
}
return bSuccess;
}
bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
{
bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, sal_True, false );
if (bSuccess)
{
GetViewData()->GetViewShell()->UpdateInputHandler();
}
return bSuccess;
}
2000-09-18 16:07:07 +00:00
//----------------------------------------------------------------------------
void ScViewFunc::InsertAreaLink( const OUString& rFile,
const OUString& rFilter, const OUString& rOptions,
const OUString& rSource, sal_uLong nRefresh )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
SCCOL nPosX = GetViewData()->GetCurX();
SCROW nPosY = GetViewData()->GetCurY();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
ScAddress aPos( nPosX, nPosY, nTab );
pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, false, false );
2000-09-18 16:07:07 +00:00
}
//----------------------------------------------------------------------------
void ScViewFunc::InsertTableLink( const OUString& rFile,
const OUString& rFilter, const OUString& rOptions,
const OUString& rTabName )
2000-09-18 16:07:07 +00:00
{
OUString aFilterName = rFilter;
OUString aOpt = rOptions;
OUString aURL = rFile;
ScDocumentLoader aLoader( aURL, aFilterName, aOpt );
2000-09-18 16:07:07 +00:00
if (!aLoader.IsError())
{
ScDocShell* pSrcSh = aLoader.GetDocShell();
ScDocument* pSrcDoc = pSrcSh->GetDocument();
SCTAB nTab = MAXTAB+1;
if (rTabName.isEmpty()) // no name given -> first table
2000-09-18 16:07:07 +00:00
nTab = 0;
else
{
OUString aTemp;
SCTAB nCount = pSrcDoc->GetTableCount();
for (SCTAB i=0; i<nCount; i++)
2000-09-18 16:07:07 +00:00
{
pSrcDoc->GetName( i, aTemp );
2011-08-26 19:33:59 -04:00
if ( aTemp.equals(rTabName) )
2000-09-18 16:07:07 +00:00
nTab = i;
}
}
if ( nTab <= MAXTAB )
ImportTables( pSrcSh, 1, &nTab, sal_True,
2000-09-18 16:07:07 +00:00
GetViewData()->GetTabNo() );
}
}
//----------------------------------------------------------------------------
// Copy/link tables from another document
2000-09-18 16:07:07 +00:00
void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab )
2000-09-18 16:07:07 +00:00
{
ScDocument* pSrcDoc = pSrcShell->GetDocument();
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
sal_Bool bUndo(pDoc->IsUndoEnabled());
2000-09-18 16:07:07 +00:00
sal_Bool bError = false;
sal_Bool bRefs = false;
sal_Bool bName = false;
2000-09-18 16:07:07 +00:00
if (pSrcDoc->GetDrawLayer())
pDocSh->MakeDrawLayer();
if (bUndo)
pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2000-09-18 16:07:07 +00:00
SCTAB nInsCount = 0;
SCTAB i;
2000-09-18 16:07:07 +00:00
for( i=0; i<nCount; i++ )
{ // insert sheets first and update all references
OUString aName;
2000-09-18 16:07:07 +00:00
pSrcDoc->GetName( pSrcTabs[i], aName );
pDoc->CreateValidTabName( aName );
if ( !pDoc->InsertTab( nTab+i, aName ) )
{
bError = sal_True; // total error
2000-09-18 16:07:07 +00:00
break; // for
}
++nInsCount;
}
for (i=0; i<nCount && !bError; i++)
{
SCTAB nSrcTab = pSrcTabs[i];
SCTAB nDestTab1=nTab+i;
sal_uLong nErrVal = pDocSh->TransferTab( *pSrcShell, nSrcTab, nDestTab1,
false, false ); // no insert
2000-09-18 16:07:07 +00:00
switch (nErrVal)
{
case 0: // internal error or full of errors
bError = true;
2000-09-18 16:07:07 +00:00
break;
case 2:
bRefs = sal_True;
2000-09-18 16:07:07 +00:00
break;
case 3:
bName = sal_True;
2000-09-18 16:07:07 +00:00
break;
case 4:
bRefs = bName = sal_True;
2000-09-18 16:07:07 +00:00
break;
}
}
if (bLink)
{
2010-01-13 22:25:07 +01:00
sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
2000-09-18 16:07:07 +00:00
SfxMedium* pMed = pSrcShell->GetMedium();
OUString aFileName = pMed->GetName();
OUString aFilterName;
2000-09-18 16:07:07 +00:00
if (pMed->GetFilter())
aFilterName = pMed->GetFilter()->GetFilterName();
OUString aOptions = ScDocumentLoader::GetOptions(*pMed);
2000-09-18 16:07:07 +00:00
sal_Bool bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
2000-09-18 16:07:07 +00:00
sal_uLong nRefresh = 0;
OUString aTabStr;
2000-09-18 16:07:07 +00:00
for (i=0; i<nInsCount; i++)
{
pSrcDoc->GetName( pSrcTabs[i], aTabStr );
pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
2001-04-18 11:14:41 +00:00
aFileName, aFilterName, aOptions, aTabStr, nRefresh );
2000-09-18 16:07:07 +00:00
}
if (!bWasThere) // Insert link only once per source document
2000-09-18 16:07:07 +00:00
{
2001-04-18 11:14:41 +00:00
ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
pLink->SetInCreate( sal_True );
2000-09-18 16:07:07 +00:00
pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
pLink->Update();
pLink->SetInCreate( false );
2000-09-18 16:07:07 +00:00
2000-09-22 17:57:10 +00:00
SfxBindings& rBindings = GetViewData()->GetBindings();
2000-09-18 16:07:07 +00:00
rBindings.Invalidate( SID_LINKS );
}
}
if (bUndo)
{
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoImportTab( pDocSh, nTab, nCount ) );
}
2000-09-18 16:07:07 +00:00
for (i=0; i<nInsCount; i++)
GetViewData()->InsertTab(nTab);
SetTabNo(nTab,sal_True);
2000-09-18 16:07:07 +00:00
pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
SfxApplication* pSfxApp = SFX_APP();
pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
pDocSh->PostPaintExtras();
pDocSh->PostPaintGridAll();
pDocSh->SetDocumentModified();
if (bRefs)
ErrorMessage(STR_ABSREFLOST);
if (bName)
ErrorMessage(STR_NAMECONFLICT);
}
//----------------------------------------------------------------------------
// Move/Copy table to another document
2000-09-18 16:07:07 +00:00
2011-08-29 21:48:06 -04:00
void ScViewFunc::MoveTable(
sal_uInt16 nDestDocNo, SCTAB nDestTab, bool bCopy, const OUString* pNewTabName )
2000-09-18 16:07:07 +00:00
{
ScDocument* pDoc = GetViewData()->GetDocument();
ScDocShell* pDocShell = GetViewData()->GetDocShell();
ScDocument* pDestDoc = NULL;
ScDocShell* pDestShell = NULL;
ScTabViewShell* pDestViewSh = NULL;
sal_Bool bUndo (pDoc->IsUndoEnabled());
2011-08-29 21:48:06 -04:00
bool bRename = pNewTabName && !pNewTabName->isEmpty();
2000-09-18 16:07:07 +00:00
bool bNewDoc = (nDestDocNo == SC_DOC_NEW);
2000-09-18 16:07:07 +00:00
if ( bNewDoc )
{
nDestTab = 0; // firstly insert
2000-09-18 16:07:07 +00:00
// execute without SFX_CALLMODE_RECORD, because already contained in move command
2000-09-18 16:07:07 +00:00
OUString aUrl("private:factory/");
aUrl += STRING_SCAPP; // "scalc"
2000-09-18 16:07:07 +00:00
SfxStringItem aItem( SID_FILE_NAME, aUrl );
SfxStringItem aTarget( SID_TARGETNAME, OUString("_blank") );
2000-09-18 16:07:07 +00:00
const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
if ( pRetItem )
2000-09-18 16:07:07 +00:00
{
if ( pRetItem->ISA( SfxObjectItem ) )
pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() );
else if ( pRetItem->ISA( SfxViewFrameItem ) )
2000-09-18 16:07:07 +00:00
{
SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
if (pFrm)
pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() );
2000-09-18 16:07:07 +00:00
}
if (pDestShell)
pDestViewSh = pDestShell->GetBestViewShell();
2000-09-18 16:07:07 +00:00
}
}
else
pDestShell = ScDocShell::GetShellByNum( nDestDocNo );
if (!pDestShell)
{
2011-03-01 19:05:02 +01:00
OSL_FAIL("Dest-Doc nicht gefunden !!!");
2000-09-18 16:07:07 +00:00
return;
}
2010-12-13 21:43:04 -05:00
ScMarkData& rMark = GetViewData()->GetMarkData();
if (bRename && rMark.GetSelectCount() != 1)
{
// Custom sheet name is provided, but more than one sheet is selected.
// We don't support this scenario at the moment.
return;
}
2000-09-18 16:07:07 +00:00
pDestDoc = pDestShell->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
2000-09-18 16:07:07 +00:00
if (pDestDoc != pDoc)
{
if (bNewDoc)
{
while (pDestDoc->GetTableCount() > 1)
pDestDoc->DeleteTab(0);
pDestDoc->RenameTab( 0, OUString("______42_____"),
false );
2000-09-18 16:07:07 +00:00
}
SCTAB nTabCount = pDoc->GetTableCount();
SCTAB nTabSelCount = rMark.GetSelectCount();
2000-09-18 16:07:07 +00:00
2011-01-27 13:52:52 +00:00
vector<SCTAB> TheTabs;
2000-09-18 16:07:07 +00:00
2011-01-27 13:52:52 +00:00
for(SCTAB i=0; i<nTabCount; ++i)
2000-09-18 16:07:07 +00:00
{
if(rMark.GetTableSelect(i))
{
OUString aTabName;
2000-09-18 16:07:07 +00:00
pDoc->GetName( i, aTabName);
2011-01-27 13:52:52 +00:00
TheTabs.push_back(i);
for(SCTAB j=i+1;j<nTabCount;j++)
2000-09-18 16:07:07 +00:00
{
if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
{
pDoc->GetName( j, aTabName);
2011-01-27 13:52:52 +00:00
TheTabs.push_back(j);
2000-09-18 16:07:07 +00:00
i=j;
}
else break;
}
}
}
GetFrameWin()->EnterWait();
if (pDoc->GetDrawLayer())
pDestShell->MakeDrawLayer();
if (!bNewDoc && bUndo)
2000-09-18 16:07:07 +00:00
pDestDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
sal_uLong nErrVal =1;
if(nDestTab==SC_TAB_APPEND)
nDestTab=pDestDoc->GetTableCount();
SCTAB nDestTab1=nDestTab;
ScClipParam aParam;
for( sal_uInt16 j=0; j<TheTabs.size(); ++j, ++nDestTab1 )
{ // insert sheets first and update all references
OUString aName;
2010-12-13 21:43:04 -05:00
if (bRename)
aName = *pNewTabName;
else
pDoc->GetName( TheTabs[j], aName );
2000-09-18 16:07:07 +00:00
pDestDoc->CreateValidTabName( aName );
if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
{
nErrVal = 0; // total error
break; // for
}
ScRange aRange( 0, 0, TheTabs[j], MAXCOL, MAXROW, TheTabs[j] );
aParam.maRanges.Append(aRange);
2000-09-18 16:07:07 +00:00
}
pDoc->SetClipParam(aParam);
2000-09-18 16:07:07 +00:00
if ( nErrVal > 0 )
{
nDestTab1 = nDestTab;
for(sal_uInt16 i=0; i<TheTabs.size();++i)
2000-09-18 16:07:07 +00:00
{
nErrVal = pDestShell->TransferTab( *pDocShell, TheTabs[i], static_cast<SCTAB>(nDestTab1), false, false );
2000-09-18 16:07:07 +00:00
nDestTab1++;
}
}
OUString sName;
if (!bNewDoc && bUndo)
2000-09-18 16:07:07 +00:00
{
pDestDoc->GetName(nDestTab, sName);
pDestShell->GetUndoManager()->AddUndoAction(
new ScUndoImportTab( pDestShell, nDestTab,
static_cast<SCTAB>(TheTabs.size())));
2000-09-18 16:07:07 +00:00
}
else
{
pDestShell->GetUndoManager()->Clear();
}
GetFrameWin()->LeaveWait();
switch (nErrVal)
{
case 0: // internal error or full of errors
2000-09-18 16:07:07 +00:00
{
ErrorMessage(STR_TABINSERT_ERROR);
return;
}
//break;
2000-09-18 16:07:07 +00:00
case 2:
ErrorMessage(STR_ABSREFLOST);
break;
case 3:
ErrorMessage(STR_NAMECONFLICT);
break;
case 4:
{
ErrorMessage(STR_ABSREFLOST);
ErrorMessage(STR_NAMECONFLICT);
}
break;
default:
break;
}
2010-12-14 18:13:46 -05:00
2000-09-18 16:07:07 +00:00
if (!bCopy)
{
if(nTabCount!=nTabSelCount)
DeleteTables(TheTabs); // incl. Paint & Undo
2000-09-18 16:07:07 +00:00
else
ErrorMessage(STR_TABREMOVE_ERROR);
}
if (bNewDoc)
{
// ChartListenerCollection must be updated before DeleteTab
if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
pDestDoc->UpdateChartListenerCollection();
pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.size())); // old first table
2000-09-18 16:07:07 +00:00
if (pDestViewSh)
{
// Make sure to clear the cached page view after sheet
// deletion, which still points to the sdr page belonging to
// the deleted sheet.
SdrView* pSdrView = pDestViewSh->GetSdrView();
if (pSdrView)
pSdrView->ClearPageView();
2000-09-18 16:07:07 +00:00
pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer
}
2000-09-18 16:07:07 +00:00
pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
PAINT_GRID | PAINT_TOP | PAINT_LEFT |
PAINT_EXTRAS | PAINT_SIZE );
// PAINT_SIZE for outline
2000-09-18 16:07:07 +00:00
}
else
{
pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
pDestShell->PostPaintExtras();
pDestShell->PostPaintGridAll();
}
2011-01-27 13:52:52 +00:00
TheTabs.clear();
2000-09-18 16:07:07 +00:00
pDestShell->SetDocumentModified();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
}
2010-12-13 21:43:04 -05:00
else
2000-09-18 16:07:07 +00:00
{
2010-12-13 21:43:04 -05:00
// Move or copy within the same document.
SCTAB nTabCount = pDoc->GetTableCount();
2000-09-18 16:07:07 +00:00
SAL_WNODEPRECATED_DECLARATIONS_PUSH
auto_ptr< vector<SCTAB> > pSrcTabs(new vector<SCTAB>);
auto_ptr< vector<SCTAB> > pDestTabs(new vector<SCTAB>);
auto_ptr< vector<OUString> > pTabNames(new vector<OUString>);
auto_ptr< vector<OUString> > pDestNames(NULL);
SAL_WNODEPRECATED_DECLARATIONS_POP
pSrcTabs->reserve(nTabCount);
pDestTabs->reserve(nTabCount);
pTabNames->reserve(nTabCount);
OUString aDestName;
2000-09-18 16:07:07 +00:00
for(SCTAB i=0;i<nTabCount;i++)
2000-09-18 16:07:07 +00:00
{
if(rMark.GetTableSelect(i))
{
OUString aTabName;
2000-09-18 16:07:07 +00:00
pDoc->GetName( i, aTabName);
pTabNames->push_back(aTabName);
2000-09-18 16:07:07 +00:00
for(SCTAB j=i+1;j<nTabCount;j++)
2000-09-18 16:07:07 +00:00
{
if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
{
pDoc->GetName( j, aTabName);
pTabNames->push_back(aTabName);
2000-09-18 16:07:07 +00:00
i=j;
}
else break;
}
}
}
if (bCopy && bUndo)
2000-09-18 16:07:07 +00:00
pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
pDoc->GetName( nDestTab, aDestName);
SCTAB nDestTab1=nDestTab;
SCTAB nMovTab=0;
for (size_t j = 0, n = pTabNames->size(); j < n; ++j)
2000-09-18 16:07:07 +00:00
{
nTabCount = pDoc->GetTableCount();
const OUString& rStr = (*pTabNames)[j];
if(!pDoc->GetTable(rStr,nMovTab))
2000-09-18 16:07:07 +00:00
{
nMovTab=nTabCount;
}
if(!pDoc->GetTable(aDestName,nDestTab1))
{
nDestTab1=nTabCount;
}
pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, false ); // Undo is here
2000-09-18 16:07:07 +00:00
if(bCopy && pDoc->IsScenario(nMovTab))
{
OUString aComment;
2000-09-18 16:07:07 +00:00
Color aColor;
sal_uInt16 nFlags;
2000-09-18 16:07:07 +00:00
pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
pDoc->SetScenario(nDestTab1,sal_True);
2000-09-18 16:07:07 +00:00
pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
sal_Bool bActive = pDoc->IsActiveScenario(nMovTab );
2000-09-18 16:07:07 +00:00
pDoc->SetActiveScenario( nDestTab1, bActive );
sal_Bool bVisible=pDoc->IsVisible(nMovTab);
2000-09-18 16:07:07 +00:00
pDoc->SetVisible(nDestTab1,bVisible );
}
pSrcTabs->push_back(nMovTab);
2000-09-18 16:07:07 +00:00
if(!bCopy)
{
if(!pDoc->GetTable(rStr,nDestTab1))
2000-09-18 16:07:07 +00:00
{
nDestTab1=nTabCount;
}
}
pDestTabs->push_back(nDestTab1);
2000-09-18 16:07:07 +00:00
}
// Rename must be done after all sheets have been moved.
2010-12-13 21:43:04 -05:00
if (bRename)
{
pDestNames.reset(new vector<OUString>);
size_t n = pDestTabs->size();
pDestNames->reserve(n);
for (size_t j = 0; j < n; ++j)
{
SCTAB nRenameTab = (*pDestTabs)[j];
OUString aTabName = *pNewTabName;
pDoc->CreateValidTabName( aTabName );
pDestNames->push_back(aTabName);
pDoc->RenameTab(nRenameTab, aTabName);
}
}
else
// No need to keep this around when we are not renaming.
pTabNames.reset();
2000-09-18 16:07:07 +00:00
nTab = GetViewData()->GetTabNo();
if (bUndo)
2000-09-18 16:07:07 +00:00
{
if (bCopy)
{
pDocShell->GetUndoManager()->AddUndoAction(
new ScUndoCopyTab(
pDocShell, pSrcTabs.release(), pDestTabs.release(), pDestNames.release()));
}
else
{
pDocShell->GetUndoManager()->AddUndoAction(
new ScUndoMoveTab(
pDocShell, pSrcTabs.release(), pDestTabs.release(), pTabNames.release(), pDestNames.release()));
}
2000-09-18 16:07:07 +00:00
}
SCTAB nNewTab = nDestTab;
2000-09-18 16:07:07 +00:00
if (nNewTab == SC_TAB_APPEND)
nNewTab = pDoc->GetTableCount()-1;
else if (!bCopy && nTab<nDestTab)
nNewTab--;
SetTabNo( nNewTab, sal_True );
//#i29848# adjust references to data on the copied sheet
if( bCopy )
ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab );
2000-09-18 16:07:07 +00:00
}
}
//----------------------------------------------------------------------------
void ScViewFunc::ShowTable( const std::vector<OUString>& rNames )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
sal_Bool bUndo(pDoc->IsUndoEnabled());
std::vector<SCTAB> undoTabs;
OUString aName;
SCTAB nPos = 0;
bool bFound(false);
for (std::vector<OUString>::const_iterator itr=rNames.begin(), itrEnd = rNames.end(); itr!=itrEnd; ++itr)
2000-09-18 16:07:07 +00:00
{
aName = *itr;
if (pDoc->GetTable(aName, nPos))
2000-09-18 16:07:07 +00:00
{
pDoc->SetVisible( nPos, sal_True );
SetTabNo( nPos, sal_True );
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
if (!bFound)
bFound = true;
if (bUndo)
undoTabs.push_back(nPos);
2000-09-18 16:07:07 +00:00
}
}
if (bFound)
{
if (bUndo)
{
pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, undoTabs, true ) );
}
2000-09-18 16:07:07 +00:00
pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
pDocSh->SetDocumentModified();
}
}
//----------------------------------------------------------------------------
void ScViewFunc::HideTable( const ScMarkData& rMark )
2000-09-18 16:07:07 +00:00
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
sal_Bool bUndo(pDoc->IsUndoEnabled());
SCTAB nVisible = 0;
SCTAB nTabCount = pDoc->GetTableCount();
SCTAB nTabSelCount = rMark.GetSelectCount();
// check to make sure we won't hide all sheets. we need at least one visible at all times.
for ( SCTAB i=0; i < nTabCount && nVisible <= nTabSelCount ; i++ )
2000-09-18 16:07:07 +00:00
if (pDoc->IsVisible(i))
++nVisible;
if (nVisible > nTabSelCount)
2000-09-18 16:07:07 +00:00
{
SCTAB nTab;
ScMarkData::MarkedTabsType::const_iterator it;
std::vector<SCTAB> undoTabs;
ScMarkData::MarkedTabsType selectedTabs = rMark.GetSelectedTabs();
for (it=selectedTabs.begin(); it!=selectedTabs.end(); ++it)
{
nTab = *it;
if (pDoc->IsVisible( nTab ))
{
pDoc->SetVisible( nTab, false );
// Update views
pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
SetTabNo( nTab, true );
// Store for undo
if (bUndo)
undoTabs.push_back(nTab);
}
}
if (bUndo)
{
pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, undoTabs, false ) );
}
2000-09-18 16:07:07 +00:00
// Update views
2000-09-18 16:07:07 +00:00
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
pDocSh->SetDocumentModified();
}
}
//----------------------------------------------------------------------------
void ScViewFunc::InsertSpecialChar( const OUString& rStr, const Font& rFont )
2000-09-18 16:07:07 +00:00
{
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.getStr();
2000-09-18 16:07:07 +00:00
ScTabViewShell* pViewShell = GetViewData()->GetViewShell();
SvxFontItem aFontItem( rFont.GetFamily(),
rFont.GetName(),
rFont.GetStyleName(),
rFont.GetPitch(),
rFont.GetCharSet(),
ATTR_FONT );
// if string contains WEAK characters, set all fonts
sal_uInt8 nScript;
ScDocument* pDoc = GetViewData()->GetDocument();
if ( pDoc->HasStringWeakCharacters( rStr ) )
nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
else
nScript = pDoc->GetStringScriptType( rStr );
SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
aSetItem.PutItemForScriptType( nScript, aFontItem );
ApplyUserItemSet( aSetItem.GetItemSet() );
2000-09-18 16:07:07 +00:00
while ( *pChar )
pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
}
//----------------------------------------------------------------------------
void ScViewFunc::UpdateLineAttrs( SvxBorderLine& rLine,
const SvxBorderLine* pDestLine,
const SvxBorderLine* pSrcLine,
sal_Bool bColor )
2000-09-18 16:07:07 +00:00
{
if ( pSrcLine && pDestLine )
{
if ( bColor )
{
rLine.SetColor ( pSrcLine->GetColor() );
rLine.SetBorderLineStyle(pDestLine->GetBorderLineStyle());
rLine.SetWidth ( pDestLine->GetWidth() );
2000-09-18 16:07:07 +00:00
}
else
{
rLine.SetColor ( pDestLine->GetColor() );
rLine.SetBorderLineStyle(pSrcLine->GetBorderLineStyle());
rLine.SetWidth ( pSrcLine->GetWidth() );
2000-09-18 16:07:07 +00:00
}
}
}
#define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
pBoxLine = aBoxItem.Get##LINE(); \
if ( pBoxLine ) \
{ \
if ( pLine ) \
{ \
UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \
aBoxItem.SetLine( &aLine, BOXLINE ); \
} \
else \
aBoxItem.SetLine( NULL, BOXLINE ); \
}
//----------------------------------------------------------------------------
void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine,
sal_Bool bColorOnly )
2000-09-18 16:07:07 +00:00
{
// Not editable only due to a matrix? Attribute is ok anyhow.
2011-08-25 11:33:20 +02:00
bool bOnlyNotBecauseOfMatrix;
2000-09-18 16:07:07 +00:00
if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
{
ErrorMessage(STR_PROTECTIONERR);
return;
}
ScDocument* pDoc = GetViewData()->GetDocument();
ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
2000-09-18 16:07:07 +00:00
ScDocShell* pDocSh = GetViewData()->GetDocShell();
const ScPatternAttr* pSelAttrs = GetSelectionPattern();
const SfxItemSet& rSelItemSet = pSelAttrs->GetItemSet();
2000-09-18 16:07:07 +00:00
const SfxPoolItem* pBorderAttr = NULL;
SfxItemState eItemState = rSelItemSet.GetItemState( ATTR_BORDER, sal_True, &pBorderAttr );
const SfxPoolItem* pTLBRItem = 0;
SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem );
const SfxPoolItem* pBLTRItem = 0;
SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, sal_True, &pBLTRItem );
2000-09-18 16:07:07 +00:00
// any of the lines visible?
if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
2000-09-18 16:07:07 +00:00
{
// none of the lines don't care?
if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
2000-09-18 16:07:07 +00:00
{
SfxItemSet* pOldSet = new SfxItemSet(
*(pDoc->GetPool()),
ATTR_PATTERN_START,
ATTR_PATTERN_END );
SfxItemSet* pNewSet = new SfxItemSet(
*(pDoc->GetPool()),
ATTR_PATTERN_START,
ATTR_PATTERN_END );
//------------------------------------------------------------
const SvxBorderLine* pBoxLine = NULL;
SvxBorderLine aLine;
// here pBoxLine is used
2000-09-18 16:07:07 +00:00
if( pBorderAttr )
{
SvxBoxItem aBoxItem( *(const SvxBoxItem*)pBorderAttr );
SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)
aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
aBoxInfoItem.ResetFlags(); // set Lines to Valid
2000-09-18 16:07:07 +00:00
pOldSet->Put( *pBorderAttr );
pNewSet->Put( aBoxItem );
pNewSet->Put( aBoxInfoItem );
}
if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() )
{
SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem );
UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly );
aTLBRItem.SetLine( &aLine );
pOldSet->Put( *pTLBRItem );
pNewSet->Put( aTLBRItem );
}
2000-09-18 16:07:07 +00:00
if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() )
{
SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem );
UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly );
aBLTRItem.SetLine( &aLine );
pOldSet->Put( *pBLTRItem );
pNewSet->Put( aBLTRItem );
}
2000-09-18 16:07:07 +00:00
ApplyAttributes( pNewSet, pOldSet );
delete pOldSet;
delete pNewSet;
}
else // if ( eItemState == SFX_ITEM_DONTCARE )
{
aFuncMark.MarkToMulti();
pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
2000-09-18 16:07:07 +00:00
}
ScRange aMarkRange;
aFuncMark.GetMultiMarkArea( aMarkRange );
SCCOL nStartCol = aMarkRange.aStart.Col();
SCROW nStartRow = aMarkRange.aStart.Row();
SCTAB nStartTab = aMarkRange.aStart.Tab();
SCCOL nEndCol = aMarkRange.aEnd.Col();
SCROW nEndRow = aMarkRange.aEnd.Row();
SCTAB nEndTab = aMarkRange.aEnd.Tab();
2000-09-18 16:07:07 +00:00
pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
nEndCol, nEndRow, nEndTab,
PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
pDocSh->UpdateOle( GetViewData() );
pDocSh->SetDocumentModified();
}
}
#undef SET_LINE_ATTRIBUTES
//----------------------------------------------------------------------------
void ScViewFunc::SetValidation( const ScValidationData& rNew )
{
ScDocument* pDoc = GetViewData()->GetDocument();
sal_uLong nIndex = pDoc->AddValidationEntry(rNew); // for it there is no Undo
2000-09-18 16:07:07 +00:00
SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
ApplyAttr( aItem ); // with Paint and Undo...
2000-09-18 16:07:07 +00:00
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */