/src/libmwaw/src/lib/ClarisWksPresentation.cxx
Line | Count | Source |
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 | | #include <algorithm> |
35 | | #include <iomanip> |
36 | | #include <iostream> |
37 | | #include <limits> |
38 | | #include <map> |
39 | | #include <sstream> |
40 | | |
41 | | #include <librevenge/librevenge.h> |
42 | | |
43 | | #include "MWAWFont.hxx" |
44 | | #include "MWAWFontConverter.hxx" |
45 | | #include "MWAWHeader.hxx" |
46 | | #include "MWAWParser.hxx" |
47 | | #include "MWAWPresentationListener.hxx" |
48 | | #include "MWAWPosition.hxx" |
49 | | |
50 | | #include "ClarisWksDocument.hxx" |
51 | | #include "ClarisWksStruct.hxx" |
52 | | #include "ClarisWksStyleManager.hxx" |
53 | | |
54 | | #include "ClarisWksPresentation.hxx" |
55 | | |
56 | | /** Internal: the structures of a ClarisWksPresentation */ |
57 | | namespace ClarisWksPresentationInternal |
58 | | { |
59 | | //! Internal the presentation |
60 | | struct Presentation final : public ClarisWksStruct::DSET { |
61 | | // constructor |
62 | | explicit Presentation(ClarisWksStruct::DSET const &dset = ClarisWksStruct::DSET()) |
63 | 273k | : ClarisWksStruct::DSET(dset) |
64 | 273k | , m_contentIdList() |
65 | 273k | , m_noteIdList() |
66 | 273k | , m_thumbnailsIdList() |
67 | 273k | , m_titleList() |
68 | 273k | , m_masterId(0) |
69 | 273k | , m_masterDetached(false) |
70 | 273k | { |
71 | 273k | } |
72 | | //! destructor |
73 | | ~Presentation() final; |
74 | | //! operator<< |
75 | | friend std::ostream &operator<<(std::ostream &o, Presentation const &doc) |
76 | 0 | { |
77 | 0 | o << static_cast<ClarisWksStruct::DSET const &>(doc); |
78 | 0 | return o; |
79 | 0 | } |
80 | | /** remove a child from a list. |
81 | | |
82 | | Normally, this function is not called, so optimizing it is not usefull |
83 | | */ |
84 | | void removeChild(int cId, bool normalChild) final |
85 | 67.9k | { |
86 | 67.9k | DSET::removeChild(cId, normalChild); |
87 | 67.9k | if (m_id+1==cId) m_masterDetached=true; |
88 | 67.9k | } |
89 | | |
90 | | //! the list of main zone id |
91 | | std::vector<int> m_contentIdList; |
92 | | //! the list of notes zone id |
93 | | std::vector<int> m_noteIdList; |
94 | | //! the list of thumbnail zone id |
95 | | std::vector<int> m_thumbnailsIdList; |
96 | | //! the list of title |
97 | | std::vector<librevenge::RVNGString> m_titleList; |
98 | | //! the master zone (background + header/footer) |
99 | | int m_masterId; |
100 | | //! true if the auxiliary zone is detached |
101 | | bool m_masterDetached; |
102 | | }; |
103 | | |
104 | | Presentation::~Presentation() |
105 | 273k | { |
106 | 273k | } |
107 | | |
108 | | //! Internal: the state of a ClarisWksPresentation |
109 | | struct State { |
110 | | //! constructor |
111 | | State() |
112 | 559k | : m_presentation() |
113 | 559k | , m_presentationMap() |
114 | 559k | { |
115 | 559k | } |
116 | | //! the main presentation |
117 | | std::shared_ptr<Presentation> m_presentation; |
118 | | //! map zId to presentation |
119 | | std::map<int, std::shared_ptr<Presentation> > m_presentationMap; |
120 | | }; |
121 | | |
122 | | //////////////////////////////////////// |
123 | | //! Internal: the subdocument of a ClarisWksPresentation |
124 | | class SubDocument final : public MWAWSubDocument |
125 | | { |
126 | | public: |
127 | | SubDocument(ClarisWksPresentation &pars, MWAWInputStreamPtr const &input, int zoneId) |
128 | 2.20k | : MWAWSubDocument(pars.m_mainParser, input, MWAWEntry()) |
129 | 2.20k | , m_presentationParser(&pars) |
130 | 2.20k | , m_id(zoneId) {} |
131 | | |
132 | | //! destructor |
133 | 0 | ~SubDocument() final {} |
134 | | |
135 | | //! operator!= |
136 | | bool operator!=(MWAWSubDocument const &doc) const final |
137 | 613 | { |
138 | 613 | if (MWAWSubDocument::operator!=(doc)) return true; |
139 | 613 | auto const *sDoc = dynamic_cast<SubDocument const *>(&doc); |
140 | 613 | if (!sDoc) return true; |
141 | 0 | if (m_presentationParser != sDoc->m_presentationParser) return true; |
142 | 0 | if (m_id != sDoc->m_id) return true; |
143 | 0 | return false; |
144 | 0 | } |
145 | | |
146 | | //! the parser function |
147 | | void parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType type) final; |
148 | | /** the presentation parser */ |
149 | | ClarisWksPresentation *m_presentationParser; |
150 | | |
151 | | protected: |
152 | | //! the subdocument id |
153 | | int m_id; |
154 | | private: |
155 | | SubDocument(SubDocument const &orig) = delete; |
156 | | SubDocument &operator=(SubDocument const &orig) = delete; |
157 | | }; |
158 | | |
159 | | void SubDocument::parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType type) |
160 | 1.05k | { |
161 | 1.05k | if (!listener || (type==libmwaw::DOC_TEXT_BOX&&!listener->canWriteText())) { |
162 | 0 | MWAW_DEBUG_MSG(("ClarisWksPresentationInternal::SubDocument::parse: no listener\n")); |
163 | 0 | return; |
164 | 0 | } |
165 | 1.05k | if (!m_presentationParser) { |
166 | 0 | MWAW_DEBUG_MSG(("ClarisWksPresentationInternal::SubDocument::parse: can not find parser\n")); |
167 | 0 | return; |
168 | 0 | } |
169 | 1.05k | long pos = m_input->tell(); |
170 | 1.05k | m_presentationParser->askToSend(m_id); |
171 | 1.05k | m_input->seek(pos, librevenge::RVNG_SEEK_SET); |
172 | 1.05k | } |
173 | | } |
174 | | |
175 | | //////////////////////////////////////////////////////////// |
176 | | // constructor/destructor, ... |
177 | | //////////////////////////////////////////////////////////// |
178 | | ClarisWksPresentation::ClarisWksPresentation(ClarisWksDocument &document) |
179 | 559k | : m_document(document) |
180 | 559k | , m_parserState(document.m_parserState) |
181 | 559k | , m_state(new ClarisWksPresentationInternal::State) |
182 | 559k | , m_mainParser(&document.getMainParser()) |
183 | 559k | { |
184 | 559k | } |
185 | | |
186 | | ClarisWksPresentation::~ClarisWksPresentation() |
187 | 559k | { } |
188 | | |
189 | | int ClarisWksPresentation::version() const |
190 | 0 | { |
191 | 0 | return m_parserState->m_version; |
192 | 0 | } |
193 | | |
194 | | int ClarisWksPresentation::numPages() const |
195 | 195k | { |
196 | 195k | if (m_parserState->m_kind!=MWAWDocument::MWAW_K_PRESENTATION || !m_state->m_presentation) |
197 | 177k | return 1; |
198 | 18.4k | return int(m_state->m_presentation->m_contentIdList.size()); |
199 | 195k | } |
200 | | |
201 | | bool ClarisWksPresentation::updatePageSpanList(MWAWPageSpan const &page, std::vector<MWAWPageSpan> &spanList) |
202 | 7.34k | { |
203 | 7.34k | if (!m_state->m_presentation) |
204 | 0 | return false; |
205 | 7.34k | int numPage=numPages(); |
206 | 7.34k | if (numPage<=0) |
207 | 3.44k | return false; |
208 | 35.2k | for (int i=0; i<numPage; ++i) { |
209 | 31.3k | MWAWPageSpan ps(page); |
210 | 31.3k | if (i<static_cast<int>(m_state->m_presentation->m_titleList.size()) && |
211 | 30.4k | !m_state->m_presentation->m_titleList[size_t(i)].empty()) |
212 | 19.9k | ps.setPageName(m_state->m_presentation->m_titleList[size_t(i)]); |
213 | 31.3k | ps.setPageSpan(1); |
214 | 31.3k | spanList.push_back(ps); |
215 | 31.3k | } |
216 | 3.89k | return true; |
217 | 7.34k | } |
218 | | |
219 | | void ClarisWksPresentation::askToSend(int number) |
220 | 1.05k | { |
221 | 1.05k | m_document.sendZone(number); |
222 | 1.05k | } |
223 | | |
224 | | //////////////////////////////////////////////////////////// |
225 | | // Intermediate level |
226 | | //////////////////////////////////////////////////////////// |
227 | | void ClarisWksPresentation::updateSlideTypes() const |
228 | 266k | { |
229 | 266k | auto it = m_state->m_presentationMap.begin(); |
230 | 326k | while (it != m_state->m_presentationMap.end()) { |
231 | 60.1k | std::shared_ptr<ClarisWksPresentationInternal::Presentation> pres = it++->second; |
232 | 60.1k | if (!pres) continue; |
233 | 60.1k | if (pres->m_id==1) |
234 | 23.7k | m_state->m_presentation=pres; |
235 | 240k | for (int step=0; step<3; ++step) { |
236 | 180k | auto const &content=step==0 ? pres->m_contentIdList : |
237 | 180k | step==1 ? pres->m_noteIdList : pres->m_thumbnailsIdList; |
238 | 180k | int c=0; |
239 | 180k | for (auto id : content) { |
240 | 106k | auto zone=m_document.getZone(id); |
241 | 106k | if (!zone) continue; |
242 | 30.1k | static ClarisWksStruct::DSET::Position const positions[]= { |
243 | 30.1k | ClarisWksStruct::DSET::P_Slide, ClarisWksStruct::DSET::P_SlideNote, ClarisWksStruct::DSET::P_SlideThumbnail |
244 | 30.1k | }; |
245 | 30.1k | zone->m_position=positions[step]; |
246 | 30.1k | zone->m_page=++c; |
247 | 30.1k | } |
248 | 180k | } |
249 | | // finally update the background type |
250 | 60.1k | auto zone=m_document.getZone(pres->m_id+1); |
251 | 60.1k | if (!zone || zone->m_fileType!=0) continue; |
252 | 13.0k | zone->m_position=ClarisWksStruct::DSET::P_SlideMaster; |
253 | 13.0k | } |
254 | 266k | } |
255 | | |
256 | | void ClarisWksPresentation::disconnectMasterFromContents() const |
257 | 15.1k | { |
258 | 15.1k | auto it = m_state->m_presentationMap.begin(); |
259 | 25.6k | while (it != m_state->m_presentationMap.end()) { |
260 | 10.4k | auto pres = it++->second; |
261 | 10.4k | if (!pres) continue; |
262 | 10.4k | auto background=m_document.getZone(pres->m_id+1); |
263 | 10.4k | pres->m_masterId=pres->m_id+1; |
264 | 10.4k | if (!background || background->m_fathersList.size()!=1) { |
265 | 7.64k | MWAW_DEBUG_MSG(("ClarisWksPresentation::disconnectMasterFromContents: can not find the background zone\n")); |
266 | 7.64k | continue; |
267 | 7.64k | } |
268 | 2.77k | int masterId=*background->m_fathersList.begin(); |
269 | 2.77k | auto master=m_document.getZone(masterId); |
270 | 2.77k | if (!master) { |
271 | 0 | MWAW_DEBUG_MSG(("ClarisWksPresentation::disconnectMasterFromContents: can not find the master zone\n")); |
272 | 0 | continue; |
273 | 0 | } |
274 | 2.77k | master->m_position=ClarisWksStruct::DSET::P_SlideMaster; |
275 | 2.77k | pres->m_masterId=masterId; |
276 | 11.1k | for (int step=0; step<3; ++step) { |
277 | 8.32k | std::vector<int> const &content=step==0 ? pres->m_contentIdList : |
278 | 8.32k | step==1 ? pres->m_noteIdList : pres->m_thumbnailsIdList; |
279 | 24.3k | for (auto childId : content) { |
280 | 24.3k | if (master->m_fathersList.find(childId)==master->m_fathersList.end()) { |
281 | 23.9k | MWAW_DEBUG_MSG(("ClarisWksPresentation::disconnectMasterFromContents: find a content zone with no link to master\n")); |
282 | 23.9k | continue; |
283 | 23.9k | } |
284 | 408 | std::shared_ptr<ClarisWksStruct::DSET> zone=m_document.getZone(childId); |
285 | 408 | if (!zone) continue; |
286 | 408 | zone->removeChild(masterId, true); |
287 | 408 | master->m_fathersList.erase(childId); |
288 | 408 | } |
289 | 8.32k | } |
290 | 2.77k | } |
291 | 15.1k | } |
292 | | |
293 | | //////////////////////////////////////////////////////////// |
294 | | // a document part |
295 | | //////////////////////////////////////////////////////////// |
296 | | std::shared_ptr<ClarisWksStruct::DSET> ClarisWksPresentation::readPresentationZone |
297 | | (ClarisWksStruct::DSET const &zone, MWAWEntry const &entry, bool &complete) |
298 | 293k | { |
299 | 293k | complete = true; |
300 | 293k | if (!entry.valid() || zone.m_fileType != 5 || entry.length() < 0x40) |
301 | 19.8k | return std::shared_ptr<ClarisWksStruct::DSET>(); |
302 | 273k | long pos = entry.begin(); |
303 | 273k | MWAWInputStreamPtr &input= m_parserState->m_input; |
304 | 273k | input->seek(pos+8+16, librevenge::RVNG_SEEK_SET); // avoid header+8 generic number |
305 | 273k | libmwaw::DebugFile &ascFile = m_parserState->m_asciiFile; |
306 | 273k | libmwaw::DebugStream f; |
307 | 273k | std::shared_ptr<ClarisWksPresentationInternal::Presentation> |
308 | 273k | presentationZone(new ClarisWksPresentationInternal::Presentation(zone)); |
309 | | |
310 | 273k | f << "Entries(PresentationDef):" << *presentationZone << ","; |
311 | 273k | ascFile.addDelimiter(input->tell(), '|'); |
312 | 273k | ascFile.addPos(pos); |
313 | 273k | ascFile.addNote(f.str().c_str()); |
314 | | |
315 | | // read the last part |
316 | 273k | long data0Length = zone.m_dataSz; |
317 | 273k | long N = zone.m_numData; |
318 | 273k | if (entry.length() -8-12 != data0Length*N + zone.m_headerSz) { |
319 | 172k | if (data0Length == 0 && N) { |
320 | 6.08k | MWAW_DEBUG_MSG(("ClarisWksPresentation::readPresentationZone: can not find definition size\n")); |
321 | 6.08k | input->seek(entry.end(), librevenge::RVNG_SEEK_SET); |
322 | 6.08k | return std::shared_ptr<ClarisWksStruct::DSET>(); |
323 | 6.08k | } |
324 | | |
325 | 166k | MWAW_DEBUG_MSG(("ClarisWksPresentation::readPresentationZone: unexpected size for zone definition, try to continue\n")); |
326 | 166k | } |
327 | | |
328 | 267k | if (m_state->m_presentationMap.find(presentationZone->m_id) != m_state->m_presentationMap.end()) { |
329 | 207k | MWAW_DEBUG_MSG(("ClarisWksPresentation::readPresentationZone: zone %d already exists!!!\n", presentationZone->m_id)); |
330 | 207k | } |
331 | 60.1k | else |
332 | 60.1k | m_state->m_presentationMap[presentationZone->m_id] = presentationZone; |
333 | | |
334 | 267k | long dataEnd = entry.end()-N*data0Length; |
335 | 267k | input->seek(dataEnd, librevenge::RVNG_SEEK_SET); |
336 | 4.20M | for (long i = 0; i < N; i++) { |
337 | 3.93M | pos = input->tell(); |
338 | | |
339 | 3.93M | f.str(""); |
340 | 3.93M | f << "PresentationDef-" << i; |
341 | 3.93M | ascFile.addPos(pos); |
342 | 3.93M | ascFile.addNote(f.str().c_str()); |
343 | 3.93M | input->seek(pos+data0Length, librevenge::RVNG_SEEK_SET); |
344 | 3.93M | } |
345 | 267k | input->seek(entry.end(), librevenge::RVNG_SEEK_SET); |
346 | | |
347 | 267k | pos = input->tell(); |
348 | 267k | bool ok = readZone1(*presentationZone); |
349 | 267k | if (ok) { |
350 | 66.2k | pos = input->tell(); |
351 | 66.2k | ok = readZone2(*presentationZone); |
352 | 66.2k | } |
353 | 267k | if (!ok) |
354 | 232k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
355 | | |
356 | 267k | return presentationZone; |
357 | 273k | } |
358 | | |
359 | | //////////////////////////////////////////////////////////// |
360 | | // |
361 | | // Intermediate level |
362 | | // |
363 | | //////////////////////////////////////////////////////////// |
364 | | bool ClarisWksPresentation::readZone1(ClarisWksPresentationInternal::Presentation &pres) |
365 | 267k | { |
366 | 267k | long val; |
367 | 267k | MWAWInputStreamPtr &input= m_parserState->m_input; |
368 | 267k | libmwaw::DebugFile &ascFile = m_parserState->m_asciiFile; |
369 | 267k | libmwaw::DebugStream f; |
370 | | |
371 | 553k | for (int st = 0; st < 3; st++) { |
372 | 487k | long pos = input->tell(); |
373 | 487k | auto N = long(input->readULong(4)); |
374 | 487k | long endPos = pos+16*N+4; |
375 | 487k | if (N < 0 || !input->checkPosition(endPos)) { |
376 | 117k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
377 | 117k | MWAW_DEBUG_MSG(("ClarisWksPresentation::readZone1: zone seems too short\n")); |
378 | 117k | return false; |
379 | 117k | } |
380 | 370k | f.str(""); |
381 | 370k | f << "Entries(PresentationStr)[" << st << "]" << ":N=" << N << ","; |
382 | 370k | ascFile.addPos(pos); |
383 | 370k | ascFile.addNote(f.str().c_str()); |
384 | | |
385 | 841k | for (long i = 0; i < N; i++) { |
386 | 555k | f.str(""); |
387 | 555k | f << "PresentationStr" << st << "-" << i << ":"; |
388 | 555k | pos = input->tell(); |
389 | 555k | auto zoneId = static_cast<int>(input->readLong(4)); |
390 | 555k | if (zoneId > 0) { |
391 | 371k | if (st == 1) |
392 | 201k | pres.m_contentIdList.push_back(zoneId); |
393 | 169k | else if (st == 2) |
394 | 47.5k | pres.m_noteIdList.push_back(zoneId); |
395 | 122k | else |
396 | 122k | pres.m_thumbnailsIdList.push_back(zoneId); |
397 | 371k | pres.m_otherChilds.push_back(zoneId); |
398 | 371k | } |
399 | 183k | else |
400 | 183k | f << "###"; |
401 | 555k | f << "zId=" << zoneId << ","; |
402 | 555k | f << "f1=" << input->readLong(4) << ","; // always 8 ? |
403 | 555k | auto sSz = static_cast<int>(input->readLong(4)); |
404 | 555k | long endStringPos=pos+12+sSz; |
405 | 555k | if (sSz < 0 || !input->checkPosition(endStringPos+4)) { |
406 | 83.8k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
407 | 83.8k | MWAW_DEBUG_MSG(("ClarisWksPresentation::readZone1: can not read string %ld\n", i)); |
408 | 83.8k | return false; |
409 | 83.8k | } |
410 | 471k | librevenge::RVNGString title(""); |
411 | 133M | for (int s = 0; s < sSz; s++) { |
412 | 132M | auto ch=char(input->readULong(1)); |
413 | 132M | if (!ch) continue; |
414 | 62.3M | f << ch; |
415 | | // checkme: can we always use a defaut font |
416 | 62.3M | int unicode= m_parserState->m_fontConverter->unicode(3, static_cast<unsigned char>(ch)); |
417 | 62.3M | if (unicode==-1) |
418 | 22.8M | title.append(ch); |
419 | 39.4M | else |
420 | 39.4M | libmwaw::appendUnicode(static_cast<uint32_t>(unicode), title); |
421 | 62.3M | } |
422 | 471k | if (st==1) |
423 | 277k | pres.m_titleList.push_back(title); |
424 | 471k | input->seek(endStringPos, librevenge::RVNG_SEEK_SET); |
425 | 471k | val = input->readLong(4); // always 0 ? |
426 | 471k | if (val) |
427 | 233k | f << "f2=" << val << ","; |
428 | 471k | ascFile.addPos(pos); |
429 | 471k | ascFile.addNote(f.str().c_str()); |
430 | 471k | } |
431 | 370k | } |
432 | | |
433 | 66.2k | return true; |
434 | 267k | } |
435 | | |
436 | | bool ClarisWksPresentation::readZone2(ClarisWksPresentationInternal::Presentation &/*pres*/) |
437 | 66.2k | { |
438 | 66.2k | libmwaw::DebugFile &ascFile = m_parserState->m_asciiFile; |
439 | 66.2k | libmwaw::DebugStream f; |
440 | | |
441 | 66.2k | MWAWInputStreamPtr &input= m_parserState->m_input; |
442 | 66.2k | long pos = input->tell(); |
443 | 66.2k | long endPos = pos+16; |
444 | 66.2k | input->seek(endPos, librevenge::RVNG_SEEK_SET); |
445 | 66.2k | if (long(input->tell()) != endPos) { |
446 | 313 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
447 | 313 | MWAW_DEBUG_MSG(("ClarisWksPresentation::readZone2: zone seems too short\n")); |
448 | 313 | return false; |
449 | 313 | } |
450 | | |
451 | 65.9k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
452 | 65.9k | f << "Entries(PresentationTitle):"; |
453 | | // checkme this also be 1 times : [ 0, f2] or 1, str0, f2, or a mixt |
454 | 263k | for (int i = 0; i < 3; i++) { // find f0=1, f1=0, f2=[0|1|2|4] |
455 | 197k | long val = input->readLong(4); |
456 | 197k | if (val) |
457 | 105k | f << "f" << i << "=" << val << ","; |
458 | 197k | } |
459 | 65.9k | auto sSz = static_cast<int>(input->readLong(4)); |
460 | 65.9k | input->seek(pos+16+sSz, librevenge::RVNG_SEEK_SET); |
461 | 65.9k | if (sSz < 0 || input->tell() != pos+16+sSz) { |
462 | 30.7k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
463 | 30.7k | MWAW_DEBUG_MSG(("ClarisWksPresentation::readZone2: can not read title\n")); |
464 | 30.7k | return false; |
465 | 30.7k | } |
466 | 35.1k | input->seek(pos+16, librevenge::RVNG_SEEK_SET); |
467 | 35.1k | std::string title(""); |
468 | 2.05M | for (int s = 0; s < sSz; s++) |
469 | 2.02M | title += char(input->readULong(1)); |
470 | 35.1k | f << title << ","; |
471 | | |
472 | 35.1k | ascFile.addPos(pos); |
473 | 35.1k | ascFile.addNote(f.str().c_str()); |
474 | 35.1k | return true; |
475 | 65.9k | } |
476 | | |
477 | | //////////////////////////////////////////////////////////// |
478 | | // |
479 | | // Low level |
480 | | // |
481 | | //////////////////////////////////////////////////////////// |
482 | | |
483 | | bool ClarisWksPresentation::sendMaster() |
484 | 7.34k | { |
485 | 7.34k | if (!m_state->m_presentation) { |
486 | 0 | MWAW_DEBUG_MSG(("ClarisWksPresentation::sendMaster: oops can not find main presentation\n")); |
487 | 0 | return false; |
488 | 0 | } |
489 | 7.34k | int masterId=m_state->m_presentation->m_masterId; |
490 | 7.34k | return m_document.sendZone(masterId > 0 ? masterId : 2); |
491 | 7.34k | } |
492 | | |
493 | | bool ClarisWksPresentation::sendZone(int number) |
494 | 19.8k | { |
495 | 19.8k | if (number != 1) { |
496 | 2.13k | MWAW_DEBUG_MSG(("ClarisWksPresentation::sendZone: sending embeded presentation is not implemented\n")); |
497 | 2.13k | return false; |
498 | 2.13k | } |
499 | 17.7k | auto presentation = m_state->m_presentation; |
500 | 17.7k | MWAWPresentationListenerPtr listener=m_parserState->m_presentationListener; |
501 | 17.7k | if (!presentation || !listener) { |
502 | 0 | MWAW_DEBUG_MSG(("ClarisWksPresentation::sendZone: can not find the presentation listener\n")); |
503 | 0 | return false; |
504 | 0 | } |
505 | 17.7k | presentation->m_parsed = true; |
506 | 17.7k | if (!presentation->m_masterDetached) |
507 | 16.6k | m_document.forceParsed(number+1); |
508 | 128k | for (size_t p = 0; p < presentation->m_contentIdList.size(); p++) { |
509 | 110k | if (p) |
510 | 98.3k | listener->insertBreak(MWAWListener::PageBreak); |
511 | | |
512 | | // first insert the content |
513 | | |
514 | 110k | int id = presentation->m_contentIdList[p]; |
515 | 110k | if (id > 0) |
516 | 110k | m_document.sendZone(id); |
517 | | |
518 | | // try to retrieve the notes: ie. the text zone in the notes zone |
519 | 110k | if (p>=presentation->m_noteIdList.size() || presentation->m_noteIdList[p] <=0) |
520 | 104k | continue; |
521 | | |
522 | 6.00k | auto zone=m_document.getZone(presentation->m_noteIdList[p]); |
523 | 6.00k | if (!zone) continue; |
524 | 3.75k | std::vector<int> listTextChild; |
525 | 2.04M | for (auto const &cZone : zone->m_childs) { |
526 | 2.04M | if (cZone.m_type != ClarisWksStruct::DSET::C_Zone) |
527 | 1.99M | continue; |
528 | 57.4k | int cId=cZone.m_id; |
529 | 57.4k | auto child=m_document.getZone(cId); |
530 | 57.4k | if (child && child->m_fileType==1) |
531 | 7.60k | listTextChild.push_back(cId); |
532 | 57.4k | } |
533 | 3.75k | if (listTextChild.size()!=1) { |
534 | 2.44k | MWAW_DEBUG_MSG(("ClarisWksPresentation::sendZone: the number of notes text zone is odd=%d\n", |
535 | 2.44k | static_cast<int>(listTextChild.size()))); |
536 | 2.44k | } |
537 | 3.75k | if (listTextChild.empty()) |
538 | 1.55k | continue; |
539 | 2.20k | std::shared_ptr<MWAWSubDocument> doc(new ClarisWksPresentationInternal::SubDocument(*this, m_parserState->m_input, listTextChild[0])); |
540 | | // fixme |
541 | 2.20k | MWAWPosition pos(MWAWVec2f(0,400), MWAWVec2f(600,200), librevenge::RVNG_POINT); |
542 | 2.20k | pos.m_anchorTo=MWAWPosition::Page; |
543 | 2.20k | listener->insertSlideNote(pos, doc); |
544 | 2.20k | } |
545 | 17.7k | return true; |
546 | 17.7k | } |
547 | | |
548 | | void ClarisWksPresentation::flushExtra() |
549 | 0 | { |
550 | 0 | std::shared_ptr<MWAWListener> listener=m_parserState->getMainListener(); |
551 | 0 | if (!listener || listener->getType()!=MWAWListener::Presentation) return; |
552 | | |
553 | 0 | for (auto const &iter : m_state->m_presentationMap) { |
554 | 0 | auto presentation = iter.second; |
555 | 0 | if (presentation->m_parsed) |
556 | 0 | continue; |
557 | 0 | listener->insertEOL(); |
558 | 0 | sendZone(iter.first); |
559 | 0 | } |
560 | 0 | } |
561 | | // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: |