/* -*- 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 .
*/
void ScDPSaveMember::SetName( const OUString& rNew )
{ // Used only if the source member was renamed (groups). // For UI renaming of members, a layout name must be used.
void ScDPSaveDimension::SetName( const OUString& rNew )
{ // Used only if the source dim was renamed (groups). // For UI renaming of dimensions, the layout name must be used.
void ScDPSaveDimension::SetMemberPosition( const OUString& rName, sal_Int32 nNewPos )
{
ScDPSaveMember* pMember = GetMemberByName( rName ); // make sure it exists and is in the hash
if (mpLayoutName)
ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_LAYOUTNAME, *mpLayoutName);
const std::optional<OUString> & pSubTotalName = GetSubtotalName(); if (pSubTotalName) // Custom subtotal name, with '?' being replaced by the visible field name later.
ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_FIELD_SUBTOTALNAME, *pSubTotalName);
}
// Level loop outside of maMemberList loop // because SubTotals have to be set independently of known members
if (mpDimensionData || rOther.mpDimensionData) if (!mpDimensionData || !rOther.mpDimensionData || !(*mpDimensionData == *rOther.mpDimensionData)) returnfalse;
if (!(::comphelper::ContainerUniquePtrEquals(m_DimList, rOther.m_DimList))) returnfalse;
if (mpGrandTotalName)
{ if (!rOther.mpGrandTotalName) returnfalse; if (*mpGrandTotalName != *rOther.mpGrandTotalName) returnfalse;
} elseif (rOther.mpGrandTotalName) returnfalse;
ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(DataPilotFieldOrientation nOrientation)
{ // return the innermost dimension for the given orientation, // excluding data layout dimension
auto iter = std::find_if(m_DimList.rbegin(), m_DimList.rend(),
[&nOrientation](const std::unique_ptr<ScDPSaveDimension>& rxDim) { return rxDim->GetOrientation() == nOrientation && !rxDim->IsDataLayout(); }); if (iter != m_DimList.rend()) return iter->get();
return nullptr;
}
ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation)
{ for (autoconst& iter : m_DimList)
{ if (iter->GetOrientation() == eOrientation && !iter->IsDataLayout()) return &(*iter);
} return nullptr;
}
auto it = std::find_if(m_DimList.begin(), m_DimList.end(),
[&pDim](const std::unique_ptr<ScDPSaveDimension>& rxDim) { return pDim == rxDim.get(); }); if (it != m_DimList.end())
{ // Tell vector<unique_ptr> to give up ownership of this element. Don't // delete this instance as it is re-inserted into the container later. // coverity[leaked_storage] - re-inserted into the container later
it->release();
m_DimList.erase(it);
}
void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
{ if (!xSource.is()) return;
// source options must be first!
uno::Reference<beans::XPropertySet> xSourceProp( xSource, uno::UNO_QUERY );
SAL_WARN_IF( !xSourceProp.is(), "sc.core", "no properties at source" ); if ( xSourceProp.is() )
{ // source options are not available for external sources //TODO: use XPropertySetInfo to test for availability?
try
{ if (mnIgnoreEmptyMode != SC_DPSAVEMODE_DONTKNOW)
lcl_SetBoolProperty(xSourceProp, SC_UNO_DP_IGNOREEMPTY, bool(mnIgnoreEmptyMode)); if (mnRepeatEmptyMode != SC_DPSAVEMODE_DONTKNOW)
lcl_SetBoolProperty(xSourceProp, SC_UNO_DP_REPEATEMPTY, bool(mnRepeatEmptyMode));
} catch(uno::Exception&)
{ // no error
}
// exceptions in the other calls are errors try
{ // reset all orientations //TODO: "forgetSettings" or similar at source ????? //TODO: reset all duplicated dimensions, or reuse them below !!!
SAL_INFO("sc.core", "ScDPSaveData::WriteToSource");
if (bFound)
{ if (rxDim->GetDupFlag())
{
uno::Reference<util::XCloneable> xCloneable(xIntDim, uno::UNO_QUERY);
SAL_WARN_IF(!xCloneable.is(), "sc.core", "cannot clone dimension"); if (xCloneable.is())
{
uno::Reference<util::XCloneable> xNew = xCloneable->createClone();
uno::Reference<container::XNamed> xNewName(xNew, uno::UNO_QUERY); if (xNewName.is())
{
xNewName->setName(aName);
rxDim->WriteToSource(xNew);
}
}
} else
rxDim->WriteToSource( xIntDim );
}
}
SAL_WARN_IF(!bFound, "sc.core", "WriteToSource: Dimension not found: " + aName + ".");
}
if ( xSourceProp.is() )
{ if (mnColumnGrandMode != SC_DPSAVEMODE_DONTKNOW)
lcl_SetBoolProperty(xSourceProp, SC_UNO_DP_COLGRAND, bool(mnColumnGrandMode)); if (mnRowGrandMode != SC_DPSAVEMODE_DONTKNOW)
lcl_SetBoolProperty(xSourceProp, SC_UNO_DP_ROWGRAND, bool(mnRowGrandMode));
}
} catch(uno::Exception const &)
{
TOOLS_WARN_EXCEPTION("sc.core", "WriteToSource");
}
}
bool ScDPSaveData::IsEmpty() const
{ for (autoconst& iter : m_DimList)
{ if (iter->GetOrientation() != sheet::DataPilotFieldOrientation_HIDDEN && !iter->IsDataLayout()) returnfalse;
} returntrue; // no entries that are not hidden
}
void ScDPSaveData::RemoveAllGroupDimensions( const OUString& rSrcDimName, std::vector<OUString>* pDeletedNames )
{ if (!mpDimensionData) // No group dimensions exist. Nothing to do. return;
// Remove numeric group dimension (exists once at most). No need to delete // anything in save data (grouping was done inplace in an existing base // dimension).
mpDimensionData->RemoveNumGroupDimension(rSrcDimName);
// Remove named group dimension(s). Dimensions have to be removed from // dimension save data and from save data too. const ScDPSaveGroupDimension* pExistingGroup = mpDimensionData->GetGroupDimForBase(rSrcDimName); while ( pExistingGroup )
{
OUString aGroupDimName = pExistingGroup->GetGroupDimName();
mpDimensionData->RemoveGroupDimension(aGroupDimName); // pExistingGroup is deleted
// also remove SaveData settings for the dimension that no longer exists
RemoveDimensionByName(aGroupDimName);
if (pDeletedNames)
pDeletedNames->push_back(aGroupDimName);
// see if there are more group dimensions
pExistingGroup = mpDimensionData->GetGroupDimForBase(rSrcDimName);
if ( pExistingGroup && pExistingGroup->GetGroupDimName() == aGroupDimName )
{ // still get the same group dimension?
OSL_FAIL("couldn't remove group dimension");
pExistingGroup = nullptr; // avoid endless loop
}
}
}
ScDPDimensionSaveData* ScDPSaveData::GetDimensionData()
{ if (!mpDimensionData)
mpDimensionData.reset(new ScDPDimensionSaveData); return mpDimensionData.get();
}
void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
{ if (mbDimensionMembersBuilt) return;
// First, build a dimension name-to-index map. typedef std::unordered_map<OUString, tools::Long> NameIndexMap;
NameIndexMap aMap;
tools::Long nColCount = pData->GetColumnCount(); for (tools::Long i = 0; i < nColCount; ++i)
aMap.emplace(pData->getDimensionName(i), i);
NameIndexMap::const_iterator itrEnd = aMap.end();
for (autoconst& iter : m_DimList)
{ const OUString& rDimName = iter->GetName(); if (rDimName.isEmpty()) // empty dimension name. It must be data layout. continue;
NameIndexMap::const_iterator itr = aMap.find(rDimName); if (itr == itrEnd) // dimension name not in the data. This should never happen! continue;
tools::Long nDimIndex = itr->second; const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
size_t nMemberCount = rMembers.size(); for (size_t j = 0; j < nMemberCount; ++j)
{ const ScDPItemData* pMemberData = pData->GetMemberById( nDimIndex, rMembers[j] );
OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData, false); if (iter->GetExistingMemberByName(aMemName)) // this member instance already exists. nothing to do. continue;
for (autoconst& it : m_DimList)
{ const OUString& rDimName = it->GetName(); if (rDimName.isEmpty()) // empty dimension name. It must be data layout. continue;
NameIndexMap::const_iterator itMap = aMap.find(rDimName); if (itMap == itMapEnd) // dimension name not in the data. This should never happen! continue;
DupNameCountType::iterator it = maDupNameCounts.find(aCoreName); if (it == maDupNameCounts.end()) return;
if (!it->second)
{
maDupNameCounts.erase(it); return;
}
--it->second;
}
ScDPSaveDimension* ScDPSaveData::AppendNewDimension(const OUString& rName, bool bDataLayout)
{ if (ScDPUtil::isDuplicateDimension(rName)) // This call is for original dimensions only. return nullptr;
ScDPSaveDimension* pNew = new ScDPSaveDimension(rName, bDataLayout);
m_DimList.push_back(std::unique_ptr<ScDPSaveDimension>(pNew)); if (!maDupNameCounts.count(rName))
maDupNameCounts.emplace(rName, 0);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.