olefilters/powerpoint97/powerpoint.cpp
1/*
2 Copyright (C) 2000, S.R.Haque <shaheedhaque@hotmail.com>.
3 This file is part of the KDE project
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19
20DESCRIPTION
21*/
22
23#include <kdebug.h>
24#include <myfile.h>
25#include <powerpoint.h>
26
27const int Powerpoint::s_area = 30512;
28
29Powerpoint::Powerpoint()
30{
31 mEditOffset = 0;
32 m_pptSlide = 0;
33}
34
35Powerpoint::~Powerpoint()
36{
37 m_persistentReferences.clear();
38 //m_slides.clear();
39}
40
41void Powerpoint::invokeHandler(
42 Header &op,
43 TQ_UINT32 bytes,
44 TQDataStream &operands)
45{
46 typedef void (Powerpoint::*method)(Header &op, TQ_UINT32 bytes, TQDataStream &operands);
47
48 typedef struct
49 {
50 const char *name;
51 TQ_UINT16 opcode;
52 method handler;
53 } opcodeEntry;
54
55 static const opcodeEntry funcTab[] =
56 {
57 { "ANIMATIONINFO", 4116, 0 /* &Powerpoint::opAnimationInfo */ },
58 { "ANIMATIONINFOATOM", 4081, 0 /* &Powerpoint::opAnimationInfoAtom */ },
59 { "ARRAYELEMENTATOM", 2030, 0 /* &Powerpoint::opArrayElementAtom */ },
60 { "BASETEXTPROPATOM", 4002, 0 /* &Powerpoint::opBaseTextPropAtom */ },
61 { "BINARYTAGDATA", 5003, 0 /* &Powerpoint::opBinaryTagData */ },
62 { "BOOKMARKCOLLECTION", 2019, 0 /* &Powerpoint::opBookmarkCollection */ },
63 { "BOOKMARKENTITYATOM", 4048, 0 /* &Powerpoint::opBookmarkEntityAtom */ },
64 { "BOOKMARKSEEDATOM", 2025, 0 /* &Powerpoint::opBookmarkSeedAtom */ },
65 { "CHARFORMATATOM", 4066, 0 /* &Powerpoint::opCharFormatAtom */ },
66 { "CLIENTSIGNAL1", 6, 0 /* &Powerpoint::opClientSignal1 */ },
67 { "CLIENTSIGNAL2", 7, 0 /* &Powerpoint::opClientSignal2 */ },
68 { "COLORSCHEMEATOM", 2032, &Powerpoint::opColorSchemeAtom },
69 { "COREPICT", 4037, 0 /* &Powerpoint::opCorePict */ },
70 { "COREPICTATOM", 4038, 0 /* &Powerpoint::opCorePictAtom */ },
71 { "CSTRING", 4026, &Powerpoint::opCString },
72 { "CURRENTUSERATOM", 4086, &Powerpoint::opCurrentUserAtom },
73 { "DATETIMEMCATOM", 4087, 0 /* &Powerpoint::opDateTimeMCAtom */ },
74 { "DEFAULTRULERATOM", 4011, 0 /* &Powerpoint::opDefaultRulerAtom */ },
75 { "DOCROUTINGSLIP", 1030, 0 /* &Powerpoint::opDocRoutingSlip */ },
76 { "DOCUMENT", 1000, &Powerpoint::opDocument },
77 { "DOCUMENTATOM", 1001, &Powerpoint::opDocumentAtom },
78 { "DOCVIEWINFO", 1014, 0 /* &Powerpoint::opDocViewInfo */ },
79 { "EMFORMATATOM", 4065, 0 /* &Powerpoint::opEmFormatAtom */ },
80 { "ENDDOCUMENT", 1002, &Powerpoint::opEndDocument },
81 { "ENVIRONMENT", 1010, &Powerpoint::opEnvironment },
82 { "EXAVIMOVIE", 4102, 0 /* &Powerpoint::opExAviMovie */ },
83 { "EXCDAUDIO", 4110, 0 /* &Powerpoint::opExCDAudio */ },
84 { "EXCDAUDIOATOM", 4114, 0 /* &Powerpoint::opExCDAudioAtom */ },
85 { "EXCONTROL", 4078, 0 /* &Powerpoint::opExControl */ },
86 { "EXCONTROLATOM", 4091, 0 /* &Powerpoint::opExControlAtom */ },
87 { "EXEMBED", 4044, &Powerpoint::opExEmbed },
88 { "EXEMBEDATOM", 4045, &Powerpoint::opExEmbedAtom },
89 { "EXHYPERLINK", 4055, 0 /* &Powerpoint::opExHyperlink */ },
90 { "EXHYPERLINKATOM", 4051, 0 /* &Powerpoint::opExHyperlinkAtom */ },
91 { "EXLINK", 4046, 0 /* &Powerpoint::opExLink */ },
92 { "EXLINKATOM", 4049, 0 /* &Powerpoint::opExLinkAtom */ },
93 { "EXLINKATOM_OLD", 4047, 0 /* &Powerpoint::opExLinkAtom_old */ },
94 { "EXMCIMOVIE", 4103, 0 /* &Powerpoint::opExMCIMovie */ },
95 { "EXMEDIAATOM", 4100, 0 /* &Powerpoint::opExMediaAtom */ },
96 { "EXMIDIAUDIO", 4109, 0 /* &Powerpoint::opExMIDIAudio */ },
97 { "EXOBJLIST", 1033, &Powerpoint::opExObjList },
98 { "EXOBJLISTATOM", 1034, &Powerpoint::opExObjListAtom },
99 { "EXOBJREFATOM", 3009, &Powerpoint::opExObjRefAtom },
100 { "EXOLEOBJ", 4034, &Powerpoint::opExOleObj },
101 { "EXOLEOBJATOM", 4035, &Powerpoint::opExOleObjAtom },
102 { "EXOLEOBJSTG", 4113, &Powerpoint::opExOleObjStg },
103 { "EXPLAIN", 4053, 0 /* &Powerpoint::opExPlain */ },
104 { "EXPLAINATOM", 4039, 0 /* &Powerpoint::opExPlainAtom */ },
105 { "EXPLAINLINK", 4054, 0 /* &Powerpoint::opExPlainLink */ },
106 { "EXPLAINLINKATOM", 4036, 0 /* &Powerpoint::opExPlainLinkAtom */ },
107 { "EXQUICKTIME", 4073, 0 /* &Powerpoint::opExQuickTime */ },
108 { "EXQUICKTIMEMOVIE", 4074, 0 /* &Powerpoint::opExQuickTimeMovie */ },
109 { "EXQUICKTIMEMOVIEDATA", 4075, 0 /* &Powerpoint::opExQuickTimeMovieData */ },
110 { "EXSUBSCRIPTION", 4076, 0 /* &Powerpoint::opExSubscription */ },
111 { "EXSUBSCRIPTIONSECTION", 4077, 0 /* &Powerpoint::opExSubscriptionSection */ },
112 { "EXTERNALOBJECT", 4027, 0 /* &Powerpoint::opExternalObject */ },
113 { "EXVIDEO", 4101, 0 /* &Powerpoint::opExVideo */ },
114 { "EXWAVAUDIOEMBEDDED", 4111, 0 /* &Powerpoint::opExWAVAudioEmbedded */ },
115 { "EXWAVAUDIOEMBEDDEDATOM", 4115, 0 /* &Powerpoint::opExWAVAudioEmbeddedAtom */ },
116 { "EXWAVAUDIOLINK", 4112, 0 /* &Powerpoint::opExWAVAudioLink */ },
117 { "FONTCOLLECTION", 2005, &Powerpoint::opFontCollection },
118 { "FONTEMBEDDATA", 4024, 0 /* &Powerpoint::opFontEmbedData */ },
119 { "FONTENTITYATOM", 4023, &Powerpoint::opFontEntityAtom },
120 { "FOOTERMCATOM", 4090, 0 /* &Powerpoint::opFooterMCAtom */ },
121 { "GENERICDATEMCATOM", 4088, 0 /* &Powerpoint::opGenericDateMCAtom */ },
122 { "GLINEATOM", 10004, 0 /* &Powerpoint::opGlineAtom */ },
123 { "GLPOINTATOM", 10003, 0 /* &Powerpoint::opGLPointAtom */ },
124 { "GPOINTATOM", 3034, 0 /* &Powerpoint::opGpointAtom */ },
125 { "GRATIOATOM", 3031, 0 /* &Powerpoint::opGratioAtom */ },
126 { "GRCOLOR", 3020, 0 /* &Powerpoint::opGrColor */ },
127 { "GRCOLORATOM", 10002, 0 /* &Powerpoint::opGrColorAtom */ },
128 { "GRECTATOM", 3025, 0 /* &Powerpoint::opGrectAtom */ },
129 { "GSCALING", 3032, 0 /* &Powerpoint::opGscaling */ },
130 { "GSCALINGATOM", 10001, 0 /* &Powerpoint::opGscalingAtom */ },
131 { "GUIDEATOM", 1019, 0 /* &Powerpoint::opGuideAtom */ },
132 { "GUIDELIST", 2026, 0 /* &Powerpoint::opGuideList */ },
133 { "HANDOUT", 4041, 0 /* &Powerpoint::opHandout */ },
134 { "HEADERMCATOM", 4089, 0 /* &Powerpoint::opHeaderMCAtom */ },
135 { "HEADERSFOOTERS", 4057, &Powerpoint::opHeadersFooters },
136 { "HEADERSFOOTERSATOM", 4058, &Powerpoint::opHeadersFootersAtom },
137 { "INT4ARRAYATOM", 2031, 0 /* &Powerpoint::opInt4ArrayAtom */ },
138 { "INTERACTIVEINFO", 4082, 0 /* &Powerpoint::opInteractiveInfo */ },
139 { "INTERACTIVEINFOATOM", 4083, 0 /* &Powerpoint::opInteractiveInfoAtom */ },
140 { "IRRATOM", 2, 0 /* &Powerpoint::opIRRAtom */ },
141 { "LIST", 2000, &Powerpoint::opList },
142 { "LISTPLACEHOLDER", 2017, 0 /* &Powerpoint::opListPlaceholder */ },
143 { "MAINMASTER", 1016, &Powerpoint::opMainMaster },
144 { "MASTERTEXT", 4068, 0 /* &Powerpoint::opMasterText */ },
145 { "METAFILE", 4033, 0 /* &Powerpoint::opMetaFile */ },
146 { "NAMEDSHOW", 1041, 0 /* &Powerpoint::opNamedShow */ },
147 { "NAMEDSHOWS", 1040, 0 /* &Powerpoint::opNamedShows */ },
148 { "NAMEDSHOWSLIDES", 1042, 0 /* &Powerpoint::opNamedShowSlides */ },
149 { "NOTES", 1008, &Powerpoint::opNotes },
150 { "NOTESATOM", 1009, &Powerpoint::opNotesAtom },
151 { "OEPLACEHOLDERATOM", 3011, 0 /* &Powerpoint::opOEPlaceholderAtom */ },
152 { "OESHAPE", 3008, 0 /* &Powerpoint::opOEShape */ },
153 { "OESHAPEATOM", 3035, 0 /* &Powerpoint::opOEShapeAtom */ },
154 { "OUTLINETEXTREFATOM", 3998, 0 /* &Powerpoint::opOutlineTextRefAtom */ },
155 { "OUTLINEVIEWINFO", 1031, &Powerpoint::opOutlineViewInfo },
156 { "PARAFORMATATOM", 4067, 0 /* &Powerpoint::opParaFormatAtom */ },
157 { "PERSISTPTRFULLBLOCK", 6001, 0 /* &Powerpoint::opPersistPtrFullBlock */ },
158 { "PERSISTPTRINCREMENTALBLOCK", 6002, &Powerpoint::opPersistPtrIncrementalBlock },
159 { "POWERPOINTSTATEINFOATOM", 10, 0 /* &Powerpoint::opPowerPointStateInfoAtom */ },
160 { "PPDRAWING", 1036, &Powerpoint::opPPDrawing },
161 { "PPDRAWINGGROUP", 1035, &Powerpoint::opPPDrawingGroup },
162 { "PRINTOPTIONS", 6000, 0 /* &Powerpoint::opPrintOptions */ },
163 { "PROGBINARYTAG", 5002, 0 /* &Powerpoint::opProgBinaryTag */ },
164 { "PROGSTRINGTAG", 5001, 0 /* &Powerpoint::opProgStringTag */ },
165 { "PROGTAGS", 5000, 0 /* &Powerpoint::opProgTags */ },
166 { "PSS", 3, 0 /* &Powerpoint::opPSS */ },
167 { "RECOLORENTRYATOM", 4062, 0 /* &Powerpoint::opRecolorEntryAtom */ },
168 { "RECOLORINFOATOM", 4071, 0 /* &Powerpoint::opRecolorInfoAtom */ },
169 { "RTFDATETIMEMCATOM", 4117, 0 /* &Powerpoint::opRTFDateTimeMCAtom */ },
170 { "RULERINDENTATOM", 10000, 0 /* &Powerpoint::opRulerIndentAtom */ },
171 { "RUNARRAY", 2028, 0 /* &Powerpoint::opRunArray */ },
172 { "RUNARRAYATOM", 2029, 0 /* &Powerpoint::opRunArrayAtom */ },
173 { "SCHEME", 1012, 0 /* &Powerpoint::opScheme */ },
174 { "SCHEMEATOM", 1013, 0 /* &Powerpoint::opSchemeAtom */ },
175 { "SLIDE", 1006, &Powerpoint::opSlide },
176 { "SLIDEATOM", 1007, &Powerpoint::opSlideAtom },
177 { "SLIDEBASE", 1004, 0 /* &Powerpoint::opSlideBase */ },
178 { "SLIDEBASEATOM", 1005, 0 /* &Powerpoint::opSlideBaseAtom */ },
179 { "SLIDELIST", 4084, 0 /* &Powerpoint::opSlideList */ },
180 { "SLIDELISTWITHTEXT", 4080, &Powerpoint::opSlideListWithText },
181 { "SLIDENUMBERMCATOM", 4056, 0 /* &Powerpoint::opSlideNumberMCAtom */ },
182 { "SLIDEPERSIST", 1003, 0 /* &Powerpoint::opSlidePersist */ },
183 { "SLIDEPERSISTATOM", 1011, &Powerpoint::opSlidePersistAtom },
184 { "SLIDEVIEWINFO", 1018, &Powerpoint::opSlideViewInfo },
185 { "SLIDEVIEWINFOATOM", 1022, 0 /* &Powerpoint::opSlideViewInfoAtom */ },
186 { "SORTERVIEWINFO", 1032, 0 /* &Powerpoint::opSorterViewInfo */ },
187 { "SOUND", 2022, 0 /* &Powerpoint::opSound */ },
188 { "SOUNDCOLLATOM", 2021, 0 /* &Powerpoint::opSoundCollAtom */ },
189 { "SOUNDCOLLECTION", 2020, 0 /* &Powerpoint::opSoundCollection */ },
190 { "SOUNDDATA", 2023, 0 /* &Powerpoint::opSoundData */ },
191 { "SRKINSOKU", 4040, &Powerpoint::opSrKinsoku },
192 { "SRKINSOKUATOM", 4050, 0 /* &Powerpoint::opSrKinsokuAtom */ },
193 { "SSDOCINFOATOM", 1025, &Powerpoint::opSSDocInfoAtom },
194 { "SSLIDELAYOUTATOM", 1015, &Powerpoint::opSSSlideLayoutAtom },
195 { "SSSLIDEINFOATOM", 1017, 0 /* &Powerpoint::opSSSlideInfoAtom */ },
196 { "STYLETEXTPROPATOM", 4001, &Powerpoint::opStyleTextPropAtom },
197 { "SUBCONTAINERCOMPLETED", 1, 0 /* &Powerpoint::opSubContainerCompleted */ },
198 { "SUBCONTAINEREXCEPTION", 4, 0 /* &Powerpoint::opSubContainerException */ },
199 { "SUMMARY", 1026, 0 /* &Powerpoint::opSummary */ },
200 { "TEXTBOOKMARKATOM", 4007, 0 /* &Powerpoint::opTextBookmarkAtom */ },
201 { "TEXTBYTESATOM", 4008, &Powerpoint::opTextBytesAtom },
202 { "TEXTCHARSATOM", 4000, &Powerpoint::opTextCharsAtom },
203 { "TEXTHEADERATOM", 3999, &Powerpoint::opTextHeaderAtom },
204 { "TEXTRULERATOM", 4006, 0 /* &Powerpoint::opTextRulerAtom */ },
205 { "TEXTSPECINFOATOM", 4010, &Powerpoint::opTextSpecInfoAtom },
206 { "TEXTURE", 1027, 0 /* &Powerpoint::opTexture */ },
207 { "TXCFSTYLEATOM", 4004, 0 /* &Powerpoint::opTxCFStyleAtom */ },
208 { "TXINTERACTIVEINFOATOM", 4063, 0 /* &Powerpoint::opTxInteractiveInfoAtom */ },
209 { "TXMASTERSTYLEATOM", 4003, &Powerpoint::opTxMasterStyleAtom },
210 { "TXPFSTYLEATOM", 4005, 0 /* &Powerpoint::opTxPFStyleAtom */ },
211 { "TXSISTYLEATOM", 4009, &Powerpoint::opTxSIStyleAtom },
212 { "TYPEFACE", 4025, 0 /* &Powerpoint::opTypeFace */ },
213 { "USEREDITATOM", 4085, &Powerpoint::opUserEditAtom },
214 { "VBAINFO", 1023, &Powerpoint::opVBAInfo },
215 { "VBAINFOATOM", 1024, 0 /* &Powerpoint::opVBAInfoAtom */ },
216 { "VBASLIDEINFO", 1028, 0 /* &Powerpoint::opVBASlideInfo */ },
217 { "VBASLIDEINFOATOM", 1029, 0 /* &Powerpoint::opVBASlideInfoAtom */ },
218 { "VIEWINFO", 1020, 0 /* &Powerpoint::opViewInfo */ },
219 { "VIEWINFOATOM", 1021, 0 /* &Powerpoint::opViewInfoAtom */ },
220 { NULL, 0, 0 },
221 { "MSOD", 0, &Powerpoint::opMsod }
222 };
223 unsigned i;
224 method result;
225
226 // Scan lookup table for operation.
227
228 for (i = 0; funcTab[i].name; i++)
229 {
230 if (funcTab[i].opcode == op.type)
231 {
232 break;
233 }
234 }
235
236 // Invoke handler.
237
238 result = funcTab[i].handler;
239 if (!result && (op.type >= 0xF000) && (0xFFFF >= op.type))
240 result = funcTab[++i].handler;
241 if (!result)
242 {
243 if (funcTab[i].name)
244 kdWarning(s_area) << "invokeHandler: unsupported opcode: " <<
245 funcTab[i].name <<
246 " operands: " << bytes << endl;
247 else
248 kdWarning(s_area) << "invokeHandler: unsupported opcode: " <<
249 op.type <<
250 " operands: " << bytes << endl;
251
252 // Skip data we cannot use.
253 skip(bytes, operands);
254 }
255 else
256 {
257 kdDebug(s_area) << "invokeHandler: opcode: " << funcTab[i].name <<
258 " operands: " << bytes << endl;
259
260 // We don't invoke the handler directly on the incoming operands, but
261 // via a temporary datastream. This adds overhead, but eliminates the
262 // need for the individual handlers to read *exactly* the right amount
263 // of data (thus speeding development, and possibly adding some
264 // future-proofing).
265
266 if (bytes)
267 {
268 TQByteArray *record = new TQByteArray(bytes);
269 TQDataStream *body;
270
271 operands.readRawBytes(record->data(), bytes);
272 body = new TQDataStream(*record, IO_ReadOnly);
273 body->setByteOrder(TQDataStream::LittleEndian);
274 (this->*result)(op, bytes, *body);
275 delete body;
276 delete record;
277 }
278 else
279 {
280 TQDataStream *body = new TQDataStream();
281
282 (this->*result)(op, bytes, *body);
283 delete body;
284 }
285 }
286}
287
288bool Powerpoint::parse(
289 myFile &mainStream,
290 myFile &currentUser,
291 myFile &pictures)
292{
293 unsigned i;
294
295 m_mainStream = mainStream;
296 m_pictures = pictures;
297 m_documentRef = 0;
298 m_documentRefFound = false;
299 m_persistentReferences.clear();
300 m_slideList.clear();
301 m_editDepth = 0;
302
303 // Find the slide references.
304
305 m_pass = PASS_GET_SLIDE_REFERENCES;
306 kdError(s_area) << "parseing step 1 walkRecord..." << endl;
307 walkRecord(currentUser.length, currentUser.data);//get curren user information
308
309 kdError(s_area) << "parseing step 2 walkReference..." << endl;
310 //for(i = 0; i <= 2; i++)//walk the 2 slide atoms
311 //{
312 // kdError(s_area) << "ref == :" << i <<endl;
313 //walkReference(i);
314 //}
315 kdError(s_area) << "walking slide list!!!!.." << endl;
316 if(mEditOffset != 0) walk(mEditOffset);
317 else walkDocument();
318 // We should have a complete list of slide persistent references.
319 m_pass = PASS_GET_SLIDE_CONTENTS;
320 kdError(s_area) << "TOTAL SLIDES XXxx: " << m_slideList.count() << endl;
321
322 for (i = 0; i < m_slideList.count(); i++)
323 {
324 m_pptSlide = m_slideList.at(i);
325 walkReference(i);
326 gotSlide(*m_pptSlide);
327 }
328
329 return true;
330}
331
332void Powerpoint::opColorSchemeAtom(
333 Header & /* op */,
334 TQ_UINT32,
335 TQDataStream &operands)
336{
337 struct
338 {
339 TQ_UINT32 background;
340 TQ_UINT32 textAndLines;
341 TQ_UINT32 shadows;
342 TQ_UINT32 titleText;
343 TQ_UINT32 fills;
344 TQ_UINT32 accent;
345 TQ_UINT32 accentAndHyperlink;
346 TQ_UINT32 accentAndFollowedHyperlink;
347 } data;
348
349 operands >> data.background >> data.textAndLines >> data.shadows >>
350 data.titleText >> data.fills >> data.accent >> data.accentAndHyperlink >>
351 data.accentAndFollowedHyperlink;
352}
353
354//
355// A Unicode String.
356//
357void Powerpoint::opCString(
358 Header & /* op */,
359 TQ_UINT32 bytes,
360 TQDataStream &operands)
361{
362 TQString value;
363 unsigned i;
364
365 for (i = 0; i < bytes / 2; i++)
366 {
367 TQ_UINT16 tmp;
368
369 operands >> tmp;
370 value += tmp;
371 }
372 kdDebug(s_area) << "value: " << value << endl;
373}
374
375void Powerpoint::opCurrentUserAtom(
376 Header & /* op */,
377 TQ_UINT32 /*bytes*/,
378 TQDataStream &operands)
379{
380
381 const TQ_UINT32 MAGIC_NUMBER = (TQ_UINT32)(-476987297);
382 //unsigned i;
383
384 operands >> mCurrentUserAtom.size >> mCurrentUserAtom.magic >> mCurrentUserAtom.offsetToCurrentEdit >>
385 mCurrentUserAtom.lenUserName >> mCurrentUserAtom.docFileVersion >> mCurrentUserAtom.majorVersion >>
386 mCurrentUserAtom.minorVersion;
387
388 kdDebug(s_area) << "\nPSR_CurrentUserAtom:" <<
389 "\n\tsize: " << mCurrentUserAtom.size <<
390 "\n\tmagic: " << mCurrentUserAtom.magic <<
391 "\n\toffsetToCurrentEdit: " << mCurrentUserAtom.offsetToCurrentEdit <<
392 "\n\tlenUserName: " << mCurrentUserAtom.lenUserName <<
393 "\n\tdocFileVersion: " << mCurrentUserAtom.docFileVersion <<
394 "\n\tmajorVersion: " << mCurrentUserAtom.majorVersion <<
395 "\n\tminorVersion: " << mCurrentUserAtom.minorVersion << endl;
396
397 switch (m_pass)
398 {
399 case PASS_GET_SLIDE_REFERENCES:
400 if (mCurrentUserAtom.size != 20)
401 {
402 kdError(s_area) << "invalid size: " << mCurrentUserAtom.size << endl;
403 }
404 if (mCurrentUserAtom.magic != MAGIC_NUMBER)
405 {
406 kdError(s_area) << "invalid magic number: " << mCurrentUserAtom.magic << endl;
407 }
408 if ((mCurrentUserAtom.docFileVersion != 1012) ||
409 (mCurrentUserAtom.majorVersion != 3) ||
410 (mCurrentUserAtom.minorVersion != 0))// ||
411 // (data.release < 8) ||
412 // (data.release > 10))
413 {
414 kdError(s_area) << "invalid version: " << mCurrentUserAtom.docFileVersion <<
415 "." << mCurrentUserAtom.majorVersion <<
416 "." << mCurrentUserAtom.minorVersion <<
417 endl;
418 //"." << data.release << endl;
419 }
420
421 // Now walk main stream starting at current edit point.
422
423 walkRecord(mCurrentUserAtom.offsetToCurrentEdit);
424 break;
425 case PASS_GET_SLIDE_CONTENTS:
426 break;
427 };
428}
429
430void Powerpoint::opDocument(
431 Header & /* op */,
432 TQ_UINT32 bytes,
433 TQDataStream &operands)
434{
435 walk(bytes, operands);
436}
437
438void Powerpoint::opDocumentAtom(
439 Header & /* op */,
440 TQ_UINT32 /*bytes*/,
441 TQDataStream &/*operands*/)
442{
443}
444
445void Powerpoint::opEndDocument(
446 Header & /* op */,
447 TQ_UINT32 bytes,
448 TQDataStream &operands)
449{
450 walk(bytes, operands);
451}
452
453void Powerpoint::opEnvironment(
454 Header & /* op */,
455 TQ_UINT32 bytes,
456 TQDataStream &operands)
457{
458 walk(bytes, operands);
459}
460
461//
462// Contains an ExEmbedAtom and 3 CStrings (the menu name, the program id which
463// unqiuely identifies the type of object, and the "paste special" name).
464//
465void Powerpoint::opExEmbed(
466 Header & /* op */,
467 TQ_UINT32 bytes,
468 TQDataStream &operands)
469{
470 walk(bytes, operands);
471}
472
473//
474// Information about an embedded object.
475//
476void Powerpoint::opExEmbedAtom(
477 Header & /* op */,
478 TQ_UINT32,
479 TQDataStream &operands)
480{
481 struct
482 {
483 TQ_INT32 followColorScheme;
484 TQ_UINT8 cantLockServerB;
485 TQ_UINT8 noSizeToServerB;
486 TQ_UINT8 isTable;
487 } data;
488
489 operands >> data.followColorScheme;
490 operands >> data.cantLockServerB;
491 operands >> data.noSizeToServerB;
492 operands >> data.isTable;
493}
494
495void Powerpoint::opFontCollection(
496 Header & /* op */,
497 TQ_UINT32 bytes,
498 TQDataStream &operands)
499{
500 walk(bytes, operands);
501}
502
503void Powerpoint::opFontEntityAtom(
504 Header & /* op */,
505 TQ_UINT32 /*bytes*/,
506 TQDataStream &/*operands*/)
507{
508}
509
510void Powerpoint::opHeadersFooters(
511 Header & /* op */,
512 TQ_UINT32 bytes,
513 TQDataStream &operands)
514{
515 walk(bytes, operands);
516}
517
518void Powerpoint::opHeadersFootersAtom(
519 Header & /* op */,
520 TQ_UINT32 /*bytes*/,
521 TQDataStream &/*operands*/)
522{
523}
524
525void Powerpoint::opList(
526 Header & /* op */,
527 TQ_UINT32 bytes,
528 TQDataStream &operands)
529{
530 walk(bytes, operands);
531}
532
533void Powerpoint::opMainMaster(
534 Header & /* op */,
535 TQ_UINT32 bytes,
536 TQDataStream &operands)
537{
538 walk(bytes, operands);
539}
540
541void Powerpoint::opMsod(
542 Header & /* op */,
543 TQ_UINT32 bytes,
544 TQDataStream &operands)
545{
546 char *data;
547
548 switch (m_pass)
549 {
550 case PASS_GET_SLIDE_REFERENCES:
551 break;
552 case PASS_GET_SLIDE_CONTENTS:
553 data = new char[bytes];
554 operands.readRawBytes((char *)data, bytes);
555kdError() <<" drgid: "<< m_pptSlide->getPsrReference() << endl;
556 gotDrawing(m_pptSlide->getPsrReference(), "msod", bytes, data);
557 delete [] data;
558 break;
559 };
560}
561
562void Powerpoint::opNotes(
563 Header & /* op */,
564 TQ_UINT32 bytes,
565 TQDataStream &operands)
566{
567 walk(bytes, operands);
568}
569
570void Powerpoint::opNotesAtom(
571 Header & /* op */,
572 TQ_UINT32 /*bytes*/,
573 TQDataStream &operands)
574{
575 struct
576 {
577 TQ_INT32 slideId; // Id for the corresponding slide.
578 TQ_UINT16 flags;
579 } data;
580
581 operands >> data.slideId >> data.flags;
582}
583
584//
585// Contains an ExObjListAtom and a list of all objects in a document.
586//
587void Powerpoint::opExObjList(
588 Header & /* op */,
589 TQ_UINT32 bytes,
590 TQDataStream &operands)
591{
592 walk(bytes, operands);
593}
594
595//
596// Get the next unique identifier for OLE objects.
597//
598void Powerpoint::opExObjListAtom(
599 Header & /* op */,
600 TQ_UINT32,
601 TQDataStream &operands)
602{
603 TQ_UINT32 objectSeedId;
604
605 operands >> objectSeedId;
606 kdDebug(s_area) << "next OLE obj id: " << objectSeedId << endl;
607}
608
609void Powerpoint::opExObjRefAtom(
610 Header & /* op */,
611 TQ_UINT32 /*bytes*/,
612 TQDataStream &/*operands*/)
613{
614}
615
616void Powerpoint::opExOleObj(
617 Header & /* op */,
618 TQ_UINT32 /*bytes*/,
619 TQDataStream &/*operands*/)
620{
621}
622
623void Powerpoint::opExOleObjAtom(
624 Header & /* op */,
625 TQ_UINT32 /*bytes*/,
626 TQDataStream &operands)
627{
628 struct
629 {
630 TQ_UINT32 drawAspect;
631 TQ_INT32 type;
632 TQ_INT32 objID;
633 TQ_INT32 subType;
634 TQ_INT8 isBlank;
635 } data;
636
637 operands >> data.drawAspect;
638 operands >> data.type;
639 operands >> data.objID;
640 operands >> data.subType;
641 operands >> data.isBlank;
642 kdDebug(s_area) << ((data.type == 0) ? "embedded " : "linked ") <<
643 "OLE obj id: " << data.objID << endl;
644}
645
646void Powerpoint::opExOleObjStg(
647 Header & /* op */,
648 TQ_UINT32 /*bytes*/,
649 TQDataStream &/*operands*/)
650{
651}
652
653void Powerpoint::opOutlineViewInfo(
654 Header & /* op */,
655 TQ_UINT32 bytes,
656 TQDataStream &operands)
657{
658 walk(bytes, operands);
659}
660
661void Powerpoint::opPersistPtrIncrementalBlock2(
662 Header & /* op */,
663 TQ_UINT32 /*bytes*/,
664 TQDataStream &/*operands*/)
665{
666 //PSR_UserEditAtom userEdit;
667 //TQ_INT16 offsetToEdit = mCurrentUserAtom.offsetToCurrentEdit;
668
669 /* huh?
670 while(0 < offsetToEdit)
671 {
672
673 }*/
674
675// mpLastUserEditAtom;
676
677}
678
679void Powerpoint::opPersistPtrIncrementalBlock(
680 Header & /* op */,
681 TQ_UINT32 bytes,
682 TQDataStream &operands)
683{
684 struct
685 {
686 union
687 {
688 TQ_UINT32 info;
689 struct
690 {
691 TQ_UINT32 offsetNumber: 20;
692 TQ_UINT32 offsetCount: 12;
693 } fields;
694 } header;
695 TQ_UINT32 offset;
696 } data;
697 TQ_UINT32 length = 0;
698
699 while (length < bytes)
700 {
701 unsigned i;
702
703 // Walk references numbered between:
704 //
705 // offsetNumber..offsetNumber + offsetCount - 1
706 //
707 operands >> data.header.info;
708 length += sizeof(data.header.info);
709 kdDebug(s_area) << "length1: " << length << endl;
710 kdDebug(s_area) << "m_pass: " << m_pass << endl;
711 //kdDebug(s_area) << "PASS_GET_SLIDE_REFERENCES: " << PASS_GET_SLIDE_REFERENCES << endl;
712 kdDebug(s_area) << "data.header.fields.offsetCount: " << data.header.fields.offsetCount << endl;
713
714 for (i = 0; i < data.header.fields.offsetCount; i++)
715 {
716 unsigned reference = data.header.fields.offsetNumber + i;
717
718 operands >> data.offset;
719 length += sizeof(data.offset);
720 //kdDebug(s_area) << "length2: " << length << endl;
721 switch (m_pass)
722 {
723 case PASS_GET_SLIDE_REFERENCES:
724
725 // Create a record of this persistent reference.
726
727 if (m_persistentReferences.end() == m_persistentReferences.find(reference))
728 {
729 if(reference < 5)
730 {
731 kdDebug(s_area) << "persistent reference: " << reference <<
732 ": " << data.offset << endl;
733 }
734 m_persistentReferences.insert(reference, data.offset);
735 }
736 else
737 {
738 // This reference has already been seen! Since the parse proceeds
739 // backwards in time form the most recent edit, I assume this means
740 // that this is an older version of this slide...so just ignore it.
741 // kdDebug(s_area) << "superseded reference: " << reference <<
742 // ": " << data.offset << endl;
743 }
744 break;
745 case PASS_GET_SLIDE_CONTENTS:
746 break;
747 };
748 }
749 kdDebug(s_area) << "LEAVING persistant block -- " << endl;
750 }
751
752}
753
754void Powerpoint::opPPDrawing(
755 Header & /* op */,
756 TQ_UINT32 bytes,
757 TQDataStream &operands)
758{
759 walk(bytes, operands);
760}
761
762void Powerpoint::opPPDrawingGroup(
763 Header & /* op */,
764 TQ_UINT32 bytes,
765 TQDataStream &operands)
766{
767 walk(bytes, operands);
768}
769
770void Powerpoint::opSlide(
771 Header & /* op */,
772 TQ_UINT32 bytes,
773 TQDataStream &operands)
774{
775 walk(bytes, operands);
776}
777
778void Powerpoint::opSlideAtom(
779 Header & /* op */,
780 TQ_UINT32 /*bytes*/,
781 TQDataStream &operands)
782{
783 struct
784 {
785 TQ_UINT8 layout[12]; // Slide layout descriptor.
786 TQ_INT32 masterId; // Id of the master of the slide. Zero for a master slide.
787 TQ_INT32 notesId; // Id for the corresponding notes slide. Zero if slide has no notes.
788 TQ_UINT16 flags;
789 } data;
790
791 Header tmp;
792 tmp.type = 1015;
793 tmp.length = sizeof(data.layout);
794 invokeHandler(tmp, tmp.length, operands);
795 operands >> data.masterId >> data.notesId >> data.flags;
796
797 kdDebug(s_area) << "\nSlideAtom:" <<
798 "\n\tmasterId: " << data.masterId <<
799 "\n\tnotesId: " << data.notesId <<
800 "\n\tflags: " << data.flags << endl;
801
802 //invokeHandler(tmp, tmp.length, operands);
803
804}
805
806void Powerpoint::opSlideListWithText(
807 Header & /* op */,
808 TQ_UINT32 bytes,
809 TQDataStream &operands)
810{
811 walk(bytes, operands);
812}
813
814void Powerpoint::opSlidePersistAtom(
815 Header & /* op */,
816 TQ_UINT32 /*bytes*/,
817 TQDataStream &operands)
818{
819 struct
820 {
821 TQ_UINT32 psrReference; // Logical reference to the slide persist object.
822 TQ_UINT32 flags; // If bit 3 set then slide contains shapes other than placeholders.
823 TQ_INT32 numberTexts; // Number of placeholder texts stored with the persist object.
824 TQ_INT32 slideId; // Unique slide identifier, used for OLE link monikers for example.
825 TQ_UINT32 reserved;
826 } data;
827
828 operands >> data.psrReference >> data.flags >> data.numberTexts >>
829 data.slideId >> data.reserved;
830
831 kdDebug(s_area) << "\nopSlidePersistAtom: " <<
832 "\n\tpsrReference: " << data.psrReference <<
833 "\n\tflags: " << data.flags <<
834 "\n\tnumberTexts: " << data.numberTexts <<
835 "\n\tslideId: " << data.slideId <<
836 "\n\treserved: " << data.reserved << endl;
837
838 switch (m_pass)
839 {
840 case PASS_GET_SLIDE_REFERENCES:
841 if(data.slideId > 0)//if not master slide.. is there another way to tell???
842 {
843 m_pptSlide = new PptSlide;
844 m_pptSlide->setPsrReference(data.psrReference);
845 m_slideList.append(m_pptSlide);
846
847 kdDebug(s_area) << "XXXXXXXXXslide: " << data.psrReference <<
848 " has texts: " << data.numberTexts << endl;
849 }
850 break;
851 case PASS_GET_SLIDE_CONTENTS:
852 break;
853 };
854}
855
856void Powerpoint::opSlideViewInfo(
857 Header & /* op */,
858 TQ_UINT32 bytes,
859 TQDataStream &operands)
860{
861 walk(bytes, operands);
862}
863
864void Powerpoint::opSrKinsoku(
865 Header & /* op */,
866 TQ_UINT32 bytes,
867 TQDataStream &operands)
868{
869 walk(bytes, operands);
870}
871
872void Powerpoint::opSSDocInfoAtom(
873 Header & /* op */,
874 TQ_UINT32 /*bytes*/,
875 TQDataStream &/*operands*/)
876{
877}
878
879void Powerpoint::opSSSlideLayoutAtom(
880 Header & /* op */,
881 TQ_UINT32 /*bytes*/,
882 TQDataStream &operands)
883{
884
885 PSR_SSlideLayoutAtom data;
886 unsigned i;
887
888 operands >> data.geom;
889 for (i = 0; i < sizeof(data.placeholderId); i++)
890 {
891 operands >> data.placeholderId[i];
892 }
893
894 kdDebug(s_area) << "\nPSR_SSlideLayoutAtom:" <<
895 "\n\tgeom: " << data.geom <<
896 "\n\tplaceholderId[0]: " << data.placeholderId[0] <<
897 "\n\tplaceholderId[1]: " << data.placeholderId[1] <<
898 "\n\tplaceholderId[2]: " << data.placeholderId[2] <<
899 "\n\tplaceholderId[3]: " << data.placeholderId[3] <<
900 "\n\tplaceholderId[4]: " << data.placeholderId[4] <<
901 "\n\tplaceholderId[5]: " << data.placeholderId[5] <<
902 "\n\tplaceholderId[6]: " << data.placeholderId[6] <<
903 "\n\tplaceholderId[7]: " << data.placeholderId[7] << endl;
904
905}
906//this is where we set bold/italic/etc and paragraph styles
907void Powerpoint::opStyleTextPropAtom(
908 Header & /* op */,
909 TQ_UINT32 bytes,
910 TQDataStream &operands)
911{
912
913 TQ_UINT16 totalLength = 0;
914 TQ_UINT16 length = 0;
915 TQ_UINT32 style1 = 0;
916 TQ_UINT32 style2 = 0;
917 TQ_UINT16 style3 = 0;
918 TQ_UINT32 BOLD = 0x00010000;
919 TQ_UINT32 ITALIC = 0x00020000;
920 TQ_UINT32 UNDERLINE = 0x00040000;
921
922 //--get the paragraph style?
923 operands >> length >> style1 >> style2;
924 totalLength += 10;
925
926 kdDebug(s_area) << "\nopStyleTextPropAtom1:" <<
927 "\n\tlength: " << length <<
928 "\n\tstyle1: " << style1 <<
929 "\n\tstyle2: " << style2 << endl;
930 //--
931
932 //--get the char styles
933 while(bytes > totalLength)
934 {
935 length = 0;
936 style1 = 0;
937 style2 = 0;
938 style3 = 0;
939
940 operands >> length >> style1;
941 totalLength += 6;
942 if(style1 == 0)
943 {
944 operands >> style3;
945 totalLength += 2;
946 }
947 else
948 {
949 operands >> style2;
950 totalLength += 4;
951 }
952
953 kdDebug(s_area) << "\nopStyleTextPropAtom2:" <<
954 "\n\tlength: " << length <<
955 "\n\tstyle1: " << style1 <<
956 "\n\tstyle2: " << style2 <<
957 "\n\tstyle3: " << style3 << endl;
958 if(style1 & BOLD)
959 kdDebug(s_area) << "BOLD here" << endl;
960 if(style1 & ITALIC)
961 kdDebug(s_area) << "ITALIC here" << endl;
962 if(style1 & UNDERLINE)
963 kdDebug(s_area) << "UNDERLINE here" << endl;
964 }
965 //--
966}
967
968void Powerpoint::opTextBytesAtom(
969 Header & /* op */,
970 TQ_UINT32 bytes,
971 TQDataStream &operands)
972{
973 TQString data;
974 unsigned i;
975
976 for (i = 0; i < bytes; i++)
977 {
978 TQ_UINT8 tmp;
979
980 operands >> tmp;
981 data += tmp;
982 }
983 kdDebug(s_area) << "\nopTextBytesAtom: " <<
984 "\n\tdata: " << data << endl;
985
986 //SlideText *text;
987 switch (m_pass)
988 {
989 case PASS_GET_SLIDE_REFERENCES:
990 //text = new SlideText;
991 //text->type = m_textType;
992 //text->data = data;
993 //m_slide->text.append(text);
994 if(m_pptSlide)
995 {
996 m_pptSlide->addText(data, m_textType);
997 kdDebug(s_area) << "Text Added: " << data << " type: " << m_textType << endl;
998 }
999 else
1000 kdDebug(s_area) << "WEVE GOTS US AN ERROR!!!" << endl;
1001
1002 break;
1003 case PASS_GET_SLIDE_CONTENTS:
1004 break;
1005 };
1006}
1007
1008void Powerpoint::opTextCharsAtom(
1009 Header & /* op */,
1010 TQ_UINT32 bytes,
1011 TQDataStream &operands)
1012{
1013 TQString data;
1014 unsigned i;
1015
1016 for (i = 0; i < bytes / 2; i++)
1017 {
1018 TQ_UINT16 tmp;
1019
1020 operands >> tmp;
1021 data += tmp;
1022 }
1023
1024 //SlideText *text;
1025 switch (m_pass)
1026 {
1027 case PASS_GET_SLIDE_REFERENCES:
1028 //text = new SlideText;
1029 //text->type = m_textType;
1030 //text->data = data;
1031 //m_slide->text.append(text);
1032 if(m_pptSlide)
1033 {
1034 m_pptSlide->addText(data, m_textType);
1035 kdDebug(s_area) << "Text Added: " << data << " type: " << m_textType << endl;
1036 }
1037 else
1038 kdDebug(s_area) << "WEVE GOTS US AN ERROR!!!" << endl;
1039
1040 break;
1041 case PASS_GET_SLIDE_CONTENTS:
1042 break;
1043 };
1044}
1045
1046void Powerpoint::opTextHeaderAtom(
1047 Header & /* op */,
1048 TQ_UINT32 /*bytes*/,
1049 TQDataStream &operands)
1050{
1051 struct
1052 {
1053 TQ_UINT32 txType; // Type of text:
1054 //
1055 // 0 Title
1056 // 1 Body
1057 // 2 Notes
1058 // 3 Not Used
1059 // 4 Other (Text in a shape)
1060 // 5 Center body (subtitle in title slide)
1061 // 6 Center title (title in title slide)
1062 // 7 Half body (body in two-column slide)
1063 // 8 Quarter body (body in four-body slide)
1064 } data;
1065
1066 operands >> data.txType;
1067
1068 kdDebug(s_area) << "\nopTextHeaderAtom:" <<
1069 "\n\ttxType: " << data.txType << endl;
1070
1071 switch (m_pass)
1072 {
1073 case PASS_GET_SLIDE_REFERENCES:
1074 m_textType = data.txType;
1075 break;
1076 case PASS_GET_SLIDE_CONTENTS:
1077 break;
1078 };
1079}
1080
1081void Powerpoint::opTextSpecInfoAtom(
1082 Header & /* op */,
1083 TQ_UINT32 /*bytes*/,
1084 TQDataStream &/*operands*/)
1085{
1086}
1087
1088void Powerpoint::opTxMasterStyleAtom(
1089 Header & /* op */,
1090 TQ_UINT32 /*bytes*/,
1091 TQDataStream &/*operands*/)
1092{
1093}
1094
1095void Powerpoint::opTxSIStyleAtom(
1096 Header & /* op */,
1097 TQ_UINT32 /*bytes*/,
1098 TQDataStream &/*operands*/)
1099{
1100}
1101
1102//
1103// This routine is where the parse actually gets going. It should be the first
1104// structure encoutered in the main OLE stream.
1105//
1106void Powerpoint::opUserEditAtom(
1107 Header & /* op */,
1108 TQ_UINT32 /*bytes*/,
1109 TQDataStream &operands)
1110{
1111
1112 operands >> mUserEditAtom.lastSlideID >> mUserEditAtom.version >> mUserEditAtom.offsetLastEdit >>
1113 mUserEditAtom.offsetPersistDirectory >> mUserEditAtom.documentRef >>
1114 mUserEditAtom.maxPersistWritten >> mUserEditAtom.lastViewType;
1115
1116 if(mEditOffset == 0)mEditOffset = mUserEditAtom.offsetLastEdit;
1117
1118 kdDebug(s_area) << "\nPSR_UserEditAtom:" <<
1119 "\n\tlastSlideID: " << mUserEditAtom.lastSlideID <<
1120 "\n\tversion: " << mUserEditAtom.version <<
1121 "\n\toffsetLastEdit: " << mUserEditAtom.offsetLastEdit <<
1122 "\n\toffsetPersistDirectory: " << mUserEditAtom.offsetPersistDirectory <<
1123 "\n\tdocumentRef: " << mUserEditAtom.documentRef <<
1124 "\n\tmaxPersistWritten: " << mUserEditAtom.maxPersistWritten <<
1125 "\n\tlastViewType: " << mUserEditAtom.lastViewType << endl;
1126
1127 if (!m_documentRefFound)
1128 {
1129 m_documentRef = mUserEditAtom.documentRef;
1130 m_documentRefFound = true;
1131 }
1132 switch (m_pass)
1133 {
1134 case PASS_GET_SLIDE_REFERENCES:
1135
1136 // Gather the persistent references. That should fill the list of
1137 // references which we then use to look up our document.
1138
1139 walkRecord(mUserEditAtom.offsetPersistDirectory);
1140
1141 // Now recursively walk the main OLE stream parsing previous edits.
1142
1143 if (mUserEditAtom.offsetLastEdit)
1144 {
1145 m_editDepth++;
1146 walkRecord(mUserEditAtom.offsetLastEdit);
1147 m_editDepth--;
1148 }
1149 break;
1150 case PASS_GET_SLIDE_CONTENTS:
1151 break;
1152 };
1153}
1154
1155void Powerpoint::opVBAInfo(
1156 Header & /* op */,
1157 TQ_UINT32 bytes,
1158 TQDataStream &operands)
1159{
1160 walk(bytes, operands);
1161}
1162
1163void Powerpoint::skip(TQ_UINT32 bytes, TQDataStream &operands)
1164{
1165 if ((int)bytes < 0)
1166 {
1167 kdError(s_area) << "skip: " << (int)bytes << endl;
1168 return;
1169 }
1170 if (bytes)
1171 {
1172 TQ_UINT32 i;
1173 TQ_UINT8 discard;
1174
1175 kdDebug(s_area) << "skip: " << bytes << endl;
1176 for (i = 0; i < bytes; i++)
1177 {
1178 operands >> discard;
1179 }
1180 }
1181}
1182
1183//
1184// Handle a container record.
1185//
1186void Powerpoint::walk(TQ_UINT32 bytes, TQDataStream &operands)
1187{
1188 Header op;
1189 TQ_UINT32 length = 0;
1190
1191 // Stop parsing when there are no more records. Note that we stop as soon
1192 // as we cannot get a complete header.
1193 while (length + 8 <= bytes)
1194 {
1195 operands >> op.opcode.info >> op.type >> op.length;
1196
1197 // If we get some duff data, protect ourselves.
1198 if (length + op.length + 8 > bytes)
1199 {
1200 op.length = bytes - length - 8;
1201 }
1202 length += op.length + 8;
1203
1204 // Package the arguments...
1205
1206 invokeHandler(op, op.length, operands);
1207 }
1208
1209 // Eat unexpected data that the caller may expect us to consume.
1210 skip(bytes - length, operands);
1211}
1212
1213void Powerpoint::walk(TQ_UINT32 mainStreamOffset)
1214{
1215 TQ_UINT32 length = m_mainStream.length - mainStreamOffset;
1216 TQByteArray a;
1217
1218 a.setRawData((const char *)m_mainStream.data + mainStreamOffset, length);
1219 TQDataStream stream(a, IO_ReadOnly);
1220 stream.setByteOrder(TQDataStream::LittleEndian);
1221 walk(length, stream);
1222 a.resetRawData((const char *)m_mainStream.data + mainStreamOffset, length);
1223}
1224void Powerpoint::walkDocument()
1225{
1226 TQByteArray a;
1227 TQ_UINT32 mainStreamOffset = 0;
1228 TQ_UINT32 bytes = m_mainStream.length - mainStreamOffset;
1229
1230 a.setRawData((const char *)m_mainStream.data + mainStreamOffset, bytes);
1231 TQDataStream stream(a, IO_ReadOnly);
1232 stream.setByteOrder(TQDataStream::LittleEndian);
1233 //--get tho the slide list
1234 Header op;
1235 TQ_UINT32 length = 0;
1236
1237 // Stop parsing when there are no more records. Note that we stop as soon
1238 // as we cannot get a complete header.
1239 while (length + 8 <= bytes && op.type != 1000)//document
1240 {
1241 stream >> op.opcode.info >> op.type >> op.length;
1242
1243 // If we get some duff data, protect ourselves.
1244 if (length + op.length + 8 > bytes)
1245 {
1246 op.length = bytes - length - 8;
1247 }
1248 length += op.length + 8;
1249 }
1250
1251 //--
1252 invokeHandler(op, op.length, stream);
1253 a.resetRawData((const char *)m_mainStream.data + mainStreamOffset, bytes);
1254
1255}
1256
1257void Powerpoint::walkRecord(TQ_UINT32 bytes, const unsigned char *operands)
1258{
1259 // First read what should be the next header using one stream.
1260
1261 kdError(s_area) << "WalkRecord - bytes: " << bytes << endl;
1262
1263 TQ_UINT32 length = sizeof(Header);
1264 TQByteArray a;
1265 Header op;
1266
1267 a.setRawData((const char *)operands, bytes);
1268 TQDataStream stream1(a, IO_ReadOnly);
1269 stream1.setByteOrder(TQDataStream::LittleEndian);
1270 stream1 >> op.opcode.info >> op.type >> op.length;
1271 a.resetRawData((const char *)operands, bytes);
1272
1273 // Armed with the length, parse in the usual way using a second stream.
1274
1275 length += op.length;
1276 a.setRawData((const char *)operands, length);
1277 TQDataStream stream2(a, IO_ReadOnly);
1278 stream2.setByteOrder(TQDataStream::LittleEndian);
1279 walk(length, stream2);
1280 a.resetRawData((const char *)operands, length);
1281}
1282
1283void Powerpoint::walkRecord(TQ_UINT32 mainStreamOffset)
1284{
1285 walkRecord(sizeof(Header), m_mainStream.data + mainStreamOffset);
1286}
1287
1288void Powerpoint::walkReference(TQ_UINT32 reference)
1289{
1290 if (m_persistentReferences.end() == m_persistentReferences.find(reference))
1291 {
1292 kdError(s_area) << "cannot find reference: " << reference << endl;
1293 }
1294 else
1295 {
1296 unsigned offset = m_persistentReferences[reference];
1297 kdDebug(s_area) << "found reference: " << reference <<
1298 " offset: " << offset << endl;
1299 walkRecord(offset);
1300 kdDebug(s_area) << "****************************" << endl;
1301
1302 }
1303}