1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ 2 /* libwps 3 * Version: MPL 2.0 / LGPLv2.1+ 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 * Major Contributor(s): 10 * Copyright (C) 2006, 2007 Andrew Ziem 11 * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch) 12 * Copyright (C) 2003-2005 William Lachance (william.lachance@sympatico.ca) 13 * Copyright (C) 2003 Marc Maurer (uwog@uwog.net) 14 * 15 * For minor contributions see the git repository. 16 * 17 * Alternatively, the contents of this file may be used under the terms 18 * of the GNU Lesser General Public License Version 2.1 or later 19 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are 20 * applicable instead of those above. 21 * 22 * For further information visit http://libwps.sourceforge.net 23 */ 24 25 #ifndef WKSCONTENTLISTENER_H 26 #define WKSCONTENTLISTENER_H 27 28 #include <vector> 29 30 #include <librevenge/librevenge.h> 31 32 #include "libwps_internal.h" 33 34 #include "WPSEntry.h" 35 #include "WPSGraphicStyle.h" 36 37 #include "WPSListener.h" 38 39 class WPSCellFormat; 40 class WKSChart; 41 struct WPSColumnFormat; 42 class WPSGraphicShape; 43 class WPSGraphicStyle; 44 class WPSList; 45 class WPSPageSpan; 46 struct WPSParagraph; 47 struct WPSRowFormat; 48 struct WPSTabStop; 49 50 struct WKSContentParsingState; 51 struct WKSDocumentParsingState; 52 53 class WKSContentListener final : public WPSListener 54 { 55 public: 56 //! small class use to define a formula instruction 57 struct FormulaInstruction 58 { 59 enum What { F_Operator, F_Function, F_Cell, F_CellList, F_Long, F_Double, F_Text }; 60 //! constructor FormulaInstructionFormulaInstruction61 FormulaInstruction() 62 : m_type(F_Text) 63 , m_content() 64 , m_longValue(0) 65 , m_doubleValue(0) 66 , m_fileName() 67 { 68 for (auto &pos : m_position) pos=Vec2i(0,0); 69 for (auto &pos : m_positionRelative) pos=Vec2b(false,false); 70 for (auto &id : m_sheetId) id=-1; 71 } 72 //! return a proplist corresponding to a instruction 73 librevenge::RVNGPropertyList getPropertyList() const; 74 //! operator<< 75 friend std::ostream &operator<<(std::ostream &o, FormulaInstruction const &inst); 76 //! the type 77 What m_type; 78 //! the content ( if type == F_Operator or type = F_Function or type==F_Text) 79 std::string m_content; 80 //! value ( if type==F_Long ) 81 double m_longValue; 82 //! value ( if type==F_Double ) 83 double m_doubleValue; 84 //! cell position ( if type==F_Cell or F_CellList ) 85 Vec2i m_position[2]; 86 //! relative cell position ( if type==F_Cell or F_CellList ) 87 Vec2b m_positionRelative[2]; 88 //! the sheet name 89 librevenge::RVNGString m_sheetName[2]; 90 /** the sheet id 91 92 \note local field which can be used to store the sheet id 93 before setting the sheet name */ 94 int m_sheetId[2]; 95 //! the file name (external reference) 96 librevenge::RVNGString m_fileName; 97 }; 98 //! small class use to define a sheet cell content 99 struct CellContent 100 { 101 /** the different types of cell's field */ 102 enum ContentType { C_NONE, C_TEXT, C_NUMBER, C_FORMULA, C_UNKNOWN }; 103 /// constructor CellContentCellContent104 CellContent() 105 : m_contentType(C_UNKNOWN) 106 , m_value(0.0) 107 , m_valueSet(false) 108 , m_textEntry() 109 , m_formula() { } 110 CellContent(CellContent const &)=default; 111 CellContent &operator=(CellContent const &)=default; 112 /// destructor ~CellContentCellContent113 ~CellContent() {} 114 //! operator<< 115 friend std::ostream &operator<<(std::ostream &o, CellContent const &cell); 116 117 //! returns true if the cell has no content emptyCellContent118 bool empty() const 119 { 120 if (m_contentType == C_NUMBER) return false; 121 if (m_contentType == C_TEXT && !m_textEntry.valid()) return false; 122 if (m_contentType == C_FORMULA && (m_formula.size() || isValueSet())) return false; 123 return true; 124 } 125 //! sets the double value setValueCellContent126 void setValue(double value) 127 { 128 m_value = value; 129 m_valueSet = true; 130 } 131 //! returns true if the value has been setted isValueSetCellContent132 bool isValueSet() const 133 { 134 return m_valueSet; 135 } 136 //! returns true if the text is set hasTextCellContent137 bool hasText() const 138 { 139 return m_textEntry.valid(); 140 } 141 /** conversion beetween double days since 1900 and date */ 142 static bool double2Date(double val, int &Y, int &M, int &D); 143 /** conversion beetween double: second since 0:00 and time */ 144 static bool double2Time(double val, int &H, int &M, int &S); 145 146 //! the content type ( by default unknown ) 147 ContentType m_contentType; 148 //! the cell value 149 double m_value; 150 //! true if the value has been set 151 bool m_valueSet; 152 //! the cell string 153 WPSEntry m_textEntry; 154 //! the formula list of instruction 155 std::vector<FormulaInstruction> m_formula; 156 }; 157 158 WKSContentListener(std::vector<WPSPageSpan> const &pageList, librevenge::RVNGSpreadsheetInterface *documentInterface); 159 ~WKSContentListener() final; 160 161 void setDocumentLanguage(int lcid) final; 162 void setMetaData(const librevenge::RVNGPropertyList &list); 163 164 void startDocument(); 165 void endDocument(); 166 void handleSubDocument(WPSSubDocumentPtr &subDocument, libwps::SubDocumentType subDocumentType); 167 168 // ------ text data ----------- 169 170 //! adds a basic character, .. 171 void insertCharacter(uint8_t character) final; 172 /** adds an unicode character 173 * 174 * by convention if \a character=0xfffd(undef), no character is added */ 175 void insertUnicode(uint32_t character) final; 176 //! adds a unicode string 177 void insertUnicodeString(librevenge::RVNGString const &str) final; 178 179 void insertTab() final; 180 void insertEOL(bool softBreak=false) final; 181 void insertBreak(const uint8_t breakType) final; 182 183 // ------ text format ----------- 184 //! set the actual font 185 void setFont(const WPSFont &font) final; 186 //! returns the actual font 187 WPSFont const &getFont() const final; 188 189 // ------ paragraph format ----------- 190 //! returns true if a paragraph or a list is opened 191 bool isParagraphOpened() const final; 192 //! sets the actual paragraph 193 void setParagraph(const WPSParagraph ¶) final; 194 //! returns the actual paragraph 195 WPSParagraph const &getParagraph() const final; 196 197 // ------- fields ---------------- 198 //! adds a field 199 void insertField(WPSField const &field) final; 200 201 // ------- subdocument ----------------- 202 /** adds comment */ 203 void insertComment(WPSSubDocumentPtr &subDocument); 204 /** adds a picture in given position */ 205 void insertPicture(WPSPosition const &pos, const librevenge::RVNGBinaryData &binaryData, 206 std::string type="image/pict", WPSGraphicStyle const &style=WPSGraphicStyle::emptyStyle()); 207 /** adds an object with replacement picture in given position */ 208 void insertObject(WPSPosition const &pos, const WPSEmbeddedObject &obj, 209 WPSGraphicStyle const &style=WPSGraphicStyle::emptyStyle()); 210 /** adds a picture in given position */ 211 void insertPicture(WPSPosition const &pos, WPSGraphicShape const &shape, WPSGraphicStyle const &style); 212 /** adds a textbox in given position */ 213 void insertTextBox(WPSPosition const &pos, WPSSubDocumentPtr subDocument, 214 WPSGraphicStyle const &frameStyle=WPSGraphicStyle::emptyStyle()); 215 /** open a group (not implemented) */ 216 bool openGroup(WPSPosition const &pos) final; 217 /** close a group (not implemented) */ 218 void closeGroup() final; 219 220 // ------- sheet ----------------- 221 /** open a sheet*/ 222 void openSheet(std::vector<WPSColumnFormat> const &columns, librevenge::RVNGString const &name=""); 223 /** closes this sheet */ 224 void closeSheet(); 225 /** open a row */ 226 void openSheetRow(WPSRowFormat const &f, int numRepeated=1); 227 /** closes this row */ 228 void closeSheetRow(); 229 /** low level function to define a cell. 230 \param cell the cell position, alignement, ... 231 \param content the cell content 232 \param numRepeated the cell columns repeatition*/ 233 void openSheetCell(WPSCell const &cell, CellContent const &content, int numRepeated=1); 234 /** close a cell */ 235 void closeSheetCell(); 236 237 // ------- chart ----------------- 238 /** adds a chart in given position */ 239 void insertChart(WPSPosition const &pos, WKSChart const &chart, 240 WPSGraphicStyle const &style=WPSGraphicStyle::emptyStyle()); 241 protected: 242 void _openPageSpan(); 243 void _closePageSpan(); 244 245 void _handleFrameParameters(librevenge::RVNGPropertyList &propList, WPSPosition const &pos); 246 bool _openFrame(WPSPosition const &pos, WPSGraphicStyle const &style); 247 void _closeFrame(); 248 249 void _startSubDocument(); 250 void _endSubDocument(); 251 252 void _openParagraph(); 253 void _closeParagraph(); 254 void _appendParagraphProperties(librevenge::RVNGPropertyList &propList, const bool isListElement=false); 255 void _resetParagraphState(const bool isListElement=false); 256 257 void _openSpan(); 258 void _closeSpan(); 259 260 void _flushText(); 261 void _flushDeferredTabs(); 262 263 void _insertBreakIfNecessary(librevenge::RVNGPropertyList &propList); 264 265 /** creates a new parsing state (copy of the actual state) 266 * 267 * \return the old one */ 268 std::shared_ptr<WKSContentParsingState> _pushParsingState(); 269 //! resets the previous parsing state 270 void _popParsingState(); 271 272 protected: 273 std::shared_ptr<WKSDocumentParsingState> m_ds; // main parse state 274 std::shared_ptr<WKSContentParsingState> m_ps; // parse state 275 std::vector<std::shared_ptr<WKSContentParsingState> > m_psStack; 276 librevenge::RVNGSpreadsheetInterface *m_documentInterface; 277 278 private: 279 WKSContentListener(const WKSContentListener &) = delete; 280 WKSContentListener &operator=(const WKSContentListener &) = delete; 281 }; 282 283 #endif 284 /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ 285