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 IWAPARSER_H_INCLUDED 11 #define IWAPARSER_H_INCLUDED 12 13 #include <deque> 14 #include <functional> 15 #include <map> 16 #include <memory> 17 #include <string> 18 #include <unordered_map> 19 20 #include <boost/optional.hpp> 21 #include <boost/variant.hpp> 22 23 #if defined(__GNUC__) && !defined(__clang__) 24 #pragma GCC diagnostic push 25 #pragma GCC diagnostic ignored "-Weffc++" 26 #endif 27 #include <mdds/flat_segment_tree.hpp> 28 #if defined(__GNUC__) && !defined(__clang__) 29 #pragma GCC diagnostic pop 30 #endif 31 32 #include "libetonyek_utils.h" 33 #include "IWAMessage.h" 34 #include "IWAObjectIndex.h" 35 #include "IWORKLanguageManager.h" 36 #include "IWORKOutputElements.h" 37 #include "IWORKStyle_fwd.h" 38 #include "IWORKTypes.h" 39 40 namespace libetonyek 41 { 42 43 class IWORKCollector; 44 class IWAObjectIndex; 45 class IWORKPropertyMap; 46 class IWORKTable; 47 class IWORKText; 48 49 class IWAParser 50 { 51 friend class IWAObjectIndex; // for readColor 52 53 // disable copying 54 IWAParser(const IWAParser &); 55 IWAParser &operator=(const IWAParser &); 56 public: 57 IWAParser(const RVNGInputStreamPtr_t &fragments, const RVNGInputStreamPtr_t &package, IWORKCollector &collector); ~IWAParser()58 virtual ~IWAParser() 59 { 60 } 61 62 bool parse(); 63 64 protected: 65 class ObjectMessage 66 { 67 public: 68 ObjectMessage(IWAParser &parser, unsigned id, unsigned type = 0); 69 ~ObjectMessage(); 70 71 operator bool() const; 72 const IWAMessage &get() const; 73 74 unsigned getType() const; 75 get(const ObjectMessage & msg)76 friend const IWAMessage &get(const ObjectMessage &msg) 77 { 78 return msg.get(); 79 } 80 81 private: 82 IWAParser &m_parser; 83 boost::optional<IWAMessage> m_message; 84 const unsigned m_id; 85 unsigned m_type; 86 }; 87 friend class ObjectMessage; 88 89 typedef std::map<unsigned, IWORKStylePtr_t> StyleMap_t; 90 typedef std::function<void(unsigned, IWORKStylePtr_t &)> StyleParseFun_t; 91 92 protected: 93 static boost::optional<unsigned> readRef(const IWAMessage &msg, unsigned field); 94 static std::deque<unsigned> readRefs(const IWAMessage &msg, unsigned field); 95 static boost::optional<IWORKPosition> readPosition(const IWAMessage &msg, unsigned field); 96 static boost::optional<IWORKSize> readSize(const IWAMessage &msg, unsigned field); 97 static boost::optional<IWORKColor> readColor(const IWAMessage &msg, unsigned field); 98 static boost::optional<std::string> readUUID(const IWAMessage &msg, unsigned field); 99 static boost::optional<uint64_t> readUID(const IWAMessage &msg, unsigned field); 100 static std::deque<uint64_t> readUIDs(const IWAMessage &msg, unsigned field); 101 static void readStroke(const IWAMessage &msg, IWORKStroke &stroke); 102 bool readFill(const IWAMessage &msg, IWORKFill &fill); 103 static void readGradient(const IWAMessage &msg, IWORKGradient &gradient); 104 static void readShadow(const IWAMessage &msg, IWORKShadow &shadow); 105 static void readPadding(const IWAMessage &msg, IWORKPadding &padding); 106 107 bool dispatchShape(unsigned id); 108 bool dispatchShapeWithMessage(const IWAMessage &msg, unsigned type); 109 bool parseText(unsigned id, bool createNoteAsFootnote=true, const std::function<void(unsigned, IWORKStylePtr_t)> &openPageSpan=nullptr); 110 void parseComment(unsigned id); 111 void parseAuthorInComment(unsigned id); 112 void parseCustomFormat(unsigned id); 113 114 virtual bool parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry, boost::optional<unsigned> &flags); 115 void parseMask(unsigned id, IWORKGeometryPtr_t &geometry, IWORKPathPtr_t &path); 116 void updateGeometryUsingTextRef(unsigned id, IWORKGeometry &geometry, unsigned flags); 117 118 const IWORKStylePtr_t queryCharacterStyle(unsigned id) const; 119 const IWORKStylePtr_t queryParagraphStyle(unsigned id) const; 120 const IWORKStylePtr_t querySectionStyle(unsigned id) const; 121 122 const IWORKStylePtr_t queryGraphicStyle(unsigned id) const; 123 const IWORKStylePtr_t queryMediaStyle(unsigned id) const; 124 const IWORKStylePtr_t queryCellStyle(unsigned id) const; 125 const IWORKStylePtr_t queryTableStyle(unsigned id) const; 126 const IWORKStylePtr_t queryListStyle(unsigned id) const; 127 128 const IWORKStylePtr_t queryStyle(unsigned id, StyleMap_t &styleMap, StyleParseFun_t parse) const; 129 boost::optional<unsigned> getObjectType(unsigned id) const; 130 131 protected: 132 IWORKLanguageManager m_langManager; 133 IWORKTableNameMapPtr_t m_tableNameMap; 134 std::shared_ptr<IWORKText> m_currentText; 135 136 private: 137 struct Format 138 { 139 Format(); 140 boost::optional<IWORKCellType> m_type; 141 boost::variant<IWORKNumberFormat,IWORKDateTimeFormat,IWORKDurationFormat> m_format; 142 }; 143 144 struct PageMaster 145 { 146 PageMaster(); 147 IWORKStylePtr_t m_style; 148 bool m_headerFootersSameAsPrevious; 149 }; 150 151 struct TableHeader 152 { 153 TableHeader(unsigned count, float defValue=0); 154 155 mdds::flat_segment_tree<unsigned, float> m_sizes; 156 mdds::flat_segment_tree<unsigned, bool> m_hidden; 157 }; 158 159 typedef std::map<unsigned, boost::variant<std::string, unsigned, IWORKFormulaPtr_t, Format> > DataList_t; 160 161 struct TableInfo 162 { 163 TableInfo(const std::shared_ptr<IWORKTable> &table, unsigned columns, unsigned rows); 164 165 std::shared_ptr<IWORKTable> m_table; 166 167 const unsigned m_columns; 168 const unsigned m_rows; 169 170 IWORKStylePtr_t m_style; 171 172 TableHeader m_columnHeader; 173 TableHeader m_rowHeader; 174 175 DataList_t m_simpleTextList; 176 DataList_t m_cellStyleList; 177 DataList_t m_formattedTextList; 178 DataList_t m_formulaList; 179 DataList_t m_formatList; 180 DataList_t m_commentList; 181 }; 182 183 private: 184 virtual bool parseDocument() = 0; 185 186 private: 187 void queryObject(unsigned id, unsigned &type, boost::optional<IWAMessage> &msg) const; 188 const RVNGInputStreamPtr_t queryFile(unsigned id) const; 189 190 void parseObjectIndex(); 191 192 void parseCharacterStyle(unsigned id, IWORKStylePtr_t &style); 193 void parseParagraphStyle(unsigned id, IWORKStylePtr_t &style); 194 void parseSectionStyle(unsigned id, IWORKStylePtr_t &style); 195 196 void parseGraphicStyle(unsigned id, IWORKStylePtr_t &style); 197 void parseMediaStyle(unsigned id, IWORKStylePtr_t &style); 198 void parseCellStyle(unsigned id, IWORKStylePtr_t &style); 199 void parseTableStyle(unsigned id, IWORKStylePtr_t &style); 200 void parseListStyle(unsigned id, IWORKStylePtr_t &style); 201 202 void parseHeaderAndFooter(unsigned id, IWORKPageMaster &hf); 203 void parsePageMaster(unsigned id, PageMaster &pageMaster); 204 205 void parseTabularModel(unsigned id); 206 void parseDataList(unsigned id, DataList_t &dataList); 207 void parseTile(unsigned id); 208 void parseTableHeaders(unsigned id, TableHeader &header); 209 void parseTableGridLines(unsigned id, IWORKGridLineMap_t (&gridLines)[4]); 210 void parseTableGridLine(unsigned id, IWORKGridLineMap_t &gridLines); 211 void parseLink(unsigned id, std::string &url); 212 213 bool parseAttachment(unsigned id); 214 bool parseDrawableShape(const IWAMessage &msg, bool isConnectionLine=false); 215 bool parseGroup(const IWAMessage &msg); 216 bool parseShapePlacement(const IWAMessage &msg); 217 bool parseImage(const IWAMessage &msg); 218 bool parseTabularInfo(const IWAMessage &msg); 219 bool parsePath(const IWAMessage &msg, IWORKPathPtr_t &path); 220 bool parseFormula(const IWAMessage &msg, IWORKFormulaPtr_t &formula); 221 bool parseFormat(const IWAMessage &msg, Format &format); 222 virtual bool parseStickyNote(const IWAMessage &msg); 223 224 bool parseArrowProperties(const IWAMessage &msg, IWORKPropertyMap &props, bool headArrow); 225 void parseCharacterProperties(const IWAMessage &msg, IWORKPropertyMap &props); 226 void parseColumnsProperties(const IWAMessage &msg, IWORKPropertyMap &props); 227 228 private: 229 IWORKCollector &m_collector; 230 231 IWAObjectIndex m_index; 232 233 std::deque<unsigned> m_visited; 234 235 mutable StyleMap_t m_charStyles; 236 mutable StyleMap_t m_paraStyles; 237 mutable StyleMap_t m_sectionStyles; 238 239 mutable StyleMap_t m_graphicStyles; 240 mutable StyleMap_t m_mediaStyles; 241 mutable StyleMap_t m_cellStyles; 242 mutable StyleMap_t m_tableStyles; 243 mutable StyleMap_t m_listStyles; 244 245 std::shared_ptr<TableInfo> m_currentTable; 246 std::map<uint64_t,Format> m_uidFormatMap; 247 }; 248 249 } 250 251 #endif 252 253 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */ 254