/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* 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/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#include <osl/diagnose.h>
#include <document.hxx>
#include <attrib.hxx>
#include <scextopt.hxx>
#include <olinetab.hxx>
#include <root.hxx>
#include <excimp8.hxx>
#include <namebuff.hxx>
#include <otlnbuff.hxx>
#include <formel.hxx>
#include <xilink.hxx>
#include <memory>
#include <vector>
RootData::RootData()
{
eDateiTyp = BiffX;
pFmlaConverter = nullptr;
pTabId = nullptr;
pUserBViewList = nullptr;
pIR = nullptr;
pER = nullptr;
pColRowBuff = nullptr;
}
RootData::~RootData()
{
pExtSheetBuff.reset();
pShrfmlaBuff.reset();
pExtNameBuff.reset();
pAutoFilterBuffer.reset();
}
XclImpOutlineBuffer::XclImpOutlineBuffer( SCSIZE nNewSize ) :
maLevels(0, nNewSize, 0),
mpOutlineArray(nullptr),
mnEndPos(nNewSize),
mnMaxLevel(0),
mbButtonAfter(true)
{
}
XclImpOutlineBuffer::~XclImpOutlineBuffer()
{
}
void XclImpOutlineBuffer::SetLevel( SCSIZE nIndex, sal_uInt8 nVal, bool bCollapsed )
{
maLevels.insert_back(nIndex, nIndex+1, nVal);
if (nVal > mnMaxLevel)
mnMaxLevel = nVal;
if (bCollapsed)
maCollapsedPosSet.insert(nIndex);
}
void XclImpOutlineBuffer::SetOutlineArray( ScOutlineArray* pOArray )
{
mpOutlineArray = pOArray;
}
void XclImpOutlineBuffer::MakeScOutline()
{
if (!mpOutlineArray)
return;
::std::vector<SCSIZE> aOutlineStack;
aOutlineStack.reserve(mnMaxLevel);
for (const auto& [nPos, nLevel] : maLevels)
{
if (nPos >= mnEndPos)
{
// Don't go beyond the max allowed position.
OSL_ENSURE(aOutlineStack.empty(), "XclImpOutlineBuffer::MakeScOutline: outline stack not empty but expected to be.");
break;
}
sal_uInt8 nCurLevel = static_cast<sal_uInt8>(aOutlineStack.size());
if (nLevel > nCurLevel)
{
for (sal_uInt8 i = 0; i < nLevel - nCurLevel; ++i)
aOutlineStack.push_back(nPos);
}
else
{
OSL_ENSURE(nLevel <= nCurLevel, "XclImpOutlineBuffer::MakeScOutline: unexpected level!");
for (sal_uInt8 i = 0; i < nCurLevel - nLevel; ++i)
{
if (aOutlineStack.empty())
{
// Something is wrong.
return;
}
SCSIZE nFirstPos = aOutlineStack.back();
aOutlineStack.pop_back();
bool bCollapsed = false;
if (mbButtonAfter)
bCollapsed = maCollapsedPosSet.count(nPos) > 0;
else if (nFirstPos > 0)
bCollapsed = maCollapsedPosSet.count(nFirstPos-1) > 0;
bool bDummy;
mpOutlineArray->Insert(nFirstPos, nPos-1, bDummy, bCollapsed);
}
}
}
}
void XclImpOutlineBuffer::SetLevelRange( SCSIZE nF, SCSIZE nL, sal_uInt8 nVal, bool bCollapsed )
{
if (nF > nL)
// invalid range
return;
maLevels.insert_back(nF, nL+1, nVal);
if (bCollapsed)
maCollapsedPosSet.insert(nF);
}
void XclImpOutlineBuffer::SetButtonMode( bool bRightOrUnder )
{
mbButtonAfter = bRightOrUnder;
}
ExcScenarioCell::ExcScenarioCell( const sal_uInt16 nC, const sal_uInt16 nR )
: nCol( nC ), nRow( nR )
{
}
ExcScenario::ExcScenario( XclImpStream& rIn, const RootData& rR )
: nTab( rR.pIR->GetCurrScTab() )
{
sal_uInt16 nCref;
sal_uInt8 nName, nComment;
nCref = rIn.ReaduInt16();
nProtected = rIn.ReaduInt8();
rIn.Ignore( 1 ); // Hide
nName = rIn.ReaduInt8();
nComment = rIn.ReaduInt8();
rIn.Ignore( 1 ); // instead of nUser!
if( nName )
aName = rIn.ReadUniString( nName );
else
{
aName = "Scenery";
rIn.Ignore( 1 );
}
rIn.ReadUniString(); // username
if( nComment )
aComment = rIn.ReadUniString();
sal_uInt16 n = nCref;
sal_uInt16 nC, nR;
aEntries.reserve(n);
while( n )
{
nR = rIn.ReaduInt16();
nC = rIn.ReaduInt16();
aEntries.emplace_back( nC, nR );
n--;
}
for (auto& rEntry : aEntries)
rEntry.SetValue(rIn.ReadUniString());
}
void ExcScenario::Apply( const XclImpRoot& rRoot, const bool bLast )
{
ScDocument& r = rRoot.GetDoc();
OUString aSzenName( aName );
sal_uInt16 nNewTab = nTab + 1;
if( !r.InsertTab( nNewTab, aSzenName ) )
return;
r.SetScenario( nNewTab, true );
// do not show scenario frames
const ScScenarioFlags nFlags = ScScenarioFlags::CopyAll
| (nProtected ? ScScenarioFlags::Protected : ScScenarioFlags::NONE);
/* | ScScenarioFlags::ShowFrame*/
r.SetScenarioData( nNewTab, aComment, COL_LIGHTGRAY, nFlags);
for (const auto& rEntry : aEntries)
{
sal_uInt16 nCol = rEntry.nCol;
sal_uInt16 nRow = rEntry.nRow;
OUString aVal = rEntry.GetValue();
r.ApplyFlagsTab( nCol, nRow, nCol, nRow, nNewTab, ScMF::Scenario );
r.SetString( nCol, nRow, nNewTab, aVal );
}
if( bLast )
r.SetActiveScenario( nNewTab, true );
// modify what the Active tab is set to if the new
// scenario tab occurs before the active tab.
ScExtDocSettings& rDocSett = rRoot.GetExtDocOptions().GetDocSettings();
if( (static_cast< SCCOL >( nTab ) < rDocSett.mnDisplTab) && (rDocSett.mnDisplTab < MAXTAB) )
++rDocSett.mnDisplTab;
rRoot.GetTabInfo().InsertScTab( nNewTab );
}
void ExcScenarioList::Apply( const XclImpRoot& rRoot )
{
sal_uInt16 n = static_cast<sal_uInt16>(aEntries.size());
std::vector< std::unique_ptr<ExcScenario> >::reverse_iterator iter;
for (iter = aEntries.rbegin(); iter != aEntries.rend(); ++iter)
{
n--;
(*iter)->Apply(rRoot, n == nLastScenario);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V530 The return value of function 'ReadUniString' is required to be utilized.