/* -*- 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 ScDPSaveGroupItem::AddElementsFromGroup( const ScDPSaveGroupItem& rGroup )
{ // add all elements of the other group (used for nested grouping)
aElements.insert( aElements.end(), rGroup.aElements.begin(), rGroup.aElements.end() );
}
bool ScDPSaveGroupItem::RemoveElement( const OUString& rName )
{ auto it = std::find(aElements.begin(), aElements.end(), rName); //TODO: ignore case if (it != aElements.end())
{
aElements.erase(it); returntrue;
} returnfalse; // not found
}
void ScDPSaveGroupItem::RemoveElementsFromGroups( ScDPSaveGroupDimension& rDimension ) const
{ // remove this group's elements from their groups in rDimension // (rDimension must be a different dimension from the one which contains this)
OUString ScDPSaveGroupDimension::CreateGroupName(std::u16string_view rPrefix)
{ // create a name for a new group, using "Group1", "Group2" etc. (translated prefix in rPrefix)
//TODO: look in all dimensions, to avoid clashes with automatic groups (=name of base element)? //TODO: (only dimensions for the same base)
sal_Int32 nAdd = 1; // first try is "Group1" const sal_Int32 nMaxAdd = nAdd + aGroups.size(); // limit the loop while ( nAdd <= nMaxAdd )
{
OUString aGroupName = rPrefix + OUString::number( nAdd );
// look for existing groups bool bExists = std::any_of(aGroups.begin(), aGroups.end(),
[&aGroupName](const ScDPSaveGroupItem& rGroup) { return rGroup.GetGroupName() == aGroupName; //TODO: ignore case
});
if ( !bExists ) return aGroupName; // found a new name
++nAdd; // continue with higher number
}
OSL_FAIL("CreateGroupName: no valid name found"); return OUString();
}
void ScDPSaveGroupDimension::RemoveFromGroups( const OUString& rItemName )
{ // if the item is in any group, remove it from the group, // also remove the group if it is empty afterwards
for ( ScDPSaveGroupItemVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); ++aIter ) if ( aIter->RemoveElement( rItemName ) )
{ if ( aIter->IsEmpty() ) // removed last item from the group?
aGroups.erase( aIter ); // then remove the group
return; // don't have to look further
}
}
void ScDPSaveGroupDimension::RemoveGroup(const OUString& rGroupName)
{ auto aIter = std::find_if(aGroups.begin(), aGroups.end(),
[&rGroupName](const ScDPSaveGroupItem& rGroup) { return rGroup.GetGroupName() == rGroupName; //TODO: ignore case
}); if (aIter != aGroups.end())
aGroups.erase( aIter );
}
bool ScDPSaveGroupDimension::HasOnlyHidden(const ScDPUniqueStringSet& rVisible)
{ // check if there are only groups that don't appear in the list of visible names
// For the start/end values, use the same date rounding as in // ScDPNumGroupDimension::GetNumEntries (but not for the list of // available years). if (rDateInfo.mbAutoStart)
rDateInfo.mfStart = rtl::math::approxFloor(fSourceMin); if (rDateInfo.mbAutoEnd)
rDateInfo.mfEnd = rtl::math::approxFloor(fSourceMax) + 1;
//TODO: if not automatic, limit fSourceMin/fSourceMax for list of year values?
tools::Long nStart = 0, nEnd = 0; // end is inclusive
switch (nDatePart)
{ case sheet::DataPilotFieldGroupBy::YEARS:
nStart = ScDPUtil::getDatePartValue(
fSourceMin, nullptr, sheet::DataPilotFieldGroupBy::YEARS, pFormatter);
nEnd = ScDPUtil::getDatePartValue(fSourceMax, nullptr, sheet::DataPilotFieldGroupBy::YEARS, pFormatter); break; case sheet::DataPilotFieldGroupBy::QUARTERS: nStart = 1; nEnd = 4; break; case sheet::DataPilotFieldGroupBy::MONTHS: nStart = 1; nEnd = 12; break; case sheet::DataPilotFieldGroupBy::DAYS: nStart = 1; nEnd = 366; break; case sheet::DataPilotFieldGroupBy::HOURS: nStart = 0; nEnd = 23; break; case sheet::DataPilotFieldGroupBy::MINUTES: nStart = 0; nEnd = 59; break; case sheet::DataPilotFieldGroupBy::SECONDS: nStart = 0; nEnd = 59; break; default:
OSL_FAIL("invalid date part");
}
// Now, populate the group items in the cache.
rCache.ResetGroupItems(nGroupDim, rDateInfo, nDatePart);
const ScDPCache::ScDPItemDataVec& rItems = rCache.GetDimMemberValues(nSourceDim); for (const ScDPItemData& rItem : rItems)
{ if (!IsInGroup(rItem)) // Not in any group. Add as its own group.
rCache.SetGroupItem(nDim, rItem);
}
}
if (fValue < fSourceMin)
fSourceMin = fValue; if (fValue > fSourceMax)
fSourceMax = fValue;
if (aGroupInfo.mbIntegerOnly && !isInteger(fValue))
{ // If any non-integer numbers are involved, the group labels // are shown including their upper limit.
aGroupInfo.mbIntegerOnly = false;
}
}
if (aGroupInfo.mbDateValues)
{ // special handling for dates: always integer, round down limits
aGroupInfo.mbIntegerOnly = true;
fSourceMin = rtl::math::approxFloor(fSourceMin);
fSourceMax = rtl::math::approxFloor(fSourceMax) + 1;
}
if (aGroupInfo.mbAutoStart)
aGroupInfo.mfStart = fSourceMin; if (aGroupInfo.mbAutoEnd)
aGroupInfo.mfEnd = fSourceMax;
// Use "less than" instead of "less or equal" for the loop - don't // create a group that consists only of the end value. Instead, the // end value is then included in the last group (last group is bigger // than the others). The first group has to be created nonetheless. // GetNumGroupForValue has corresponding logic.
ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNextNamedGroupDimAcc( const OUString& rGroupDimName )
{ // find the group dimension with the passed name
ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDimName ) ); // find next group dimension based on the same source dimension name if( aIt != maGroupDims.end() )
aIt = ::std::find_if( aIt + 1, maGroupDims.end(), ScDPSaveGroupSourceNameFunc( aIt->GetSourceDimName() ) ); return (aIt == maGroupDims.end()) ? nullptr : &*aIt;
}
sal_Int32 ScDPDimensionSaveData::CollectDateParts( const OUString& rBaseDimName ) const
{
sal_Int32 nParts = 0; // start with part of numeric group if( const ScDPSaveNumGroupDimension* pNumDim = GetNumGroupDim( rBaseDimName ) )
nParts |= pNumDim->GetDatePart(); // collect parts from all matching group dimensions for( const ScDPSaveGroupDimension* pGroupDim = GetFirstNamedGroupDim( rBaseDimName ); pGroupDim; pGroupDim = GetNextNamedGroupDim( pGroupDim->GetGroupDimName() ) )
nParts |= pGroupDim->GetDatePart();
return nParts;
}
OUString ScDPDimensionSaveData::CreateGroupDimName( const OUString& rSourceName, const ScDPObject& rObject, bool bAllowSource, const std::vector<OUString>* pDeletedNames )
{ // create a name for the new dimension by appending a number to the original // dimension's name
bool bUseSource = bAllowSource; // if set, try the unchanged original name first
sal_Int32 nAdd = 2; // first try is "Name2" const sal_Int32 nMaxAdd = 1000; // limit the loop while ( nAdd <= nMaxAdd )
{
OUString aDimName( rSourceName ); if ( !bUseSource )
aDimName += OUString::number(nAdd);
// look for existing group dimensions bool bExists = std::any_of(maGroupDims.begin(), maGroupDims.end(),
[&aDimName](const ScDPSaveGroupDimension& rDim) { return rDim.GetGroupDimName() == aDimName; //TODO: ignore case
});
// look for base dimensions that happen to have that name if ( !bExists && rObject.IsDimNameInUse( aDimName ) )
{ if ( pDeletedNames &&
std::find( pDeletedNames->begin(), pDeletedNames->end(), aDimName ) != pDeletedNames->end() )
{ // allow the name anyway if the name is in pDeletedNames
} else
bExists = true;
}
if ( !bExists ) return aDimName; // found a new name
if ( bUseSource )
bUseSource = false; else
++nAdd; // continue with higher number
}
OSL_FAIL("CreateGroupDimName: no valid name found"); return OUString();
}
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.