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) 2003-2005 William Lachance (william.lachance@sympatico.ca)
12  * Copyright (C) 2003 Marc Maurer (uwog@uwog.net)
13  *
14  * For minor contributions see the git repository.
15  *
16  * Alternatively, the contents of this file may be used under the terms
17  * of the GNU Lesser General Public License Version 2.1 or later
18  * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
19  * applicable instead of those above.
20  */
21 
22 #ifndef LOTUS_H
23 #define LOTUS_H
24 
25 #include <vector>
26 
27 #include <librevenge-stream/librevenge-stream.h>
28 #include "libwps_internal.h"
29 #include "libwps_tools_win.h"
30 #include "WPSDebug.h"
31 
32 #include "WKSParser.h"
33 
34 namespace LotusParserInternal
35 {
36 class SubDocument;
37 struct State;
38 }
39 
40 class LotusGraph;
41 class LotusChart;
42 class LotusSpreadsheet;
43 class LotusStyleManager;
44 class WPSGraphicStyle;
45 class WPSOLE1Parser;
46 
47 /* .wk3: a spreadsheet is composed in two files
48        + a wk3 file which contains the spreadsheet data
49        + a fm3 file which contains the different formatings
50 
51    .wk4: the file contains three parts:
52        + the wk3 previous file
53 	   + the fm3 file
54 	   + an unknown part, which may code the file structure,
55 
56 	   Normally the wk3 and the fm3 are a sequence of small zones,
57 	   but picture seems to be appeared at random position inside the
58 	   fm3 part (and even inside some structure fm3 structures...)
59 
60 	   search for .ole and OLE1
61 
62 	.123: the file contains at least two parts:
63 	   + the 123 storing the spreadsheet's data and format
64 	   + the last part containing the file's structure
65 	   + some optional part containing chart, picture, ...
66  */
67 
68 /**
69  * This class parses a wk3,wk4,123 Lotus spreadsheet
70  *
71  */
72 class LotusParser final : public WKSParser
73 {
74 	friend class LotusParserInternal::SubDocument;
75 	friend class LotusChart;
76 	friend class LotusGraph;
77 	friend class LotusSpreadsheet;
78 	friend class LotusStyleManager;
79 public:
80 	//! constructor
81 	LotusParser(RVNGInputStreamPtr &input, WPSHeaderPtr &header,
82 	            libwps_tools_win::Font::Type encoding=libwps_tools_win::Font::UNKNOWN,
83 	            char const *password=nullptr);
84 	//! destructor
85 	~LotusParser() final;
86 	//! called by WPSDocument to parse the file
87 	void parse(librevenge::RVNGSpreadsheetInterface *documentInterface) final;
88 	//! checks if the document header is correct (or not)
89 	bool checkHeader(WPSHeader *header, bool strict=false);
90 
91 	//! basic struct used to store link
92 	struct Link
93 	{
94 		//! constructor
LinkLink95 		Link() : m_name(), m_linkName()
96 		{
97 		}
98 		//! the basic name(used to retrieve a data)
99 		std::string m_name;
100 		//! the cell positions
101 		WPSVec3i m_cells[2];
102 		//! the link name
103 		librevenge::RVNGString m_linkName;
104 	};
105 protected:
106 	//! return the file version
107 	int version() const;
108 
109 	//
110 	// interface
111 	//
112 
113 	//! returns the font corresponding to an id
114 	bool getFont(int id, WPSFont &font, libwps_tools_win::Font::Type &type) const;
115 	/** returns the default font type, ie. the encoding given by the constructor if given
116 		or the encoding deduced from the version.
117 	 */
118 	libwps_tools_win::Font::Type getDefaultFontType() const;
119 	//! returns a list of links corresponding to an id
120 	std::vector<Link> getLinksList(int lId) const;
121 
122 	//
123 	// interface with LotusChart
124 	//
125 
126 	//! try to send a chart
127 	bool sendChart(int cId, WPSPosition const &pos, WPSGraphicStyle const &style);
128 
129 	//
130 	// interface with LotusGraph
131 	//
132 
133 	//! return true if the sheet sheetId has some graphic
134 	bool hasGraphics(int sheetId) const;
135 	//! send the graphics corresponding to a sheetId
136 	void sendGraphics(int sheetId);
137 
138 	//
139 	// interface with LotusSpreadsheet
140 	//
141 
142 	//! returns the left top position of a cell
143 	bool getLeftTopPosition(Vec2i const &cell, int spreadsheet, Vec2f &pos) const;
144 	//! returns the name of the id's spreadsheet
145 	librevenge::RVNGString getSheetName(int id) const;
146 
147 	//
148 	// interface with WPSOLE1Parser
149 	//
150 
151 	/** try to retrieve the content of a graphic, knowing it local id */
152 	bool updateEmbeddedObject(int id, WPSEmbeddedObject &object) const;
153 
154 	/** try to parse the different zones */
155 	bool createZones();
156 	/** creates the main listener */
157 	bool createListener(librevenge::RVNGSpreadsheetInterface *interface);
158 
159 	//
160 	// low level
161 	//
162 
163 	/// check for the existence of a format stream, if it exists, parse it
164 	bool parseFormatStream();
165 
166 	//! checks if the document header is correct (or not)
167 	bool checkHeader(std::shared_ptr<WPSStream> stream, bool mainStream, bool strict);
168 	/** finds the different zones (spreadsheet, chart, print, ...) */
169 	bool readZones(std::shared_ptr<WPSStream> stream);
170 	/** parse the different zones 1B */
171 	bool readDataZone(std::shared_ptr<WPSStream> stream);
172 	//! reads a zone
173 	bool readZone(std::shared_ptr<WPSStream> &stream);
174 	//! reads a zone of type 1: 123 files
175 	bool readZone1(std::shared_ptr<WPSStream> stream);
176 	//! reads a zone of type 2: 123 files
177 	bool readSheetZone(std::shared_ptr<WPSStream> stream);
178 	//! reads a zone of type 4: 123 files
179 	static bool readZone4(std::shared_ptr<WPSStream> stream);
180 	//! reads a zone of type 5: 123 files
181 	static bool readChartZone(std::shared_ptr<WPSStream> stream);
182 	//! reads a zone of type 6: 123 files
183 	static bool readRefZone(std::shared_ptr<WPSStream> stream);
184 	//! reads a zone of type 7: 123 files
185 	static bool readZone7(std::shared_ptr<WPSStream> stream);
186 	//! reads a zone of type 8: 123 files
187 	bool readZone8(std::shared_ptr<WPSStream> stream);
188 	//! reads a zone of type a: 123 files
189 	static bool readVersionZone(std::shared_ptr<WPSStream> stream);
190 	//! parse a wk123 zone
191 	static bool readZoneV3(std::shared_ptr<WPSStream> stream);
192 	//////////////////////// generic ////////////////////////////////////
193 
194 	//! reads a mac font name
195 	bool readMacFontName(std::shared_ptr<WPSStream> stream, long endPos);
196 	//! reads a format style name: b6
197 	static bool readFMTStyleName(std::shared_ptr<WPSStream> stream);
198 	//! reads a link
199 	bool readLinkZone(std::shared_ptr<WPSStream> stream);
200 	//! reads a mac document info zone: zone 1b, then 2af8
201 	bool readDocumentInfoMac(std::shared_ptr<WPSStream> stream, long endPos);
202 
203 	//////////////////////// decode a stream //////////////////////////////
204 
205 	//! try to decode a stream, if successful, replace the stream'input by the new one
206 	static RVNGInputStreamPtr decodeStream(RVNGInputStreamPtr input, long endPos, std::vector<uint8_t> const &key);
207 	//! try to guess a password knowing its file keys. Returns the keys if it founds a valid password
208 	static std::vector<uint8_t> retrievePasswordKeys(std::vector<uint8_t> const &fileKeys);
209 
210 	std::shared_ptr<WKSContentListener> m_listener; /** the listener (if set)*/
211 	//! the internal state
212 	std::shared_ptr<LotusParserInternal::State> m_state;
213 	//! the style manager
214 	std::shared_ptr<LotusStyleManager> m_styleManager;
215 	//! the chart manager
216 	std::shared_ptr<LotusChart> m_chartParser;
217 	//! the graph manager
218 	std::shared_ptr<LotusGraph> m_graphParser;
219 	//! the spreadsheet manager
220 	std::shared_ptr<LotusSpreadsheet> m_spreadsheetParser;
221 	//! the ole1 parser
222 	std::shared_ptr<WPSOLE1Parser> m_ole1Parser;
223 };
224 
225 #endif /* LOTUS_H */
226 /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */
227