1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * This file is part of the libetonyek 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 #ifndef IWORKCOLLECTOR_H_INCLUDED
11 #define IWORKCOLLECTOR_H_INCLUDED
12 
13 #include <deque>
14 #include <memory>
15 #include <stack>
16 #include <string>
17 
18 #include <boost/optional.hpp>
19 
20 #include "libetonyek_utils.h"
21 #include "IWORKPath_fwd.h"
22 #include "IWORKShape.h"
23 #include "IWORKStyle.h"
24 #include "IWORKStyleStack.h"
25 #include "IWORKStylesheet.h"
26 #include "IWORKTransformation.h"
27 #include "IWORKTypes.h"
28 #include "IWORKOutputManager.h"
29 
30 namespace libetonyek
31 {
32 
33 class IWORKDocumentInterface;
34 class IWORKLanguageManager;
35 class IWORKPropertyMap;
36 class IWORKRecorder;
37 class IWORKTable;
38 class IWORKText;
39 struct IWORKSize;
40 
41 class IWORKCollector
42 {
43 private:
44   struct Level
45   {
46     IWORKGeometryPtr_t m_geometry;
47     IWORKStylePtr_t m_graphicStyle;
48     glm::dmat3 m_trafo;
49     glm::dmat3 m_previousTrafo;
50 
51     Level();
52   };
53 
54 public:
55   explicit IWORKCollector(IWORKDocumentInterface *document);
56   virtual ~IWORKCollector();
57 
58   void setRecorder(const std::shared_ptr<IWORKRecorder> &recorder);
59 
60   // collector functions
61 
62   void collectStyle(const IWORKStylePtr_t &style);
63 
64   void setGraphicStyle(const IWORKStylePtr_t &style);
65 
66   void collectGeometry(const IWORKGeometryPtr_t &geometry);
67   void setAccumulateTransformTo(bool accumulate);
68 
69   void collectBezier(const IWORKPathPtr_t &path);
70   void collectLine(const IWORKLinePtr_t &line);
71   void collectShape(const boost::optional<int> &order=boost::none, const boost::optional<unsigned> &resizeFlags=boost::none, bool locked=false);
72 
73   void collectBezierPath();
74   void collectPolygonPath(const IWORKSize &size, unsigned edges);
75   void collectRoundedRectanglePath(const IWORKSize &size, double radius);
76   void collectArrowPath(const IWORKSize &size, double headWidth, double stemRelYPos, bool doubleSided);
77   void collectStarPath(const IWORKSize &size, unsigned points, double innerRadius);
78   void collectConnectionPath(const IWORKConnectionPath &path);
79   void collectCalloutPath(const IWORKSize &size, double radius, double tailSize, double tailX, double tailY, bool quoteBubble);
80 
81   void collectImage(const IWORKMediaContentPtr_t &image, const IWORKGeometryPtr_t &cropGeometry=IWORKGeometryPtr_t(),
82                     const boost::optional<int> &order=boost::none, bool locked=false);
83   void collectMedia(const IWORKMediaContentPtr_t &content, const IWORKGeometryPtr_t &cropGeometry=IWORKGeometryPtr_t(), const boost::optional<int> &order=boost::none);
84 
85   void collectStylesheet(const IWORKStylesheetPtr_t &stylesheet);
86 
87   void collectMetadata(const IWORKMetadata &metadata);
88 
89   void collectHeader(const std::string &name);
90   void collectFooter(const std::string &name);
91 
92   void collectTable(const std::shared_ptr<IWORKTable> &table);
93   void collectText(const std::shared_ptr<IWORKText> &text);
94   virtual void collectStickyNote();
95 
96   void startDocument(const librevenge::RVNGPropertyList &props);
97   void endDocument();
98 
99   void startAttachment();
100   void endAttachment();
101 
102   void startAttachments();
103   void endAttachments();
104 
105   void startGroup();
106   void endGroup();
107 
108   // really add a group in the final file
109   void openGroup();
110   void closeGroup();
getOpenGroupLevel()111   bool getOpenGroupLevel() const
112   {
113     return m_groupOpenLevel;
114   };
115 
116   void startLevel();
117   void endLevel();
118 
119   void pushStyle();
120   void popStyle();
121 
122   void pushStylesheet(const IWORKStylesheetPtr_t &stylesheet);
123   void popStylesheet();
getStylesheet()124   IWORKStylesheetPtr_t getStylesheet() const
125   {
126     if (m_stylesheetStack.empty())
127       return IWORKStylesheetPtr_t();
128     return m_stylesheetStack.top();
129   }
130 
131   IWORKOutputManager &getOutputManager();
132 
133 public:
134   virtual std::shared_ptr<IWORKTable> createTable(const IWORKTableNameMapPtr_t &tableNameMap, const IWORKLanguageManager &langManager) const;
135   virtual std::shared_ptr<IWORKText> createText(const IWORKLanguageManager &langManager, bool discardEmptyContent = false, bool allowListInsertion=true) const;
136 
137 protected:
138   void fillMetadata(librevenge::RVNGPropertyList &props);
139 
140   static void fillGraphicProps(const IWORKStylePtr_t style, librevenge::RVNGPropertyList &props,
141                                bool isSurface=true, bool isFrame=false);
142   static void fillLayoutProps(const IWORKStylePtr_t style, librevenge::RVNGPropertyList &props);
143   static void fillTextAutoSizeProps(const boost::optional<unsigned> &resizeFlags, const IWORKGeometryPtr_t &boundingBox, librevenge::RVNGPropertyList &props);
144   static void fillWrapProps(const IWORKStylePtr_t style, librevenge::RVNGPropertyList &props,
145                             const boost::optional<int> &order);
146   static void writeFill(const IWORKFill &fill, librevenge::RVNGPropertyList &props);
147   void drawShape(const IWORKShapePtr_t &shape);
148 
149 private:
150   void pushStyle(const IWORKStylePtr_t &style);
151 
152   void collectHeaderFooter(const std::string &name, IWORKHeaderFooterMap_t &map);
153 
154   void drawLine(const IWORKLinePtr_t &line);
155   void drawMedia(const IWORKMediaPtr_t &media);
156   virtual void drawTable() = 0;
157   virtual void drawMedia(double x, double y, const librevenge::RVNGPropertyList &data) = 0;
158   virtual void fillShapeProperties(librevenge::RVNGPropertyList &props) = 0;
159   virtual bool createFrameStylesForTextBox() const = 0;
160   virtual void drawTextBox(const IWORKTextPtr_t &text, const glm::dmat3 &trafo, const IWORKGeometryPtr_t &boundingBox, const librevenge::RVNGPropertyList &style) = 0;
161 
162 protected:
163   IWORKCollector(const IWORKCollector &);
164   IWORKCollector &operator=(const IWORKCollector &);
165 
166   IWORKDocumentInterface *m_document;
167   std::shared_ptr<IWORKRecorder> m_recorder;
168 
169   std::stack<Level> m_levelStack;
170   IWORKStyleStack m_styleStack;
171   std::stack<IWORKStylesheetPtr_t> m_stylesheetStack;
172   IWORKOutputManager m_outputManager;
173 
174   std::deque<IWORKStylePtr_t> m_newStyles;
175 
176   std::shared_ptr<IWORKTable> m_currentTable;
177   std::shared_ptr<IWORKText> m_currentText;
178 
179   IWORKHeaderFooterMap_t m_headers;
180   IWORKHeaderFooterMap_t m_footers;
181 
182   std::stack<IWORKPathPtr_t> m_pathStack;
183   IWORKPathPtr_t m_currentPath;
184 
185   std::stack<bool> m_attachmentStack;
186   bool m_inAttachment;
187   bool m_inAttachments;
188 
189 private:
190   IWORKDataPtr_t m_currentData;
191   IWORKMediaContentPtr_t m_currentUnfiltered;
192   IWORKMediaContentPtr_t m_currentFiltered;
193   IWORKMediaContentPtr_t m_currentLeveled;
194   IWORKMediaContentPtr_t m_currentContent;
195 
196   IWORKMetadata m_metadata;
197 
198   bool m_accumulateTransform;
199   int m_groupLevel;
200   int m_groupOpenLevel;
201 };
202 
203 } // namespace libetonyek
204 
205 #endif // IWORKCOLLECTOR_H_INCLUDED
206 
207 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
208