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