1 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
2 
3 /* libmwaw
4 * Version: MPL 2.0 / LGPLv2+
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 2.0 (the "License"); you may not use this file except in compliance with
8 * the License or as specified alternatively below. You may obtain a copy of
9 * the License at http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * Major Contributor(s):
17 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
18 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
19 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
20 * Copyright (C) 2006, 2007 Andrew Ziem
21 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
22 *
23 *
24 * All Rights Reserved.
25 *
26 * For minor contributions see the git repository.
27 *
28 * Alternatively, the contents of this file may be used under the terms of
29 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
30 * in which case the provisions of the LGPLv2+ are applicable
31 * instead of those above.
32 */
33 
34 #ifndef MWAW_GRAPHIC_LISTENER_H
35 #define MWAW_GRAPHIC_LISTENER_H
36 
37 #include <vector>
38 
39 #include <librevenge/librevenge.h>
40 
41 #include "libmwaw_internal.hxx"
42 
43 #include "MWAWGraphicStyle.hxx"
44 
45 #include "MWAWListener.hxx"
46 
47 class MWAWGraphicShape;
48 
49 namespace MWAWGraphicListenerInternal
50 {
51 struct GraphicState;
52 struct State;
53 }
54 
55 /** This class contains the code needed to create Graphic document.
56 
57     \note All units are specified in librevenge::RVNG_POINT
58  */
59 class MWAWGraphicListener final : public MWAWListener
60 {
61 public:
62   /** constructor */
63   MWAWGraphicListener(MWAWParserState &parserState, std::vector<MWAWPageSpan> const &pageList, librevenge::RVNGDrawingInterface *documentInterface);
64   /** simplified constructor (can be used for a embedded graphic with one page).
65 
66    \note the box coordinates must be given in point.*/
67   MWAWGraphicListener(MWAWParserState &parserState, MWAWBox2f const &box, librevenge::RVNGDrawingInterface *documentInterface);
68   /** destructor */
69   ~MWAWGraphicListener() final;
70 
71   /** returns the listener type */
getType() const72   Type getType() const final
73   {
74     return Graphic;
75   }
76 
77   /** sets the documents metadata */
78   void setDocumentMetaData(librevenge::RVNGPropertyList const &metadata) final;
79   /** sets the documents language */
80   void setDocumentLanguage(std::string const &locale) final;
81   /** starts a new document */
82   void startDocument() final;
83   /** ends the actual document */
84   void endDocument(bool delayed=true) final;
85 
86   // ------ general information --------
87   /** returns true if a text zone is opened */
88   bool canWriteText() const final;
89   /** returns true if a document is opened */
90   bool isDocumentStarted() const final;
91 
92   /** function called to add a subdocument and modify the origin*/
93   void handleSubDocument(MWAWVec2f const &orig, MWAWSubDocumentPtr const &subDocument, libmwaw::SubDocumentType subDocumentType);
94   /** function called to add a subdocument */
handleSubDocument(MWAWSubDocumentPtr const & subDocument,libmwaw::SubDocumentType subDocumentType)95   void handleSubDocument(MWAWSubDocumentPtr const &subDocument, libmwaw::SubDocumentType subDocumentType) final
96   {
97     handleSubDocument(MWAWVec2f(0,0), subDocument, subDocumentType);
98   }
99   /** returns try if a subdocument is open  */
100   bool isSubDocumentOpened(libmwaw::SubDocumentType &subdocType) const final;
101   /** store the position and the style (which will be needed further to insert a textbox or a table with openTable) */
102   bool openFrame(MWAWPosition const &pos, MWAWGraphicStyle const &style=MWAWGraphicStyle::emptyStyle()) final;
103   /** close a frame */
104   void closeFrame() final;
105   /** open a group */
106   bool openGroup(MWAWPosition const &pos) final;
107   /** close a group */
108   void closeGroup() final;
109   /** open a layer */
110   bool openLayer(librevenge::RVNGString const &name);
111   /** close a layer */
112   void closeLayer();
113 
114   // ------ page --------
115   /** opens a master page */
116   bool openMasterPage(MWAWPageSpan &masterPage);
117   /** close a master page */
closeMasterPage()118   void closeMasterPage()
119   {
120     _closePageSpan(true);
121   }
122   /** returns true if a page is opened */
123   bool isPageSpanOpened() const final;
124   /** returns the current page span
125 
126   \note this forces the opening of a new page if no page is opened.*/
127   MWAWPageSpan const &getPageSpan() final;
128 
129   // ------ header/footer --------
130   /** insert a header */
131   bool insertHeader(MWAWSubDocumentPtr const &subDocument, librevenge::RVNGPropertyList const &extras) final;
132   /** insert a footer */
133   bool insertFooter(MWAWSubDocumentPtr const &subDocument, librevenge::RVNGPropertyList const &extras) final;
134   /** returns true if the header/footer is open */
135   bool isHeaderFooterOpened() const final;
136 
137   // ------ text data -----------
138   //! adds a basic character, ..
139   void insertChar(uint8_t character) final;
140   /** insert a character using the font converter to find the utf8
141       character */
142   void insertCharacter(unsigned char c) final;
143   /** insert a character using the font converter to find the utf8
144       character and if needed, input to read extra character.
145 
146       \return the number of extra character read
147    */
148   int insertCharacter(unsigned char c, MWAWInputStreamPtr &input, long endPos=-1) final;
149   /** adds an unicode character.
150    *  By convention if \a character=0xfffd(undef), no character is added */
151   void insertUnicode(uint32_t character) final;
152   //! adds a unicode string
153   void insertUnicodeString(librevenge::RVNGString const &str) final;
154 
155   //! adds a tab
156   void insertTab() final;
157   //! adds an end of line ( by default an hard one)
158   void insertEOL(bool softBreak=false) final;
159 
160   // ------ text format -----------
161   //! sets the font
162   void setFont(MWAWFont const &font) final;
163   //! returns the actual font
164   MWAWFont const &getFont() const final;
165 
166   // ------ paragraph format -----------
167   //! returns true if a paragraph or a list is opened
168   bool isParagraphOpened() const final;
169   //! sets the paragraph
170   void setParagraph(MWAWParagraph const &paragraph) final;
171   //! returns the actual paragraph
172   MWAWParagraph const &getParagraph() const final;
173 
174   // ------- fields ----------------
175   //! adds a field type
176   void insertField(MWAWField const &field) final;
177 
178   // ------- link ----------------
179   //! open a link
180   void openLink(MWAWLink const &link) final;
181   //! close a link
182   void closeLink() final;
183 
184   // ------- subdocument -----------------
185   /** adds a picture with potential various representationin given position */
186   void insertPicture(MWAWPosition const &pos, MWAWEmbeddedObject const &picture,
187                      MWAWGraphicStyle const &style=MWAWGraphicStyle::emptyStyle()) final;
188   /** adds a shape picture in given position */
189   void insertShape(MWAWPosition const &pos, MWAWGraphicShape const &shape, MWAWGraphicStyle const &style) final;
190   /** adds a textbox in given position */
191   void insertTextBox(MWAWPosition const &pos, MWAWSubDocumentPtr const &subDocument, MWAWGraphicStyle const &style) final;
192   /** adds a group: ie. next insertion will be done relative to this bdbox[0] position */
193   void insertGroup(MWAWBox2f const &bdbox, MWAWSubDocumentPtr const &subDocument);
194   /** insert a note
195 
196    \note as RVNGDrawingInterface does not accept note, note can only be inserted in a text zone (and are inserted between --) */
197   void insertNote(MWAWNote const &note, MWAWSubDocumentPtr &subDocument) final;
198   /** adds comment
199 
200    \note as RVNGDrawingInterface does not accept comment, comment can only be inserted in a text zone (and are inserted between --) */
201   void insertComment(MWAWSubDocumentPtr &subDocument) final;
202 
203   // ------- table -----------------
204 
205   /** adds a table in given position */
206   void insertTable(MWAWPosition const &pos, MWAWTable &table, MWAWGraphicStyle const &style=MWAWGraphicStyle::emptyStyle());
207   /** open a table (using the last parameters of openFrame for the position ) */
208   void openTable(MWAWTable const &table) final;
209   /** open a table in a given position */
210   void openTable(MWAWPosition const &pos, MWAWTable const &table, MWAWGraphicStyle const &style);
211   /** closes this table */
212   void closeTable() final;
213   /** open a row with given height ( if h < 0.0, set min-row-height = -h )*/
214   void openTableRow(float h, librevenge::RVNGUnit unit, bool headerRow=false) final;
215   /** closes this row */
216   void closeTableRow() final;
217   /** open a cell */
218   void openTableCell(MWAWCell const &cell) final;
219   /** close a cell */
220   void closeTableCell() final;
221   /** add empty cell */
222   void addEmptyTableCell(MWAWVec2i const &pos, MWAWVec2i span=MWAWVec2i(1,1)) final;
223 
224   // ------- section ---------------
225 
226   /** returns true if we can add open a section, add page break, ... */
canOpenSectionAddBreak() const227   bool canOpenSectionAddBreak() const final
228   {
229     return false;
230   }
231   //! returns true if a section is opened
isSectionOpened() const232   bool isSectionOpened() const final
233   {
234     return false;
235   }
236   //! returns the actual section
237   MWAWSection const &getSection() const final;
238   //! open a section if possible
239   bool openSection(MWAWSection const &section) final;
240   //! close a section
closeSection()241   bool closeSection() final
242   {
243     return false;
244   }
245   //! inserts a break type: ColumBreak, PageBreak, ..
246   void insertBreak(BreakType breakType) final;
247 
248 protected:
249   //! does open a new page (low level)
250   void _openPageSpan(bool sendHeaderFooters=true);
251   //! does close a page (low level)
252   void _closePageSpan(bool masterPage=false);
253 
254   void _startSubDocument();
255   void _endSubDocument();
256 
257   /** adds in propList the frame parameters.
258 
259    \note if there is some gradient, first draw a rectangle to print the gradient and them update propList */
260   void _handleFrameParameters(librevenge::RVNGPropertyList &propList, MWAWPosition const &pos, MWAWGraphicStyle const &style);
261 
262   void _openParagraph();
263   void _closeParagraph();
264   void _resetParagraphState(const bool isListElement=false);
265 
266   /** open a list level */
267   void _openListElement();
268   /** close a list level */
269   void _closeListElement();
270   /** update the list so that it corresponds to the actual level */
271   void _changeList();
272   /** low level: find a list id which corresponds to actual list and a change of level.
273 
274   \note called when the list id is not set
275   */
276   int _getListId() const;
277 
278   void _openSpan();
279   void _closeSpan();
280 
281   void _flushText();
282 
283   /** creates a new parsing state (copy of the actual state)
284    *
285    * \return the old one */
286   std::shared_ptr<MWAWGraphicListenerInternal::State> _pushParsingState();
287   //! resets the previous parsing state
288   void _popParsingState();
289 
290 protected:
291   //! the actual global state
292   std::shared_ptr<MWAWGraphicListenerInternal::GraphicState> m_ds;
293   //! the actual local parse state
294   std::shared_ptr<MWAWGraphicListenerInternal::State> m_ps;
295   //! stack of local state
296   std::vector<std::shared_ptr<MWAWGraphicListenerInternal::State> > m_psStack;
297   //! the parser state
298   MWAWParserState &m_parserState;
299   //! the document interface
300   librevenge::RVNGDrawingInterface *m_documentInterface;
301 
302 private:
303   MWAWGraphicListener(const MWAWGraphicListener &) = delete;
304   MWAWGraphicListener &operator=(const MWAWGraphicListener &) = delete;
305 };
306 
307 #endif
308 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
309