summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/plucker_base.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-reader/plucker_base.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-reader/plucker_base.cpp1240
1 files changed, 0 insertions, 1240 deletions
diff --git a/noncore/apps/opie-reader/plucker_base.cpp b/noncore/apps/opie-reader/plucker_base.cpp
deleted file mode 100644
index 9047a45..0000000
--- a/noncore/apps/opie-reader/plucker_base.cpp
+++ b/dev/null
@@ -1,1240 +0,0 @@
1#include "useqpe.h"
2#include <stdio.h>
3#include <string.h>
4#include <qmessagebox.h>
5#include <qpixmap.h>
6#ifdef USEQPE
7#include <qpe/qcopenvelope_qws.h>
8#endif /* USEQPE */
9#ifdef LOCALPICTURES
10#include <qscrollview.h>
11#endif
12#ifdef USEQPE
13#include <qpe/global.h>
14#endif /* USEQPE */
15#include <qclipboard.h>
16#ifndef USEQPE
17#include <qapplication.h>
18#else /* USEQPE */
19#include <qpe/qpeapplication.h>
20#endif /* USEQPE */
21
22#include "plucker_base.h"
23#include "Aportis.h"
24#include "Palm2QImage.h"
25
26CPlucker_base::CPlucker_base() :
27#ifdef LOCALPICTURES
28 m_viewer(NULL),
29 m_picture(NULL),
30#endif
31 expandedtextbuffer(NULL),
32 compressedtextbuffer(NULL)
33//, urls(NULL)
34 { /*printf("constructing:%x\n",fin);*/ }
35
36
37void CPlucker_base::Expand(UInt32 reclen, UInt8 type, UInt8* buffer, UInt32 buffersize)
38{
39 if (type%2 == 0)
40 {
41 fread(buffer, reclen, sizeof(char), fin);
42 }
43 else
44 {
45 UInt8* readbuffer = NULL;
46 if (reclen > compressedbuffersize)
47 {
48 readbuffer = new UInt8[reclen];
49 }
50 else
51 {
52 readbuffer = compressedtextbuffer;
53 }
54 if (readbuffer != NULL)
55 {
56 fread(readbuffer, reclen, sizeof(char), fin);
57 switch (ntohs(hdr0.version))
58 {
59 case 2:
60 UnZip(readbuffer, reclen, buffer, buffersize);
61 break;
62 case 1:
63 UnDoc(readbuffer, reclen, buffer, buffersize);
64 break;
65 }
66 if (reclen > compressedbuffersize)
67 {
68 delete [] readbuffer;
69 }
70 }
71 }
72}
73
74void CPlucker_base::sizes(unsigned long& _file, unsigned long& _text)
75{
76 _file = file_length;
77 if (textlength == 0)
78 {
79 for (int recptr = 1; recptr < ntohs(head.recordList.numRecords); recptr++)
80 {
81 gotorecordnumber(recptr);
82 UInt16 thishdr_uid, thishdr_nParagraphs;
83 UInt32 thishdr_size;
84 UInt8 thishdr_type, thishdr_reserved;
85 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
86 if (thishdr_type < 2) textlength += thishdr_size;
87 }
88 }
89 _text = textlength;
90//ntohl(hdr0.size);
91}
92
93char* CPlucker_base::geturl(UInt16 tgt)
94{
95 char * pRet = NULL;
96 gotorecordnumber(0);
97 fread(&hdr0, 1, 6, fin);
98 unsigned int nrecs = ntohs(hdr0.nRecords);
99 //qDebug("Version %u, no. recs %u", ntohs(hdr0.version), nrecs);
100 UInt16 urlid = 0;
101 bool urlsfound = false;
102 char* urls = NULL;
103 size_t urlsize = 0;
104 for (unsigned int i = 0; i < nrecs; i++)
105 {
106 UInt16 id, name;
107 fread(&name, 1, sizeof(name), fin);
108 fread(&id, 1, sizeof(id), fin);
109 //qDebug("N:%d, I:%d", ntohs(name), ntohs(id));
110 if (ntohs(name) == 2)
111 {
112 urlsfound = true;
113 urlid = id;
114 //qDebug("Found url index:%d", ntohs(urlid));
115 }
116 ////qDebug("%x", id);
117 }
118 if (urlsfound)
119 {
120 unsigned short recptr = finduid(ntohs(urlid));
121 if (recptr != 0)
122 {
123 gotorecordnumber(recptr);
124 UInt16 thishdr_uid, thishdr_nParagraphs;
125 UInt32 thishdr_size;
126 UInt8 thishdr_type, thishdr_reserved;
127 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
128 UInt16 urlctr = 0;
129 while (1)
130 {
131 UInt16 tctr;
132 fread(&tctr, 1, sizeof(tctr), fin);
133 fread(&urlid, 1, sizeof(urlid), fin);
134 tctr = ntohs(tctr);
135 //qDebug("tgt:%u urlctr:%u tctr:%u", tgt, urlctr, tctr);
136 if (tctr >= tgt)
137 {
138 break;
139 }
140 urlctr = tctr;
141 }
142 //qDebug("urls are in %d", ntohs(urlid));
143 recptr = finduid(ntohs(urlid));
144 if (recptr != 0)
145 {
146 UInt32 reclen = recordlength(recptr) - HeaderSize();
147 gotorecordnumber(recptr);
148 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
149 //qDebug("Found urls:%x",thishdr_type);
150 urlsize = thishdr_size;
151 urls = new char[urlsize];
152 Expand(reclen, thishdr_type, (UInt8*)urls, urlsize);
153 char* ptr = urls;
154 int rn = urlctr+1;
155 while (ptr - urls < urlsize)
156 {
157 if (rn == tgt)
158 {
159 //qDebug("URL:%s", ptr);
160 int len = strlen(ptr)+1;
161 pRet = new char[len];
162 memcpy(pRet, ptr, len);
163 break;
164 }
165 ptr += strlen(ptr)+1;
166 rn++;
167 }
168 delete [] urls;
169 }
170 }
171 }
172 else
173 {
174 QMessageBox::information(NULL,
175 QString(PROGNAME),
176 QString("No external links\nin this pluck")
177 );
178 }
179 return pRet;
180}
181
182CPlucker_base::~CPlucker_base()
183{
184 if (expandedtextbuffer != NULL) delete [] expandedtextbuffer;
185 if (compressedtextbuffer != NULL) delete [] compressedtextbuffer;
186#ifdef LOCALPICTURES
187 if (m_viewer != NULL) delete m_viewer;
188#endif
189}
190
191int CPlucker_base::getch() { return getch(false); }
192
193void CPlucker_base::getch(tchar& ch, CStyle& sty)
194{
195 ch = getch(false);
196 sty = mystyle;
197}
198
199unsigned int CPlucker_base::locate()
200{
201 return currentpos;
202/*
203 UInt16 thisrec = 1;
204 unsigned long locpos = 0;
205 gotorecordnumber(thisrec);
206 UInt16 thishdr_uid, thishdr_nParagraphs;
207 UInt32 thishdr_size;
208 UInt8 thishdr_type, thishdr_reserved;
209 while (thisrec < bufferrec)
210 {
211 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
212 if (thishdr_type < 2) locpos += thishdr_size;
213 thisrec++;
214 gotorecordnumber(thisrec);
215 }
216 return locpos+bufferpos;
217*/
218}
219
220void CPlucker_base::locate(unsigned int n)
221{
222
223// clock_t start = clock();
224 UInt32 textlength = currentpos - bufferpos;
225 UInt16 recptr = bufferrec;
226 if (n < textlength/2)
227 {
228 textlength = 0;
229 UInt16 thishdr_uid, thishdr_nParagraphs;
230 UInt32 thishdr_size = buffercontent;
231 UInt8 thishdr_type, thishdr_reserved;
232 for (recptr = 1; recptr < ntohs(head.recordList.numRecords); recptr++)
233 {
234 gotorecordnumber(recptr);
235 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
236 if (thishdr_type < 2)
237 {
238 textlength += thishdr_size;
239 if (textlength > n)
240 {
241 textlength -= thishdr_size;
242 break;
243 }
244 }
245 }
246 }
247 else if (n < textlength)
248 {
249 UInt16 thishdr_uid, thishdr_nParagraphs;
250 UInt32 thishdr_size;
251 UInt8 thishdr_type, thishdr_reserved;
252 while (n < textlength && recptr > 1)
253 {
254 recptr--;
255 gotorecordnumber(recptr);
256 //qDebug("recptr:%u", recptr);
257 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
258 if (thishdr_type < 2)
259 {
260 textlength -= thishdr_size;
261 }
262 }
263 }
264 else
265 {
266 UInt16 thishdr_uid, thishdr_nParagraphs;
267 UInt32 thishdr_size = buffercontent;
268 UInt8 thishdr_type, thishdr_reserved;
269 while (n > textlength + thishdr_size && recptr < ntohs(head.recordList.numRecords)-1)
270 {
271 textlength += thishdr_size;
272 recptr++;
273 gotorecordnumber(recptr);
274 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
275 if (!(thishdr_type < 2))
276 {
277 thishdr_size = 0;
278 }
279 }
280 }
281// qDebug("Time(1): %u", clock()-start);
282/*
283 expand(recptr);
284 mystyle.unset();
285 bufferpos = n-textlength;
286 currentpos = n;
287 while (bufferpos >= m_nextPara && m_nextPara >= 0)
288 {
289 UInt16 attr = m_ParaAttrs[m_nextParaIndex];
290 m_nextParaIndex++;
291 if (m_nextParaIndex == m_nParas)
292 {
293 m_nextPara = -1;
294 }
295 else
296 {
297 m_nextPara += m_ParaOffsets[m_nextParaIndex];
298 }
299 }
300
301 return;
302*/
303// start = clock();
304
305 UInt16 thisrec = 0;
306 unsigned long locpos = 0;
307 unsigned long bs = 0;
308 UInt16 thishdr_uid, thishdr_nParagraphs;
309 UInt32 thishdr_size;
310 UInt8 thishdr_type, thishdr_reserved;
311 do
312 {
313 thisrec++;
314 locpos += bs;
315 gotorecordnumber(thisrec);
316 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
317 if (thishdr_type < 2)
318 {
319 bs = thishdr_size;
320 }
321 else
322 {
323 bs = 0;
324 }
325 } while (locpos + bs <= n);
326
327// qDebug("Time(2): %u", clock()-start);
328 if (recptr != thisrec)
329 {
330 qDebug("Disaster:recptr:%u thisrec:%u", recptr, thisrec);
331 UInt16 thishdr_uid, thishdr_nParagraphs;
332 UInt32 thishdr_size = buffercontent;
333 UInt8 thishdr_type, thishdr_reserved;
334 for (recptr = 1; recptr < ntohs(head.recordList.numRecords); recptr++)
335 {
336 gotorecordnumber(recptr);
337 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
338 // qDebug("UID:%u Paras:%u Size:%u Type:%u Reserved:%u", thishdr_uid, thishdr_nParagraphs, thishdr_size, (unsigned int)thishdr_type, (unsigned int)thishdr_reserved);
339 }
340 //QApplication::exit ( 100 );
341 }
342
343 currentpos = locpos;
344 expand(thisrec);
345 while (currentpos < n && bufferpos < buffercontent) getch_base(true);
346
347/* // This is faster but the alignment attribute doesn't get set 8^(
348 bufferpos = n-locpos;
349 currentpos = n;
350 while (bufferpos >= m_nextPara && m_nextPara >= 0)
351 {
352 UInt16 attr = m_ParaAttrs[m_nextParaIndex];
353 m_nextParaIndex++;
354 if (m_nextParaIndex == m_nParas)
355 {
356 m_nextPara = -1;
357 }
358 else
359 {
360 m_nextPara += m_ParaOffsets[m_nextParaIndex];
361 }
362 }
363*/
364}
365
366bool CPlucker_base::expand(int thisrec)
367{
368 mystyle.unset();
369 size_t reclen = recordlength(thisrec);
370 gotorecordnumber(thisrec);
371 UInt16 thishdr_uid, thishdr_nParagraphs;
372 UInt32 thishdr_size;
373 UInt8 thishdr_type, thishdr_reserved;
374 while (1)
375 {
376 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
377 //qDebug("This (%d) type is %d, uid is %u", thisrec, thishdr_type, thishdr_uid);
378 if (thishdr_type < 2) break;
379 //qDebug("Skipping paragraph of type %d", thishdr_type);
380 if (++thisrec >= ntohs(head.recordList.numRecords) - 1) return false;
381 reclen = recordlength(thisrec);
382 gotorecordnumber(thisrec);
383 }
384 m_nParas = thishdr_nParagraphs;
385 m_bufferisreserved = (thishdr_reserved != 0);
386 //qDebug("It has %u paragraphs and is %u bytes", thishdr_nParagraphs, thishdr_size);
387 uid = thishdr_uid;
388// gotorecordnumber(thisrec);
389// fread(expandedtextbuffer,1,10,fin);
390 for (int i = 0; i < m_nParas; i++)
391 {
392 UInt16 ubytes, attrs;
393 fread(&ubytes, 1, sizeof(ubytes), fin);
394 fread(&attrs, 1, sizeof(attrs), fin);
395 m_ParaOffsets[i] = ntohs(ubytes);
396 m_ParaAttrs[i] = ntohs(attrs);
397 ////qDebug("Bytes %u, Attr %x", ntohs(ubytes), ntohs(attrs));
398 }
399 if (m_nParas > 0)
400 {
401 m_nextPara = m_ParaOffsets[0];
402 //qDebug("First offset = %u", m_nextPara);
403 m_nextParaIndex = 0;
404 }
405 else
406 {
407 m_nextPara = -1;
408 }
409
410 reclen -= HeaderSize()+4*m_nParas;
411
412 buffercontent = thishdr_size;
413
414 if (thishdr_size > buffersize)
415 {
416 delete [] expandedtextbuffer;
417 buffersize = thishdr_size;
418 expandedtextbuffer = new UInt8[buffersize];
419 }
420
421 Expand(reclen, thishdr_type, expandedtextbuffer, buffercontent);
422 bufferpos = 0;
423 bufferrec = thisrec;
424 //qDebug("BC:%u, HS:%u", buffercontent, thishdr_size);
425 return true;
426}
427
428void CPlucker_base::UnZip(UInt8* compressedbuffer, size_t reclen, UInt8* tgtbuffer, size_t bsize)
429{
430 z_stream zstream;
431 memset(&zstream,sizeof(zstream),0);
432 zstream.next_in = compressedbuffer;
433 zstream.next_out = tgtbuffer;
434 zstream.avail_out = bsize;
435 zstream.avail_in = reclen;
436
437 int keylen = 0;
438
439 zstream.zalloc = Z_NULL;
440 zstream.zfree = Z_NULL;
441 zstream.opaque = Z_NULL;
442
443// printf("Initialising\n");
444
445 inflateInit(&zstream);
446 int err = 0;
447 do {
448 if ( zstream.avail_in == 0 && 0 < keylen ) {
449 zstream.next_in = compressedbuffer + keylen;
450 zstream.avail_in = reclen - keylen;
451 keylen = 0;
452 }
453 zstream.next_out = tgtbuffer;
454 zstream.avail_out = bsize;
455
456 err = inflate( &zstream, Z_SYNC_FLUSH );
457
458 ////qDebug("err:%d - %u", err, zstream.avail_in);
459
460 } while ( err == Z_OK );
461
462 inflateEnd(&zstream);
463}
464
465void CPlucker_base::UnDoc(UInt8* compressedbuffer, size_t reclen, UInt8* tgtbuffer, size_t bsize)
466{
467// UInt16 headerSize;
468 UInt16 docSize;
469 UInt16 i;
470 UInt16 j;
471 UInt16 k;
472
473 UInt8 *inBuf = compressedbuffer;
474 UInt8 *outBuf = tgtbuffer;
475
476// headerSize = sizeof( Header ) + record->paragraphs * sizeof( Paragraph );
477 docSize = reclen;
478
479 j = 0;
480 k = 0;
481 while ( j < docSize ) {
482 i = 0;
483 while ( i < bsize && j < docSize ) {
484 UInt16 c;
485
486 c = (UInt16) inBuf[ j++ ];
487 if ( 0 < c && c < 9 ) {
488 while ( 0 < c-- )
489 outBuf[ i++ ] = inBuf[ j++ ];
490 }
491 else if ( c < 0x80 )
492 outBuf[ i++ ] = c;
493 else if ( 0xc0 <= c ) {
494 outBuf[ i++ ] = ' ';
495 outBuf[ i++ ] = c ^ 0x80;
496 }
497 else {
498 Int16 m;
499 Int16 n;
500
501 c <<= 8;
502 c += inBuf[ j++ ];
503
504 m = ( c & 0x3fff ) >> COUNT_BITS;
505 n = c & ( ( 1 << COUNT_BITS ) - 1 );
506 n += 2;
507
508 do {
509 outBuf[ i ] = outBuf[ i - m ];
510 i++;
511 } while ( 0 < n-- );
512 }
513 }
514 k += bsize;
515 }
516}
517
518void CPlucker_base::home()
519{
520 currentpos = 0;
521 expand(1);
522}
523
524CList<Bkmk>* CPlucker_base::getbkmklist()
525{
526/*
527 UInt16 thishdr_uid, thishdr_nParagraphs;
528 UInt32 thishdr_size;
529 UInt8 thishdr_type, thishdr_reserved;
530
531 for (int i = 1; i < ntohs(head.recordList.numRecords); i++)
532 {
533 gotorecordnumber(i);
534 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
535 if (thishdr_type == 8)
536 {
537 UInt16 n;
538 fread(&n, 1, sizeof(n), fin);
539 n = ntohs(n);
540 //qDebug("Found %u bookmarks", n);
541 }
542 //qDebug("Found:%d, %u", i , thishdr_type);
543 }
544*/
545 return NULL;
546}
547
548#include <qnamespace.h>
549
550QImage* CPlucker_base::expandimg(UInt16 tgt, bool border)
551{
552 QImage* qimage = getimg(tgt);
553 QImage* ret;
554 if (qimage == NULL) return NULL;
555 if (border)
556 {
557 QPixmap* image = new QPixmap(0,0);
558 image->convertFromImage(*qimage);
559 delete qimage;
560 QPixmap* pret = new QPixmap(image->width()+4, image->height()+4);
561 pret->fill(Qt::red);
562 bitBlt(pret, 2, 2, image, 0, 0, -1, -1);//, Qt::RasterOp::CopyROP);
563 delete image;
564 ret = new QImage(pret->convertToImage());
565 }
566 else
567 {
568 ret = qimage;
569 }
570 return ret;
571}
572
573#ifdef _BUFFERPICS
574#include <qmap.h>
575#endif
576
577QImage* CPlucker_base::getPicture(unsigned long tgt)
578{
579#ifdef _BUFFERPICS
580 static QMap<unsigned long, QPixmap> pix;
581 QMap<unsigned long, QPixmap>::Iterator t = pix.find(tgt);
582 if (t == pix.end())
583 {
584 pix[tgt] = *expandimg(tgt);
585 return &pix[tgt];
586 }
587 else
588 return &(t.data());
589#else
590 return expandimg(tgt >> 16);
591#endif
592}
593
594#ifdef LOCALPICTURES
595#include <unistd.h>
596#include <qpe/global.h>
597void CPlucker_base::showimg(UInt16 tgt)
598{
599 //qDebug("Crassssssh!");
600 QPixmap* qimage = expandimg(tgt);
601 m_picture->setFixedSize(qimage->size());
602 m_picture->setBackgroundPixmap(*qimage);
603 delete qimage;
604 m_viewer->show();
605
606/*
607 char tmp[] = "uqtreader.XXXXXX";
608 QImage* qimage = getimg(tgt);
609 QPixmap* image = new QPixmap(0,0);
610// //qDebug("New image");
611 image->convertFromImage(*qimage);
612 delete qimage;
613 char tmpfile[sizeof(tmp)+1];
614 strcpy(tmpfile,tmp);
615 int f = mkstemp(tmpfile);
616 close(f);
617 //qDebug("TMPFILE:%s", tmpfile);
618 if (image->save(tmpfile,"PNG"))
619 {
620 QCopEnvelope e("QPE/Application/showimg", "setDocument(QString)");
621 e << QString(tmpfile);
622 }
623 Global::statusMessage("Opening image");
624 sleep(5);
625 delete image;
626 unlink(tmpfile);
627*/
628}
629
630#endif
631
632unsigned short CPlucker_base::finduid(unsigned short urlid)
633{
634// //qDebug("Finding %u", urlid);
635 unsigned short jmin = 1, jmax = ntohs(head.recordList.numRecords);
636 unsigned short jmid = (jmin+jmax) >> 1;
637 while (jmax - jmin > 1)
638 {
639 gotorecordnumber(jmid);
640 UInt16 thishdr_uid, thishdr_nParagraphs;
641 UInt32 thishdr_size;
642 UInt8 thishdr_type, thishdr_reserved;
643 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
644 unsigned short luid = thishdr_uid;
645 ////qDebug("%u %u %u : %u", jmin, jmid, jmax, urlid);
646 if (luid == urlid)
647 {
648 return jmid;
649 }
650 if (luid < urlid)
651 {
652 jmin = jmid;
653 }
654 else
655 {
656 jmax = jmid;
657 }
658 jmid = (jmin+jmax) >> 1;
659 }
660 gotorecordnumber(jmin);
661 UInt16 thishdr_uid, thishdr_nParagraphs;
662 UInt32 thishdr_size;
663 UInt8 thishdr_type, thishdr_reserved;
664 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
665 unsigned short luid = thishdr_uid;
666 //qDebug("jmin at end:%u,%u", jmin, luid);
667 if (luid == urlid)
668 {
669 return jmin;
670 }
671 gotorecordnumber(jmax);
672 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
673 luid = thishdr_uid;
674 //qDebug("jmax at end:%u,%u", jmax, luid);
675 if (luid == urlid)
676 {
677 return jmax;
678 }
679 //qDebug("Couldn't find %u", urlid);
680 return 0; // Not found!
681}
682
683#include <qnamespace.h>
684
685void CPlucker_base::setSaveData(unsigned char*& data, unsigned short& len, unsigned char* src, unsigned short srclen)
686{
687 unsigned short sz = 0;
688 for (CList<unsigned long>::iterator it = visited.begin(); it != visited.end(); it++)
689 {
690 sz++;
691 }
692 size_t newlen = srclen+sizeof(sz)+sz*sizeof(unsigned long);
693 unsigned char* newdata = new unsigned char[newlen];
694 unsigned char* pdata = newdata;
695 memcpy(newdata, src, srclen);
696 newdata += srclen;
697 memcpy(newdata, &sz, sizeof(sz));
698 newdata += sizeof(sz);
699#ifdef _WINDOWS
700 for (it = visited.begin(); it != visited.end(); it++)
701#else
702 for (CList<unsigned long>::iterator it = visited.begin(); it != visited.end(); it++)
703#endif
704 {
705 unsigned long t = *it;
706 //qDebug("[%u]", t);
707 memcpy(newdata, &t, sizeof(t));
708 newdata += sizeof(t);
709 }
710 m_nav.setSaveData(data, len, pdata, newlen);
711 delete [] pdata;
712}
713
714void CPlucker_base::putSaveData(unsigned char*& src, unsigned short& srclen)
715{
716 unsigned short sz;
717 if (srclen >= sizeof(sz))
718 {
719 memcpy(&sz, src, sizeof(sz));
720 src += sizeof(sz);
721 srclen -= sizeof(sz);
722 }
723 for (int i = 0; i < sz; i++)
724 {
725 unsigned long t;
726 if (srclen >= sizeof(t))
727 {
728 memcpy(&t, src, sizeof(t));
729 // qDebug("[%u]", t);
730 visited.push_front(t);
731 src += sizeof(t);
732 srclen -= sizeof(t);
733 }
734 else
735 {
736 QMessageBox::warning(NULL, PROGNAME, "File data mismatch\nMight fix itself");
737 break;
738 }
739 }
740 m_nav.putSaveData(src, srclen);
741}
742
743int CPlucker_base::OpenFile(const char *src)
744{
745 m_lastBreak = 0;
746 if (!Cpdb::openfile(src))
747 {
748 return -1;
749 }
750
751 if (!CorrectDecoder()) return -1;
752
753 gotorecordnumber(0);
754 fread(&hdr0, 1, 6, fin);
755 setbuffersize();
756 compressedtextbuffer = new UInt8[compressedbuffersize];
757 expandedtextbuffer = new UInt8[buffersize];
758
759 //qDebug("Total number of records:%u", ntohs(head.recordList.numRecords));
760
761 unsigned int nrecs = ntohs(hdr0.nRecords);
762 //qDebug("Version %u, no. recs %u", ntohs(hdr0.version), nrecs);
763 UInt16 homerecid = 1;
764 for (unsigned int i = 0; i < nrecs; i++)
765 {
766 UInt16 id, name;
767 fread(&name, 1, sizeof(name), fin);
768 fread(&id, 1, sizeof(id), fin);
769 //qDebug("N:%d, I:%d", ntohs(name), ntohs(id));
770 if (ntohs(name) == 0) homerecid = ntohs(id);
771 }
772
773 textlength = 0;
774 for (int recptr = 1; recptr < ntohs(head.recordList.numRecords); recptr++)
775 {
776 gotorecordnumber(recptr);
777 UInt16 thishdr_uid, thishdr_nParagraphs;
778 UInt32 thishdr_size;
779 UInt8 thishdr_type, thishdr_reserved;
780 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
781 if (thishdr_uid == homerecid)
782 {
783 m_homepos = textlength;
784 break;
785 }
786 if (thishdr_type < 2) textlength += thishdr_size;
787 }
788 textlength = 0;
789 home();
790#ifdef LOCALPICTURES
791 if (m_viewer == NULL)
792 {
793 m_viewer = new QScrollView(NULL);
794 m_picture = new QWidget(m_viewer->viewport());
795 m_viewer->addChild(m_picture);
796 }
797#endif
798 return 0;
799
800}
801
802QImage* CPlucker_base::getimg(UInt16 tgt)
803{
804 size_t reclen;
805 UInt16 thisrec = finduid(tgt);
806 reclen = recordlength(thisrec);
807 gotorecordnumber(thisrec);
808 UInt16 thishdr_uid, thishdr_nParagraphs;
809 UInt32 thishdr_size;
810 UInt8 thishdr_type, thishdr_reserved;
811 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
812 reclen -= HeaderSize();
813
814 UInt32 imgsize = thishdr_size;
815 UInt8* imgbuffer = new UInt8[imgsize];
816
817 Expand(reclen, thishdr_type, imgbuffer, imgsize);
818
819 return imagefromdata(imgbuffer, imgsize);
820}
821
822linkType CPlucker_base::hyperlink(unsigned int n, QString& wrd)
823{
824 visited.push_front(n);
825 UInt16 tuid = (n >> 16);
826 n &= 0xffff;
827// //qDebug("Hyper:<%u,%u>", tuid, n);
828 UInt16 thisrec = 1;
829 currentpos = 0;
830 gotorecordnumber(thisrec);
831 UInt16 thishdr_uid, thishdr_nParagraphs;
832 UInt32 thishdr_size;
833 UInt8 thishdr_type, thishdr_reserved;
834 while (1)
835 {
836 GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
837 if (tuid == thishdr_uid) break;
838 if (thishdr_type < 2) currentpos += thishdr_size;
839 ////qDebug("hyper-cp:%u", currentpos);
840 thisrec++;
841 if (thisrec >= ntohs(head.recordList.numRecords))
842 {
843 char *turl = geturl(tuid);
844 if (turl == NULL)
845 {
846 QMessageBox::information(NULL,
847 QString(PROGNAME),
848 QString("Couldn't find link")
849 );
850 }
851 else
852 {
853 wrd = turl;
854#ifdef USEQPE
855 if (wrd.length() > 10)
856 {
857 Global::statusMessage(wrd.left(8) + "..");
858 }
859 else
860 {
861 Global::statusMessage(wrd);
862 }
863#else
864#endif /* USEQPE */
865 //qDebug("Link:%s", (const char*)wrd);
866 // setlink(fn, wrd);
867 delete [] turl;
868 }
869 return eNone;
870 }
871 gotorecordnumber(thisrec);
872 }
873 if (thishdr_type > 1)
874 {
875 if (thishdr_type == 4)
876 {
877 QMessageBox::information(NULL,
878 QString(PROGNAME),
879 QString("Mailto links\nnot yet supported (2)"));
880 }
881 else
882 {
883 if (thishdr_type > 3)
884 {
885 QMessageBox::information(NULL,
886 QString(PROGNAME),
887 QString("External links\nnot yet supported (2)")
888 );
889 return eNone;
890 }
891 else
892 {
893#ifdef LOCALPICTURES
894 showimg(tuid);
895#else
896 return ePicture;
897#endif
898 }
899 }
900 return eNone;
901 }
902/*
903 if (thishdr_type == 2 || thishdr_type == 3)
904 {
905 expandimg(thisrec);
906
907 }
908*/
909 else
910 {
911 expand(thisrec);
912 if (n != 0)
913 {
914 if (n >= m_nParas)
915 {
916 QMessageBox::information(NULL,
917 QString(PROGNAME),
918 QString("Error in link\nPara # too big")
919 );
920 return eNone;
921 }
922 unsigned int noff = 0;
923 for (unsigned int i = 0; i < n; i++) noff += m_ParaOffsets[i];
924 n = noff;
925 }
926 if (n > thishdr_size)
927 {
928 QMessageBox::information(NULL,
929 QString(PROGNAME),
930 QString("Error in link\nOffset too big")
931 );
932 return eNone;
933 }
934 //qDebug("Hyper:<%u,%u>", tuid, n);
935 while (bufferpos < n && bufferpos < buffercontent) getch_base(true);
936/* // This is faster but the alignment doesn't get set
937 mystyle.unset();
938 bufferpos = n;
939 currentpos += n;
940 while (bufferpos >= m_nextPara && m_nextPara >= 0)
941 {
942 UInt16 attr = m_ParaAttrs[m_nextParaIndex];
943 m_nextParaIndex++;
944 if (m_nextParaIndex == m_nParas)
945 {
946 m_nextPara = -1;
947 }
948 else
949 {
950 m_nextPara += m_ParaOffsets[m_nextParaIndex];
951 }
952 }
953*/
954 }
955 return eLink;
956}
957
958tchar CPlucker_base::getch_base(bool fast)
959{
960 int ch = bgetch();
961 while (ch == 0)
962 {
963 ch = bgetch();
964 ////qDebug("Function:%x", ch);
965 switch (ch)
966 {
967 case 0x38:
968 // //qDebug("Break:%u", locate());
969 if (m_lastBreak == locate())
970 {
971 ch = bgetch();
972 }
973 else
974 {
975 ch = 10;
976 }
977 m_lastBreak = locate();
978 break;
979 case 0x0a:
980 case 0x0c:
981 {
982 unsigned long ln = 0;
983 int skip = ch & 7;
984 for (int i = 0; i < 2; i++)
985 {
986 int ch = bgetch();
987 ln = (ln << 8) + ch;
988 // //qDebug("ch:%d, ln:%u", ch, ln);
989 }
990 if (skip == 2)
991 {
992 ln <<= 16;
993 }
994 else
995 {
996 for (int i = 0; i < 2; i++)
997 {
998 int ch = bgetch();
999 ln = (ln << 8) + ch;
1000 // //qDebug("ch:%d, ln:%u", ch, ln);
1001 }
1002 }
1003 // //qDebug("ln:%u", ln);
1004 mystyle.setLink(true);
1005 mystyle.setData(ln);
1006 // mystyle.setColour(255, 0, 0);
1007 bool hasseen = false;
1008 for (CList<unsigned long>::iterator it = visited.begin(); it != visited.end(); it++)
1009 {
1010 if (*it == ln)
1011 {
1012 hasseen = true;
1013 break;
1014 }
1015 }
1016 if (hasseen)
1017 {
1018 mystyle.setStrikethru();
1019 }
1020 else
1021 {
1022 mystyle.setUnderline();
1023 }
1024 ch = bgetch();
1025 }
1026 break;
1027 case 0x08:
1028 ch = bgetch();
1029 // mystyle.setColour(0, 0, 0);
1030 mystyle.unsetUnderline();
1031 mystyle.unsetStrikethru();
1032 mystyle.setLink(false);
1033 mystyle.setData(0);
1034 break;
1035 case 0x40:
1036 mystyle.setItalic();
1037 ch = bgetch();
1038 break;
1039 case 0x48:
1040 mystyle.unsetItalic();
1041 ch = bgetch();
1042 break;
1043 case 0x11:
1044 {
1045 ch = bgetch();
1046 // //qDebug("Font:%d",ch);
1047 mystyle.setVOffset(0);
1048 mystyle.unsetMono();
1049 mystyle.unsetBold();
1050 mystyle.setFontSize(0);
1051 switch (ch)
1052 {
1053 case 0:
1054 break;
1055 case 1:
1056 mystyle.setBold();
1057 mystyle.setFontSize(3);
1058 break;
1059 case 2:
1060 mystyle.setBold();
1061 mystyle.setFontSize(2);
1062 break;
1063 case 3:
1064 mystyle.setBold();
1065 mystyle.setFontSize(1);
1066 break;
1067 case 4:
1068 mystyle.setBold();
1069 break;
1070 case 5:
1071 mystyle.setBold();
1072 break;
1073 case 6:
1074 mystyle.setBold();
1075 break;
1076 case 7:
1077 mystyle.setBold();
1078 break;
1079 case 8: // should be fixed width
1080 //qDebug("Trying fixed width");
1081 mystyle.setMono();
1082 break;
1083 case 9:
1084 mystyle.setFontSize(-1);
1085 break;
1086 case 10:
1087 mystyle.setFontSize(-2);
1088 mystyle.setVOffset(1);
1089 break;
1090 case 11:
1091 mystyle.setFontSize(-2);
1092 mystyle.setVOffset(-1);
1093 break;
1094 default:
1095 qDebug("Unrecognised font");
1096 break;
1097 }
1098 ch = bgetch();
1099 }
1100 break;
1101 case 0x29:
1102 ch = bgetch();
1103 switch (ch)
1104 {
1105 case 0:
1106 mystyle.setLeftJustify();
1107 // //qDebug("left");
1108 break;
1109 case 1:
1110 mystyle.setRightJustify();
1111 // //qDebug("right");
1112 break;
1113 case 2:
1114 mystyle.setCentreJustify();
1115 // //qDebug("centre");
1116 break;
1117 case 3:
1118 mystyle.setFullJustify();
1119 // //qDebug("full");
1120 break;
1121
1122 }
1123 ch = bgetch();
1124 break;
1125 case 0x53:
1126 {
1127 int r = bgetch();
1128 int g = bgetch();
1129 int b = bgetch();
1130 mystyle.setColour(r,g,b);
1131 ch = bgetch();
1132 }
1133 break;
1134 case 0x1a:
1135 case 0x5c:
1136 {
1137 bool hasalternate = (ch == 0x5c);
1138 UInt16 ir = bgetch();
1139 ir = (ir << 8) + bgetch();
1140 if (hasalternate)
1141 {
1142 //qDebug("Alternate image:%x", ir);
1143 UInt16 ir2 = bgetch();
1144 ir2 = (ir2 << 8) + bgetch();
1145 if (!fast) mystyle.setPicture(true, expandimg(ir2, true), true, ir << 16);
1146#ifdef LOCALPICTURES
1147 UInt32 ln = ir;
1148 ln <<= 16;
1149 mystyle.setLink(true);
1150 mystyle.setData(ln);
1151#endif
1152 }
1153 else
1154 {
1155 if (!fast) mystyle.setPicture(true, expandimg(ir));
1156 }
1157 // if (mystyle.getLink()) qDebug("Picture link!");
1158 ch = '#';
1159 }
1160 // ch = bgetch();
1161 break;
1162 case 0x33:
1163 {
1164 UInt8 h = bgetch();
1165 UInt8 wc = bgetch();
1166 UInt8 pc = bgetch();
1167 UInt16 w = wc;
1168 // //qDebug("h,w,pc [%u, %u, %u]", h, w, pc);
1169 if (w == 0)
1170 {
1171 w = (m_scrWidth*(unsigned long)pc)/100;
1172 }
1173 if (w == 0) w = m_scrWidth;
1174 mystyle.setPicture(false, hRule(w,h,mystyle.Red(),mystyle.Green(),mystyle.Blue()));
1175 // if (mystyle.getLink()) //qDebug("hRule link!");
1176 ch = '#';
1177 }
1178 break;
1179 case 0x60:
1180 mystyle.setUnderline();
1181 ch = bgetch();
1182 break;
1183 case 0x68:
1184 mystyle.unsetUnderline();
1185 ch = bgetch();
1186 break;
1187 case 0x22:
1188 ch = bgetch();
1189 mystyle.setLeftMargin(ch);
1190 // //qDebug("Left margin:%d", ch);
1191 ch = bgetch();
1192 mystyle.setRightMargin(ch);
1193 // //qDebug("Right margin:%d", ch);
1194 ch = bgetch();
1195 break;
1196 case 0x70:
1197 mystyle.setStrikethru();
1198 ch = bgetch();
1199 break;
1200 case 0x78:
1201 mystyle.unsetStrikethru();
1202 ch = bgetch();
1203 break;
1204 case 0x83:
1205 {
1206 int tlen = bgetch();
1207 ch = bgetch();
1208 ch <<= 8;
1209 ch |= (tchar)bgetch();
1210 for (int i = 0; i < tlen; i++) bgetch();
1211 //qDebug("Function 83");
1212 }
1213 break;
1214 case 0x85:
1215 default:
1216 qDebug("Function:%x NOT IMPLEMENTED", ch);
1217 {
1218 int skip = ch & 7;
1219 for (int i = 0; i < skip; i++)
1220 {
1221 ch = bgetch();
1222 //qDebug("Arg %d, %d", i, ch);
1223 }
1224 ch = bgetch();
1225 }
1226 }
1227 }
1228
1229 if (m_lastIsBreak && !mystyle.isMono())
1230 {
1231 while (ch == ' ')
1232 {
1233 ch = getch(false);
1234 }
1235 }
1236
1237 m_lastIsBreak = (ch == 10);
1238
1239 return (ch == EOF) ? UEOF : ch;
1240}