Kaydet (Commit) bc140731 authored tarafından Arkadiy Illarionov's avatar Arkadiy Illarionov Kaydeden (comit) Noel Grandin

Simplify containers iterations in sw/source/core

Use range-based loop or replace with STL functions

Change-Id: I53f9d76b5232488856098c86c6d51decc08a6b64
Reviewed-on: https://gerrit.libreoffice.org/63490
Tested-by: Jenkins
Reviewed-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
üst 9ffe350a
......@@ -184,26 +184,12 @@ bool SwNodeNum::IsCounted() const
// #i64010#
bool SwNodeNum::HasCountedChildren() const
{
bool bResult = false;
tSwNumberTreeChildren::const_iterator aIt;
for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
{
SwNodeNum* pChild( dynamic_cast<SwNodeNum*>(*aIt) );
OSL_ENSURE( pChild,
"<SwNodeNum::HasCountedChildren()> - unexpected type of child" );
if ( pChild &&
( pChild->IsCountedForNumbering() ||
pChild->HasCountedChildren() ) )
{
bResult = true;
break;
}
}
return bResult;
return std::any_of(mChildren.begin(), mChildren.end(),
[](SwNumberTreeNode* pNode) {
SwNodeNum* pChild( dynamic_cast<SwNodeNum*>(pNode) );
OSL_ENSURE( pChild, "<SwNodeNum::HasCountedChildren()> - unexpected type of child" );
return pChild && (pChild->IsCountedForNumbering() || pChild->HasCountedChildren());
});
}
// #i64010#
bool SwNodeNum::IsCountedForNumbering() const
......
......@@ -396,9 +396,8 @@ void SwNumberTreeNode::MoveChildren(SwNumberTreeNode * pDest)
aItBegin = mChildren.begin();
}
tSwNumberTreeChildren::iterator aIt;
for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
(*aIt)->mpParent = pDest;
for (auto& rpChild : mChildren)
rpChild->mpParent = pDest;
pDest->mChildren.insert(mChildren.begin(), mChildren.end());
mChildren.clear();
......@@ -846,8 +845,6 @@ void SwNumberTreeNode::IsSane(bool bRecursive,
vector<const SwNumberTreeNode *> rParents)
const
{
tSwNumberTreeChildren::const_iterator aIt;
assert(find(rParents.begin(), rParents.end(), this) == rParents.end());
assert(rParents.empty() || rParents.back() == mpParent);
......@@ -855,23 +852,23 @@ void SwNumberTreeNode::IsSane(bool bRecursive,
rParents.push_back(this);
bool bFirst = true;
for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
for (const auto& rpChild : mChildren)
{
if (*aIt)
if (rpChild)
{
if ((*aIt)->IsPhantom())
if (rpChild->IsPhantom())
{
SAL_WARN_IF((*aIt)->HasOnlyPhantoms(), "sw.core",
SAL_WARN_IF(rpChild->HasOnlyPhantoms(), "sw.core",
"HasOnlyPhantoms: is this an error?");
assert(bFirst && "found phantom not at first position.");
}
assert((*aIt)->mpParent == this);
assert(rpChild->mpParent == this);
if (mpParent)
{
assert((*aIt)->IsPhantom() || !(*aIt)->LessThan(*this));
assert(rpChild->IsPhantom() || !rpChild->LessThan(*this));
}
}
else
......@@ -881,7 +878,7 @@ void SwNumberTreeNode::IsSane(bool bRecursive,
if (bRecursive)
{
(*aIt)->IsSane(bRecursive, rParents);
rpChild->IsSane(bRecursive, rParents);
}
bFirst = false;
......@@ -1031,10 +1028,8 @@ void SwNumberTreeNode::InvalidateTree() const
// do not call SetInvalid, would cause loop !!!
mItLastValid = mChildren.end();
tSwNumberTreeChildren::const_iterator aIt;
for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
(*aIt)->InvalidateTree();
for (const auto& rpChild : mChildren)
rpChild->InvalidateTree();
}
void SwNumberTreeNode::Invalidate(SwNumberTreeNode const * pChild)
......@@ -1072,10 +1067,8 @@ void SwNumberTreeNode::Notify()
if (! IsPhantom())
NotifyNode();
tSwNumberTreeChildren::iterator aIt;
for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
(*aIt)->Notify();
for (auto& rpChild : mChildren)
rpChild->Notify();
}
}
......@@ -1174,20 +1167,16 @@ void SwNumberTreeNode::NotifyChildrenOnDepth( const int nDepth )
OSL_ENSURE( nDepth >= 0,
"<SwNumberTreeNode::NotifyChildrenOnDepth(..)> - misusage" );
SwNumberTreeNode::tSwNumberTreeChildren::iterator aChildIter =
mChildren.begin();
while ( aChildIter != mChildren.end() )
for ( const auto& rpChild : mChildren )
{
if ( nDepth == 0 )
{
(*aChildIter)->NotifyNode();
rpChild->NotifyNode();
}
else
{
(*aChildIter)->NotifyChildrenOnDepth( nDepth - 1 );
rpChild->NotifyChildrenOnDepth( nDepth - 1 );
}
++aChildIter;
}
}
......
......@@ -855,10 +855,10 @@ css::uno::Sequence< css::uno::Any >
if ( !vFrameList.empty() )
{
uno::Sequence< uno::Any > aRet(vFrameList.size());
auto aIter = vFrameList.begin();
for ( sal_Int32 nIndex = 0; aIter != vFrameList.end(); ++aIter, nIndex++ )
sal_Int32 nIndex = 0;
for ( const auto& rpFrame : vFrameList )
{
uno::Reference< XAccessible > xAcc = pAccMap->GetContext(*aIter, false);
uno::Reference< XAccessible > xAcc = pAccMap->GetContext(rpFrame, false);
if ( xAcc.is() )
{
SwAccessibleContext *pAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
......@@ -867,6 +867,7 @@ css::uno::Sequence< css::uno::Any >
aRet[nIndex] <<= xAcc;
}
}
nIndex++;
}
return aRet;
......
......@@ -107,11 +107,9 @@ SwAccessibleChildMap::SwAccessibleChildMap( const SwRect& rVisArea,
pAccImpl->GetAdditionalAccessibleChildren( &aAdditionalChildren );
sal_Int32 nCounter( 0 );
for ( std::vector< vcl::Window* >::iterator aIter = aAdditionalChildren.begin();
aIter != aAdditionalChildren.end();
++aIter )
for ( const auto& rpChild : aAdditionalChildren )
{
aLower = (*aIter);
aLower = rpChild;
insert( ++nCounter, SwAccessibleChildMapKey::XWINDOW, aLower );
}
}
......
......@@ -286,15 +286,12 @@ std::unique_ptr<SwAccessibleObjShape_Impl[]>
{
pShapes.reset(new SwAccessibleObjShape_Impl[rSize]);
const_iterator aIter = maMap.cbegin();
const_iterator aEndIter = maMap.cend();
SwAccessibleObjShape_Impl *pShape = pShapes.get();
pSelShape = &(pShapes[rSize]);
while( aIter != aEndIter )
for( const auto& rEntry : maMap )
{
const SdrObject *pObj = (*aIter).first;
uno::Reference < XAccessible > xAcc( (*aIter).second );
const SdrObject *pObj = rEntry.first;
uno::Reference < XAccessible > xAcc( rEntry.second );
if( nSelShapes && pFESh && pFESh->IsObjSelected( *pObj ) )
{
// selected objects are inserted from the back
......@@ -313,7 +310,6 @@ std::unique_ptr<SwAccessibleObjShape_Impl[]>
xAcc.get() );
++pShape;
}
++aIter;
}
assert(pSelShape == pShape);
}
......@@ -1405,23 +1401,19 @@ void SwAccessibleMap::InvalidateShapeInParaSelection()
}
if( bMarkChanged && mpFrameMap)
{
VEC_PARA::iterator vi = vecAdd.begin();
for (; vi != vecAdd.end() ; ++vi)
for (SwAccessibleContext* pAccPara : vecAdd)
{
AccessibleEventObject aEvent;
aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
SwAccessibleContext* pAccPara = *vi;
if (pAccPara)
{
pAccPara->FireAccessibleEvent( aEvent );
}
}
vi = vecRemove.begin();
for (; vi != vecRemove.end() ; ++vi)
for (SwAccessibleContext* pAccPara : vecRemove)
{
AccessibleEventObject aEvent;
aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
SwAccessibleContext* pAccPara = *vi;
if (pAccPara)
{
pAccPara->FireAccessibleEvent( aEvent );
......@@ -1483,10 +1475,9 @@ void SwAccessibleMap::DoInvalidateShapeSelection(bool bInvalidateFocusMode /*=fa
++pShape;
}
VEC_SHAPE::iterator vi =vecxShapeRemove.begin();
for (; vi != vecxShapeRemove.end(); ++vi)
for (const auto& rpShape : vecxShapeRemove)
{
::accessibility::AccessibleShape *pAccShape = vi->get();
::accessibility::AccessibleShape *pAccShape = rpShape.get();
if (pAccShape)
{
pAccShape->CommitChange(AccessibleEventId::SELECTION_CHANGED_REMOVE, uno::Any(), uno::Any());
......@@ -1538,10 +1529,9 @@ void SwAccessibleMap::DoInvalidateShapeSelection(bool bInvalidateFocusMode /*=fa
{
nEventID = AccessibleEventId::SELECTION_CHANGED;
}
vi = vecxShapeAdd.begin();
for (; vi != vecxShapeAdd.end(); ++vi)
for (const auto& rpShape : vecxShapeAdd)
{
::accessibility::AccessibleShape *pAccShape = vi->get();
::accessibility::AccessibleShape *pAccShape = rpShape.get();
if (pAccShape)
{
pAccShape->CommitChange(nEventID, uno::Any(), uno::Any());
......@@ -1549,10 +1539,9 @@ void SwAccessibleMap::DoInvalidateShapeSelection(bool bInvalidateFocusMode /*=fa
}
}
vi = vecxShapeAdd.begin();
for (; vi != vecxShapeAdd.end(); ++vi)
for (const auto& rpShape : vecxShapeAdd)
{
::accessibility::AccessibleShape *pAccShape = vi->get();
::accessibility::AccessibleShape *pAccShape = rpShape.get();
if (pAccShape)
{
SdrObject *pObj = GetSdrObjectFromXShape(pAccShape->GetXShape());
......@@ -1579,10 +1568,9 @@ void SwAccessibleMap::DoInvalidateShapeSelection(bool bInvalidateFocusMode /*=fa
}
}
}
vi = vecxShapeRemove.begin();
for (; vi != vecxShapeRemove.end(); ++vi)
for (const auto& rpShape : vecxShapeRemove)
{
::accessibility::AccessibleShape *pAccShape = vi->get();
::accessibility::AccessibleShape *pAccShape = rpShape.get();
if (pAccShape)
{
uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent();
......@@ -2688,10 +2676,8 @@ void SwAccessibleMap::InvalidateCursorPosition( const SwFrame *pFrame )
InvalidateShapeInParaSelection();
SET_PARA::iterator si = m_setParaRemove.begin();
for (; si != m_setParaRemove.end() ; ++si)
for (SwAccessibleParagraph* pAccPara : m_setParaRemove)
{
SwAccessibleParagraph* pAccPara = *si;
if(pAccPara && pAccPara->getSelectedAccessibleChildCount() == 0 && pAccPara->getSelectedText().getLength() == 0)
{
if(pAccPara->SetSelectedState(false))
......@@ -2702,10 +2688,8 @@ void SwAccessibleMap::InvalidateCursorPosition( const SwFrame *pFrame )
}
}
}
si = m_setParaAdd.begin();
for (; si != m_setParaAdd.end() ; ++si)
for (SwAccessibleParagraph* pAccPara : m_setParaAdd)
{
SwAccessibleParagraph* pAccPara = *si;
if(pAccPara && pAccPara->SetSelectedState(true))
{
AccessibleEventObject aEvent;
......
......@@ -1402,19 +1402,17 @@ uno::Sequence<PropertyValue> SwAccessibleParagraph::getCharacterAttributes(
// merge default and run attributes
std::vector< PropertyValue > aValues( aDefAttrSeq.size() );
sal_Int32 i = 0;
for ( tAccParaPropValMap::const_iterator aDefIter = aDefAttrSeq.begin();
aDefIter != aDefAttrSeq.end();
++aDefIter )
for ( const auto& rDefEntry : aDefAttrSeq )
{
tAccParaPropValMap::const_iterator aRunIter =
aRunAttrSeq.find( aDefIter->first );
aRunAttrSeq.find( rDefEntry.first );
if ( aRunIter != aRunAttrSeq.end() )
{
aValues[i] = aRunIter->second;
}
else
{
aValues[i] = aDefIter->second;
aValues[i] = rDefEntry.second;
}
++i;
}
......@@ -1429,11 +1427,9 @@ uno::Sequence<PropertyValue> SwAccessibleParagraph::getCharacterAttributes(
aValues.resize( aValues.size() + aSupplementalAttrSeq.size() );
for ( tAccParaPropValMap::const_iterator aSupplementalIter = aSupplementalAttrSeq.begin();
aSupplementalIter != aSupplementalAttrSeq.end();
++aSupplementalIter )
for ( const auto& rSupplementalEntry : aSupplementalAttrSeq )
{
aValues[i] = aSupplementalIter->second;
aValues[i] = rSupplementalEntry.second;
++i;
}
......@@ -1534,24 +1530,22 @@ void SwAccessibleParagraph::_getDefaultAttributesImpl(
const SfxItemPropertyMap& rPropMap =
aSwMapProvider.GetPropertySet( PROPERTY_MAP_TEXT_CURSOR )->getPropertyMap();
PropertyEntryVector_t aPropertyEntries = rPropMap.getPropertyEntries();
PropertyEntryVector_t::const_iterator aPropIt = aPropertyEntries.begin();
while ( aPropIt != aPropertyEntries.end() )
for ( const auto& rProp : aPropertyEntries )
{
const SfxPoolItem* pItem = pSet->GetItem( aPropIt->nWID );
const SfxPoolItem* pItem = pSet->GetItem( rProp.nWID );
if ( pItem )
{
uno::Any aVal;
pItem->QueryValue( aVal, aPropIt->nMemberId );
pItem->QueryValue( aVal, rProp.nMemberId );
PropertyValue rPropVal;
rPropVal.Name = aPropIt->sName;
rPropVal.Name = rProp.sName;
rPropVal.Value = aVal;
rPropVal.Handle = -1;
rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
aDefAttrSeq[rPropVal.Name] = rPropVal;
}
++aPropIt;
}
// #i72800#
......@@ -1669,11 +1663,9 @@ uno::Sequence< PropertyValue > SwAccessibleParagraph::getDefaultAttributes(
( bProvideMMToPixelRatio ? 1 : 0 ) );
PropertyValue* pValues = aValues.getArray();
sal_Int32 i = 0;
for ( tAccParaPropValMap::const_iterator aIter = aDefAttrSeq.begin();
aIter != aDefAttrSeq.end();
++aIter )
for ( const auto& rEntry : aDefAttrSeq )
{
pValues[i] = aIter->second;
pValues[i] = rEntry.second;
++i;
}
......@@ -1750,19 +1742,18 @@ void SwAccessibleParagraph::_getRunAttributesImpl(
const SfxItemPropertyMap& rPropMap =
aSwMapProvider.GetPropertySet( PROPERTY_MAP_TEXT_CURSOR )->getPropertyMap();
PropertyEntryVector_t aPropertyEntries = rPropMap.getPropertyEntries();
PropertyEntryVector_t::const_iterator aPropIt = aPropertyEntries.begin();
while ( aPropIt != aPropertyEntries.end() )
for ( const auto& rProp : aPropertyEntries )
{
const SfxPoolItem* pItem( nullptr );
// #i82637# - Found character attributes, whose value equals the value of
// the corresponding default character attributes, are excluded.
if ( aSet.GetItemState( aPropIt->nWID, true, &pItem ) == SfxItemState::SET )
if ( aSet.GetItemState( rProp.nWID, true, &pItem ) == SfxItemState::SET )
{
uno::Any aVal;
pItem->QueryValue( aVal, aPropIt->nMemberId );
pItem->QueryValue( aVal, rProp.nMemberId );
PropertyValue rPropVal;
rPropVal.Name = aPropIt->sName;
rPropVal.Name = rProp.sName;
rPropVal.Value = aVal;
rPropVal.Handle = -1;
rPropVal.State = PropertyState_DIRECT_VALUE;
......@@ -1775,8 +1766,6 @@ void SwAccessibleParagraph::_getRunAttributesImpl(
aRunAttrSeq[rPropVal.Name] = rPropVal;
}
}
++aPropIt;
}
}
......
......@@ -182,11 +182,8 @@ void SwAccessibleSelectionHelper::selectAllAccessibleChildren( )
std::list< SwAccessibleChild > aChildren;
m_rContext.GetChildren( *(m_rContext.GetMap()), aChildren );
std::list< SwAccessibleChild >::const_iterator aIter = aChildren.begin();
std::list< SwAccessibleChild >::const_iterator aEndIter = aChildren.end();
while( aIter != aEndIter )
for( const SwAccessibleChild& rChild : aChildren )
{
const SwAccessibleChild& rChild = *aIter;
const SdrObject* pObj = rChild.GetDrawObject();
const SwFrame* pFrame = rChild.GetSwFrame();
if( pObj && !(pFrame != nullptr && pFEShell->IsObjSelected()) )
......@@ -195,7 +192,6 @@ void SwAccessibleSelectionHelper::selectAllAccessibleChildren( )
if( pFrame )
break;
}
++aIter;
}
}
}
......@@ -223,13 +219,8 @@ sal_Int32 SwAccessibleSelectionHelper::getSelectedAccessibleChildCount( )
std::list< SwAccessibleChild > aChildren;
m_rContext.GetChildren( *(m_rContext.GetMap()), aChildren );
std::list< SwAccessibleChild >::const_iterator aIter =
aChildren.begin();
std::list< SwAccessibleChild >::const_iterator aEndIter =
aChildren.end();
while( aIter != aEndIter && static_cast<size_t>(nCount) < nSelObjs )
for( const SwAccessibleChild& rChild : aChildren )
{
const SwAccessibleChild& rChild = *aIter;
if( rChild.GetDrawObject() && !rChild.GetSwFrame() &&
SwAccessibleFrame::GetParent(rChild, m_rContext.IsInPagePreview())
== m_rContext.GetFrame() &&
......@@ -237,7 +228,8 @@ sal_Int32 SwAccessibleSelectionHelper::getSelectedAccessibleChildCount( )
{
nCount++;
}
++aIter;
if (static_cast<size_t>(nCount) >= nSelObjs)
break;
}
}
}
......@@ -247,17 +239,8 @@ sal_Int32 SwAccessibleSelectionHelper::getSelectedAccessibleChildCount( )
{
std::list< SwAccessibleChild > aChildren;
m_rContext.GetChildren( *(m_rContext.GetMap()), aChildren );
std::list< SwAccessibleChild >::const_iterator aIter =
aChildren.begin();
std::list< SwAccessibleChild >::const_iterator aEndIter =
aChildren.end();
while( aIter != aEndIter )
{
const SwAccessibleChild& aChild = *aIter;
if( lcl_getSelectedState( aChild, &m_rContext, m_rContext.GetMap() ) )
nCount++;
++aIter;
}
nCount = static_cast<sal_Int32>(std::count_if(aChildren.begin(), aChildren.end(),
[this](const SwAccessibleChild& aChild) { return lcl_getSelectedState(aChild, &m_rContext, m_rContext.GetMap()); }));
}
}
return nCount;
......@@ -310,11 +293,8 @@ Reference<XAccessible> SwAccessibleSelectionHelper::getSelectedAccessibleChild(
std::list< SwAccessibleChild > aChildren;
m_rContext.GetChildren( *(m_rContext.GetMap()), aChildren );
std::list< SwAccessibleChild >::const_iterator aIter = aChildren.begin();
std::list< SwAccessibleChild >::const_iterator aEndIter = aChildren.end();
while( aIter != aEndIter && !aChild.IsValid() )
for( const SwAccessibleChild& rChild : aChildren )
{
const SwAccessibleChild& rChild = *aIter;
if( rChild.GetDrawObject() && !rChild.GetSwFrame() &&
SwAccessibleFrame::GetParent(rChild, m_rContext.IsInPagePreview()) ==
m_rContext.GetFrame() &&
......@@ -325,7 +305,8 @@ Reference<XAccessible> SwAccessibleSelectionHelper::getSelectedAccessibleChild(
else
--nSelectedChildIndex;
}
++aIter;
if (aChild.IsValid())
break;
}
}
......
......@@ -1589,14 +1589,13 @@ void SwAccessibleTable::FireSelectionEvent( )
aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
for (Cells_t::iterator vi = m_vecCellRemove.begin();
vi != m_vecCellRemove.end(); ++vi)
for (const auto& rCell : m_vecCellRemove)
{
// fdo#57197: check if the object is still alive
uno::Reference<XAccessible> const xAcc(vi->second);
uno::Reference<XAccessible> const xAcc(rCell.second);
if (xAcc.is())
{
SwAccessibleContext *const pAccCell(vi->first);
SwAccessibleContext *const pAccCell(rCell.first);
assert(pAccCell);
pAccCell->FireAccessibleEvent(aEvent);
}
......@@ -1605,14 +1604,13 @@ void SwAccessibleTable::FireSelectionEvent( )
if (m_vecCellAdd.size() <= SELECTION_WITH_NUM)
{
aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD;
for (Cells_t::iterator vi = m_vecCellAdd.begin();
vi != m_vecCellAdd.end(); ++vi)
for (const auto& rCell : m_vecCellAdd)
{
// fdo#57197: check if the object is still alive
uno::Reference<XAccessible> const xAcc(vi->second);
uno::Reference<XAccessible> const xAcc(rCell.second);
if (xAcc.is())
{
SwAccessibleContext *const pAccCell(vi->first);
SwAccessibleContext *const pAccCell(rCell.first);
assert(pAccCell);
pAccCell->FireAccessibleEvent(aEvent);
}
......
......@@ -126,8 +126,8 @@ SwCache::~SwCache()
Check();
#endif
for(SwCacheObjArr::const_iterator it = m_aCacheObjects.begin(); it != m_aCacheObjects.end(); ++it)
delete *it;
for(const auto& rpObj : m_aCacheObjects)
delete rpObj;
}
void SwCache::IncreaseMax( const sal_uInt16 nAdd )
......
......@@ -76,10 +76,9 @@ void SwTabCols::Insert( long nValue, bool bValue, size_t nPos )
aData.insert( aData.begin() + nPos, aEntry );
#if OSL_DEBUG_LEVEL > 1
SwTabColsEntries::iterator aPos = aData.begin();
for ( ; aPos != aData.end(); ++aPos )
for ( const auto& rPos : aData )
{
aEntry =(*aPos);
aEntry = rPos;
}
#endif
}
......
......@@ -64,6 +64,7 @@
#include <IDocumentLayoutAccess.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <comphelper/lok.hxx>
#include <comphelper/sequence.hxx>
#include <sfx2/lokhelper.hxx>
#include <editeng/editview.hxx>
#include <sal/log.hxx>
......@@ -3546,12 +3547,7 @@ static void lcl_FillRecognizerData( std::vector< OUString >& rSmartTagTypes,
if ( !rSmartTagTypes.empty() )
{
rStringKeyMaps.realloc( rSmartTagTypes.size() );
std::vector< uno::Reference< container::XStringKeyMap > >::const_iterator aMapsIter = aStringKeyMaps.begin();
sal_uInt16 i = 0;
for ( aMapsIter = aStringKeyMaps.begin(); aMapsIter != aStringKeyMaps.end(); ++aMapsIter )
rStringKeyMaps[i++] = *aMapsIter;
rStringKeyMaps = comphelper::containerToSequence(aStringKeyMaps);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment