use insert function instead of for loop
[LibreOffice.git] / oox / source / drawingml / diagram / layoutatomvisitorbase.cxx
blob6ffa1c34e57bd5c729b0425c83f115a4ff3bdc26
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "layoutatomvisitorbase.hxx"
22 #include <sal/log.hxx>
24 using namespace ::com::sun::star;
26 namespace oox::drawingml {
28 void LayoutAtomVisitorBase::defaultVisit(LayoutAtom const& rAtom)
30 for (const auto& pAtom : rAtom.getChildren())
31 pAtom->accept(*this);
34 void LayoutAtomVisitorBase::visit(ChooseAtom& rAtom)
36 for (const auto& pChild : rAtom.getChildren())
38 const ConditionAtomPtr pCond = std::dynamic_pointer_cast<ConditionAtom>(pChild);
39 if (pCond && pCond->getDecision(mpCurrentNode))
41 SAL_INFO("oox.drawingml", "Entering if node: " << pCond->getName());
42 pCond->accept(*this);
43 break;
48 void LayoutAtomVisitorBase::visit(ConditionAtom& rAtom)
50 defaultVisit(rAtom);
53 void LayoutAtomVisitorBase::visit(ForEachAtom& rAtom)
55 if (!rAtom.getRef().isEmpty())
57 if (LayoutAtomPtr pRefAtom = rAtom.getRefAtom())
58 pRefAtom->accept(*this);
59 return;
62 if (rAtom.iterator().mbHideLastTrans && !rAtom.iterator().maAxis.empty() && rAtom.iterator().maAxis[0] == XML_followSib)
64 // If last transition is hidden and the axis is the follow sibling,
65 // then the last atom should not be visited.
66 if (mnCurrIdx + mnCurrStep >= mnCurrCnt)
67 return;
70 sal_Int32 nChildren = 1;
71 // Approximate the non-assistant type with the node type.
72 if (rAtom.iterator().mnPtType == XML_node || rAtom.iterator().mnPtType == XML_nonAsst)
74 // count child data nodes - check all child Atoms for "name"
75 // attribute that is contained in diagram's
76 // getPointsPresNameMap()
77 ShallowPresNameVisitor aVisitor(mrDgm, mpCurrentNode);
78 for (const auto& pAtom : rAtom.getChildren())
79 pAtom->accept(aVisitor);
80 nChildren = aVisitor.getCount();
83 const sal_Int32 nCnt = std::min(
84 nChildren,
85 rAtom.iterator().mnCnt==-1 ? nChildren : rAtom.iterator().mnCnt);
87 const sal_Int32 nOldIdx = mnCurrIdx;
88 const sal_Int32 nOldStep = mnCurrStep;
89 const sal_Int32 nOldCnt = mnCurrCnt;
90 const sal_Int32 nStep = rAtom.iterator().mnStep;
91 mnCurrStep = nStep;
92 mnCurrCnt = nCnt;
93 for( mnCurrIdx=0; mnCurrIdx<nCnt && nStep>0; mnCurrIdx+=nStep )
95 // TODO there is likely some conditions
96 for (const auto& pAtom : rAtom.getChildren())
97 pAtom->accept(*this);
100 // and restore idx
101 mnCurrIdx = nOldIdx;
102 mnCurrStep = nOldStep;
103 mnCurrCnt = nOldCnt;
106 void LayoutAtomVisitorBase::visit(LayoutNode& rAtom)
108 // TODO: deduplicate code in descendants
110 // stop processing if it's not a child of previous LayoutNode
112 const DiagramData::PointsNameMap::const_iterator aDataNode
113 = mrDgm.getData()->getPointsPresNameMap().find(rAtom.getName());
114 if (aDataNode == mrDgm.getData()->getPointsPresNameMap().end()
115 || mnCurrIdx >= static_cast<sal_Int32>(aDataNode->second.size()))
116 return;
118 const svx::diagram::Point* pNewNode = aDataNode->second.at(mnCurrIdx);
119 if (!mpCurrentNode || !pNewNode)
120 return;
122 bool bIsChild = false;
123 for (const auto& aConnection : mrDgm.getData()->getConnections())
124 if (aConnection.msSourceId == mpCurrentNode->msModelId
125 && aConnection.msDestId == pNewNode->msModelId)
126 bIsChild = true;
128 if (!bIsChild)
129 return;
131 const svx::diagram::Point* pPreviousNode = mpCurrentNode;
132 mpCurrentNode = pNewNode;
134 defaultVisit(rAtom);
136 mpCurrentNode = pPreviousNode;
139 void ShallowPresNameVisitor::visit(ConstraintAtom& /*rAtom*/)
141 // stop processing
144 void ShallowPresNameVisitor::visit(RuleAtom& /*rAtom*/)
146 // stop processing
149 void ShallowPresNameVisitor::visit(AlgAtom& /*rAtom*/)
151 // stop processing
154 void ShallowPresNameVisitor::visit(ForEachAtom& rAtom)
156 defaultVisit(rAtom);
159 void ShallowPresNameVisitor::visit(LayoutNode& rAtom)
161 DiagramData::PointsNameMap::const_iterator aDataNode =
162 mrDgm.getData()->getPointsPresNameMap().find(rAtom.getName());
163 if( aDataNode != mrDgm.getData()->getPointsPresNameMap().end() )
164 mnCnt = std::max(mnCnt,
165 aDataNode->second.size());
168 void ShallowPresNameVisitor::visit(ShapeAtom& /*rAtom*/)
170 // stop processing
175 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */