1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * This file is part of the libvisio project.
4  *
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/.
8  */
9 
10 #include "VSDParagraphList.h"
11 
12 #include "VSDCollector.h"
13 
14 namespace libvisio
15 {
16 
17 class VSDParagraphListElement
18 {
19 public:
VSDParagraphListElement(unsigned id,unsigned level)20   VSDParagraphListElement(unsigned id, unsigned level) : m_id(id), m_level(level) {}
~VSDParagraphListElement()21   virtual ~VSDParagraphListElement() {}
22   virtual void handle(VSDCollector *collector) const = 0;
23   virtual VSDParagraphListElement *clone() = 0;
24   virtual unsigned getCharCount() const = 0;
25   virtual void setCharCount(unsigned charCount) = 0;
26 
27   unsigned m_id, m_level;
28 };
29 
30 class VSDParaIX : public VSDParagraphListElement
31 {
32 public:
VSDParaIX(unsigned id,unsigned level,unsigned charCount,const boost::optional<double> & indFirst,const boost::optional<double> & indLeft,const boost::optional<double> & indRight,const boost::optional<double> & spLine,const boost::optional<double> & spBefore,const boost::optional<double> & spAfter,const boost::optional<unsigned char> & align,const boost::optional<unsigned char> & bullet,const boost::optional<VSDName> & bulletStr,const boost::optional<VSDName> & bulletFont,const boost::optional<double> & bulletFontSize,const boost::optional<double> & textPosAfterBullet,const boost::optional<unsigned> & flags)33   VSDParaIX(unsigned id, unsigned level, unsigned charCount, const boost::optional<double> &indFirst,
34             const boost::optional<double> &indLeft, const boost::optional<double> &indRight,
35             const boost::optional<double> &spLine, const boost::optional<double> &spBefore,
36             const boost::optional<double> &spAfter, const boost::optional<unsigned char> &align,
37             const boost::optional<unsigned char> &bullet, const boost::optional<VSDName> &bulletStr,
38             const boost::optional<VSDName> &bulletFont, const boost::optional<double> &bulletFontSize,
39             const boost::optional<double> &textPosAfterBullet, const boost::optional<unsigned> &flags) :
40     VSDParagraphListElement(id, level),
41     m_style(charCount, indFirst, indLeft, indRight, spLine, spBefore, spAfter,
42             align, bullet, bulletStr, bulletFont, bulletFontSize, textPosAfterBullet, flags) {}
~VSDParaIX()43   ~VSDParaIX() override {}
44   void handle(VSDCollector *collector) const override;
45   VSDParagraphListElement *clone() override;
getCharCount() const46   unsigned getCharCount() const override
47   {
48     return m_style.charCount;
49   }
setCharCount(unsigned charCount)50   void setCharCount(unsigned charCount) override
51   {
52     m_style.charCount = charCount;
53   }
54 
55   VSDOptionalParaStyle m_style;
56 };
57 } // namespace libvisio
58 
59 
handle(VSDCollector * collector) const60 void libvisio::VSDParaIX::handle(VSDCollector *collector) const
61 {
62   collector->collectParaIX(m_id, m_level, m_style.charCount, m_style.indFirst, m_style.indLeft,
63                            m_style.indRight, m_style.spLine, m_style.spBefore, m_style.spAfter,
64                            m_style.align, m_style.bullet, m_style.bulletStr, m_style.bulletFont,
65                            m_style.bulletFontSize, m_style.textPosAfterBullet, m_style.flags);
66 }
67 
clone()68 libvisio::VSDParagraphListElement *libvisio::VSDParaIX::clone()
69 {
70   return new VSDParaIX(m_id, m_level, m_style.charCount, m_style.indFirst, m_style.indLeft,
71                        m_style.indRight, m_style.spLine, m_style.spBefore, m_style.spAfter,
72                        m_style.align, m_style.bullet, m_style.bulletStr, m_style.bulletFont,
73                        m_style.bulletFontSize, m_style.textPosAfterBullet, m_style.flags);
74 }
75 
76 
VSDParagraphList()77 libvisio::VSDParagraphList::VSDParagraphList() :
78   m_elements(),
79   m_elementsOrder()
80 {
81 }
82 
VSDParagraphList(const libvisio::VSDParagraphList & paraList)83 libvisio::VSDParagraphList::VSDParagraphList(const libvisio::VSDParagraphList &paraList) :
84   m_elements(),
85   m_elementsOrder(paraList.m_elementsOrder)
86 {
87   for (auto iter = paraList.m_elements.begin(); iter != paraList.m_elements.end(); ++iter)
88     m_elements[iter->first] = clone(iter->second);
89 }
90 
operator =(const libvisio::VSDParagraphList & paraList)91 libvisio::VSDParagraphList &libvisio::VSDParagraphList::operator=(const libvisio::VSDParagraphList &paraList)
92 {
93   if (this != &paraList)
94   {
95     clear();
96     for (auto iter = paraList.m_elements.begin(); iter != paraList.m_elements.end(); ++iter)
97       m_elements[iter->first] = clone(iter->second);
98     m_elementsOrder = paraList.m_elementsOrder;
99   }
100   return *this;
101 }
102 
~VSDParagraphList()103 libvisio::VSDParagraphList::~VSDParagraphList()
104 {
105 }
106 
addParaIX(unsigned id,unsigned level,unsigned charCount,const boost::optional<double> & indFirst,const boost::optional<double> & indLeft,const boost::optional<double> & indRight,const boost::optional<double> & spLine,const boost::optional<double> & spBefore,const boost::optional<double> & spAfter,const boost::optional<unsigned char> & align,const boost::optional<unsigned char> & bullet,const boost::optional<VSDName> & bulletStr,const boost::optional<VSDName> & bulletFont,const boost::optional<double> & bulletFontSize,const boost::optional<double> & textPosAfterBullet,const boost::optional<unsigned> & flags)107 void libvisio::VSDParagraphList::addParaIX(unsigned id, unsigned level, unsigned charCount, const boost::optional<double> &indFirst,
108                                            const boost::optional<double> &indLeft, const boost::optional<double> &indRight,
109                                            const boost::optional<double> &spLine, const boost::optional<double> &spBefore,
110                                            const boost::optional<double> &spAfter, const boost::optional<unsigned char> &align,
111                                            const boost::optional<unsigned char> &bullet, const boost::optional<VSDName> &bulletStr,
112                                            const boost::optional<VSDName> &bulletFont, const boost::optional<double> &bulletFontSize,
113                                            const boost::optional<double> &textPosAfterBullet, const boost::optional<unsigned> &flags)
114 {
115   auto *tmpElement = dynamic_cast<VSDParaIX *>(m_elements[id].get());
116   if (!tmpElement)
117     m_elements[id] = make_unique<VSDParaIX>(id, level, charCount, indFirst, indLeft, indRight, spLine, spBefore,
118                                             spAfter, align, bullet, bulletStr, bulletFont, bulletFontSize,
119                                             textPosAfterBullet, flags);
120   else
121     tmpElement->m_style.override(VSDOptionalParaStyle(charCount, indFirst, indLeft, indRight, spLine, spBefore,
122                                                       spAfter, align, bullet, bulletStr, bulletFont, bulletFontSize,
123                                                       textPosAfterBullet, flags));
124 }
125 
addParaIX(unsigned id,unsigned level,const VSDOptionalParaStyle & style)126 void libvisio::VSDParagraphList::addParaIX(unsigned id, unsigned level, const VSDOptionalParaStyle &style)
127 {
128   addParaIX(id, level, style.charCount, style.indFirst, style.indLeft, style.indRight,
129             style.spLine, style.spBefore, style.spAfter, style.align,
130             style.bullet, style.bulletStr, style.bulletFont, style.bulletFontSize,
131             style.textPosAfterBullet, style.flags);
132 }
133 
getCharCount(unsigned id) const134 unsigned libvisio::VSDParagraphList::getCharCount(unsigned id) const
135 {
136   auto iter = m_elements.find(id);
137   if (iter != m_elements.end() && iter->second)
138     return iter->second->getCharCount();
139   else
140     return MINUS_ONE;
141 }
142 
setCharCount(unsigned id,unsigned charCount)143 void libvisio::VSDParagraphList::setCharCount(unsigned id, unsigned charCount)
144 {
145   auto iter = m_elements.find(id);
146   if (iter != m_elements.end() && iter->second)
147     iter->second->setCharCount(charCount);
148 }
149 
resetCharCount()150 void libvisio::VSDParagraphList::resetCharCount()
151 {
152   for (auto &element : m_elements)
153     element.second->setCharCount(0);
154 }
155 
getLevel() const156 unsigned libvisio::VSDParagraphList::getLevel() const
157 {
158   if (m_elements.empty() || !m_elements.begin()->second)
159     return 0;
160   return m_elements.begin()->second->m_level;
161 }
162 
setElementsOrder(const std::vector<unsigned> & elementsOrder)163 void libvisio::VSDParagraphList::setElementsOrder(const std::vector<unsigned> &elementsOrder)
164 {
165   m_elementsOrder.clear();
166   for (unsigned int i : elementsOrder)
167     m_elementsOrder.push_back(i);
168 }
169 
handle(VSDCollector * collector) const170 void libvisio::VSDParagraphList::handle(VSDCollector *collector) const
171 {
172   if (empty())
173     return;
174   if (!m_elementsOrder.empty())
175   {
176     for (size_t i = 0; i < m_elementsOrder.size(); i++)
177     {
178       auto iter = m_elements.find(m_elementsOrder[i]);
179       if (iter != m_elements.end() && (0 == i || iter->second->getCharCount()))
180         iter->second->handle(collector);
181     }
182   }
183   else
184   {
185     for (auto iter = m_elements.begin(); iter != m_elements.end(); ++iter)
186       if (m_elements.begin() == iter || iter->second->getCharCount())
187         iter->second->handle(collector);
188   }
189 }
190 
clear()191 void libvisio::VSDParagraphList::clear()
192 {
193   m_elements.clear();
194   m_elementsOrder.clear();
195 }
196 
197 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
198